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