git @ Cat's Eye Technologies Vinegar / aed635c
Put the literate tests inline in the language description. Chris Pressey 1 year, 10 months ago
3 changed file(s) with 68 addition(s) and 39 deletion(s). Raw diff Collapse all Expand all
9797
9898 (a | b) | c = a | (b | c) = a | b | c
9999
100 ### Similar things
101
100102 It's all a bit like `MonadPlus` in Haskell, with concatenation
101103 being a lot like `>=>`, although I really had `Either` more
102104 in mind than `Maybe`, but `Either` isn't an instance of
103105 `MonadPlus` for technical reasons, and I don't understand
104 monads anyway I'm sure.
106 monads anyway I'm sure. I'd explain further, but it's strictly
107 taboo -- I might start babbling about burritos, you see.
108
109 Probably a more familiar thing that it's similar to is the
110 Bourne shell. If `a` and `b` are executables, then `a && b`
111 executes `a` and checks the error code. If the error code is
112 non-zero, it exits with that exit code, otherwise it executes
113 `b` and exits with its exit code. Alternately, `a || b`
114 executes `a` and checks the error code. If the error code is
115 _zero_, it exits with that exit code, otherwise it executes
116 `b` and exits with its exit code.
105117
106118 ### The practical upshot of all this
107119
126138
127139 As an example, let's try to write a factorial function in Vinegar.
128140
141 Well, first, let's get some preliminaries out of the way. Up 'til
142 now we've been fairly vague about the actual language. Let's pin
143 down some concrete syntax.
144
145 -> Tests for functionality "Execute Vinegar Program"
146
147 -> Functionality "Execute Vinegar Program" is implemented by
148 -> shell command
149 -> "python3 bin/vinegar <%(test-body-file)"
150
151 Each definition is on its own line, which is terminated by
152 a semicolon. The result of executing a program, is the result
153 of executing `main`. The form `int[n]` where _n_ is a literal
154 integer in decimal notation, pushes _n_ onto the stack.
155
156 main = other;
157 other = int[3];
158 ==> OK([3])
159
160 There is a built-in operation to swap the top two values on the stack.
161
162 main = int[100] int[200] swap;
163 ==> OK([200, 100])
164
165 There is a built-in operation to pop the topmost value off the stack and
166 discard it.
167
168 main = int[40] int[50] pop int[60];
169 ==> OK([40, 60])
170
171 If there are not enough values on the stack for an operation, it fails
172 with underflow.
173
174 main = swap;
175 ==> Failure(underflow)
176
177 There is a built-in operation to pop the topmost two values and assert
178 that they are equal.
179
180 main = int[5] int[5] equal | int[4];
181 ==> OK([])
182
183 main = int[5] int[8] equal | int[4];
184 ==> OK([4])
185
186 OK, _now_ let's try to write a factorial function in Vinegar.
187
129188 fact = dup <1> gt! dup <1> sub fact mul | nop
130189
131190 What we have here is:
150209
151210 fact = dup <1> eq! | dup <1> sub fact mul
152211
212 (Here's that factorial in test form. I need to make the
213 syntax consistent, I know, sorry about that. Anyway:)
214
215 main = int[5] fact;
216 fact = dup int[1] equal | dup int[1] sub fact mul;
217 ==> OK([120])
218
153219 Now, we take the argument and assert that it *is* 1. If
154220 it is, we just return it. If not, we compute factorial
155221 on it, and return that. If anything in our factorial
+0
-37
Tests.md less more
0
1 -> Tests for functionality "Execute Vinegar Program"
2
3 -> Functionality "Execute Vinegar Program" is implemented by
4 -> shell command
5 -> "python3 bin/vinegar <%(test-body-file)"
6
7 Equal
8
9 main = int[5] int[5] equal | int[4];
10 ==> OK([])
11
12 Unequal
13
14 main = int[5] int[8] equal | int[4];
15 ==> OK([4])
16
17 Factorial
18
19 main = int[5] fact;
20 fact = dup int[1] equal | dup int[1] sub fact mul;
21 ==> OK([120])
22
23 Failure
24
25 main = swap;
26 ==> Failure(underflow)
27
28 Pop
29
30 main = int[40] int[50] pop int[60];
31 ==> OK([40, 60])
32
33 Swap
34
35 main = int[100] int[200] swap;
36 ==> OK([200, 100])
00 #!/bin/sh
11
2 falderal Tests.md
2 falderal README.md