Moving right along... start on the analyzer-in-Tamsin.
--HG--
rename : eg/tamsin-desugarer.tamsin => lib/tamsin_analyzer.tamsin
Cat's Eye Technologies
11 years ago
0 | 0 | TODO |
1 | 1 | ---- |
2 | ||
3 | * tamsin_analyzer.tamsin | |
4 | * finish implementing compiler (to C) for a subset of Tamsin, in Tamsin — | |
5 | get it to compile at least one Tamsin program | |
6 | ||
7 | ### escaping ### | |
2 | 8 | |
3 | 9 | * unescape scanned atoms/""'s in tamsin_parser -- `$:unescape`? |
4 | 10 | * `$:unescape` must support \xXX codes |
6 | 12 | * __str__ should be Tamsin repr()? |
7 | 13 | * `$:substr` and/or `$:atom_to_list` |
8 | 14 | * should not really need `$:substr` if we implement `@`... just parse it! |
9 | * finish implementing compiler (to C) for a subset of Tamsin, in Tamsin | |
10 | * `$:alpha` | |
11 | * `$:digit` | |
12 | * remove `$.alnum`? | |
13 | 15 | * scanner should probably not be responsible for escaping characters; |
14 | 16 | the token `"\n"` should turn into the term whose repr is `'"\\n"'`. |
15 | 17 | ("scanner sanity") (belay this, document it) |
16 | * tamsin_analyzer.tamsin | |
17 | 18 | |
18 | 19 | ### testing ### |
19 | 20 | |
22 | 23 | * tests for failing when utf8 scanner hits badly-encoded utf8 |
23 | 24 | * test that `$:alpha` and `$:digit` are not locale-dependent (hard) |
24 | 25 | |
25 | ### lower-priority ### | |
26 | ### vm ### | |
26 | 27 | |
28 | * `$:alpha` | |
29 | * `$:digit` | |
27 | 30 | * `$:add`, `$:sub`, `$:mul`, `$:div`, `$:rem`, for atoms which look like |
28 | 31 | integers: `["-"] & {$:digit}`. |
29 | 32 | * `$:tell` and `$:seek` the implicit buffer -- for VM's etc -- although |
30 | 33 | note, this may have scary consequences when combined with backtracking |
31 | 34 | * non-backtracking versions of `|` and `{}`: `|!` and `{}!` |
35 | ||
36 | ### lower-priority ### | |
37 | ||
32 | 38 | * `$:deep_reverse` |
33 | 39 | * find different way to match variables in libtamsin, so that |
34 | 40 | struct term's can be const all the way down — then share terms |
0 | main = tamsin_parser:parse → AST & {" " | "\n" } & eof & | |
1 | tamsin_analyzer:desugar(AST) → AST & | |
2 | tamsin_analyzer:analyze(AST) → AST & | |
3 | $:repr(AST). |
0 | main = tamsin_parser:parse → AST & {" " | "\n" } & eof & | |
1 | tamsin_analyzer:desugar(AST) → AST & | |
2 | $:repr(AST). |
0 | # Desugarer for Tamsin AST, written in Tamsin. | |
1 | # Distributed under a BSD-style license; see LICENSE. | |
2 | ||
3 | # REQUIRES lib/tamsin_scanner.tamsin | |
4 | # REQUIRES lib/tamsin_parser.tamsin | |
5 | ||
6 | # Note that this may contain support for some features which are not in | |
7 | # the current released or pre-released version. | |
8 | ||
9 | main = tamsin_parser:parse → AST & {" " | "\n" } & eof & | |
10 | desugar(AST) → AST & $:repr(AST). | |
11 | ||
12 | desugar_all(list(H,T)) = | |
13 | desugar(H) → DH & | |
14 | desugar_all(T) → DT & | |
15 | return list(DH, DT). | |
16 | desugar_all(nil) = 'nil'. | |
17 | ||
18 | desugar(program(L)) = desugar_all(L) → DL & return program(DL). | |
19 | desugar(module(N, L)) = desugar_all(L) → DL & return module(N, DL). | |
20 | desugar(production(N, F, E, Ps)) = desugar(E) → DE & return production(N, F, DE, Ps). | |
21 | desugar(or(L, R)) = desugar(L) → DL & desugar(R) → DR & return or(DL, DR). | |
22 | desugar(and(L, R)) = desugar(L) → DL & desugar(R) → DR & return and(DL, DR). | |
23 | desugar(not(X)) = desugar(X) → DX & return not(DX). | |
24 | desugar(while(X)) = desugar(X) → DX & return while(DX). | |
25 | desugar(concat(L, R)) = desugar(L) → DL & desugar(R) → DR & return concat(DL, DR). | |
26 | desugar(using(R, P)) = desugar(R) → DR & return using(DR, P). | |
27 | ||
28 | desugar(send(R, V)) = desugar(R) → DR & return send(DR, V). | |
29 | desugar(set(V, T)) = desugar(T) → DT & return set(V, DT). | |
30 | ||
31 | desugar(fold(R, I)) = | |
32 | desugar(R) → DR & | |
33 | SET ← set(term('_1'), I) & | |
34 | SEND ← send(DR, term('_2')) & | |
35 | CAT ← concat(term('_1'), term('_2')) & | |
36 | ACC ← set(term('_1'), CAT) & | |
37 | RET ← call(prodref('$', 'return'), list(term('_1'), nil)) & | |
38 | return and(and(SET, while(and(SEND, ACC))), RET). | |
39 | ||
40 | desugar(Else) = Else. | |
41 |
0 | # Desugarer for Tamsin AST, written in Tamsin. | |
1 | # Distributed under a BSD-style license; see LICENSE. | |
2 | ||
3 | tamsin_analyzer { | |
4 | ||
5 | desugar_all(list(H,T)) = | |
6 | desugar(H) → DH & | |
7 | desugar_all(T) → DT & | |
8 | return list(DH, DT). | |
9 | desugar_all(nil) = 'nil'. | |
10 | ||
11 | desugar(program(L)) = desugar_all(L) → DL & return program(DL). | |
12 | desugar(module(N, L)) = desugar_all(L) → DL & return module(N, DL). | |
13 | desugar(production(N, F, E, Ps)) = desugar(E) → DE & return production(N, F, DE, Ps). | |
14 | desugar(call(PR, Args)) = return call(PR, Args). | |
15 | desugar(or(L, R)) = desugar(L) → DL & desugar(R) → DR & return or(DL, DR). | |
16 | desugar(and(L, R)) = desugar(L) → DL & desugar(R) → DR & return and(DL, DR). | |
17 | desugar(not(X)) = desugar(X) → DX & return not(DX). | |
18 | desugar(while(X)) = desugar(X) → DX & return while(DX). | |
19 | desugar(concat(L, R)) = desugar(L) → DL & desugar(R) → DR & return concat(DL, DR). | |
20 | desugar(using(R, P)) = desugar(R) → DR & return using(DR, P). | |
21 | desugar(send(R, V)) = desugar(R) → DR & return send(DR, V). | |
22 | desugar(set(V, T)) = desugar(T) → DT & return set(V, DT). | |
23 | desugar(term(T)) = return term(T). | |
24 | desugar(fold(R, I)) = | |
25 | desugar(R) → DR & | |
26 | SET ← set(term('_1'), I) & | |
27 | SEND ← send(DR, term('_2')) & | |
28 | CAT ← concat(term('_1'), term('_2')) & | |
29 | ACC ← set(term('_1'), CAT) & | |
30 | RET ← call(prodref('$', 'return'), list(term('_1'), nil)) & | |
31 | return and(and(SET, while(and(SEND, ACC))), RET). | |
32 | ||
33 | analyze_all(list(H,T)) = | |
34 | analyze(H) → DH & | |
35 | analyze_all(T) → DT & | |
36 | return list(DH, DT). | |
37 | analyze_all(nil) = 'nil'. | |
38 | ||
39 | analyze(program(L)) = analyze_all(L) → DL & return program(DL). | |
40 | analyze(module(N, L)) = analyze_all(L) → DL & return module(N, DL). | |
41 | analyze(production(N, F, E, Ps)) = analyze(E) → DE & return production(N, F, DE, Ps). | |
42 | analyze(call(PR, Args)) = return call(PR, Args). | |
43 | analyze(or(L, R)) = analyze(L) → DL & analyze(R) → DR & return or(DL, DR). | |
44 | analyze(and(L, R)) = analyze(L) → DL & analyze(R) → DR & return and(DL, DR). | |
45 | analyze(not(X)) = analyze(X) → DX & return not(DX). | |
46 | analyze(while(X)) = analyze(X) → DX & return while(DX). | |
47 | analyze(concat(L, R)) = analyze(L) → DL & analyze(R) → DR & return concat(DL, DR). | |
48 | analyze(using(R, P)) = analyze(R) → DR & return using(DR, P). | |
49 | analyze(send(R, V)) = analyze(R) → DR & return send(DR, V). | |
50 | analyze(set(V, T)) = analyze(T) → DT & return set(V, DT). | |
51 | analyze(term(T)) = return term(T). | |
52 | } |
88 | 88 | bin/tamsin desugar $EG > 1.txt |
89 | 89 | bin/tamsin lib/tamsin_scanner.tamsin \ |
90 | 90 | lib/tamsin_parser.tamsin \ |
91 | eg/tamsin-desugarer.tamsin <$EG > 2.txt || exit 1 | |
91 | lib/tamsin_analyzer.tamsin \ | |
92 | eg/tamsin-desugarer-driver.tamsin <$EG > 2.txt || exit 1 | |
92 | 93 | diff -ru 1.txt 2.txt > ast.diff |
93 | 94 | diff -ru 1.txt 2.txt || exit 1 |
94 | 95 | done |
97 | 98 | ./build.sh |
98 | 99 | bin/tamsin compile lib/tamsin_scanner.tamsin \ |
99 | 100 | lib/tamsin_parser.tamsin \ |
100 | eg/tamsin-desugarer.tamsin > foo.c && \ | |
101 | lib/tamsin_analyzer.tamsin \ | |
102 | eg/tamsin-desugarer-driver.tamsin > foo.c && \ | |
101 | 103 | gcc -g -Ic_src -Lc_src foo.c -o tamsin-desugarer -ltamsin || exit 1 |
102 | 104 | for EG in eg/*.tamsin; do |
103 | 105 | echo $EG |