2013-10-18 11:33:46 +00:00
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 ;
2014-02-09 15:07:31 +00:00
import typinferenz.assumptions.TypeAssumptions ;
2013-10-18 11:33:46 +00:00
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 < Type > paralist ,
Vector < GenericTypeVar > 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 < rty , a1 , . . . , aN > 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 < Type > paramTypes = new Vector < Type > ( ) ;
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 ;
}
}