- /*
- * Semant.java -- semantic checks
- */
- package semant;
- import java.io.IOException;
- import absyn.*;
- import sym.Sym;
- import table.*;
- import types.*;
- import parse.*;
- public class Semant {
- // private Table globalTable;
- private boolean showTables;
- public Semant(boolean s) {
- showTables = s;
- }
- public Table check(Absyn program) {
- /* generate built-in types */
- /* setup global symbol table */
- Table globalTable = erzeugeStartTabelle();
- try {
- globalTable = procsDefsEintragen(globalTable, program);
- globalTable = procRumpfBearbeitung(globalTable, program);
- // ProcEntry pe = (ProcEntry)
- // globalTable.lookup(Sym.newSym("prozedur2"));
- // Table lokTab = pe.localTable;
- // lokTab.show();
- } catch (Exception e) {
- e.printStackTrace();
- }
- /* do semantic checks in 2 passes */
- /* check if "main()" is present */
- /* return global symbol table */
- return globalTable;
- }
- private Table procRumpfBearbeitung(Table globalTable, Absyn program)
- throws Exception {
- Table rueck = globalTable;
- DecList dl = (DecList) program;
- ProcDec pDec;
- DecList decls;
- StmList stmList;
- ProcEntry pe;
- TypeEntry te;
- Table lokTab;
- Entry ent;
- Sym sym;
- VarDec vDec;
- VarEntry vEntry;
- Type typ;
- Type typ2;
- NameTy nTy;
- Ty ty;
- ArrayTy aTy;
- PrimitiveType primType;
- ArrayType aTypeTmp;
- while (dl.isEmpty == false) {
- if (dl.head instanceof ProcDec) {
- pDec = (ProcDec) dl.head;
- decls = (DecList) pDec.decls;
- stmList = (StmList) pDec.body;
- pe = (ProcEntry) rueck.lookup(pDec.name);
- lokTab = pe.localTable;
- // Eintragen der lokalen Variabeln in die lokale Symboltabelle
- while (decls.isEmpty == false) {
- vDec = (VarDec) decls.head;
- ty = vDec.ty;
- while (ty instanceof ArrayTy)
- {
- aTy = (ArrayTy) ty;
- ty = aTy.ty;
- }
- nTy = (NameTy) ty;
- sym = nTy.name;
- typ = typRek2(vDec.ty, globalTable);
- typ2 = varTypFinden(typ);
- primType = (PrimitiveType) typ2;
- ent = globalTable.lookup(Sym.newSym(primType.printName));
- if (!(ent instanceof TypeEntry)) {
- throw new Exception(primType.printName
- + " is not a type in line " + vDec.row);
- }
- te = (TypeEntry) globalTable.lookup(sym);
- if (vDec.ty instanceof NameTy)
- {
- vEntry = new VarEntry(te.type, false);
- }
- else
- {
- vEntry = new VarEntry(typ, false);
- }
- if (lokTab.enter(vDec.name, vEntry) == null) {
- throw new Exception("redeclaration of " + vDec.name
- + " as variable in line " + vDec.row);
- }
- decls = decls.tail;
- }
- // Alle lokalen Variablen sind nun in einer lokalen Tabelle
- // eingetragen.
- rueck = anweisungsBearbeitung(rueck, stmList, pe, lokTab);
- // rueck = null;
- // lokTab.show();
- }
- // Abhandlung der aktuellen Prozedur abgeschlossen
- dl = dl.tail;
- }
- return rueck;
- }
- /*
- *
- */
- private Table anweisungsBearbeitung(Table rueck, StmList stmList,
- ProcEntry pe, Table lokTab) throws Exception {
- Stm stm;
- CallStm callStm;
- IfStm ifStm;
- CompStm compStm;
- StmList compStmList;
- WhileStm whileStm;
- Stm stmIf;
- Stm stmElse;
- Stm stmWhile;
- Entry ent;
- Var var;
- Var var2;
- Exp exp;
- Exp exp2;
- Exp exp3;
- ExpList expList;
- IntExp iExp;
- OpExp oExp;
- VarExp vExp;
- AssignStm aStm;
- Sym sym;
- SimpleVar sVar;
- Type typ;
- VarEntry vEnt;
- ProcEntry pEnt;
- TypeEntry te;
- PrimitiveType pType;
- PrimitiveType pType2;
- PrimitiveType pType3;
- ParamTypeList params;
- StmList stmList2;
- int zaehler = 0;
- int zaehler2 = 0;
- while (stmList.isEmpty == false) {
- if (stmList.head instanceof AssignStm) {
- // Name der Variable aus der Zuweisung holen
- aStm = (AssignStm) stmList.head;
- sVar = (SimpleVar) varNameFinden(aStm.var);
- sym = sVar.name;
- // Checken, ob Variable definiert.
- if (lokTab.lookup(sym) == null) {
- throw new Exception("undefined variable " + sVar.name
- + " in line " + sVar.row);
- }
- // Checken, ob Variable wirklich Variable oder doch Typ oder
- // Prozedur.
- ent = lokTab.lookup(sym);
- if (!(ent instanceof VarEntry)) {
- throw new Exception(sVar.name + "is not a variable"
- + " in line " + sVar.row);
- }
- // Type der Variable ermitteln
- vEnt = (VarEntry) lokTab.lookup(sym);
- arrayIndexCheck(vEnt.type, aStm.var, aStm.exp, lokTab);
- typ = varTypFinden(vEnt.type);
- pType2 = (PrimitiveType) typ;
- // rechte Seite prüfen, wenn dort Variable enthalten ist.
- exp = aStm.exp;
- if (exp instanceof VarExp) {
- vExp = (VarExp) exp;
- var2 = vExp.var;
- sVar = (SimpleVar) varNameFinden(vExp.var);
- sym = sVar.name;
- vEnt = (VarEntry) lokTab.lookup(sym);
- if (vEnt == null) {
- throw new Exception("undefined variable " + sVar.name
- + " in line " + sVar.row);
- }
- if ((vEnt.type instanceof ArrayType && var2 instanceof SimpleVar) || (vEnt.type instanceof PrimitiveType && var2 instanceof ArrayVar))
- {
- throw new Exception(
- "illegal indexing a non-array in line "
- + sVar.row);
- }
- pType = (PrimitiveType) varTypFinden(vEnt.type);
- if (!(pType.printName.equals(pType2.printName))) {
- throw new Exception(
- "assignment has different types in line"
- + sVar.row);
- }
- if (vEnt.type instanceof ArrayType
- && vExp.var instanceof ArrayVar) {
- ArrayVar test = (ArrayVar) vExp.var;
- arrayIndexCheck(vEnt.type, vExp.var, test.index, lokTab);
- }
- } // rechte Seite geprüft, falls dort Variable enthalten ist.
- if (exp instanceof IntExp) { // linke Seite prüfen, falls rechts
- // eine IntExp steht.
- vEnt = (VarEntry) lokTab.lookup(sym);
- pType = (PrimitiveType) varTypFinden(vEnt.type);
- te = (TypeEntry) rueck.lookup(Sym.newSym(pType.printName));
- pType3 = (PrimitiveType) varTypFinden(te.type);
- if (!pType3.printName.equals("int")) {
- throw new Exception(
- "assignment requires integer variable in line "
- + sVar.row);
- }
- } // IntExp fertig geprüft
- // Prüfen, wenn rechts eine OpExp steht.
- if (exp instanceof OpExp) { // Ist Variable auf linker Seite vom
- // Typ int?
- vEnt = (VarEntry) lokTab.lookup(sym);
- pType = (PrimitiveType) varTypFinden(vEnt.type);
- if (!pType.printName.equals("int")) {
- throw new Exception(
- "assignment requires integer variable in line "
- + sVar.row);
- }
- oExp = (OpExp) exp;
- if (oExp.op != OpExp.ADD && oExp.op != OpExp.SUB
- && oExp.op != OpExp.DIV && oExp.op != OpExp.MUL) {
- throw new Exception(
- "assignment has different types in line"
- + sVar.row);
- }
- exp2 = oExpRek2(oExp.left, lokTab);
- exp3 = oExpRek2(oExp.right, lokTab);
- }
- } // Zuweisungbehandlung abgeschlossen.
- // Behandlung, falls Stm ein CallStm ist.
- if (stmList.head instanceof CallStm) {
- // Name der Variable aus der Zuweisung holen
- callStm = (CallStm) stmList.head;
- expList = callStm.args;
- sym = callStm.name;
- // Gibt es Eintrag in GlobTable mit diesem Namen?
- if (rueck.lookup(sym) == null) {
- throw new Exception("undefined procedure " + callStm.name
- + "in line " + callStm.row);
- }
- ent = rueck.lookup(sym);
- if (!(ent instanceof ProcEntry)) {
- throw new Exception("call of non-procedure " + callStm.name
- + "in line " + callStm.row);
- }
- while (expList.isEmpty == false) {
- zaehler++;
- expList = expList.tail;
- }
- expList = callStm.args;
- pEnt = (ProcEntry) ent;
- params = pEnt.paramTypes;
- while (params.isEmpty == false) {
- zaehler2++;
- params = params.next;
- }
- params = pEnt.paramTypes;
- if (zaehler > zaehler2) {
- throw new Exception("procedure " + callStm.name
- + " called with too many arguments in line "
- + callStm.row);
- }
- if (zaehler < zaehler2) {
- throw new Exception("procedure " + callStm.name
- + " called with too few arguments in line "
- + callStm.row);
- }
- zaehler = 0;
- zaehler2 = 0;
- argParamCheck(params, expList, sym, lokTab);
- } // Callstm fertig geprüft.
- if (stmList.head instanceof CompStm) {
- compStm = (CompStm) stmList.head;
- compStmList = compStm.stms;
- anweisungsBearbeitung(rueck, compStmList, pe, lokTab);
- } // CompStm fertig geprüft
- if (stmList.head instanceof EmptyStm) {
- }
- if (stmList.head instanceof IfStm) {
- ifStm = (IfStm) stmList.head;
- exp = ifStm.test;
- if (exp instanceof IntExp) {
- iExp = (IntExp) exp;
- throw new Exception(
- "'if' test expression must be of type boolean in line "
- + iExp.row);
- }
- if (exp instanceof VarExp) {
- vExp = (VarExp) exp;
- throw new Exception(
- "'if' test expression must be of type boolean in line "
- + vExp.row);
- }
- oExp = (OpExp) exp;
- if (oExp.op == OpExp.ADD || oExp.op == OpExp.SUB
- || oExp.op == OpExp.DIV || oExp.op == OpExp.MUL) {
- throw new Exception(
- "'if' test expression must be of type boolean in line "
- + oExp.row);
- }
- ifWhileRekCheck3(exp, lokTab);
- stmIf = ifStm.thenPart;
- stmElse = ifStm.elsePart;
- stmList2 = new StmList(stmIf, new StmList());
- anweisungsBearbeitung(rueck, stmList2, pe, lokTab);
- stmList2 = new StmList(stmElse, new StmList());
- anweisungsBearbeitung(rueck, stmList2, pe, lokTab);
- }
- if (stmList.head instanceof WhileStm) {
- whileStm = (WhileStm) stmList.head;
- exp = whileStm.test;
- if (exp instanceof IntExp) {
- iExp = (IntExp) exp;
- throw new Exception(
- "'if' test expression must be of type boolean in line "
- + iExp.row);
- }
- if (exp instanceof VarExp) {
- vExp = (VarExp) exp;
- throw new Exception(
- "'if' test expression must be of type boolean in line "
- + vExp.row);
- }
- oExp = (OpExp) exp;
- if (oExp.op == OpExp.ADD || oExp.op == OpExp.SUB
- || oExp.op == OpExp.DIV || oExp.op == OpExp.MUL) {
- throw new Exception(
- "'while' test expression must be of type boolean in line "
- + oExp.row);
- }
- ifWhileRekCheck3(exp, lokTab);
- stmWhile = whileStm.body;
- stmList2 = new StmList(stmWhile, new StmList());
- anweisungsBearbeitung(rueck, stmList2, pe, lokTab);
- } // Bearbeitung While-Stm abgeschlossen.
- stmList = stmList.tail;
- }
- return rueck;
- }
- private void ifWhileRekCheck3(Exp exp, Table lokTab) throws Exception {
- OpExp oExp;
- VarExp vExp;
- IntExp iExp;
- if (exp instanceof IntExp) {
- }
- if (exp instanceof VarExp) {
- }
- if (exp instanceof OpExp) {
- oExp = (OpExp) exp;
- if (oExp.op != OpExp.ADD && oExp.op != OpExp.SUB
- && oExp.op != OpExp.DIV && oExp.op != OpExp.MUL) {
- throw new Exception(
- " comparison requires integer operands in line "
- + oExp.row);
- }
- oExpRekCheck3(oExp.left, lokTab);
- oExpRekCheck3(oExp.right, lokTab);
- }
- }
- private void arrayIndexCheck(Type type, Var var, Exp exp, Table lokTab)
- throws Exception {
- ArrayVar aVar;
- SimpleVar sVar;
- ArrayType aType;
- PrimitiveType pType;
- if (var instanceof ArrayVar) {
- aVar = (ArrayVar) var;
- if (type instanceof PrimitiveType) {
- throw new Exception("illegal indexing a non-array in line "
- + aVar.row);
- }
- aType = (ArrayType) type;
- oExpRekCheck3(aVar.index, lokTab);
- oExpRekCheck3(exp, lokTab);
- arrayIndexCheck(aType.baseType, aVar.var, exp, lokTab);
- }
- if (var instanceof SimpleVar) {
- sVar = (SimpleVar) var;
- if (type instanceof ArrayType) {
- throw new Exception("illegal indexing a non-array in line "
- + sVar.row);
- }
- }
- }
- /*
- * Checkt rekursiv eine Exp, ob sie einen Int-Wert zurück gibt.
- */
- private void oExpRekCheck3(Exp exp, Table lokTab) throws Exception {
- OpExp oExp;
- VarExp vExp;
- ArrayVar aVar;
- SimpleVar sVar;
- Sym sym;
- if (exp instanceof IntExp) {
- }
- if (exp instanceof VarExp) {
- vExp = (VarExp) exp;
- sVar = (SimpleVar) varNameFinden(vExp.var);
- sym = sVar.name;
- // Checken, ob Variable definiert.
- if (lokTab.lookup(sym) == null) {
- throw new Exception("undefined variable " + sVar.name
- + " in line " + sVar.row);
- }
- if (vExp.var instanceof ArrayVar) {
- aVar = (ArrayVar) vExp.var;
- oExpRekCheck3(aVar.index, lokTab);
- }
- }
- if (exp instanceof OpExp) {
- oExp = (OpExp) exp;
- if (oExp.op != OpExp.ADD && oExp.op != OpExp.SUB
- && oExp.op != OpExp.DIV && oExp.op != OpExp.MUL) {
- throw new Exception(
- " illegal indexing with a non-integer in line "
- + oExp.row);
- }
- oExpRekCheck3(oExp.left, lokTab);
- oExpRekCheck3(oExp.right, lokTab);
- }
- }
- private void argParamCheck(ParamTypeList params, ExpList expList, Sym sym,
- Table lokTab) throws Exception {
- Sym sym2;
- Exp exp;
- Exp exp2;
- Exp exp3;
- PrimitiveType pType2;
- Type type;
- Type type2;
- IntExp iExp;
- VarExp vExp;
- OpExp oExp;
- PrimitiveType pType;
- SimpleVar sVar;
- VarEntry vEnt;
- String paramTypName;
- while (expList.isEmpty == false) {
- type = params.type;
- exp = expList.head;
- pType = (PrimitiveType) varTypFinden(type);
- paramTypName = pType.printName;
- Entry ent;
- if (exp instanceof IntExp) {
- iExp = (IntExp) exp;
- if (!(paramTypName.equals("int"))) {
- throw new Exception("procedure " + sym.toString()
- + " argument " + iExp.val
- + " type mismatch in line " + iExp.row);
- }
- if (params.isRef) {
- throw new Exception(" parameter " + paramTypName
- + " must be a reference parameter in line "
- + iExp.row);
- }
- } // Prüfung abgeschlossen, wenn Argument IntExp war.
- if (exp instanceof OpExp) {
- oExp = (OpExp) exp;
- if (!(paramTypName.equals("int"))) {
- throw new Exception("procedure " + sym.toString()
- + " argument " + oExp + " type mismatch in line "
- + oExp.row);
- // Baustelle : oexp ist hier nicht richtig.
- }
- if (params.isRef) {
- throw new Exception(" parameter " + paramTypName
- + " must be a reference parameter in line "
- + oExp.row);
- }
- if (oExp.op != OpExp.ADD && oExp.op != OpExp.SUB
- && oExp.op != OpExp.DIV && oExp.op != OpExp.MUL) {
- throw new Exception("procedure " + sym.toString()
- + " argument " + oExp + " type mismatch in line "
- + oExp.row);
- } // Baustelle oexp!
- argParamRekCheck3(oExp.left, paramTypName, sym, lokTab, params);
- argParamRekCheck3(oExp.right, paramTypName, sym, lokTab, params);
- } // Prüfung abgeschlossen, wenn Argument OpExp war.
- if (exp instanceof VarExp) {
- vExp = (VarExp) exp;
- sVar = (SimpleVar) varNameFinden(vExp.var);
- sym2 = sVar.name;
- ent = lokTab.lookup(sym2);
- if (!(ent instanceof VarEntry)) {
- throw new Exception("procedure " + sym.toString()
- + " argument must be a variable in line "
- + vExp.row);
- }
- vEnt = (VarEntry) ent;
- pType2 = (PrimitiveType) varTypFinden(vEnt.type);
- if (pType2.printName.equals(paramTypName)) {
- throw new Exception("procedure " + sym.toString()
- + " argument " + pType2.printName
- + " type mismatch in line " + vExp.row);
- }
- }// Prüfung abgeschlossen, wenn Argument VarExp war.
- expList = expList.tail;
- params = params.next;
- }
- }
- /*
- * Ermittelt rekursiv, die übergebene EXP vom Typ her korrekt ist.
- */
- private void argParamRekCheck3(Exp exp, String paramTypName, Sym sym,
- Table lokTab, ParamTypeList params) throws Exception {
- VarExp vExp;
- SimpleVar sVar;
- Sym sym2;
- VarEntry vEnt;
- PrimitiveType pType;
- IntExp iExp;
- OpExp oExp;
- if (exp instanceof VarExp) {
- vExp = (VarExp) exp;
- sVar = (SimpleVar) varNameFinden(vExp.var);
- sym2 = sVar.name;
- vEnt = (VarEntry) lokTab.lookup(sym2);
- pType = (PrimitiveType) varTypFinden(vEnt.type);
- if (pType.printName.equals(paramTypName)) {
- throw new Exception("procedure " + sym.toString()
- + " argument " + pType.printName
- + " type mismatch in line " + vExp.row);
- }
- } // Prüfung abgeschlossen, wenn Argument VarExp war.
- if (exp instanceof IntExp) {
- iExp = (IntExp) exp;
- if (!(paramTypName.equals("int"))) {
- throw new Exception("procedure " + sym.toString()
- + " argument " + iExp.val + " type mismatch in line "
- + iExp.row);
- }
- if (params.isRef) {
- throw new Exception(" parameter " + paramTypName
- + " must be a reference parameter in line " + iExp.row);
- }
- } // Prüfung abgeschlossen, wenn Argument IntExp war.
- if (exp instanceof OpExp) {
- oExp = (OpExp) exp;
- if (!(paramTypName.equals("int"))) {
- throw new Exception("procedure " + sym.toString()
- + " argument " + oExp + " type mismatch in line "
- + oExp.row);
- // Baustelle : oexp ist hier nicht richtig.
- }
- if (oExp.op != OpExp.ADD && oExp.op != OpExp.SUB
- && oExp.op != OpExp.DIV && oExp.op != OpExp.MUL) {
- throw new Exception("procedure " + sym.toString()
- + " argument " + oExp + " type mismatch in line "
- + oExp.row);
- } // Baustelle oexp!
- if (params.isRef) {
- throw new Exception(" parameter " + paramTypName
- + " must be a reference parameter in line " + oExp.row);
- }
- argParamRekCheck3(oExp.left, paramTypName, sym, lokTab, params);
- argParamRekCheck3(oExp.right, paramTypName, sym, lokTab, params);
- } // Prüfung abgeschlossen, wenn Argument OpExp war.
- }
- /*
- * Ermittelt rekursiv, ob die übergebene Exp ein Int ist.
- */
- private Exp oExpRek2(Exp exp, Table lokTab) throws Exception {
- OpExp opExp;
- Exp exp2;
- Exp exp3;
- VarExp vExp;
- SimpleVar sVar;
- Sym sym;
- VarEntry vEnt;
- PrimitiveType pTyp;
- if (exp instanceof VarExp) {
- vExp = (VarExp) exp;
- sVar = (SimpleVar) varNameFinden(vExp.var);
- sym = sVar.name;
- vEnt = (VarEntry) lokTab.lookup(sym);
- pTyp = (PrimitiveType) varTypFinden(vEnt.type);
- if (!pTyp.printName.equals("int")) {
- throw new Exception(
- "arithmetic operation requires integer operands in line "
- + sVar.row);
- }
- return exp;
- } // Prüfung für EXP instanceof VarExp abgeschlossen
- if (exp instanceof OpExp) {
- opExp = (OpExp) exp;
- if (opExp.op != OpExp.ADD && opExp.op != OpExp.SUB
- && opExp.op != OpExp.DIV && opExp.op != OpExp.MUL) {
- throw new Exception(
- "arithmetic operation requires integer operands in line "
- + opExp.row);
- }
- exp2 = oExpRek2(opExp.left, lokTab);
- exp3 = oExpRek2(opExp.right, lokTab);
- return exp;
- } // Prüfung für EXP instanceof Opexp abgeschlossen
- return exp;
- }
- private Type varTypFinden(Type type) {
- PrimitiveType pTyp;
- ArrayType aTyp;
- if (type instanceof ArrayType) {
- aTyp = (ArrayType) type;
- return varTypFinden(aTyp.baseType);
- }
- if (type instanceof PrimitiveType) {
- pTyp = (PrimitiveType) type;
- return pTyp;
- }
- return null;
- }
- private Var varNameFinden(Var var) {
- SimpleVar sVar;
- ArrayVar aVar;
- if (var instanceof ArrayVar) {
- aVar = (ArrayVar) var;
- return varNameFinden(aVar.var);
- }
- if (var instanceof SimpleVar) {
- sVar = (SimpleVar) var;
- return sVar;
- }
- return null;
- }
- private Table procsDefsEintragen(Table globalTable, Absyn program)
- throws Exception {
- Table rueck = globalTable;
- DecList dl = (DecList) program;
- DecList dl2 = (DecList) program;
- ProcDec pDec;
- TypeDec tDec;
- ParamTypeList ptl;
- Type typ;
- ProcEntry pe;
- TypeEntry te;
- // Eintragen der Typdefinitionen:
- while (dl.isEmpty == false) {
- if (dl.head instanceof TypeDec) {
- tDec = (TypeDec) dl.head;
- if (rueck.lookup(tDec.name) != null) {
- throw new Exception("redeclaration of " + tDec.name
- + " as type in line " + tDec.row);
- }
- te = erstelleTypeEntry(tDec, globalTable);
- rueck.enter(tDec.name, te);
- }
- dl = dl.tail;
- } // Eintragen der Typdefinitionen abgeschlossen.
- // Ist Main evtl. als Typ definiert?
- if (rueck.lookup(Sym.newSym("main")) != null) {
- throw new Exception("'main' is not a procedure");
- }
- // Eintragen der Prozedurdefinitionen:
- while (dl2.isEmpty == false) {
- if (dl2.head instanceof ProcDec) {
- // Checken, ob Prozedur schon definiert.
- pDec = (ProcDec) dl2.head;
- if (rueck.lookup(pDec.name) != null) {
- throw new Exception("redeclaration of " + pDec.name
- + " as procedure in line " + pDec.row);
- }
- // Checken, ob Main Parameter hat.
- if (!(pDec.params.isEmpty)
- && pDec.name.toString().equals("main")) {
- throw new Exception(
- "procedure 'main' must not have any parameters");
- }
- pe = erstelleProcEntry(pDec.params, rueck);
- rueck.enter(pDec.name, pe);
- }
- dl2 = dl2.tail;
- } // Eintagen der Prozedurdefinitionen abgeschlossen.
- if (rueck.lookup(Sym.newSym("main")) == null) {
- throw new Exception("procedure 'main' is missing");
- }
- return rueck;
- }
- private TypeEntry erstelleTypeEntry(TypeDec tDec, Table globalTable)
- throws Exception {
- TypeEntry rueck;
- if (tDec.ty instanceof NameTy) {
- NameTy nt = (NameTy) tDec.ty;
- rueck = new TypeEntry(new PrimitiveType(nt.name.toString()));
- } else {
- ArrayTy at = (ArrayTy) tDec.ty;
- rueck = new TypeEntry(new ArrayType(at.size, typRek2(at.ty,
- globalTable)));
- }
- return rueck;
- }
- private Type typRek2(Ty ty, Table globalTable) throws Exception {
- Type rueck;
- Entry ent;
- if (ty instanceof NameTy) {
- NameTy nt = (NameTy) ty;
- ent = globalTable.lookup(nt.name);
- if (!(ent instanceof TypeEntry)) {
- throw new Exception(nt.name.toString()
- + " is not a type in line " + nt.row);
- }
- return new PrimitiveType(nt.name.toString());
- } else {
- ArrayTy at = (ArrayTy) ty;
- return new ArrayType(at.size, typRek2(at.ty, globalTable));
- }
- }
- private ProcEntry erstelleProcEntry(DecList dl, Table globalTable)
- throws Exception {
- ParamTypeList ptl = new ParamTypeList();
- ProcEntry rueck;
- ParDec parDec;
- NameTy nTy;
- ArrayTy aTy;
- Table lokTab;
- Entry ent;
- TypeEntry te;
- // Falls keine Paramter definiert sind:
- if (dl.isEmpty == true) {
- rueck = new ProcEntry(ptl, new Table(globalTable));
- return rueck;
- }
- parDec = (ParDec) dl.head;
- if (parDec.ty instanceof NameTy) {
- nTy = (NameTy) parDec.ty;
- // Checken, ob Typ definiert wurde.
- if (globalTable.lookup(nTy.name) == null) {
- throw new Exception("undefined type " + nTy.name + " in line "
- + nTy.row);
- }
- // Checken, ob Parameter ein Typeentry ist.
- ent = globalTable.lookup(nTy.name);
- if (!(ent instanceof TypeEntry)) {
- throw new Exception(nTy.name.toString()
- + " is not a type in line " + nTy.row);
- }
- te = (TypeEntry) ent;
- if (parDec.isRef == false && te.type instanceof ArrayType) {
- throw new Exception("Paramater must " + parDec.name
- + " be reference parameter" + " in line " + parDec.row);
- }
- ptl = new ParamTypeList(new PrimitiveType(nTy.name.toString()),
- parDec.isRef, paramListRek2(dl.tail, globalTable));
- }
- if (parDec.ty instanceof ArrayTy) {
- aTy = (ArrayTy) parDec.ty;
- // Checken, ob Parmater als Ref definiert ist.
- if (parDec.isRef == false) {
- throw new Exception("Paramater must " + parDec.name
- + " be reference parameter" + " in line " + parDec.row);
- }
- ptl = new ParamTypeList(new ArrayType(aTy.size, typRek2(aTy.ty,
- globalTable)), parDec.isRef, paramListRek2(dl.tail,
- globalTable));
- }
- ParamTypeList tmpptl = ptl;
- lokTab = new Table(globalTable);
- while (tmpptl.isEmpty == false) {
- parDec = (ParDec) dl.head;
- if (lokTab.enter(parDec.name, new VarEntry(tmpptl.type,
- tmpptl.isRef)) == null) {
- throw new Exception("redeclaration of " + parDec.name
- + " as parameter in line " + parDec.row);
- }
- tmpptl = tmpptl.next;
- dl = dl.tail;
- }
- rueck = new ProcEntry(ptl, lokTab);
- return rueck;
- }
- private ParamTypeList paramListRek2(DecList dl, Table globalTable)
- throws Exception {
- NameTy nTyp;
- NameTy nTy;
- ArrayTy aTyp;
- ParamTypeList ptl;
- Entry ent;
- TypeEntry te;
- if (dl.isEmpty == true) {
- return new ParamTypeList();
- }
- ParDec parDec = (ParDec) dl.head;
- if (parDec.ty instanceof NameTy) {
- nTyp = (NameTy) parDec.ty;
- if (globalTable.lookup(nTyp.name) == null) {
- throw new Exception("undefined type " + nTyp.name + " in line "
- + nTyp.row);
- }
- nTy = (NameTy) parDec.ty;
- ent = globalTable.lookup(nTy.name);
- te = (TypeEntry) ent;
- if (parDec.isRef == false && te.type instanceof ArrayType) {
- throw new Exception("Paramater must " + parDec.name
- + " be reference parameter" + " in line " + parDec.row);
- }
- ptl = new ParamTypeList(new PrimitiveType(nTyp.name.toString()),
- parDec.isRef, paramListRek2(dl.tail, globalTable));
- } else {
- aTyp = (ArrayTy) parDec.ty;
- if (parDec.isRef == false) {
- throw new Exception("Paramater must " + parDec.name
- + " be reference parameter" + " in line " + parDec.row);
- }
- ptl = new ParamTypeList(new ArrayType(aTyp.size, typRek2(aTyp.ty,
- globalTable)), parDec.isRef, paramListRek2(dl.tail,
- globalTable));
- }
- return ptl;
- }
- private Table erzeugeStartTabelle() {
- Table rueck = new Table();
- PrimitiveType pt = new PrimitiveType("bool");
- TypeEntry te = new TypeEntry(pt);
- rueck.enter(Sym.newSym("bool"), te);
- pt = new PrimitiveType("int");
- te = new TypeEntry(pt);
- rueck.enter(Sym.newSym("int"), te);
- ParamTypeList ptl = new ParamTypeList(pt, false, new ParamTypeList());
- ProcEntry pe = new ProcEntry(ptl, new Table());
- rueck.enter(Sym.newSym("printc"), pe);
- ptl = new ParamTypeList(pt, true, new ParamTypeList());
- pe = new ProcEntry(ptl, new Table());
- rueck.enter(Sym.newSym("readi"), pe);
- ptl = new ParamTypeList(pt, true, new ParamTypeList());
- pe = new ProcEntry(ptl, new Table());
- rueck.enter(Sym.newSym("readc"), pe);
- ptl = new ParamTypeList();
- pe = new ProcEntry(ptl, new Table());
- rueck.enter(Sym.newSym("exit"), pe);
- ptl = new ParamTypeList(pt, true, new ParamTypeList());
- pe = new ProcEntry(ptl, new Table());
- rueck.enter(Sym.newSym("time"), pe);
- ptl = new ParamTypeList(pt, true, new ParamTypeList());
- pe = new ProcEntry(ptl, new Table());
- rueck.enter(Sym.newSym("clearAll"), pe);
- ParamTypeList ptl3 = new ParamTypeList(pt, false, new ParamTypeList());
- ParamTypeList ptl2 = new ParamTypeList(pt, false, ptl3);
- ptl = new ParamTypeList(pt, false, ptl2);
- pe = new ProcEntry(ptl, new Table());
- rueck.enter(Sym.newSym("setPixel"), pe);
- ParamTypeList ptl5 = new ParamTypeList(pt, false, new ParamTypeList());
- ParamTypeList ptl4 = new ParamTypeList(pt, false, ptl5);
- ptl3 = new ParamTypeList(pt, false, ptl4);
- ptl2 = new ParamTypeList(pt, false, ptl3);
- ptl = new ParamTypeList(pt, false, ptl2);
- pe = new ProcEntry(ptl, new Table());
- rueck.enter(Sym.newSym("drawLine"), pe);
- ptl4 = new ParamTypeList(pt, false, new ParamTypeList());
- ptl3 = new ParamTypeList(pt, false, ptl4);
- ptl2 = new ParamTypeList(pt, false, ptl3);
- ptl = new ParamTypeList(pt, false, ptl2);
- pe = new ProcEntry(ptl, new Table());
- rueck.enter(Sym.newSym("drawCircle"), pe);
- return rueck;
- }
- }