forked from glen/fostr
feat: sequencing of expressions with newline to same indent
Also revised README to reflect greater emphasis on streams. Resolves #3.
This commit is contained in:
parent
c4d3f66c51
commit
5d81316ce2
10 changed files with 130 additions and 84 deletions
|
@ -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
|
||||
```
|
||||
**/
|
||||
|
|
|
@ -1 +1 @@
|
|||
stdio << 72 + 87 + 33
|
||||
stream << 72 + 87 + 33
|
||||
|
|
5
tests/emit_thrice.fos
Normal file
5
tests/emit_thrice.fos
Normal file
|
@ -0,0 +1,5 @@
|
|||
stream << 72 + 87
|
||||
stream << 88
|
||||
+ 96
|
||||
99 + 12 >>
|
||||
stream
|
Loading…
Add table
Add a link
Reference in a new issue