2014-09-02 08:33:54 +00:00
package de.dhbwstuttgart.syntaxtree.statement ;
2013-10-18 11:33:46 +00:00
import java.util.Hashtable ;
import java.util.Vector ;
2014-09-04 14:35:44 +00:00
import de.dhbwstuttgart.bytecode.ClassFile ;
import de.dhbwstuttgart.bytecode.CodeAttribute ;
import de.dhbwstuttgart.myexception.CTypeReconstructionException ;
import de.dhbwstuttgart.myexception.JVMCodeException ;
import de.dhbwstuttgart.myexception.SCStatementException ;
2014-09-02 08:33:54 +00:00
import de.dhbwstuttgart.syntaxtree.Class ;
import de.dhbwstuttgart.syntaxtree.ClassHelper ;
import de.dhbwstuttgart.syntaxtree.FormalParameter ;
import de.dhbwstuttgart.syntaxtree.Method ;
import de.dhbwstuttgart.syntaxtree.ParameterList ;
2014-09-04 14:35:44 +00:00
import de.dhbwstuttgart.syntaxtree.SyntaxTreeNode ;
2014-09-02 08:33:54 +00:00
import de.dhbwstuttgart.syntaxtree.type.DoubleType ;
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.typeinference.ConstraintsSet ;
import de.dhbwstuttgart.typeinference.FreshTypeVariable ;
import de.dhbwstuttgart.typeinference.FunN ;
import de.dhbwstuttgart.typeinference.JavaCodeResult ;
import de.dhbwstuttgart.typeinference.ResultSet ;
import de.dhbwstuttgart.typeinference.SingleConstraint ;
import de.dhbwstuttgart.typeinference.Typeable ;
import de.dhbwstuttgart.typeinference.assumptions.ParameterAssumption ;
import de.dhbwstuttgart.typeinference.assumptions.TypeAssumptions ;
import de.dhbwstuttgart.typeinference.exceptions.TypeinferenceException ;
2013-10-18 11:33:46 +00:00
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 ) {
2014-04-23 13:19:56 +00:00
ParameterList lambdaParameter = new ParameterList ( ) ;
for ( FormalParameter fp : params ) {
lambdaParameter . formalparameter . add ( new LambdaParameter ( fp ) ) ;
}
this . params = lambdaParameter ;
2013-10-18 11:33:46 +00:00
}
@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 ) {
2014-03-27 15:43:07 +00:00
Block block = this . method_body ;
// Zuerst Returntype untersuchen
Type returnType = getType ( ) ;
2014-04-14 16:05:24 +00:00
Type pendantReturnType = null ;
if ( returnType instanceof RefType )
pendantReturnType = ( ( RefType ) returnType ) . findGenericType ( paralist , new Vector < GenericTypeVar > ( ) ) ;
//GenericTypeVar pendantReturnType=ClassHelper.findGenericType(returnType, paralist,genericMethodParameters);
2014-03-27 15:43:07 +00:00
if ( pendantReturnType ! = null ) { //Wenn generisch, dann modifizieren
setType ( pendantReturnType ) ;
}
// Dann parameterlist untersuchen
for ( FormalParameter fp : params ) {
Type fpType = fp . getType ( ) ;
// Nur wenn es sich um ein RefType-Field handelt
2014-04-14 16:05:24 +00:00
Type pendantPara = null ;
if ( fpType instanceof RefType )
pendantPara = ( ( RefType ) fpType ) . findGenericType ( paralist , new Vector < GenericTypeVar > ( ) ) ;
//GenericTypeVar pendantPara=ClassHelper.findGenericType(fpType,paralist,genericMethodParameters);
2014-03-27 15:43:07 +00:00
if ( pendantPara ! = null ) { //Wenn generisch, dann modifizieren
fp . setType ( pendantPara ) ;
}
}
// Zuletzt alle Lokalen Variablendeklarationen durchgehen
if ( block ! = null ) {
block . wandleRefTypeAttributes2GenericAttributes ( paralist , genericMethodParameters ) ;
}
2013-10-18 11:33:46 +00:00
}
@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
2014-03-18 19:18:57 +00:00
TypeAssumptions ArgumentAssumptions = new TypeAssumptions ( this . getParentClass ( ) . getName ( ) ) ;
2013-10-18 11:33:46 +00:00
Vector < Type > paramTypes = new Vector < Type > ( ) ;
for ( FormalParameter param : params . formalparameter ) {
2014-02-11 15:30:38 +00:00
if ( param . getType ( ) = = null ) param . setType ( TypePlaceholder . fresh ( this ) ) ;
2013-10-18 11:33:46 +00:00
int offset = 0 ;
//Jeder Parameter der LambdaExpression wird als CParaTypeAssumption der Assumption liste hinzugefügt:
2014-04-09 12:12:55 +00:00
ArgumentAssumptions . addAssumption ( new ParameterAssumption ( param ) ) ;
2014-02-11 15:30:38 +00:00
paramTypes . add ( param . getType ( ) ) ;
2013-10-18 11:33:46 +00:00
}
2014-02-11 15:30:38 +00:00
this . setType ( TypePlaceholder . fresh ( this ) ) ;
2013-10-18 11:33:46 +00:00
//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
2014-02-11 15:30:38 +00:00
ret . add ( new SingleConstraint ( new FunN ( method_body . getType ( ) , paramTypes ) , this . getType ( ) ) ) ;
2013-10-18 11:33:46 +00:00
return ret ;
}
@Override
public ConstraintsSet TYPEStmt ( TypeAssumptions ass ) {
2014-04-15 12:56:20 +00:00
throw new TypeinferenceException ( " Eine LambdaExpression darf nicht als Statement verwendet werden. " , this ) ;
2013-10-18 11:33:46 +00:00
}
@Override
public String getTypeInformation ( ) {
2014-02-11 15:30:38 +00:00
return this . getType ( ) . toString ( ) + " :: ( " + this . params . getTypeInformation ( ) + " ) -> " + this . method_body . getTypeInformation ( ) ;
2013-10-18 11:33:46 +00:00
}
@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 ;
}
2014-02-22 03:58:49 +00:00
@Override
public Vector < SyntaxTreeNode > getChildren ( ) {
Vector < SyntaxTreeNode > ret = new Vector < SyntaxTreeNode > ( ) ;
ret . add ( this . method_body ) ;
2014-04-16 14:02:16 +00:00
for ( FormalParameter fp : this . params ) ret . add ( fp ) ;
2014-02-22 03:58:49 +00:00
return ret ;
}
2013-10-18 11:33:46 +00:00
}