forked from ucsd-cse231-w21/chocopy-wasm-compiler
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathast.ts
53 lines (41 loc) · 2.12 KB
/
ast.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
// import { TypeCheckError } from "./type-check";
// export enum Type {NUM, BOOL, NONE, OBJ};
export type Type =
| {tag: "number"}
| {tag: "bool"}
| {tag: "none"}
| {tag: "class", name: string}
export type Parameter<A> = { name: string, type: Type }
export type Program<A> = { a?: A, funs: Array<FunDef<A>>, inits: Array<VarInit<A>>, classes: Array<Class<A>>, stmts: Array<Stmt<A>> }
export type Class<A> = { a?: A, name: string, fields: Array<VarInit<A>>, methods: Array<FunDef<A>>}
export type VarInit<A> = { a?: A, name: string, type: Type, value: Literal }
export type FunDef<A> = { a?: A, name: string, parameters: Array<Parameter<A>>, ret: Type, inits: Array<VarInit<A>>, body: Array<Stmt<A>> }
export type Stmt<A> =
| { a?: A, tag: "assign", name: string, value: Expr<A> }
| { a?: A, tag: "return", value: Expr<A> }
| { a?: A, tag: "expr", expr: Expr<A> }
| { a?: A, tag: "if", cond: Expr<A>, thn: Array<Stmt<A>>, els: Array<Stmt<A>> }
| { a?: A, tag: "while", cond: Expr<A>, body: Array<Stmt<A>> }
| { a?: A, tag: "pass" }
| { a?: A, tag: "field-assign", obj: Expr<A>, field: string, value: Expr<A> }
export type Expr<A> =
{ a?: A, tag: "literal", value: Literal }
| { a?: A, tag: "id", name: string }
| { a?: A, tag: "binop", op: BinOp, left: Expr<A>, right: Expr<A>}
| { a?: A, tag: "uniop", op: UniOp, expr: Expr<A> }
| { a?: A, tag: "builtin1", name: string, arg: Expr<A> }
| { a?: A, tag: "builtin2", name: string, left: Expr<A>, right: Expr<A>}
| { a?: A, tag: "call", name: string, arguments: Array<Expr<A>> }
| { a?: A, tag: "lookup", obj: Expr<A>, field: string }
| { a?: A, tag: "method-call", obj: Expr<A>, method: string, arguments: Array<Expr<A>> }
| { a?: A, tag: "construct", name: string }
export type Literal =
{ tag: "num", value: number }
| { tag: "bool", value: boolean }
| { tag: "none" }
// TODO: should we split up arithmetic ops from bool ops?
export enum BinOp { Plus, Minus, Mul, IDiv, Mod, Eq, Neq, Lte, Gte, Lt, Gt, Is, And, Or};
export enum UniOp { Neg, Not };
export type Value =
Literal
| { tag: "object", name: string, address: number}