From e63d3705454c62fd1eff1c0c9cd78f042e621fbc Mon Sep 17 00:00:00 2001 From: Joshua Wise Date: Sat, 10 Jul 2010 01:33:31 -0400 Subject: [PATCH] Add cast syntax. --- parse/ast.sml | 3 +++ parse/l5.grm | 1 + trans/trans.sml | 1 + type/typechecker.sml | 4 ++++ 4 files changed, 9 insertions(+) diff --git a/parse/ast.sml b/parse/ast.sml index ce756ab..9645f6a 100644 --- a/parse/ast.sml +++ b/parse/ast.sml @@ -38,6 +38,7 @@ sig datatype exp = Var of ident + | Cast of Type.vtype * exp | ConstExp of Word32.word | StringExp of string | OpExp of oper * exp list @@ -109,6 +110,7 @@ struct datatype exp = Var of ident + | Cast of Type.vtype * exp | ConstExp of Word32.word | StringExp of string | OpExp of oper * exp list @@ -172,6 +174,7 @@ struct | 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])) = diff --git a/parse/l5.grm b/parse/l5.grm index 39f33cd..bf2e261 100644 --- a/parse/l5.grm +++ b/parse/l5.grm @@ -188,6 +188,7 @@ exp : LPAREN exp RPAREN (exp) | 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))) diff --git a/trans/trans.sml b/trans/trans.sml index 0ec6574..ec66fd5 100644 --- a/trans/trans.sml +++ b/trans/trans.sml @@ -97,6 +97,7 @@ struct 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])) = diff --git a/type/typechecker.sml b/type/typechecker.sml index 8be3731..3191979 100644 --- a/type/typechecker.sml +++ b/type/typechecker.sml @@ -24,6 +24,9 @@ struct 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]) => @@ -207,6 +210,7 @@ struct | 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 -- 2.39.2