-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathfj_ir.ml
More file actions
executable file
·274 lines (246 loc) · 6.59 KB
/
fj_ir.ml
File metadata and controls
executable file
·274 lines (246 loc) · 6.59 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
(*
* FJava intermediate representation.
*
* ----------------------------------------------------------------
*
* Copyright (C) Kai Chen
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*)
open Symbol
open Field_table
(*
* A variable is just a symbol.
*)
type var = symbol
type ty_var = symbol
(*
* Types.
*)
type ty =
(* Basic types *)
| TyUnit
| TyNil
| TyBool
| TyChar
| TyString
| TyInt
| TyFloat
(* Arrays of values, all elements have the same type *)
| TyArray of ty
(* Functions have a list of types for the arguments, and a result type *)
| TyFun of ty list * ty
(* A method has a "this" type, some args, and a result *)
| TyMethod of (ty * ty list * ty)
(* TyObject is an instance of a class *)
| TyObject of ty_var
(*
* A class has:
*
* A parent class. Only the built-in FjObject class
* does not have a parent.
*
* A list of interfaces. This includes all the
* interfaces, including those defined by the parent.
*
*
* An initialization function. This is a function
* that sets the initial values for the fields.
*
* A set of constructors.
*
* The method and field lists hold _all_ of the methods
* and fields, including those defined by the parent.
*)
type class_info =
{ class_parents : var list;
class_consts : (var * ty) list;
class_methods : ty FieldMTable.t;
class_fields : ty FieldMTable.t;
}
(*
* Typedefs are used to define classes and types
* at the program level.
*)
type tydef =
TyDefClass of class_info option
(*
* Unary operators.
*)
type unop =
(* Arithmetic *)
UMinusIntOp
| UMinusFloatOp
| UNotIntOp
| UNotBoolOp
(* Numeric coercions *)
| UIntOfFloat
| UFloatOfInt
| UCharOfInt
| UIntOfChar
(*
* Binary operators.
*)
type binop =
(* Integers *)
AddIntOp
| SubIntOp
| MulIntOp
| DivIntOp
| RemIntOp
| AndIntOp
| OrIntOp
| LslIntOp (* Logical shift left << *)
| LsrIntOp (* Logical shift right >> *)
| AsrIntOp (* Arithmetic shift right >>> *)
| XorIntOp
| EqIntOp
| NeqIntOp
| LeIntOp
| LtIntOp
| GtIntOp
| GeIntOp
(* Floats *)
| AddFloatOp
| SubFloatOp
| MulFloatOp
| DivFloatOp
| RemFloatOp
| EqFloatOp
| NeqFloatOp
| LeFloatOp
| LtFloatOp
| GtFloatOp
| GeFloatOp
(* Bools *)
| EqBoolOp
| NeqBoolOp
(*
* Values.
*)
type atom =
AtomUnit
| AtomNil
| AtomBool of bool
| AtomChar of char
| AtomInt of int
| AtomFloat of float
| AtomVar of var
(*
* Function classes:
* FunGlobalClass: any user-defined function that is not a method (not
* necessarily with global scope)
* FunLocalClass: local (compiler-defined) function
*
* Note that return statements are associated with global/method functions,
* never with local functions.
*)
type fun_class =
FunGlobalClass
| FunMethodClass
| FunLocalClass
(*
* Intermediate code expressions.
*)
type exp =
(* Mutually recursive function definitions. They are in scope for each
function's body and the duration of exp. *)
LetFuns of fundef list * exp
(* Arithmetic *)
(* Functional Variable/atom creation (non-destructive) *)
| LetVar of var * ty * atom * exp
| LetAtom of var * ty * atom * exp
| LetUnop of var * ty * unop * atom * exp
| LetBinop of var * ty * binop * atom * atom * exp
(* Functions *)
(* let v1 : ty = v2(a1, ..., aN) in exp *)
| LetApply of var * ty * var * atom list * exp
(* You pass the pointer to self explicitly when calling a method:
let v1 : ty = v2[a_this](a1, ..., aN) in exp *)
| LetApplyMethod of var * ty * var * atom * atom list * exp
(* External functions need to have their types explicitly annotated.
let v1 : ty1 = External_fun["f_name", ext_fun_ty](a1, ... , aN) in exp *)
| LetExt of var * ty * string * ty * atom list * exp
| TailCall of var * atom list
(* var = the function being returned from. atom = value returned *)
| Return of var * atom
(* Conditional *)
| IfThenElse of atom * exp * exp
(* Exception handling *)
(* if e1 throws an exception, bind it to var and execute e2 *)
| Try of exp * var * exp
| Raise of atom
(* TypeCase is like a bunch of if/then/else statements for switching based on
the run-time type of an object:
if a instanceof ty_var_1 then
let var_1 : ty_var_1 = a in exp_1
else if a instanceof ty_var_2 then
...
else
exp (* The last exp, outside of the list *)
*)
| TypeCase of atom * (ty_var * var * exp) list * exp
(* Destructive (non-functional) variable assignment
v : ty <- a; exp *)
| SetVar of var * ty * atom * exp
(* Array/pointer operations *)
(* a1[a2] : ty <- a3; exp *)
| SetSubscript of atom * atom * ty * atom * exp
(* let v : ty = a1[a2] in exp *)
| LetSubscript of var * ty * atom * atom * exp
(* Record projection *)
(* a1.var : ty <- a2; exp *)
| SetProject of atom * var * ty * atom * exp
(* let v1 : ty = a.v2 in exp *)
| LetProject of var * ty * atom * var * exp
(* Allocation *)
| LetString of var * string * exp
(* atom list is list of array dimensions. Other atom is the value to
initialize the array elements with *)
| LetArray of var * ty * atom list * atom * exp
(* let v1 : ty = new v2 in exp *)
| LetObject of var * ty * ty_var * exp
(*
* A function definition has:
* 1. a function classification (global, method, or local)
* 2. the function type
* 3. then formal parameters
* 4. the body
*)
and fundef = var * fun_info
and fun_info = fun_class * ty * var list * exp
(*
* A program has the following parts:
* prog_types: type definitions
* prog_abstypes: abstract type identifiers
* prog_funs: a set of function definitions
* prog_main: the name of the main function
* prog_object: the name of the FjObject type
*)
type prog =
{ prog_types : tydef SymbolTable.t;
prog_abstypes : SymbolSet.t;
prog_funs : fun_info SymbolTable.t;
prog_main : var;
prog_object : var
}
(*
* -*-
* Local Variables:
* Caml-master: "compile"
* End:
* -*-
*)