Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion java-type-checker/.idea/misc.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion java-type-checker/.idea/type-checker.iml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

81 changes: 81 additions & 0 deletions java-type-checker/java_type_checker/expressions.py
Original file line number Diff line number Diff line change
Expand Up @@ -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`.
Expand All @@ -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):
Expand All @@ -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):
"""
Expand All @@ -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.
Expand All @@ -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]) + ")"

18 changes: 17 additions & 1 deletion java-type-checker/java_type_checker/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -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().
Expand Down Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion python-attr-lookup/.idea/misc.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 10 additions & 0 deletions python-attr-lookup/python-attr-lookup.iml
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,15 @@
<SOURCES />
</library>
</orderEntry>
<orderEntry type="module-library" scope="TEST">
<library name="JUnit5">
<CLASSES>
<root url="jar://$APPLICATION_HOME_DIR$/plugins/junit/lib/junit-jupiter-api-5.0.0.jar!/" />
<root url="jar://$APPLICATION_HOME_DIR$/plugins/junit/lib/opentest4j-1.0.0.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</orderEntry>
</component>
</module>
21 changes: 18 additions & 3 deletions python-attr-lookup/src/plang/PythonObject.java
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,15 @@ public List<PythonObject> getMRO() {
* result (i.e. it remembers the list buildMRO() returned and keeps returning it).
*/
protected List<PythonObject> buildMRO() {
throw new UnsupportedOperationException("not implemented yet");

List<PythonObject> result = new ArrayList<>();

result.add(this);
if(type != null) {
result.addAll(this.type.buildMRO());
}
return result;

}

/**
Expand All @@ -62,7 +70,14 @@ protected List<PythonObject> 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);
}

/**
Expand All @@ -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
Expand Down
16 changes: 14 additions & 2 deletions python-attr-lookup/src/plang/PythonType.java
Original file line number Diff line number Diff line change
Expand Up @@ -41,15 +41,27 @@ public PythonObject getBase() {

@Override
protected List<PythonObject> buildMRO() {
throw new UnsupportedOperationException("not implemented yet");

List<PythonObject> result = new ArrayList<>();
result.add(this);
if(this.base != null) {
result.addAll(this.base.buildMRO());
}
return result;

}

/**
* Creates and returns a new instance of this class, i.e. a PythonObject whose type is
* 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
Expand Down