3 (* name := namespace * symbol *)
4 type name = (string * string) Node.t
5 type ident = string Node.t
7 (* expression has no side-effect. *)
10 | String of string Node.t
12 | Float of float Node.t
14 | Lambda of ident list * expr
16 | If of expr * expr * expr
17 | Let of (ident*expr) list * expr
18 | LetRec of (ident*expr) list * expr
20 | New of name * expr list
21 | Invoke of expr * ident * expr list (* (invoke <object> <method-name> <arg1> <arg2>...)*)
22 | SlotRef of expr * ident
23 | SlotSet of expr * ident * expr
25 (* statement has side-effect *)
27 type method_ = ident * ident list * expr
29 | Define of ident * expr
31 | Class of ident * name * attr list * method_ list
33 type program = stmt list
41 | Class (name,sname,attrs,body) ->
43 List.map (Tuple.T3.map3 f) body in
44 Class (name,sname,attrs,body')
46 let lift_program f = List.map (lift_stmt f)
52 Int _ | String _ | Bool _ | Float _ | Var _ ->
54 | Lambda (name,expr') ->
55 f @@ Lambda (name,(g expr'))
57 f @@ Call (List.map g exprs)
59 f @@ If ((g a),(g b),(g c))
62 List.map (fun (a,b)->(a,g b)) decl in
65 f @@ Let (decl',body')
66 | LetRec (decl,body) ->
68 List.map (fun (a,b)->(a,g b)) decl in
71 f @@ LetRec (decl',body')
73 f @@ Block (List.map g exprs')
75 f @@ New (name,List.map g args)
76 | Invoke (obj,name,args) ->
77 f @@ Invoke (g obj,name,List.map g args)
78 | SlotRef (obj,name) ->
79 f @@ SlotRef (g obj,name)
80 | SlotSet (obj,name,value) ->
81 f @@ SlotSet (g obj,name,g value)
86 Node.to_string (Printf.sprintf "Int %d") n
88 Node.to_string (Printf.sprintf "String %s") s
91 (fun b -> if true then "Bool true" else "Bool false")
94 Node.to_string (Printf.sprintf "Float %f") d
96 Node.to_string (Printf.sprintf "Var %s") n
97 | Lambda (args,expr') ->
98 Printf.sprintf "Lambda (%s,%s)"
99 (string_of_list @@ List.map (Node.to_string id) args)
102 Printf.sprintf "Call %s" @@
103 string_of_list @@ List.map to_string exprs
105 Printf.sprintf "If (%s,%s,%s)"
106 (to_string a) (to_string b) (to_string c)
110 List.map (fun (a,b)->
111 Printf.sprintf "(%s,%s)"
112 (Node.to_string id a)
113 (to_string b)) decl in
116 Printf.sprintf "Let (%s,%s)" decl' body'
117 | LetRec (decl,body) ->
120 List.map (fun (a,b)->
121 Printf.sprintf "(%s,%s)"
122 (Node.to_string id a)
123 (to_string b)) decl in
126 Printf.sprintf "LetRec (%s,%s)" decl' body'
128 Printf.sprintf "Block %s" @@ string_of_list @@
129 List.map to_string exprs
131 Printf.sprintf "New (%s,%s)"
132 (Node.to_string (fun (a,b) -> a ^ ":" ^ b) name) @@
133 string_of_list @@ List.map to_string args
134 | Invoke (obj,name,args) ->
135 Printf.sprintf "Invoke (%s,%s,%s)"
137 (Node.to_string id name) @@
138 string_of_list @@ List.map to_string args
139 | SlotRef (obj,name) ->
140 Printf.sprintf "SlotRef (%s,%s)"
141 (to_string obj) @@ Node.to_string id name
142 | SlotSet (obj,name,value) ->
143 Printf.sprintf "SlotSet (%s,%s,%s)"
145 (Node.to_string id name)
151 Printf.sprintf "Define (%s,%s)"
152 (Node.to_string id x) @@
155 Printf.sprintf "Expr (%s)" (to_string x)
156 | Class (name,sname,attrs,body) ->
157 Printf.sprintf "Class (%s,%s,%s,%s)"
158 (Node.to_string id name)
159 (Node.to_string (fun (a,b) -> a ^ ":" ^ b) sname)
160 (string_of_list @@ List.map (Node.to_string id) attrs)
161 @@ String.concat "\n"
162 @@ List.map (fun (name,args,expr) ->
163 Printf.sprintf "((%s %s) %s)"
164 (Node.to_string id name)
165 (String.concat " " @@
166 List.map (Node.to_string id) args)