Don't like ads? PRO users don't see any ads ;-)
Guest

Untitled

By: a guest on Aug 5th, 2012  |  syntax: None  |  size: 27.65 KB  |  hits: 10  |  expires: Never
download  |  raw  |  embed  |  report abuse  |  print
Text below is selected. Please press Ctrl+C to copy to your clipboard. (⌘+C on Mac)
  1. /*
  2.  * Semant.java -- semantic checks
  3.  */
  4.  
  5. package semant;
  6.  
  7. import java.io.IOException;
  8.  
  9. import absyn.*;
  10. import sym.Sym;
  11. import table.*;
  12. import types.*;
  13. import parse.*;
  14.  
  15. public class Semant {
  16.  
  17.         // private Table globalTable;
  18.         private boolean showTables;
  19.  
  20.         public Semant(boolean s) {
  21.                 showTables = s;
  22.         }
  23.  
  24.         public Table check(Absyn program) {
  25.                 /* generate built-in types */
  26.                 /* setup global symbol table */
  27.                 Table globalTable = erzeugeStartTabelle();
  28.                 try {
  29.                         globalTable = procsDefsEintragen(globalTable, program);
  30.                         globalTable = procRumpfBearbeitung(globalTable, program);
  31.  
  32.                         // ProcEntry pe = (ProcEntry)
  33.                         // globalTable.lookup(Sym.newSym("prozedur2"));
  34.                         // Table lokTab = pe.localTable;
  35.                         // lokTab.show();
  36.                 } catch (Exception e) {
  37.                         e.printStackTrace();
  38.                 }
  39.                 /* do semantic checks in 2 passes */
  40.                 /* check if "main()" is present */
  41.                 /* return global symbol table */
  42.                 return globalTable;
  43.         }
  44.  
  45.         private Table procRumpfBearbeitung(Table globalTable, Absyn program)
  46.                         throws Exception {
  47.                 Table rueck = globalTable;
  48.                 DecList dl = (DecList) program;
  49.                 ProcDec pDec;
  50.                 DecList decls;
  51.                 StmList stmList;
  52.                 ProcEntry pe;
  53.                 TypeEntry te;
  54.                 Table lokTab;
  55.                 Entry ent;
  56.                 Sym sym;
  57.                 VarDec vDec;
  58.                 VarEntry vEntry;
  59.                 Type typ;
  60.                 Type typ2;
  61.                 NameTy nTy;
  62.                 Ty ty;
  63.                 ArrayTy aTy;
  64.                 PrimitiveType primType;
  65.                 ArrayType aTypeTmp;
  66.  
  67.                 while (dl.isEmpty == false) {
  68.                         if (dl.head instanceof ProcDec) {
  69.                                 pDec = (ProcDec) dl.head;
  70.                                 decls = (DecList) pDec.decls;
  71.                                 stmList = (StmList) pDec.body;
  72.                                 pe = (ProcEntry) rueck.lookup(pDec.name);
  73.                                 lokTab = pe.localTable;
  74.  
  75.                                 // Eintragen der lokalen Variabeln in die lokale Symboltabelle
  76.                                 while (decls.isEmpty == false) {
  77.                                         vDec = (VarDec) decls.head;
  78.                                        
  79.                                         ty = vDec.ty;
  80.                                         while (ty instanceof ArrayTy)
  81.                                         {
  82.                                                 aTy = (ArrayTy) ty;
  83.                                                 ty = aTy.ty;
  84.                                         }
  85.                                         nTy = (NameTy) ty;
  86.                                        
  87.                                         sym = nTy.name;                                        
  88.                                        
  89.                                         typ = typRek2(vDec.ty, globalTable);
  90.                                         typ2 = varTypFinden(typ);
  91.  
  92.                                         primType = (PrimitiveType) typ2;                                       
  93.  
  94.                                         ent = globalTable.lookup(Sym.newSym(primType.printName));
  95.                                         if (!(ent instanceof TypeEntry)) {
  96.                                                 throw new Exception(primType.printName
  97.                                                                 + " is not a type in line " + vDec.row);
  98.                                         }
  99.                                         te = (TypeEntry) globalTable.lookup(sym);
  100.                                                                                
  101.                                         if (vDec.ty instanceof NameTy)
  102.                                         {
  103.                                                 vEntry = new VarEntry(te.type, false);
  104.                                         }                                      
  105.                                         else
  106.                                         {
  107.                                                 vEntry = new VarEntry(typ, false);
  108.                                         }                                      
  109.                                        
  110.                                         if (lokTab.enter(vDec.name, vEntry) == null) {
  111.                                                 throw new Exception("redeclaration of " + vDec.name
  112.                                                                 + " as variable in line " + vDec.row);
  113.                                         }                                              
  114.                                         decls = decls.tail;
  115.                                 }
  116.                                 // Alle lokalen Variablen sind nun in einer lokalen Tabelle
  117.                                 // eingetragen.
  118.  
  119.                                 rueck = anweisungsBearbeitung(rueck, stmList, pe, lokTab);     
  120.                                 // rueck = null;
  121.                                
  122.                                 // lokTab.show();
  123.                         }
  124.                         // Abhandlung der aktuellen Prozedur abgeschlossen
  125.                         dl = dl.tail;
  126.                 }
  127.                 return rueck;
  128.         }
  129.  
  130.         /*
  131.  *
  132.  */
  133.         private Table anweisungsBearbeitung(Table rueck, StmList stmList,
  134.                         ProcEntry pe, Table lokTab) throws Exception {
  135.                 Stm stm;
  136.                 CallStm callStm;
  137.                 IfStm ifStm;
  138.                 CompStm compStm;
  139.                 StmList compStmList;
  140.                 WhileStm whileStm;
  141.                 Stm stmIf;
  142.                 Stm stmElse;
  143.                 Stm stmWhile;
  144.                 Entry ent;
  145.                 Var var;
  146.                 Var var2;
  147.                 Exp exp;
  148.                 Exp exp2;
  149.                 Exp exp3;
  150.                 ExpList expList;
  151.                 IntExp iExp;
  152.                 OpExp oExp;
  153.                 VarExp vExp;
  154.                 AssignStm aStm;
  155.                 Sym sym;
  156.                 SimpleVar sVar;        
  157.                 Type typ;
  158.                 VarEntry vEnt;
  159.                 ProcEntry pEnt;
  160.                 TypeEntry te;
  161.                 PrimitiveType pType;
  162.                 PrimitiveType pType2;
  163.                 PrimitiveType pType3;
  164.                 ParamTypeList params;
  165.                 StmList stmList2;
  166.                 int zaehler = 0;
  167.                 int zaehler2 = 0;
  168.  
  169.                 while (stmList.isEmpty == false) {
  170.                         if (stmList.head instanceof AssignStm) {
  171.  
  172.                                 // Name der Variable aus der Zuweisung holen
  173.                                 aStm = (AssignStm) stmList.head;
  174.                                 sVar = (SimpleVar) varNameFinden(aStm.var);
  175.                                 sym = sVar.name;
  176.  
  177.                                 // Checken, ob Variable definiert.
  178.                                 if (lokTab.lookup(sym) == null) {
  179.                                         throw new Exception("undefined variable " + sVar.name
  180.                                                         + " in line " + sVar.row);
  181.                                 }
  182.  
  183.                                 // Checken, ob Variable wirklich Variable oder doch Typ oder
  184.                                 // Prozedur.
  185.                                 ent = lokTab.lookup(sym);
  186.                                 if (!(ent instanceof VarEntry)) {
  187.                                         throw new Exception(sVar.name + "is not a variable"
  188.                                                         + " in line " + sVar.row);
  189.                                 }
  190.  
  191.                                 // Type der Variable ermitteln
  192.                                 vEnt = (VarEntry) lokTab.lookup(sym);
  193.                                 arrayIndexCheck(vEnt.type, aStm.var, aStm.exp, lokTab);
  194.                                 typ = varTypFinden(vEnt.type);
  195.                                 pType2 = (PrimitiveType) typ;
  196.  
  197.                                 // rechte Seite prüfen, wenn dort Variable enthalten ist.
  198.                                 exp = aStm.exp;
  199.                                 if (exp instanceof VarExp) {
  200.                                         vExp = (VarExp) exp;
  201.                                         var2 = vExp.var;
  202.                                         sVar = (SimpleVar) varNameFinden(vExp.var);
  203.                                         sym = sVar.name;
  204.                                         vEnt = (VarEntry) lokTab.lookup(sym);                                  
  205.                                     if (vEnt == null) {
  206.                                         throw new Exception("undefined variable " + sVar.name
  207.                                           + " in line " + sVar.row);
  208.                                        }
  209.                                    
  210.                                     if ((vEnt.type instanceof ArrayType && var2 instanceof SimpleVar) || (vEnt.type instanceof PrimitiveType && var2 instanceof ArrayVar))
  211.                                     {
  212.                                         throw new Exception(
  213.                                                                 "illegal indexing a non-array in line "
  214.                                                                                 + sVar.row);
  215.                                     }                              
  216.                                    
  217.                                         pType = (PrimitiveType) varTypFinden(vEnt.type);
  218.                                         if (!(pType.printName.equals(pType2.printName))) {
  219.                                                 throw new Exception(
  220.                                                                 "assignment has different types in line"
  221.                                                                                 + sVar.row);
  222.                                         }
  223.  
  224.                                         if (vEnt.type instanceof ArrayType
  225.                                                         && vExp.var instanceof ArrayVar) {
  226.                                                 ArrayVar test = (ArrayVar) vExp.var;                                           
  227.                                                 arrayIndexCheck(vEnt.type, vExp.var, test.index, lokTab);
  228.                                         }
  229.  
  230.                                 } // rechte Seite geprüft, falls dort Variable enthalten ist.
  231.  
  232.                                 if (exp instanceof IntExp) { // linke Seite prüfen, falls rechts
  233.                                                                                                 // eine IntExp steht.
  234.                                         vEnt = (VarEntry) lokTab.lookup(sym);
  235.                                         pType = (PrimitiveType) varTypFinden(vEnt.type);
  236.                                         te = (TypeEntry) rueck.lookup(Sym.newSym(pType.printName));
  237.                                         pType3 = (PrimitiveType) varTypFinden(te.type);
  238.                                        
  239.                                         if (!pType3.printName.equals("int")) {
  240.                                                 throw new Exception(
  241.                                                                 "assignment requires integer variable in line "
  242.                                                                                 + sVar.row);
  243.                                         }
  244.                                 } // IntExp fertig geprüft
  245.  
  246.                                 // Prüfen, wenn rechts eine OpExp steht.
  247.                                 if (exp instanceof OpExp) { // Ist Variable auf linker Seite vom
  248.                                                                                         // Typ int?
  249.                                         vEnt = (VarEntry) lokTab.lookup(sym);
  250.                                         pType = (PrimitiveType) varTypFinden(vEnt.type);
  251.                                         if (!pType.printName.equals("int")) {
  252.                                                 throw new Exception(
  253.                                                                 "assignment requires integer variable in line "
  254.                                                                                 + sVar.row);
  255.                                         }
  256.  
  257.                                         oExp = (OpExp) exp;
  258.                                         if (oExp.op != OpExp.ADD && oExp.op != OpExp.SUB
  259.                                                         && oExp.op != OpExp.DIV && oExp.op != OpExp.MUL) {
  260.                                                 throw new Exception(
  261.                                                                 "assignment has different types in line"
  262.                                                                                 + sVar.row);
  263.                                         }
  264.                                         exp2 = oExpRek2(oExp.left, lokTab);
  265.                                         exp3 = oExpRek2(oExp.right, lokTab);
  266.                                 }
  267.                         } // Zuweisungbehandlung abgeschlossen.
  268.  
  269.                         // Behandlung, falls Stm ein CallStm ist.
  270.                         if (stmList.head instanceof CallStm) {
  271.                                 // Name der Variable aus der Zuweisung holen
  272.                                 callStm = (CallStm) stmList.head;
  273.                                 expList = callStm.args;
  274.                                 sym = callStm.name;
  275.  
  276.                                 // Gibt es Eintrag in GlobTable mit diesem Namen?
  277.                                 if (rueck.lookup(sym) == null) {
  278.                                         throw new Exception("undefined procedure " + callStm.name
  279.                                                         + "in line " + callStm.row);
  280.                                 }
  281.  
  282.                                 ent = rueck.lookup(sym);
  283.                                 if (!(ent instanceof ProcEntry)) {
  284.                                         throw new Exception("call of non-procedure " + callStm.name
  285.                                                         + "in line " + callStm.row);
  286.                                 }
  287.  
  288.                                 while (expList.isEmpty == false) {
  289.                                         zaehler++;
  290.                                         expList = expList.tail;
  291.                                 }
  292.  
  293.                                 expList = callStm.args;
  294.  
  295.                                 pEnt = (ProcEntry) ent;
  296.                                 params = pEnt.paramTypes;
  297.  
  298.                                 while (params.isEmpty == false) {
  299.                                         zaehler2++;
  300.                                         params = params.next;
  301.                                 }
  302.                                 params = pEnt.paramTypes;
  303.  
  304.                                 if (zaehler > zaehler2) {
  305.                                         throw new Exception("procedure " + callStm.name
  306.                                                         + " called with too many arguments in line "
  307.                                                         + callStm.row);
  308.                                 }
  309.  
  310.                                 if (zaehler < zaehler2) {
  311.                                         throw new Exception("procedure " + callStm.name
  312.                                                         + " called with too few arguments in line "
  313.                                                         + callStm.row);
  314.                                 }
  315.                                 zaehler = 0;
  316.                                 zaehler2 = 0;
  317.  
  318.                                 argParamCheck(params, expList, sym, lokTab);
  319.                         } // Callstm fertig geprüft.
  320.  
  321.                         if (stmList.head instanceof CompStm) {
  322.                                 compStm = (CompStm) stmList.head;
  323.                                 compStmList = compStm.stms;
  324.                                 anweisungsBearbeitung(rueck, compStmList, pe, lokTab);
  325.                         } // CompStm fertig geprüft
  326.  
  327.                         if (stmList.head instanceof EmptyStm) {
  328.  
  329.                         }
  330.  
  331.                         if (stmList.head instanceof IfStm) {
  332.                                 ifStm = (IfStm) stmList.head;
  333.                                 exp = ifStm.test;
  334.  
  335.                                 if (exp instanceof IntExp) {
  336.                                         iExp = (IntExp) exp;
  337.                                         throw new Exception(
  338.                                                         "'if' test expression must be of type boolean in line "
  339.                                                                         + iExp.row);
  340.                                 }
  341.  
  342.                                 if (exp instanceof VarExp) {
  343.                                         vExp = (VarExp) exp;
  344.                                         throw new Exception(
  345.                                                         "'if' test expression must be of type boolean in line "
  346.                                                                         + vExp.row);
  347.                                 }
  348.  
  349.                                 oExp = (OpExp) exp;
  350.                                 if (oExp.op == OpExp.ADD || oExp.op == OpExp.SUB
  351.                                                 || oExp.op == OpExp.DIV || oExp.op == OpExp.MUL) {
  352.                                         throw new Exception(
  353.                                                         "'if' test expression must be of type boolean in line "
  354.                                                                         + oExp.row);
  355.                                 }
  356.  
  357.                                 ifWhileRekCheck3(exp, lokTab);
  358.                                 stmIf = ifStm.thenPart;
  359.                                 stmElse = ifStm.elsePart;
  360.                                 stmList2 = new StmList(stmIf, new StmList());
  361.                                 anweisungsBearbeitung(rueck, stmList2, pe, lokTab);
  362.  
  363.                                 stmList2 = new StmList(stmElse, new StmList());
  364.                                 anweisungsBearbeitung(rueck, stmList2, pe, lokTab);
  365.                         }
  366.  
  367.                         if (stmList.head instanceof WhileStm) {
  368.                                 whileStm = (WhileStm) stmList.head;
  369.                                 exp = whileStm.test;
  370.  
  371.                                 if (exp instanceof IntExp) {
  372.                                         iExp = (IntExp) exp;
  373.                                         throw new Exception(
  374.                                                         "'if' test expression must be of type boolean in line "
  375.                                                                         + iExp.row);
  376.                                 }
  377.  
  378.                                 if (exp instanceof VarExp) {
  379.                                         vExp = (VarExp) exp;
  380.                                         throw new Exception(
  381.                                                         "'if' test expression must be of type boolean in line "
  382.                                                                         + vExp.row);
  383.                                 }
  384.  
  385.                                 oExp = (OpExp) exp;
  386.                                 if (oExp.op == OpExp.ADD || oExp.op == OpExp.SUB
  387.                                                 || oExp.op == OpExp.DIV || oExp.op == OpExp.MUL) {
  388.                                         throw new Exception(
  389.                                                         "'while' test expression must be of type boolean in line "
  390.                                                                         + oExp.row);
  391.                                 }
  392.  
  393.                                 ifWhileRekCheck3(exp, lokTab);
  394.                                 stmWhile = whileStm.body;
  395.                                 stmList2 = new StmList(stmWhile, new StmList());
  396.                                 anweisungsBearbeitung(rueck, stmList2, pe, lokTab);
  397.  
  398.                         } // Bearbeitung While-Stm abgeschlossen.
  399.                         stmList = stmList.tail;
  400.                 }
  401.  
  402.                 return rueck;
  403.         }
  404.  
  405.         private void ifWhileRekCheck3(Exp exp, Table lokTab) throws Exception {
  406.                 OpExp oExp;
  407.                 VarExp vExp;
  408.                 IntExp iExp;
  409.  
  410.                 if (exp instanceof IntExp) {
  411.                 }
  412.  
  413.                 if (exp instanceof VarExp) {
  414.                 }
  415.  
  416.                 if (exp instanceof OpExp) {
  417.                         oExp = (OpExp) exp;
  418.                         if (oExp.op != OpExp.ADD && oExp.op != OpExp.SUB
  419.                                         && oExp.op != OpExp.DIV && oExp.op != OpExp.MUL) {
  420.                                 throw new Exception(
  421.                                                 "  comparison requires integer operands in line "
  422.                                                                 + oExp.row);
  423.                         }
  424.                         oExpRekCheck3(oExp.left, lokTab);
  425.                         oExpRekCheck3(oExp.right, lokTab);
  426.                 }
  427.         }
  428.  
  429.         private void arrayIndexCheck(Type type, Var var, Exp exp, Table lokTab)
  430.                         throws Exception {
  431.                 ArrayVar aVar;
  432.                 SimpleVar sVar;
  433.                 ArrayType aType;
  434.                 PrimitiveType pType;
  435.  
  436.                 if (var instanceof ArrayVar) {
  437.                         aVar = (ArrayVar) var;
  438.  
  439.                         if (type instanceof PrimitiveType) {
  440.                                 throw new Exception("illegal indexing a non-array in line "
  441.                                                 + aVar.row);
  442.                         }
  443.                         aType = (ArrayType) type;
  444.                         oExpRekCheck3(aVar.index, lokTab);
  445.                         oExpRekCheck3(exp, lokTab);
  446.                         arrayIndexCheck(aType.baseType, aVar.var, exp, lokTab);
  447.                 }
  448.  
  449.                 if (var instanceof SimpleVar) {
  450.                         sVar = (SimpleVar) var;
  451.                         if (type instanceof ArrayType) {
  452.                                 throw new Exception("illegal indexing a non-array in line "
  453.                                                 + sVar.row);
  454.                         }
  455.                 }
  456.         }
  457.  
  458.         /*
  459.          * Checkt rekursiv eine Exp, ob sie einen Int-Wert zurück gibt.
  460.          */
  461.         private void oExpRekCheck3(Exp exp, Table lokTab) throws Exception {
  462.                 OpExp oExp;
  463.                 VarExp vExp;
  464.                 ArrayVar aVar;
  465.                 SimpleVar sVar;
  466.                 Sym sym;
  467.  
  468.                 if (exp instanceof IntExp) {
  469.  
  470.                 }
  471.  
  472.                 if (exp instanceof VarExp) {
  473.                         vExp = (VarExp) exp;
  474.                         sVar = (SimpleVar) varNameFinden(vExp.var);
  475.                         sym = sVar.name;
  476.  
  477.                         // Checken, ob Variable definiert.
  478.                         if (lokTab.lookup(sym) == null) {
  479.                                 throw new Exception("undefined variable " + sVar.name
  480.                                                 + " in line " + sVar.row);
  481.                         }
  482.  
  483.                         if (vExp.var instanceof ArrayVar) {
  484.                                 aVar = (ArrayVar) vExp.var;
  485.                                 oExpRekCheck3(aVar.index, lokTab);
  486.                         }
  487.  
  488.                 }
  489.  
  490.                 if (exp instanceof OpExp) {
  491.                         oExp = (OpExp) exp;
  492.                         if (oExp.op != OpExp.ADD && oExp.op != OpExp.SUB
  493.                                         && oExp.op != OpExp.DIV && oExp.op != OpExp.MUL) {
  494.                                 throw new Exception(
  495.                                                 "  illegal indexing with a non-integer in line "
  496.                                                                 + oExp.row);
  497.                         }
  498.                         oExpRekCheck3(oExp.left, lokTab);
  499.                         oExpRekCheck3(oExp.right, lokTab);
  500.                 }
  501.         }
  502.  
  503.         private void argParamCheck(ParamTypeList params, ExpList expList, Sym sym,
  504.                         Table lokTab) throws Exception {
  505.                 Sym sym2;
  506.                 Exp exp;
  507.                 Exp exp2;
  508.                 Exp exp3;
  509.                 PrimitiveType pType2;
  510.                 Type type;
  511.                 Type type2;
  512.                 IntExp iExp;
  513.                 VarExp vExp;
  514.                 OpExp oExp;
  515.                 PrimitiveType pType;
  516.                 SimpleVar sVar;
  517.                 VarEntry vEnt;
  518.                 String paramTypName;
  519.  
  520.                 while (expList.isEmpty == false) {
  521.                         type = params.type;
  522.                         exp = expList.head;
  523.                         pType = (PrimitiveType) varTypFinden(type);
  524.                         paramTypName = pType.printName;
  525.                         Entry ent;
  526.  
  527.                         if (exp instanceof IntExp) {
  528.                                 iExp = (IntExp) exp;
  529.                                 if (!(paramTypName.equals("int"))) {
  530.                                         throw new Exception("procedure " + sym.toString()
  531.                                                         + " argument " + iExp.val
  532.                                                         + " type mismatch in line " + iExp.row);
  533.                                 }
  534.  
  535.                                 if (params.isRef) {
  536.                                         throw new Exception(" parameter " + paramTypName
  537.                                                         + " must be a reference parameter in line "
  538.                                                         + iExp.row);
  539.                                 }
  540.  
  541.                         } // Prüfung abgeschlossen, wenn Argument IntExp war.
  542.  
  543.                         if (exp instanceof OpExp) {
  544.                                 oExp = (OpExp) exp;
  545.                                 if (!(paramTypName.equals("int"))) {
  546.                                         throw new Exception("procedure " + sym.toString()
  547.                                                         + " argument " + oExp + " type mismatch in line "
  548.                                                         + oExp.row);
  549.                                         // Baustelle : oexp ist hier nicht richtig.
  550.                                 }
  551.  
  552.                                 if (params.isRef) {
  553.                                         throw new Exception(" parameter " + paramTypName
  554.                                                         + " must be a reference parameter in line "
  555.                                                         + oExp.row);
  556.                                 }
  557.  
  558.                                 if (oExp.op != OpExp.ADD && oExp.op != OpExp.SUB
  559.                                                 && oExp.op != OpExp.DIV && oExp.op != OpExp.MUL) {
  560.                                         throw new Exception("procedure " + sym.toString()
  561.                                                         + " argument " + oExp + " type mismatch in line "
  562.                                                         + oExp.row);
  563.                                 } // Baustelle oexp!
  564.  
  565.                                 argParamRekCheck3(oExp.left, paramTypName, sym, lokTab, params);
  566.                                 argParamRekCheck3(oExp.right, paramTypName, sym, lokTab, params);
  567.                         } // Prüfung abgeschlossen, wenn Argument OpExp war.
  568.  
  569.                         if (exp instanceof VarExp) {
  570.                                 vExp = (VarExp) exp;
  571.                                 sVar = (SimpleVar) varNameFinden(vExp.var);
  572.                                 sym2 = sVar.name;
  573.                                 ent = lokTab.lookup(sym2);
  574.  
  575.                                 if (!(ent instanceof VarEntry)) {
  576.                                         throw new Exception("procedure " + sym.toString()
  577.                                                         + " argument must be a variable in line "
  578.                                                         + vExp.row);
  579.                                 }
  580.  
  581.                                 vEnt = (VarEntry) ent;
  582.                                 pType2 = (PrimitiveType) varTypFinden(vEnt.type);
  583.  
  584.                                 if (pType2.printName.equals(paramTypName)) {
  585.                                         throw new Exception("procedure " + sym.toString()
  586.                                                         + " argument " + pType2.printName
  587.                                                         + " type mismatch in line " + vExp.row);
  588.                                 }
  589.                         }// Prüfung abgeschlossen, wenn Argument VarExp war.
  590.  
  591.                         expList = expList.tail;
  592.                         params = params.next;
  593.                 }
  594.         }
  595.  
  596.         /*
  597.          * Ermittelt rekursiv, die übergebene EXP vom Typ her korrekt ist.
  598.          */
  599.         private void argParamRekCheck3(Exp exp, String paramTypName, Sym sym,
  600.                         Table lokTab, ParamTypeList params) throws Exception {
  601.                 VarExp vExp;
  602.                 SimpleVar sVar;
  603.                 Sym sym2;
  604.                 VarEntry vEnt;
  605.                 PrimitiveType pType;
  606.                 IntExp iExp;
  607.                 OpExp oExp;
  608.  
  609.                 if (exp instanceof VarExp) {
  610.                         vExp = (VarExp) exp;
  611.                         sVar = (SimpleVar) varNameFinden(vExp.var);
  612.                         sym2 = sVar.name;
  613.                         vEnt = (VarEntry) lokTab.lookup(sym2);
  614.                         pType = (PrimitiveType) varTypFinden(vEnt.type);
  615.  
  616.                         if (pType.printName.equals(paramTypName)) {
  617.                                 throw new Exception("procedure " + sym.toString()
  618.                                                 + " argument " + pType.printName
  619.                                                 + " type mismatch in line " + vExp.row);
  620.                         }
  621.                 } // Prüfung abgeschlossen, wenn Argument VarExp war.
  622.  
  623.                 if (exp instanceof IntExp) {
  624.                         iExp = (IntExp) exp;
  625.                         if (!(paramTypName.equals("int"))) {
  626.                                 throw new Exception("procedure " + sym.toString()
  627.                                                 + " argument " + iExp.val + " type mismatch in line "
  628.                                                 + iExp.row);
  629.                         }
  630.  
  631.                         if (params.isRef) {
  632.                                 throw new Exception(" parameter " + paramTypName
  633.                                                 + " must be a reference parameter in line " + iExp.row);
  634.                         }
  635.                 } // Prüfung abgeschlossen, wenn Argument IntExp war.
  636.  
  637.                 if (exp instanceof OpExp) {
  638.                         oExp = (OpExp) exp;
  639.                         if (!(paramTypName.equals("int"))) {
  640.                                 throw new Exception("procedure " + sym.toString()
  641.                                                 + " argument " + oExp + " type mismatch in line "
  642.                                                 + oExp.row);
  643.                                 // Baustelle : oexp ist hier nicht richtig.
  644.                         }
  645.  
  646.                         if (oExp.op != OpExp.ADD && oExp.op != OpExp.SUB
  647.                                         && oExp.op != OpExp.DIV && oExp.op != OpExp.MUL) {
  648.                                 throw new Exception("procedure " + sym.toString()
  649.                                                 + " argument " + oExp + " type mismatch in line "
  650.                                                 + oExp.row);
  651.                         } // Baustelle oexp!
  652.  
  653.                         if (params.isRef) {
  654.                                 throw new Exception(" parameter " + paramTypName
  655.                                                 + " must be a reference parameter in line " + oExp.row);
  656.                         }
  657.  
  658.                         argParamRekCheck3(oExp.left, paramTypName, sym, lokTab, params);
  659.                         argParamRekCheck3(oExp.right, paramTypName, sym, lokTab, params);
  660.                 } // Prüfung abgeschlossen, wenn Argument OpExp war.
  661.         }
  662.  
  663.         /*
  664.          * Ermittelt rekursiv, ob die übergebene Exp ein Int ist.
  665.          */
  666.         private Exp oExpRek2(Exp exp, Table lokTab) throws Exception {
  667.                 OpExp opExp;
  668.                 Exp exp2;
  669.                 Exp exp3;
  670.                 VarExp vExp;
  671.                 SimpleVar sVar;
  672.                 Sym sym;
  673.                 VarEntry vEnt;
  674.                 PrimitiveType pTyp;
  675.  
  676.                 if (exp instanceof VarExp) {
  677.                         vExp = (VarExp) exp;
  678.                         sVar = (SimpleVar) varNameFinden(vExp.var);
  679.                         sym = sVar.name;
  680.                         vEnt = (VarEntry) lokTab.lookup(sym);
  681.                         pTyp = (PrimitiveType) varTypFinden(vEnt.type);
  682.  
  683.                         if (!pTyp.printName.equals("int")) {
  684.                                 throw new Exception(
  685.                                                 "arithmetic operation requires integer operands in line "
  686.                                                                 + sVar.row);
  687.                         }
  688.                         return exp;
  689.                 } // Prüfung für EXP instanceof VarExp abgeschlossen
  690.  
  691.                 if (exp instanceof OpExp) {
  692.                         opExp = (OpExp) exp;
  693.                         if (opExp.op != OpExp.ADD && opExp.op != OpExp.SUB
  694.                                         && opExp.op != OpExp.DIV && opExp.op != OpExp.MUL) {
  695.                                 throw new Exception(
  696.                                                 "arithmetic operation requires integer operands in line "
  697.                                                                 + opExp.row);
  698.                         }
  699.                         exp2 = oExpRek2(opExp.left, lokTab);
  700.                         exp3 = oExpRek2(opExp.right, lokTab);
  701.                         return exp;
  702.                 } // Prüfung für EXP instanceof Opexp abgeschlossen
  703.  
  704.                 return exp;
  705.         }
  706.  
  707.         private Type varTypFinden(Type type) {
  708.                 PrimitiveType pTyp;
  709.                 ArrayType aTyp;
  710.                 if (type instanceof ArrayType) {
  711.                         aTyp = (ArrayType) type;
  712.                         return varTypFinden(aTyp.baseType);
  713.                 }
  714.  
  715.                 if (type instanceof PrimitiveType) {
  716.                         pTyp = (PrimitiveType) type;
  717.                         return pTyp;
  718.                 }
  719.                 return null;
  720.         }
  721.  
  722.         private Var varNameFinden(Var var) {
  723.                 SimpleVar sVar;
  724.                 ArrayVar aVar;
  725.  
  726.                 if (var instanceof ArrayVar) {
  727.                         aVar = (ArrayVar) var;
  728.  
  729.                         return varNameFinden(aVar.var);
  730.                 }
  731.  
  732.                 if (var instanceof SimpleVar) {
  733.                         sVar = (SimpleVar) var;
  734.                         return sVar;
  735.                 }
  736.                 return null;
  737.         }
  738.  
  739.         private Table procsDefsEintragen(Table globalTable, Absyn program)
  740.                         throws Exception {
  741.                 Table rueck = globalTable;
  742.                 DecList dl = (DecList) program;
  743.                 DecList dl2 = (DecList) program;
  744.                 ProcDec pDec;
  745.                 TypeDec tDec;
  746.                 ParamTypeList ptl;
  747.                 Type typ;
  748.                 ProcEntry pe;
  749.                 TypeEntry te;
  750.  
  751.                 // Eintragen der Typdefinitionen:
  752.                 while (dl.isEmpty == false) {
  753.                         if (dl.head instanceof TypeDec) {
  754.                                 tDec = (TypeDec) dl.head;
  755.                                 if (rueck.lookup(tDec.name) != null) {
  756.                                         throw new Exception("redeclaration of " + tDec.name
  757.                                                         + " as type in line " + tDec.row);
  758.                                 }
  759.                                 te = erstelleTypeEntry(tDec, globalTable);
  760.                                 rueck.enter(tDec.name, te);
  761.                         }
  762.                         dl = dl.tail;
  763.                 } // Eintragen der Typdefinitionen abgeschlossen.
  764.  
  765.                 // Ist Main evtl. als Typ definiert?
  766.                 if (rueck.lookup(Sym.newSym("main")) != null) {
  767.                         throw new Exception("'main' is not a procedure");
  768.                 }
  769.  
  770.                 // Eintragen der Prozedurdefinitionen:
  771.                 while (dl2.isEmpty == false) {
  772.                         if (dl2.head instanceof ProcDec) {
  773.  
  774.                                 // Checken, ob Prozedur schon definiert.
  775.                                 pDec = (ProcDec) dl2.head;
  776.                                 if (rueck.lookup(pDec.name) != null) {
  777.                                         throw new Exception("redeclaration of " + pDec.name
  778.                                                         + " as procedure in line " + pDec.row);
  779.                                 }
  780.  
  781.                                 // Checken, ob Main Parameter hat.
  782.                                 if (!(pDec.params.isEmpty)
  783.                                                 && pDec.name.toString().equals("main")) {
  784.                                         throw new Exception(
  785.                                                         "procedure 'main' must not have any parameters");
  786.                                 }
  787.  
  788.                                 pe = erstelleProcEntry(pDec.params, rueck);
  789.                                 rueck.enter(pDec.name, pe);
  790.                         }
  791.                         dl2 = dl2.tail;
  792.                 } // Eintagen der Prozedurdefinitionen abgeschlossen.
  793.  
  794.                 if (rueck.lookup(Sym.newSym("main")) == null) {
  795.                         throw new Exception("procedure 'main' is missing");
  796.                 }
  797.  
  798.                 return rueck;
  799.         }
  800.  
  801.         private TypeEntry erstelleTypeEntry(TypeDec tDec, Table globalTable)
  802.                         throws Exception {
  803.                 TypeEntry rueck;
  804.  
  805.                 if (tDec.ty instanceof NameTy) {
  806.                         NameTy nt = (NameTy) tDec.ty;
  807.                         rueck = new TypeEntry(new PrimitiveType(nt.name.toString()));
  808.                 } else {
  809.                         ArrayTy at = (ArrayTy) tDec.ty;
  810.                         rueck = new TypeEntry(new ArrayType(at.size, typRek2(at.ty,
  811.                                         globalTable)));
  812.                 }
  813.                 return rueck;
  814.         }
  815.  
  816.         private Type typRek2(Ty ty, Table globalTable) throws Exception {
  817.                 Type rueck;
  818.                 Entry ent;
  819.  
  820.                 if (ty instanceof NameTy) {
  821.                         NameTy nt = (NameTy) ty;
  822.                         ent = globalTable.lookup(nt.name);
  823.                         if (!(ent instanceof TypeEntry)) {
  824.                                 throw new Exception(nt.name.toString()
  825.                                                 + " is not a type in line " + nt.row);
  826.                         }
  827.  
  828.                         return new PrimitiveType(nt.name.toString());
  829.                 } else {
  830.                         ArrayTy at = (ArrayTy) ty;
  831.                         return new ArrayType(at.size, typRek2(at.ty, globalTable));
  832.                 }
  833.         }
  834.  
  835.         private ProcEntry erstelleProcEntry(DecList dl, Table globalTable)
  836.                         throws Exception {
  837.                 ParamTypeList ptl = new ParamTypeList();
  838.                 ProcEntry rueck;
  839.                 ParDec parDec;
  840.                 NameTy nTy;
  841.                 ArrayTy aTy;
  842.                 Table lokTab;
  843.                 Entry ent;
  844.                 TypeEntry te;
  845.  
  846.                 // Falls keine Paramter definiert sind:
  847.                 if (dl.isEmpty == true) {
  848.                         rueck = new ProcEntry(ptl, new Table(globalTable));
  849.                         return rueck;
  850.                 }
  851.  
  852.                 parDec = (ParDec) dl.head;
  853.                 if (parDec.ty instanceof NameTy) {
  854.                         nTy = (NameTy) parDec.ty;
  855.  
  856.                         // Checken, ob Typ definiert wurde.
  857.                         if (globalTable.lookup(nTy.name) == null) {
  858.                                 throw new Exception("undefined type " + nTy.name + " in line "
  859.                                                 + nTy.row);
  860.                         }
  861.  
  862.                         // Checken, ob Parameter ein Typeentry ist.
  863.                         ent = globalTable.lookup(nTy.name);
  864.                         if (!(ent instanceof TypeEntry)) {
  865.                                 throw new Exception(nTy.name.toString()
  866.                                                 + " is not a type in line " + nTy.row);
  867.                         }
  868.  
  869.                         te = (TypeEntry) ent;
  870.                         if (parDec.isRef == false && te.type instanceof ArrayType) {
  871.                                 throw new Exception("Paramater must " + parDec.name
  872.                                                 + " be reference parameter" + " in line " + parDec.row);
  873.                         }
  874.  
  875.                         ptl = new ParamTypeList(new PrimitiveType(nTy.name.toString()),
  876.                                         parDec.isRef, paramListRek2(dl.tail, globalTable));
  877.                 }
  878.  
  879.                 if (parDec.ty instanceof ArrayTy) {
  880.                         aTy = (ArrayTy) parDec.ty;
  881.  
  882.                         // Checken, ob Parmater als Ref definiert ist.
  883.                         if (parDec.isRef == false) {
  884.                                 throw new Exception("Paramater must " + parDec.name
  885.                                                 + " be reference parameter" + " in line " + parDec.row);
  886.                         }
  887.                         ptl = new ParamTypeList(new ArrayType(aTy.size, typRek2(aTy.ty,
  888.                                         globalTable)), parDec.isRef, paramListRek2(dl.tail,
  889.                                         globalTable));
  890.                 }
  891.  
  892.                 ParamTypeList tmpptl = ptl;
  893.                 lokTab = new Table(globalTable);
  894.  
  895.                 while (tmpptl.isEmpty == false) {
  896.                         parDec = (ParDec) dl.head;
  897.                         if (lokTab.enter(parDec.name, new VarEntry(tmpptl.type,
  898.                                         tmpptl.isRef)) == null) {
  899.                                 throw new Exception("redeclaration of " + parDec.name
  900.                                                 + " as parameter in line " + parDec.row);
  901.                         }
  902.                         tmpptl = tmpptl.next;
  903.                         dl = dl.tail;
  904.                 }
  905.  
  906.                 rueck = new ProcEntry(ptl, lokTab);
  907.                 return rueck;
  908.         }
  909.  
  910.         private ParamTypeList paramListRek2(DecList dl, Table globalTable)
  911.                         throws Exception {
  912.                 NameTy nTyp;
  913.                 NameTy nTy;
  914.                 ArrayTy aTyp;
  915.                 ParamTypeList ptl;
  916.                 Entry ent;
  917.                 TypeEntry te;
  918.  
  919.                 if (dl.isEmpty == true) {
  920.                         return new ParamTypeList();
  921.                 }
  922.  
  923.                 ParDec parDec = (ParDec) dl.head;
  924.  
  925.                 if (parDec.ty instanceof NameTy) {
  926.                         nTyp = (NameTy) parDec.ty;
  927.                         if (globalTable.lookup(nTyp.name) == null) {
  928.                                 throw new Exception("undefined type " + nTyp.name + " in line "
  929.                                                 + nTyp.row);
  930.                         }
  931.                         nTy = (NameTy) parDec.ty;
  932.                         ent = globalTable.lookup(nTy.name);
  933.                         te = (TypeEntry) ent;
  934.                         if (parDec.isRef == false && te.type instanceof ArrayType) {
  935.                                 throw new Exception("Paramater must " + parDec.name
  936.                                                 + " be reference parameter" + " in line " + parDec.row);
  937.                         }
  938.  
  939.                         ptl = new ParamTypeList(new PrimitiveType(nTyp.name.toString()),
  940.                                         parDec.isRef, paramListRek2(dl.tail, globalTable));
  941.                 } else {
  942.                         aTyp = (ArrayTy) parDec.ty;
  943.  
  944.                         if (parDec.isRef == false) {
  945.                                 throw new Exception("Paramater must " + parDec.name
  946.                                                 + " be reference parameter" + " in line " + parDec.row);
  947.                         }
  948.  
  949.                         ptl = new ParamTypeList(new ArrayType(aTyp.size, typRek2(aTyp.ty,
  950.                                         globalTable)), parDec.isRef, paramListRek2(dl.tail,
  951.                                         globalTable));
  952.                 }
  953.                 return ptl;
  954.         }
  955.  
  956.         private Table erzeugeStartTabelle() {
  957.                 Table rueck = new Table();
  958.                 PrimitiveType pt = new PrimitiveType("bool");
  959.                 TypeEntry te = new TypeEntry(pt);
  960.                 rueck.enter(Sym.newSym("bool"), te);
  961.  
  962.                 pt = new PrimitiveType("int");
  963.                 te = new TypeEntry(pt);
  964.                 rueck.enter(Sym.newSym("int"), te);
  965.  
  966.                 ParamTypeList ptl = new ParamTypeList(pt, false, new ParamTypeList());
  967.                 ProcEntry pe = new ProcEntry(ptl, new Table());
  968.                 rueck.enter(Sym.newSym("printc"), pe);
  969.  
  970.                 ptl = new ParamTypeList(pt, true, new ParamTypeList());
  971.                 pe = new ProcEntry(ptl, new Table());
  972.                 rueck.enter(Sym.newSym("readi"), pe);
  973.  
  974.                 ptl = new ParamTypeList(pt, true, new ParamTypeList());
  975.                 pe = new ProcEntry(ptl, new Table());
  976.                 rueck.enter(Sym.newSym("readc"), pe);
  977.  
  978.                 ptl = new ParamTypeList();
  979.                 pe = new ProcEntry(ptl, new Table());
  980.                 rueck.enter(Sym.newSym("exit"), pe);
  981.  
  982.                 ptl = new ParamTypeList(pt, true, new ParamTypeList());
  983.                 pe = new ProcEntry(ptl, new Table());
  984.                 rueck.enter(Sym.newSym("time"), pe);
  985.  
  986.                 ptl = new ParamTypeList(pt, true, new ParamTypeList());
  987.                 pe = new ProcEntry(ptl, new Table());
  988.                 rueck.enter(Sym.newSym("clearAll"), pe);
  989.  
  990.                 ParamTypeList ptl3 = new ParamTypeList(pt, false, new ParamTypeList());
  991.                 ParamTypeList ptl2 = new ParamTypeList(pt, false, ptl3);
  992.                 ptl = new ParamTypeList(pt, false, ptl2);
  993.                 pe = new ProcEntry(ptl, new Table());
  994.                 rueck.enter(Sym.newSym("setPixel"), pe);
  995.  
  996.                 ParamTypeList ptl5 = new ParamTypeList(pt, false, new ParamTypeList());
  997.                 ParamTypeList ptl4 = new ParamTypeList(pt, false, ptl5);
  998.                 ptl3 = new ParamTypeList(pt, false, ptl4);
  999.                 ptl2 = new ParamTypeList(pt, false, ptl3);
  1000.                 ptl = new ParamTypeList(pt, false, ptl2);
  1001.                 pe = new ProcEntry(ptl, new Table());
  1002.                 rueck.enter(Sym.newSym("drawLine"), pe);
  1003.  
  1004.                 ptl4 = new ParamTypeList(pt, false, new ParamTypeList());
  1005.                 ptl3 = new ParamTypeList(pt, false, ptl4);
  1006.                 ptl2 = new ParamTypeList(pt, false, ptl3);
  1007.                 ptl = new ParamTypeList(pt, false, ptl2);
  1008.                 pe = new ProcEntry(ptl, new Table());
  1009.                 rueck.enter(Sym.newSym("drawCircle"), pe);
  1010.  
  1011.                 return rueck;
  1012.         }
  1013. }