feat WIP: checkpoint initial efforts on stream extraction
Some checks failed
continuous-integration/drone/push Build is failing

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.
This commit is contained in:
Glen Whitney 2021-03-01 20:51:12 -08:00
parent cc89ad1e93
commit 7c69b82484
5 changed files with 49 additions and 1 deletions

View File

@ -42,10 +42,13 @@ context-free syntax
Ex.EscString = STRING Ex.EscString = STRING
Ex.Stream = <stream> Ex.Stream = <stream>
Ex.Sum = <<Ex> + <Ex>> {left} Ex.Sum = <<Ex> + <Ex>> {left}
Ex.Concat = <<Ex> ++ <Ex>> {left}
Ex.Gets = [[Ex] << [Ex]] {left} Ex.Gets = [[Ex] << [Ex]] {left}
Ex.DefGets = [<<< [Ex]] Ex.DefGets = [<<< [Ex]]
Ex.To = [[Ex] >> [Ex]] {left} Ex.To = [[Ex] >> [Ex]] {left}
Ex.DefTo = [[Ex] >>>] Ex.DefTo = [[Ex] >>>]
Ex.Emits = <<Ex>!>
Ex.DefEmits = <!!>
Ex = <(<Ex>)> {bracket} Ex = <(<Ex>)> {bracket}
@ -53,7 +56,7 @@ context-free priorities
Ex.To Ex.To
> Ex.DefTo > Ex.DefTo
> Ex.Sum > {Ex.Sum Ex.Concat}
> Ex.DefGets > Ex.DefGets
> Ex.Gets, > Ex.Gets,

View File

@ -294,3 +294,36 @@ test emit_several_default [[
]] parse succeeds ]] parse succeeds
/** writes /** writes
3399677527121313*/ 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.
**/

View File

@ -17,6 +17,7 @@ rules
defStream: DefGets(x) -> Gets(Stream(), x) defStream: DefGets(x) -> Gets(Stream(), x)
defStream: DefTo(x) -> To(x, Stream()) defStream: DefTo(x) -> To(x, Stream())
defStream: DefEmits() -> Emits(Stream())
strategies strategies

View File

@ -8,6 +8,8 @@ rules
def gets(self, v): def gets(self, v):
print(v, file=sys.stdout, end='') print(v, file=sys.stdout, end='')
return self return self
def emit(self):
return input()
def to(data,strm): def to(data,strm):
strm.gets(data) strm.gets(data)
return data return data
@ -21,8 +23,10 @@ rules
py: LitString(x) -> $[r[x]] py: LitString(x) -> $[r[x]]
py: EscString(x) -> x py: EscString(x) -> x
py: Sum(x,y) -> $[[x] + [y]] py: Sum(x,y) -> $[[x] + [y]]
py: Concat(x,y) -> $[[x] + [y]]
py: Gets(x, y) -> $[[x].gets([y])] py: Gets(x, y) -> $[[x].gets([y])]
py: To(x, y) -> $[to([x],[y])] py: To(x, y) -> $[to([x],[y])]
py: Emits(x) -> $[[x].emit()]
py: Terminate(x) -> $[[x];] py: Terminate(x) -> $[[x];]
py: Sequence(l) -> <join(|"\n")>l py: Sequence(l) -> <join(|"\n")>l

View File

@ -222,6 +222,13 @@ This pattern lets us specify error messages.
type_Ex(e2) == STREAM() | error $[Items may only be sent to Streams.]@e2. 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 /** md
``` ```