feat: Allow indented continuation lines

Resolves #2.
This commit is contained in:
Glen Whitney 2021-02-01 00:29:00 -08:00
parent 2e49065031
commit eaa06e62eb
9 changed files with 58 additions and 33 deletions

View File

@ -23,6 +23,8 @@ for path in TEST_LIST:
tests = re.split(r'test\s*(.+?)\s*\[\[.*?\n', contents)[1:] tests = re.split(r'test\s*(.+?)\s*\[\[.*?\n', contents)[1:]
testit = iter(tests) testit = iter(tests)
for name, details in zip(testit, testit): for name, details in zip(testit, testit):
pfm = re.search(r'\n\s*\]\].*?parse\s*fails', details)
if pfm: continue # skip examples that don't parse
em = re.search(r'\n\s*\]\]', details) em = re.search(r'\n\s*\]\]', details)
if not em: continue if not em: continue
example = details[:em.start()+1] example = details[:em.start()+1]

View File

@ -8,7 +8,7 @@ imports
language language
table : target/metaborg/sdf.tbl table : target/metaborg/sdf.tbl
start symbols : Ex start symbols : Start
line comment : "//" line comment : "//"
block comment : "/*" * "*/" block comment : "/*" * "*/"

View File

@ -6,14 +6,16 @@ imports
context-free start-symbols context-free start-symbols
Ex Start
context-free sorts context-free sorts
Ex Start Ex
context-free syntax context-free syntax
Start.TopLevel = prog:Ex {layout(offside prog)}
Ex.Int = INT Ex.Int = INT
Ex.Stdio = <stdio> Ex.Stdio = <stdio>
Ex.Sum = {Ex "+"}+ Ex.Sum = {Ex "+"}+

View File

@ -14,7 +14,8 @@ that writes the sum of the ASCII codes for 'H', 'W', and '!' to standard output:
/** md */ test emit_sum [[ /** md */ test emit_sum [[
stdio << 72 + 87 + 33 stdio << 72 + 87 + 33
]]/* **/ parse to Receives(Stdio(), Sum([Int("72"), Int("87"), Int("33")])) ]]/* **/ parse to TopLevel(Receives(Stdio(),
Sum([Int("72"), Int("87"), Int("33")])))
/** writes /** writes
192**/ 192**/
@ -62,9 +63,9 @@ left-associative, so that way we can chain insertions into a stream:
/** md */ test emit_twice [[ /** md */ test emit_twice [[
stdio << 72 + 87 + 33 << 291 stdio << 72 + 87 + 33 << 291
]]/* **/ parse to Receives( ]]/* **/ parse to TopLevel(
Receives(Stdio(), Sum([Int("72"), Int("87"), Int("33")])), Receives(Receives(Stdio(), Sum([Int("72"), Int("87"), Int("33")])),
Int("291")) Int("291")))
/** writes /** writes
192291**/ 192291**/
@ -80,25 +81,48 @@ with `>>`; both forms return the first argument:
/** md */ test enters_twice [[ /** md */ test enters_twice [[
(7 + 8 >> stdio + 9) >> stdio (7 + 8 >> stdio + 9) >> stdio
]]/* **/ parse to ]]/* **/ parse to TopLevel(
Enters(Sum([Int("7"), Enters(Int("8"), Stdio()), Int("9")]), Stdio()) Enters(Sum([Int("7"), Enters(Int("8"), Stdio()), Int("9")]), Stdio()))
/** writes /** writes
824**/ 824**/
/** md
```
### Layout in fostr
Expressions may be laid out onto multiple lines, as long as all continuation
lines are indented from the start of the initial line:
```fostr
**/
/** md */ test receive_enter_break [[
stdio <<
7
+ 8 >> stdio
+ 9
]]/* **/ parse to TopLevel(
Receives(Stdio(), Sum([Int("7"), Enters(Int("8"), Stdio()), Int("9")])))
/** writes
824**/
/** md
```
(So for example you will get a parse error with something like this:)
```fostr
**/
/** md */ test enter_receive_bad_break [[
(7 + 8 >> stdio + 9)
>> (stdio << 9 + 2)
]] /* **/ parse fails
/* Extra tests not in the tour */ /* Extra tests not in the tour */
test receive_enter [[
stdio << (7 + 8 >> stdio + 9)
]]/* **/ parse to
Receives(Stdio(), Sum([Int("7"), Enters(Int("8"), Stdio()), Int("9")]))
/** writes
824**/
test enter_receive [[ test enter_receive [[
(7 + 8 >> stdio + 9) >> (stdio << 9 + 2) (7 + 8 >> stdio + 9) >> (stdio << 9 + 2)
]]/* **/ parse to ]]/* **/ parse to TopLevel(
Enters(Sum([Int("7"),Enters(Int("8"),Stdio()),Int("9")]), Enters(Sum([Int("7"),Enters(Int("8"),Stdio()),Int("9")]),
Receives(Stdio(),Sum([Int("9"),Int("2")]))) Receives(Stdio(),Sum([Int("9"),Int("2")]))))
/** writes /** writes
81124**/ 81124**/

