-
Notifications
You must be signed in to change notification settings - Fork 1
/
ast.ml
202 lines (170 loc) · 5.27 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
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
type op = Add | Sub | Mult | Div | Mod | Equal | Neq | Less | Leq | Greater | Geq | And | Or
type uop = Neg | Not
type prim_type =
Bool_Type
| Int_Type
| Pitch_Type
| String_Type
| Frac_Type
| Rhythm_Type
| Duration_Type
| PD_Type
| Chord_Type
| Track_Type
| Composition_Type
| Null_Type
type types =
Corgi_Prim of prim_type
type var = string * bool * prim_type
type expr =
Bool_Lit of bool
| Int_Lit of int
| String_Lit of string
| Frac_Lit of expr * expr (* int * int or Id's of type int *)
| Id of string
| Array_Lit of expr list
| Binop of expr * op * expr
| Unop of expr * uop
(* | Create of types * string * expr *)
| Call of string * expr list
| Access of string * expr
| Tuple of expr * expr
| Noexpr
type stmt =
Block of block
| Expr of expr
| Assign of string * expr
| Array_Assign of string * expr * expr
| Return of expr
| If of expr * block * block
| For of stmt * stmt * stmt * block
| While of expr * block
and block = {
locals : var list;
statements: stmt list;
block_id: int;
}
(*type variable = {
vname : string;
vtype : types;
vexpr : expr;
}*)
type parameter = {
pname : string;
ptype : prim_type;
}
type func = {
ret_type : prim_type;
fname : string;
formals : var list;
fblock : block;
}
type program = var list * func list
(* Added from Lorax *)
type scope_var_decl = string * bool * prim_type * int
type scope_func_decl = string * prim_type * prim_type list * int
type decl =
Func_Decl of scope_func_decl
| Var_Decl of scope_var_decl
let string_of_prim_type = function
Bool_Type -> "bool"
| Int_Type -> "int"
| Pitch_Type -> "pitch"
| String_Type -> "string"
| Frac_Type -> "frac"
| Rhythm_Type -> "rhythm"
| Duration_Type -> "duration"
| Chord_Type -> "chord"
| Track_Type -> "track"
| Composition_Type -> "composition"
| PD_Type -> "(pitch, duration)"
| Null_Type -> "null"
let string_of_types = function
Corgi_Prim(t) -> string_of_prim_type t
let string_of_unop = function
Neg -> "-"
| Not -> "!"
let string_of_binop = function
Add -> "+"
| Sub -> "-"
| Mult -> "*"
| Div -> "/"
| Mod -> "%"
| Equal -> "=="
| Neq -> "!="
| Less -> "<"
| Leq -> "<="
| Greater -> ">"
| Geq -> ">="
| And -> "&&"
| Or -> "||"
let rec string_of_expr = function
Bool_Lit(b) -> string_of_bool b
| Int_Lit(i) -> string_of_int i
| String_Lit(s) -> s
| Frac_Lit(n, d) -> "$" ^ string_of_expr n ^ "/" ^ string_of_expr d ^ "$"
| Array_Lit(e) -> String.concat ", " (List.map string_of_expr e)
| Id(s) -> s
| Access(ar, i) -> ar ^ "@" ^ string_of_expr i
| Binop(e1, o, e2) ->
string_of_expr e1 ^ " " ^
string_of_binop o ^ " " ^
string_of_expr e2
| Unop(e, o) ->
(match o with
Neg -> "-" ^ string_of_expr e
| Not -> "!" ^ string_of_expr e)
(* | Create(t, id, rhs) -> string_of_types t ^ " " ^ id ^ " = " ^ string_of_expr rhs *)
| Tuple(e1, e2) -> "(" ^ string_of_expr e1 ^ ", " ^ string_of_expr e2 ^ ")"
| Call(f, e) ->
f ^ "(" ^ String.concat ", " (List.map string_of_expr e) ^ ")"
| Noexpr -> ""
(* let string_of_elif (expr, stmt) =
"elif (" ^ string_of_expr expr ^ ") { \n" ^
string_of_stmt stmt ^ "\n}\n"
let string_of_elseifs elseifs =
String.concat "" (List.map (function(expr, stmt) -> string_of_expr expr ^ string_of_stmt stmt) elseifs) ^ "\n" *)
(*
let string_of_vdecl vdecl = string_of_types vdecl.vtype ^ " " ^ vdecl.vname ^
" = " ^ string_of_expr vdecl.vexpr ^ ";\n"
*)
let string_of_array_bool a =
if a then "[] " else ""
let string_of_vdecl v =
let (n, a, t) = v in
string_of_prim_type t ^ " " ^ string_of_array_bool a ^ n
let rec string_of_stmt = function
Block(b) -> string_of_block b
| Expr(expr) -> string_of_expr expr ^ ";\n";
| Assign(id, rhs) -> id ^ " = " ^ string_of_expr rhs ^ "; \n"
| Return(expr) -> "return " ^ string_of_expr expr ^ ";\n";
| If(e, b1, b2) ->
(match b2.statements with
[] -> "if (" ^ string_of_expr e ^ ")\n" ^ string_of_block b1
| _ -> "if (" ^ string_of_expr e ^ ")\n" ^
string_of_block b1 ^ "else\n" ^ string_of_block b2)
| For(a1, c, a2, b) ->
"for (" ^ string_of_stmt a1 ^ string_of_stmt c ^
string_of_stmt a2 ^ ") " ^ string_of_block b
| While(e, b) -> "while (" ^ string_of_expr e ^ ") " ^ string_of_block b
| Array_Assign (_, _, _) -> ""
and string_of_block (b:block) =
"{\n" ^
String.concat ";\n" (List.map string_of_vdecl b.locals) ^ (if (List.length b.locals) > 0 then ";\n" else "") ^
String.concat "" (List.map string_of_stmt b.statements) ^
"}\n"
let string_of_fdecl fdecl =
(string_of_prim_type fdecl.ret_type) ^ " " ^
fdecl.fname ^ "(" ^ String.concat ", " (List.map string_of_vdecl fdecl.formals) ^ ")\n" ^
string_of_block fdecl.fblock
(* need to rewrite *)
let string_of_decl = function
Var_Decl(n, a, t, id) -> string_of_vdecl (n, a, t)
| Func_Decl(n, t, f, id) ->
(string_of_prim_type t) ^ " " ^
n ^ "(" ^
String.concat ", " (List.map string_of_prim_type f) ^ ")"
(* ___________________________________ *)
let string_of_program (vars, funcs) =
String.concat "" (List.map string_of_vdecl (List.rev vars) ) ^ "\n" ^
String.concat "\n" (List.map string_of_fdecl (List.rev funcs) ) ^ "\n"