type) {
ASTNode n = getParentNode();
while ((!type.isInstance(n)) && (n != null)) {
n = n.getParentNode();
}
- return n;
+ return (T) n;
}
/** Set parent node.
diff --git a/src/main/java/de/uni/bremen/monty/moco/ast/ClassScope.java b/src/main/java/de/uni/bremen/monty/moco/ast/ClassScope.java
index 330107b..26fb875 100644
--- a/src/main/java/de/uni/bremen/monty/moco/ast/ClassScope.java
+++ b/src/main/java/de/uni/bremen/monty/moco/ast/ClassScope.java
@@ -39,9 +39,18 @@
package de.uni.bremen.monty.moco.ast;
import de.uni.bremen.monty.moco.ast.declaration.*;
+import de.uni.bremen.monty.moco.ast.types.FunctionType;
+import de.uni.bremen.monty.moco.ast.types.TypeContext;
+import de.uni.bremen.monty.moco.ast.types.TypeFactory;
import de.uni.bremen.monty.moco.exception.*;
+import de.uni.bremen.monty.moco.util.JavaUtil;
+import de.uni.bremen.monty.moco.visitor.VisitOnceVisitor;
+
+import java.util.Collections;
import java.util.List;
import java.util.ArrayList;
+import java.util.Optional;
+import java.util.stream.Collectors;
/** A scope in which identifier are associated with declarations.
*
@@ -64,6 +73,7 @@
* Note: only single inheritance so far. */
public class ClassScope extends Scope {
+ private final TypeContext context;
/** The parent class in inheritance hierachy. */
private List parentClassesScopes;
@@ -71,8 +81,9 @@ public class ClassScope extends Scope {
*
* @param parent
* the parent scope in nesting hierachy */
- public ClassScope(Scope parent) {
+ public ClassScope(Scope parent, TypeContext context) {
super(parent);
+ this.context = context;
this.parentClassesScopes = new ArrayList<>();
}
@@ -85,23 +96,23 @@ public void addParentClassScope(ClassScope scope) {
* @param identifier
* the identifier
* @return the declaration or null if nothing is found */
- protected Declaration resolveMember(ResolvableIdentifier identifier) {
+ protected Optional resolveMember(ResolvableIdentifier identifier) {
Declaration declaration = members.get(identifier);
if (declaration != null) {
- return declaration;
+ return Optional.of(declaration);
}
for (ClassScope scope : parentClassesScopes) {
try {
- declaration = scope.resolveMember(identifier);
+ Optional parentDecl = scope.resolveMember(identifier);
+ if(parentDecl.isPresent()){
+ return parentDecl;
+ }
} catch (StackOverflowError soe) {
throw new CyclicDependencyException("Cyclic dependency detected: " + identifier.getSymbol());
}
- if (declaration != null) {
- return declaration;
- }
}
- return null;
+ return Optional.empty();
}
/** Resolve an identifier for list of overloaded functions in inherited scope.
@@ -109,18 +120,21 @@ protected Declaration resolveMember(ResolvableIdentifier identifier) {
* @param identifier
* the identifier to resolve
* @return the list of function declarations */
- protected List resolveFunctionMember(ResolvableIdentifier identifier) {
- List result = new ArrayList<>();
+ protected List resolveFunctionMember(ResolvableIdentifier identifier, VisitOnceVisitor visitor) {
+ List result = new ArrayList<>();
if (functions.containsKey(identifier)) {
- result.addAll(functions.get(identifier));
+ result.addAll(getResolvedFunctions(identifier,visitor));
}
if (members.containsKey(identifier)) {
- result.add(members.get(identifier));
+ Declaration declaration = members.get(identifier);
+ if(isFunctionVariable(declaration)) {
+ result.add(TypeFactory.createFunction((VariableDeclaration) declaration));
+ }
}
for (ClassScope scope : parentClassesScopes) {
- result.addAll(scope.resolveFunctionMember(identifier));
+ result.addAll(scope.resolveFunctionMember(identifier,visitor));
}
return result;
}
@@ -133,13 +147,8 @@ protected List resolveFunctionMember(ResolvableIdentifier identifie
* the identifier to resolve
* @return the declaration or null if nothing is found */
@Override
- public Declaration resolve(ResolvableIdentifier identifier) {
- Declaration declaration = resolveMember(identifier);
-
- if (declaration != null) {
- return declaration;
- }
- return super.resolve(identifier);
+ public Optional _resolve(ResolvableIdentifier identifier) {
+ return JavaUtil.or(resolveMember(identifier), () -> super._resolve(identifier));
}
/** Resolve an identifier for list of overloaded functions.
@@ -150,18 +159,35 @@ public Declaration resolve(ResolvableIdentifier identifier) {
* the identifier to resolve
* @return the list of function declarations */
@Override
- public List resolveFunction(ResolvableIdentifier identifier) {
- List result = new ArrayList<>();
- result.addAll(resolveFunctionMember(identifier));
+ public Optional> _resolveFunction(ResolvableIdentifier identifier, VisitOnceVisitor visitor) {
+ List result = new ArrayList<>();
+ result.addAll(resolveFunctionMember(identifier,visitor));
if (parent != null) {
- try {
- result.addAll(parent.resolveFunction(identifier));
- } catch (UnknownIdentifierException e) {
- }
+ result.addAll(parent._resolveFunction(identifier, visitor).orElse(Collections.emptyList()));
}
if (result.isEmpty()) {
- throw new UnknownIdentifierException(identifier);
+ return Optional.empty();
}
- return result;
+ return Optional.of(result);
+ }
+
+ @Override
+ protected List getResolvedFunctions(ResolvableIdentifier identifier, VisitOnceVisitor visitor) {
+ return functions.get(identifier).stream().map(f -> {
+ visitor.visitDoubleDispatched(f);
+ return TypeFactory.from(f, context);
+ }).collect(Collectors.toList());
+ }
+
+ public ClassScope extend(TypeContext context) {
+ ClassScope classScope = new ClassScope(parent, this.context.extend(context));
+ classScope.parentClassesScopes = this.parentClassesScopes;
+ classScope.members = this.members;
+ classScope.functions = this.functions;
+ return classScope;
+ }
+
+ public TypeContext getContext() {
+ return context;
}
}
diff --git a/src/main/java/de/uni/bremen/monty/moco/ast/CoreClasses.java b/src/main/java/de/uni/bremen/monty/moco/ast/CoreClasses.java
index dcc2f26..1a1e67b 100644
--- a/src/main/java/de/uni/bremen/monty/moco/ast/CoreClasses.java
+++ b/src/main/java/de/uni/bremen/monty/moco/ast/CoreClasses.java
@@ -47,16 +47,24 @@
public class CoreClasses {
- private static Map coreClasses = new HashMap();
+ public static final String OBJECT_SYMBOL = "Object";
+ public static final String VOID_SYMBOL = "__void";
+
+ private static Map coreClasses;
static {
+ reset();
+ }
+
+ public static void reset() {
+ coreClasses = new HashMap<>();
// TODO find name for void that is not a valid identifier
String[] classNames =
- new String[] { "Object", "Char", "String", "Int", "Float", "Bool", "Array", "__void", "Function" };
+ new String[] { "Object", "Char", "String", "Int", "Float", "Bool", "NativeArray", VOID_SYMBOL, "Function" };
for (String name : classNames) {
CoreClasses.setCoreClass(name, new ClassDeclaration(new Position("Dummy_" + name, 0, 0), new Identifier(
- name), Collections. emptyList(), new Block(
- new Position("Dummy_" + name, 1, 0))));
+ name), Collections.emptyList(), new Block(
+ new Position("Dummy_" + name, 1, 0)), true));
}
}
@@ -65,7 +73,7 @@ public static void setCoreClass(String name, ClassDeclaration classDeclaration)
}
public static ClassDeclaration objectType() {
- return coreClasses.get("Object");
+ return coreClasses.get(OBJECT_SYMBOL);
}
public static ClassDeclaration charType() {
@@ -89,7 +97,7 @@ public static ClassDeclaration boolType() {
}
public static ClassDeclaration arrayType() {
- return coreClasses.get("Array");
+ return coreClasses.get("NativeArray");
}
public static ClassDeclaration functionType() {
@@ -97,6 +105,6 @@ public static ClassDeclaration functionType() {
}
public static ClassDeclaration voidType() {
- return coreClasses.get("__void");
+ return coreClasses.get(VOID_SYMBOL);
}
}
diff --git a/src/main/java/de/uni/bremen/monty/moco/ast/ResolvableIdentifier.java b/src/main/java/de/uni/bremen/monty/moco/ast/ResolvableIdentifier.java
index 7bdc34c..6f979b6 100644
--- a/src/main/java/de/uni/bremen/monty/moco/ast/ResolvableIdentifier.java
+++ b/src/main/java/de/uni/bremen/monty/moco/ast/ResolvableIdentifier.java
@@ -99,6 +99,7 @@ public String toString() {
for (ResolvableIdentifier generic : getGenericTypes()) {
generics += generic != null ? generic.toString() + ", " : "?, ";
}
+ generics = generics.substring(0, generics.length()-2);
generics += ">";
}
return getSymbol() + generics;
diff --git a/src/main/java/de/uni/bremen/monty/moco/ast/Scope.java b/src/main/java/de/uni/bremen/monty/moco/ast/Scope.java
index d3bf962..74da6e5 100644
--- a/src/main/java/de/uni/bremen/monty/moco/ast/Scope.java
+++ b/src/main/java/de/uni/bremen/monty/moco/ast/Scope.java
@@ -39,15 +39,15 @@
package de.uni.bremen.monty.moco.ast;
import de.uni.bremen.monty.moco.ast.declaration.*;
+import de.uni.bremen.monty.moco.ast.types.*;
import de.uni.bremen.monty.moco.exception.InvalidExpressionException;
import de.uni.bremen.monty.moco.exception.RedeclarationException;
import de.uni.bremen.monty.moco.exception.UnknownIdentifierException;
import de.uni.bremen.monty.moco.exception.UnknownTypeException;
+import de.uni.bremen.monty.moco.visitor.VisitOnceVisitor;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
+import java.util.*;
+import java.util.stream.Collectors;
/** A scope in which an identifier is associated with a declaration.
*
@@ -103,15 +103,19 @@ public Scope getParentScope() {
* the identifier to resolve
* @return the declaration */
public Declaration resolve(ResolvableIdentifier identifier) {
+ return _resolve(identifier).orElseThrow(() -> new UnknownIdentifierException(identifier));
+ }
+
+ protected Optional _resolve(ResolvableIdentifier identifier) {
Declaration declaration = members.get(identifier);
if (declaration != null) {
- return declaration;
+ return Optional.of(declaration);
}
if (functions.containsKey(identifier)) {
List functionDeclarations = functions.get(identifier);
if (functionDeclarations.size() == 1) {
- return functionDeclarations.get(0).getWrapperFunctionObjectDeclaration();
+ return Optional.ofNullable(functionDeclarations.get(0).getWrapperFunctionObjectDeclaration());
} else if (functionDeclarations.size() > 1) {
throw new InvalidExpressionException(null, "Accessing the identifier '" + identifier.getSymbol()
+ "' without a cast is ambiguous, since there are " + functionDeclarations.size()
@@ -119,10 +123,10 @@ public Declaration resolve(ResolvableIdentifier identifier) {
}
}
if (parent != null) {
- return parent.resolve(identifier);
+ return parent._resolve(identifier);
}
- throw new UnknownIdentifierException(identifier);
+ return Optional.empty();
}
/** Resolve an identifier for a type declaration.
@@ -130,16 +134,9 @@ public Declaration resolve(ResolvableIdentifier identifier) {
* @param identifier
* the identifier to resolve
* @return the declaration */
- public TypeDeclaration resolveType(ResolvableIdentifier identifier) {
- try {
- Declaration declaration = resolve(identifier);
- if (declaration instanceof TypeDeclaration) {
- return resolveGenericClass((TypeDeclaration) declaration, identifier);
- }
- throw new UnknownTypeException(identifier);
- } catch (UnknownIdentifierException e) {
- throw new UnknownTypeException(identifier);
- }
+ public Type resolveType(ResolvableIdentifier identifier, VisitOnceVisitor visitor) {
+ Optional maybeType = tryToResolveType(identifier, visitor);
+ return maybeType.map(t -> t.extend(getContext())).orElseThrow(() -> new UnknownTypeException(identifier));
}
/** Tries to resolve an identifier for a type declaration.
@@ -147,13 +144,22 @@ public TypeDeclaration resolveType(ResolvableIdentifier identifier) {
* @param identifier
* the identifier to resolve
* @return the declaration or null */
- public TypeDeclaration tryToResolveType(ResolvableIdentifier identifier) {
+ public Optional tryToResolveType(ResolvableIdentifier identifier, VisitOnceVisitor visitor) {
try {
- return resolveType(identifier);
- } catch (UnknownTypeException e) {
- return null;
+ return _resolve(identifier).flatMap((declaration) -> {
+ if (declaration instanceof TypeDeclaration) {
+ List resolvedGenericTypes = resolveGenericIdentifier(identifier, visitor);
+ visitor.visitDoubleDispatched(declaration);
+ if (declaration instanceof ClassDeclaration) {
+ TypeContext context = TypeContext.from((ClassDeclaration) declaration, resolvedGenericTypes);
+ return Optional.of(TypeFactory.from((ClassDeclaration) declaration, context));
+ }
+ return Optional.of(new TypeVariable((TypeParameterDeclaration) declaration));
+ }
+ return Optional.empty();
+ });
} catch (InvalidExpressionException e) {
- return null;
+ return Optional.empty();
}
}
@@ -162,25 +168,49 @@ public TypeDeclaration tryToResolveType(ResolvableIdentifier identifier) {
* @param identifier
* the identifier to resolve
* @return the list of function declarations */
- public List resolveFunction(ResolvableIdentifier identifier) {
- List result = new ArrayList();
+ public List resolveFunction(ResolvableIdentifier identifier, VisitOnceVisitor visitor) {
+ return _resolveFunction(identifier, visitor).orElseThrow(() -> new UnknownIdentifierException(identifier));
+ }
+ public Optional> _resolveFunction(ResolvableIdentifier identifier, VisitOnceVisitor visitor) {
+ List result = new ArrayList<>();
if (functions.containsKey(identifier)) {
- result.addAll(functions.get(identifier));
+ List functionDeclarations = getResolvedFunctions(identifier, visitor);
+ result.addAll(functionDeclarations);
}
if (members.containsKey(identifier)) {
- result.add(members.get(identifier));
+ Declaration declaration = members.get(identifier);
+ if(isFunctionVariable(declaration)) {
+ result.add(TypeFactory.createFunction((VariableDeclaration) declaration));
+ }
}
if (parent != null) {
- try {
- result.addAll(parent.resolveFunction(identifier));
- } catch (UnknownIdentifierException e) {
- }
+ result.addAll(parent._resolveFunction(identifier, visitor).orElse(Collections.emptyList()));
}
if (result.isEmpty()) {
- throw new UnknownIdentifierException(identifier);
+ return Optional.empty();
+ }
+ return Optional.of(result);
+ }
+
+ public boolean isFunctionVariable(Declaration declaration) {
+ return declaration instanceof VariableDeclaration && ((VariableDeclaration) declaration).getType().isAssignableFrom(Types.functionType());
+ }
+
+ protected List getResolvedFunctions(ResolvableIdentifier identifier, VisitOnceVisitor visitor) {
+ return functions.get(identifier).stream().map((declaration) -> {
+ visitor.visitDoubleDispatched(declaration);
+ return TypeFactory.from(declaration, TypeContext.EMPTY);
+ }).collect(Collectors.toList());
+ }
+
+ private List resolveGenericIdentifier(ResolvableIdentifier identifier, VisitOnceVisitor visitor) {
+ ArrayList genericIdentifier = new ArrayList<>();
+ for (ResolvableIdentifier resolvableIdentifier : identifier.getGenericTypes()) {
+ Type typeInfo = resolveType(resolvableIdentifier,visitor);
+ genericIdentifier.add(typeInfo);
}
- return result;
+ return genericIdentifier;
}
/** Associate an identifier with a declaration.
@@ -228,29 +258,14 @@ public void define(Declaration declaration) throws RedeclarationException {
* the declaration
* @throws RedeclarationException
* if this is invalid overloading */
- public void define(Identifier identifier, FunctionDeclaration declaration) throws RedeclarationException {
+ private void define(Identifier identifier, FunctionDeclaration declaration) throws RedeclarationException {
if (!functions.containsKey(identifier)) {
functions.put(identifier, new ArrayList());
}
functions.get(identifier).add(declaration);
}
- private TypeDeclaration resolveGenericClass(TypeDeclaration originalType, ResolvableIdentifier genericIdentifier) {
- List genericTypes = genericIdentifier.getGenericTypes();
- if (!genericTypes.isEmpty() && originalType instanceof ClassDeclaration) {
- ClassDeclaration originalClass = (ClassDeclaration) originalType;
- ArrayList concreteGenerics = new ArrayList<>();
- for (ResolvableIdentifier genericType : genericTypes) {
- TypeDeclaration decl = resolveType(genericType);
- decl = resolveGenericClass(decl, genericType);
-
- if (decl instanceof AbstractGenericType) {
- return originalType;
- }
- concreteGenerics.add((ClassDeclaration) decl);
- }
- return originalClass.getVariation(genericIdentifier, concreteGenerics);
- }
- return originalType;
+ public TypeContext getContext() {
+ return TypeContext.EMPTY;
}
}
diff --git a/src/main/java/de/uni/bremen/monty/moco/ast/declaration/AbstractGenericType.java b/src/main/java/de/uni/bremen/monty/moco/ast/declaration/AbstractGenericType.java
deleted file mode 100644
index 142ca8a..0000000
--- a/src/main/java/de/uni/bremen/monty/moco/ast/declaration/AbstractGenericType.java
+++ /dev/null
@@ -1,44 +0,0 @@
-package de.uni.bremen.monty.moco.ast.declaration;
-
-import de.uni.bremen.monty.moco.ast.ASTNode;
-import de.uni.bremen.monty.moco.ast.Identifier;
-import de.uni.bremen.monty.moco.ast.Position;
-import de.uni.bremen.monty.moco.visitor.BaseVisitor;
-
-public class AbstractGenericType extends TypeDeclaration {
-
- private ClassDeclaration definedIn;
-
- /** Constructor.
- *
- * @param definedIn
- * @param position
- * Position of this node
- * @param identifier
- * the identifier */
- public AbstractGenericType(ClassDeclaration definedIn, Position position, Identifier identifier) {
- super(position, identifier);
- this.definedIn = definedIn;
- }
-
- @Override
- public void visit(BaseVisitor visitor) {
- visitor.visit(this);
- }
-
- @Override
- public void visitChildren(BaseVisitor visitor) {
-
- }
-
- public ClassDeclaration getDefinedIn() {
- return definedIn;
- }
-
- public boolean equals(Object other) {
- if (other instanceof AbstractGenericType) {
- return ((AbstractGenericType) other).getIdentifier().equals(getIdentifier());
- }
- return false;
- }
-}
diff --git a/src/main/java/de/uni/bremen/monty/moco/ast/declaration/ClassDeclaration.java b/src/main/java/de/uni/bremen/monty/moco/ast/declaration/ClassDeclaration.java
index 1c1c310..cdec023 100644
--- a/src/main/java/de/uni/bremen/monty/moco/ast/declaration/ClassDeclaration.java
+++ b/src/main/java/de/uni/bremen/monty/moco/ast/declaration/ClassDeclaration.java
@@ -38,10 +38,8 @@
*/
package de.uni.bremen.monty.moco.ast.declaration;
-import de.uni.bremen.monty.moco.ast.Block;
-import de.uni.bremen.monty.moco.ast.Identifier;
-import de.uni.bremen.monty.moco.ast.Position;
-import de.uni.bremen.monty.moco.ast.ResolvableIdentifier;
+import de.uni.bremen.monty.moco.ast.*;
+import de.uni.bremen.monty.moco.ast.types.PartialAppliedTypeInfo;
import de.uni.bremen.monty.moco.visitor.BaseVisitor;
import java.util.ArrayList;
@@ -53,13 +51,15 @@
* A ClassDeclaration has a list of superclasses and a list of nested declarations. It can be used as a type. */
public class ClassDeclaration extends TypeDeclaration {
- private final List abstractGenericTypes;
+ private final List typeParameterDeclarations;
/** Identifier of superclasses. */
private final List superClassIdentifiers;
/** Superclasses. */
- private final List superClassDeclarations = new ArrayList<>();
+ private final List superClassDeclarations = new ArrayList<>();
+
+ private final boolean dummy;
/** The generated default initializer to be called from every user defined initializer. */
private FunctionDeclaration defaultInitializer;
@@ -67,8 +67,6 @@ public class ClassDeclaration extends TypeDeclaration {
/** Block with assignments **/
private Block block;
- private final List variations;
-
/** The virtal method table for this class */
private List virtualMethodTable = new ArrayList<>();
@@ -77,7 +75,7 @@ public class ClassDeclaration extends TypeDeclaration {
/** The last index for the attributes of this class. This counter starts at `1` as index 0 is reserved for a pointer
* to the vmt. */
- private int lastAttributeIndex = 1;
+ private int lastAttributeIndex = -1;
private boolean abstractClass = false;
@@ -98,21 +96,31 @@ public ClassDeclaration(Position position, Identifier identifier, List superClasses,
+ Block block, boolean dummy) {
+ super(position, identifier);
+ this.block = block;
+ this.superClassIdentifiers = superClasses;
+ this.typeParameterDeclarations = Collections.emptyList();
+ this.dummy = dummy;
}
public ClassDeclaration(Position position, Identifier identifier, List superClassIdentifiers,
- Block block, boolean isAbstract, List abstractGenericTypes) {
+ Block block, boolean isAbstract, List typeParameterDeclarations) {
super(position, identifier);
this.superClassIdentifiers = superClassIdentifiers;
this.block = block;
- this.abstractGenericTypes = abstractGenericTypes;
- this.variations = new ArrayList<>(abstractGenericTypes.size());
+ this.typeParameterDeclarations = typeParameterDeclarations;
this.abstractClass = isAbstract;
+ this.dummy = false;
}
/** Get the list of declarations and assignments.
+ *
*
* @return the block with declarations and assignments */
public Block getBlock() {
@@ -134,22 +142,10 @@ public List getSuperClassIdentifiers() {
/** Get the list of direct superclasses this class inherits from.
*
* @return the superclasses */
- public List getSuperClassDeclarations() {
+ public List getSuperClassDeclarations() {
return superClassDeclarations;
}
- /** Get a list of all the declarations of superclasses and this one. */
- public List getSuperClassDeclarationsRecursive() {
- List allSuperClassDeclarations = new ArrayList<>();
- for (TypeDeclaration superClass : superClassDeclarations) {
- if (superClass instanceof ClassDeclaration) {
- allSuperClassDeclarations.addAll(((ClassDeclaration) superClass).getSuperClassDeclarationsRecursive());
- }
- }
- allSuperClassDeclarations.add(this);
- return allSuperClassDeclarations;
- }
-
/** set the last attribute index.
*
* @param lastAttributeIndex
@@ -187,8 +183,8 @@ public void setDefaultInitializer(FunctionDeclaration defaultInitializer) {
this.defaultInitializer = defaultInitializer;
}
- public List getAbstractGenericTypes() {
- return abstractGenericTypes;
+ public List getTypeParameterDeclarations() {
+ return typeParameterDeclarations;
}
/** {@inheritDoc} */
@@ -200,49 +196,10 @@ public void visit(BaseVisitor visitor) {
/** {@inheritDoc} */
@Override
public void visitChildren(BaseVisitor visitor) {
- for (AbstractGenericType abstractGenericType : abstractGenericTypes) {
- visitor.visitDoubleDispatched(abstractGenericType);
- }
- for (ClassDeclarationVariation variation : variations) {
- visitor.visitDoubleDispatched(variation);
- }
+ typeParameterDeclarations.forEach(visitor::visitDoubleDispatched);
visitor.visitDoubleDispatched(block);
}
- /** {@inheritDoc} */
- @Override
- public boolean matchesType(TypeDeclaration other) {
- if (super.matchesType(other)) {
- return true;
- }
- if (other instanceof ClassDeclaration) {
- for (TypeDeclaration parentClass : superClassDeclarations) {
- if (parentClass.matchesType(other)) {
- return true;
- }
- }
- }
- return false;
- }
-
- public void addVariation(ClassDeclarationVariation variation) {
- variations.add(variation);
- }
-
- public List getVariations() {
- return variations;
- }
-
- public TypeDeclaration getVariation(ResolvableIdentifier genericIdentifier,
- ArrayList concreteGenerics) {
- for (ClassDeclarationVariation variation : getVariations()) {
- if (variation.getConcreteGenericTypes().equals(concreteGenerics)) {
- return variation;
- }
- }
- return new ClassDeclarationVariation(this, genericIdentifier, concreteGenerics);
- }
-
public List getMethods() {
ArrayList methods = new ArrayList<>();
for (Declaration decl : getBlock().getDeclarations()) {
@@ -272,4 +229,23 @@ public boolean isGenerator() {
public void setGenerator(boolean gen) {
_isGenerator = gen;
}
+
+ public ClassScope getScope() {
+ return (ClassScope) super.getScope();
+ }
+
+ public String toString(){
+ Object abstractGenericTypes = getTypeParameterDeclarations().isEmpty() ? "" : getTypeParameterDeclarations();
+ String symbol;
+ if(isFunctionWrapper()) {
+ symbol = getWrappedFunction().getIdentifier().toString();
+ } else {
+ symbol = getIdentifier().getSymbol();
+ }
+ return symbol + abstractGenericTypes;
+ }
+
+ public boolean isDummy() {
+ return dummy;
+ }
}
diff --git a/src/main/java/de/uni/bremen/monty/moco/ast/declaration/ClassDeclarationVariation.java b/src/main/java/de/uni/bremen/monty/moco/ast/declaration/ClassDeclarationVariation.java
deleted file mode 100644
index cb9f37d..0000000
--- a/src/main/java/de/uni/bremen/monty/moco/ast/declaration/ClassDeclarationVariation.java
+++ /dev/null
@@ -1,291 +0,0 @@
-package de.uni.bremen.monty.moco.ast.declaration;
-
-import de.uni.bremen.monty.moco.ast.Block;
-import de.uni.bremen.monty.moco.ast.ClassScope;
-import de.uni.bremen.monty.moco.ast.ResolvableIdentifier;
-import de.uni.bremen.monty.moco.ast.statement.Statement;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
-
-public class ClassDeclarationVariation extends ClassDeclaration {
-
- private List concreteGenericTypes;
-
- private final ClassDeclaration baseClass;
-
- public ClassDeclarationVariation(ClassDeclaration classDecl, ResolvableIdentifier identifier,
- List concreteGenericTypes) {
- super(classDecl.getPosition(), identifier, classDecl.getSuperClassIdentifiers(), new Block(
- classDecl.getBlock().getPosition()), classDecl.isAbstract(), classDecl.getAbstractGenericTypes());
- this.baseClass = classDecl;
- this.concreteGenericTypes = concreteGenericTypes;
- setParentNode(classDecl.getParentNode());
- ClassScope classScope = new ClassScope(classDecl.getScope().getParentScope());
- setScope(classScope);
- classDecl.addVariation(this);
-
- addSuperClassDeclarations(classDecl);
-
- Collection functionDeclarations = mapFunctions(classDecl.getVirtualMethodTable());
- getVirtualMethodTable().addAll(functionDeclarations);
- mapBlock(classDecl.getBlock());
- getBlock().setParentNode(this);
- FunctionDeclaration defaultInitializer = mapFunction(classDecl.getDefaultInitializer());
- setDefaultInitializer(defaultInitializer);
- for (Declaration functionDeclaration : getBlock().getDeclarations()) {
- if (!(functionDeclaration instanceof FunctionDeclaration)
- || !((FunctionDeclaration) functionDeclaration).isDefaultInitializer()) {
- classScope.define(functionDeclaration);
- }
- }
- classScope.define(defaultInitializer);
- }
-
- /** The parent (super) class declarations should also be referenced in the ClassDeclarationVariation and not only in
- * the ClassDeclaration, since they can be used interchangeably
- *
- * @param classDecl */
- private void addSuperClassDeclarations(ClassDeclaration classDecl) {
- List ownParents = getSuperClassDeclarations();
- for (TypeDeclaration parent : classDecl.getSuperClassDeclarations()) {
- // if the parent class is a concrete generic class, we can add it
- if (parent instanceof ClassDeclarationVariation) {
- ownParents.add(parent);
- } else if (parent instanceof ClassDeclaration) {
- // if the parent class has no unresolved abstract generic types, we can add it as well
- if (((ClassDeclaration) parent).getAbstractGenericTypes().isEmpty()) {
- ownParents.add(parent);
- ((ClassScope) getScope()).addParentClassScope((ClassScope) parent.getScope());
- }
- // if there are unresolved type parameters, we have to resolve them using our own
- else {
- TypeDeclaration newParent = mapAbstractGenericSuperClass((ClassDeclaration) parent);
- ownParents.add(newParent);
- ((ClassScope) getScope()).addParentClassScope((ClassScope) newParent.getScope());
- }
- }
- // if the parent is neither one of the above, something is terribly going wrong...
- else {
- throw new RuntimeException("Was ist hier los?!?");
- }
- }
- }
-
- /** converts a parent ClassDeclaration with abstractGenericTypes into a ClassDeclarationVariation with
- * concreteGenericTypes
- *
- * @return */
- private TypeDeclaration mapAbstractGenericSuperClass(ClassDeclaration parent) {
- List placeholders = parent.getAbstractGenericTypes();
- List ownPlaceholders = baseClass.getAbstractGenericTypes();
- ArrayList concreteTypes = new ArrayList<>(placeholders.size());
- ArrayList concreteIdentifiers = new ArrayList<>(placeholders.size());
-
- for (AbstractGenericType placeholder : placeholders) {
- int index = ownPlaceholders.indexOf(placeholder);
- concreteTypes.add(concreteGenericTypes.get(index));
- concreteIdentifiers.add(ResolvableIdentifier.convert(concreteGenericTypes.get(index).getIdentifier()));
- }
-
- return parent.getVariation(
- new ResolvableIdentifier(parent.getIdentifier().getSymbol(), concreteIdentifiers),
- concreteTypes);
- }
-
- private void mapBlock(Block block) {
- for (Statement statement : block.getStatements()) {
- getBlock().addStatement(statement);
- }
- for (Declaration declaration : block.getDeclarations()) {
-
- if (declaration instanceof FunctionDeclaration) {
- declaration = mapFunction((FunctionDeclaration) declaration);
- } else if (declaration instanceof VariableDeclaration) {
- declaration = mapDeclaration((VariableDeclaration) declaration);
- }
- getBlock().addDeclaration(declaration);
- }
- }
-
- private Collection mapFunctions(List originalVirtualMethods) {
- ArrayList functionDeclarations = new ArrayList<>();
- for (FunctionDeclaration functionDeclaration : originalVirtualMethods) {
- functionDeclarations.add(mapFunction(functionDeclaration));
- }
- return functionDeclarations;
- }
-
- private FunctionDeclaration mapFunction(FunctionDeclaration functionDeclaration) {
- FunctionDeclaration funDecl;
- // important for generic inheritance
-
- if (!functionDeclaration.getDefiningClass().getAbstractGenericTypes().isEmpty()) {
- ClassDeclarationVariation parent = findCorrectSuperClass(functionDeclaration);
- parent = parent != null ? parent : this;
- if (functionDeclaration.isFunction()) {
- TypeDeclaration returnType = mapGenericType((functionDeclaration).getReturnType());
- funDecl = new ConcreteProcDecl(parent, functionDeclaration, returnType);
- } else {
- funDecl = new ConcreteProcDecl(parent, functionDeclaration);
- }
- funDecl.getParameters().addAll(mapParameter(functionDeclaration.getParameters(), funDecl));
- funDecl.setParentNode(this);
- funDecl.setScope(functionDeclaration.getScope());
- return funDecl;
- }
- return functionDeclaration;
- }
-
- /** inherited methods in the VMT should get the correct ClassDeclarationVariation reference. If this does not happen,
- * inheritance does not work for ``Gen2 ----|> Gen1`` but only for ``NotGen ----|> Gen``
- *
- * @param funDecl
- * @return */
- private ClassDeclarationVariation findCorrectSuperClass(FunctionDeclaration funDecl) {
- ClassDeclaration classDecl = funDecl.getDefiningClass();
- for (TypeDeclaration parent : getSuperClassDeclarations()) {
- if (parent instanceof ClassDeclarationVariation) {
- int index = classDecl.getVariations().indexOf(parent);
- if (index >= 0) {
- return classDecl.getVariations().get(index);
- }
- }
- }
- return null;
- }
-
- private TypeDeclaration mapGenericType(TypeDeclaration type) {
- if (type instanceof AbstractGenericType) {
- return mapAbstractToConcrete((AbstractGenericType) type);
- } else if ((type instanceof ClassDeclaration)
- && (!((ClassDeclaration) type).getAbstractGenericTypes().isEmpty())) {
- return mapAbstractGenericToConcrete((ClassDeclaration) type);
- } else {
- return type;
- }
- }
-
- public TypeDeclaration mapAbstractGenericToConcrete(ClassDeclaration type) {
- ArrayList concreteTypes = new ArrayList<>(type.getAbstractGenericTypes().size());
- ArrayList concreteIdentifiers = new ArrayList<>(type.getAbstractGenericTypes().size());
- for (AbstractGenericType abs : type.getAbstractGenericTypes()) {
- TypeDeclaration con = mapGenericType(abs);
- concreteTypes.add((ClassDeclaration) con);
- concreteIdentifiers.add(ResolvableIdentifier.convert(con.getIdentifier()));
- }
- TypeDeclaration result =
- type.getVariation(
- new ResolvableIdentifier(type.getIdentifier().getSymbol(), concreteIdentifiers),
- concreteTypes);
- return result;
- }
-
- public ClassDeclaration mapAbstractToConcrete(AbstractGenericType type) {
- int index = getAbstractGenericTypes().indexOf(type);
- if (index >= 0) {
- return concreteGenericTypes.get(index);
- } else {
- throw new RuntimeException("is this really an Error?");
- }
- }
-
- public List getConcreteGenericTypes() {
- return concreteGenericTypes;
- }
-
- private List mapParameter(List parameter, FunctionDeclaration decl) {
- ArrayList params = new ArrayList<>();
- for (VariableDeclaration variableDeclaration : parameter) {
- VariableDeclaration var;
- TypeDeclaration abstractType = variableDeclaration.getType();
- if (abstractType instanceof AbstractGenericType) {
- ClassDeclaration type = mapAbstractToConcrete((AbstractGenericType) abstractType);
- var =
- new VariableDeclaration(variableDeclaration.getPosition(), variableDeclaration.getIdentifier(),
- type, variableDeclaration.getDeclarationType());
- var.setParentNode(decl);
- var.setScope(getScope());
- } else {
- var = variableDeclaration;
- }
- params.add(var);
- }
- return params;
- }
-
- private Declaration mapDeclaration(VariableDeclaration declaration) {
- VariableDeclaration variableDeclaration =
- new VariableDeclaration(declaration.getPosition(), declaration.getIdentifier(),
- mapGenericType(declaration.getType()), declaration.getDeclarationType());
- variableDeclaration.setParentNode(this);
- variableDeclaration.setScope(getScope());
- variableDeclaration.setAttributeIndex(declaration.getAttributeIndex());
- return variableDeclaration;
- }
-
- @Override
- public List getVariations() {
- return baseClass.getVariations();
- }
-
- @Override
- public TypeDeclaration getVariation(ResolvableIdentifier genericIdentifier,
- ArrayList concreteGenerics) {
- return baseClass.getVariation(genericIdentifier, concreteGenerics);
- }
-
- @Override
- public void addVariation(ClassDeclarationVariation variation) {
- baseClass.addVariation(variation);
- }
-
- /** this method checks whether the type parameters match exactly
- *
- * @param other
- * @return true if all params have the same type */
- protected boolean doTypeParamsMatch(TypeDeclaration other) {
- if (other instanceof ClassDeclarationVariation) {
- List otherGenerics = ((ClassDeclarationVariation) other).getConcreteGenericTypes();
- List ownGenerics = getConcreteGenericTypes();
- if (otherGenerics.size() == ownGenerics.size()) {
- for (int i = 0; i < ownGenerics.size(); i++) {
- // invariant behavior for generic classes
- if (!ownGenerics.get(i).matchesTypeExactly(otherGenerics.get(i))) {
- return false;
- }
- }
- return true;
- }
- }
- return false;
- }
-
- @Override
- public int getTypeDist(TypeDeclaration other, int dist) {
- if (doTypeParamsMatch(other)) { // currently we only support invariance
- return super.getTypeDist(other, dist);
- } else { // but if the other one does not have any type parameters, super types of it could do so...
- if (other instanceof ClassDeclaration) {
- List superTypes = ((ClassDeclaration) other).getSuperClassDeclarations();
- int minScore = Integer.MAX_VALUE;
- for (TypeDeclaration superType : superTypes) {
- int score = getTypeDist(superType);
- if (score < minScore) {
- minScore = score;
- }
- }
- if ((dist < Integer.MAX_VALUE) && (minScore < Integer.MAX_VALUE)) {
- return dist + minScore;
- }
- }
- }
- return Integer.MAX_VALUE;
- }
-
- public ClassDeclaration getBaseClass() {
- return baseClass;
- }
-
-}
diff --git a/src/main/java/de/uni/bremen/monty/moco/ast/declaration/ConcreteProcDecl.java b/src/main/java/de/uni/bremen/monty/moco/ast/declaration/ConcreteProcDecl.java
deleted file mode 100644
index 1dd15cb..0000000
--- a/src/main/java/de/uni/bremen/monty/moco/ast/declaration/ConcreteProcDecl.java
+++ /dev/null
@@ -1,33 +0,0 @@
-package de.uni.bremen.monty.moco.ast.declaration;
-
-import java.util.ArrayList;
-
-public class ConcreteProcDecl extends FunctionDeclaration {
- private final ClassDeclarationVariation variation;
-
- public ConcreteProcDecl(ClassDeclarationVariation variation, FunctionDeclaration abstractDecl) {
- super(abstractDecl.getPosition(), abstractDecl.getIdentifier(), abstractDecl.getBody(),
- new ArrayList(), abstractDecl.getDeclarationType(),
- abstractDecl.getReturnTypeIdentifier(), abstractDecl.isAbstract());
- this.variation = variation;
- setParentNode(variation);
- setVMTIndex(abstractDecl.getVMTIndex());
- }
-
- public ConcreteProcDecl(ClassDeclarationVariation variation, FunctionDeclaration abstractDecl,
- TypeDeclaration returnType) {
- super(abstractDecl.getPosition(), abstractDecl.getIdentifier(), abstractDecl.getBody(),
- new ArrayList(), abstractDecl.getDeclarationType(), returnType,
- abstractDecl.isAbstract());
- this.variation = variation;
- setParentNode(variation);
- setVMTIndex(abstractDecl.getVMTIndex());
- setScope(abstractDecl.getScope());
- }
-
- @Override
- public ClassDeclarationVariation getDefiningClass() {
- return variation;
- }
-
-}
diff --git a/src/main/java/de/uni/bremen/monty/moco/ast/declaration/Declaration.java b/src/main/java/de/uni/bremen/monty/moco/ast/declaration/Declaration.java
index cbeda87..e3c95f7 100644
--- a/src/main/java/de/uni/bremen/monty/moco/ast/declaration/Declaration.java
+++ b/src/main/java/de/uni/bremen/monty/moco/ast/declaration/Declaration.java
@@ -42,6 +42,8 @@
import de.uni.bremen.monty.moco.ast.BasicASTNode;
import de.uni.bremen.monty.moco.ast.Identifier;
import de.uni.bremen.monty.moco.ast.Position;
+import org.apache.commons.lang3.builder.EqualsBuilder;
+import org.apache.commons.lang3.builder.HashCodeBuilder;
/** The baseclass of every declaration.
*
@@ -75,4 +77,24 @@ public void setAccessModifier(AccessModifier access) {
public Identifier getIdentifier() {
return identifier;
}
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+
+ if (o == null || getClass() != o.getClass()) return false;
+
+ Declaration that = (Declaration) o;
+
+ return new EqualsBuilder()
+ .append(identifier, that.identifier)
+ .isEquals();
+ }
+
+ @Override
+ public int hashCode() {
+ return new HashCodeBuilder(17, 37)
+ .append(identifier)
+ .toHashCode();
+ }
}
diff --git a/src/main/java/de/uni/bremen/monty/moco/ast/declaration/FunctionDeclaration.java b/src/main/java/de/uni/bremen/monty/moco/ast/declaration/FunctionDeclaration.java
index 6474a64..04ac63d 100644
--- a/src/main/java/de/uni/bremen/monty/moco/ast/declaration/FunctionDeclaration.java
+++ b/src/main/java/de/uni/bremen/monty/moco/ast/declaration/FunctionDeclaration.java
@@ -41,11 +41,12 @@
import de.uni.bremen.monty.moco.ast.*;
import de.uni.bremen.monty.moco.ast.expression.Expression;
import de.uni.bremen.monty.moco.ast.expression.FunctionCall;
-import de.uni.bremen.monty.moco.ast.expression.WrappedFunctionCall;
import de.uni.bremen.monty.moco.ast.statement.Assignment;
import de.uni.bremen.monty.moco.ast.statement.ReturnStatement;
import de.uni.bremen.monty.moco.ast.statement.Statement;
+import de.uni.bremen.monty.moco.ast.types.*;
import de.uni.bremen.monty.moco.visitor.BaseVisitor;
+import de.uni.bremen.monty.moco.visitor.VisitOnceVisitor;
import java.util.*;
@@ -57,9 +58,9 @@ public enum DeclarationType {
INITIALIZER, DEFAULT_INITIALIZER, METHOD, UNBOUND
}
- ClassDeclaration wrapperClass = null;
- VariableDeclaration wrapperFunctionObjectDeclaration = null;
- Assignment wrapperFunctionAssignment = null;
+ private ClassDeclaration wrapperClass = null;
+ private VariableDeclaration wrapperFunctionObjectDeclaration = null;
+ private Assignment wrapperFunctionAssignment = null;
/** The declarations and statements within this declaration. */
private final Block body;
@@ -74,7 +75,7 @@ public enum DeclarationType {
/** The return returnType. */
private ResolvableIdentifier returnTypeIdentifier;
- private TypeDeclaration returnType;
+ private Type returnType;
private final boolean abstractMethod;
@@ -118,36 +119,12 @@ public FunctionDeclaration(Position position, Identifier identifier, Block body,
public FunctionDeclaration(Position position, Identifier identifier, Block body,
List parameters) {
- this(position, identifier, body, parameters, DeclarationType.UNBOUND, (ResolvableIdentifier) null);
+ this(position, identifier, body, parameters, DeclarationType.UNBOUND, null);
returnTypeMustBeInferred = true;
}
public FunctionDeclaration(Position position, Identifier identifier, Block body,
- List parameters, ResolvableIdentifier returnTypeIdentifier) {
- this(position, identifier, body, parameters, DeclarationType.UNBOUND, returnTypeIdentifier);
- }
-
- /** Constructor
- *
- * @param position
- * * Position of this node
- * @param identifier
- * the identifier
- * @param body
- * the body of this function
- * @param parameters
- * the parameters of this function
- * @param returnType
- * the return returnType */
- public FunctionDeclaration(Position position, Identifier identifier, Block body,
- List parameters, ClassDeclaration returnType) {
- this(position, identifier, body, parameters,
- returnType != null ? ResolvableIdentifier.convert(returnType.getIdentifier()) : null);
- this.returnType = returnType;
- }
-
- public FunctionDeclaration(Position position, Identifier identifier, Block body,
- List parameters, DeclarationType declarationType, TypeDeclaration returnType,
+ List parameters, DeclarationType declarationType, Type returnType,
boolean isAbstract) {
this(position, identifier, body, parameters, declarationType,
returnType != null ? ResolvableIdentifier.convert(returnType.getIdentifier()) : null, isAbstract);
@@ -158,15 +135,18 @@ public FunctionDeclaration(Position position, Identifier identifier, Block body,
*
* @return the return returnType */
public ResolvableIdentifier getReturnTypeIdentifier() {
+ if (returnTypeIdentifier == null && !returnTypeMustBeInferred) {
+ return ResolvableIdentifier.convert(Types.voidType().getIdentifier());
+ }
return returnTypeIdentifier;
}
/** get the returnType.
*
* @return the returnType */
- public TypeDeclaration getReturnType() {
- if (returnType == null) {
- return CoreClasses.voidType();
+ public Type getReturnType() {
+ if (returnType == null && !returnTypeMustBeInferred) {
+ return Types.voidType();
}
return returnType;
}
@@ -174,7 +154,7 @@ public TypeDeclaration getReturnType() {
/** set the returnType
*
* @param returnType */
- public void setReturnType(TypeDeclaration returnType) {
+ public void setReturnType(Type returnType) {
if (this.returnType != null) return;
this.returnType = returnType;
}
@@ -227,7 +207,7 @@ public boolean isUnbound() {
public ClassDeclaration getDefiningClass() {
if (isMethod() || isInitializer()) {
- return (ClassDeclaration) getParentNodeByType(ClassDeclaration.class);
+ return getParentNodeByType(ClassDeclaration.class);
}
return null;
}
@@ -254,64 +234,46 @@ public void visitChildren(BaseVisitor visitor) {
for (VariableDeclaration variableDeclaration : parameters) {
visitor.visitDoubleDispatched(variableDeclaration);
}
+// if(wrapperFunctionObjectDeclaration != null){
+// visitor.visitDoubleDispatched(wrapperFunctionAssignment);
+// }
visitor.visitDoubleDispatched(body);
}
/** @return true if the procedure has no return type */
public boolean isProcedure() {
- return returnTypeIdentifier == null;
+ return returnTypeIdentifier == null
+ || new ResolvableIdentifier(CoreClasses.VOID_SYMBOL).equals(returnTypeIdentifier);
}
/** @return true if the function has a return type */
public boolean isFunction() {
- return returnTypeIdentifier != null;
- }
-
- /** Check equality of two types taking into account the AST object hierachy.
- *
- *
- * @param other
- * the other TypeDeclaration to check against
- * @return if equal */
- @Override
- public boolean matchesType(TypeDeclaration other) {
- if (!super.matchesType(other)) {
- return false;
- }
- if (!(other instanceof FunctionDeclaration)) {
- return false;
- }
- List otherParameter = ((FunctionDeclaration) other).getParameters();
- if (parameters.size() != otherParameter.size()) {
- return false;
- }
- for (int i = 0; i < parameters.size(); i++) {
- if (!parameters.get(i).getType().matchesType(otherParameter.get(i).getType())) {
- return false;
- }
- }
- FunctionDeclaration proc = ((FunctionDeclaration) other);
-
- return !((proc.getReturnType() != null) && (proc.getReturnType() != CoreClasses.voidType()))
- || returnType.matchesType(proc.getReturnType());
+ return !isProcedure();
}
- public boolean overridesFunction(FunctionDeclaration other) {
+ public boolean overridesFunction(FunctionType other) {
+// ClassDeclaration thisClass = this.getParentNodeByType(ClassDeclaration.class); // List
+// ClassDeclaration otherClass = other.getParentNodeByType(ClassDeclaration.class); // Collection
+// if(thisClass.isAssignableFrom(otherClass)){
+// throw new RuntimeException("this Function must be invoked from the super class");
+// }
+// if(thisClass.getSuperClassDeclarations())
if (!other.getIdentifier().getSymbol().equals(getIdentifier().getSymbol())) {
return false;
}
- List otherParameter = other.getParameters();
+ List extends Type> otherParameter = other.getParameterTypes();
if (parameters.size() != otherParameter.size()) {
return false;
}
for (int i = 0; i < parameters.size(); i++) {
- if (!parameters.get(i).getType().matchesTypeExactly(otherParameter.get(i).getType())) {
+ Type type = otherParameter.get(i);
+ if (!parameters.get(i).getType().matchesTypeExactly(type)) {
return false;
}
}
- return !((other.getReturnType() != null) && (other.getReturnType() != CoreClasses.voidType()))
- || returnType.matchesType(other.getReturnType());
+ return !((other.getReturnType() != null) && (!other.getReturnType().isVoid()))
+ || returnType.isAssignableFrom(other.getReturnType());
}
public boolean isAbstract() {
@@ -346,18 +308,19 @@ public boolean isReturnTypeToBeInferred() {
return returnTypeMustBeInferred;
}
- public void setInferredReturnType(TypeDeclaration type) {
+ public void setInferredReturnType(Type type, VisitOnceVisitor visitor) {
returnType = type;
returnTypeIdentifier = ResolvableIdentifier.convert(type.getIdentifier());
ResolvableIdentifier retIdent = returnTypeIdentifier;
FunctionDeclaration applyMethod = wrapperClass.getMethods().get(0);
- if (CoreClasses.voidType().equals(type)) {
+ if (type.isVoid()) {
returnTypeIdentifier = null;
retIdent = new ResolvableIdentifier("Tuple0");
applyMethod.setReturnTypeIdentifier(retIdent);
- applyMethod.setReturnType(getScope().resolveType(retIdent));
+ Type tuple0Type = getScope().resolveType(retIdent, visitor);
+ applyMethod.setReturnType(tuple0Type);
splitReturnStatement(false);
applyMethod.splitReturnStatement(true);
@@ -373,7 +336,7 @@ public void setInferredReturnType(TypeDeclaration type) {
genericWrapper.getGenericTypes().add(retIdent);
}
- protected void splitReturnStatement(boolean tupleInsteadOfVoid) {
+ protected ReturnStatement splitReturnStatement(boolean tupleInsteadOfVoid) {
ReturnStatement oldRet = (ReturnStatement) getBody().getStatements().get(getBody().getStatements().size() - 1);
// create a new return statement
@@ -405,6 +368,7 @@ protected void splitReturnStatement(boolean tupleInsteadOfVoid) {
throw new RuntimeException("invalid AST!");
}
getBody().addStatement(newRet);
+ return newRet;
}
public String toString() {
diff --git a/src/main/java/de/uni/bremen/monty/moco/ast/declaration/GeneratorFunctionDeclaration.java b/src/main/java/de/uni/bremen/monty/moco/ast/declaration/GeneratorFunctionDeclaration.java
index f2bb383..01c70fb 100644
--- a/src/main/java/de/uni/bremen/monty/moco/ast/declaration/GeneratorFunctionDeclaration.java
+++ b/src/main/java/de/uni/bremen/monty/moco/ast/declaration/GeneratorFunctionDeclaration.java
@@ -1,3 +1,41 @@
+/*
+ * moco, the Monty Compiler
+ * Copyright (c) 2013-2014, Monty's Coconut, All rights reserved.
+ *
+ * This file is part of moco, the Monty Compiler.
+ *
+ * moco is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 3.0 of the License, or (at your option) any later version.
+ *
+ * moco is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * Linking this program and/or its accompanying libraries statically or
+ * dynamically with other modules is making a combined work based on this
+ * program. Thus, the terms and conditions of the GNU General Public License
+ * cover the whole combination.
+ *
+ * As a special exception, the copyright holders of moco give
+ * you permission to link this programm and/or its accompanying libraries
+ * with independent modules to produce an executable, regardless of the
+ * license terms of these independent modules, and to copy and distribute the
+ * resulting executable under terms of your choice, provided that you also meet,
+ * for each linked independent module, the terms and conditions of the
+ * license of that module.
+ *
+ * An independent module is a module which is not
+ * derived from or based on this program and/or its accompanying libraries.
+ * If you modify this library, you may extend this exception to your version of
+ * the program or library, but you are not obliged to do so. If you do not wish
+ * to do so, delete this exception statement from your version.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this library.
+ */
package de.uni.bremen.monty.moco.ast.declaration;
import de.uni.bremen.monty.moco.ast.Block;
diff --git a/src/main/java/de/uni/bremen/monty/moco/ast/declaration/TypeDeclaration.java b/src/main/java/de/uni/bremen/monty/moco/ast/declaration/TypeDeclaration.java
index 8219ddf..d3c768e 100644
--- a/src/main/java/de/uni/bremen/monty/moco/ast/declaration/TypeDeclaration.java
+++ b/src/main/java/de/uni/bremen/monty/moco/ast/declaration/TypeDeclaration.java
@@ -54,53 +54,4 @@ public abstract class TypeDeclaration extends Declaration {
public TypeDeclaration(Position position, Identifier identifier) {
super(position, identifier);
}
-
- /** Check equality of two types taking into account the AST object hierachy.
- *
- *
- * @param other
- * the other TypeDeclaration to check against
- * @return if equal */
- public boolean matchesType(TypeDeclaration other) {
- return matchesTypeExactly(other);
- }
-
- public boolean matchesTypeExactly(TypeDeclaration other) {
- return getIdentifier().equals(other.getIdentifier());
- }
-
- /** Calculates the distance of this and other in the inheritance graph. Only calculates positive distances, i.e. if
- * this is a parameter and other is an argument, other must be equal to or a subtype of this. otherwise the result
- * will be Integer.MAX_VALUE.
- *
- * @param other
- * @return a distance 0 <= dist <= Integer.MAX_VALUE */
- public int getTypeDist(TypeDeclaration other) {
- return getTypeDist(other, 0);
- }
-
- /** a helper method for "public int getTypeDist(TypeDeclaration other)"
- *
- * @param other
- * @param dist
- * @return */
- protected int getTypeDist(TypeDeclaration other, int dist) {
- if (dist == Integer.MAX_VALUE) {
- return dist;
- }
- if (matchesTypeExactly(other)) {
- return dist;
- } else if ((other instanceof ClassDeclaration)
- && (!((ClassDeclaration) other).getSuperClassDeclarations().isEmpty())) {
- int parentDist = Integer.MAX_VALUE;
- for (TypeDeclaration superClass : ((ClassDeclaration) other).getSuperClassDeclarations()) {
- int superDist = getTypeDist(superClass, dist + 1);
- if (superDist < parentDist) {
- parentDist = superDist;
- }
- }
- return parentDist;
- }
- return Integer.MAX_VALUE;
- }
}
diff --git a/src/main/java/de/uni/bremen/monty/moco/ast/declaration/TypeParameterDeclaration.java b/src/main/java/de/uni/bremen/monty/moco/ast/declaration/TypeParameterDeclaration.java
new file mode 100644
index 0000000..ab3e389
--- /dev/null
+++ b/src/main/java/de/uni/bremen/monty/moco/ast/declaration/TypeParameterDeclaration.java
@@ -0,0 +1,89 @@
+/*
+ * moco, the Monty Compiler
+ * Copyright (c) 2013-2014, Monty's Coconut, All rights reserved.
+ *
+ * This file is part of moco, the Monty Compiler.
+ *
+ * moco is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 3.0 of the License, or (at your option) any later version.
+ *
+ * moco is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * Linking this program and/or its accompanying libraries statically or
+ * dynamically with other modules is making a combined work based on this
+ * program. Thus, the terms and conditions of the GNU General Public License
+ * cover the whole combination.
+ *
+ * As a special exception, the copyright holders of moco give
+ * you permission to link this programm and/or its accompanying libraries
+ * with independent modules to produce an executable, regardless of the
+ * license terms of these independent modules, and to copy and distribute the
+ * resulting executable under terms of your choice, provided that you also meet,
+ * for each linked independent module, the terms and conditions of the
+ * license of that module.
+ *
+ * An independent module is a module which is not
+ * derived from or based on this program and/or its accompanying libraries.
+ * If you modify this library, you may extend this exception to your version of
+ * the program or library, but you are not obliged to do so. If you do not wish
+ * to do so, delete this exception statement from your version.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this library.
+ */
+package de.uni.bremen.monty.moco.ast.declaration;
+
+import de.uni.bremen.monty.moco.ast.*;
+import de.uni.bremen.monty.moco.ast.types.Type;
+import de.uni.bremen.monty.moco.visitor.BaseVisitor;
+
+import java.util.Optional;
+
+
+public class TypeParameterDeclaration extends TypeDeclaration {
+
+ private Type upperTypeBound;
+ private final ResolvableIdentifier upperTypeBoundIdentifier;
+
+ public TypeParameterDeclaration(Position position, Identifier identifier, Optional typeBound) {
+ super(position, identifier);
+ this.upperTypeBoundIdentifier = typeBound.orElse(new ResolvableIdentifier(CoreClasses.OBJECT_SYMBOL));
+ }
+
+ @Override
+ public void visit(BaseVisitor visitor) {
+ visitor.visit(this);
+ }
+
+ @Override
+ public void visitChildren(BaseVisitor visitor) {}
+
+ public boolean equals(Object other) {
+ if (other instanceof TypeParameterDeclaration) {
+ return ((TypeParameterDeclaration) other).getIdentifier().equals(getIdentifier());
+ }
+ return false;
+ }
+
+ public Type getUpperTypeBound() {
+ return upperTypeBound;
+ }
+
+ @Override
+ public String toString() {
+ return getIdentifier().getSymbol();
+ }
+
+ public ResolvableIdentifier getUpperTypeBoundIdentifier() {
+ return upperTypeBoundIdentifier;
+ }
+
+ public void setUpperTypeBound(Type upperTypeBound) {
+ this.upperTypeBound = upperTypeBound;
+ }
+}
diff --git a/src/main/java/de/uni/bremen/monty/moco/ast/declaration/VariableDeclaration.java b/src/main/java/de/uni/bremen/monty/moco/ast/declaration/VariableDeclaration.java
index 4e6153c..e80bd90 100644
--- a/src/main/java/de/uni/bremen/monty/moco/ast/declaration/VariableDeclaration.java
+++ b/src/main/java/de/uni/bremen/monty/moco/ast/declaration/VariableDeclaration.java
@@ -42,6 +42,7 @@
import de.uni.bremen.monty.moco.ast.Position;
import de.uni.bremen.monty.moco.ast.ResolvableIdentifier;
import de.uni.bremen.monty.moco.ast.expression.Expression;
+import de.uni.bremen.monty.moco.ast.types.Type;
import de.uni.bremen.monty.moco.visitor.BaseVisitor;
public class VariableDeclaration extends Declaration {
@@ -50,8 +51,8 @@ public enum DeclarationType {
}
private ResolvableIdentifier typeIdentifier;
- private TypeDeclaration type;
- private DeclarationType declarationType;
+ private Type type;
+ private final DeclarationType declarationType;
private boolean isGlobal;
private Expression inferTypeFrom = null;
@@ -60,11 +61,13 @@ public enum DeclarationType {
public VariableDeclaration(Position position, Identifier identifier, ResolvableIdentifier typeIdentifier,
DeclarationType declarationType) {
- this(position, identifier, typeIdentifier);
+ super(position, identifier);
+ this.typeIdentifier = typeIdentifier;
this.declarationType = declarationType;
+ attributeIndex = -1;
}
- public VariableDeclaration(Position position, Identifier identifier, TypeDeclaration type,
+ public VariableDeclaration(Position position, Identifier identifier, Type type,
DeclarationType declarationType) {
super(position, identifier);
this.declarationType = declarationType;
@@ -84,11 +87,6 @@ public VariableDeclaration(Position position, Identifier identifier, Expression
this.inferTypeFrom = inferTypeFrom;
}
- /** set the declaration type */
- public void setDeclarationType(DeclarationType type) {
- this.declarationType = type;
- }
-
/** get the declaration type
*
* @return the declaration type */
@@ -118,14 +116,14 @@ public ResolvableIdentifier getTypeIdentifier() {
/** get the type.
*
* @return the type */
- public TypeDeclaration getType() {
+ public Type getType() {
return type;
}
/** set the type
*
* @param type */
- public void setType(TypeDeclaration type) {
+ public void setType(Type type) {
if (this.type != null) return;
this.type = type;
}
diff --git a/src/main/java/de/uni/bremen/monty/moco/ast/expression/CastExpression.java b/src/main/java/de/uni/bremen/monty/moco/ast/expression/CastExpression.java
index 9ff757a..9a9c411 100644
--- a/src/main/java/de/uni/bremen/monty/moco/ast/expression/CastExpression.java
+++ b/src/main/java/de/uni/bremen/monty/moco/ast/expression/CastExpression.java
@@ -39,7 +39,9 @@
package de.uni.bremen.monty.moco.ast.expression;
import de.uni.bremen.monty.moco.ast.*;
+import de.uni.bremen.monty.moco.ast.types.Type;
import de.uni.bremen.monty.moco.visitor.BaseVisitor;
+import de.uni.bremen.monty.moco.visitor.ResolveVisitor;
public class CastExpression extends Expression {
@@ -93,31 +95,18 @@ public Expression getExpression() {
return expression;
}
- public boolean typeParameterMustBeInferred() {
- return inferTypeParameterFrom != null;
- }
-
- public void inferTypeParameter() {
- if (inferTypeParameterFrom.getType().getIdentifier() instanceof ResolvableIdentifier) {
- ResolvableIdentifier otherIdent = (ResolvableIdentifier) inferTypeParameterFrom.getType().getIdentifier();
- int max = Math.min(otherIdent.getGenericTypes().size(), castIdentifier.getGenericTypes().size());
- for (int i = 0; i < max; i++) {
- castIdentifier.getGenericTypes().set(i, otherIdent.getGenericTypes().get(i));
- }
- }
+ public Type inferType(ResolveVisitor visitor) {
+ if (inferTypeParameterFrom != null) {
+ Scope inferScope = inferTypeParameterFrom.getType().getScope();
+ return inferScope.resolveType(castIdentifier, visitor);
+ } else if(inferTypeFrom != null) {
+ visitor.visitDoubleDispatched(inferTypeFrom);
+ return inferTypeFrom.getType();
+ } else throw new RuntimeException("Type doesn't need to be infered");
}
public boolean typeMustBeInferred() {
- return inferTypeFrom != null;
- }
-
- public Expression getExpressionToInferFrom() {
- return inferTypeFrom;
- }
-
- public void inferType() {
- setType(inferTypeFrom.getType());
- castIdentifier = ResolvableIdentifier.convert(getType().getIdentifier());
+ return inferTypeFrom != null || inferTypeParameterFrom != null;
}
@Override
diff --git a/src/main/java/de/uni/bremen/monty/moco/ast/expression/Expression.java b/src/main/java/de/uni/bremen/monty/moco/ast/expression/Expression.java
index e5d8c92..dc09fa8 100644
--- a/src/main/java/de/uni/bremen/monty/moco/ast/expression/Expression.java
+++ b/src/main/java/de/uni/bremen/monty/moco/ast/expression/Expression.java
@@ -39,7 +39,7 @@
package de.uni.bremen.monty.moco.ast.expression;
import de.uni.bremen.monty.moco.ast.*;
-import de.uni.bremen.monty.moco.ast.declaration.TypeDeclaration;
+import de.uni.bremen.monty.moco.ast.types.Type;
/** The base class for every expression.
*
@@ -47,7 +47,7 @@
public abstract class Expression extends BasicASTNode {
/** The type. */
- private TypeDeclaration type;
+ private Type type;
/** Constructor.
*
@@ -61,14 +61,14 @@ public Expression(Position position) {
*
* @param type
* the new type */
- public void setType(TypeDeclaration type) {
+ public void setType(Type type) {
this.type = type;
}
/** Get the type.
*
* @return the type */
- public TypeDeclaration getType() {
+ public Type getType() {
return type;
}
}
diff --git a/src/main/java/de/uni/bremen/monty/moco/ast/expression/FunctionCall.java b/src/main/java/de/uni/bremen/monty/moco/ast/expression/FunctionCall.java
index e752b1a..6d3d479 100644
--- a/src/main/java/de/uni/bremen/monty/moco/ast/expression/FunctionCall.java
+++ b/src/main/java/de/uni/bremen/monty/moco/ast/expression/FunctionCall.java
@@ -40,8 +40,8 @@
import de.uni.bremen.monty.moco.ast.Position;
import de.uni.bremen.monty.moco.ast.ResolvableIdentifier;
-import de.uni.bremen.monty.moco.ast.declaration.FunctionDeclaration;
import de.uni.bremen.monty.moco.ast.statement.Statement;
+import de.uni.bremen.monty.moco.ast.types.FunctionType;
import de.uni.bremen.monty.moco.visitor.BaseVisitor;
import java.util.List;
@@ -49,7 +49,7 @@
public class FunctionCall extends Expression implements Statement {
private final ResolvableIdentifier identifier;
protected final List arguments;
- private FunctionDeclaration declaration;
+ private FunctionType declaration;
public FunctionCall(Position position, ResolvableIdentifier identifier, List arguments) {
super(position);
@@ -86,13 +86,13 @@ public void visitChildren(BaseVisitor visitor) {
}
/** @return the declaration */
- public FunctionDeclaration getDeclaration() {
+ public FunctionType getDeclaration() {
return declaration;
}
/** @param declaration
* the declaration to set */
- public void setDeclaration(FunctionDeclaration declaration) {
+ public void setDeclaration(FunctionType declaration) {
this.declaration = declaration;
}
}
diff --git a/src/main/java/de/uni/bremen/monty/moco/ast/expression/IsExpression.java b/src/main/java/de/uni/bremen/monty/moco/ast/expression/IsExpression.java
index 472dc26..bffff47 100644
--- a/src/main/java/de/uni/bremen/monty/moco/ast/expression/IsExpression.java
+++ b/src/main/java/de/uni/bremen/monty/moco/ast/expression/IsExpression.java
@@ -39,14 +39,14 @@
package de.uni.bremen.monty.moco.ast.expression;
import de.uni.bremen.monty.moco.ast.*;
-import de.uni.bremen.monty.moco.ast.declaration.*;
+import de.uni.bremen.monty.moco.ast.types.Type;
import de.uni.bremen.monty.moco.visitor.BaseVisitor;
public class IsExpression extends Expression {
private Expression expression;
private ResolvableIdentifier isIdentifier;
- private TypeDeclaration toType;
+ private Type toType;
private Expression inferTypeFrom;
public IsExpression(Position position, Expression expression, ResolvableIdentifier isIdentifier) {
@@ -69,11 +69,11 @@ public Expression getExpression() {
return expression;
}
- public void setToType(TypeDeclaration toType) {
+ public void setToType(Type toType) {
this.toType = toType;
}
- public TypeDeclaration getToType() {
+ public Type getToType() {
return toType;
}
diff --git a/src/main/java/de/uni/bremen/monty/moco/ast/expression/ParentExpression.java b/src/main/java/de/uni/bremen/monty/moco/ast/expression/ParentExpression.java
index 4cb5c22..32c9e32 100644
--- a/src/main/java/de/uni/bremen/monty/moco/ast/expression/ParentExpression.java
+++ b/src/main/java/de/uni/bremen/monty/moco/ast/expression/ParentExpression.java
@@ -39,13 +39,13 @@
package de.uni.bremen.monty.moco.ast.expression;
import de.uni.bremen.monty.moco.ast.*;
-import de.uni.bremen.monty.moco.ast.declaration.*;
+import de.uni.bremen.monty.moco.ast.types.PartialAppliedTypeInfo;
import de.uni.bremen.monty.moco.visitor.BaseVisitor;
public class ParentExpression extends Expression {
private ResolvableIdentifier parentIdentifier;
- private ClassDeclaration selfType;
+ private PartialAppliedTypeInfo selfType;
public ParentExpression(Position position, ResolvableIdentifier parentIdentifier) {
super(position);
@@ -56,11 +56,11 @@ public ResolvableIdentifier getParentIdentifier() {
return parentIdentifier;
}
- public ClassDeclaration getSelfType() {
+ public PartialAppliedTypeInfo getSelfType() {
return selfType;
}
- public void setSelfType(ClassDeclaration selfType) {
+ public void setSelfType(PartialAppliedTypeInfo selfType) {
this.selfType = selfType;
}
diff --git a/src/main/java/de/uni/bremen/monty/moco/ast/expression/WrappedFunctionCall.java b/src/main/java/de/uni/bremen/monty/moco/ast/expression/WrappedFunctionCall.java
index 4bb2ccc..940107b 100644
--- a/src/main/java/de/uni/bremen/monty/moco/ast/expression/WrappedFunctionCall.java
+++ b/src/main/java/de/uni/bremen/monty/moco/ast/expression/WrappedFunctionCall.java
@@ -40,7 +40,7 @@
import de.uni.bremen.monty.moco.ast.Position;
import de.uni.bremen.monty.moco.ast.Scope;
-import de.uni.bremen.monty.moco.ast.declaration.TypeDeclaration;
+import de.uni.bremen.monty.moco.ast.types.Type;
import de.uni.bremen.monty.moco.ast.statement.Statement;
import de.uni.bremen.monty.moco.visitor.BaseVisitor;
@@ -88,7 +88,7 @@ public void setMemberAccess(MemberAccess memberAccess) {
}
@Override
- public TypeDeclaration getType() {
+ public Type getType() {
if (functionCall != null) {
return functionCall.getType();
}
diff --git a/src/main/java/de/uni/bremen/monty/moco/ast/expression/literal/TupleLiteral.java b/src/main/java/de/uni/bremen/monty/moco/ast/expression/literal/TupleLiteral.java
index 1a0f7e6..0b498da 100644
--- a/src/main/java/de/uni/bremen/monty/moco/ast/expression/literal/TupleLiteral.java
+++ b/src/main/java/de/uni/bremen/monty/moco/ast/expression/literal/TupleLiteral.java
@@ -59,11 +59,7 @@ public TupleLiteral(Position position, List entries) {
public void setConcreteTupleType() {
for (Expression entry : arguments) {
- if (entry.getType() instanceof ClassDeclaration) {
- getIdentifier().getGenericTypes().add(ResolvableIdentifier.convert(entry.getType().getIdentifier()));
- } else {
- throw new RuntimeException("TYPE:: " + entry.getType());
- }
+ getIdentifier().getGenericTypes().add(ResolvableIdentifier.convert(entry.getType().getIdentifier()));
}
}
}
diff --git a/src/main/java/de/uni/bremen/monty/moco/ast/statement/ReturnStatement.java b/src/main/java/de/uni/bremen/monty/moco/ast/statement/ReturnStatement.java
index 8ae4025..9071504 100644
--- a/src/main/java/de/uni/bremen/monty/moco/ast/statement/ReturnStatement.java
+++ b/src/main/java/de/uni/bremen/monty/moco/ast/statement/ReturnStatement.java
@@ -43,7 +43,7 @@
import de.uni.bremen.monty.moco.visitor.BaseVisitor;
public class ReturnStatement extends BasicASTNode implements Statement {
- private Expression parameter;
+ private final Expression parameter;
/** Constructor.
*
diff --git a/src/main/java/de/uni/bremen/monty/moco/ast/types/ConcreteFunctionType.java b/src/main/java/de/uni/bremen/monty/moco/ast/types/ConcreteFunctionType.java
new file mode 100644
index 0000000..28e8790
--- /dev/null
+++ b/src/main/java/de/uni/bremen/monty/moco/ast/types/ConcreteFunctionType.java
@@ -0,0 +1,66 @@
+/*
+ * moco, the Monty Compiler
+ * Copyright (c) 2013-2014, Monty's Coconut, All rights reserved.
+ *
+ * This file is part of moco, the Monty Compiler.
+ *
+ * moco is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 3.0 of the License, or (at your option) any later version.
+ *
+ * moco is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * Linking this program and/or its accompanying libraries statically or
+ * dynamically with other modules is making a combined work based on this
+ * program. Thus, the terms and conditions of the GNU General Public License
+ * cover the whole combination.
+ *
+ * As a special exception, the copyright holders of moco give
+ * you permission to link this programm and/or its accompanying libraries
+ * with independent modules to produce an executable, regardless of the
+ * license terms of these independent modules, and to copy and distribute the
+ * resulting executable under terms of your choice, provided that you also meet,
+ * for each linked independent module, the terms and conditions of the
+ * license of that module.
+ *
+ * An independent module is a module which is not
+ * derived from or based on this program and/or its accompanying libraries.
+ * If you modify this library, you may extend this exception to your version of
+ * the program or library, but you are not obliged to do so. If you do not wish
+ * to do so, delete this exception statement from your version.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this library.
+ */
+package de.uni.bremen.monty.moco.ast.types;
+
+import de.uni.bremen.monty.moco.ast.declaration.FunctionDeclaration;
+
+import java.util.List;
+
+public interface ConcreteFunctionType extends FunctionType {
+
+ @Override
+ public ConcreteType getReturnType();
+
+ public List getParameter();
+
+ @Override
+ public ConcreteType getWrapperClass();
+
+ @Override
+ public ConcreteVariableType getWrapperFunctionObjectDeclaration();
+
+ @Override
+ public List getClosureVariables();
+
+ @Override
+ public ConcreteType getDefiningClass();
+
+ @Override
+ public FunctionType extend(TypeContext context);
+}
diff --git a/src/main/java/de/uni/bremen/monty/moco/ast/types/ConcreteFunctionTypeDecl.java b/src/main/java/de/uni/bremen/monty/moco/ast/types/ConcreteFunctionTypeDecl.java
new file mode 100644
index 0000000..a7a38e7
--- /dev/null
+++ b/src/main/java/de/uni/bremen/monty/moco/ast/types/ConcreteFunctionTypeDecl.java
@@ -0,0 +1,84 @@
+/*
+ * moco, the Monty Compiler
+ * Copyright (c) 2013-2014, Monty's Coconut, All rights reserved.
+ *
+ * This file is part of moco, the Monty Compiler.
+ *
+ * moco is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 3.0 of the License, or (at your option) any later version.
+ *
+ * moco is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * Linking this program and/or its accompanying libraries statically or
+ * dynamically with other modules is making a combined work based on this
+ * program. Thus, the terms and conditions of the GNU General Public License
+ * cover the whole combination.
+ *
+ * As a special exception, the copyright holders of moco give
+ * you permission to link this programm and/or its accompanying libraries
+ * with independent modules to produce an executable, regardless of the
+ * license terms of these independent modules, and to copy and distribute the
+ * resulting executable under terms of your choice, provided that you also meet,
+ * for each linked independent module, the terms and conditions of the
+ * license of that module.
+ *
+ * An independent module is a module which is not
+ * derived from or based on this program and/or its accompanying libraries.
+ * If you modify this library, you may extend this exception to your version of
+ * the program or library, but you are not obliged to do so. If you do not wish
+ * to do so, delete this exception statement from your version.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this library.
+ */
+package de.uni.bremen.monty.moco.ast.types;
+
+import de.uni.bremen.monty.moco.ast.declaration.FunctionDeclaration;
+
+import java.util.List;
+
+public class ConcreteFunctionTypeDecl extends FunctionTypeDecl implements ConcreteFunctionType {
+ ConcreteFunctionTypeDecl(FunctionDeclaration declaration, TypeContext context, List extends ConcreteVariableType> parameter, ConcreteType returnType, ConcreteType definingClass, ConcreteType wrapperClass, ConcreteVariableType wrapperFunctionObjects, List closureVariables) {
+ super(declaration, context, parameter, returnType, definingClass, wrapperClass, wrapperFunctionObjects, closureVariables);
+ }
+
+ @Override
+ public ConcreteType getReturnType() {
+ return (ConcreteType) super.getReturnType();
+ }
+
+ @Override
+ public List getParameter() {
+ return (List) super.getParameter();
+ }
+
+ @Override
+ public ConcreteType getWrapperClass() {
+ return (ConcreteType) super.getWrapperClass();
+ }
+
+ @Override
+ public ConcreteVariableType getWrapperFunctionObjectDeclaration() {
+ return (ConcreteVariableType) super.getWrapperFunctionObjectDeclaration();
+ }
+
+ @Override
+ public List getClosureVariables() {
+ return (List) super.getClosureVariables();
+ }
+
+ @Override
+ public ConcreteType getDefiningClass() {
+ return (ConcreteType) super.getDefiningClass();
+ }
+
+ @Override
+ public FunctionType extend(TypeContext context) {
+ return new ConcreteFunctionTypeDecl(declaration, this.context.extend(context), getParameter(), getReturnType(), getDefiningClass(), getWrapperClass(), getWrapperFunctionObjectDeclaration(), getClosureVariables());
+ }
+}
diff --git a/src/main/java/de/uni/bremen/monty/moco/ast/types/ConcreteGeneratorFunctionType.java b/src/main/java/de/uni/bremen/monty/moco/ast/types/ConcreteGeneratorFunctionType.java
new file mode 100644
index 0000000..e2146c2
--- /dev/null
+++ b/src/main/java/de/uni/bremen/monty/moco/ast/types/ConcreteGeneratorFunctionType.java
@@ -0,0 +1,65 @@
+/*
+ * moco, the Monty Compiler
+ * Copyright (c) 2013-2014, Monty's Coconut, All rights reserved.
+ *
+ * This file is part of moco, the Monty Compiler.
+ *
+ * moco is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 3.0 of the License, or (at your option) any later version.
+ *
+ * moco is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * Linking this program and/or its accompanying libraries statically or
+ * dynamically with other modules is making a combined work based on this
+ * program. Thus, the terms and conditions of the GNU General Public License
+ * cover the whole combination.
+ *
+ * As a special exception, the copyright holders of moco give
+ * you permission to link this programm and/or its accompanying libraries
+ * with independent modules to produce an executable, regardless of the
+ * license terms of these independent modules, and to copy and distribute the
+ * resulting executable under terms of your choice, provided that you also meet,
+ * for each linked independent module, the terms and conditions of the
+ * license of that module.
+ *
+ * An independent module is a module which is not
+ * derived from or based on this program and/or its accompanying libraries.
+ * If you modify this library, you may extend this exception to your version of
+ * the program or library, but you are not obliged to do so. If you do not wish
+ * to do so, delete this exception statement from your version.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this library.
+ */
+package de.uni.bremen.monty.moco.ast.types;
+
+import de.uni.bremen.monty.moco.ast.declaration.GeneratorFunctionDeclaration;
+import de.uni.bremen.monty.moco.ast.statement.YieldStatement;
+
+import java.util.List;
+import java.util.stream.Collectors;
+
+public class ConcreteGeneratorFunctionType extends ConcreteFunctionTypeDecl implements GeneratorFunctionType {
+ ConcreteGeneratorFunctionType(GeneratorFunctionDeclaration declaration, TypeContext context, List extends ConcreteVariableType> parameter, ConcreteType returnType, ConcreteType definingClass, ConcreteType wrapperClass, ConcreteVariableType wrapperFunctionObjects, List closureVariables) {
+ super(declaration, context, parameter, returnType, definingClass, wrapperClass, wrapperFunctionObjects, closureVariables);
+ }
+
+ private GeneratorFunctionDeclaration getDeclaration(){
+ return (GeneratorFunctionDeclaration) super.declaration;
+ }
+
+ @Override
+ public List getYieldStatements() {
+ return getDeclaration().getYieldStatements();
+ }
+
+ @Override
+ public List getVariableDeclarations() {
+ return getDeclaration().getVariableDeclarations().stream().map(d -> (ConcreteVariableType) TypeFactory.from(d, context)).collect(Collectors.toList());
+ }
+}
diff --git a/src/main/java/de/uni/bremen/monty/moco/ast/types/ConcreteType.java b/src/main/java/de/uni/bremen/monty/moco/ast/types/ConcreteType.java
new file mode 100644
index 0000000..b101b19
--- /dev/null
+++ b/src/main/java/de/uni/bremen/monty/moco/ast/types/ConcreteType.java
@@ -0,0 +1,171 @@
+/*
+ * moco, the Monty Compiler
+ * Copyright (c) 2013-2014, Monty's Coconut, All rights reserved.
+ *
+ * This file is part of moco, the Monty Compiler.
+ *
+ * moco is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 3.0 of the License, or (at your option) any later version.
+ *
+ * moco is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * Linking this program and/or its accompanying libraries statically or
+ * dynamically with other modules is making a combined work based on this
+ * program. Thus, the terms and conditions of the GNU General Public License
+ * cover the whole combination.
+ *
+ * As a special exception, the copyright holders of moco give
+ * you permission to link this programm and/or its accompanying libraries
+ * with independent modules to produce an executable, regardless of the
+ * license terms of these independent modules, and to copy and distribute the
+ * resulting executable under terms of your choice, provided that you also meet,
+ * for each linked independent module, the terms and conditions of the
+ * license of that module.
+ *
+ * An independent module is a module which is not
+ * derived from or based on this program and/or its accompanying libraries.
+ * If you modify this library, you may extend this exception to your version of
+ * the program or library, but you are not obliged to do so. If you do not wish
+ * to do so, delete this exception statement from your version.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this library.
+ */
+package de.uni.bremen.monty.moco.ast.types;
+
+import de.uni.bremen.monty.moco.ast.ASTNode;
+import de.uni.bremen.monty.moco.ast.Identifier;
+import de.uni.bremen.monty.moco.ast.declaration.*;
+import de.uni.bremen.monty.moco.util.AllIterator;
+import org.apache.commons.lang3.builder.EqualsBuilder;
+import org.apache.commons.lang3.builder.HashCodeBuilder;
+
+import java.util.*;
+
+public class ConcreteType extends PartialAppliedTypeInfo {
+
+ private static Set allTypes = new HashSet<>();
+ private final List concreteTypeParamters;
+
+ ConcreteType(ClassDeclaration declaration, List concreteTypeParamters, TypeContext context) {
+ super(declaration,concreteTypeParamters, context);
+ this.concreteTypeParamters = concreteTypeParamters;
+ if(declaration.getTypeParameterDeclarations().size() != concreteTypeParamters.size()){
+ throw new RuntimeException("abstract and concrete Types does not match");
+ }
+ if(!declaration.isDummy()) {
+ allTypes.add(this);
+ }
+ }
+
+ public List getSuperClassDeclarationsRecursive() {
+ List allSuperClassDeclarations = new ArrayList<>();
+ for (PartialAppliedTypeInfo superClass : declaration.getSuperClassDeclarations()) {
+ ConcreteType concreteType = (ConcreteType) superClass.extend(context);
+ Collection superClassDeclarationsRecursive = concreteType.getSuperClassDeclarationsRecursive();
+ allSuperClassDeclarations.addAll(superClassDeclarationsRecursive);
+ }
+ allSuperClassDeclarations.add(this);
+ return allSuperClassDeclarations;
+ }
+
+ @Override
+ public Identifier getIdentifier() {
+ return declaration.getIdentifier();
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+
+ if (o == null || getClass() != o.getClass()) return false;
+
+ ConcreteType that = (ConcreteType) o;
+
+ return new EqualsBuilder()
+ .append(declaration, that.declaration)
+ .append(concreteTypeParamters, that.concreteTypeParamters)
+ .isEquals();
+ }
+
+ @Override
+ public int hashCode() {
+ return new HashCodeBuilder(17, 37)
+ .append(declaration.getIdentifier())
+ .append(1)
+ .append(concreteTypeParamters)
+ .toHashCode();
+ }
+
+ public List getVirtualMethods() {
+ List functions = new ArrayList<>();
+ for (FunctionDeclaration functionDeclaration : declaration.getVirtualMethodTable()) {
+ functions.add(TypeFactory.makeConcrete(functionDeclaration, context));
+ }
+ return functions;
+ }
+
+ public ConcreteFunctionType getWrappedFunction() {
+ return TypeFactory.makeConcrete(declaration.getWrappedFunction(), context);
+ }
+
+ public List getVariables() {
+ ArrayList result = new ArrayList<>();
+ for (Declaration decl : declaration.getBlock().getDeclarations()) {
+ if (decl instanceof VariableDeclaration) {
+ result.add(TypeFactory.makeConcrete((VariableDeclaration) decl,context));
+ }
+ }
+ return result;
+ }
+
+ public boolean isGenerator() {
+ return declaration.isGenerator();
+ }
+
+ public ModuleDeclaration getModuleDeclaration() {
+ return declaration.getParentNodeByType(ModuleDeclaration.class);
+ }
+
+ public List getConcreteGenericTypes() {
+ return concreteTypeParamters;
+ }
+
+ public List getMethods() {
+ List functions = new ArrayList<>();
+
+ for (FunctionDeclaration declaration : declaration.getMethods()) {
+ functions.add(TypeFactory.makeConcrete(declaration, context));
+ }
+ return functions;
+ }
+
+ public static Iterable getAllTypes() {
+ return () -> new AllIterator(allTypes);
+ }
+
+ public ASTNode getBlock() {
+ return declaration.getBlock();
+ }
+
+ public boolean hasWrappedFunction() {
+ return declaration.getWrappedFunction() != null;
+ }
+
+ public static void reset() {
+ allTypes.clear();
+ }
+
+ public boolean isFunctionWrapper() {
+ return declaration.isFunctionWrapper();
+ }
+
+ public ConcreteFunctionType getDefaultInitializer() {
+ return (ConcreteFunctionType) super.getDefaultInitializer();
+ }
+}
diff --git a/src/main/java/de/uni/bremen/monty/moco/ast/types/ConcreteVariableType.java b/src/main/java/de/uni/bremen/monty/moco/ast/types/ConcreteVariableType.java
new file mode 100644
index 0000000..19404dd
--- /dev/null
+++ b/src/main/java/de/uni/bremen/monty/moco/ast/types/ConcreteVariableType.java
@@ -0,0 +1,63 @@
+/*
+ * moco, the Monty Compiler
+ * Copyright (c) 2013-2014, Monty's Coconut, All rights reserved.
+ *
+ * This file is part of moco, the Monty Compiler.
+ *
+ * moco is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 3.0 of the License, or (at your option) any later version.
+ *
+ * moco is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * Linking this program and/or its accompanying libraries statically or
+ * dynamically with other modules is making a combined work based on this
+ * program. Thus, the terms and conditions of the GNU General Public License
+ * cover the whole combination.
+ *
+ * As a special exception, the copyright holders of moco give
+ * you permission to link this programm and/or its accompanying libraries
+ * with independent modules to produce an executable, regardless of the
+ * license terms of these independent modules, and to copy and distribute the
+ * resulting executable under terms of your choice, provided that you also meet,
+ * for each linked independent module, the terms and conditions of the
+ * license of that module.
+ *
+ * An independent module is a module which is not
+ * derived from or based on this program and/or its accompanying libraries.
+ * If you modify this library, you may extend this exception to your version of
+ * the program or library, but you are not obliged to do so. If you do not wish
+ * to do so, delete this exception statement from your version.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this library.
+ */
+package de.uni.bremen.monty.moco.ast.types;
+
+import de.uni.bremen.monty.moco.ast.declaration.VariableDeclaration;
+
+public class ConcreteVariableType extends VariableType {
+ private final TypeContext context;
+
+ ConcreteVariableType(VariableDeclaration declaration, ConcreteType returnType, TypeContext context) {
+ super(declaration, returnType);
+ this.context = context;
+ }
+
+ @Override
+ public ConcreteType getType() {
+ return (ConcreteType) super.getType();
+ }
+
+ public TypeContext getContext() {
+ return context;
+ }
+
+ public VariableDeclaration getDeclaration() {
+ return declaration;
+ }
+}
diff --git a/src/main/java/de/uni/bremen/monty/moco/ast/types/FunctionType.java b/src/main/java/de/uni/bremen/monty/moco/ast/types/FunctionType.java
new file mode 100644
index 0000000..c7159f0
--- /dev/null
+++ b/src/main/java/de/uni/bremen/monty/moco/ast/types/FunctionType.java
@@ -0,0 +1,84 @@
+/*
+ * moco, the Monty Compiler
+ * Copyright (c) 2013-2014, Monty's Coconut, All rights reserved.
+ *
+ * This file is part of moco, the Monty Compiler.
+ *
+ * moco is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 3.0 of the License, or (at your option) any later version.
+ *
+ * moco is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * Linking this program and/or its accompanying libraries statically or
+ * dynamically with other modules is making a combined work based on this
+ * program. Thus, the terms and conditions of the GNU General Public License
+ * cover the whole combination.
+ *
+ * As a special exception, the copyright holders of moco give
+ * you permission to link this programm and/or its accompanying libraries
+ * with independent modules to produce an executable, regardless of the
+ * license terms of these independent modules, and to copy and distribute the
+ * resulting executable under terms of your choice, provided that you also meet,
+ * for each linked independent module, the terms and conditions of the
+ * license of that module.
+ *
+ * An independent module is a module which is not
+ * derived from or based on this program and/or its accompanying libraries.
+ * If you modify this library, you may extend this exception to your version of
+ * the program or library, but you are not obliged to do so. If you do not wish
+ * to do so, delete this exception statement from your version.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this library.
+ */
+package de.uni.bremen.monty.moco.ast.types;
+
+import de.uni.bremen.monty.moco.ast.ASTNode;
+import de.uni.bremen.monty.moco.ast.Identifier;
+import de.uni.bremen.monty.moco.ast.declaration.FunctionDeclaration;
+
+import java.util.List;
+
+public interface FunctionType extends MemberType {
+ int getVMTIndex();
+
+ Identifier getIdentifier();
+
+ PartialAppliedTypeInfo getDefiningClass();
+
+ Type getReturnType();
+
+ boolean isFunction();
+
+ List extends Type> getParameterTypes();
+
+ @Override
+ ASTNode getASTNode();
+
+ TypeContext getContext();
+
+ boolean isMethod();
+
+ boolean isInitializer();
+
+ boolean isClosure();
+
+ PartialAppliedTypeInfo getWrapperClass();
+
+ boolean isDefaultInitializer();
+
+ VariableType getWrapperFunctionObjectDeclaration();
+
+ List extends VariableType> getClosureVariables();
+
+ FunctionDeclaration.DeclarationType getDeclarationType();
+
+ FunctionType extend(TypeContext context);
+
+ String toString();
+}
diff --git a/src/main/java/de/uni/bremen/monty/moco/ast/types/FunctionTypeDecl.java b/src/main/java/de/uni/bremen/monty/moco/ast/types/FunctionTypeDecl.java
new file mode 100644
index 0000000..94341bc
--- /dev/null
+++ b/src/main/java/de/uni/bremen/monty/moco/ast/types/FunctionTypeDecl.java
@@ -0,0 +1,164 @@
+/*
+ * moco, the Monty Compiler
+ * Copyright (c) 2013-2014, Monty's Coconut, All rights reserved.
+ *
+ * This file is part of moco, the Monty Compiler.
+ *
+ * moco is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 3.0 of the License, or (at your option) any later version.
+ *
+ * moco is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * Linking this program and/or its accompanying libraries statically or
+ * dynamically with other modules is making a combined work based on this
+ * program. Thus, the terms and conditions of the GNU General Public License
+ * cover the whole combination.
+ *
+ * As a special exception, the copyright holders of moco give
+ * you permission to link this programm and/or its accompanying libraries
+ * with independent modules to produce an executable, regardless of the
+ * license terms of these independent modules, and to copy and distribute the
+ * resulting executable under terms of your choice, provided that you also meet,
+ * for each linked independent module, the terms and conditions of the
+ * license of that module.
+ *
+ * An independent module is a module which is not
+ * derived from or based on this program and/or its accompanying libraries.
+ * If you modify this library, you may extend this exception to your version of
+ * the program or library, but you are not obliged to do so. If you do not wish
+ * to do so, delete this exception statement from your version.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this library.
+ */
+package de.uni.bremen.monty.moco.ast.types;
+
+import de.uni.bremen.monty.moco.ast.ASTNode;
+import de.uni.bremen.monty.moco.ast.Identifier;
+import de.uni.bremen.monty.moco.ast.declaration.FunctionDeclaration;
+
+import java.util.List;
+import java.util.stream.Collectors;
+
+public class FunctionTypeDecl implements FunctionType {
+ protected final FunctionDeclaration declaration;
+ protected final TypeContext context;
+ protected final Type returnType;
+ protected final PartialAppliedTypeInfo definingClass;
+ protected final List extends VariableType> parameter;
+ protected final PartialAppliedTypeInfo wrapperClass;
+ protected final VariableType wrapperFunctionObjects;
+ protected final List extends VariableType> closureVariables;
+
+ FunctionTypeDecl(FunctionDeclaration declaration, TypeContext context, List extends VariableType> parameter, Type returnType, PartialAppliedTypeInfo definingClass, PartialAppliedTypeInfo wrapperClass, VariableType wrapperFunctionObjects, List extends VariableType> closureVariables) {
+ this.declaration = declaration;
+ this.context = context;
+ this.parameter = parameter;
+ this.returnType = returnType;
+ this.definingClass = definingClass;
+ this.wrapperClass = wrapperClass;
+ this.wrapperFunctionObjects = wrapperFunctionObjects;
+ this.closureVariables = closureVariables;
+ }
+
+ @Override
+ public int getVMTIndex() {
+ return declaration.getVMTIndex();
+ }
+
+ @Override
+ public Identifier getIdentifier() {
+ return declaration.getIdentifier();
+ }
+
+ @Override
+ public PartialAppliedTypeInfo getDefiningClass() {
+ return definingClass;
+ }
+
+ @Override
+ public Type getReturnType() {
+ if(declaration.isReturnTypeToBeInferred()){
+ return declaration.getReturnType().extend(context);
+ }
+ return returnType;
+ }
+
+ @Override
+ public boolean isFunction() {
+ return declaration.isFunction();
+ }
+
+ public List getParameterTypes() {
+ return parameter.stream().map(VariableType::getType).collect(Collectors.toList());
+ }
+
+ public List extends VariableType> getParameter() {
+ return parameter;
+ }
+
+ @Override
+ public ASTNode getASTNode() {
+ return declaration;
+ }
+
+ @Override
+ public TypeContext getContext() {
+ return context;
+ }
+
+ @Override
+ public boolean isMethod() {
+ return declaration.isMethod();
+ }
+
+ @Override
+ public boolean isInitializer() {
+ return declaration.isInitializer();
+ }
+
+ @Override
+ public boolean isClosure() {
+ return declaration.isClosure();
+ }
+
+ @Override
+ public PartialAppliedTypeInfo getWrapperClass() {
+ return wrapperClass;
+ }
+
+ @Override
+ public boolean isDefaultInitializer() {
+ return declaration.isDefaultInitializer();
+ }
+
+ @Override
+ public VariableType getWrapperFunctionObjectDeclaration() {
+ return wrapperFunctionObjects;
+ }
+
+ @Override
+ public List extends VariableType> getClosureVariables() {
+ return closureVariables;
+ }
+
+ @Override
+ public FunctionDeclaration.DeclarationType getDeclarationType() {
+ return declaration.getDeclarationType();
+ }
+
+ @Override
+ public FunctionType extend(TypeContext context) {
+ return TypeFactory.from(declaration, this.context.extend(context));
+ }
+
+ @Override
+ public String toString() {
+ return declaration.toString();
+ }
+}
diff --git a/src/main/java/de/uni/bremen/monty/moco/ast/types/FunctionTypeVariable.java b/src/main/java/de/uni/bremen/monty/moco/ast/types/FunctionTypeVariable.java
new file mode 100644
index 0000000..983ef59
--- /dev/null
+++ b/src/main/java/de/uni/bremen/monty/moco/ast/types/FunctionTypeVariable.java
@@ -0,0 +1,169 @@
+/*
+ * moco, the Monty Compiler
+ * Copyright (c) 2013-2014, Monty's Coconut, All rights reserved.
+ *
+ * This file is part of moco, the Monty Compiler.
+ *
+ * moco is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 3.0 of the License, or (at your option) any later version.
+ *
+ * moco is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * Linking this program and/or its accompanying libraries statically or
+ * dynamically with other modules is making a combined work based on this
+ * program. Thus, the terms and conditions of the GNU General Public License
+ * cover the whole combination.
+ *
+ * As a special exception, the copyright holders of moco give
+ * you permission to link this programm and/or its accompanying libraries
+ * with independent modules to produce an executable, regardless of the
+ * license terms of these independent modules, and to copy and distribute the
+ * resulting executable under terms of your choice, provided that you also meet,
+ * for each linked independent module, the terms and conditions of the
+ * license of that module.
+ *
+ * An independent module is a module which is not
+ * derived from or based on this program and/or its accompanying libraries.
+ * If you modify this library, you may extend this exception to your version of
+ * the program or library, but you are not obliged to do so. If you do not wish
+ * to do so, delete this exception statement from your version.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this library.
+ */
+package de.uni.bremen.monty.moco.ast.types;
+
+import de.uni.bremen.monty.moco.ast.ASTNode;
+import de.uni.bremen.monty.moco.ast.Identifier;
+import de.uni.bremen.monty.moco.ast.declaration.FunctionDeclaration;
+import de.uni.bremen.monty.moco.ast.declaration.VariableDeclaration;
+
+import java.util.Collections;
+import java.util.List;
+
+public class FunctionTypeVariable implements ConcreteFunctionType {
+ private final List paramTypes;
+ private final ConcreteType returnType;
+ private VariableDeclaration declaration;
+
+ FunctionTypeVariable(VariableDeclaration declaration) {
+ this.declaration = declaration;
+ if(!declaration.getType().isFunction()){
+ throw new RuntimeException("Function Variable has to be a Function");
+ }
+ List functionTypes = ((ConcreteType) declaration.getType()).getConcreteGenericTypes();
+
+ ConcreteType paramType = functionTypes.get(0);
+ if (paramType.isTuple()) {
+ paramTypes = paramType.getConcreteGenericTypes();
+ } else {
+ paramTypes = Collections.singletonList(paramType);
+ }
+
+ returnType = functionTypes.get(1);
+
+ if(!(returnType instanceof ConcreteType && paramTypes.stream().allMatch( s -> s instanceof ConcreteType) )) {
+ throw new RuntimeException("Only concrete Function Variables are allowed");
+ }
+ }
+
+ @Override
+ public int getVMTIndex() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public Identifier getIdentifier() {
+ return declaration.getIdentifier();
+ }
+
+ @Override
+ public ConcreteType getDefiningClass() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public ConcreteType getReturnType() {
+ return returnType;
+ }
+
+ @Override
+ public List getParameter() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean isFunction() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public List extends Type> getParameterTypes() {
+ return paramTypes;
+ }
+
+ @Override
+ public ASTNode getASTNode() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public TypeContext getContext() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean isMethod() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean isInitializer() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean isClosure() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public ConcreteType getWrapperClass() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean isDefaultInitializer() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public ConcreteVariableType getWrapperFunctionObjectDeclaration() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public List getClosureVariables() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public FunctionDeclaration.DeclarationType getDeclarationType() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public FunctionType extend(TypeContext context) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public String toString() {
+ throw new UnsupportedOperationException();
+ }
+}
diff --git a/src/main/java/de/uni/bremen/monty/moco/ast/types/GeneratorFunctionType.java b/src/main/java/de/uni/bremen/monty/moco/ast/types/GeneratorFunctionType.java
new file mode 100644
index 0000000..24b9dc8
--- /dev/null
+++ b/src/main/java/de/uni/bremen/monty/moco/ast/types/GeneratorFunctionType.java
@@ -0,0 +1,49 @@
+/*
+ * moco, the Monty Compiler
+ * Copyright (c) 2013-2014, Monty's Coconut, All rights reserved.
+ *
+ * This file is part of moco, the Monty Compiler.
+ *
+ * moco is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 3.0 of the License, or (at your option) any later version.
+ *
+ * moco is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * Linking this program and/or its accompanying libraries statically or
+ * dynamically with other modules is making a combined work based on this
+ * program. Thus, the terms and conditions of the GNU General Public License
+ * cover the whole combination.
+ *
+ * As a special exception, the copyright holders of moco give
+ * you permission to link this programm and/or its accompanying libraries
+ * with independent modules to produce an executable, regardless of the
+ * license terms of these independent modules, and to copy and distribute the
+ * resulting executable under terms of your choice, provided that you also meet,
+ * for each linked independent module, the terms and conditions of the
+ * license of that module.
+ *
+ * An independent module is a module which is not
+ * derived from or based on this program and/or its accompanying libraries.
+ * If you modify this library, you may extend this exception to your version of
+ * the program or library, but you are not obliged to do so. If you do not wish
+ * to do so, delete this exception statement from your version.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this library.
+ */
+package de.uni.bremen.monty.moco.ast.types;
+
+import de.uni.bremen.monty.moco.ast.statement.YieldStatement;
+
+import java.util.List;
+
+public interface GeneratorFunctionType {
+ List getYieldStatements();
+
+ List extends VariableType> getVariableDeclarations();
+}
diff --git a/src/main/java/de/uni/bremen/monty/moco/ast/types/GeneratorFunctionTypeImpl.java b/src/main/java/de/uni/bremen/monty/moco/ast/types/GeneratorFunctionTypeImpl.java
new file mode 100644
index 0000000..005edf5
--- /dev/null
+++ b/src/main/java/de/uni/bremen/monty/moco/ast/types/GeneratorFunctionTypeImpl.java
@@ -0,0 +1,66 @@
+/*
+ * moco, the Monty Compiler
+ * Copyright (c) 2013-2014, Monty's Coconut, All rights reserved.
+ *
+ * This file is part of moco, the Monty Compiler.
+ *
+ * moco is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 3.0 of the License, or (at your option) any later version.
+ *
+ * moco is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * Linking this program and/or its accompanying libraries statically or
+ * dynamically with other modules is making a combined work based on this
+ * program. Thus, the terms and conditions of the GNU General Public License
+ * cover the whole combination.
+ *
+ * As a special exception, the copyright holders of moco give
+ * you permission to link this programm and/or its accompanying libraries
+ * with independent modules to produce an executable, regardless of the
+ * license terms of these independent modules, and to copy and distribute the
+ * resulting executable under terms of your choice, provided that you also meet,
+ * for each linked independent module, the terms and conditions of the
+ * license of that module.
+ *
+ * An independent module is a module which is not
+ * derived from or based on this program and/or its accompanying libraries.
+ * If you modify this library, you may extend this exception to your version of
+ * the program or library, but you are not obliged to do so. If you do not wish
+ * to do so, delete this exception statement from your version.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this library.
+ */
+package de.uni.bremen.monty.moco.ast.types;
+
+import de.uni.bremen.monty.moco.ast.declaration.GeneratorFunctionDeclaration;
+import de.uni.bremen.monty.moco.ast.statement.YieldStatement;
+
+import java.util.List;
+import java.util.stream.Collectors;
+
+public class GeneratorFunctionTypeImpl extends FunctionTypeDecl implements GeneratorFunctionType {
+
+ GeneratorFunctionTypeImpl(GeneratorFunctionDeclaration declaration, TypeContext context, List extends VariableType> parameter, Type returnType, PartialAppliedTypeInfo definingClass, PartialAppliedTypeInfo wrapperClass, VariableType wrapperFunctionObjects, List extends VariableType> closureVariables) {
+ super(declaration, context, parameter, returnType, definingClass, wrapperClass, wrapperFunctionObjects, closureVariables);
+ }
+
+ private GeneratorFunctionDeclaration getDeclaration(){
+ return (GeneratorFunctionDeclaration) super.declaration;
+ }
+
+ @Override
+ public List getYieldStatements() {
+ return getDeclaration().getYieldStatements();
+ }
+
+ @Override
+ public List extends VariableType> getVariableDeclarations() {
+ return getDeclaration().getVariableDeclarations().stream().map(d -> TypeFactory.from(d, context)).collect(Collectors.toList());
+ }
+}
diff --git a/src/main/java/de/uni/bremen/monty/moco/ast/types/MemberType.java b/src/main/java/de/uni/bremen/monty/moco/ast/types/MemberType.java
new file mode 100644
index 0000000..978d819
--- /dev/null
+++ b/src/main/java/de/uni/bremen/monty/moco/ast/types/MemberType.java
@@ -0,0 +1,45 @@
+/*
+ * moco, the Monty Compiler
+ * Copyright (c) 2013-2014, Monty's Coconut, All rights reserved.
+ *
+ * This file is part of moco, the Monty Compiler.
+ *
+ * moco is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 3.0 of the License, or (at your option) any later version.
+ *
+ * moco is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * Linking this program and/or its accompanying libraries statically or
+ * dynamically with other modules is making a combined work based on this
+ * program. Thus, the terms and conditions of the GNU General Public License
+ * cover the whole combination.
+ *
+ * As a special exception, the copyright holders of moco give
+ * you permission to link this programm and/or its accompanying libraries
+ * with independent modules to produce an executable, regardless of the
+ * license terms of these independent modules, and to copy and distribute the
+ * resulting executable under terms of your choice, provided that you also meet,
+ * for each linked independent module, the terms and conditions of the
+ * license of that module.
+ *
+ * An independent module is a module which is not
+ * derived from or based on this program and/or its accompanying libraries.
+ * If you modify this library, you may extend this exception to your version of
+ * the program or library, but you are not obliged to do so. If you do not wish
+ * to do so, delete this exception statement from your version.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this library.
+ */
+package de.uni.bremen.monty.moco.ast.types;
+
+import de.uni.bremen.monty.moco.ast.ASTNode;
+
+public interface MemberType {
+ ASTNode getASTNode();
+}
diff --git a/src/main/java/de/uni/bremen/monty/moco/ast/types/PartialAppliedTypeInfo.java b/src/main/java/de/uni/bremen/monty/moco/ast/types/PartialAppliedTypeInfo.java
new file mode 100644
index 0000000..780c404
--- /dev/null
+++ b/src/main/java/de/uni/bremen/monty/moco/ast/types/PartialAppliedTypeInfo.java
@@ -0,0 +1,220 @@
+/*
+ * moco, the Monty Compiler
+ * Copyright (c) 2013-2014, Monty's Coconut, All rights reserved.
+ *
+ * This file is part of moco, the Monty Compiler.
+ *
+ * moco is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 3.0 of the License, or (at your option) any later version.
+ *
+ * moco is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * Linking this program and/or its accompanying libraries statically or
+ * dynamically with other modules is making a combined work based on this
+ * program. Thus, the terms and conditions of the GNU General Public License
+ * cover the whole combination.
+ *
+ * As a special exception, the copyright holders of moco give
+ * you permission to link this programm and/or its accompanying libraries
+ * with independent modules to produce an executable, regardless of the
+ * license terms of these independent modules, and to copy and distribute the
+ * resulting executable under terms of your choice, provided that you also meet,
+ * for each linked independent module, the terms and conditions of the
+ * license of that module.
+ *
+ * An independent module is a module which is not
+ * derived from or based on this program and/or its accompanying libraries.
+ * If you modify this library, you may extend this exception to your version of
+ * the program or library, but you are not obliged to do so. If you do not wish
+ * to do so, delete this exception statement from your version.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this library.
+ */
+package de.uni.bremen.monty.moco.ast.types;
+
+import de.uni.bremen.monty.moco.ast.ClassScope;
+import de.uni.bremen.monty.moco.ast.Identifier;
+import de.uni.bremen.monty.moco.ast.ResolvableIdentifier;
+import de.uni.bremen.monty.moco.ast.declaration.ClassDeclaration;
+import de.uni.bremen.monty.moco.ast.declaration.FunctionDeclaration;
+import de.uni.bremen.monty.moco.visitor.VisitOnceVisitor;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.stream.Collectors;
+
+public class PartialAppliedTypeInfo extends Type {
+
+ protected final ClassDeclaration declaration;
+ private final List extends Type> partialAppliedTypes;
+ protected final TypeContext context;
+
+ PartialAppliedTypeInfo(ClassDeclaration declaration, List extends Type> partialAppliedTypes, TypeContext context) {
+ this.declaration = declaration;
+ this.partialAppliedTypes = partialAppliedTypes;
+ this.context = TypeContext.from(declaration, partialAppliedTypes).extend(context);
+ }
+
+ @Override
+ public boolean matchesTypeExactly(Type type) {
+ if(type instanceof PartialAppliedTypeInfo){
+ PartialAppliedTypeInfo other = (PartialAppliedTypeInfo) type;
+ if (other.declaration.equals(this.declaration)) {
+ for (int i = 0; i < partialAppliedTypes.size(); i++) {
+ Type partialAppliedType = partialAppliedTypes.get(i);
+ Type typeVariable = other.partialAppliedTypes.get(i);
+ if(typeVariable instanceof TypeVariable){
+ continue;
+ }
+ if(!partialAppliedType.matchesTypeExactly(typeVariable)){
+ return false;
+ }
+ }
+ return true;
+ } else if (matchesVoidAndTuple0(this, other) || matchesVoidAndTuple0(other, this)) {
+ return true;
+ }
+ }
+// else {
+//// context.makeConcrete()
+//// TypeVariable typeVariable = (TypeVariable) type;
+//// typeVariable.turnConcrete(this)
+//// turnConcrete(typeVariable)
+// return false;
+// }
+ return false;
+ }
+
+ private static boolean matchesVoidAndTuple0(PartialAppliedTypeInfo type, PartialAppliedTypeInfo other) {
+ return type.isVoid() && other.isTuple(0);
+ }
+
+ @Override
+ public Identifier getIdentifier() {
+ return declaration.getIdentifier();
+ }
+
+ public ClassScope getScope() {
+ return declaration.getScope().extend(context);
+ }
+
+ public int getLastAttributeIndex() {
+ return declaration.getLastAttributeIndex();
+ }
+
+ public List getVirtualMethodTable() {
+ return declaration.getVirtualMethodTable();
+ }
+
+ public List getSuperClassDeclarations() {
+ return declaration.getSuperClassDeclarations();
+ }
+
+ @Override
+ public boolean isAssignableFrom(Type other) {
+ if (matchesTypeExactly(other)) {
+ return true;
+ }
+ if ((other instanceof PartialAppliedTypeInfo)) {
+ PartialAppliedTypeInfo otherType = (PartialAppliedTypeInfo) other;
+ boolean superMatch = declaration.getSuperClassDeclarations().stream().anyMatch(e -> e.declaration == otherType.declaration);
+ return superMatch;
+ }
+ return false;
+ }
+
+ @Override
+ protected boolean matchesDeclaration(ClassDeclaration declaration) {
+ return this.declaration.equals(declaration);
+ }
+
+ public TypeContext getContext() {
+ return context;
+ }
+
+// ConcreteTypeInfo turnConcrete(TypeContext context) {
+// ArrayList concreteTypeParamters = new ArrayList<>();
+// for (Type partialAppliedType : partialAppliedTypes) {
+// concreteTypeParamters.add(context.makeConcrete(partialAppliedType));
+// }
+// return new ConcreteTypeInfo(declaration, concreteTypeParamters);
+// }
+
+ public Type extend(TypeContext context) {
+ return TypeFactory.from(declaration, this.context.extend(context));
+ }
+
+ public String toString() {
+ Object genericTypes = partialAppliedTypes.isEmpty() ? "" : partialAppliedTypes;
+ return getIdentifier().getSymbol() + genericTypes;
+ }
+
+ public boolean isTuple(int n) {
+ return isTuple() && partialAppliedTypes.size() == n;
+ }
+
+ public boolean isTuple() {
+ String strIdent = getIdentifier().getSymbol();
+ if (strIdent.startsWith("Tuple")) {
+ int n;
+ try {
+ n = Integer.parseInt(strIdent.substring(5));
+ } catch (Exception e) {
+ return false;
+ }
+ if (partialAppliedTypes.size() == n) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public boolean isFunction() {
+ return isAssignableFrom(Types.functionType());
+ }
+
+ public List extends Type> getPartialAppliedTypes() {
+ return partialAppliedTypes;
+ }
+
+ public boolean isAbstract() {
+ return declaration.isAbstract();
+ }
+
+ public FunctionType getDefaultInitializer() {
+ return TypeFactory.from(declaration.getDefaultInitializer(), context);
+ }
+
+ public List getInitializers(VisitOnceVisitor visitor) {
+ List functions = new ArrayList<>();
+
+ // iterate through the declarations of the given class
+ for (FunctionDeclaration declaration : declaration.getMethods()) {
+ // find a matching declaration
+ if ("initializer".equals(declaration.getIdentifier().getSymbol())) {
+ // and verify that it is a function...
+ // without any return type
+ if (!(declaration.isFunction())) {
+ visitor.visitDoubleDispatched(declaration);
+ functions.add(TypeFactory.from(declaration, context));
+ }
+ }
+ }
+ return functions;
+ }
+
+ public void visit(VisitOnceVisitor visitor) {
+ visitor.visitDoubleDispatched(declaration);
+ }
+
+ public ResolvableIdentifier getResolvableIdentifier() {
+ return new ResolvableIdentifier(declaration.getIdentifier().getSymbol(), partialAppliedTypes.stream().map(r -> r.getResolvableIdentifier()).collect(Collectors.toList()));
+ }
+}
diff --git a/src/main/java/de/uni/bremen/monty/moco/ast/types/Type.java b/src/main/java/de/uni/bremen/monty/moco/ast/types/Type.java
new file mode 100644
index 0000000..c0dab5e
--- /dev/null
+++ b/src/main/java/de/uni/bremen/monty/moco/ast/types/Type.java
@@ -0,0 +1,124 @@
+/*
+ * moco, the Monty Compiler
+ * Copyright (c) 2013-2014, Monty's Coconut, All rights reserved.
+ *
+ * This file is part of moco, the Monty Compiler.
+ *
+ * moco is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 3.0 of the License, or (at your option) any later version.
+ *
+ * moco is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * Linking this program and/or its accompanying libraries statically or
+ * dynamically with other modules is making a combined work based on this
+ * program. Thus, the terms and conditions of the GNU General Public License
+ * cover the whole combination.
+ *
+ * As a special exception, the copyright holders of moco give
+ * you permission to link this programm and/or its accompanying libraries
+ * with independent modules to produce an executable, regardless of the
+ * license terms of these independent modules, and to copy and distribute the
+ * resulting executable under terms of your choice, provided that you also meet,
+ * for each linked independent module, the terms and conditions of the
+ * license of that module.
+ *
+ * An independent module is a module which is not
+ * derived from or based on this program and/or its accompanying libraries.
+ * If you modify this library, you may extend this exception to your version of
+ * the program or library, but you are not obliged to do so. If you do not wish
+ * to do so, delete this exception statement from your version.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this library.
+ */
+package de.uni.bremen.monty.moco.ast.types;
+
+import de.uni.bremen.monty.moco.ast.CoreClasses;
+import de.uni.bremen.monty.moco.ast.Identifier;
+import de.uni.bremen.monty.moco.ast.ResolvableIdentifier;
+import de.uni.bremen.monty.moco.ast.Scope;
+import de.uni.bremen.monty.moco.ast.declaration.ClassDeclaration;
+
+/**
+ * Is a Class or a TypeVariable or something between.
+ * Not FunctionDecl or Mudule
+ */
+public abstract class Type {
+
+ public abstract boolean isAssignableFrom(Type other);
+
+ public boolean isVoid() {
+ return this.matchesDeclaration(CoreClasses.voidType());
+ }
+
+ protected abstract boolean matchesDeclaration(ClassDeclaration declaration);
+
+ public abstract boolean matchesTypeExactly(Type type);
+
+ public abstract Identifier getIdentifier();
+
+ /** Calculates the distance of this and other in the inheritance graph. Only calculates positive distances, i.e. if
+ * this is a parameter and other is an argument, other must be equal to or a subtype of this. otherwise the result
+ * will be Integer.MAX_VALUE.
+ *
+ * @param other
+ * @return a distance 0 <= dist <= Integer.MAX_VALUE */
+ public int getTypeDist(Type other) {
+ return getTypeDist(other, 0);
+ }
+
+ /** a helper method for "public int getTypeDist(TypeDeclaration other)"
+ *
+ * @param other
+ * @param dist
+ * @return */
+ protected int getTypeDist(Type other, int dist) {
+ if (dist == Integer.MAX_VALUE) {
+ return dist;
+ }
+ if (matchesTypeExactly(other)) {
+ return dist;
+ } else if ((other instanceof PartialAppliedTypeInfo)
+ && (!((PartialAppliedTypeInfo) other).getSuperClassDeclarations().isEmpty())) {
+ int parentDist = Integer.MAX_VALUE;
+ for (Type superClass : ((PartialAppliedTypeInfo) other).getSuperClassDeclarations()) {
+ int superDist = getTypeDist(superClass, dist + 1);
+ if (superDist < parentDist) {
+ parentDist = superDist;
+ }
+ }
+ return parentDist;
+ } else if (other instanceof TypeVariable) {
+ return getTypeDist(((TypeVariable) other).getUpperTypeBound());
+ }
+ return Integer.MAX_VALUE;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public int hashCode() {
+ throw new UnsupportedOperationException();
+ }
+
+ public abstract Scope getScope();
+
+ public abstract Type extend(TypeContext context);
+// abstract ConcreteTypeInfo turnConcrete(TypeContext context);
+
+ public abstract boolean isTuple(int n);
+
+ public abstract boolean isTuple();
+
+ public abstract boolean isFunction();
+
+ public abstract ResolvableIdentifier getResolvableIdentifier();
+}
diff --git a/src/main/java/de/uni/bremen/monty/moco/ast/types/TypeContext.java b/src/main/java/de/uni/bremen/monty/moco/ast/types/TypeContext.java
new file mode 100644
index 0000000..e7bc271
--- /dev/null
+++ b/src/main/java/de/uni/bremen/monty/moco/ast/types/TypeContext.java
@@ -0,0 +1,86 @@
+/*
+ * moco, the Monty Compiler
+ * Copyright (c) 2013-2014, Monty's Coconut, All rights reserved.
+ *
+ * This file is part of moco, the Monty Compiler.
+ *
+ * moco is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 3.0 of the License, or (at your option) any later version.
+ *
+ * moco is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * Linking this program and/or its accompanying libraries statically or
+ * dynamically with other modules is making a combined work based on this
+ * program. Thus, the terms and conditions of the GNU General Public License
+ * cover the whole combination.
+ *
+ * As a special exception, the copyright holders of moco give
+ * you permission to link this programm and/or its accompanying libraries
+ * with independent modules to produce an executable, regardless of the
+ * license terms of these independent modules, and to copy and distribute the
+ * resulting executable under terms of your choice, provided that you also meet,
+ * for each linked independent module, the terms and conditions of the
+ * license of that module.
+ *
+ * An independent module is a module which is not
+ * derived from or based on this program and/or its accompanying libraries.
+ * If you modify this library, you may extend this exception to your version of
+ * the program or library, but you are not obliged to do so. If you do not wish
+ * to do so, delete this exception statement from your version.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this library.
+ */
+package de.uni.bremen.monty.moco.ast.types;
+
+import de.uni.bremen.monty.moco.ast.declaration.TypeParameterDeclaration;
+import de.uni.bremen.monty.moco.ast.declaration.ClassDeclaration;
+import de.uni.bremen.monty.moco.exception.InvalidTypeException;
+
+import java.util.List;
+
+public abstract class TypeContext {
+ public static TypeContext EMPTY = new TypeContext() {
+ @Override
+ public TypeContext extend(TypeContext context) {
+ return context;
+ }
+
+ @Override
+ public Type resolve(Type type) {
+ return type;
+ }
+
+ @Override
+ public Type resolve(TypeParameterDeclaration typeVariable) {
+ return new TypeVariable(typeVariable);
+ }
+
+ @Override
+ protected Type tryToResolve(TypeParameterDeclaration typeVariable) {
+ return null;
+ }
+ };
+
+ public abstract TypeContext extend(TypeContext context);
+ public abstract Type resolve(Type type);
+ public abstract Type resolve(TypeParameterDeclaration typeVariable);
+ protected abstract Type tryToResolve(TypeParameterDeclaration typeVariable);
+
+ public ConcreteType makeConcrete(Type type) {
+ return (ConcreteType) resolve(type);
+ }
+
+ public static TypeContext from(ClassDeclaration declaration, List extends Type> partialAppliedTypes) {
+ int declsize = declaration.getTypeParameterDeclarations().size();
+ if(declsize != partialAppliedTypes.size()){
+ throw new InvalidTypeException(String.format("The class %s has %d Typeparameters but only %d were provided", declaration.getIdentifier(), declsize, partialAppliedTypes.size()));
+ }
+ return new TypeContextImpl(declaration, partialAppliedTypes);
+ }
+}
diff --git a/src/main/java/de/uni/bremen/monty/moco/ast/types/TypeContextImpl.java b/src/main/java/de/uni/bremen/monty/moco/ast/types/TypeContextImpl.java
new file mode 100644
index 0000000..107abce
--- /dev/null
+++ b/src/main/java/de/uni/bremen/monty/moco/ast/types/TypeContextImpl.java
@@ -0,0 +1,160 @@
+/*
+ * moco, the Monty Compiler
+ * Copyright (c) 2013-2014, Monty's Coconut, All rights reserved.
+ *
+ * This file is part of moco, the Monty Compiler.
+ *
+ * moco is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 3.0 of the License, or (at your option) any later version.
+ *
+ * moco is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * Linking this program and/or its accompanying libraries statically or
+ * dynamically with other modules is making a combined work based on this
+ * program. Thus, the terms and conditions of the GNU General Public License
+ * cover the whole combination.
+ *
+ * As a special exception, the copyright holders of moco give
+ * you permission to link this programm and/or its accompanying libraries
+ * with independent modules to produce an executable, regardless of the
+ * license terms of these independent modules, and to copy and distribute the
+ * resulting executable under terms of your choice, provided that you also meet,
+ * for each linked independent module, the terms and conditions of the
+ * license of that module.
+ *
+ * An independent module is a module which is not
+ * derived from or based on this program and/or its accompanying libraries.
+ * If you modify this library, you may extend this exception to your version of
+ * the program or library, but you are not obliged to do so. If you do not wish
+ * to do so, delete this exception statement from your version.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this library.
+ */
+package de.uni.bremen.monty.moco.ast.types;
+
+import de.uni.bremen.monty.moco.ast.CoreClasses;
+import de.uni.bremen.monty.moco.ast.declaration.TypeParameterDeclaration;
+import de.uni.bremen.monty.moco.ast.declaration.ClassDeclaration;
+
+import java.util.*;
+import java.util.stream.Collectors;
+
+
+public class TypeContextImpl extends TypeContext {
+
+ private ClassDeclaration declaration;
+ private final List extends Type> appliedTypes;
+ private final TypeContext parent;
+
+ protected TypeContextImpl(ClassDeclaration declaration, List extends Type> appliedTypes) {
+ this.declaration = declaration;
+ this.appliedTypes = appliedTypes;
+ parent = EMPTY;
+ }
+
+ protected TypeContextImpl(ClassDeclaration declaration, List extends Type> appliedTypes, TypeContext parent) {
+ this.declaration = declaration;
+ this.appliedTypes = appliedTypes;
+ this.parent = parent;
+ }
+
+ private List superContext() {
+ return declaration.getSuperClassDeclarations().stream().map( s -> s.context).collect(Collectors.toList());
+ }
+
+ @Override
+ public TypeContext extend(TypeContext context) {
+ return new TypeContextImpl(declaration, appliedTypes, context);
+ }
+
+ @Override
+ public Type resolve(Type type) {
+ if(type instanceof TypeVariable) {
+ return resolve(((TypeVariable) type).declaration);
+ } else {
+ return type.extend(this);
+ }
+ }
+
+ @Override
+ public Type resolve(TypeParameterDeclaration typeVariable) {
+ Type type = tryToResolve(typeVariable);
+ if(type == null){
+ return new TypeVariable(typeVariable);
+ }
+ return type;
+ }
+
+ @Override
+ protected Type tryToResolve(TypeParameterDeclaration typeVariable) {
+ Type type = resolveOwnTypes(typeVariable);
+ if (type != null) {
+ return type;
+ }
+ type = resolveClassParentTypes(typeVariable);
+ if (type != null) return type;
+
+ type = resolveParentTypes(typeVariable);
+ if (type != null) return type;
+
+ return null;
+ }
+
+ private Type resolveFunctionTypes(TypeContext typeContext, TypeParameterDeclaration typeVariable) {
+ if(typeContext instanceof TypeContextImpl && ((TypeContextImpl) typeContext).declaration.equals(CoreClasses.functionType())){
+ Type tuple = ((TypeContextImpl) typeContext).appliedTypes.get(0);
+ if (tuple instanceof PartialAppliedTypeInfo){
+ PartialAppliedTypeInfo concreteTuple = (ConcreteType) tuple;
+ return concreteTuple.context.tryToResolve(typeVariable);
+ }
+ }
+ return null;
+ }
+
+ private Type resolveParentTypes(TypeParameterDeclaration typeVariable) {
+ return parent.tryToResolve(typeVariable);
+ }
+
+ private Type resolveClassParentTypes(TypeParameterDeclaration typeVariable) {
+ Type type;
+ for (TypeContext typeContext : superContext()) {
+ type = typeContext.tryToResolve(typeVariable);
+ if(type != null) {
+ return type;
+ }
+ type = resolveFunctionTypes(typeContext, typeVariable);
+ if (type != null) {
+ return type;
+ }
+ }
+ return null;
+ }
+
+ private Type resolveOwnTypes(TypeParameterDeclaration typeVariable) {
+ Type type = mappings().get(typeVariable);
+ if(type instanceof TypeVariable) {
+ Type otherType = tryToResolve(((TypeVariable) type).declaration);
+ return otherType != null ? otherType : type;
+ }
+ return type;
+ }
+
+ private HashMap mappings() {
+ HashMap map = new HashMap<>();
+ List typeParameterDeclarations = declaration.getTypeParameterDeclarations();
+ for (int i = 0; i < typeParameterDeclarations.size(); i++) {
+ TypeParameterDeclaration key = typeParameterDeclarations.get(i);
+ Type value = appliedTypes.get(i);
+ if (!(value instanceof TypeVariable && ((TypeVariable) value).declaration.equals(key))) {
+ map.put(key, value);
+ }
+ }
+ return map;
+ }
+}
diff --git a/src/main/java/de/uni/bremen/monty/moco/ast/types/TypeFactory.java b/src/main/java/de/uni/bremen/monty/moco/ast/types/TypeFactory.java
new file mode 100644
index 0000000..3210f8f
--- /dev/null
+++ b/src/main/java/de/uni/bremen/monty/moco/ast/types/TypeFactory.java
@@ -0,0 +1,130 @@
+/*
+ * moco, the Monty Compiler
+ * Copyright (c) 2013-2014, Monty's Coconut, All rights reserved.
+ *
+ * This file is part of moco, the Monty Compiler.
+ *
+ * moco is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 3.0 of the License, or (at your option) any later version.
+ *
+ * moco is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * Linking this program and/or its accompanying libraries statically or
+ * dynamically with other modules is making a combined work based on this
+ * program. Thus, the terms and conditions of the GNU General Public License
+ * cover the whole combination.
+ *
+ * As a special exception, the copyright holders of moco give
+ * you permission to link this programm and/or its accompanying libraries
+ * with independent modules to produce an executable, regardless of the
+ * license terms of these independent modules, and to copy and distribute the
+ * resulting executable under terms of your choice, provided that you also meet,
+ * for each linked independent module, the terms and conditions of the
+ * license of that module.
+ *
+ * An independent module is a module which is not
+ * derived from or based on this program and/or its accompanying libraries.
+ * If you modify this library, you may extend this exception to your version of
+ * the program or library, but you are not obliged to do so. If you do not wish
+ * to do so, delete this exception statement from your version.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this library.
+ */
+package de.uni.bremen.monty.moco.ast.types;
+
+import de.uni.bremen.monty.moco.ast.declaration.*;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.stream.Collectors;
+
+public class TypeFactory {
+
+ public static PartialAppliedTypeInfo from(ClassDeclaration declaration, TypeContext context){
+ List types = new ArrayList<>();
+ boolean concrete = true;
+ for (TypeParameterDeclaration typeParameterDeclaration : declaration.getTypeParameterDeclarations()) {
+ Type type = context.resolve(typeParameterDeclaration);
+ types.add(type);
+ if(!(type instanceof ConcreteType)) {
+ concrete = false;
+ }
+ }
+ if(concrete){
+ return new ConcreteType(declaration, (List) types, context);
+ }
+ return new PartialAppliedTypeInfo(declaration, types, context);
+ }
+
+ public static VariableType from(VariableDeclaration declaration, TypeContext context) {
+ Type type = declaration.getType();
+ Type returnType = context.resolve(type);
+ if (returnType instanceof ConcreteType) {
+ return new ConcreteVariableType(declaration, (ConcreteType) returnType, context);
+ }
+ return new VariableType(declaration, returnType);
+ }
+
+ public static FunctionType from(FunctionDeclaration declaration, TypeContext context){
+ Type type = declaration.getReturnType();
+ Type returnType = context.resolve(type);
+
+ List extends VariableType> parameter = declaration.getParameters().stream().map(p -> from(p, context)).collect(Collectors.toList());
+ List extends VariableType> closureVariables = declaration.getClosureVariables().stream().map(d -> from(d, context)).collect(Collectors.toList());
+ PartialAppliedTypeInfo wrapperClass;
+ VariableType wrapperObject;
+ PartialAppliedTypeInfo definingClass;
+ boolean isUnbound = declaration.getDeclarationType() == FunctionDeclaration.DeclarationType.UNBOUND;
+ if(isUnbound){
+ definingClass = null;
+ } else {
+ definingClass = from(declaration.getDefiningClass(), context);
+ }
+ if (declaration.getWrapperClass() != null) {
+ wrapperClass = from(declaration.getWrapperClass(), context);
+ wrapperObject = TypeFactory.from(declaration.getWrapperFunctionObjectDeclaration(), context);
+ } else {
+ wrapperClass = null;
+ wrapperObject = null;
+ }
+
+ if((!declaration.isReturnTypeToBeInferred() || declaration.getReturnType()!=null) && returnType instanceof ConcreteType && parameter.stream().allMatch(t -> t instanceof ConcreteVariableType) && (isUnbound || definingClass instanceof ConcreteType)) {
+ if(declaration instanceof GeneratorFunctionDeclaration){
+ return new ConcreteGeneratorFunctionType((GeneratorFunctionDeclaration) declaration, context, (List) parameter, (ConcreteType)returnType,(ConcreteType) definingClass, (ConcreteType) wrapperClass, (ConcreteVariableType) wrapperObject, (List) closureVariables);
+ }
+ return new ConcreteFunctionTypeDecl(declaration, context, (List) parameter, (ConcreteType)returnType, (ConcreteType) definingClass, (ConcreteType) wrapperClass, (ConcreteVariableType) wrapperObject, (List) closureVariables);
+ }
+ if(declaration instanceof GeneratorFunctionDeclaration){
+ return new GeneratorFunctionTypeImpl((GeneratorFunctionDeclaration) declaration, context, parameter, returnType, definingClass, wrapperClass, wrapperObject, closureVariables);
+ }
+ return new FunctionTypeDecl(declaration, context, parameter, returnType, definingClass, wrapperClass, wrapperObject, closureVariables);
+ }
+
+ public static ConcreteType makeConcrete(ClassDeclaration declaration, TypeContext context) {
+ return (ConcreteType) from(declaration, context);
+ }
+
+ public static ConcreteFunctionType makeConcrete(FunctionDeclaration declaration, TypeContext context) {
+ FunctionType from = from(declaration, context);
+ return (ConcreteFunctionType) from;
+ }
+
+ public static ConcreteFunctionType makeConcrete(FunctionType declaration, TypeContext context) {
+ FunctionType extend = declaration.extend(context);
+ return (ConcreteFunctionType) extend;
+ }
+
+ public static ConcreteVariableType makeConcrete(VariableDeclaration declaration, TypeContext context) {
+ return (ConcreteVariableType) from(declaration, context);
+ }
+
+ public static FunctionType createFunction(VariableDeclaration declaration) {
+ return new FunctionTypeVariable(declaration);
+ }
+}
diff --git a/src/main/java/de/uni/bremen/monty/moco/ast/types/TypeVariable.java b/src/main/java/de/uni/bremen/monty/moco/ast/types/TypeVariable.java
new file mode 100644
index 0000000..2833621
--- /dev/null
+++ b/src/main/java/de/uni/bremen/monty/moco/ast/types/TypeVariable.java
@@ -0,0 +1,135 @@
+/*
+ * moco, the Monty Compiler
+ * Copyright (c) 2013-2014, Monty's Coconut, All rights reserved.
+ *
+ * This file is part of moco, the Monty Compiler.
+ *
+ * moco is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 3.0 of the License, or (at your option) any later version.
+ *
+ * moco is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * Linking this program and/or its accompanying libraries statically or
+ * dynamically with other modules is making a combined work based on this
+ * program. Thus, the terms and conditions of the GNU General Public License
+ * cover the whole combination.
+ *
+ * As a special exception, the copyright holders of moco give
+ * you permission to link this programm and/or its accompanying libraries
+ * with independent modules to produce an executable, regardless of the
+ * license terms of these independent modules, and to copy and distribute the
+ * resulting executable under terms of your choice, provided that you also meet,
+ * for each linked independent module, the terms and conditions of the
+ * license of that module.
+ *
+ * An independent module is a module which is not
+ * derived from or based on this program and/or its accompanying libraries.
+ * If you modify this library, you may extend this exception to your version of
+ * the program or library, but you are not obliged to do so. If you do not wish
+ * to do so, delete this exception statement from your version.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this library.
+ */
+package de.uni.bremen.monty.moco.ast.types;
+
+import de.uni.bremen.monty.moco.ast.Identifier;
+import de.uni.bremen.monty.moco.ast.ResolvableIdentifier;
+import de.uni.bremen.monty.moco.ast.Scope;
+import de.uni.bremen.monty.moco.ast.declaration.TypeParameterDeclaration;
+import de.uni.bremen.monty.moco.ast.declaration.ClassDeclaration;
+
+public class TypeVariable extends Type {
+
+ TypeParameterDeclaration declaration;
+
+ public TypeVariable(TypeParameterDeclaration declaration) {
+ this.declaration = declaration;
+ }
+
+ @Override
+ public boolean isAssignableFrom(Type other) {
+ if(other instanceof TypeVariable){
+ return this.declaration.equals(((TypeVariable) other).declaration);
+ }
+ return declaration.getUpperTypeBound().isAssignableFrom(other);
+ }
+
+ @Override
+ protected boolean matchesDeclaration(ClassDeclaration declaration) {
+ return false;
+ }
+
+ @Override
+ public boolean matchesTypeExactly(Type type) {
+ if (type instanceof TypeVariable) {
+ if (((TypeVariable) type).declaration.equals(declaration)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public Identifier getIdentifier() {
+ return declaration.getIdentifier();
+ }
+
+ @Override
+ public Scope getScope() {
+ return declaration.getUpperTypeBound().getScope();
+ }
+
+ public Type extend(TypeContext context) {
+ return context.resolve(this);
+ }
+
+ @Override
+ public boolean isTuple(int n) {
+ return false;
+ }
+
+ @Override
+ public boolean isTuple() {
+ return false;
+ }
+
+ @Override
+ public boolean isFunction() {
+ return false;
+ }
+
+ public Type getUpperTypeBound() {
+ return declaration.getUpperTypeBound();
+ }
+
+ @Override
+ public int getTypeDist(Type other) {
+ if(other instanceof TypeVariable){
+ if(this.declaration == ((TypeVariable) other).declaration){
+ return 0;
+ }
+ return Integer.MAX_VALUE;
+ }
+ throw new RuntimeException();
+ }
+
+ @Override
+ protected int getTypeDist(Type other, int dist) {
+ throw new RuntimeException();
+ }
+
+ @Override
+ public String toString() {
+ return declaration.getIdentifier().getSymbol();
+ }
+
+ public ResolvableIdentifier getResolvableIdentifier() {
+ return new ResolvableIdentifier(declaration.getIdentifier().getSymbol());
+ }
+}
diff --git a/src/main/java/de/uni/bremen/monty/moco/ast/types/Types.java b/src/main/java/de/uni/bremen/monty/moco/ast/types/Types.java
new file mode 100644
index 0000000..e0cd5b6
--- /dev/null
+++ b/src/main/java/de/uni/bremen/monty/moco/ast/types/Types.java
@@ -0,0 +1,89 @@
+/*
+ * moco, the Monty Compiler
+ * Copyright (c) 2013-2014, Monty's Coconut, All rights reserved.
+ *
+ * This file is part of moco, the Monty Compiler.
+ *
+ * moco is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 3.0 of the License, or (at your option) any later version.
+ *
+ * moco is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * Linking this program and/or its accompanying libraries statically or
+ * dynamically with other modules is making a combined work based on this
+ * program. Thus, the terms and conditions of the GNU General Public License
+ * cover the whole combination.
+ *
+ * As a special exception, the copyright holders of moco give
+ * you permission to link this programm and/or its accompanying libraries
+ * with independent modules to produce an executable, regardless of the
+ * license terms of these independent modules, and to copy and distribute the
+ * resulting executable under terms of your choice, provided that you also meet,
+ * for each linked independent module, the terms and conditions of the
+ * license of that module.
+ *
+ * An independent module is a module which is not
+ * derived from or based on this program and/or its accompanying libraries.
+ * If you modify this library, you may extend this exception to your version of
+ * the program or library, but you are not obliged to do so. If you do not wish
+ * to do so, delete this exception statement from your version.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this library.
+ */
+package de.uni.bremen.monty.moco.ast.types;
+
+import de.uni.bremen.monty.moco.ast.CoreClasses;
+import de.uni.bremen.monty.moco.ast.declaration.ClassDeclaration;
+
+import java.util.Collections;
+
+public class Types {
+
+ public static PartialAppliedTypeInfo functionType() {
+ return TypeFactory.from(CoreClasses.functionType(), TypeContext.EMPTY);
+ };
+
+ public static ConcreteType create(ClassDeclaration declaration) {
+ return new ConcreteType(declaration, Collections.emptyList(), TypeContext.EMPTY);
+ }
+
+ public static ConcreteType intType() {
+ ClassDeclaration declaration = CoreClasses.intType();
+ return create(declaration);
+ }
+
+ public static ConcreteType boolType() {
+ return create(CoreClasses.boolType());
+ }
+
+ public static ConcreteType floatType() {
+ return create(CoreClasses.floatType());
+ }
+
+ public static ConcreteType charType() {
+ return create(CoreClasses.charType());
+ }
+
+ public static ConcreteType stringType() {
+ return create(CoreClasses.stringType());
+ }
+
+ public static ConcreteType arrayType() {
+ return create(CoreClasses.arrayType());
+ }
+
+ public static ConcreteType objectType() {
+ return create(CoreClasses.objectType());
+ }
+
+ public static ConcreteType voidType() {
+ return create(CoreClasses.voidType());
+ }
+
+}
diff --git a/src/main/java/de/uni/bremen/monty/moco/ast/types/VariableType.java b/src/main/java/de/uni/bremen/monty/moco/ast/types/VariableType.java
new file mode 100644
index 0000000..dbcfb1f
--- /dev/null
+++ b/src/main/java/de/uni/bremen/monty/moco/ast/types/VariableType.java
@@ -0,0 +1,75 @@
+/*
+ * moco, the Monty Compiler
+ * Copyright (c) 2013-2014, Monty's Coconut, All rights reserved.
+ *
+ * This file is part of moco, the Monty Compiler.
+ *
+ * moco is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 3.0 of the License, or (at your option) any later version.
+ *
+ * moco is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * Linking this program and/or its accompanying libraries statically or
+ * dynamically with other modules is making a combined work based on this
+ * program. Thus, the terms and conditions of the GNU General Public License
+ * cover the whole combination.
+ *
+ * As a special exception, the copyright holders of moco give
+ * you permission to link this programm and/or its accompanying libraries
+ * with independent modules to produce an executable, regardless of the
+ * license terms of these independent modules, and to copy and distribute the
+ * resulting executable under terms of your choice, provided that you also meet,
+ * for each linked independent module, the terms and conditions of the
+ * license of that module.
+ *
+ * An independent module is a module which is not
+ * derived from or based on this program and/or its accompanying libraries.
+ * If you modify this library, you may extend this exception to your version of
+ * the program or library, but you are not obliged to do so. If you do not wish
+ * to do so, delete this exception statement from your version.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this library.
+ */
+package de.uni.bremen.monty.moco.ast.types;
+
+import de.uni.bremen.monty.moco.ast.ASTNode;
+import de.uni.bremen.monty.moco.ast.Identifier;
+import de.uni.bremen.monty.moco.ast.ResolvableIdentifier;
+import de.uni.bremen.monty.moco.ast.declaration.VariableDeclaration;
+
+public class VariableType implements MemberType {
+ protected final VariableDeclaration declaration;
+ private final Type returnType;
+
+ VariableType(VariableDeclaration declaration, Type returnType) {
+ this.declaration = declaration;
+ this.returnType = returnType;
+ }
+
+ public Identifier getIdentifier() {
+ return declaration.getIdentifier();
+ }
+
+ public Type getType() {
+ return returnType;
+ }
+
+ @Override
+ public ASTNode getASTNode() {
+ return declaration;
+ }
+
+ public void setAttributeIndex(int attributeIndex) {
+ this.declaration.setAttributeIndex(attributeIndex);
+ }
+
+ public ResolvableIdentifier getTypeIdentifier() {
+ return declaration.getTypeIdentifier();
+ }
+}
diff --git a/src/main/java/de/uni/bremen/monty/moco/codegeneration/CodeGenerator.java b/src/main/java/de/uni/bremen/monty/moco/codegeneration/CodeGenerator.java
index a381f65..3336929 100644
--- a/src/main/java/de/uni/bremen/monty/moco/codegeneration/CodeGenerator.java
+++ b/src/main/java/de/uni/bremen/monty/moco/codegeneration/CodeGenerator.java
@@ -39,10 +39,10 @@
package de.uni.bremen.monty.moco.codegeneration;
import de.uni.bremen.monty.moco.ast.ASTNode;
-import de.uni.bremen.monty.moco.ast.CoreClasses;
import de.uni.bremen.monty.moco.ast.declaration.*;
import de.uni.bremen.monty.moco.ast.expression.VariableAccess;
import de.uni.bremen.monty.moco.ast.expression.literal.StringLiteral;
+import de.uni.bremen.monty.moco.ast.types.*;
import de.uni.bremen.monty.moco.codegeneration.context.CodeContext;
import de.uni.bremen.monty.moco.codegeneration.context.CodeContext.LLVMFunctionAttribute;
import de.uni.bremen.monty.moco.codegeneration.context.CodeContext.Linkage;
@@ -53,7 +53,6 @@
import de.uni.bremen.monty.moco.codegeneration.types.*;
import de.uni.bremen.monty.moco.codegeneration.voodoo.BlackMagic;
-import java.lang.reflect.Type;
import java.util.*;
import static de.uni.bremen.monty.moco.codegeneration.types.LLVMTypeFactory.*;
@@ -126,7 +125,7 @@ public LLVMIdentifier resolveIfNeeded(CodeContext c, LLV
}
private List> resolveArgumentsIfNeeded(CodeContext c,
- List> arguments, List parameters) {
+ List> arguments, List parameters) {
List> resolvedArguments = new ArrayList<>(arguments.size());
for (int i = 0; i < arguments.size(); i++) {
LLVMIdentifier resolvedArgument = resolveIfNeeded(c, (LLVMIdentifier) arguments.get(i));
@@ -140,18 +139,18 @@ private List> unboxArgumentsIfNeeded(CodeCont
List> arguments) {
List> unboxedArguments = new ArrayList<>(arguments.size());
for (LLVMIdentifier> llvmIdentifier : arguments) {
- if (llvmIdentifier.getType().equals(mapToLLVMType(CoreClasses.intType()))) {
+ if (llvmIdentifier.getType().equals(mapToLLVMType(Types.intType()))) {
unboxedArguments.add(unboxType(c, (LLVMIdentifier) llvmIdentifier, int64()));
- } else if (llvmIdentifier.getType().equals(mapToLLVMType(CoreClasses.boolType()))) {
+ } else if (llvmIdentifier.getType().equals(mapToLLVMType(Types.boolType()))) {
unboxedArguments.add(unboxType(c, (LLVMIdentifier) llvmIdentifier, int1()));
- } else if (llvmIdentifier.getType().equals(mapToLLVMType(CoreClasses.floatType()))) {
+ } else if (llvmIdentifier.getType().equals(mapToLLVMType(Types.floatType()))) {
unboxedArguments.add(unboxType(c, (LLVMIdentifier) llvmIdentifier, double64()));
- } else if (llvmIdentifier.getType().equals(mapToLLVMType(CoreClasses.charType()))) {
+ } else if (llvmIdentifier.getType().equals(mapToLLVMType(Types.charType()))) {
unboxedArguments.add(unboxType(c, (LLVMIdentifier) llvmIdentifier, int8()));
- } else if (llvmIdentifier.getType().equals(mapToLLVMType(CoreClasses.stringType()))) {
+ } else if (llvmIdentifier.getType().equals(mapToLLVMType(Types.stringType()))) {
unboxedArguments.add(unboxType(c, (LLVMIdentifier) llvmIdentifier, pointer(int8())));
- } else if (llvmIdentifier.getType().equals(mapToLLVMType(CoreClasses.arrayType()))) {
- LLVMType llvmType = mapToLLVMType((TypeDeclaration) CoreClasses.objectType());
+ } else if (llvmIdentifier.getType().equals(mapToLLVMType(Types.arrayType()))) {
+ LLVMType llvmType = mapToLLVMType(Types.objectType());
LLVMType array = pointer(struct(Arrays.asList(int64(), array(llvmType, 0))));
unboxedArguments.add(unboxType(c, (LLVMIdentifier) llvmIdentifier, array));
} else {
@@ -173,7 +172,7 @@ private LLVMIdentifier> addStringToDataField(CodeContext
}
private LLVMIdentifier> getVMTPointer(CodeContext c,
- LLVMIdentifier> selfReference, ClassDeclaration classDeclaration) {
+ LLVMIdentifier> selfReference, ConcreteType classDeclaration) {
String s = nameMangler.mangleClass(classDeclaration);
LLVMPointer vmtType = pointer((LLVMType) struct(s + "_vmt_type"));
LLVMIdentifier> vmtPointer = llvmIdentifierFactory.newLocal(vmtType, true);
@@ -186,15 +185,15 @@ private LLVMIdentifier> getVMTPointer(CodeContext c,
}
private LLVMIdentifier> getFunctionPointer(CodeContext c,
- LLVMIdentifier> selfReference, FunctionDeclaration declaration) {
+ LLVMIdentifier> selfReference, ConcreteFunctionType declaration) {
LLVMIdentifier> vmtPointer =
getVMTPointer(
c,
selfReference,
- (ClassDeclaration) mapAbstractGenericToConcreteIfApplicable(declaration.getDefiningClass()));
+ declaration.getDefiningClass());
- LLVMPointer functionType = mapToLLVMType(declaration);
- LLVMIdentifier> functionPointer = llvmIdentifierFactory.newLocal(functionType);
+ LLVMPointer ConcreteFunctionType = mapToLLVMType(declaration);
+ LLVMIdentifier> functionPointer = llvmIdentifierFactory.newLocal(ConcreteFunctionType);
c.getelementptr(
functionPointer,
resolveIfNeeded(c, vmtPointer),
@@ -203,7 +202,7 @@ private LLVMIdentifier> getFunctionPointer(CodeCon
return functionPointer;
}
- public void buildConstructor(CodeContext c, ClassDeclaration classDeclaration) {
+ public void buildConstructor(CodeContext c, ConcreteType classDeclaration) {
List> llvmParameter = new ArrayList<>();
String mangledClass = nameMangler.mangleClass(classDeclaration);
String constructorName = mangledClass + "_constructor";
@@ -222,7 +221,7 @@ public void buildConstructor(CodeContext c, ClassDeclaration classDeclaration) {
returnValue(c, (LLVMIdentifier) selfReference, classDeclaration);
}
- public LLVMIdentifier callConstructor(CodeContext c, ClassDeclaration classDeclaration) {
+ public LLVMIdentifier callConstructor(CodeContext c, ConcreteType classDeclaration) {
LLVMIdentifier result = llvmIdentifierFactory.newLocal(mapToLLVMType(classDeclaration), false);
LLVMIdentifier signature =
llvmIdentifierFactory.newGlobal(
@@ -251,14 +250,14 @@ public String getLabelPrefix(ASTNode node) {
return node2label.get(node);
}
- public LLVMIdentifier declareGlobalVariable(CodeContext c, String name, TypeDeclaration type) {
+ public LLVMIdentifier declareGlobalVariable(CodeContext c, String name, ConcreteType type) {
LLVMType llvmType = mapToLLVMType(type);
LLVMIdentifier variable = llvmIdentifierFactory.newGlobal(name, llvmType);
c.global(Linkage.priv, variable, false);
return variable;
}
- public LLVMIdentifier declareLocalVariable(CodeContext c, String name, TypeDeclaration type) {
+ public LLVMIdentifier declareLocalVariable(CodeContext c, String name, ConcreteType type) {
LLVMType llvmType = mapToLLVMType(type);
LLVMIdentifier variable = llvmIdentifierFactory.newLocal(name, llvmType, true);
@@ -266,13 +265,13 @@ public LLVMIdentifier declareLocalVariable(CodeContext c, String name,
return variable;
}
- public LLVMIdentifier resolveLocalVarName(String name, TypeDeclaration type,
+ public LLVMIdentifier resolveLocalVarName(String name, ConcreteType type,
boolean resolvable) {
T llvmType = mapToLLVMType(type);
return llvmIdentifierFactory.newLocal(name, llvmType, resolvable);
}
- public LLVMIdentifier resolveGlobalVarName(String name, TypeDeclaration type) {
+ public LLVMIdentifier resolveGlobalVarName(String name, ConcreteType type) {
T llvmType = mapToLLVMType(type);
return llvmIdentifierFactory.newGlobal(name, llvmType);
}
@@ -289,7 +288,7 @@ public void addMain(CodeContext active) {
active.label("entry");
}
- public void addFunction(CodeContext c, TypeDeclaration returnType,
+ public void addFunction(CodeContext c, ConcreteType returnType,
List> llvmParameter, String name) {
LLVMType llvmReturnType = mapToLLVMType(returnType);
c.define(
@@ -298,7 +297,7 @@ public void addFunction(CodeContext c, TypeDeclaration returnType,
c.label("entry");
}
- public void addNativeFunction(CodeContext c, TypeDeclaration returnType,
+ public void addNativeFunction(CodeContext c, ConcreteType returnType,
List> llvmParameter, String name) {
addFunction(c, returnType, llvmParameter, name);
@@ -316,7 +315,7 @@ public void addNativeFunction(CodeContext c, TypeDeclaration returnType,
returnValue(
c,
(LLVMIdentifier) (LLVMIdentifier>) llvmIdentifierFactory.voidId(),
- CoreClasses.voidType());
+ Types.voidType());
}
}
@@ -324,7 +323,7 @@ public void returnMain(CodeContext c) {
c.ret(llvmIdentifierFactory.constant(int32(), 0));
}
- public void returnValue(CodeContext c, LLVMIdentifier returnValue, TypeDeclaration expectedType) {
+ public void returnValue(CodeContext c, LLVMIdentifier returnValue, ConcreteType expectedType) {
LLVMIdentifier resolved = resolveIfNeeded(c, returnValue);
LLVMIdentifier casted = castIfNeeded(c, resolved, mapToLLVMType(expectedType));
c.ret(casted);
@@ -387,7 +386,7 @@ public LLVMIdentifier accessMember(CodeContext c, LLVMIdentifier accessMember(CodeContext c, LLVMIdentifier> pointer,
- int attributeOffset, TypeDeclaration type, boolean load) {
+ int attributeOffset, ConcreteType type, boolean load) {
LLVMIdentifier result = llvmIdentifierFactory.newLocal(mapToLLVMType(type), load);
c.getelementptr(
@@ -398,8 +397,8 @@ public LLVMIdentifier accessMember(CodeContext c, LLVMIdentifier accessClosureContextMember(CodeContext c, ClassDeclaration closureClass,
- VariableDeclaration varDecl, VariableAccess varAccess, TypeDeclaration variableType,
+ public LLVMIdentifier accessClosureContextMember(CodeContext c, ConcreteType closureClass,
+ VariableDeclaration varDecl, VariableAccess varAccess, ConcreteType variableType,
LLVMIdentifier> context) {
LLVMType contextType = LLVMTypeFactory.struct(nameMangler.mangleClass(closureClass) + "_closure_context");
@@ -415,15 +414,15 @@ public LLVMIdentifier accessClosureContextMember(CodeContext c, ClassD
return result;
}
- public LLVMIdentifier accessClosureContextMember(CodeContext c, ClassDeclaration closureClass,
- VariableDeclaration varDecl, VariableAccess varAccess, TypeDeclaration variableType) {
+ public LLVMIdentifier accessClosureContextMember(CodeContext c, ConcreteType closureClass,
+ VariableDeclaration varDecl, VariableAccess varAccess, ConcreteType variableType) {
LLVMIdentifier> self = resolveLocalVarName("..ctx..", closureClass, false);
return accessClosureContextMember(c, closureClass, varDecl, varAccess, variableType, self);
}
- public LLVMIdentifier accessContextMember(CodeContext c, ClassDeclaration generatorClass,
- VariableDeclaration varDecl, VariableAccess varAccess, TypeDeclaration variableType) {
+ public LLVMIdentifier accessContextMember(CodeContext c, ConcreteType generatorClass,
+ VariableDeclaration varDecl, VariableAccess varAccess, ConcreteType variableType) {
LLVMType contextType = LLVMTypeFactory.struct(nameMangler.mangleClass(generatorClass) + "_context");
@@ -446,8 +445,8 @@ public LLVMIdentifier accessContextMember(CodeContext c, ClassDeclarat
}
public LLVMIdentifier accessGeneratorJumpPointer(CodeContext c,
- LLVMIdentifier> pointer, ClassDeclaration generatorClass, int attributeOffset,
- boolean load) {
+ LLVMIdentifier> pointer, ConcreteType generatorClass, int attributeOffset,
+ boolean load) {
LLVMType contextType = LLVMTypeFactory.struct(nameMangler.mangleClass(generatorClass) + "_context");
LLVMType jumpPrtType = LLVMTypeFactory.pointer(LLVMTypeFactory.int8());
@@ -464,13 +463,22 @@ public LLVMIdentifier accessGeneratorJumpPointer(CodeContext c,
return pointervar;
}
- public T mapToLLVMType(TypeDeclaration type) {
+ public T mapToLLVMType(ConcreteVariableType type) {
+ return typeConverter.mapToLLVMType(type.getType());
+ }
+
+
+ public LLVMPointer mapToLLVMType(ConcreteFunctionType type) {
+ return typeConverter.mapToLLVMType(type);
+ }
+
+ public T mapToLLVMType(ConcreteType type) {
return typeConverter.mapToLLVMType(type);
}
public LLVMIdentifier> castClass(CodeContext c,
- LLVMIdentifier