diff --git a/java-type-checker/.idea/misc.xml b/java-type-checker/.idea/misc.xml
index c24fcb0..651217f 100644
--- a/java-type-checker/.idea/misc.xml
+++ b/java-type-checker/.idea/misc.xml
@@ -12,5 +12,5 @@
-
+
\ No newline at end of file
diff --git a/java-type-checker/.idea/type-checker.iml b/java-type-checker/.idea/type-checker.iml
index 52e75c6..9eedabc 100644
--- a/java-type-checker/.idea/type-checker.iml
+++ b/java-type-checker/.idea/type-checker.iml
@@ -1,8 +1,10 @@
-
-
+
+
+
+
diff --git a/java-type-checker/java_type_checker/expressions.py b/java-type-checker/java_type_checker/expressions.py
index 27ed57e..fd7ba52 100644
--- a/java-type-checker/java_type_checker/expressions.py
+++ b/java-type-checker/java_type_checker/expressions.py
@@ -14,6 +14,7 @@ def static_type(self):
Returns the compile-time type of this expression, i.e. the most specific type that describes
all the possible values it could take on at runtime. Subclasses must implement this method.
"""
+
raise NotImplementedError(type(self).__name__ + " must implement static_type()")
def check_types(self):
@@ -31,6 +32,12 @@ def __init__(self, name, declared_type):
self.name = name #: The name of the variable
self.declared_type = declared_type #: The declared type of the variable (Type)
+ def static_type(self):
+ return self.declared_type
+
+ def check_types(self):
+ pass
+
class Literal(Expression):
""" A literal value entered in the code, e.g. `5` in the expression `x + 5`.
@@ -39,11 +46,22 @@ def __init__(self, value, type):
self.value = value #: The literal value, as a string
self.type = type #: The type of the literal (Type)
+ def static_type(self):
+ return self.type
+
+ def check_types(self):
+ pass
class NullLiteral(Literal):
def __init__(self):
super().__init__("null", Type.null)
+ def static_type(self):
+ return Type.null
+
+ def check_types(self):
+ pass
+
class MethodCall(Expression):
"""
@@ -55,6 +73,37 @@ def __init__(self, receiver, method_name, *args):
self.method_name = method_name #: The name of the method to call (String)
self.args = args #: The method arguments (list of Expressions)
+ def static_type(self):
+ return self.receiver.static_type().method_named(self.method_name).return_type
+
+
+ def check_types(self):
+
+ for arg in self.args:
+ arg.check_types()
+
+
+ correctTypes = self.receiver.static_type().method_named(self.method_name).argument_types
+ argTypes = []
+ for arg in self.args:
+ argTypes += [arg.static_type()]
+
+ if len(correctTypes) != len(argTypes):
+ raise JavaTypeError(
+ "Wrong number of arguments for {0}: expected {1}, got {2}".format(
+ "{}.{}()".format(self.receiver.static_type().name, self.method_name),
+ len(correctTypes),
+ len(argTypes)))
+
+ for i in range(len(correctTypes)):
+ if not argTypes[i].is_subtype_of(correctTypes[i]):
+ raise JavaTypeError(
+ "{0} expects arguments of type {1}, but got {2}".format(
+ "{}.{}()".format(self.receiver.static_type().name, self.method_name),
+ names(correctTypes),
+ names(argTypes)))
+
+
class ConstructorCall(Expression):
"""
@@ -64,6 +113,38 @@ def __init__(self, instantiated_type, *args):
self.instantiated_type = instantiated_type #: The type to instantiate (Type)
self.args = args #: Constructor arguments (list of Expressions)
+ def static_type(self):
+ return self.instantiated_type
+
+ def check_types(self):
+
+
+ for arg in self.args:
+ arg.check_types()
+
+ correctTypes = self.instantiated_type.constructor.argument_types
+ argTypes = []
+ for arg in self.args:
+ argTypes += [arg.static_type()]
+
+
+ if len(correctTypes) != len(argTypes):
+ raise JavaTypeError(
+ "Wrong number of arguments for {0}: expected {1}, got {2}".format(
+ self.instantiated_type.name + " constructor",
+ len(correctTypes),
+ len(argTypes)))
+
+ for i in range(len(correctTypes)):
+ if not argTypes[i].is_subtype_of(correctTypes[i]):
+ raise JavaTypeError(
+ "{0} expects arguments of type {1}, but got {2}".format(
+ self.instantiated_type.name + " constructor",
+ names(correctTypes),
+ names(argTypes)))
+
+
+
class JavaTypeError(Exception):
""" Indicates a compile-time type error in an expression.
diff --git a/java-type-checker/java_type_checker/types.py b/java-type-checker/java_type_checker/types.py
index 465f7f4..e80d735 100644
--- a/java-type-checker/java_type_checker/types.py
+++ b/java-type-checker/java_type_checker/types.py
@@ -12,7 +12,13 @@ def __init__(self, name, direct_supertypes=[]):
def is_subtype_of(self, other):
""" True if this type can be used where the other type is expected.
"""
- return True # TODO: implement
+ if other == self:
+ return True
+ for type in self.direct_supertypes:
+ if type.is_subtype_of(other):
+ return True
+ return False
+
def is_supertype_of(self, other):
""" Convenience counterpart to is_subtype_of().
diff --git a/python-attr-lookup/.idea/misc.xml b/python-attr-lookup/.idea/misc.xml
index 0548357..8e8843c 100644
--- a/python-attr-lookup/.idea/misc.xml
+++ b/python-attr-lookup/.idea/misc.xml
@@ -1,6 +1,6 @@
-
+
\ No newline at end of file
diff --git a/python-attr-lookup/python-attr-lookup.iml b/python-attr-lookup/python-attr-lookup.iml
index 01e8e1b..a2b4cff 100644
--- a/python-attr-lookup/python-attr-lookup.iml
+++ b/python-attr-lookup/python-attr-lookup.iml
@@ -20,5 +20,17 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/python-attr-lookup/src/plang/PythonObject.java b/python-attr-lookup/src/plang/PythonObject.java
index a8e311f..1e2f1ae 100644
--- a/python-attr-lookup/src/plang/PythonObject.java
+++ b/python-attr-lookup/src/plang/PythonObject.java
@@ -51,7 +51,17 @@ public List getMRO() {
* result (i.e. it remembers the list buildMRO() returned and keeps returning it).
*/
protected List buildMRO() {
- throw new UnsupportedOperationException("not implemented yet");
+
+ List mro = new ArrayList();
+
+ mro.add(this);
+
+ if (type != null){
+ List moreMRO = type.buildMRO();
+ mro.addAll(moreMRO);
+ }
+ return mro;
+
}
/**
@@ -62,7 +72,17 @@ protected List buildMRO() {
* @throws PythonAttributeException When there is no attribute on this object with that name.
*/
public final PythonObject get(String attrName) throws PythonAttributeException {
- throw new UnsupportedOperationException("not implemented yet");
+
+
+ for (PythonObject o : getMRO()){
+ if (o.attrs.containsKey(attrName)){
+ return o.attrs.get(attrName);
+ }
+ }
+
+ throw new PythonAttributeException(this, attrName);
+
+
}
/**
@@ -73,8 +93,9 @@ public final PythonObject get(String attrName) throws PythonAttributeException {
* @param attrName The name of the attribute to set
* @param value Its new value
*/
+
public final void set(String attrName, PythonObject value) {
- throw new UnsupportedOperationException("not implemented yet");
+ attrs.put(attrName, value);
}
@Override
diff --git a/python-attr-lookup/src/plang/PythonType.java b/python-attr-lookup/src/plang/PythonType.java
index 4e2be4a..aea53eb 100644
--- a/python-attr-lookup/src/plang/PythonType.java
+++ b/python-attr-lookup/src/plang/PythonType.java
@@ -41,7 +41,16 @@ public PythonObject getBase() {
@Override
protected List buildMRO() {
- throw new UnsupportedOperationException("not implemented yet");
+ List mro = new ArrayList();
+
+ mro.add(this);
+ PythonType tmp = this;
+ while (tmp.getBase() != null) {
+ mro.add(tmp.base);
+ tmp = (PythonType)tmp.base;
+ }
+ return mro;
+
}
/**
@@ -49,7 +58,9 @@ protected List buildMRO() {
* this PythonType.
*/
public PythonObject instantiate() {
- throw new UnsupportedOperationException("not implemented yet");
+ PythonObject newInstance = new PythonObject(this);
+
+ return newInstance;
}
@Override