Skip to content

Conversation

@jauzatopauza
Copy link
Collaborator

A Fram backend that fits the new architecture.

I have added the directories test/sexpr and test/calc with 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?

- 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.
@ppolesiuk
Copy link
Member

ppolesiuk commented Dec 14, 2025

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 %{ import M %} doesn't work, since this code is appended after some generated preamble, that contains some definitions, but Fram requires that all imports must appear before definitions.

Copy link
Member

@ppolesiuk ppolesiuk left a 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).

Comment on lines +1 to +2
{# This file should be placed in the same directory as the generated
parser #}
Copy link
Member

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.

Comment on lines +4 to +8
pub data Pos = Pos of
{ fname : String
, lnum : Int
, bol : Int
, cnum : Int }
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. Fram supports record type. Mentioning the constructor name explicitly is not necessary.
  2. 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.
Suggested change
pub data Pos = Pos of
{ fname : String
, lnum : Int
, bol : Int
, cnum : Int }
pub data Pos =
{ fname : String
, lnum : Int
, bol : Int
, cnum : Int
}

Comment on lines +12 to +15
pub data Lex E Tok =
{ token : Unit ->[E] Tok
, startPos : Unit ->[E] Pos
, curPos : Unit -> [E] Pos }
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as above.

Suggested change
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
}

Comment on lines +26 to +27
parameter E_err
parameter ~error : Parsing.Error E_err
Copy link
Member

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).

Comment on lines +37 to +40
match ~loc with
| l :: _ => snd l
| [] => Parsing.dummyPos
end
Copy link
Member

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?

Suggested change
match ~loc with
| l :: _ => snd l
| [] => Parsing.dummyPos
end
match ~loc with
| l :: _ => snd l
| [] => Parsing.dummyPos
end

Comment on lines +85 to +87
let locReduce {E_err, E_lex,
~error : Parsing.Error E_err,
~lex : Parsing.Lex E_lex Tok} n =
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, code formatting.

Comment on lines +401 to +403
(* 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`. *)
Copy link
Member

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.

Comment on lines +6 to +21
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
Copy link
Member

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.

Comment on lines +5 to +8
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))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fix indentation.

Comment on lines +6 to +21
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
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fix indentation.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants