feat: Add OCaml code generation
Some checks failed
continuous-integration/drone/push Build is failing
Some checks failed
continuous-integration/drone/push Build is failing
Also start using nailgun to speed up code generation. Resolves #6.
This commit is contained in:
parent
380177b274
commit
f789ed94fd
10 changed files with 128 additions and 4 deletions
|
@ -6,6 +6,7 @@ imports
|
|||
pp
|
||||
outline
|
||||
analysis
|
||||
ocaml
|
||||
haskell
|
||||
javascript
|
||||
python
|
||||
|
|
|
@ -10,7 +10,7 @@ rules
|
|||
rule.
|
||||
C) We will use bottomup-para to traverse the full AST with the
|
||||
transformation from A so that we have access to the original expression
|
||||
(and get get the Statix-associated type when we need to).
|
||||
(and can get the Statix-associated type when we need to).
|
||||
Hence the transformation in (A) must actually take a pair of
|
||||
an (original) term and a term with value strings at each child,
|
||||
and be certain to return a value string.
|
||||
|
|
61
trans/ocaml.str
Normal file
61
trans/ocaml.str
Normal file
|
@ -0,0 +1,61 @@
|
|||
module ocaml
|
||||
imports libstrategolib signatures/- util signature/TYPE analysis
|
||||
|
||||
/* Note will use bottomup-para to traverse the full AST so that
|
||||
we have access to the original expression (and can get the
|
||||
Statix-associated type when we need to).
|
||||
|
||||
This means that every one of our local rules must take a pair
|
||||
of an original term and a term with every child replaced by
|
||||
its generated code.
|
||||
*/
|
||||
|
||||
rules
|
||||
ml: (_, TopLevel(x)) -> $[(* fostr preamble *)
|
||||
type stream = { getS: string -> stream }
|
||||
let rec stdio = {
|
||||
getS = (fun s -> print_string s; stdio)
|
||||
};;
|
||||
(* End of preamble *)
|
||||
|
||||
[x]]
|
||||
|
||||
ml: (_, Stream()) -> $[stdio]
|
||||
ml: (_, Int(x)) -> x
|
||||
ml: (_, LitString(x)) -> $[{|[<un-single-quote>x]|}]
|
||||
ml: (_, EscString(x)) -> x
|
||||
ml: (_, Sum(x,y)) -> $[[x] + [y]]
|
||||
ml: (Gets(_,yn), Gets(x, y))
|
||||
-> $[([x]).getS ([<ml_str>(yn,y)])]
|
||||
ml: (To(xn,_), To(x, y))
|
||||
-> $[let _fto = ([x]) in (ignore (([y]).getS ([<ml_str>(xn,"_fto")])); _fto)]
|
||||
ml: (_, Terminate(x)) -> x
|
||||
ml: (_, Sequence(l)) -> <ml_seq>l
|
||||
|
||||
ml_seq: [x] -> x
|
||||
ml_seq: [x | xs ] -> $[ignore ([x]);
|
||||
[<ml_seq>xs]]
|
||||
|
||||
/* One drawback of using paramorphism is we have to handle lists
|
||||
explicitly:
|
||||
*/
|
||||
ml: (_, []) -> []
|
||||
ml: (_, [x | xs]) -> [x | xs]
|
||||
|
||||
/* Another drawback of using paramorphism is at the very leaves we have
|
||||
to undouble the tuple:
|
||||
*/
|
||||
ml: (x, x) -> x where <is-string>x
|
||||
|
||||
ml_str: (node, code) -> $[[<ml_string_cast>node]([code])]
|
||||
|
||||
strategies
|
||||
|
||||
ml_string_cast = get-type; (?INT() < !"string_of_int" + !"")
|
||||
|
||||
ocaml = bottomup-para(try(ml))
|
||||
|
||||
// Interface ocaml code generation with editor services and file system
|
||||
to-ocaml: (selected, _, _, path, project-path) -> (filename, result)
|
||||
with filename := <guarantee-extension(|"ml")> path
|
||||
; result := <ocaml> selected
|
Loading…
Add table
Add a link
Reference in a new issue