-
Notifications
You must be signed in to change notification settings - Fork 2
Fram backend #4
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Fram backend #4
Conversation
- Enabled Printer.ml to output Fram syntax. - Added a Fram code generation module. - Re-added tests from old Fram backend. Use test/sexpr to witness that something works. Effect reconstruction in test/calc still takes too long. - Re-added framtools with the Parsing module.
|
I tried to play with the Fram backend a bit. With the current implementation of effect inference, it requires ~10 minutes to type-check the generated parser of Lua, but I prepared an optimization #294 that shortens this time to around 5 seconds. I noticed one important issue with this backend that should be fixed: there is no way of importing a module from the generated code. The |
ppolesiuk
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changes looks good, and the solution seems to work. As noticed, there are performance issues with DBL, but with upcoming changes it should work fine. I have one major remark (related to import preamble), and several minor remarks related to code formatting (see below). Moreover, the code could be better documented (this remark concerns the whole CPSPG, but a one thousand miles journey begins with a single step).
| {# This file should be placed in the same directory as the generated | ||
| parser #} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is not necessary. This file could be a library, that is accessible through for the Fram compiler/interpreter. DBL supports -L flag.
| pub data Pos = Pos of | ||
| { fname : String | ||
| , lnum : Int | ||
| , bol : Int | ||
| , cnum : Int } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- Fram supports record type. Mentioning the constructor name explicitly is not necessary.
- Code formatting could be improved (closing brace in a new line, 2 space indentation) to match existing code base, as well as proposed coding style.
| pub data Pos = Pos of | |
| { fname : String | |
| , lnum : Int | |
| , bol : Int | |
| , cnum : Int } | |
| pub data Pos = | |
| { fname : String | |
| , lnum : Int | |
| , bol : Int | |
| , cnum : Int | |
| } |
| pub data Lex E Tok = | ||
| { token : Unit ->[E] Tok | ||
| , startPos : Unit ->[E] Pos | ||
| , curPos : Unit -> [E] Pos } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same as above.
| pub data Lex E Tok = | |
| { token : Unit ->[E] Tok | |
| , startPos : Unit ->[E] Pos | |
| , curPos : Unit -> [E] Pos } | |
| pub data Lex E Tok = | |
| { token : Unit ->[E] Tok | |
| , startPos : Unit ->[E] Pos | |
| , curPos : Unit -> [E] Pos | |
| } |
| parameter E_err | ||
| parameter ~error : Parsing.Error E_err |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The declaration of parameters should be moved somewhere below. The prelude should include only imports, so the user can provide own imports before the first definition (Fram requires that all imports are before definitions).
| match ~loc with | ||
| | l :: _ => snd l | ||
| | [] => Parsing.dummyPos | ||
| end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't we indent this code?
| match ~loc with | |
| | l :: _ => snd l | |
| | [] => Parsing.dummyPos | |
| end | |
| match ~loc with | |
| | l :: _ => snd l | |
| | [] => Parsing.dummyPos | |
| end |
| let locReduce {E_err, E_lex, | ||
| ~error : Parsing.Error E_err, | ||
| ~lex : Parsing.Lex E_lex Tok} n = |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, code formatting.
| (* We have no disjunctions of patterns yet. | ||
| For now, this function copies the same right-hand-side expression | ||
| for each left-hand-side pattern in `patterns`. *) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We have no or patterns yet, but hopefully, we would have them in the near future. See #287.
| pub let withFeeder {Tok} | ||
| (xs : List Tok) | ||
| (eof : Tok) | ||
| (f : {E} -> Parsing.Lex E Tok -> [E] _) = | ||
| handle lex = Parsing.Lex | ||
| { token = effect () / r => | ||
| fn ys => | ||
| match ys with | ||
| | [] => r eof ys | ||
| | y :: ys => r y ys | ||
| end | ||
| , curPos = effect () / r => fn ys => r Parsing.dummyPos ys | ||
| , startPos = effect () / r => fn ys => r Parsing.dummyPos ys } | ||
| return x => fn _ => x | ||
| finally f => f xs | ||
| in f lex |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In Fram, we use two-space indentation.
| if n == 0 then 1 | ||
| else if n == 1 then a | ||
| else (let (b : Int) = pow a (n / 2) in | ||
| b * b * (if n % 2 == 0 then 1 else a)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix indentation.
| pub let withFeeder {Tok} | ||
| (xs : List Tok) | ||
| (eof : Tok) | ||
| (f : {E} -> Parsing.Lex E Tok -> [E] _) = | ||
| handle lex = Parsing.Lex | ||
| { token = effect () / r => | ||
| fn ys => | ||
| match ys with | ||
| | [] => r eof ys | ||
| | y :: ys => r y ys | ||
| end | ||
| , curPos = effect () / r => fn ys => r Parsing.dummyPos ys | ||
| , startPos = effect () / r => fn ys => r Parsing.dummyPos ys } | ||
| return x => fn _ => x | ||
| finally f => f xs | ||
| in f lex |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix indentation.
A Fram backend that fits the new architecture.
I have added the directories
test/sexprandtest/calcwith some Fram tests. The duration of effect reconstruction in the latter remains very long.Another apparent issue is that the generated parsers often contain redundant pattern-matching cases. The OCaml parsers handle this by muting the warnings in their code. Have we got such a feature yet?