View File

@ -19,8 +19,8 @@ rules // Analysis
// multi-file analysis // multi-file analysis
// editor-analyze = stx-editor-analyze(pre-analyze, post-analyze|"statics", "projectOk", "fileOk") // editor-analyze = stx-editor-analyze(pre-analyze, post-analyze|"statics", "projectOk", "fileOk")
pre-analyze = origin-track-forced(explicate-injections-fostr-Ex) pre-analyze = origin-track-forced(explicate-injections-fostr-Start)
post-analyze = origin-track-forced(implicate-injections-fostr-Ex) post-analyze = origin-track-forced(implicate-injections-fostr-Start)
rules // Editor Services rules // Editor Services

View File

@ -42,8 +42,8 @@ rules
brack: x -> $<[<x>]> brack: x -> $<[<x>]>
strategies strategies
// wrap expression in a toplevel and then apply code generation
haskell = !TopLevel(<id>); bottomup(try(hs <+ hslist)) haskell = bottomup(try(hs <+ hslist))
// Interface haskell code generation with editor services and file system // Interface haskell code generation with editor services and file system
to-haskell: (selected, _, _, path, project-path) -> (filename, result) to-haskell: (selected, _, _, path, project-path) -> (filename, result)

View File

@ -24,8 +24,8 @@ rules
jslist: x -> $<[<<join(|", ")>x>]> jslist: x -> $<[<<join(|", ")>x>]>
strategies strategies
// wrap expression in a toplevel, then generate code from bottom up
javascript = !TopLevel(<id>); bottomup(try(js <+ jslist)) javascript = bottomup(try(js <+ jslist))
// Interface javascript code generation with editor services and file system // Interface javascript code generation with editor services and file system
to-javascript: (selected, _, _, path, project-path) -> (filename, result) to-javascript: (selected, _, _, path, project-path) -> (filename, result)

View File

@ -28,8 +28,7 @@ rules
strategies strategies
// wrap with a toplevel, then generate code from the bottom up python = bottomup(try(py <+ pylist))
python = !TopLevel(<id>); bottomup(try(py <+ pylist))
// Interface python code generation with editor services and file system // Interface python code generation with editor services and file system
to-python: (selected, _, _, path, project-path) -> (filename, result) to-python: (selected, _, _, path, project-path) -> (filename, result)

View File

@ -6,11 +6,9 @@ imports signatures/fostr-sig
rules // single-file entry point rules // single-file entry point
programOk : Ex programOk : Start
programOk(Sum(_)). programOk(TopLevel(_)).
programOk(Receives(_,_)).
programOk(Enters(_,_)).
rules // multi-file entry point rules // multi-file entry point
@ -18,6 +16,6 @@ rules // multi-file entry point
projectOk(s). projectOk(s).
fileOk : scope * Ex fileOk : scope * Start
fileOk(s, Receives(_,_)). fileOk(s, TopLevel(_)).