feat: Allow expressions to be terminated/sequenced by ;
Some checks failed
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is failing

Note that ultimately a terminated sequence may have
   a slightly different semantics (applying streams
   to `_|_`, most likely) but for now they don't.
This commit is contained in:
Glen Whitney 2021-02-10 12:47:34 -08:00
parent 991976d3a8
commit b9c8532899
10 changed files with 156 additions and 65 deletions

View file

@ -9,6 +9,7 @@ imports
injections/-
libspoofax/term/origin
desugar
rules // Analysis
@ -19,7 +20,8 @@ rules // Analysis
// multi-file analysis
// editor-analyze = stx-editor-analyze(pre-analyze, post-analyze|"statics", "projectOk", "fileOk")
pre-analyze = origin-track-forced(explicate-injections-fostr-Start)
pre-analyze = desugar-fostr
; origin-track-forced(explicate-injections-fostr-Start)
post-analyze = origin-track-forced(implicate-injections-fostr-Start)
rules // Editor Services
@ -31,16 +33,21 @@ rules // Editor Services
rules // Debugging
// Prints the abstract syntax ATerm of a selection.
debug-show-aterm: (selected, _, _, path, project-path) -> (filename, result)
debug-show-aterm: (sel, _, _, path, projp) -> (filename, result)
with filename := <guarantee-extension(|"aterm")> path
; result := selected
; result := sel
// Prints the desugared abstract syntax ATerm of a selection.
debug-desugar-fostr: (sel, _, _, path, projp) -> (filename, result)
with filename := <guarantee-extension(|"desugared.aterm")> path
; result := <desugar-fostr> sel
// Prints the pre-analyzed abstract syntax ATerm of a selection.
debug-show-pre-analyzed: (selected, _, _, path, project-path) -> (filename, result)
debug-show-pre-analyzed: (sel, _, _, path, projp) -> (filename, result)
with filename := <guarantee-extension(|"pre-analyzed.aterm")> path
; result := <pre-analyze> selected
; result := <pre-analyze> sel
// Prints the analyzed annotated abstract syntax ATerm of a selection.
debug-show-analyzed: (selected, _, _, path, project-path) -> (filename, result)
debug-show-analyzed: (sel, _, _, path, projp) -> (filename, result)
with filename := <guarantee-extension(|"analyzed.aterm")> path
; result := selected
; result := sel

22
trans/desugar.str Normal file
View file

@ -0,0 +1,22 @@
module desugar
imports libstrategolib signatures/-
rules
/* ISequence() and Prior() are just noise for more expressions in sequence,
put in to get the layout rules right. So we remove them and collapse
all occurrence of them into one big Sequence() call on a list.
This is slightly tricky because there might not be any Sequence() call
at the top level, but yet an ISequence(). So we do it in two passes,
first converting ISequence()s to Sequence()s, and then collapsing
Sequence()s.
*/
deISe: ISequence(Prior(l),x) -> Sequence(<conc>(l, [x]))
enList: x -> [x]
seqFlatten: Sequence(l) -> Sequence(<mapconcat(?Sequence(<id>) <+ enList)>l)
strategies
desugar-fostr = bottomup(try(deISe <+ seqFlatten))

View file

@ -1,10 +1,5 @@
module haskell
imports libstrategolib signatures/- util
signature
constructors
TopLevel: Ex -> Ex
rules
/* Approach: Generate code from the bottom up.
At every node, we create a pair of the implementation and
@ -25,20 +20,20 @@ rules
main = do
[p]return [c]]
hs: Stream() -> ("StdIO", "")
hs: Int(x) -> (x, "")
hs: Stream() -> ("StdIO", "")
hs: Int(x) -> (x, "")
hs: Sum( (c, p), (d, q)) -> ($[([c] + [d])], <conc-strings>(p,q))
hs: Gets((c, p), (d, q)) -> <hsget>(c,d,<conc-strings>(p,q),<newname>"fosgt")
hs: Gets((c, p), (d, q)) -> <hsget>(c,d,<conc-strings>(p,q),<newname>"fosgt")
hsget: (s, x, p, v) -> (v, <concat-strings>[p, $[[v] <- [s] `gets` [x]],
"\n"])
hs: To( (c, p), (d, q)) -> <hsto>(c,d,<conc-strings>(p,q),<newname>"fosto")
hsto: (x, s, p, v) -> (v, <concat-strings>[p, $[let [v] = [x]], "\n",
$[[s] `gets` [v]], "\n"])
$[[s] `gets` [v]], "\n"])
hs: Sequence(l) -> (<last; Fst>l, <map(Snd); concat-strings>l)
hs: Terminate((c,p)) -> ($[[c];;], p)
hs: Sequence(l) -> (<last; Fst>l, <map(Snd); concat-strings>l)
strategies

View file

@ -1,10 +1,6 @@
module javascript
imports libstrategolib signatures/- util
signature
constructors
TopLevel: Ex -> Ex
rules
js: TopLevel(x) -> $[const Stdio = {
gets: v => { process.stdout.write(String(v)); return Stdio; },
@ -15,12 +11,13 @@ rules
}
[x]]
js: Stream() -> $[Stdio]
js: Int(x) -> x
js: Sum(x,y) -> $[[x] + [y]]
js: Gets(x, y) -> $[[x].gets([y])]
js: To(x, y) -> $[to([x],[y])]
js: Sequence(l) -> <join(|";\n")>l
js: Stream() -> $[Stdio]
js: Int(x) -> x
js: Sum(x,y) -> $[[x] + [y]]
js: Gets(x, y) -> $[[x].gets([y])]
js: To(x, y) -> $[to([x],[y])]
js: Terminate(x) -> x
js: Sequence(l) -> <join(|";\n")>l
strategies

View file

@ -1,10 +1,5 @@
module python
imports libstrategolib signatures/- util
signature
constructors
TopLevel: Ex -> Ex
rules
py: TopLevel(x) -> $[import sys
@ -18,12 +13,13 @@ rules
Stdio = StdioC()
[x]]
py: Stream() -> $[Stdio]
py: Int(x) -> x
py: Sum(x,y) -> $[[x] + [y]]
py: Gets(x, y) -> $[[x].gets([y])]
py: To(x, y) -> $[to([x],[y])]
py: Sequence(l) -> <join(|"\n")>l
py: Stream() -> $[Stdio]
py: Int(x) -> x
py: Sum(x,y) -> $[[x] + [y]]
py: Gets(x, y) -> $[[x].gets([y])]
py: To(x, y) -> $[to([x],[y])]
py: Terminate(x) -> $[[x];]
py: Sequence(l) -> <join(|"\n")>l
strategies