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)))