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/java-type-checker/java_type_checker/expressions.py b/java-type-checker/java_type_checker/expressions.py
index 27ed57e..f6a0c71 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,76 @@ 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 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]:
+ pass
+ elif method.argument_types[i] in passedArgTypes[i].direct_supertypes or passedArgTypes[i] == Type.null:
+ 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 +125,47 @@ 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
+ ))
+ 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
+ # 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 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]:
+ pass
+ elif expectedArgTypes[i] in passedArgTypes[i].direct_supertypes:
+ pass
+ 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",
+ 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..15024d8 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().
@@ -72,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(
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