85 |
| PT.E_Norm of expr |
| PT.E_Norm of expr |
86 |
(* end case *)) |
(* end case *)) |
87 |
|
|
88 |
|
fun checkVarDecl (env, cxt, kind, d) = (case d |
89 |
|
of PT.VD_Mark m => checkVarDecl (env, #span m, kind, #tree m) |
90 |
|
| PT.VD_Decl(ty, x, e) => let |
91 |
|
val ty = checkType ty |
92 |
|
val x' = Var.new (x, kind, ty) |
93 |
|
val (e', ty') = checkExpr (env, cxt, e) |
94 |
|
in |
95 |
|
(* FIXME: check types *) |
96 |
|
AST.VD_Decl(x', e') |
97 |
|
end |
98 |
|
(* end case *)) |
99 |
|
|
100 |
(* typecheck a statement and translate it to AST *) |
(* typecheck a statement and translate it to AST *) |
101 |
fun checkStmt (env, cxt, s) = (case s |
fun checkStmt (env, cxt, s) = (case s |
102 |
of PT.S_Mark m => checkStmt (env, #span m, #tree m) |
of PT.S_Mark m => checkStmt (env, #span m, #tree m) |
103 |
| PT.S_Block of stmt list |
| PT.S_Block stms => let |
104 |
| PT.S_Decl of var_decl |
fun chk (_, [], stms) = AST.S_Block(List.rev stms) |
105 |
| PT.S_IfThen of expr * stmt |
| chk (env, s::ss, stms) = let |
106 |
| PT.S_IfThenElse of expr * stmt * stmt |
val (s', env') = checkStmt (env, cxt, s) |
107 |
| PT.S_Assign of var * expr |
in |
108 |
| PT.S_New of var * expr list |
chk (env', ss, s'::ss) |
109 |
| PT.S_Die |
end |
110 |
| PT.S_Stabilize |
in |
111 |
|
(chk (env, stms, []), env) |
112 |
|
end |
113 |
|
| PT.S_Decl vd => let |
114 |
|
val vd as AST.VD_Decl(x, _) = checkVarDecl (env, cxt, Var.LocalVar, vd) |
115 |
|
in |
116 |
|
(AST.S_Decl vd, Env.insertLocal(env, x, x')) |
117 |
|
end |
118 |
|
| PT.S_IfThen(e, s) => let |
119 |
|
val (e', ty) = checkExpr (env, cxt, e) |
120 |
|
val s' = checkStmt (env, cxt, s) |
121 |
|
in |
122 |
|
(* check that condition has bool type *) |
123 |
|
case ty |
124 |
|
of Ty.T_Bool => () |
125 |
|
| _ => raise Fail "condition not boolean type" |
126 |
|
(* end case *); |
127 |
|
(AST.S_IfThenElse(e', s', AST.S_Block[]), env) |
128 |
|
end |
129 |
|
| PT.S_IfThenElse(e, s1, s2) => let |
130 |
|
val (e', ty) = checkExpr (env, cxt, e) |
131 |
|
val s1' = checkStmt (env, cxt, s1) |
132 |
|
val s2' = checkStmt (env, cxt, s2) |
133 |
|
in |
134 |
|
(* check that condition has bool type *) |
135 |
|
case ty |
136 |
|
of Ty.T_Bool => () |
137 |
|
| _ => raise Fail "condition not boolean type" |
138 |
|
(* end case *); |
139 |
|
(AST.S_IfThenElse(e', s1', s2'), env) |
140 |
|
end |
141 |
|
| PT.S_Assign(x, e) => (case Env.findVar (env, x) |
142 |
|
of NONE => raise Fail "undefined variable" |
143 |
|
| SOME x' => let |
144 |
|
val (e', ty) = checkExpr (env, cxt, e) |
145 |
|
in |
146 |
|
(* FIXME: check types *) |
147 |
|
(* check that x' is mutable *) |
148 |
|
case Var.kindOf x' |
149 |
|
of Var.ActorStateVar => () |
150 |
|
| Var.LocalVar => () |
151 |
|
| _ => raise Fail "assignment to immutable variable" |
152 |
|
(* end case *); |
153 |
|
(AST.S_Assign(x', e'), env) |
154 |
|
end |
155 |
|
(* end case *)) |
156 |
|
| PT.S_New(actor, args) => let |
157 |
|
val argTys' = List.map (fn e => checkExpr(env, cxt, e)) args |
158 |
|
val (args', tys') = ListPair.unzip argTys' |
159 |
|
in |
160 |
|
(* FIXME: check that actor is defined and has the argument types match *) |
161 |
|
AST.S_New(actor, args') |
162 |
|
end |
163 |
|
| PT.S_Die => (AST.S_Die, env) |
164 |
|
| PT.S_Stabilize => (AST.S_Stabilize, env) |
165 |
(* end case *)) |
(* end case *)) |
166 |
|
|
167 |
fun checkDecl (env, cxt, d) = (case d |
fun checkDecl (env, cxt, d) = (case d |
168 |
of PT.D_Mark m => checkDecl (env, #span m, #tree m) |
of PT.D_Mark m => checkDecl (env, #span m, #tree m) |
169 |
| PT.D_Input(ty, x, optExp) = let |
| PT.D_Input(ty, x, optExp) => let |
170 |
val ty = checkTy(cxt, ty) |
val ty = checkTy(cxt, ty) |
171 |
val x' = Var.new(x, Var.InputVar, ty) |
val x' = Var.new(x, Var.InputVar, ty) |
172 |
val dcl = (case optExp |
val dcl = (case optExp |
181 |
in |
in |
182 |
(dcl, Env.insertGlobal(env, x, x')) |
(dcl, Env.insertGlobal(env, x, x')) |
183 |
end |
end |
184 |
| PT.D_Var of var_decl (* global variable decl *) |
| PT.D_Var vd => let |
185 |
| PT.D_Actor of { (* actor decl *) |
val vd as AST.VD_Decl(x, _) = checkVarDecl (env, cxt, Var.GlobalVar, vd) |
186 |
name : var, |
in |
187 |
params : param list, |
(AST.D_Var vd, Env.insertGlobal(env, x, x')) |
188 |
state : var_decl list, |
end |
189 |
methods : method list |
| PT.D_Actor{nam, params, state, methods} => ?? |
|
} |
|
190 |
| PT.D_InitialArray of create * iter list |
| PT.D_InitialArray of create * iter list |
191 |
| PT.D_InitialCollection of create * iter list |
| PT.D_InitialCollection of create * iter list |
192 |
(* end case *)) |
(* end case *)) |