From 55043d0c92e95c7ae70bfcc2d1dba18d266b323f Mon Sep 17 00:00:00 2001 From: kaylabeckm Date: Tue, 6 Feb 2018 15:17:43 -0600 Subject: [PATCH 1/5] Finished java part of the hw --- .idea/.name | 1 + .idea/compiler.xml | 22 +++++++++++++++++ .idea/copyright/profiles_settings.xml | 3 +++ .idea/encodings.xml | 6 +++++ .idea/misc.xml | 23 ++++++++++++++++++ java-type-checker/.idea/misc.xml | 2 +- java-type-checker/.idea/type-checker.iml | 2 +- python-attr-lookup/.idea/compiler.xml | 6 +++++ .../.idea/copyright/profiles_settings.xml | 3 +++ python-attr-lookup/.idea/misc.xml | 2 +- python-attr-lookup/python-attr-lookup.iml | 22 +++++++++++++++++ .../src/plang/PythonObject.java | 24 ++++++++++++------- python-attr-lookup/src/plang/PythonType.java | 10 ++++++-- 13 files changed, 113 insertions(+), 13 deletions(-) create mode 100644 .idea/.name create mode 100644 .idea/compiler.xml create mode 100644 .idea/copyright/profiles_settings.xml create mode 100644 .idea/encodings.xml create mode 100644 .idea/misc.xml create mode 100644 python-attr-lookup/.idea/copyright/profiles_settings.xml diff --git a/.idea/.name b/.idea/.name new file mode 100644 index 0000000..9e911f7 --- /dev/null +++ b/.idea/.name @@ -0,0 +1 @@ +comp394-type-modeling \ No newline at end of file diff --git a/.idea/compiler.xml b/.idea/compiler.xml new file mode 100644 index 0000000..96cc43e --- /dev/null +++ b/.idea/compiler.xml @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/copyright/profiles_settings.xml b/.idea/copyright/profiles_settings.xml new file mode 100644 index 0000000..e7bedf3 --- /dev/null +++ b/.idea/copyright/profiles_settings.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/.idea/encodings.xml b/.idea/encodings.xml new file mode 100644 index 0000000..97626ba --- /dev/null +++ b/.idea/encodings.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..757ea42 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/java-type-checker/.idea/misc.xml b/java-type-checker/.idea/misc.xml index c24fcb0..fc57a9d 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..4a747f3 100644 --- a/java-type-checker/.idea/type-checker.iml +++ b/java-type-checker/.idea/type-checker.iml @@ -2,7 +2,7 @@ - + diff --git a/python-attr-lookup/.idea/compiler.xml b/python-attr-lookup/.idea/compiler.xml index 40ed937..1f2af51 100644 --- a/python-attr-lookup/.idea/compiler.xml +++ b/python-attr-lookup/.idea/compiler.xml @@ -1,6 +1,7 @@ + @@ -11,5 +12,10 @@ + + + + + \ No newline at end of file diff --git a/python-attr-lookup/.idea/copyright/profiles_settings.xml b/python-attr-lookup/.idea/copyright/profiles_settings.xml new file mode 100644 index 0000000..e7bedf3 --- /dev/null +++ b/python-attr-lookup/.idea/copyright/profiles_settings.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/python-attr-lookup/.idea/misc.xml b/python-attr-lookup/.idea/misc.xml index 0548357..1e41899 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..e03a82f 100644 --- a/python-attr-lookup/python-attr-lookup.iml +++ b/python-attr-lookup/python-attr-lookup.iml @@ -20,5 +20,27 @@ + + + + + + + + + + + + + + + + + + + + + + \ 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..e140251 100644 --- a/python-attr-lookup/src/plang/PythonObject.java +++ b/python-attr-lookup/src/plang/PythonObject.java @@ -1,10 +1,6 @@ package plang; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; +import java.util.*; /** * The runtime state of an object in Python. @@ -51,7 +47,10 @@ 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"); + mro = new ArrayList<>(); + mro.add(this); + mro.addAll(type.getMRO()); + return mro; } /** @@ -62,7 +61,13 @@ 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 currObj:getMRO()){ + if(currObj.attrs.containsKey(attrName)){ + return currObj.attrs.get(attrName); + } + } + throw new PythonAttributeException(this,attrName); + //throw new UnsupportedOperationException("not implemented yet"); } /** @@ -74,7 +79,10 @@ 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); + + //throw new UnsupportedOperationException("not implemented yet"); } @Override diff --git a/python-attr-lookup/src/plang/PythonType.java b/python-attr-lookup/src/plang/PythonType.java index 4e2be4a..b891ab6 100644 --- a/python-attr-lookup/src/plang/PythonType.java +++ b/python-attr-lookup/src/plang/PythonType.java @@ -41,7 +41,12 @@ public PythonObject getBase() { @Override protected List buildMRO() { - throw new UnsupportedOperationException("not implemented yet"); + List mro = new ArrayList<>(); + mro.add(this); + if(getBase() != null) { + mro.addAll(getBase().getMRO()); + } + return mro; } /** @@ -49,7 +54,8 @@ protected List buildMRO() { * this PythonType. */ public PythonObject instantiate() { - throw new UnsupportedOperationException("not implemented yet"); + PythonObject newPythonObj = new PythonObject(this); + return newPythonObj; } @Override From d8a04041d3df605cdc3f3676f749195bed85eca5 Mon Sep 17 00:00:00 2001 From: kaylabeckm Date: Fri, 9 Feb 2018 19:13:48 -0600 Subject: [PATCH 2/5] almost done with 1.3 --- .../java_type_checker/expressions.py | 91 ++++++++++++++++++- java-type-checker/java_type_checker/types.py | 11 ++- 2 files changed, 100 insertions(+), 2 deletions(-) diff --git a/java-type-checker/java_type_checker/expressions.py b/java-type-checker/java_type_checker/expressions.py index 27ed57e..412cf33 100644 --- a/java-type-checker/java_type_checker/expressions.py +++ b/java-type-checker/java_type_checker/expressions.py @@ -21,6 +21,7 @@ def check_types(self): Validates the structure of this expression, checking for any logical inconsistencies in the child nodes and the operation this expression applies to them. """ + raise NotImplementedError(type(self).__name__ + " must implement check_types()") @@ -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,22 +46,69 @@ 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 + class MethodCall(Expression): """ A Java method invocation, i.e. `foo.bar(0, 1, 2)`. """ def __init__(self, receiver, method_name, *args): - self.receiver = receiver self.receiver = receiver #: The object whose method we are calling (Expression) 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): + objType = self.receiver.static_type() + method = objType.method_named(self.method_name) + return method.return_type + + def check_types(self): + primitives = [Type.int, Type.boolean, Type.double] + objType = self.receiver.static_type() + passedArgTypes = [] + if objType in primitives: #cant call methods on primitives + raise JavaTypeError("Type {0} does not have methods".format( + objType.name + )) + if objType.method_named(self.method_name): #if the object has the correct method + method = objType.method_named(self.method_name) + pass + else: + raise JavaTypeError("{0} has no method named {1}".format( + objType.name, + self.method_name + )) + if len(self.args) == len(method.argument_types): #if you passed enough arguments for the method + pass + else: + raise JavaTypeError("Wrong number of arguments for {0}: expected {1}, got {2}".format( + objType.name + "." + method.name+ "()", + len(method.argument_types), + len(self.args))) + for i in range(0,len(self.args)): # if you passed args of the correct type for the method + passedArgTypes += [self.args[i].static_type()] + if passedArgTypes[i] == method.argument_types[i]: + pass + elif method.argument_types[i] in passedArgTypes[i].direct_supertypes: + pass + else: + raise JavaTypeError("{0} expects arguments of type {1}, but got {2}".format( + objType.name + "." + method.name + "()", + names(method.argument_types), + names(passedArgTypes))) + class ConstructorCall(Expression): """ @@ -64,6 +118,41 @@ 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): + # can't instantiate primitives + primitives = [Type.int, Type.boolean, Type.double] + if self.instantiated_type in primitives: + raise JavaTypeError("Type {0} is not instantiable".format( + self.instantiated_type.name + )) + + passedArgTypes = [] #setup a list for the types of passed arguments + expectedArgTypes = self.instantiated_type.constructor.argument_types + # make sure you passed the expected number of arguments + if len(self.args) == len(expectedArgTypes): + pass + else: + raise JavaTypeError("Wrong number of arguments for {0}: expected {1}, got {2}".format( + self.instantiated_type.name + " constructor", + len(expectedArgTypes), + len(self.args))) + + # make sure you passed arguments with the expected types (or supertypes) + for i in range(0,len(self.args)): + passedArgTypes += [self.args[i].static_type()] + if passedArgTypes[i] == expectedArgTypes[i]: + pass + elif expectedArgTypes[i] in passedArgTypes[i].direct_supertypes: + pass + else: + raise JavaTypeError("{0} expects arguments of type {1}, but got {2}".format( + self.instantiated_type.name + " constructor", + names(expectedArgTypes), + names(passedArgTypes))) + 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..e4db2ed 100644 --- a/java-type-checker/java_type_checker/types.py +++ b/java-type-checker/java_type_checker/types.py @@ -12,7 +12,16 @@ 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 + for x in self.direct_supertypes: + for y in x.direct_supertypes: + if y.name == other.name: + return True + if x.name == other.name: + return True + + return False def is_supertype_of(self, other): """ Convenience counterpart to is_subtype_of(). From 0abd3b71a4aa922f75aee784ed0ae505b61db916 Mon Sep 17 00:00:00 2001 From: kaylabeckm Date: Fri, 9 Feb 2018 20:19:19 -0600 Subject: [PATCH 3/5] Finished 1.3!! --- .../java_type_checker/expressions.py | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/java-type-checker/java_type_checker/expressions.py b/java-type-checker/java_type_checker/expressions.py index 412cf33..80a9aba 100644 --- a/java-type-checker/java_type_checker/expressions.py +++ b/java-type-checker/java_type_checker/expressions.py @@ -78,6 +78,7 @@ def check_types(self): primitives = [Type.int, Type.boolean, Type.double] objType = self.receiver.static_type() passedArgTypes = [] + if objType in primitives: #cant call methods on primitives raise JavaTypeError("Type {0} does not have methods".format( objType.name @@ -90,6 +91,7 @@ def check_types(self): objType.name, self.method_name )) + if len(self.args) == len(method.argument_types): #if you passed enough arguments for the method pass else: @@ -97,12 +99,14 @@ def check_types(self): objType.name + "." + method.name+ "()", len(method.argument_types), len(self.args))) + + for e in self.args: + passedArgTypes.append(e.static_type()) for i in range(0,len(self.args)): # if you passed args of the correct type for the method - passedArgTypes += [self.args[i].static_type()] if passedArgTypes[i] == method.argument_types[i]: - pass + self.args[i].check_types() elif method.argument_types[i] in passedArgTypes[i].direct_supertypes: - pass + self.args[i].check_types() else: raise JavaTypeError("{0} expects arguments of type {1}, but got {2}".format( objType.name + "." + method.name + "()", @@ -141,12 +145,13 @@ def check_types(self): len(self.args))) # make sure you passed arguments with the expected types (or supertypes) + for e in self.args: + passedArgTypes.append(e.static_type()) for i in range(0,len(self.args)): - passedArgTypes += [self.args[i].static_type()] if passedArgTypes[i] == expectedArgTypes[i]: - pass + self.args[i].check_types() elif expectedArgTypes[i] in passedArgTypes[i].direct_supertypes: - pass + self.args[i].check_types() else: raise JavaTypeError("{0} expects arguments of type {1}, but got {2}".format( self.instantiated_type.name + " constructor", From ba4006f1cc88b38e323ac638cc83890f55f993db Mon Sep 17 00:00:00 2001 From: kaylabeckm Date: Fri, 9 Feb 2018 21:16:43 -0600 Subject: [PATCH 4/5] Only one test left for null stuff --- java-type-checker/java_type_checker/expressions.py | 8 +++++++- java-type-checker/java_type_checker/types.py | 7 +++++++ java-type-checker/tests/test_null.py | 2 +- 3 files changed, 15 insertions(+), 2 deletions(-) diff --git a/java-type-checker/java_type_checker/expressions.py b/java-type-checker/java_type_checker/expressions.py index 80a9aba..e9f9df9 100644 --- a/java-type-checker/java_type_checker/expressions.py +++ b/java-type-checker/java_type_checker/expressions.py @@ -60,6 +60,7 @@ def static_type(self): return Type.null + class MethodCall(Expression): """ A Java method invocation, i.e. `foo.bar(0, 1, 2)`. @@ -83,6 +84,7 @@ def check_types(self): raise JavaTypeError("Type {0} does not have methods".format( objType.name )) + if objType.method_named(self.method_name): #if the object has the correct method method = objType.method_named(self.method_name) pass @@ -105,7 +107,7 @@ def check_types(self): for i in range(0,len(self.args)): # if you passed args of the correct type for the method if passedArgTypes[i] == method.argument_types[i]: self.args[i].check_types() - elif method.argument_types[i] in passedArgTypes[i].direct_supertypes: + elif method.argument_types[i] in passedArgTypes[i].direct_supertypes or passedArgTypes[i] == Type.null: self.args[i].check_types() else: raise JavaTypeError("{0} expects arguments of type {1}, but got {2}".format( @@ -132,6 +134,8 @@ def check_types(self): raise JavaTypeError("Type {0} is not instantiable".format( self.instantiated_type.name )) + if self.instantiated_type == Type.null: + raise JavaTypeError("Type null is not instantiable") passedArgTypes = [] #setup a list for the types of passed arguments expectedArgTypes = self.instantiated_type.constructor.argument_types @@ -152,6 +156,8 @@ def check_types(self): self.args[i].check_types() elif expectedArgTypes[i] in passedArgTypes[i].direct_supertypes: self.args[i].check_types() + elif passedArgTypes[i] == Type.null and not expectedArgTypes[i] in primitives: + pass else: raise JavaTypeError("{0} expects arguments of type {1}, but got {2}".format( self.instantiated_type.name + " constructor", diff --git a/java-type-checker/java_type_checker/types.py b/java-type-checker/java_type_checker/types.py index e4db2ed..15024d8 100644 --- a/java-type-checker/java_type_checker/types.py +++ b/java-type-checker/java_type_checker/types.py @@ -81,6 +81,13 @@ class NullType(Type): def __init__(self): super().__init__("null") + def is_subtype_of(self, other): + return True + + def method_named(self, name): + raise NoSuchMethod("Cannot invoke method {0} on null".format( + name + "()")) + class NoSuchMethod(Exception): pass diff --git a/java-type-checker/tests/test_null.py b/java-type-checker/tests/test_null.py index 36693c2..32ab529 100644 --- a/java-type-checker/tests/test_null.py +++ b/java-type-checker/tests/test_null.py @@ -84,7 +84,7 @@ def test_catch_wrong_type_in_deep_expression(self): """ Equivalent Java: - GraphicsGroup group; + GraphicsGroup group; Window window; group.add( From c9a61829efe90970f93a7cd45b4ccefaf116cfd6 Mon Sep 17 00:00:00 2001 From: kaylabeckm Date: Fri, 9 Feb 2018 21:23:42 -0600 Subject: [PATCH 5/5] Done! All tests pass! --- java-type-checker/java_type_checker/expressions.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/java-type-checker/java_type_checker/expressions.py b/java-type-checker/java_type_checker/expressions.py index e9f9df9..f6a0c71 100644 --- a/java-type-checker/java_type_checker/expressions.py +++ b/java-type-checker/java_type_checker/expressions.py @@ -105,10 +105,11 @@ def check_types(self): for e in self.args: passedArgTypes.append(e.static_type()) for i in range(0,len(self.args)): # if you passed args of the correct type for the method + self.args[i].check_types() if passedArgTypes[i] == method.argument_types[i]: - self.args[i].check_types() + pass elif method.argument_types[i] in passedArgTypes[i].direct_supertypes or passedArgTypes[i] == Type.null: - self.args[i].check_types() + pass else: raise JavaTypeError("{0} expects arguments of type {1}, but got {2}".format( objType.name + "." + method.name + "()", @@ -152,10 +153,11 @@ def check_types(self): for e in self.args: passedArgTypes.append(e.static_type()) for i in range(0,len(self.args)): + self.args[i].check_types() if passedArgTypes[i] == expectedArgTypes[i]: - self.args[i].check_types() + pass elif expectedArgTypes[i] in passedArgTypes[i].direct_supertypes: - self.args[i].check_types() + pass elif passedArgTypes[i] == Type.null and not expectedArgTypes[i] in primitives: pass else: