package mycompiler.mystatement; import java.util.Hashtable; import java.util.Vector; import typinferenz.JavaCodeResult; import typinferenz.SingleConstraint; import typinferenz.ConstraintsSet; import typinferenz.FreshTypeVariable; import typinferenz.FunN; import typinferenz.ResultSet; import typinferenz.Typable; import typinferenz.TypinferenzException; import typinferenz.assumptions.TypeAssumptions; import mycompiler.mybytecode.ClassFile; import mycompiler.mybytecode.CodeAttribute; import mycompiler.myclass.Class; import mycompiler.myclass.FormalParameter; import mycompiler.myclass.Method; import mycompiler.myclass.ParameterList; import mycompiler.myexception.CTypeReconstructionException; import mycompiler.myexception.JVMCodeException; import mycompiler.myexception.SCStatementException; import mycompiler.mytype.DoubleType; import mycompiler.mytype.GenericTypeVar; import mycompiler.mytype.Type; import mycompiler.mytype.TypePlaceholder; import mycompiler.mytypereconstruction.CSupportData; import mycompiler.mytypereconstruction.CTriple; import mycompiler.mytypereconstruction.set.CSubstitutionSet; import mycompiler.mytypereconstruction.set.CTripleSet; import mycompiler.mytypereconstruction.set.CTypeAssumptionSet; import mycompiler.mytypereconstruction.typeassumption.CParaTypeAssumption; import mycompiler.mytypereconstruction.typeassumption.CTypeAssumption; /** * @author A10023 - Andreas Stadelmeier * Momentan erweitert LambdaExpression noch Expr und erbt dadurch auch von ExprStatement ist also auch ein Statement * * LambdaExpression Aufbau: * ( ParameterList ) -> { method_body }; */ public class LambdaExpression extends Expr{ private Block method_body; private ParameterList params; public LambdaExpression(int offset, int variableLength) { super(offset, variableLength); setParameterList(new ParameterList());//default is empty parameterlist } public void setBody(Block block){ method_body = block; } public void setExpr(Expr expression){ Block bl = new Block(); Return returnStmt = new Return(0, 0); returnStmt.retexpr = expression; bl.set_Statement(returnStmt); this.setBody(bl); } public void setParameterList(ParameterList params){ this.params = params; } @Override public void codegen(ClassFile classfile, CodeAttribute code, Vector paralist) throws JVMCodeException { // TODO Auto-generated method stub } @Override public void wandleRefTypeAttributes2GenericAttributes( Vector paralist, Vector genericMethodParameters) { // TODO Auto-generated method stub } @Override public boolean addOffsetsToStatement(CTypeAssumption localAssumption, String NameVariable, boolean isMemberVariable) { // TODO Auto-generated method stub return false; } @Override public String get_Name() { // TODO Auto-generated method stub return null; } @Override public void addOffsetsToExpression(CTypeAssumption localAssumption, String NameVariable, boolean isMemberVariable) { // TODO Auto-generated method stub } /** * Spezifikation: * * TYPEExpr( Ass, Lambda( (x1 , . . . , xN ), expr|stmt ) ) = * let * AssArgs = { xi : ai | ai fresh type variables } * (exprt : rty, ConS) = TYPEExpr( Ass ∪ AssArgs, expr ) * | (stmtt : rty, ConS) = TYPEStmt( Ass u AssArgs, stmt ) * in * (Lambda( (x1 : a1 , . . . , xN : aN ), exprt : rty|stmtt : rty ) : a, * ConS ∪ { (FunN a) }), * where a is a fresh type variable */ @Override public ConstraintsSet TYPEExpr(TypeAssumptions assumptions) { ConstraintsSet ret = new ConstraintsSet(); //Die Assumptions für die Parameter der LambdaExpression TypeAssumptions ArgumentAssumptions = new TypeAssumptions(assumptions.getThisValue().getName()); Vector paramTypes = new Vector(); for(FormalParameter param : params.formalparameter){ if(param.getTypeVariable()==null)param.setTypeVariable(TypePlaceholder.fresh(this)); int offset = 0; //Jeder Parameter der LambdaExpression wird als CParaTypeAssumption der Assumption liste hinzugefügt: ArgumentAssumptions.add(new CParaTypeAssumption("", "", offset, offset, param.get_Name(), param.getTypeVariable(), offset, offset, null)); paramTypes.add(param.getTypeVariable()); } this.setTypeVariable(TypePlaceholder.fresh(this)); //ArgumentAssumptions + assumptions ergeben die Assumptions für die Statements innerhalb des Lambda-Bodys: ret.add(method_body.TYPEStmt(ArgumentAssumptions.add(assumptions))); //Es gibt die LambdaExpression nur mit einem Block als Method Body, nicht mit einer einzelnen Expression ret.add(new SingleConstraint(new FunN(method_body.getTypeVariable(), paramTypes),this.getTypeVariable())); return ret; } @Override public ConstraintsSet TYPEStmt(TypeAssumptions ass){ throw new TypinferenzException("Eine LambdaExpression darf nicht als Statement verwendet werden."); } @Override public String getTypeInformation(){ return this.getTypeVariable().toString()+" :: ("+this.params.getTypeInformation()+ ") -> " +this.method_body.getTypeInformation(); } @Override public String toString(){ //return "LambdaExpression, Parameter: "+this.params+ ", Body: " +this.method_body; return this.getType() + " (("+this.params+ ") -> "+this.method_body + ")"; } @Override public JavaCodeResult printJavaCode(ResultSet resultSet){ JavaCodeResult ret = new JavaCodeResult(); ret.attach( "(").attach(this.params.printJavaCode(resultSet)).attach(")"); ret.attach( " -> ").attach( this.method_body.printJavaCode(resultSet)); return ret; } }