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
50 | If of exp * stm list * stm list option
51 | For of stm option * exp * stm option * stm list
52 | While of exp * stm list
53 | MarkedStm of stm Mark.marked
55 type program = stm list
57 (* print as source, with redundant parentheses *)
60 val pp_exp : exp -> string
61 val pp_stm : stm -> string
62 val pp_program : program -> string
67 structure Ast :> AST =
69 type ident = Symbol.symbol
77 | NEGATIVE (* unary minus *)
96 | ConstExp of Word32.word
97 | OpExp of oper * exp list
98 | Marked of exp Mark.marked
100 Assign of ident * exp
105 | If of exp * stm list * stm list option
106 | For of stm option * exp * stm option * stm list
107 | While of exp * stm list
108 | MarkedStm of stm Mark.marked
110 type program = stm list
112 (* print programs and expressions in source form
113 * using redundant parentheses to clarify precedence
117 fun pp_ident id = Symbol.name id
119 fun pp_oper PLUS = "+"
120 | pp_oper MINUS = "-"
121 | pp_oper TIMES = "*"
122 | pp_oper DIVIDEDBY = "/"
123 | pp_oper MODULO = "%"
124 | pp_oper NEGATIVE = "-"
127 | pp_oper LOGAND = "&&"
128 | pp_oper LOGOR = "||"
129 | pp_oper BITAND = "&"
130 | pp_oper BITXOR = "^"
131 | pp_oper BITOR = "|"
132 | pp_oper BITNOT = "~"
141 fun pp_exp (Var(id)) = pp_ident id
142 | pp_exp (ConstExp(c)) = Word32Signed.toString c
143 | pp_exp (OpExp(oper, [e])) =
144 pp_oper oper ^ "(" ^ pp_exp e ^ ")"
145 | pp_exp (OpExp(oper, [e1,e2])) =
146 "(" ^ pp_exp e1 ^ " " ^ pp_oper oper
147 ^ " " ^ pp_exp e2 ^ ")"
148 | pp_exp (OpExp(oper, _)) =
150 | pp_exp (Marked(marked_exp)) =
151 pp_exp (Mark.data marked_exp)
153 fun pp_stm (Assign (id,e)) =
154 pp_ident id ^ " = " ^ pp_exp e ^ ";"
155 | pp_stm (Return e) =
156 "return " ^ pp_exp e ^ ";"
158 | pp_stm Break = "break;"
159 | pp_stm Continue = "continue;"
160 | pp_stm (If (e, s, NONE)) = "if ("^pp_exp e^")"^pp_block s
161 | pp_stm (If (e, s, SOME s2)) = "if ("^pp_exp e^")"^pp_block s^" else "^pp_block s2
162 | pp_stm (While (e, s)) = "while ("^pp_exp e^") "^pp_block s
163 | 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 "") ^ ")" ^ pp_block s
164 | pp_stm (MarkedStm m) = pp_stm (Mark.data m)
166 and pp_block (nil) = ";"
167 | pp_block (a::nil) = pp_stm a
169 val contents = map pp_stm l
171 "{" ^ String.concat contents ^ "}"
175 | pp_stms (s::ss) = pp_stm s ^ "\n" ^ pp_stms ss
177 fun pp_program ss = "{\n" ^ pp_stms ss ^ "}"