I'm currently working the new parser for Lucid V2. This will be a major update to the Lucid language and will bring many breaking changes.
Currently, these are the changes I'm working on.
The rest of this post is the nitty gritty of the update.
The original Lucid parser has had feature after feature tacked on to where it is a bit of a mess today. Originally, it only attempted to figure out the width of signals. Then I added stuff that would parse constant expressions so custom functions could be added. Now I want a general interpreter that could be used to build a simulator. This was the motivation behind the full overhaul.
The original parser is broken into a handful of modules here https://github.com/alchitry/Alchitry-Lab...ools/lucid
The main parent is the LucidExtractor. This deals with all the declarations of stuff like modules, dffs, fsms, etc.
The BitWidthChecker attempts to figure out how wide each signal is. It is responsible for giving errors for situations like when you try to assign a struct to an array.
The ConstExprParser was original used to parse constant expressions for functions but has slowly outgrown that role to general expression parsing.
The BoundsParser parses array bounds (like [5:1] or [0+:3])
The ConstParser builds a list of constants declared
The ParamsParser builds a list of parameters declared
There are also a handful of other helper parsers like the LucidGlobalExtractor that parses globals in an initial pass of all the files.
These are all weirdly interdependent which is one of the goals to fix for the new parse.
Currently, the V2 parser handles expressions. I now need to add the rest (variable declarations, various block parsing, global statements, etc)
Its code can be found here https://github.com/alchitry/Alchitry-Lab...rs/lucidv2
The ExprParser is responsible for assigning a Value to every expression. This combines the functionality of the BitWidthChecker and ConstExprParser as these were often redundant. The Value type has an associated width to it and can be an UndefinedValue that still has a width which covers the cases that the BitWidthChecker used to deal with when ConstExprParser couldn't figure out a value.
I also plan to roll some of the small parsers into ExprParser such as BoundsParser (which I added today). Having multiple parsers that are interdependent makes using them difficult.
Currently, these are the changes I'm working on.
- Optional semicolons. Following the trend of many modern languages, new lines can be used in place of semicolons.
- Removal the 'var' type. This type never really made much use sense to me. It is functionally equivalent to 'sig' that is 32 bits wide.
- Replace the 'for' loop with a 'repeat' statement. This will likely have the syntax like "repeat(5: sig) { }" where "sig" would be assigned 0,1,2,3,4 depending on the iteration. For statements are kind of a weird thing to have in hardware since they must have a fixed number of iterations. The "C" style loop used currently and by Verilog is a bit cumbersome and can easily be written to not be a fixed number of iterations.
The rest of this post is the nitty gritty of the update.
The original Lucid parser has had feature after feature tacked on to where it is a bit of a mess today. Originally, it only attempted to figure out the width of signals. Then I added stuff that would parse constant expressions so custom functions could be added. Now I want a general interpreter that could be used to build a simulator. This was the motivation behind the full overhaul.
The original parser is broken into a handful of modules here https://github.com/alchitry/Alchitry-Lab...ools/lucid
The main parent is the LucidExtractor. This deals with all the declarations of stuff like modules, dffs, fsms, etc.
The BitWidthChecker attempts to figure out how wide each signal is. It is responsible for giving errors for situations like when you try to assign a struct to an array.
The ConstExprParser was original used to parse constant expressions for functions but has slowly outgrown that role to general expression parsing.
The BoundsParser parses array bounds (like [5:1] or [0+:3])
The ConstParser builds a list of constants declared
The ParamsParser builds a list of parameters declared
There are also a handful of other helper parsers like the LucidGlobalExtractor that parses globals in an initial pass of all the files.
These are all weirdly interdependent which is one of the goals to fix for the new parse.
Currently, the V2 parser handles expressions. I now need to add the rest (variable declarations, various block parsing, global statements, etc)
Its code can be found here https://github.com/alchitry/Alchitry-Lab...rs/lucidv2
The ExprParser is responsible for assigning a Value to every expression. This combines the functionality of the BitWidthChecker and ConstExprParser as these were often redundant. The Value type has an associated width to it and can be an UndefinedValue that still has a width which covers the cases that the BitWidthChecker used to deal with when ConstExprParser couldn't figure out a value.
I also plan to roll some of the small parsers into ExprParser such as BoundsParser (which I added today). Having multiple parsers that are interdependent makes using them difficult.