-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathast.ml
140 lines (123 loc) · 4.61 KB
/
ast.ml
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
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
(* Abstract Syntax Tree and functions for printing it *)
type op = Add | Sub | Mult | Div | Mod | Equal | Neq | Less | Leq | Greater | Geq |
And | Or | Incr | Decr
type uop = Neg | Not
type typ = Num | Int | String | Bool | Void | AnyType | NumberType |
Arraytype of typ * int | QueueType of typ | LinkedListType of typ |
StackType of typ | BSTreeType of typ
type bind = typ * string
type expr =
NumLit of float
| IntLit of int
| StringLit of string
| BoolLit of bool
| Null
| Id of string
| Binop of expr * op * expr
| Unop of uop * expr
| Postop of expr * op
| Assign of typ * string * expr
| Reassign of string * expr
| FuncCall of string * expr list
| QueueLit of typ * expr list
| BSTreeLit of typ * expr list
| LinkedListLit of typ * expr list
| StackLit of typ * expr list
| ObjectCall of expr * string * expr list
| Noexpr
| ArrayLit of expr list
| ArrayAccess of string * expr
| ArrayElementAssign of string * expr * expr
type stmt =
Block of stmt list
| Expr of expr
| Return of expr
| If of expr * stmt * stmt
| For of expr * expr * expr * stmt
| While of expr * stmt
type func_decl = {
typ : typ;
fname : string;
formals : bind list;
body : stmt list;
}
type program = func_decl list
(* Pretty-printing functions *)
let string_of_op = function
Add -> "+"
| Sub -> "-"
| Mult -> "*"
| Div -> "/"
| Mod -> "%"
| Equal -> "=="
| Neq -> "!="
| Less -> "<"
| Leq -> "<="
| Greater -> ">"
| Geq -> ">="
| And -> "and"
| Or -> "or"
| Incr -> "++"
| Decr -> "--"
let string_of_uop = function
Neg -> "-"
| Not -> "not"
let rec string_of_typ = function
Num -> "num"
| Int -> "int"
| String -> "string"
| Bool -> "bool"
| Void -> "void"
| Arraytype(typ, len) -> string_of_typ typ ^ "[" ^ string_of_int len ^ "]"
| QueueType(typ) -> "Queue " ^ string_of_typ typ
| BSTreeType(typ) -> "BSTree " ^ string_of_typ typ
| LinkedListType(typ) -> "LinkedList " ^ string_of_typ typ
| StackType(typ) -> "Stack " ^ string_of_typ typ
| AnyType -> "AnyType"
| NumberType -> "NumberType"
let rec string_of_expr = function
StringLit(s) -> s
| NumLit(f) -> string_of_float f
| IntLit(i) -> string_of_int i
| BoolLit(true) -> "true"
| BoolLit(false) -> "false"
| Null -> "null"
| Id(s) -> s
| Binop(e1, o, e2) ->
string_of_expr e1 ^ " " ^ string_of_op o ^ " " ^ string_of_expr e2
| Unop(o, e) -> string_of_uop o ^ string_of_expr e
| Postop(e, o) -> string_of_expr e ^ string_of_op o
| Assign(t, v, e) -> string_of_typ t ^ " " ^ v ^ " = " ^ string_of_expr e
| Reassign(v, e) -> v ^ "=" ^ string_of_expr e
| FuncCall(f, el) ->
f ^ "(" ^ String.concat ", " (List.map string_of_expr el) ^ ")"
| ObjectCall(o, f, e1) -> string_of_expr o ^ "." ^ f ^ "(" ^ String.concat ", " (List.map string_of_expr e1) ^ ")"
| ArrayLit a -> "[" ^ String.concat " " (List.map string_of_expr a) ^ "]"
| ArrayAccess(v, i) -> v ^ "[" ^ string_of_expr i ^ "]"
| ArrayElementAssign(s, i, e) -> s ^ "[" ^ string_of_expr i ^ "]" ^ " = " ^ string_of_expr e
| Noexpr -> ""
| QueueLit(typ, e1) -> "new " ^ "Queue" ^ "::" ^ string_of_typ typ ^ "(" ^ String.concat ", " (List.map string_of_expr e1) ^ ")"
| LinkedListLit(typ, e1) -> "new " ^ "LinkedList" ^ "::" ^ string_of_typ typ ^ "(" ^ String.concat ", " (List.map string_of_expr e1) ^ ")"
| BSTreeLit(typ, e1) -> "new " ^ "BSTree" ^ "::" ^ string_of_typ typ ^ "(" ^ String.concat ", " (List.map string_of_expr e1) ^ ")"
| StackLit(typ, e1) -> "new " ^ "Stack" ^ "::" ^ string_of_typ typ ^ "(" ^ String.concat ", " (List.map string_of_expr e1) ^ ")"
let rec string_of_stmt = function
Block(stmts) ->
"{\n" ^ String.concat "" (List.map string_of_stmt stmts) ^ "}\n"
| Expr(expr) -> string_of_expr expr ^ ";\n";
| Return(expr) -> "return " ^ string_of_expr expr ^ ";\n";
| If(e, s, Block([])) -> "if (" ^ string_of_expr e ^ ")\n" ^ string_of_stmt s
| If(e, s1, s2) -> "if (" ^ string_of_expr e ^ ")\n" ^
string_of_stmt s1 ^ "else\n" ^ string_of_stmt s2
| For(e1, e2, e3, s) ->
"for (" ^ string_of_expr e1 ^ " ; " ^ string_of_expr e2 ^ " ; " ^
string_of_expr e3 ^ ") " ^ string_of_stmt s
| While(e, s) -> "while (" ^ string_of_expr e ^ ") " ^ string_of_stmt s
let string_of_vdecl (t, id) = string_of_typ t ^ " " ^ id ^ ";\n"
let string_of_fdecl fdecl =
string_of_typ fdecl.typ ^ " " ^
fdecl.fname ^ "(" ^ String.concat ", " (List.map snd fdecl.formals) ^
")\n{\n" ^
String.concat "" (List.map string_of_stmt fdecl.body) ^
"}\n"
let string_of_program (funcs) =
String.concat "\n" (List.map string_of_fdecl funcs)