]> Joshua Wise's Git repositories - snipe.git/blob - parse/ast.sml
Initial import of l2c
[snipe.git] / parse / ast.sml
1 (* L2 Compiler
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>
7  *
8  * Uses pretty printing library
9  * structure PP  -- see util/pp.sml
10  *)
11
12 signature AST =
13 sig
14   type ident = Symbol.symbol
15
16   datatype oper = 
17      PLUS
18    | MINUS
19    | TIMES
20    | DIVIDEDBY
21    | MODULO
22    | NEGATIVE                   (* unary minus *)
23    | LSH
24    | RSH
25    | LOGOR
26    | LOGAND
27    | BITAND
28    | BITXOR
29    | BITOR
30    | BITNOT
31    | BANG                       (* logical not *)
32    | NEQ
33    | EQ
34    | LT
35    | LE
36    | GE
37    | GT
38
39   datatype exp =
40      Var of ident
41    | ConstExp of Word32.word
42    | OpExp of oper * exp list
43    | Marked of (* Kane *) exp Mark.marked
44   and stm =
45      Assign of ident * exp
46    | Return of exp
47    | Nop
48    | Break
49    | Continue
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
54
55   type program = stm list
56
57   (* print as source, with redundant parentheses *)
58   structure Print :
59   sig
60     val pp_exp : exp -> string
61     val pp_stm : stm -> string
62     val pp_program : program -> string
63   end
64
65 end
66
67 structure Ast :> AST =
68 struct
69   type ident = Symbol.symbol
70
71   datatype oper = 
72      PLUS
73    | MINUS
74    | TIMES
75    | DIVIDEDBY
76    | MODULO
77    | NEGATIVE                   (* unary minus *)
78    | LSH
79    | RSH
80    | LOGOR
81    | LOGAND
82    | BITAND
83    | BITXOR
84    | BITOR
85    | BITNOT
86    | BANG
87    | NEQ
88    | EQ
89    | LT
90    | LE
91    | GE
92    | GT
93
94   datatype exp =
95      Var of ident
96    | ConstExp of Word32.word
97    | OpExp of oper * exp list
98    | Marked of exp Mark.marked
99   and stm =
100      Assign of ident * exp
101    | Return of exp
102    | Nop
103    | Break
104    | Continue
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
109
110   type program = stm list
111
112   (* print programs and expressions in source form
113    * using redundant parentheses to clarify precedence
114    *)
115   structure Print =
116   struct
117     fun pp_ident id = Symbol.name id
118
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 = "-"
125       | pp_oper LSH = "<<"
126       | pp_oper RSH = ">>"
127       | pp_oper LOGAND = "&&"
128       | pp_oper LOGOR = "||"
129       | pp_oper BITAND = "&"
130       | pp_oper BITXOR = "^"
131       | pp_oper BITOR = "|"
132       | pp_oper BITNOT = "~"
133       | pp_oper BANG = "!"
134       | pp_oper NEQ = "!="
135       | pp_oper EQ = "=="
136       | pp_oper LT = "<"
137       | pp_oper LE = "<="
138       | pp_oper GT = ">"
139       | pp_oper GE = ">="
140
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, _)) =
149           pp_oper oper
150       | pp_exp (Marked(marked_exp)) =
151           pp_exp (Mark.data marked_exp)
152
153     fun pp_stm (Assign (id,e)) =
154         pp_ident id ^ " = " ^ pp_exp e ^ ";"
155       | pp_stm (Return e) =
156           "return " ^ pp_exp e ^ ";"
157       | pp_stm Nop = ";"
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)
165
166     and pp_block (nil) = ";"
167       | pp_block (a::nil) = pp_stm a
168       | pp_block (l) = let
169           val contents = map pp_stm l
170         in
171           "{" ^ String.concat contents ^ "}"
172         end
173
174     fun pp_stms nil = ""
175       | pp_stms (s::ss) = pp_stm s ^ "\n" ^ pp_stms ss
176
177     fun pp_program ss = "{\n" ^ pp_stms ss ^ "}"
178   end
179 end
This page took 0.037456 seconds and 4 git commands to generate.