ExpTy transVar(Absyn.SimpleVar v, boolean lhs) { Entry x = (Entry) env.venv.get(v.name); if (x instanceof VarEntry) { VarEntry ent = (VarEntry) x; if (lhs && ent instanceof LoopVarEntry) error(v.pos, "assignment to loop index"); return new ExpTy(translate.SimpleVar(ent.access, level), ent.ty); } error(v.pos, "undeclared variable: " + v.name); return new ExpTy(translate.Error(), VOID); }
ExpTy transExp(Absyn.RecordExp e) { Types.NAME name = (Types.NAME) env.tenv.get(e.typ); if (name != null) { Type actual = name.actual(); if (actual instanceof Types.RECORD) { Types.RECORD r = (Types.RECORD) actual; return new ExpTy(translate.RecordExp(transFields(e.pos, r, e.fields)), name); } error(e.pos, "record type required"); } else error(e.pos, "undeclared type: " + e.typ); return new ExpTy(translate.Error(), VOID); }
ExpTy transVar(Absyn.SubscriptVar v) { ExpTy var = transVar(v.var); ExpTy index = transExp(v.index); checkInt(index, v.index.pos); Type actual = var.ty.actual(); if (actual instanceof Types.ARRAY) { Types.ARRAY array = (Types.ARRAY) actual; return new ExpTy(translate.SubscriptVar(var.exp, index.exp), array.element); } error(v.var.pos, "array required"); return new ExpTy(translate.Error(), VOID); }
ExpTy transVar(Absyn.FieldVar v) { ExpTy var = transVar(v.var); Type actual = var.ty.actual(); if (actual instanceof Types.RECORD) { int count = 0; for (Types.RECORD field = (Types.RECORD) actual; field != null; field = field.tail) { if (field.fieldName == v.field) return new ExpTy(translate.FieldVar(var.exp, count), field.fieldType); ++count; } error(v.pos, "undeclared field: " + v.field); } else error(v.var.pos, "record required"); return new ExpTy(translate.Error(), VOID); }
ExpTy transExp(Absyn.ArrayExp e) { Types.NAME name = (Types.NAME) env.tenv.get(e.typ); ExpTy size = transExp(e.size); ExpTy init = transExp(e.init); checkInt(size, e.size.pos); if (name != null) { Type actual = name.actual(); if (actual instanceof Types.ARRAY) { Types.ARRAY array = (Types.ARRAY) actual; if (!init.ty.coerceTo(array.element)) error(e.init.pos, "element type mismatch"); return new ExpTy(translate.ArrayExp(size.exp, init.exp), name); } else error(e.pos, "array type required"); } else error(e.pos, "undeclared type: " + e.typ); return new ExpTy(translate.Error(), VOID); }
ExpTy transExp(Absyn.CallExp e) { Entry x = (Entry) env.venv.get(e.func); if (x instanceof FunEntry) { FunEntry f = (FunEntry) x; ExpList args = transArgs(e.pos, f.formals, e.args); if (f.level == null) return new ExpTy( f.result.coerceTo(VOID) ? translate.ProcExp(e.func, args, level) : translate.FunExp(e.func, args, level), f.result); else return new ExpTy( f.result.coerceTo(VOID) ? translate.ProcExp(f.level, args, level) : translate.FunExp(f.level, args, level), f.result); } error(e.pos, "undeclared function: " + e.func); return new ExpTy(translate.Error(), VOID); }
ExpTy transExp(Absyn.Exp e) { ExpTy result; if (e == null) return new ExpTy(translate.Error(), VOID); else if (e instanceof Absyn.VarExp) result = transExp((Absyn.VarExp) e); else if (e instanceof Absyn.NilExp) result = transExp((Absyn.NilExp) e); else if (e instanceof Absyn.IntExp) result = transExp((Absyn.IntExp) e); else if (e instanceof Absyn.StringExp) result = transExp((Absyn.StringExp) e); else if (e instanceof Absyn.CallExp) result = transExp((Absyn.CallExp) e); else if (e instanceof Absyn.OpExp) result = transExp((Absyn.OpExp) e); else if (e instanceof Absyn.RecordExp) result = transExp((Absyn.RecordExp) e); else if (e instanceof Absyn.SeqExp) result = transExp((Absyn.SeqExp) e); else if (e instanceof Absyn.AssignExp) result = transExp((Absyn.AssignExp) e); else if (e instanceof Absyn.IfExp) result = transExp((Absyn.IfExp) e); else if (e instanceof Absyn.WhileExp) result = transExp((Absyn.WhileExp) e); else if (e instanceof Absyn.ForExp) result = transExp((Absyn.ForExp) e); else if (e instanceof Absyn.BreakExp) result = transExp((Absyn.BreakExp) e); else if (e instanceof Absyn.LetExp) result = transExp((Absyn.LetExp) e); else if (e instanceof Absyn.ArrayExp) result = transExp((Absyn.ArrayExp) e); else throw new Error("Semant.transExp"); e.type = result.ty; return result; }