3 module List = ListLabels
4 module String = StringLabels
6 module Sym = Tiger_symbol
7 module Pos = Tiger_position
41 { fields : (Sym.t * exp * Pos.t) list
65 ; escape : bool ref (* Whoa - why a mutable cell in AST? *)
102 | FunDecs of (* "FunctionDec" in Appel's code *)
106 ; escape : bool ref (* Again, why mutable? *)
107 ; typ : (Sym.t * Pos.t) option
111 | TypeDecs of (* "TypeDec" in Appel's code *)
132 | TypeDec of (* An anonymous record in Appel's code *)
140 ; params : field list
141 ; result : (Sym.t * Pos.t) option
148 let op_to_string = function
150 | MinusOp -> "MinusOp"
151 | TimesOp -> "TimesOp"
152 | DivideOp -> "DivideOp"
160 let xs_to_string ?(sep=", ") ~f xs =
161 xs |> List.map ~f |> String.concat ~sep
163 let field_to_string (Field {name; typ; _}) =
164 let name = Sym.to_string name in
165 let typ = Sym.to_string typ in
168 let fields_to_string fields =
169 xs_to_string fields ~f:field_to_string
170 let rec exp_to_string exp =
175 sprintf "IntExp[%d]" i
176 | StringExp {string; _} ->
177 sprintf "StringExp[%S]" string
178 | CallExp {func; args; _} ->
179 let func = Sym.to_string func in
180 let args = xs_to_string args ~f:exp_to_string in
181 sprintf "CallExp[%s, %s]" func args
182 | OpExp {left; oper; right; _} ->
183 let oper = op_to_string oper in
184 let left = exp_to_string left in
185 let right = exp_to_string right in
186 sprintf "OpExp[%s[%s, %s]]" oper left right
187 | RecordExp {fields; typ; _} ->
191 ~f:(fun (s, e, _) -> (Sym.to_string s) ^ " = " ^ (exp_to_string e))
193 let typ = Sym.to_string typ in
194 sprintf "RecordExp[%s, %s]" typ fields
197 |> List.map ~f:(fun (exp, _pos) -> exp)
198 |> xs_to_string ~f:exp_to_string
199 |> sprintf "SeqExp[%s]"
200 | AssignExp {var; exp; _} ->
201 let var = var_to_string var in
202 let exp = exp_to_string exp in
203 sprintf "AssignExp[%s, %s]" var exp
204 | IfExp {test; then'; else'; _} ->
205 let test = exp_to_string test in
206 let then' = exp_to_string then' in
208 | None -> sprintf "IfThen[%s, %s]" test then'
209 | Some e -> sprintf "IfThenElse[%s, %s, %s]" test then' (exp_to_string e)
211 | WhileExp {test; body; _} ->
212 let test = exp_to_string test in
213 let body = exp_to_string body in
214 sprintf "WhileExp[%s, %s]" test body
215 | ForExp {var; lo; hi; body; _} ->
217 "ForExp[ForVar[%S], ForLo[%s], ForHi[%s], ForBody[%s]]"
224 | LetExp {decs; body; _} ->
225 let decs = xs_to_string decs ~f:dec_to_string in
226 let body = exp_to_string body in
227 sprintf "LetExp[LetDecs[%s], LetIn[%s]]" decs body
228 | ArrayExp {typ; size; init; _} ->
229 let typ = Sym.to_string typ in
230 let size = exp_to_string size in
231 let init = exp_to_string init in
232 sprintf "ArrayExp[%s, %s, %s]" typ size init
234 sprintf "VarExp[%s]" (var_to_string var)
236 and var_to_string = function
237 | SimpleVar {symbol; _} ->
238 sprintf "SimpleVar[%s]" (Sym.to_string symbol)
239 | FieldVar {var; symbol; _} ->
240 sprintf "FieldVar[%s, %s]" (var_to_string var) (Sym.to_string symbol)
241 | SubscriptVar {var; exp; _} ->
242 sprintf "SubscriptVar[%s, %s]" (var_to_string var) (exp_to_string exp)
243 and dec_to_string = function
244 | VarDec {name; typ; init; _} ->
245 let name = Sym.to_string name in
246 let init = exp_to_string init in
249 let typ = Sym.to_string typ in
250 sprintf "VarDec[%s, %s, %s]" name typ init
252 sprintf "VarDec[%s, %s]" name init
254 | TypeDecs type_decs ->
255 sprintf "TypeDecs[%s]" (xs_to_string type_decs ~f:type_dec_to_string)
256 | FunDecs fun_decs ->
257 sprintf "FunDecs[%s]" (xs_to_string fun_decs ~f:fun_dec_to_string)
258 and fun_dec_to_string = function
259 | FunDec {name; params; body; _} ->
260 let name = Sym.to_string name in
261 let params = fields_to_string params in
262 let body = exp_to_string body in
263 sprintf "FunDec[%s, FunParams[%s], FunBody[%s]]" name params body
264 and type_dec_to_string = function
265 | TypeDec {name; ty; _} ->
266 sprintf "TypeDec[%s, %s]" (Sym.to_string name) (ty_to_string ty)
267 and ty_to_string = function
268 | NameTy {symbol; _} -> sprintf "NameTy[%s]" (Sym.to_string symbol)
269 | ArrayTy {symbol; _} -> sprintf "ArrayTy[%s]" (Sym.to_string symbol)
270 | RecordTy fields -> sprintf "RecordTy[%s]" (fields_to_string fields)
272 let to_string = exp_to_string