2 * Abstract Syntax Trees
3 * Author: Alex Vaynberg
4 * Modified: Frank Pfenning <fp@cs.cmu.edu>
5 * Modified: Joshua Wise <jwise@andrew.cmu.edu>
6 * Modified: Chris Lu <czl@andrew.cmu.edu>
8 * Uses pretty printing library
9 * structure PP -- see util/pp.sml
14 type ident = Symbol.symbol
22 | NEGATIVE (* unary minus *)
31 | BANG (* logical not *)
41 | ConstExp of Word32.word
42 | OpExp of oper * exp list
43 | Marked of (* Kane *) exp Mark.marked
44 | FuncCall of ident * (exp list)
45 | Member of exp * ident
46 | DerefMember of exp * ident
48 | ArrIndex of exp * exp
50 | NewArr of Type.vtype * exp
52 | Conditional of exp * exp * exp
55 | AsnOp of oper * exp * exp
56 | Effect of exp (* Just side effect the expression *)
61 | If of exp * stm list * stm list option
62 | For of stm option * exp * stm option * stm list
63 | While of exp * stm list
64 | MarkedStm of stm Mark.marked
67 Extern of Type.vtype * (Type.variable list)
68 | Function of Type.vtype * (Type.variable list) * (Type.variable list) * stm list
69 | MarkedFunction of function Mark.marked
71 type program = Type.typedef Symbol.table * function Symbol.table
73 (* print as source, with redundant parentheses *)
76 val pp_exp : exp -> string
77 val pp_stm : stm -> string
78 val pp_program : program -> string
82 structure Ast :> AST =
84 type ident = Symbol.symbol
92 | NEGATIVE (* unary minus *)
111 | ConstExp of Word32.word
112 | OpExp of oper * exp list
113 | Marked of exp Mark.marked
114 | FuncCall of ident * (exp list)
115 | Member of exp * ident
116 | DerefMember of exp * ident
118 | ArrIndex of exp * exp
120 | NewArr of Type.vtype * exp
122 | Conditional of exp * exp * exp
125 | AsnOp of oper * exp * exp
126 | Effect of exp (* Just side effect the expression *)
131 | If of exp * stm list * stm list option
132 | For of stm option * exp * stm option * stm list
133 | While of exp * stm list
134 | MarkedStm of stm Mark.marked
137 Extern of Type.vtype * (Type.variable list)
138 | Function of Type.vtype * (Type.variable list) * (Type.variable list) * stm list
139 | MarkedFunction of function Mark.marked
141 type program = Type.typedef Symbol.table * function Symbol.table
143 (* print programs and expressions in source form
144 * using redundant parentheses to clarify precedence
148 fun pp_ident id = Symbol.name id
150 fun pp_oper PLUS = "+"
151 | pp_oper MINUS = "-"
152 | pp_oper TIMES = "*"
153 | pp_oper DIVIDEDBY = "/"
154 | pp_oper MODULO = "%"
155 | pp_oper NEGATIVE = "-"
158 | pp_oper LOGAND = "&&"
159 | pp_oper LOGOR = "||"
160 | pp_oper BITAND = "&"
161 | pp_oper BITXOR = "^"
162 | pp_oper BITOR = "|"
163 | pp_oper BITNOT = "~"
172 fun pp_exp (Var(id)) = pp_ident id
173 | pp_exp (ConstExp(c)) = Word32Signed.toString c
174 | pp_exp (OpExp(oper, [e])) =
175 pp_oper oper ^ "(" ^ pp_exp e ^ ")"
176 | pp_exp (OpExp(oper, [e1,e2])) =
177 "(" ^ pp_exp e1 ^ " " ^ pp_oper oper
178 ^ " " ^ pp_exp e2 ^ ")"
179 | pp_exp (OpExp(oper, _)) =
181 | pp_exp (FuncCall(id, l)) = pp_ident id ^ "(" ^ pp_expl l ^ ")"
182 | pp_exp (Marked(marked_exp)) =
183 pp_exp (Mark.data marked_exp)
184 | pp_exp (Member(e, i)) = pp_exp e ^ "." ^ pp_ident i
185 | pp_exp (DerefMember(e, i)) = pp_exp e ^ "->" ^ pp_ident i
186 | pp_exp (Dereference(e)) = "*(" ^ pp_exp e ^ ")"
187 | pp_exp (ArrIndex(e1, e2)) = pp_exp e1 ^ "[" ^pp_exp e2 ^ "]"
188 | pp_exp (New t) = "new(" ^ Type.Print.pp_type t ^ ")"
189 | pp_exp (NewArr (t, s)) = "new(" ^ Type.Print.pp_type t ^ "[" ^ pp_exp s ^ "])"
190 | pp_exp Null = "NULL"
191 | pp_exp (Conditional (q, e1, e2)) = "("^(pp_exp q)^"?"^(pp_exp e1)^":"^(pp_exp e2)^")"
194 | pp_expl (e::a::l) = (pp_exp e) ^ ", " ^ (pp_expl (a::l))
195 | pp_expl (e::l) = (pp_exp e) ^ (pp_expl l)
197 and pp_stm (Assign (e1,e2)) =
198 pp_exp e1 ^ " = " ^ pp_exp e2 ^ ";\n"
199 | pp_stm (AsnOp (oop, e1, e2)) =
200 pp_exp e1 ^ " " ^ pp_oper oop ^ "= " ^ pp_exp e2 ^ ";\n"
201 | pp_stm (Effect (e)) =
203 | pp_stm (Return e) =
204 "return " ^ pp_exp e ^ ";\n"
206 | pp_stm Break = "break;\n"
207 | pp_stm Continue = "continue;\n"
208 | pp_stm (If (e, s, NONE)) = "if ("^pp_exp e^")\n"^pp_block s
209 | pp_stm (If (e, s, SOME s2)) = "if ("^pp_exp e^")\n"^pp_block s^"else\n"^pp_block s2
210 | pp_stm (While (e, s)) = "while ("^pp_exp e^")\n"^pp_block s
211 | pp_stm (For (so1, e, so2, s)) = "for ("^ (if (isSome so1) then pp_stm (valOf so1) else "") ^ pp_exp e ^ (if(isSome so2) then pp_stm (valOf so2) else "") ^ ")\n" ^ pp_block s
212 | pp_stm (MarkedStm m) = pp_stm (Mark.data m)
214 and pp_block (nil) = ";"
215 | pp_block (a::nil) = pp_stm a
217 val contents = map pp_stm l
219 "{\n" ^ String.concat contents ^ "}\n"
223 | pp_stms (s::ss) = pp_stm s ^ "\n" ^ pp_stms ss
225 and pp_params nil = ""
226 | pp_params ((i, t)::a::l) = (pp_ident i) ^ " : " ^ (Type.Print.pp_type t) ^ ", " ^ (pp_params (a::l))
227 | pp_params ((i, t)::l) = (pp_ident i) ^ " : " ^ (Type.Print.pp_type t) ^ (pp_params l)
230 | pp_vars ((i, t)::l) = "var " ^ (pp_ident i) ^ " : " ^ (Type.Print.pp_type t) ^ ";\n" ^ (pp_vars l)
232 and pp_function (n, Extern(t, pl)) = "extern " ^ (Type.Print.pp_type t) ^ " " ^ (pp_ident n) ^ "(" ^ (pp_params pl) ^ ");\n"
233 | pp_function (n, Function(t, pl, vl, stms)) = (Type.Print.pp_type t) ^ " " ^ (pp_ident n) ^ "(" ^ (pp_params pl) ^ ")\n{\n" ^ (pp_vars vl) ^ (String.concat (map pp_stm stms)) ^ "\n}\n"
234 | pp_function (n, MarkedFunction d) = pp_function (n, Mark.data d)
236 and pp_program (types, funs) = String.concat ((map Type.Print.pp_typedef (Symbol.elemsi types)) @ (map pp_function (Symbol.elemsi funs)))