datatype exp =
Var of ident
+ | Cast of Type.vtype * exp
| ConstExp of Word32.word
| StringExp of string
| OpExp of oper * exp list
datatype exp =
Var of ident
+ | Cast of Type.vtype * exp
| ConstExp of Word32.word
| StringExp of string
| OpExp of oper * exp list
| pp_oper GE = ">="
fun pp_exp (Var(id)) = pp_ident id
+ | pp_exp (Cast(ty, exp)) = "["^(Type.Print.pp_type ty)^"]"^(pp_exp exp)
| pp_exp (ConstExp(c)) = Word32Signed.toString c
| pp_exp (StringExp(s)) = "\"" ^ s ^ "\""
| pp_exp (OpExp(oper, [e])) =
| INTNUM (mark (A.ConstExp(INTNUM),(INTNUMleft,INTNUMright)))
| STRING (mark (A.StringExp(STRING),(STRINGleft,STRINGright)))
| IDENT (mark (A.Var(IDENT), (IDENTleft,IDENTright)))
+ | LBRACKET vtype RBRACKET exp %prec UNARY (mark (A.Cast (vtype, exp), (LBRACKETleft, expright)))
| exp DOT IDENT (mark (A.Member(exp, IDENT), (expleft, IDENTright)))
| exp ARROW IDENT (mark (A.DerefMember(exp, IDENT), (expleft, IDENTright)))
| STAR exp %prec UNARY (mark (A.Dereference(exp), (STARleft, expright)))
fun trans_exp env vartypes (A.Var(id)) =
(* after type-checking, id must be declared; do not guard lookup *)
T.TEMP (Symbol.look' env id)
+ | trans_exp env vartypes (A.Cast (ty, e)) = trans_exp env vartypes e (* lurrr *)
| trans_exp env vartypes (A.ConstExp c) = T.CONST(c)
| trans_exp env vartypes (A.StringExp s) = T.STRING(Stringref.new s)
| trans_exp env vartypes (A.OpExp(oper, [e1, e2])) =
of A.Var a => (case Symbol.look vars a
of NONE => (ErrorMsg.error mark ("variable `"^(Symbol.name a)^"' not declared here") ; raise ErrorMsg.Error)
| SOME t => t)
+ | A.Cast (ty, e') => if (T.issmall ty) andalso (T.issmall (typeof (tds, funcs) vars mark e'))
+ then ty
+ else (ErrorMsg.error mark ("cannot cast: one of `"^(T.Print.pp_type ty)^"' or `"^(T.Print.pp_type (typeof (tds, funcs) vars mark e))^"' was not small"); raise ErrorMsg.Error)
| A.ConstExp _ => T.Int
| A.StringExp _ => T.String
| A.OpExp (A.EQ, [a, b]) =>
| SOME UNASSIGNED => ( ErrorMsg.error mark ("usage of unassigned variable `" ^ Symbol.name v ^ "'") ;
raise ErrorMsg.Error )
| SOME ASSIGNED => ())
+ | varcheck_exp env (A.Cast (ty, e)) mark = varcheck_exp env e mark
| varcheck_exp env (A.ConstExp _) mark = ()
| varcheck_exp env (A.StringExp _) mark = ()
| varcheck_exp env (A.OpExp (_, l)) mark = List.app (fn znt => varcheck_exp env znt mark) l