feat: sequencing of expressions with newline to same indent
Some checks failed
continuous-integration/drone/push Build is failing

Also revised README to reflect greater emphasis on streams.

  Resolves #3.
This commit is contained in:
Glen Whitney 2021-02-05 20:13:18 -08:00
parent c4d3f66c51
commit 5d81316ce2
10 changed files with 130 additions and 84 deletions

View file

@ -13,9 +13,9 @@ 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 TopLevel(Receives(Stdio(),
Sum([Int("72"), Int("87"), Int("33")])))
stream << 72 + 87 + 33
]]/* **/ parse to TopLevel(Gets(Stream(),
Sum(Sum(Int("72"), Int("87")), Int("33"))))
/** writes
192**/
@ -40,32 +40,27 @@ For example, this snippet generates the following Python:
start: 'Stdio\s='
!}
```
(which writes "192" to standard output), or this non-idiomatic, inefficient, but
working Javascript:
```javascript
{! ../tests/emit_sum.js extract:
start: '^}'
!}
```
In either case, there's also a preamble defining Stdio that's generated.
(Haskell code generation is also currently supported.)
(which writes "192" to standard output); it also generates identical code in
this simple example for
Javascript, although it generates a different preamble defining Stdio in each
case. (Haskell code generation is also currently supported.)
### Everything has a value
As mentioned in the [Introduction](../README.md), everything in a fostr
program (including the entire program itself) is an expression and has
a value. So what's the value of that expression above? Well, `stdio` is our
a value. So what's the value of that expression above? Well, appropriately
enough, `stream` is our
first example of a stream, and for convenience, the value of a stream
receiving an item is just the stream back again. The `<<` operator is also
left-associative, so that way we can chain insertions into a stream:
receiving an item is (usually) just the stream back again. The `<<` operator
is also left-associative, so that way we can chain insertions into a stream:
```fostr
**/
/** md */ test emit_twice [[
stdio << 72 + 87 + 33 << 291
stream << 72 + 87 + 33 << 291
]]/* **/ parse to TopLevel(
Receives(Receives(Stdio(), Sum([Int("72"), Int("87"), Int("33")])),
Int("291")))
Gets(Gets(Stream(), Sum(Sum(Int("72"), Int("87")), Int("33"))), Int("291")))
/** writes
192291**/
@ -75,14 +70,14 @@ Running this program produces a nice palindromic output: "192291".
And because sometimes you want to emphasize the value and propagate that
instead of the stream, you can also write these expressions "the other way"
with `>>`; both forms return the first argument:
with `>>`; both forms return the first argument, so the following writes "824":
```fostr
**/
/** md */ test enters_twice [[
(7 + 8 >> stdio + 9) >> stdio
(7 + 8 >> stream + 9) >> stream
]]/* **/ parse to TopLevel(
Enters(Sum([Int("7"), Enters(Int("8"), Stdio()), Int("9")]), Stdio()))
To(Sum(Sum(Int("7"), To(Int("8"), Stream())), Int("9")), Stream()))
/** writes
824**/
@ -97,12 +92,12 @@ lines are indented from the start of the initial line:
**/
/** md */ test receive_enter_break [[
stdio <<
stream <<
7
+ 8 >> stdio
+ 8 >> stream
+ 9
]]/* **/ parse to TopLevel(
Receives(Stdio(), Sum([Int("7"), Enters(Int("8"), Stdio()), Int("9")])))
Gets(Stream(), Sum(Sum(Int("7"), To(Int("8"), Stream())), Int("9"))))
/** writes
824**/
@ -113,19 +108,56 @@ stdio <<
**/
/** md */ test enter_receive_bad_break [[
(7 + 8 >> stdio + 9)
>> (stdio << 9 + 2)
(7 + 8 >> stream + 9)
>> (stream << 9 + 2)
]] /* **/ parse fails
/* Extra tests not in the tour */
test enter_receive [[
(7 + 8 >> stdio + 9) >> (stdio << 9 + 2)
(7 + 8 >> stream + 9) >> (stream << 9 + 2)
]]/* **/ parse to TopLevel(
Enters(Sum([Int("7"),Enters(Int("8"),Stdio()),Int("9")]),
Receives(Stdio(),Sum([Int("9"),Int("2")]))))
To(Sum(Sum(Int("7"),To(Int("8"),Stream())),Int("9")),
Gets(Stream(),Sum(Int("9"),Int("2")))))
/** writes
81124**/
/** md
```
Of course, fostr programs are not limited to one line; expressions on successive
lines are evaluated in sequence. For example, the program
```fostr
**/
/** md */ test emit_thrice [[
stream << 72 + 87
stream << 88
+ 96
99 + 12 >>
stream
]] /* **/ parse to TopLevel( Sequence(
[ Gets(Stream(), Sum(Int("72"), Int("87")))
, Gets(Stream(), Sum(Int("88"), Int("96")))
, Sum(Int("99"), To(Int("12"), Stream()))]))
/** writes
15918412**/
/** md
```
will write 15918412. fostr enforces that successive expressions in sequence
must line up at the left, i.e., the following will not parse:
```fostr
**/
/** md */ test emit_thrice_bad_alignment [[
stream << 72 + 87
stream << 88
+ 96
99 + 12 >> stream
]] /* **/ parse fails
/** md
```
**/

View file

@ -1 +1 @@
stdio << 72 + 87 + 33
stream << 72 + 87 + 33

5
tests/emit_thrice.fos Normal file
View file

@ -0,0 +1,5 @@
stream << 72 + 87
stream << 88
+ 96
99 + 12 >>
stream