Comments (6)
In src/comp/Parser/BSV/CVParser.lhs
, there are parsing functions pExpressionSimple
and pExpression
, where the only difference is that the first excludes the ternary conditional operator (? :
). The first is only used in one place, in the definition of pCondExpression
, which is the parsing of the boolean condition in conditional syntax -- presumably this is to avoid ambiguity of nested conditional operators, so you have to put parentheses around them.
The parsing of case-expressions is done by calling the parser for case-statements and just telling it to allow naked expressions (see pCasePrimary
which sets allowNakedExpr
and calls pImperativeCase
). In the parsing of case-statements, the arm is parsed by pImperativeStmt
. This calls pImperativeStmtWithAttrs
which has a long list of parsers that it tries, and I believe it's the last one (pImperativeDeclOrAssignSemi
that calls pImperativeDeclOrAssign
) which handles naked expressions. Or it should. It could be something else earlier in the list is parsing the start of the expression but failing on the rest; it probably just needs try
to be added to it, so that the failure doesn't cause the parsing to stop immediately.
I don't think the issue has anything to do with case-expressions or case-statements specifically, but with the fact that x == y
doesn't parse as a statement (and thus doesn't parse as the arm of a case). That is, we get the same error if we try this:
module mkTest (Empty);
int x = 1;
int y = 2;
x == y;
endmodule
but it parses if we add parentheses around the expression (and BSC fails in the later typecheck stage, after parsing has succeeded).
from bsc.
FYI, you don't need the keyword matches
here, since you're not using any pattern matching. An ordrinary non-matching case would be fine. (You get the same error, either way.) I notice that the BSV Ref Guide doesn't document non-matching case, which should probably be fixed.
from bsc.
Ah, I think I've solved it.
In pImperativeDeclOrAssign
, the last two things that it tries are pVarTypeCases
and naked expressions. As the comment explains, it calls pVarTypeCases
twice: the first time, if it fails, it goes on to try a naked expression; then, if parsing a naked expression fails, it calls pVarTypeCases
again, this time for its error message. The result is that both are tried, but the error message is for the more common case.
The code for trying a naked expressions looks for a semicolon after what it has parsed, to guarantee that it has consumed the entire statement. But the code for trying pVarTypeCases
doesn't do this. When the expression x==y
is encountered, the parsing of pVarTypeCases
can match the first part of it (though I'm not entirely sure how, maybe the bare variable?) and so we never get to trying for a naked expression: the statement parses, but then we get an error that the next part isn't expected after a statement. If I change the try of pVarTypeCases
to only match if it consumes up to a semicolon, then the above examples parse. That is:
<|> try (do
s <- pVarTypeCases2
lookAhead pSemi
return s)
However, I don't know if this is OK to do, so I will have to test it. I also don't know if it's safe to assume that there will always be a semicolon -- it's what the try
for the naked expression does, so that would also be broken, if not -- but I would guess so?
Looking close at why pVarTypeCases
matches on x==y
. It's the first option that is matching, where it calls pQualIdOrTuple
(which matches an identifier like x
) and then it calls pImperativeWithVar
, which looks for any "suffix" on the identifier (with pPrimaryWithSuffix
) but is OK with not finding any (the return e
branch of pPrimaryWithSuffix
), and then it attempts to parse what comes after the variable, which can be <=
or <-
or =
, but it can apparently also be nothing (pImperativeWithExprNakedExpr
). I'm not sure why that is there -- maybe a better fix (than looking for a semicolon) is to just remove pImperativeWithExprNakedExpr
as an option within pImperativeWithVarCall
, since that case is covered by the later trying of a naked expression. Yeah, I'm tempted by that approach, and will try testing it.
from bsc.
Thank you very much for the elaborate reply! For now I will work around this behavior by just wrapping the expression in parentheses. On a different note, is there documentation available on the internal architecture of the compiler?
from bsc.
is there documentation available on the internal architecture of the compiler?
I don't believe there is anything compiled in one place, yet. Feel free to ask questions here on GitHub (in an Issue or a Discussion) or in the mailing lists (bsc-dev
or b-lang-discuss
-- I would recommend using bsc-dev
for questions that are only relevant to developers, to keep traffic light for people who are just users and might not be interested). In those four places, I have written up long responses on a number of topics, and it's my intention to collect them up and put them in a single place, but I haven't decided what that is yet. GitHub provides a wiki feature, that we could use; but maybe a document (in bsc/doc/
) would be better.
For example, some writeups are:
- BSC is a series of stages
- which includes a link to these (incomplete) diagrams of the BSC stages
- See also this brief breakdown of BSC by its three internal representations (CSyntax, ISyntax, ASyntax)
- Briefly on printing and dumping from BSC and intermediate files
- How to add a new evaluator primitive to BSC
- specifically how to add a function to get the current module name
- Understanding scheduling
- The meaning of
.bo
and.ba
files and compiler flow - How the Bluesim C API is imported into Bluetcl
- Support for reflection in BSC
- specifically, Bluetcl (outside the language) and Generics (inside the language)
- The ways that SMT solvers are used in BSC
- Keyword parsing in BH/Classic
from bsc.
maybe a better fix (than looking for a semicolon) is to just remove
pImperativeWithExprNakedExpr
as an option withinpImperativeWithVarCall
When I do this, there is a testcase (ImperativeFunctionBeginEndMissingReturn.bsv
in bsc.syntax/bsv05/
) that fails with a different error. That test has a function body like this:
function int f();
...
y;
endfunction
Currently, BSC gives this error:
Error: "ImperativeFunctionBeginEndMissingReturn.bsv", line 7, column 4: (P0106)
Unassigned expressions forbidden in expression block; perhaps `return' is
missing before the expression?
That's because pImperativeWithExprNakedExpr
accepts y
to be parsed but then reports it with this special error. If I remove that, then the parser just rejects the code with the typical "unexpected tokens" error:
Error: "ImperativeFunctionBeginEndMissingReturn.bsv", line 7, column 4: (P0005)
Unexpected `;'; expected `=', `<-', `<=', type parameters, `{', identifier
starting with lowercase, `.', `(', or `['
I'm not convinced that the existing message is the best. But I don't feel strongly enough to change things. So, instead of removing pImperativeWithExprNakedExpr
, I think I'll leave it in, but make it only parse if it consumes all the way to the semicolon.
from bsc.
Related Issues (20)
- Bluesim divide-by-zero behavior is inconsistent on arm64 HOT 2
- Type synonyms with phantom parameters can lead to strange behaviors (E.g., compiler hang) HOT 4
- doc example for mkUniqueWrapper2 HOT 7
- -remove-unused-modules flag doesn't work with mkProbe module provided in std library HOT 2
- Failures with compilation on raspberry-pi 5 HOT 4
- GCC 14 emits extra warnings HOT 1
- Github's macos-11 runner is going away HOT 1
- [Bluesim] Simulation executable fails with `undefined symbol: _Z21vcd_write_scope_startP9tSimStatePKc` HOT 9
- `sqrtFP` is incorrect HOT 6
- compile to verilog, convert function to function, but not to modules. HOT 1
- Preserving structure at synthesis boundaries HOT 2
- Better control of wrapper generation HOT 6
- Incremental compilation model and UX improvements
- how does bsc disambiguate between V2K keywords and library functions? HOT 2
- Debugging with Bluetcl - displaying values
- implicit pack/unpack + custom Bits instance can result in extraneous logic. HOT 1
- Rules with conflicts can happen at the same cycle HOT 2
- truncate has wrong provisos in the BSC libraries reference guide documentation HOT 1
- Add back middle-dot as function composition for backward compatibility HOT 4
- Add support for windows builds HOT 4
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from bsc.