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
1 change: 1 addition & 0 deletions .idea/.name

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

22 changes: 22 additions & 0 deletions .idea/compiler.xml

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

3 changes: 3 additions & 0 deletions .idea/copyright/profiles_settings.xml

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

6 changes: 6 additions & 0 deletions .idea/encodings.xml

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

6 changes: 6 additions & 0 deletions .idea/misc.xml

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

8 changes: 8 additions & 0 deletions .idea/modules.xml

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

21 changes: 0 additions & 21 deletions java-type-checker/.idea/inspectionProfiles/Project_Default.xml

This file was deleted.

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.

74 changes: 74 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,11 @@ 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):
return

class Literal(Expression):
""" A literal value entered in the code, e.g. `5` in the expression `x + 5`.
Expand All @@ -39,11 +44,19 @@ 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):
return

class NullLiteral(Literal):
def __init__(self):
super().__init__("null", Type.null)
self.declared_type = Type.null

def static_type(self):
return Type.null

class MethodCall(Expression):
"""
Expand All @@ -55,6 +68,38 @@ 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):
classtype = self.receiver.declared_type
method = classtype.method_named(self.method_name)
return(method.return_type)

def check_types(self):
classtype = self.receiver.declared_type

if classtype.is_subtype_of(Type.boolean) or classtype.is_subtype_of(Type.int) or classtype.is_subtype_of(Type.double):
raise JavaTypeError("Type {0} does not have methods".format(classtype.name))

method = classtype.method_named(self.method_name)
argsExpected = method.argument_types #not certain what type this is.
args = self.args #But these are definitely expressions
typesGot = []

for arg in args:
typesGot.append(arg.static_type())
arg.check_types()


if(len(argsExpected) != len(args)):
raise JavaTypeError("Wrong number of arguments for {3}.{0}(): expected {1}, got {2}".format(self.method_name, len(argsExpected), len(args), classtype.name))

for i in range(len(args)):
typeExp = argsExpected[i]
expressionGot = args[i]
expressionGot.check_types()
typeGot = expressionGot.static_type()
if (not typeGot.is_subtype_of(typeExp)) and typesGot != argsExpected:
raise JavaTypeError("{0}.{1}() expects arguments of type {2}, but got {3}".format(classtype.name, self.method_name, names(argsExpected), names(typesGot)))
return

class ConstructorCall(Expression):
"""
Expand All @@ -65,6 +110,35 @@ def __init__(self, instantiated_type, *args):
self.args = args #: Constructor arguments (list of Expressions)



def static_type(self):
return self.instantiated_type

def check_types(self):
classType = self.static_type()
if classType == Type.null:
raise JavaTypeError("Type null is not instantiable")

if classType.is_subtype_of(Type.boolean) or classType.is_subtype_of(Type.int) or classType.is_subtype_of(Type.double):
raise JavaTypeError("Type {0} is not instantiable".format(classType.name))

argsGot = self.args
argsExp = classType.constructor.argument_types
typesGot = []
for arg in argsGot:
typesGot.append(arg.static_type())
arg.check_types()

if(len(argsExp) != len(argsGot)):
raise JavaTypeError("Wrong number of arguments for {0} constructor: expected {1}, got {2}".format(classType.name, len(argsExp), len(argsGot)))
for i in range(len(argsGot)):
typeExp = argsExp[i]
typeGot = argsGot[i].static_type()
#second part checks for a weird edge case where Got (Point, Size) Expected (Point, Size) TODO: figure out why
if (not typeGot.is_subtype_of(typeExp)) and typesGot != argsExp:
raise JavaTypeError("{0} constructor expects arguments of type {1}, but got {2}".format(classType.name, names(argsExp), names(typesGot)))
return

class JavaTypeError(Exception):
""" Indicates a compile-time type error in an expression.
"""
Expand Down
32 changes: 30 additions & 2 deletions java-type-checker/java_type_checker/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,20 @@ 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
#Catch for self not in supertypes, modifies a copy of the direct_supertypes in case user didn't spec self in list
allSupers = [self]
prevSize = -1
currentSize = 1
while currentSize > prevSize:
prevSize = currentSize
for super in allSupers:
potentialNewSupers = super.direct_supertypes
for potentialSuper in potentialNewSupers:
if potentialSuper not in allSupers:
allSupers.append(potentialSuper)
currentSize+=1
#Is this messy? yes it is. I'd rather use a set in this case but apparently returning arrays and then extending sets isn't viable
return(other in allSupers)

def is_supertype_of(self, other):
""" Convenience counterpart to is_subtype_of().
Expand Down Expand Up @@ -66,11 +79,26 @@ def method_named(self, name):
raise NoSuchMethod("{0} has no method named {1}".format(self.name, name))


class NullType(Type):
class NullType(ClassOrInterface):
""" The type of the value `null` in Java.
"""
def __init__(self):
super().__init__("null")
self.is_instantiable = False
self.methods = {}

def method_named(self, name):
raise NoSuchMethod("Cannot invoke method {0}() on {1}".format(name, self.name))

def is_subtype_of(self, other):
#primitives can't be null
if(other.is_subtype_of(Type.boolean) or other.is_subtype_of(Type.int) or other.is_subtype_of(Type.double)):
return False
return True






class NoSuchMethod(Exception):
Expand Down
12 changes: 12 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,17 @@
<SOURCES />
</library>
</orderEntry>
<orderEntry type="module-library" scope="TEST">
<library name="JUnit5.0">
<CLASSES>
<root url="jar://$MAVEN_REPOSITORY$/org/junit/jupiter/junit-jupiter-api/5.0.0/junit-jupiter-api-5.0.0.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/org/apiguardian/apiguardian-api/1.0.0/apiguardian-api-1.0.0.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/org/opentest4j/opentest4j/1.0.0/opentest4j-1.0.0.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/org/junit/platform/junit-platform-commons/1.0.0/junit-platform-commons-1.0.0.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</orderEntry>
</component>
</module>
23 changes: 15 additions & 8 deletions python-attr-lookup/src/plang/PythonObject.java
Original file line number Diff line number Diff line change
@@ -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.
Expand Down Expand Up @@ -51,7 +47,10 @@ 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");
mro = new ArrayList<>();
mro.add(this);
mro.addAll(this.getType().buildMRO());
return mro;
}

/**
Expand All @@ -62,7 +61,15 @@ 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");
boolean foundVal = false;
List<PythonObject> layers = getMRO();
for(PythonObject layer : layers){
if(layer.attrs.containsKey(attrName))
return layer.attrs.get(attrName);
}
if(!foundVal)
throw new PythonAttributeException(this, attrName);
return null;
}

/**
Expand All @@ -74,7 +81,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
12 changes: 9 additions & 3 deletions python-attr-lookup/src/plang/PythonType.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package plang;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
Expand Down Expand Up @@ -41,15 +40,22 @@ public PythonObject getBase() {

@Override
protected List<PythonObject> buildMRO() {
throw new UnsupportedOperationException("not implemented yet");
List<PythonObject> mro = new ArrayList<>();
mro.add(this);
if(this.base == null)
return mro;
mro.addAll(this.base.getMRO());
return mro;
}

/**
* 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");
return new PythonObject(this);
// todo: confirm this works?
//throw new UnsupportedOperationException("not implemented yet");
}

@Override
Expand Down