From eaa06e62ebb64d46d4fad14628239472db597376 Mon Sep 17 00:00:00 2001 From: Glen Whitney Date: Mon, 1 Feb 2021 00:29:00 -0800 Subject: [PATCH] feat: Allow indented continuation lines Resolves #2. --- bin/extract_tests.xsh | 2 ++ editor/Syntax.esv | 2 +- syntax/fostr.sdf3 | 6 +++-- tests/basic.spt | 56 ++++++++++++++++++++++++++++++------------- trans/analysis.str | 4 ++-- trans/haskell.str | 4 ++-- trans/javascript.str | 4 ++-- trans/python.str | 3 +-- trans/statics.stx | 10 ++++---- 9 files changed, 58 insertions(+), 33 deletions(-) diff --git a/bin/extract_tests.xsh b/bin/extract_tests.xsh index 40ead93..38edb7f 100644 --- a/bin/extract_tests.xsh +++ b/bin/extract_tests.xsh @@ -23,6 +23,8 @@ for path in TEST_LIST: tests = re.split(r'test\s*(.+?)\s*\[\[.*?\n', contents)[1:] testit = iter(tests) 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) if not em: continue example = details[:em.start()+1] diff --git a/editor/Syntax.esv b/editor/Syntax.esv index e8e0e23..aad195c 100644 --- a/editor/Syntax.esv +++ b/editor/Syntax.esv @@ -8,7 +8,7 @@ imports language table : target/metaborg/sdf.tbl - start symbols : Ex + start symbols : Start line comment : "//" block comment : "/*" * "*/" diff --git a/syntax/fostr.sdf3 b/syntax/fostr.sdf3 index b454b2f..aa1b048 100644 --- a/syntax/fostr.sdf3 +++ b/syntax/fostr.sdf3 @@ -6,14 +6,16 @@ imports context-free start-symbols - Ex + Start context-free sorts - Ex + Start Ex context-free syntax + Start.TopLevel = prog:Ex {layout(offside prog)} + Ex.Int = INT Ex.Stdio = Ex.Sum = {Ex "+"}+ diff --git a/tests/basic.spt b/tests/basic.spt index 9b00d89..24b9b54 100644 --- a/tests/basic.spt +++ b/tests/basic.spt @@ -14,7 +14,8 @@ that writes the sum of the ASCII codes for 'H', 'W', and '!' to standard output: /** md */ test emit_sum [[ 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 192**/ @@ -62,9 +63,9 @@ left-associative, so that way we can chain insertions into a stream: /** md */ test emit_twice [[ stdio << 72 + 87 + 33 << 291 -]]/* **/ parse to Receives( - Receives(Stdio(), Sum([Int("72"), Int("87"), Int("33")])), - Int("291")) +]]/* **/ parse to TopLevel( + Receives(Receives(Stdio(), Sum([Int("72"), Int("87"), Int("33")])), + Int("291"))) /** writes 192291**/ @@ -80,25 +81,48 @@ with `>>`; both forms return the first argument: /** md */ test enters_twice [[ (7 + 8 >> stdio + 9) >> stdio -]]/* **/ parse to - Enters(Sum([Int("7"), Enters(Int("8"), Stdio()), Int("9")]), Stdio()) +]]/* **/ parse to TopLevel( + Enters(Sum([Int("7"), Enters(Int("8"), Stdio()), Int("9")]), Stdio())) /** writes 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 */ - -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 [[ (7 + 8 >> stdio + 9) >> (stdio << 9 + 2) -]]/* **/ parse to +]]/* **/ parse to TopLevel( 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 81124**/ diff --git a/trans/analysis.str b/trans/analysis.str index a28f21a..265f53e 100644 --- a/trans/analysis.str +++ b/trans/analysis.str @@ -19,8 +19,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-Ex) - post-analyze = origin-track-forced(implicate-injections-fostr-Ex) + pre-analyze = origin-track-forced(explicate-injections-fostr-Start) + post-analyze = origin-track-forced(implicate-injections-fostr-Start) rules // Editor Services diff --git a/trans/haskell.str b/trans/haskell.str index 028a7bd..f5fc7e7 100644 --- a/trans/haskell.str +++ b/trans/haskell.str @@ -42,8 +42,8 @@ rules brack: x -> $<[]> strategies - // wrap expression in a toplevel and then apply code generation - haskell = !TopLevel(); bottomup(try(hs <+ hslist)) + + haskell = bottomup(try(hs <+ hslist)) // Interface haskell code generation with editor services and file system to-haskell: (selected, _, _, path, project-path) -> (filename, result) diff --git a/trans/javascript.str b/trans/javascript.str index 398c29e..fe88092 100644 --- a/trans/javascript.str +++ b/trans/javascript.str @@ -24,8 +24,8 @@ rules jslist: x -> $<[<x>]> strategies - // wrap expression in a toplevel, then generate code from bottom up - javascript = !TopLevel(); bottomup(try(js <+ jslist)) + + javascript = bottomup(try(js <+ jslist)) // Interface javascript code generation with editor services and file system to-javascript: (selected, _, _, path, project-path) -> (filename, result) diff --git a/trans/python.str b/trans/python.str index 85b845b..f9f1972 100644 --- a/trans/python.str +++ b/trans/python.str @@ -28,8 +28,7 @@ rules strategies - // wrap with a toplevel, then generate code from the bottom up - python = !TopLevel(); bottomup(try(py <+ pylist)) + python = bottomup(try(py <+ pylist)) // Interface python code generation with editor services and file system to-python: (selected, _, _, path, project-path) -> (filename, result) diff --git a/trans/statics.stx b/trans/statics.stx index fcd0c7f..7772698 100644 --- a/trans/statics.stx +++ b/trans/statics.stx @@ -6,11 +6,9 @@ imports signatures/fostr-sig rules // single-file entry point - programOk : Ex + programOk : Start - programOk(Sum(_)). - programOk(Receives(_,_)). - programOk(Enters(_,_)). + programOk(TopLevel(_)). rules // multi-file entry point @@ -18,6 +16,6 @@ rules // multi-file entry point projectOk(s). - fileOk : scope * Ex + fileOk : scope * Start - fileOk(s, Receives(_,_)). + fileOk(s, TopLevel(_)).