package mycompiler.mystatement; import java.util.Enumeration; import java.util.Hashtable; import java.util.Iterator; import java.util.Vector; import mycompiler.mybytecode.ClassFile; import mycompiler.mybytecode.CodeAttribute; import mycompiler.mybytecode.JVMCode; import mycompiler.myclass.Class; import mycompiler.myexception.CTypeReconstructionException; import mycompiler.myexception.JVMCodeException; import mycompiler.myexception.SCExcept; import mycompiler.myexception.SCStatementException; import mycompiler.myoperator.LogOp; import mycompiler.myoperator.Operator; import mycompiler.myoperator.RelOp; import mycompiler.mytype.GenericTypeVar; import mycompiler.mytype.Pair; import mycompiler.mytype.RefType; import mycompiler.mytype.Type; import mycompiler.mytypereconstruction.CSupportData; import mycompiler.mytypereconstruction.CTriple; import mycompiler.mytypereconstruction.replacementlistener.CReplaceTypeEvent; import mycompiler.mytypereconstruction.set.CSubstitutionSet; import mycompiler.mytypereconstruction.set.CTripleSet; import mycompiler.mytypereconstruction.set.CTypeAssumptionSet; import mycompiler.mytypereconstruction.typeassumption.CTypeAssumption; import mycompiler.mytypereconstruction.unify.Unify; import org.apache.log4j.Logger; import sun.reflect.generics.reflectiveObjects.NotImplementedException; import typinferenz.ConstraintsSet; import typinferenz.JavaCodeResult; import typinferenz.ResultSet; import typinferenz.TypeAssumptions; public class ForStmt extends Statement { private Expr head_Initializer_1; private Expr head_Condition_1; private Expr head_Loop_expr_1; private Expr head_Initializer; private Expr head_Condition; private Expr head_Loop_expr; private Statement body_Loop_block; public ForStmt(int offset, int variableLength) { super(offset,variableLength); } void sc_check(Vector classname, Hashtable ch, Hashtable bh, boolean ext, Hashtable parach, Hashtable parabh) throws SCStatementException { } public void codegen(ClassFile classfile, CodeAttribute code, Vector paralist) throws JVMCodeException { } /** * Implementierung des Algorithmus 5.23 von Martin Pl�micke *
Achtung Workaround: RefType "Boolean" muss noch durch BaseType * "BooleanType" ersetzt werden. *
Author: J�rg B�uerle * @param sigma * @param V * @param supportData * @return */ public CTripleSet TRStatement(CSubstitutionSet sigma, CTypeAssumptionSet V, CSupportData supportData) { CTripleSet start_set = new CTripleSet(); CTripleSet init_set = new CTripleSet(); CTripleSet cond_set = new CTripleSet(); CTripleSet return_set = new CTripleSet(); //Expressions kopieren für die Typrekonstruktion um Codegen nicht zu tangieren head_Initializer_1 = head_Initializer; head_Condition_1 = head_Condition; head_Loop_expr_1 = head_Loop_expr; //Fälle überprüfen, in denen nicht alle drei Expressions im Schleifenkopf existieren //Überprüfen, ob eine Expression existiert und diese in ersatz speichern boolean condition_exists = true; Expr ersatz = null; if(head_Initializer_1 == null){ if(head_Condition_1 == null){ condition_exists = false; if(head_Loop_expr_1 == null){ //Falls keine Expression existiert, nur TRStatement mit Loop-Block return_set = body_Loop_block.TRStatement(sigma, V,supportData); return return_set; } else ersatz = head_Loop_expr_1; } else ersatz = head_Condition_1; } else ersatz = head_Initializer_1; //Falls mindestens eine Expression existiert, werden die leeren mit ersatz überschrieben if(ersatz != null){ if(head_Initializer_1 == null) head_Initializer_1 = ersatz; if(head_Condition_1 == null) head_Condition_1 = ersatz; if(head_Loop_expr_1 == null) head_Loop_expr_1 = ersatz; } //Folgender Code wird ausgeführt, wenn mindestens eine Expression existiert start_set = head_Initializer_1.TRExp(sigma,V,supportData); Iterator it_init = start_set.getIterator(); //-------------------------- // Initializer-Typ rekonstruieren: // -------------------------- int successfulls1 = 0; Vector exceptions1 = new Vector(); while( it_init.hasNext() ) { // CTriple initTriple = it_init.next(); // init_set.unite(head_Condition_1.TRExp(initTriple.getSubstitutions(), initTriple.getAssumptionSet(),supportData)); // //init_set = head_Condition_1.TRExp(initTriple.getSubstitutions(), initTriple.getAssumptionSet(),supportData); // Type r = initTriple.getResultType(); try{ CTriple initTriple = it_init.next(); CTripleSet condit = head_Condition_1.TRExp(initTriple.getSubstitutions(), initTriple.getAssumptionSet (),supportData); init_set.unite( condit ); //init_set = head_Condition_1.TRExp(initTriple.getSubstitutions(), initTriple.getAssumptionSet(),supportData); Type r = initTriple.getResultType (); successfulls1++; } catch (CTypeReconstructionException tre) { exceptions1.addElement(tre); } } if (successfulls1 == 0) { if (exceptions1.size() == 1) { throw exceptions1.elementAt(0); } throw new CTypeReconstructionException( "ForStmt: Es konnte keine Assumption gefunden werden, die auf die Anforderung passt.", exceptions1, this); } Iterator it_cond = init_set.getIterator(); while(it_cond.hasNext()){ CTriple condTriple = it_cond.next(); //Wird ausgeführt, falls die Condition existiert if(condition_exists == true){ // -------------------------- // Rückgabe der Condition mit Boolean unifizieren: // -------------------------- Vector> cond_poss = Unify.unify(condTriple.getResultType(), new RefType("java.lang.Boolean",getOffset()), supportData.getFiniteClosure()); // System.out.println("cond_set:"+cond_set.toString()); // System.out.println("condTriple:"+condTriple.toString()); if (cond_poss.size() != 0) { // -------------------------- // Alle möglichen Unifier anwenden: // -------------------------- int successfulls = 0; Vector exceptions = new Vector(); for (int i = 0; i < cond_poss.size(); i++) { // -------------------------- // Condition-Typ rekonstruieren: // -------------------------- try { CSubstitutionSet unifier = new CSubstitutionSet(cond_poss.elementAt(i)); CTriple boolTriple = condTriple.cloneAndApplyUnify(unifier); cond_set.unite(head_Loop_expr_1.TRExp(boolTriple.getSubstitutions(), boolTriple.getAssumptionSet(), supportData)); successfulls++; } catch (CTypeReconstructionException tre) { exceptions.addElement(tre); } if (successfulls == 0) { if (exceptions.size() == 1) { throw exceptions.elementAt(0); } throw new CTypeReconstructionException( "ForStmt: Es konnte keine Assumption gefunden werden, die auf die Anforderung passt.", exceptions, this); } } } else { throw new CTypeReconstructionException("ForStmt.TRStatement(): Bedingung muss boolean sein!",this); } } //Wird ausgeführt, falls keine Condition existiert else{ int successfulls2 = 0; Vector exceptions2 = new Vector(); try{ CTripleSet condit = head_Loop_expr_1.TRExp(condTriple.getSubstitutions(), condTriple.getAssumptionSet (),supportData); cond_set.unite( condit ); successfulls2++; } catch (CTypeReconstructionException tre) { exceptions2.addElement(tre); } if (successfulls2 == 0) { if (exceptions2.size() == 1) { throw exceptions2.elementAt(0); } throw new CTypeReconstructionException( "ForStmt: Es konnte keine Assumption gefunden werden, die auf die Anforderung passt.", exceptions2, this); } } } Iterator it_loop_block = cond_set.getIterator(); // -------------------------- // Loop-Expression-Typ rekonstruieren: // -------------------------- while( it_loop_block.hasNext() ) { CTriple loop_blockTriple = it_loop_block.next(); return_set.unite(body_Loop_block.TRStatement(loop_blockTriple.getSubstitutions(), loop_blockTriple.getAssumptionSet(),supportData)); } return return_set; } public String toString() { return "FOR "; } public void wandleRefTypeAttributes2GenericAttributes(Vector paralist, Vector genericMethodParameters) { if(body_Loop_block!=null){ body_Loop_block.wandleRefTypeAttributes2GenericAttributes(paralist,genericMethodParameters); } } public void set_head_Initializer(Expr expr) { head_Initializer = expr; } public void set_head_Condition(Expr expr) { head_Condition = expr; } public void set_head_Loop_expr(Expr expr) { head_Loop_expr = expr; } public void set_body_Loop_block(Statement statement) { body_Loop_block = statement; } public boolean addOffsetsToStatement(CTypeAssumption localAssumption, String NameVariable, boolean isMemberVariable) { head_Initializer_1.addOffsetsToStatement(localAssumption,NameVariable,isMemberVariable); body_Loop_block.addOffsetsToStatement(localAssumption,NameVariable,isMemberVariable); return true; } @Override public ConstraintsSet TYPEStmt(TypeAssumptions assumptions) { // TODO Auto-generated method stub return null; } public void replaceType(CReplaceTypeEvent e) { // TODO Auto-generated method stub throw new NotImplementedException(); } public int getTypeLineNumber() { throw new NotImplementedException(); } @Override public JavaCodeResult printJavaCode(ResultSet resultSet) { // TODO Auto-generated method stub throw new NotImplementedException(); } }