1 ///////////////////////////////////////////////////////////////////////////////
3 // This file implements the type checker for the SETL-like sublanguage.
5 ///////////////////////////////////////////////////////////////////////////////
13 ///////////////////////////////////////////////////////////////////////////////
15 // Method to elaborate a definition.
17 ///////////////////////////////////////////////////////////////////////////////
18 Env type_of (Def def, const Env& E)
23 ///////////////////////////////////////////////////////////////////////////////
25 // Method to elaborate a definition list.
27 ///////////////////////////////////////////////////////////////////////////////
28 Env type_of (Defs defs, const Env& E)
33 ///////////////////////////////////////////////////////////////////////////////
35 // Method to unify two expressions type.
37 ///////////////////////////////////////////////////////////////////////////////
38 Bool unify (Exp exp, Ty a, Ty b)
40 { error("%Ltype mismatch in expression: %f\n"
41 "%Lexpecting '%T' but found '%T'\n",exp,a,b);
47 ///////////////////////////////////////////////////////////////////////////////
49 // Method to infer the type of an expression.
51 ///////////////////////////////////////////////////////////////////////////////
52 Ty type_of (Exp exp, const Env& E)
56 | LITERALexp l: { ty = type_of(l); }
57 | IDexp id: { ty = mkvar(); }
58 | MARKEDexp(l, e): { l.set_loc(); ty = type_of(e,E); }
59 | CONSexp(ONEcons { cons_ty ... }, _, NOexp):
60 { ty = inst(cons_ty); }
61 | CONSexp(ONEcons { cons_ty ... }, _, e):
62 { Ty fun_ty = inst(cons_ty);
64 unify(exp,fun_ty,mkfunty(type_of(e,E),ty));
66 | RELexp i: { ty = mkvar(); }
67 | DOTexp (e, id): { ty = component_ty(type_of(e,E),id); }
68 | SELECTORexp(e, cons,t): { ty = component_ty(type_of(e,E),cons); }
69 | DEREFexp (e): { ty = mkvar(); }
70 | ARROWexp (e, id): { ty = mkvar(); }
71 | INDEXexp (e, i): { ty = mkvar(); }
72 | BINOPexp (id, a, b): { ty = mkvar(); }
73 | PREFIXexp (id, e): { ty = mkvar(); }
74 | POSTFIXexp (id, e): { ty = mkvar(); }
75 | APPexp (f, a): { ty = mkvar(); }
76 | ASSIGNexp (a, b): { ty = mkvar(); }
77 | IFexp (c, yes, no): { ty = mkvar(); }
78 | TUPLEexp (es): { return mktuplety(type_of(es,E)); }
79 | EXTUPLEexp (es): { return extuplety(type_of(es,E)); }
81 { .[Ids, Tys] t = type_of(es,E);
82 return mkrecordty(t.#1,t.#2,false);
84 | SENDexp (id, es): { return mkvar(); }
85 | LISTexp (ONEcons { cons_ty = cons_ty ... }, _, hd, tl):
86 { Tys head_tys = type_of(hd,E);
87 Ty tail_ty = type_of(tl,E);
89 for_each (Ty, one_ty, head_tys)
90 unify(exp, one_ty, arg_ty);
91 Ty fun_ty = inst(cons_ty);
93 unify(exp,fun_ty,mkfunty(mktuplety(#[arg_ty,mkvar()]),ty));
94 if (tl != NOexp) unify(exp, tail_ty, ty);
96 | VECTORexp (c, es): { return mkvar(); }
97 | CASTexp (ty,e): { type_of(e,E); return ty; }
98 | QUALexp (ty,id): { return mkvar(); }
99 | EQexp (ty, a, b): { return bool_ty; }
100 | UNIFYexp (ty, a, b): { return NOty; }
101 | LTexp (ty, a, b): { return bool_ty; }
102 | HASHexp (ty, e): { return integer_ty; }
103 | THISCOSTexp _: { return integer_ty; }
104 | COSTexp (childno): { return integer_ty; }
105 | THISSYNexp (ruleno,ty,_): { return ty; }
106 | SYNexp (childno, ruleno,ty,_): { return ty; }
107 | SETLexp (op,es): { ty = NOty; }
108 | LISTCOMPexp{ ... }: { ty = NOty; }
109 | FORALLexp (id,exp): { ty = NOty; }
110 | EXISTSexp (id,exp): { ty = NOty; }
114 if (boxed(exp)) exp->ty = ty;
118 ///////////////////////////////////////////////////////////////////////////////
120 // Method to infer the type of an expression list.
122 ///////////////////////////////////////////////////////////////////////////////
123 Tys type_of (Exps es, const Env& E)
126 | #[h ... t]: return #[type_of(h,E) ... type_of(t,E)];
130 ///////////////////////////////////////////////////////////////////////////////
132 // Method to infer the type of an labeled expression list.
134 ///////////////////////////////////////////////////////////////////////////////
135 .[Ids,Tys] type_of (LabExps es, const Env& E)
139 { #[{ label, exp } ... t]:
140 { labels = #[ label ... labels ];
141 tys = #[ type_of(exp,E) ... tys ];
145 return .(labels,tys);
148 ///////////////////////////////////////////////////////////////////////////////
150 // Method to infer the type of a statement.
152 ///////////////////////////////////////////////////////////////////////////////
153 void type_of (Stmt s, const Env& E)
157 | BLOCKstmt (_,stmts):
159 | IFstmt (e, yes, no):
160 | FORALLstmt (bindings, s):
168 ///////////////////////////////////////////////////////////////////////////////
170 // Method to infer the type of a list of statements.
172 ///////////////////////////////////////////////////////////////////////////////
173 void type_of (Stmts ss, const Env& E)
175 { #[h ... t]: { type_of(h,E); ss = t; }