Closed udif closed 1 week ago
For the sake of completeness, I edited the original issue to include the expected output when the bug is not triggered, which I forgot to include earlier.
This is essentially an API bug; the API should not allow you to access the parameter list before the instance body has been elaborated, but currently it does. If you do something like call .members() prior to accessing the parameters things will work correctly. I'll add an accessor that enforces this.
I am confused.
I was using the code below, and assumed that by the time driver.createCompilation()
returns, everything is elaborated, and I'm merely traversing an already elaborated tree.
bool ok = driver.parseAllSources();
auto compilation = driver.createCompilation();
auto instances = compilation->getRoot().topInstances;
for (auto& i : instances) {
i->visit(makeVisitor([&](auto& visitor, const InstanceSymbol& type) {...}));
}
...
The truth is, I couldn't find any document/tutorial that explains how to use slang as a parser. I could only rely on the tools
directory as examples, but apparently that's not enoug.
In sv-lang.com, you have several sections:
User Manual, which more-or-less only talks about using the slang
executable, perhaps as a simple syntax checker.
Developer Guide, that has 5 sub-sections. The first is a technical build/install section, the next deal with some subclasses you don't need to know about if you use the driver. only in the last sub-section you mention the SyntaxTree class.
And finally, the API Reference which is way too low level and only serves as a reference material if you already knows what each class does and just needs a reference.
I'm left with so many questions:
slang
I see that a fully elaborated design includes both final parameter values, and the expression used to derive it. How does this work for other stuff such as if/for generate? do I see both code paths, those covered by if/generate and the else
branch that is not?Yeah, it's on my list to write some higher level documentation for the AST constructs. The key points to get you going:
I just independently confirmed this.
For the sake of the test, I added an additional silent driver.reportCompilation(*compilation, /* quiet */ true);
call before my code, and the problems went away (I left the original reportCompilation
at the end.
When you look at repotCompilation
, you see that when it is in quiet mode, all it does is this code:
for (auto& diag : compilation.getAllDiagnostics())
diagEngine.issue(diag);
bool succeeded = diagEngine.getNumErrors() == 0;
std::string diagStr = diagClient->getString();
OS::printE(fmt::format("{}", diagStr));
Apparently, as you wrote, it does more work as it gets the diagnostics messages. My permanent solution is simply to call it once before my code.
Fixed in b9d54238b0a62838c99a5a442312b95ad8e1c1f8
Describe the bug In some places when calling the AST to get a parameter value, it triggers an erroneous error message.
To Reproduce
Run the following with:
slang-hier test.v
Which produces:
Then run again with:
slang-hier --params test.v
Which produces:
Notice that the error appears only when 2 parameters are both defined in a macro and one depends on the other. All other test cases, where only one is defined in the macro, do not trigger this.
The error is triggered by the following lines in
slang-hier.v
on lines 93-94:The
assign
is in the test because this was an effort to get a minimum sized example to another bug where a parameter on the same code was incorrectly inferred as 0, but instead it triggered this bug I already ran into earlier but didn't have a clue as how to recreate.