-
Notifications
You must be signed in to change notification settings - Fork 19
/
Copy pathparser.ts
78 lines (74 loc) · 2.27 KB
/
parser.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
import {parser} from "lezer-python";
import {TreeCursor} from "lezer-tree";
import {Expr, Stmt} from "./ast";
export function traverseExpr(c : TreeCursor, s : string) : Expr {
switch(c.type.name) {
case "Number":
return {
tag: "num",
value: Number(s.substring(c.from, c.to))
}
case "VariableName":
return {
tag: "id",
name: s.substring(c.from, c.to)
}
case "CallExpression":
c.firstChild();
const callName = s.substring(c.from, c.to);
c.nextSibling(); // go to arglist
c.firstChild(); // go into arglist
c.nextSibling(); // find single argument in arglist
const arg = traverseExpr(c, s);
c.parent(); // pop arglist
c.parent(); // pop CallExpression
return {
tag: "builtin1",
name: callName,
arg: arg
};
default:
throw new Error("Could not parse expr at " + c.from + " " + c.to + ": " + s.substring(c.from, c.to));
}
}
export function traverseStmt(c : TreeCursor, s : string) : Stmt {
switch(c.node.type.name) {
case "AssignStatement":
c.firstChild(); // go to name
const name = s.substring(c.from, c.to);
c.nextSibling(); // go to equals
c.nextSibling(); // go to value
const value = traverseExpr(c, s);
c.parent();
return {
tag: "define",
name: name,
value: value
}
case "ExpressionStatement":
c.firstChild();
const expr = traverseExpr(c, s);
c.parent(); // pop going into stmt
return { tag: "expr", expr: expr }
default:
throw new Error("Could not parse stmt at " + c.node.from + " " + c.node.to + ": " + s.substring(c.from, c.to));
}
}
export function traverse(c : TreeCursor, s : string) : Array<Stmt> {
switch(c.node.type.name) {
case "Script":
const stmts = [];
c.firstChild();
do {
stmts.push(traverseStmt(c, s));
} while(c.nextSibling())
console.log("traversed " + stmts.length + " statements ", stmts, "stopped at " , c.node);
return stmts;
default:
throw new Error("Could not parse program at " + c.node.from + " " + c.node.to);
}
}
export function parse(source : string) : Array<Stmt> {
const t = parser.parse(source);
return traverse(t.cursor(), source);
}