// ino.module.IfStmt.8632.package package de.dhbwstuttgart.syntaxtree.statement; // ino.end // ino.module.IfStmt.8632.import import java.util.Enumeration; import java.util.Hashtable; import java.util.Iterator; import java.util.Vector; import org.apache.log4j.Logger; import de.dhbwstuttgart.bytecode.ClassFile; import de.dhbwstuttgart.bytecode.CodeAttribute; import de.dhbwstuttgart.bytecode.JVMCode; import de.dhbwstuttgart.myexception.CTypeReconstructionException; import de.dhbwstuttgart.myexception.JVMCodeException; import de.dhbwstuttgart.myexception.SCExcept; import de.dhbwstuttgart.myexception.SCStatementException; import de.dhbwstuttgart.syntaxtree.Class; import de.dhbwstuttgart.syntaxtree.SyntaxTreeNode; import de.dhbwstuttgart.syntaxtree.operator.LogOp; import de.dhbwstuttgart.syntaxtree.operator.Operator; import de.dhbwstuttgart.syntaxtree.operator.RelOp; import de.dhbwstuttgart.syntaxtree.type.BooleanType; import de.dhbwstuttgart.syntaxtree.type.GenericTypeVar; import de.dhbwstuttgart.syntaxtree.type.RefType; import de.dhbwstuttgart.syntaxtree.type.Type; import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder; import de.dhbwstuttgart.syntaxtree.type.Void; import de.dhbwstuttgart.typeinference.ConstraintsSet; import de.dhbwstuttgart.typeinference.JavaCodeResult; import de.dhbwstuttgart.typeinference.Pair; import de.dhbwstuttgart.typeinference.ResultSet; import de.dhbwstuttgart.typeinference.SingleConstraint; import de.dhbwstuttgart.typeinference.assumptions.TypeAssumptions; import de.dhbwstuttgart.typeinference.exceptions.NotImplementedException; import de.dhbwstuttgart.typeinference.unify.MUB; import de.dhbwstuttgart.typeinference.unify.Unify; // ino.class.IfStmt.25300.declaration public class IfStmt extends Statement // ino.end // ino.class.IfStmt.25300.body { // ino.method.IfStmt.25304.definition public IfStmt(int offset, int variableLength) // ino.end // ino.method.IfStmt.25304.body { super(offset,variableLength); } // ino.end // ino.attribute.hamaDebug.25307.declaration public boolean hamaDebug = true; //hama: Debug Ausgaben von mir ein- bzw. ausschalten // ino.end // ino.attribute.expr.25310.declaration public Expr expr; // ino.end // ino.attribute.then_block.25313.declaration public Statement then_block; // ino.end // ino.attribute.else_block.25316.declaration public Statement else_block; // ino.end // ino.attribute.parserlog.25319.declaration protected static Logger parserlog = Logger.getLogger("parser"); // ino.end // ino.method.set_Expr.25322.definition public void set_Expr(Expr exp) // ino.end // ino.method.set_Expr.25322.body { this.expr = exp; } // ino.end // ino.method.set_Then_block.25325.definition public void set_Then_block(Statement blk) // ino.end // ino.method.set_Then_block.25325.body { this.then_block = blk; } // ino.end // ino.method.set_Else_block.25328.definition public void set_Else_block(Statement blk) // ino.end // ino.method.set_Else_block.25328.body { this.else_block = blk; } // ino.end // ino.method.codegen.25334.definition public void codegen(ClassFile classfile, CodeAttribute code, Vector paralist) throws JVMCodeException // ino.end // ino.method.codegen.25334.body { if_codegen(classfile, code, false, paralist); } // ino.end // ino.method.if_codegen.25337.definition public void if_codegen(ClassFile classfile, CodeAttribute code, boolean not, Vector paralist) throws JVMCodeException // ino.end // ino.method.if_codegen.25337.body { if(expr instanceof NotExpr) { expr = ((NotExpr)expr).get_Expr(); if_codegen(classfile, code, !not, paralist); } else { if(expr instanceof Binary) { Operator op = ((Binary)expr).get_Operator(); if(op instanceof LogOp) { ((LogOp)op).if_codegen(classfile, code, not, expr, then_block, else_block, paralist); } else { if(op instanceof RelOp) { Expr expr1 = ((Binary)expr).get_Expr1(); Expr expr2 = ((Binary)expr).get_Expr2(); expr1.codegen(classfile, code, paralist); expr2.codegen(classfile, code, paralist); if(expr1 instanceof Null || expr2 instanceof Null) { ((RelOp)op).if_codegen(classfile, code, "null", not); } else { ((RelOp)op).if_codegen(classfile, code, expr1.getTypeName(), not); } int breakpoint1 = code.get_code_length(); code.add_code_short(0); if(then_block!=null) { then_block.codegen(classfile, code, paralist); code.set_code_short(code.get_code_length() + 1 - breakpoint1, breakpoint1); } int breakpoint2 = code.get_code_length(); if(else_block != null) { code.add_code(JVMCode.goto_); code.add_code_short(0); // replaced later else_block.codegen(classfile, code, paralist); code.set_code_short(breakpoint2 + 4 - breakpoint1, breakpoint1); code.set_code_short(code.get_code_length() - breakpoint2, breakpoint2 + 1); } } else { throw new JVMCodeException("JVMCodeException: IfStmt: void if_codegen(ClassFile classfile, Code_attribute code, boolean not)"); } } } else { expr.codegen(classfile, code, paralist); if(!not) { code.add_code(JVMCode.ifeq); } else { code.add_code(JVMCode.ifne); } int breakpoint1 = code.get_code_length(); code.add_code_short(0); if(then_block!=null) { then_block.codegen(classfile, code, paralist); code.set_code_short(code.get_code_length() + 1 - breakpoint1, breakpoint1); } int breakpoint2 = code.get_code_length(); if(!(else_block==null || else_block instanceof EmptyStmt)) { //hama: Die zwei folgenen if-Abfragen wurden eingef�gt und beheben den Bug, //der zuerst im Use Case Toggle1 bemerkt wurde. Hier wird nun gepr�ft ob der //letzte Befehl in einem if-Block ein return war. Trifft dieser Fall zu, //so wird kein goto Befehl (f�r das �berspringen des else-Blocks eingef�gt) //-> das verlangt die vm ->der code w�re nicht erreichbar. //Allerdings k�nnte das return-Statement nat�rlich auch an einer anderen //Stelle (nicht als letzter Befehl) stehen, f�r diesen Fall d�rfte die //Codegenerierung noch nicht funktionieren. Hab versucht diesen Fall mit //Toggle3 zu erzeugen - wird aber richtig generiert. //letztes Statement im Vector in s schreiben //Statement s = (Statement)(((Block)this.then_block).statements.lastElement()); //Instanz von Return zum pr�fen anlegen Return r = new Return(getOffset(),getVariableLength()); if( !(((Block)this.then_block).statements.lastElement()).getClass().equals(r.getClass()) ) { code.add_code(JVMCode.goto_); code.add_code_short(0); } else_block.codegen(classfile, code, paralist); if( !(((Block)this.then_block).statements.lastElement()).getClass().equals(r.getClass()) ) { code.set_code_short(breakpoint2 + 4 - breakpoint1, breakpoint1); code.set_code_short(code.get_code_length()-breakpoint2, breakpoint2 + 1); } } } } } // ino.end // ino.method.wandleRefTypeAttributes2GenericAttributes.25349.definition public void wandleRefTypeAttributes2GenericAttributes(Vector paralist, Vector genericMethodParameters) // ino.end // ino.method.wandleRefTypeAttributes2GenericAttributes.25349.body { if(then_block!=null){ then_block.wandleRefTypeAttributes2GenericAttributes(paralist,genericMethodParameters); } if(else_block!=null){ else_block.wandleRefTypeAttributes2GenericAttributes(paralist,genericMethodParameters); } } // ino.end @Override public ConstraintsSet TYPEStmt(TypeAssumptions assumptions) { ConstraintsSet ret = new ConstraintsSet(); this.setType(TypePlaceholder.fresh(this)); ret.add(expr.TYPEExpr(assumptions)); // die Constraints für (expressionDesIfStmt) ret.add(this.then_block.TYPEStmt(assumptions)); if(else_block!=null){ ret.add(this.else_block.TYPEStmt(assumptions)); if(!(else_block.getType() instanceof Void))ret.add(new SingleConstraint(else_block.getType().TYPE(assumptions, this),this.getType().TYPE(assumptions, this))); } ret.add(new SingleConstraint(expr.getType().TYPE(assumptions, this),assumptions.getTypeFor(new RefType("Boolean",this,0), this))); //(expressionDesIfStmt)<.boolean if(!(then_block.getType() instanceof Void))ret.add(new SingleConstraint(then_block.getType().TYPE(assumptions, this),this.getType().TYPE(assumptions, this))); if(then_block.getType() instanceof Void && (else_block == null || else_block.getType() instanceof Void))this.setType(new Void(this,this.getOffset())); return ret; } public int getTypeLineNumber() { throw new NotImplementedException(); } @Override public JavaCodeResult printJavaCode(ResultSet resultSet) { JavaCodeResult ret = new JavaCodeResult("If(").attach(this.expr.printJavaCode(resultSet)).attach("){\n"); if(this.then_block!=null)ret.attach(this.then_block.printJavaCode(resultSet)); ret.attach("\n}else{\n"); if(this.else_block!=null)ret.attach(this.else_block.printJavaCode(resultSet)); ret.attach("\n}"); return ret; } @Override public Vector getChildren() { Vector ret = new Vector(); if(this.expr!=null)ret.add(this.expr); if(this.else_block!=null)ret.add(this.else_block); if(this.then_block!=null)ret.add(this.then_block); return ret; } } // ino.end