diff --git a/.idea/comp394-type-modeling.iml b/.idea/comp394-type-modeling.iml
new file mode 100644
index 0000000..d6ebd48
--- /dev/null
+++ b/.idea/comp394-type-modeling.iml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
new file mode 100644
index 0000000..58918f5
--- /dev/null
+++ b/.idea/misc.xml
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff --git a/.idea/modules.xml b/.idea/modules.xml
new file mode 100644
index 0000000..96bca08
--- /dev/null
+++ b/.idea/modules.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/java-type-checker/.idea/inspectionProfiles/Project_Default.xml b/java-type-checker/.idea/inspectionProfiles/Project_Default.xml
deleted file mode 100644
index b169286..0000000
--- a/java-type-checker/.idea/inspectionProfiles/Project_Default.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/java-type-checker/.idea/misc.xml b/java-type-checker/.idea/misc.xml
index c24fcb0..0535679 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..53835e7 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..eb330c3 100644
--- a/java-type-checker/java_type_checker/expressions.py
+++ b/java-type-checker/java_type_checker/expressions.py
@@ -14,14 +14,17 @@ 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()")
+ # raise NotImplementedError(type(self).__name__ + " must implement static_type()")
+
+ return Expression
+
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()")
+
class Variable(Expression):
@@ -30,7 +33,8 @@ class Variable(Expression):
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
class Literal(Expression):
""" A literal value entered in the code, e.g. `5` in the expression `x + 5`.
@@ -39,11 +43,14 @@ 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
class NullLiteral(Literal):
def __init__(self):
super().__init__("null", Type.null)
-
+ def static_type(self):
+ return self.type
class MethodCall(Expression):
"""
@@ -55,6 +62,57 @@ 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):
+ #if the reciever is null
+ try:
+ self.static_type()
+ pass
+ except AttributeError:
+ pass
+
+ #check if the receiver is instantiable
+ if not self.receiver.static_type().is_instantiable:
+ raise JavaTypeError("Type {0} does not have methods".format(self.receiver.static_type().name))
+
+ #check for wrong number of arguments
+ if len(self.args) != len(self.receiver.static_type().method_named(self.method_name).argument_types):
+ raise JavaTypeError(
+ "Wrong number of arguments for {3}.{0}(): expected {1}, got {2}".format(
+ self.method_name, len(self.receiver.static_type().method_named(self.method_name).argument_types),
+ len(self.args),self.receiver.static_type().name))
+
+
+ #check for wrong type of arguments
+ argList = []
+ for arg in self.args:
+ argList += [arg.static_type()]
+ consList = []
+ for constype in self.receiver.static_type().method_named(self.method_name).argument_types:
+ consList += [constype]
+ for i in range(len(self.args)):
+ if hasattr(self.args[i],"args"):
+ self.args[i].check_types()
+ if ( not argList[i].is_subtype_of(consList[i])) and (argList[i] is not Type.null):
+ raise JavaTypeError(
+ "{0}.{1}() expects arguments of type {2}, but got {3}".format(
+ self.receiver.static_type().name, self.method_name, names(consList), names(argList)
+ )
+ )
+ if (not consList[i].is_subtype_of([Type.object])):
+ print(consList[i].name)
+ if (( not consList[i].is_instantiable) and (argList[i] is Type.null)):
+ raise JavaTypeError(
+ "{0}.{1}() expects arguments of type {2}, but got {3}".format(
+ self.receiver.static_type().name, self.method_name, names(consList), names(argList)
+ )
+ )
+
+
+
+
class ConstructorCall(Expression):
"""
@@ -63,6 +121,46 @@ class ConstructorCall(Expression):
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):
+ #Check if primitive
+ if not self.instantiated_type.is_instantiable:
+ raise JavaTypeError("Type {0} is not instantiable".format(self.instantiated_type.name))
+
+ #Wrong number of constructor args
+ if len(self.args) != len(self.static_type().constructor.argument_types):
+ raise JavaTypeError(
+ "Wrong number of arguments for {0} constructor: expected {1}, got {2}".format(
+ self.static_type().name,
+ len(self.static_type().constructor.argument_types),
+ len(self.args)))
+ #wrong type of construct
+ argList = []
+ for arg in self.args:
+ argList += [arg.static_type()]
+ consList = []
+ for cons in self.static_type().constructor.argument_types:
+ consList += [cons]
+ for i in range(len(self.args)):
+ if hasattr(self.args[i],"args"):
+ self.args[i].check_types()
+
+
+
+ if (not argList[i].is_subtype_of(consList[i])) and (argList[i] is not Type.null) :
+ raise JavaTypeError(
+ "{0} constructor expects arguments of type {1}, but got {2}".format(
+ self.static_type().name, names(consList),names(argList)
+ )
+ )
+ if (not consList[i].is_instantiable) and (argList[i] is Type.null):
+ raise JavaTypeError(
+ "{0} constructor expects arguments of type {1}, but got {2}".format(
+ self.static_type().name, names(consList), names(argList)
+ )
+ )
+
class JavaTypeError(Exception):
diff --git a/java-type-checker/java_type_checker/types.py b/java-type-checker/java_type_checker/types.py
index 465f7f4..813c1de 100644
--- a/java-type-checker/java_type_checker/types.py
+++ b/java-type-checker/java_type_checker/types.py
@@ -12,7 +12,11 @@ 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) or (other in self.direct_supertypes):
+ return True
+ else:
+ for item in self.direct_supertypes:
+ return False or item.is_subtype_of(other)
def is_supertype_of(self, other):
""" Convenience counterpart to is_subtype_of().
@@ -23,13 +27,16 @@ def is_supertype_of(self, other):
class Constructor(object):
""" The declaration of a Java constructor.
"""
+ is_runnable = True
def __init__(self, argument_types=[]):
self.argument_types = argument_types
+
class Method(object):
""" The declaration of a Java method.
"""
+ is_runnable = True
def __init__(self, name, argument_types=[], return_type=None):
self.name = name
self.argument_types = argument_types
@@ -71,6 +78,9 @@ class NullType(Type):
"""
def __init__(self):
super().__init__("null")
+ self.is_instantiable=False
+ def method_named(self,name):
+ raise NoSuchMethod("Cannot invoke method {0}() on null".format(name))
class NoSuchMethod(Exception):
diff --git a/java-type-checker/tests/test_null.py b/java-type-checker/tests/test_null.py
index 36693c2..b5b8d2c 100644
--- a/java-type-checker/tests/test_null.py
+++ b/java-type-checker/tests/test_null.py
@@ -75,10 +75,7 @@ def test_passes_deep_expression(self):
MethodCall(
Variable("group", Graphics.graphics_group),
"add",
- ConstructorCall(
- Graphics.rectangle,
- NullLiteral(),
- NullLiteral())))
+ ConstructorCall(Graphics.rectangle,NullLiteral(),NullLiteral())))
def test_catch_wrong_type_in_deep_expression(self):
"""
diff --git a/java-type-checker/tests/test_static_types.py b/java-type-checker/tests/test_static_types.py
index fcedb26..61cd7f6 100755
--- a/java-type-checker/tests/test_static_types.py
+++ b/java-type-checker/tests/test_static_types.py
@@ -25,9 +25,7 @@ def test_null_literal_static_type_is_null(self):
def test_method_call_static_type_is_method_return_type(self):
# p.getX() → double
- self.assertEqual(
- Type.double,
- MethodCall(Variable("p", Graphics.point), "getX").static_type())
+ self.assertEqual(Type.double, MethodCall(Variable("p", Graphics.point), "getX").static_type())
def test_object_instantiation_static_type_is_the_instantiate_type(self):
# new Point() → Point
diff --git a/java-type-checker/tests/test_type_checking.py b/java-type-checker/tests/test_type_checking.py
index b10ef24..9915f82 100644
--- a/java-type-checker/tests/test_type_checking.py
+++ b/java-type-checker/tests/test_type_checking.py
@@ -56,10 +56,7 @@ def test_flags_too_many_arguments(self):
JavaTypeError,
"Wrong number of arguments for Point.getX(): expected 0, got 2",
MethodCall(
- Variable("p", Graphics.point),
- "getX",
- Literal("0.0", Type.double),
- Literal("1.0", Type.double)))
+ Variable("p", Graphics.point),"getX",Literal("0.0", Type.double),Literal("1.0", Type.double)))
def test_flags_too_few_arguments(self):
"""
@@ -135,10 +132,7 @@ def test_flags_wrong_constructor_argument_type(self):
self.assertCompileError(
JavaTypeError,
"Rectangle constructor expects arguments of type (Point, Size), but got (Point, boolean)",
- ConstructorCall(
- Graphics.rectangle,
- Variable("p", Graphics.point),
- Literal("true", Type.boolean)))
+ ConstructorCall(Graphics.rectangle, Variable("p", Graphics.point), Literal("true", Type.boolean)))
def test_cannot_call_methods_on_primitives(self):
"""
@@ -148,8 +142,7 @@ def test_cannot_call_methods_on_primitives(self):
x.hashCode()
"""
- self.assertCompileError(
- JavaTypeError,
+ self.assertCompileError(JavaTypeError,
"Type int does not have methods",
MethodCall(
Variable("x", Type.int),
@@ -177,17 +170,12 @@ def test_does_not_allow_void_passed_as_argument(self):
rect.setFillColor( // error here
rect.setStrokeColor(red)); // returns void
"""
- self.assertCompileError(
- JavaTypeError,
- "Rectangle.setFillColor() expects arguments of type (Paint), but got (void)",
- MethodCall(
- Variable("rect", Graphics.rectangle),
- "setFillColor",
- MethodCall(
- Variable("rect", Graphics.rectangle),
- "setStrokeColor",
+ self.assertCompileError(JavaTypeError,"Rectangle.setFillColor() expects arguments of type (Paint), but got (void)",
+ MethodCall(Variable("rect", Graphics.rectangle),"setFillColor",
+ MethodCall(Variable("rect", Graphics.rectangle),"setStrokeColor",
Variable("red", Graphics.color))))
+
def test_passes_deep_expression(self):
"""
Equivalent Java:
@@ -231,11 +219,7 @@ def test_catch_wrong_name_in_deep_expression(self):
MethodCall(
Variable("group", Graphics.graphics_group),
"add",
- ConstructorCall(
- Graphics.rectangle,
- ConstructorCall(Graphics.point,
- Literal("0.0", Type.double),
- Literal("0.0", Type.double)),
+ ConstructorCall(Graphics.rectangle, ConstructorCall(Graphics.point,Literal("0.0", Type.double),Literal("0.0", Type.double)),
MethodCall(
Variable("window", Graphics.window),
"getFunky"))))
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..862d818 100644
--- a/python-attr-lookup/src/plang/PythonObject.java
+++ b/python-attr-lookup/src/plang/PythonObject.java
@@ -50,8 +50,12 @@ public List getMRO() {
* Constructs the MRO. Called only once, the first time we need the MRO; this class memoizes the
* result (i.e. it remembers the list buildMRO() returned and keeps returning it).
*/
- protected List buildMRO() {
- throw new UnsupportedOperationException("not implemented yet");
+ protected List buildMRO(){
+
+ List list = type.buildMRO();
+ list.add(0,this);
+ return list;
+ //throw new UnsupportedOperationException("not implemented yet");
}
/**
@@ -62,7 +66,12 @@ 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 pobject : getMRO()){
+ if(pobject.attrs.containsKey(attrName)){
+ return pobject.attrs.get(attrName);
+ }
+ }
+ throw new PythonAttributeException(this,attrName);
}
/**
@@ -74,7 +83,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..fd2d185 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 list = new ArrayList<>();
+ list.add(this);
+ if(base!= null){
+ list.addAll(base.getMRO());
+ }
+ return list;
}
/**
@@ -49,7 +54,8 @@ protected List buildMRO() {
* this PythonType.
*/
public PythonObject instantiate() {
- throw new UnsupportedOperationException("not implemented yet");
+ return new PythonObject(this);
+
}
@Override
diff --git a/python-attr-lookup/test/plang/PythonObjectTest.java b/python-attr-lookup/test/plang/PythonObjectTest.java
index 2080d71..179795f 100644
--- a/python-attr-lookup/test/plang/PythonObjectTest.java
+++ b/python-attr-lookup/test/plang/PythonObjectTest.java
@@ -1,6 +1,7 @@
package plang;
import org.junit.jupiter.api.BeforeEach;
+
import org.junit.jupiter.api.Test;
import java.util.Arrays;