diff --git a/java-type-checker/.idea/inspectionProfiles/Project_Default.xml b/java-type-checker/.idea/inspectionProfiles/Project_Default.xml
index b169286..8813ec9 100644
--- a/java-type-checker/.idea/inspectionProfiles/Project_Default.xml
+++ b/java-type-checker/.idea/inspectionProfiles/Project_Default.xml
@@ -7,6 +7,15 @@
+
+
+
+
+
+
+
diff --git a/java-type-checker/.idea/misc.xml b/java-type-checker/.idea/misc.xml
index c24fcb0..5371031 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..0acd853 100644
--- a/java-type-checker/.idea/type-checker.iml
+++ b/java-type-checker/.idea/type-checker.iml
@@ -2,7 +2,7 @@
-
+
diff --git a/java-type-checker/java_type_checker/expressions.py b/java-type-checker/java_type_checker/expressions.py
index 27ed57e..b972dd7 100644
--- a/java-type-checker/java_type_checker/expressions.py
+++ b/java-type-checker/java_type_checker/expressions.py
@@ -31,6 +31,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,10 +45,24 @@ 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)
+ self.declared_type = Type.null
+
+ def static_type(self):
+ return Type.null
+
+ # def check_types(self):
+ # raise NoSuchMethod()
+
class MethodCall(Expression):
@@ -55,6 +75,31 @@ 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.declared_type.method_named(self.method_name).return_type
+
+ def check_types(self):
+ if self.receiver.declared_type == Type.null:
+ self.receiver.declared_type.check_for_null_method(self.method_name)
+
+ if not self.receiver.declared_type.is_subtype_of(Type.object):
+ raise JavaTypeError("Type {0} does not have methods".format(self.receiver.declared_type.name))
+
+ method = self.receiver.declared_type.method_named(self.method_name)
+ if len(method.argument_types) != len(self.args):
+ raise JavaTypeError("Wrong number of arguments for {3}.{0}(): expected {1}, got {2}".format(self.method_name,
+ len(method.argument_types),
+ len(self.args),
+ self.receiver.declared_type.name))
+ for i in range(len(method.argument_types)):
+ if not self.args[i].static_type().is_subtype_of(method.argument_types[i]):
+ raise JavaTypeError("{3}.{0}() expects arguments of type {1}, but got {2}".format(self.method_name,
+ names(method.argument_types),
+ typeNames(self.args),
+ self.receiver.declared_type.name))
+ # if self.args[i].type == Type.null and method
+ self.args[i].check_types() # THIS IS AMAZING <-----------
+
class ConstructorCall(Expression):
"""
@@ -64,6 +109,33 @@ 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):
+ if self.instantiated_type == Type.null:
+ raise JavaTypeError("Type null is not instantiable")
+
+ if not self.static_type().is_subtype_of(Type.object):
+ raise JavaTypeError("Type "+self.instantiated_type.name+" is not instantiable")
+
+ if len(self.args) != len(self.instantiated_type.constructor.argument_types):
+ raise JavaTypeError("Wrong number of arguments for {0} constructor: expected {1}, got {2}".format(self.instantiated_type.name, len(self.instantiated_type.constructor.argument_types), len(self.args)))
+
+ constructorString = self.instantiated_type.name
+ reqArgs = names(self.instantiated_type.constructor.argument_types)
+ givenArgs = typeNames(self.args)
+
+ for i in range(len(self.args)):
+ self.args[i].check_types()
+
+ for i in range(len(self.args)):
+ if not self.args[i].static_type().is_subtype_of(self.instantiated_type.constructor.argument_types[i]):
+ raise JavaTypeError("{0} constructor expects arguments of type {1}, but got {2}".format(constructorString,
+ reqArgs,
+ givenArgs))
+
+
class JavaTypeError(Exception):
""" Indicates a compile-time type error in an expression.
@@ -74,4 +146,13 @@ class JavaTypeError(Exception):
def names(named_things):
""" Helper for formatting pretty error messages
"""
+ # str = "("
+
return "(" + ", ".join([e.name for e in named_things]) + ")"
+
+
+def typeNames(items):
+ """ Helper for formatting pretty error messages for type names
+ """
+ return "(" + ", ".join([e.static_type().name for e in items]) + ")"
+
diff --git a/java-type-checker/java_type_checker/types.py b/java-type-checker/java_type_checker/types.py
index 465f7f4..9840fac 100644
--- a/java-type-checker/java_type_checker/types.py
+++ b/java-type-checker/java_type_checker/types.py
@@ -12,7 +12,15 @@ 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 self.name == other.name:
+ return True
+ elif len(self.direct_supertypes) == 0:
+ return False
+ else:
+ for supertype in self.direct_supertypes:
+ if supertype.is_subtype_of(other):
+ return True
+ return False
def is_supertype_of(self, other):
""" Convenience counterpart to is_subtype_of().
@@ -72,6 +80,14 @@ class NullType(Type):
def __init__(self):
super().__init__("null")
+ def is_subtype_of(self, other):
+ if not other.is_subtype_of(Type.object):
+ return False
+ return True
+
+ def check_for_null_method(self, method_name):
+ raise NoSuchMethod("Cannot invoke method {0}() on null".format(method_name))
+
class NoSuchMethod(Exception):
pass
diff --git a/python-attr-lookup/.idea/misc.xml b/python-attr-lookup/.idea/misc.xml
index 0548357..57d62b3 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..6543de3 100644
--- a/python-attr-lookup/python-attr-lookup.iml
+++ b/python-attr-lookup/python-attr-lookup.iml
@@ -20,5 +20,15 @@
+
+
+
+
+
+
+
+
+
+
\ 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..8b0369b 100644
--- a/python-attr-lookup/src/plang/PythonObject.java
+++ b/python-attr-lookup/src/plang/PythonObject.java
@@ -51,7 +51,15 @@ 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 result = new ArrayList<>();
+
+ result.add(this);
+ if(type != null) {
+ result.addAll(this.type.buildMRO());
+ }
+ return result;
+
}
/**
@@ -62,7 +70,14 @@ 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);
}
/**
@@ -74,7 +89,7 @@ public final PythonObject get(String attrName) throws PythonAttributeException {
* @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..2c503f8 100644
--- a/python-attr-lookup/src/plang/PythonType.java
+++ b/python-attr-lookup/src/plang/PythonType.java
@@ -41,7 +41,14 @@ public PythonObject getBase() {
@Override
protected List buildMRO() {
- throw new UnsupportedOperationException("not implemented yet");
+
+ List result = new ArrayList<>();
+ result.add(this);
+ if(this.base != null) {
+ result.addAll(this.base.buildMRO());
+ }
+ return result;
+
}
/**
@@ -49,7 +56,12 @@ protected List buildMRO() {
* this PythonType.
*/
public PythonObject instantiate() {
- throw new UnsupportedOperationException("not implemented yet");
+
+ if(name != null && !name.equals("")) {
+ return new PythonObject(this);
+ }
+
+ throw new UnsupportedOperationException("PyObject name cannot be null");
}
@Override