32 | 32 |
| main = 'Hello, world!'.
|
33 | 33 |
= Hello, world!
|
34 | 34 |
|
35 | |
Copy input to output, not unlike unix `cat`.
|
36 | |
|
37 | |
| main = T ← '' & {any → S & T ← T + S} & T.
|
38 | |
+ This file
|
39 | |
+ gets catted.
|
40 | |
= This file
|
41 | |
= gets catted.
|
42 | |
|
43 | |
Parse an algebraic expression for correctness.
|
44 | |
|
45 | |
| main = (expr0 & eof & 'ok').
|
46 | |
| expr0 = expr1 & {"+" & expr1}.
|
47 | |
| expr1 = term & {"*" & term}.
|
48 | |
| term = "x" | "y" | "z" | "(" & expr0 & ")".
|
49 | |
+ x+y*(z+x+y)
|
50 | |
= ok
|
51 | |
|
52 | |
| main = (expr0 & eof & 'ok').
|
53 | |
| expr0 = expr1 & {"+" & expr1}.
|
54 | |
| expr1 = term & {"*" & term}.
|
55 | |
| term = "x" | "y" | "z" | "(" & expr0 & ")".
|
56 | |
+ x+xy
|
57 | |
? expected EOF found 'y'
|
58 | |
|
59 | |
Parse an algebraic expression to a syntax tree.
|
60 | |
|
61 | |
| main = expr0.
|
62 | |
| expr0 = expr1 → E1 & {"+" & expr1 → E2 & E1 ← add(E1,E2)} & E1.
|
63 | |
| expr1 = term → E1 & {"*" & term → E2 & E1 ← mul(E1,E2)} & E1.
|
64 | |
| term = "x" | "y" | "z" | "(" & expr0 → E & ")" & E.
|
65 | |
+ x+y*(z+x+y)
|
66 | |
= add(x, mul(y, add(add(z, x), y)))
|
67 | |
|
68 | |
Translate an algebraic expression to RPN (Reverse Polish Notation).
|
69 | |
|
70 | |
| main = expr0 → E & walk(E).
|
71 | |
| expr0 = expr1 → E1 & {"+" & expr1 → E2 & E1 ← add(E1,E2)} & E1.
|
72 | |
| expr1 = term → E1 & {"*" & term → E2 & E1 ← mul(E1,E2)} & E1.
|
73 | |
| term = "x" | "y" | "z" | "(" & expr0 → E & ")" & E.
|
74 | |
| walk(add(L,R)) = walk(L) → LS & walk(R) → RS & return LS+RS+' +'.
|
75 | |
| walk(mul(L,R)) = walk(L) → LS & walk(R) → RS & return LS+RS+' *'.
|
76 | |
| walk(X) = return ' '+X.
|
77 | |
+ x+y*(z+x+y)
|
78 | |
= x y z x + y + * +
|
79 | |
|
80 | |
Make a story more exciting — a one-liner!
|
|
35 |
Make a story more exciting!
|
81 | 36 |
|
82 | 37 |
| main = S ← '' & {("." & '!' | "?" & '?!' | any) → C & S ← S + C} & S.
|
83 | 38 |
+ Chapter 1
|
|
90 | 45 |
= It was raining! She knocked on the door! She heard
|
91 | 46 |
= footsteps inside! The door opened! The butler peered
|
92 | 47 |
= out! "Hello," she said! "May I come in?!"
|
|
48 |
|
|
49 |
Parse an algebraic expression for syntactic correctness.
|
|
50 |
|
|
51 |
| main = (expr0 & eof & 'ok').
|
|
52 |
| expr0 = expr1 & {"+" & expr1}.
|
|
53 |
| expr1 = term & {"*" & term}.
|
|
54 |
| term = "x" | "y" | "z" | "(" & expr0 & ")".
|
|
55 |
+ x+y*(z+x+y)
|
|
56 |
= ok
|
|
57 |
|
|
58 |
Parse an algebraic expression to a syntax tree.
|
|
59 |
|
|
60 |
| main = expr0.
|
|
61 |
| expr0 = expr1 → E1 & {"+" & expr1 → E2 & E1 ← add(E1,E2)} & E1.
|
|
62 |
| expr1 = term → E1 & {"*" & term → E2 & E1 ← mul(E1,E2)} & E1.
|
|
63 |
| term = "x" | "y" | "z" | "(" & expr0 → E & ")" & E.
|
|
64 |
+ x+y*(z+x+y)
|
|
65 |
= add(x, mul(y, add(add(z, x), y)))
|
|
66 |
|
|
67 |
Translate an algebraic expression to RPN (Reverse Polish Notation).
|
|
68 |
|
|
69 |
| main = expr0 → E & walk(E).
|
|
70 |
| expr0 = expr1 → E1 & {"+" & expr1 → E2 & E1 ← add(E1,E2)} & E1.
|
|
71 |
| expr1 = term → E1 & {"*" & term → E2 & E1 ← mul(E1,E2)} & E1.
|
|
72 |
| term = "x" | "y" | "z" | "(" & expr0 → E & ")" & E.
|
|
73 |
| walk(add(L,R)) = walk(L) → LS & walk(R) → RS & return LS+RS+' +'.
|
|
74 |
| walk(mul(L,R)) = walk(L) → LS & walk(R) → RS & return LS+RS+' *'.
|
|
75 |
| walk(X) = return ' '+X.
|
|
76 |
+ x+y*(z+x+y)
|
|
77 |
= x y z x + y + * +
|
93 | 78 |
|
94 | 79 |
Reverse a list.
|
95 | 80 |
|
|
127 | 112 |
| extract(lines(Lines, Line)) = extract(Lines) & extract_field(Line).
|
128 | 113 |
| extract(L) = L.
|
129 | 114 |
| extract_field(fields(Last, fields(This, X))) = print This.
|
|
115 |
| extract_field(X) = return X.
|
130 | 116 |
+ Harold,1850,"21 Baxter Street",burgundy
|
131 | 117 |
+ Smythe,1833,"31 Little Street, St. James",mauve
|
132 | 118 |
+ Jones,1791,"41 ""The Gardens""",crimson
|
|
151 | 137 |
Quick Start
|
152 | 138 |
-----------
|
153 | 139 |
|
|
140 |
This repository contains the reference implementation of Tamsin, written in
|
|
141 |
Python. It can interpret a Tamsin program, and compile a program written
|
|
142 |
in (core) Tamsin to C. To start using it,
|
|
143 |
|
154 | 144 |
* Install [toolshelf](https://github.com/catseye/toolshelf).
|
155 | 145 |
* `toolshelf dock gh:catseye/tamsin`
|
156 | 146 |
|
157 | 147 |
Or just clone this repo and make a symbolic link to `bin/tamsin` somewhere
|
158 | 148 |
on your path (or alter your path to contain the `bin/` directory of this repo.)
|
|
149 |
|
|
150 |
Then you can run `tamsin` like so:
|
|
151 |
|
|
152 |
* `tamsin run eg/csv_extract.tamsin < eg/names.csv`
|
159 | 153 |
|
160 | 154 |
Design Goals
|
161 | 155 |
------------
|
|
167 | 161 |
parsing techniques.
|
168 | 162 |
* Provide means to solve practical problems.
|
169 | 163 |
* Keep the language simple (grammar should fit on a page)
|
170 | |
* Have a relatively simple reference implementation (currently ~1000 lines
|
171 | |
of Python, not counting debugging).
|
|
164 |
* Have a relatively simple reference implementation (currently ~1700 lines,
|
|
165 |
including everything — debugging and the C runtime used by the compiler.)
|
172 | 166 |
|
173 | 167 |
License
|
174 | 168 |
-------
|
|
185 | 179 |
* `bin/tamsin runast astfile.txt` -- for testing the meta-circular parser
|
186 | 180 |
* `bin/tamsin runscan scanfile.txt` -- for testing the meta-circular scanner
|
187 | 181 |
* `bin/tamsin scan file.tamsin` -- to generate a scanfile
|
188 | |
|
189 | |
### compiler ###
|
190 | |
|
191 | |
* refactor analyzer to find locals for each branch-prod
|
192 | |
* handle evaluation
|
|
182 |
* refactor nastier bits of the compiler
|
193 | 183 |
|
194 | 184 |
### document ###
|
195 | 185 |
|
|
216 | 206 |
expr1 = term → E & fold ("*" & term) E mul.
|
217 | 207 |
term = "x" | "y" | "z" | "(" & expr0 → E & ")" & E.
|
218 | 208 |
|
|
209 |
* auto-generate terms from productions, like Rooibos does
|
219 | 210 |
* `;` = `&`?
|
220 | 211 |
* pretty-print AST for error messages
|
221 | 212 |
* have analyzer, interpreter, compiler all inherit from ASTWalker or smth?
|