From 7c69b82484fd4cae5b9b63b18a127b1c1be61a37 Mon Sep 17 00:00:00 2001 From: Glen Whitney Date: Mon, 1 Mar 2021 20:51:12 -0800 Subject: [PATCH] feat WIP: checkpoint initial efforts on stream extraction Adds ! operator and !! expression, with Python code gen and an item in tour. Still needs: other languages, check generated docs, and addition of standard input to test scheme. --- syntax/fostr.sdf3 | 5 ++++- tests/basic.spt | 33 +++++++++++++++++++++++++++++++++ trans/desugar.str | 1 + trans/python.str | 4 ++++ trans/statics.stx | 7 +++++++ 5 files changed, 49 insertions(+), 1 deletion(-) diff --git a/syntax/fostr.sdf3 b/syntax/fostr.sdf3 index 8624b58..f782466 100644 --- a/syntax/fostr.sdf3 +++ b/syntax/fostr.sdf3 @@ -42,10 +42,13 @@ context-free syntax Ex.EscString = STRING Ex.Stream = Ex.Sum = < + > {left} + Ex.Concat = < ++ > {left} Ex.Gets = [[Ex] << [Ex]] {left} Ex.DefGets = [<<< [Ex]] Ex.To = [[Ex] >> [Ex]] {left} Ex.DefTo = [[Ex] >>>] + Ex.Emits = <!> + Ex.DefEmits = Ex = <()> {bracket} @@ -53,7 +56,7 @@ context-free priorities Ex.To > Ex.DefTo - > Ex.Sum + > {Ex.Sum Ex.Concat} > Ex.DefGets > Ex.Gets, diff --git a/tests/basic.spt b/tests/basic.spt index a5e98c0..c6540b0 100644 --- a/tests/basic.spt +++ b/tests/basic.spt @@ -294,3 +294,36 @@ test emit_several_default [[ ]] parse succeeds /** writes 3399677527121313*/ + +/** md +### Streams are bidirectional + +So far we have only sent items to a stream. But we can extract them from +streams as well, with the `!` postfix operator. `!!` all by itself abbreviates +`stream!`, i.e., extraction from the standard stream. For example, + +```fostr +**/ + +/** md */ test custom_hw [[ +<<< "What is your name?\n" +<<< 'Hello, ' ++ !! +]] /* **/ +parse to TopLevel(Sequence([ + DefGets(EscString("\"What is your name?\n\"")), + DefGets(Concat(LitString("'Hello, '"),DefEmits())) +])) +/** accepts +Kilroy +**/ +/** writes +What is your name? +Hello, Kilroy**/ + +/** md +``` + +queries users for their name and then writes a customized greeting. It also +illustratesthe use of `++` for string concatenation, as opposed to `+` for +(numerical) addition. +**/ diff --git a/trans/desugar.str b/trans/desugar.str index 7276f38..b22ebd8 100644 --- a/trans/desugar.str +++ b/trans/desugar.str @@ -17,6 +17,7 @@ rules defStream: DefGets(x) -> Gets(Stream(), x) defStream: DefTo(x) -> To(x, Stream()) + defStream: DefEmits() -> Emits(Stream()) strategies diff --git a/trans/python.str b/trans/python.str index 6449417..a0a2ae7 100644 --- a/trans/python.str +++ b/trans/python.str @@ -8,6 +8,8 @@ rules def gets(self, v): print(v, file=sys.stdout, end='') return self + def emit(self): + return input() def to(data,strm): strm.gets(data) return data @@ -21,8 +23,10 @@ rules py: LitString(x) -> $[r[x]] py: EscString(x) -> x py: Sum(x,y) -> $[[x] + [y]] + py: Concat(x,y) -> $[[x] + [y]] py: Gets(x, y) -> $[[x].gets([y])] py: To(x, y) -> $[to([x],[y])] + py: Emits(x) -> $[[x].emit()] py: Terminate(x) -> $[[x];] py: Sequence(l) -> l diff --git a/trans/statics.stx b/trans/statics.stx index 340a1df..ce99bf7 100644 --- a/trans/statics.stx +++ b/trans/statics.stx @@ -222,6 +222,13 @@ This pattern lets us specify error messages. type_Ex(e2) == STREAM() | error $[Items may only be sent to Streams.]@e2. /* **/ + ty_Ex(Concat(e1, e2)) = STRING() :- + type_Ex(e1) == STRING() | error $[Expression [e1] not String in concat.]@e1, + type_Ex(e2) == STRING() | error $[Expression [e2] not String in concat.]@e2. + + ty_Ex(Emits(e)) = STRING() :- // At the moment, only stream is stdio + type_Ex(e) == STREAM() | error $[Only Streams may emit items.]@e. + /** md ```