aboutsummaryrefslogtreecommitdiff
path: root/src/main
diff options
context:
space:
mode:
Diffstat (limited to 'src/main')
-rw-r--r--src/main/java/org/zwobble/couscous/ast/StaticMethodCallNode.java42
-rw-r--r--src/main/java/org/zwobble/couscous/backends/python/PrimitiveMethods.java24
-rw-r--r--src/main/java/org/zwobble/couscous/backends/python/PythonCodeGenerator.java19
-rw-r--r--src/main/java/org/zwobble/couscous/backends/python/PythonCompiler.java4
-rw-r--r--src/main/java/org/zwobble/couscous/backends/python/PythonSerializer.java12
-rw-r--r--src/main/java/org/zwobble/couscous/backends/python/ast/PythonBinaryOperation.java39
-rw-r--r--src/main/java/org/zwobble/couscous/backends/python/ast/visitors/PythonNodeVisitor.java2
-rw-r--r--src/main/java/org/zwobble/couscous/frontends/java/JavaReader.java52
-rw-r--r--src/main/java/org/zwobble/couscous/interpreter/Interpreter.java24
-rw-r--r--src/main/java/org/zwobble/couscous/interpreter/JavaProject.java6
-rw-r--r--src/main/java/org/zwobble/couscous/interpreter/values/InternalCouscousInterpeterValue.java14
-rw-r--r--src/main/java/org/zwobble/couscous/values/InternalCouscousValue.java7
-rw-r--r--src/main/java/org/zwobble/couscous/values/ObjectValue.java7
-rw-r--r--src/main/resources/python/runtime/java/lang/Object.py1
14 files changed, 206 insertions, 47 deletions
diff --git a/src/main/java/org/zwobble/couscous/ast/StaticMethodCallNode.java b/src/main/java/org/zwobble/couscous/ast/StaticMethodCallNode.java
index 2b63948..4af0701 100644
--- a/src/main/java/org/zwobble/couscous/ast/StaticMethodCallNode.java
+++ b/src/main/java/org/zwobble/couscous/ast/StaticMethodCallNode.java
@@ -3,36 +3,46 @@ package org.zwobble.couscous.ast;
import java.util.List;
import org.zwobble.couscous.ast.visitors.ExpressionNodeMapper;
+import org.zwobble.couscous.values.BooleanValue;
+import org.zwobble.couscous.values.InternalCouscousValue;
import static java.util.Arrays.asList;
public class StaticMethodCallNode implements ExpressionNode {
- public static StaticMethodCallNode staticMethodCall(String className, String methodName, ExpressionNode... arguments) {
- return staticMethodCall(className, methodName, asList(arguments));
+ public static ExpressionNode same(ExpressionNode left, ExpressionNode right) {
+ return staticMethodCall(InternalCouscousValue.REF, "same", asList(left, right), BooleanValue.REF);
}
- public static StaticMethodCallNode staticMethodCall(String className, String methodName, List<ExpressionNode> arguments) {
- return staticMethodCall(TypeName.of(className), methodName, arguments);
+ public static StaticMethodCallNode staticMethodCall(
+ String className,
+ String methodName,
+ List<ExpressionNode> arguments,
+ TypeName type) {
+ return staticMethodCall(TypeName.of(className), methodName, arguments, type);
}
public static StaticMethodCallNode staticMethodCall(
TypeName className,
String methodName,
- List<ExpressionNode> arguments) {
- return new StaticMethodCallNode(className, methodName, arguments);
+ List<ExpressionNode> arguments,
+ TypeName type) {
+ return new StaticMethodCallNode(className, methodName, arguments, type);
}
private final TypeName className;
private final String methodName;
private final List<ExpressionNode> arguments;
+ private final TypeName type;
public StaticMethodCallNode(
TypeName className,
String methodName,
- List<ExpressionNode> arguments) {
+ List<ExpressionNode> arguments,
+ TypeName type) {
this.className = className;
this.methodName = methodName;
this.arguments = arguments;
+ this.type = type;
}
public TypeName getClassName() {
@@ -47,20 +57,20 @@ public class StaticMethodCallNode implements ExpressionNode {
return arguments;
}
+ public TypeName getType() {
+ return type;
+ }
+
@Override
public <T> T accept(ExpressionNodeMapper<T> visitor) {
return visitor.visit(this);
}
@Override
- public TypeName getType() {
- throw new UnsupportedOperationException();
- }
-
- @Override
public String toString() {
return "StaticMethodCallNode(className=" + className + ", methodName="
- + methodName + ", arguments=" + arguments + ")";
+ + methodName + ", arguments=" + arguments + ", type=" + type
+ + ")";
}
@Override
@@ -73,6 +83,7 @@ public class StaticMethodCallNode implements ExpressionNode {
+ ((className == null) ? 0 : className.hashCode());
result = prime * result
+ ((methodName == null) ? 0 : methodName.hashCode());
+ result = prime * result + ((type == null) ? 0 : type.hashCode());
return result;
}
@@ -100,6 +111,11 @@ public class StaticMethodCallNode implements ExpressionNode {
return false;
} else if (!methodName.equals(other.methodName))
return false;
+ if (type == null) {
+ if (other.type != null)
+ return false;
+ } else if (!type.equals(other.type))
+ return false;
return true;
}
}
diff --git a/src/main/java/org/zwobble/couscous/backends/python/PrimitiveMethods.java b/src/main/java/org/zwobble/couscous/backends/python/PrimitiveMethods.java
index c6aa62d..6605fc9 100644
--- a/src/main/java/org/zwobble/couscous/backends/python/PrimitiveMethods.java
+++ b/src/main/java/org/zwobble/couscous/backends/python/PrimitiveMethods.java
@@ -9,6 +9,7 @@ import org.zwobble.couscous.backends.python.ast.PythonExpressionNode;
import org.zwobble.couscous.backends.python.ast.PythonNotNode;
import org.zwobble.couscous.values.BooleanValue;
import org.zwobble.couscous.values.IntegerValue;
+import org.zwobble.couscous.values.InternalCouscousValue;
import org.zwobble.couscous.values.StringValue;
import com.google.common.collect.ImmutableMap;
@@ -16,6 +17,7 @@ import com.google.common.collect.ImmutableMap.Builder;
import static java.util.Arrays.asList;
import static org.zwobble.couscous.backends.python.ast.PythonAttributeAccessNode.pythonAttributeAccess;
+import static org.zwobble.couscous.backends.python.ast.PythonBinaryOperation.pythonIs;
import static org.zwobble.couscous.backends.python.ast.PythonCallNode.pythonCall;
import static org.zwobble.couscous.backends.python.ast.PythonGetSliceNode.pythonGetSlice;
import static org.zwobble.couscous.backends.python.ast.PythonVariableReferenceNode.pythonVariableReference;
@@ -90,6 +92,18 @@ public class PrimitiveMethods {
.put(IntegerValue.REF, INT_METHODS)
.build();
+ private static final Map<String, PrimitiveStaticMethodGenerator> INTERNAL_METHODS =
+ ImmutableMap.<String, PrimitiveStaticMethodGenerator>builder()
+
+ .put("same", arguments -> pythonIs(arguments.get(0), arguments.get(1)))
+
+ .build();
+
+ private static final Map<TypeName, Map<String, PrimitiveStaticMethodGenerator>> STATIC_METHODS =
+ ImmutableMap.<TypeName, Map<String, PrimitiveStaticMethodGenerator>>builder()
+ .put(InternalCouscousValue.REF, INTERNAL_METHODS)
+ .build();
+
public static boolean isPrimitive(TypeName type) {
return METHODS.containsKey(type);
}
@@ -103,4 +117,14 @@ public class PrimitiveMethods {
public interface PrimitiveMethodGenerator {
PythonExpressionNode generate(PythonExpressionNode receiver, List<PythonExpressionNode> arguments);
}
+
+ public static Optional<PrimitiveStaticMethodGenerator> getPrimitiveStaticMethod(TypeName type, String methodName) {
+ return Optional.ofNullable(STATIC_METHODS.get(type))
+ .flatMap(methodsForType -> Optional.ofNullable(methodsForType.get(methodName)));
+ }
+
+ @FunctionalInterface
+ public interface PrimitiveStaticMethodGenerator {
+ PythonExpressionNode generate(List<PythonExpressionNode> arguments);
+ }
}
diff --git a/src/main/java/org/zwobble/couscous/backends/python/PythonCodeGenerator.java b/src/main/java/org/zwobble/couscous/backends/python/PythonCodeGenerator.java
index 54d56ed..fb1851c 100644
--- a/src/main/java/org/zwobble/couscous/backends/python/PythonCodeGenerator.java
+++ b/src/main/java/org/zwobble/couscous/backends/python/PythonCodeGenerator.java
@@ -29,6 +29,7 @@ import org.zwobble.couscous.ast.visitors.NodeVisitorWithEmptyDefaults;
import org.zwobble.couscous.ast.visitors.NodeVisitors;
import org.zwobble.couscous.ast.visitors.StatementNodeMapper;
import org.zwobble.couscous.backends.python.PrimitiveMethods.PrimitiveMethodGenerator;
+import org.zwobble.couscous.backends.python.ast.PythonAttributeAccessNode;
import org.zwobble.couscous.backends.python.ast.PythonBlock;
import org.zwobble.couscous.backends.python.ast.PythonClassNode;
import org.zwobble.couscous.backends.python.ast.PythonExpressionNode;
@@ -39,6 +40,7 @@ import org.zwobble.couscous.backends.python.ast.PythonStatementNode;
import org.zwobble.couscous.backends.python.ast.PythonVariableReferenceNode;
import org.zwobble.couscous.values.BooleanValue;
import org.zwobble.couscous.values.IntegerValue;
+import org.zwobble.couscous.values.InternalCouscousValue;
import org.zwobble.couscous.values.PrimitiveValue;
import org.zwobble.couscous.values.PrimitiveValueVisitor;
import org.zwobble.couscous.values.StringValue;
@@ -92,7 +94,9 @@ public class PythonCodeGenerator {
private static Stream<PythonImportNode> generateImports(ClassNode classNode) {
Set<TypeName> classes = findReferencedClasses(classNode);
- return classes.stream().map(name -> pythonImport(importPathToRoot(classNode) + name.getQualifiedName(), asList(pythonImportAlias(name.getSimpleName()))));
+ return classes.stream()
+ .filter(name -> !name.equals(InternalCouscousValue.REF))
+ .map(name -> pythonImport(importPathToRoot(classNode) + name.getQualifiedName(), asList(pythonImportAlias(name.getSimpleName()))));
}
private static String importPathToRoot(ClassNode classNode) {
@@ -243,11 +247,14 @@ public class PythonCodeGenerator {
@Override
public PythonExpressionNode visit(StaticMethodCallNode staticMethodCall) {
- final org.zwobble.couscous.ast.TypeName className = staticMethodCall.getClassName();
- final org.zwobble.couscous.backends.python.ast.PythonVariableReferenceNode classReference = pythonVariableReference(className.getSimpleName());
- final org.zwobble.couscous.backends.python.ast.PythonAttributeAccessNode methodReference = pythonAttributeAccess(classReference, staticMethodCall.getMethodName());
- final java.util.List<org.zwobble.couscous.backends.python.ast.PythonExpressionNode> arguments = generateExpressions(staticMethodCall.getArguments());
- return pythonCall(methodReference, arguments);
+ TypeName className = staticMethodCall.getClassName();
+ PythonVariableReferenceNode classReference = pythonVariableReference(className.getSimpleName());
+ PythonAttributeAccessNode methodReference = pythonAttributeAccess(classReference, staticMethodCall.getMethodName());
+ List<PythonExpressionNode> arguments = generateExpressions(staticMethodCall.getArguments());
+
+ return PrimitiveMethods.getPrimitiveStaticMethod(className, staticMethodCall.getMethodName())
+ .map(generator -> generator.generate(arguments))
+ .orElseGet(() -> pythonCall(methodReference, arguments));
}
@Override
diff --git a/src/main/java/org/zwobble/couscous/backends/python/PythonCompiler.java b/src/main/java/org/zwobble/couscous/backends/python/PythonCompiler.java
index c8f9932..d077736 100644
--- a/src/main/java/org/zwobble/couscous/backends/python/PythonCompiler.java
+++ b/src/main/java/org/zwobble/couscous/backends/python/PythonCompiler.java
@@ -17,7 +17,9 @@ import static org.zwobble.couscous.backends.python.PythonSerializer.serialize;
public class PythonCompiler {
private static final List<String> RUNTIME_FILES = asList(
- "java.lang.Integer", "_couscous");
+ "java.lang.Object",
+ "java.lang.Integer",
+ "_couscous");
private final Path root;
private final String packageName;
diff --git a/src/main/java/org/zwobble/couscous/backends/python/PythonSerializer.java b/src/main/java/org/zwobble/couscous/backends/python/PythonSerializer.java
index eadb545..2fb341f 100644
--- a/src/main/java/org/zwobble/couscous/backends/python/PythonSerializer.java
+++ b/src/main/java/org/zwobble/couscous/backends/python/PythonSerializer.java
@@ -4,6 +4,7 @@ import java.util.List;
import java.util.function.Consumer;
import org.zwobble.couscous.backends.python.ast.PythonAssignmentNode;
import org.zwobble.couscous.backends.python.ast.PythonAttributeAccessNode;
+import org.zwobble.couscous.backends.python.ast.PythonBinaryOperation;
import org.zwobble.couscous.backends.python.ast.PythonBlock;
import org.zwobble.couscous.backends.python.ast.PythonBooleanLiteralNode;
import org.zwobble.couscous.backends.python.ast.PythonCallNode;
@@ -34,7 +35,7 @@ public class PythonSerializer implements PythonNodeVisitor {
return writer.asString();
}
- private PythonWriter writer;
+ private final PythonWriter writer;
private PythonSerializer(PythonWriter writer) {
this.writer = writer;
@@ -111,6 +112,15 @@ public class PythonSerializer implements PythonNodeVisitor {
writer.writeSpace();
writeParenthesised(notOperation.getOperand());
}
+
+ @Override
+ public void visit(PythonBinaryOperation operation) {
+ writeParenthesised(operation.getLeft());
+ writer.writeSpace();
+ writer.writeKeyword(operation.getOperator());
+ writer.writeSpace();
+ writeParenthesised(operation.getRight());
+ }
@Override
public void visit(PythonReturnNode pythonReturn) {
diff --git a/src/main/java/org/zwobble/couscous/backends/python/ast/PythonBinaryOperation.java b/src/main/java/org/zwobble/couscous/backends/python/ast/PythonBinaryOperation.java
new file mode 100644
index 0000000..1fc87c3
--- /dev/null
+++ b/src/main/java/org/zwobble/couscous/backends/python/ast/PythonBinaryOperation.java
@@ -0,0 +1,39 @@
+package org.zwobble.couscous.backends.python.ast;
+
+import org.zwobble.couscous.backends.python.ast.visitors.PythonNodeVisitor;
+
+public class PythonBinaryOperation implements PythonExpressionNode {
+ public static PythonExpressionNode pythonIs(PythonExpressionNode left, PythonExpressionNode right) {
+ return new PythonBinaryOperation("is", left, right);
+ }
+
+ private final String operator;
+ private final PythonExpressionNode left;
+ private final PythonExpressionNode right;
+
+ public PythonBinaryOperation(
+ String operator,
+ PythonExpressionNode left,
+ PythonExpressionNode right) {
+ this.operator = operator;
+ this.left = left;
+ this.right = right;
+ }
+
+ public String getOperator() {
+ return operator;
+ }
+
+ public PythonExpressionNode getLeft() {
+ return left;
+ }
+
+ public PythonExpressionNode getRight() {
+ return right;
+ }
+
+ @Override
+ public void accept(PythonNodeVisitor visitor) {
+ visitor.visit(this);
+ }
+}
diff --git a/src/main/java/org/zwobble/couscous/backends/python/ast/visitors/PythonNodeVisitor.java b/src/main/java/org/zwobble/couscous/backends/python/ast/visitors/PythonNodeVisitor.java
index 59a1fe9..a1ed7d5 100644
--- a/src/main/java/org/zwobble/couscous/backends/python/ast/visitors/PythonNodeVisitor.java
+++ b/src/main/java/org/zwobble/couscous/backends/python/ast/visitors/PythonNodeVisitor.java
@@ -2,6 +2,7 @@ package org.zwobble.couscous.backends.python.ast.visitors;
import org.zwobble.couscous.backends.python.ast.PythonAssignmentNode;
import org.zwobble.couscous.backends.python.ast.PythonAttributeAccessNode;
+import org.zwobble.couscous.backends.python.ast.PythonBinaryOperation;
import org.zwobble.couscous.backends.python.ast.PythonBooleanLiteralNode;
import org.zwobble.couscous.backends.python.ast.PythonCallNode;
import org.zwobble.couscous.backends.python.ast.PythonClassNode;
@@ -27,6 +28,7 @@ public interface PythonNodeVisitor {
void visit(PythonCallNode call);
void visit(PythonGetSliceNode getSlice);
void visit(PythonNotNode notOperation);
+ void visit(PythonBinaryOperation operation);
void visit(PythonReturnNode pythonReturn);
void visit(PythonPassNode pass);
diff --git a/src/main/java/org/zwobble/couscous/frontends/java/JavaReader.java b/src/main/java/org/zwobble/couscous/frontends/java/JavaReader.java
index 2e1be0c..601e565 100644
--- a/src/main/java/org/zwobble/couscous/frontends/java/JavaReader.java
+++ b/src/main/java/org/zwobble/couscous/frontends/java/JavaReader.java
@@ -243,19 +243,36 @@ public class JavaReader {
String methodName = expression.getName().getIdentifier();
@SuppressWarnings("unchecked")
List<ExpressionNode> arguments = readArguments(expression.arguments());
+ final TypeName type = typeOf(expression);
if (expression.getExpression() == null) {
IMethodBinding methodBinding = expression.resolveMethodBinding();
TypeName receiverType = typeOf(methodBinding.getDeclaringClass());
if ((methodBinding.getModifiers() & Modifier.STATIC) != 0) {
- return StaticMethodCallNode.staticMethodCall(receiverType, methodName, arguments);
+ return StaticMethodCallNode.staticMethodCall(
+ receiverType,
+ methodName,
+ arguments,
+ type);
} else {
- return MethodCallNode.methodCall(ThisReferenceNode.thisReference(receiverType), methodName, arguments, typeOf(expression));
+ return MethodCallNode.methodCall(
+ ThisReferenceNode.thisReference(receiverType),
+ methodName,
+ arguments,
+ type);
}
} else if (expression.getExpression().getNodeType() == ASTNode.SIMPLE_NAME) {
Expression receiver = expression.getExpression();
- return StaticMethodCallNode.staticMethodCall(typeOf(receiver), methodName, arguments);
+ return StaticMethodCallNode.staticMethodCall(
+ typeOf(receiver),
+ methodName,
+ arguments,
+ type);
} else {
- return MethodCallNode.methodCall(readExpression(expression.getExpression()), methodName, arguments, typeOf(expression));
+ return MethodCallNode.methodCall(
+ readExpression(expression.getExpression()),
+ methodName,
+ arguments,
+ type);
}
}
@@ -274,15 +291,26 @@ public class JavaReader {
private static ExpressionNode readInfixExpression(InfixExpression expression) {
final ExpressionNode left = readExpression(expression.getLeftOperand());
final ExpressionNode right = readExpression(expression.getRightOperand());
- if (expression.getOperator() == Operator.NOT_EQUALS) {
- return MethodCallNode.not(methodCall(left, "equals", asList(right), BooleanValue.REF));
+
+ if (left.getType().equals(IntegerValue.REF)) {
+ if (expression.getOperator() == Operator.NOT_EQUALS) {
+ return MethodCallNode.not(methodCall(left, "equals", asList(right), BooleanValue.REF));
+ } else {
+ JavaOperator operator = readOperator(expression.getOperator());
+ return MethodCallNode.methodCall(
+ left,
+ operator.methodName,
+ asList(right),
+ operator.returnValue);
+ }
} else {
- JavaOperator operator = readOperator(expression.getOperator());
- return MethodCallNode.methodCall(
- left,
- operator.methodName,
- asList(right),
- operator.returnValue);
+ if (expression.getOperator() == Operator.EQUALS) {
+ return StaticMethodCallNode.same(left, right);
+ } else if (expression.getOperator() == Operator.NOT_EQUALS) {
+ return MethodCallNode.not(StaticMethodCallNode.same(left, right));
+ } else {
+ throw new IllegalArgumentException("Unsupported operator: " + expression.getOperator());
+ }
}
}
diff --git a/src/main/java/org/zwobble/couscous/interpreter/Interpreter.java b/src/main/java/org/zwobble/couscous/interpreter/Interpreter.java
index e5f6482..95510cd 100644
--- a/src/main/java/org/zwobble/couscous/interpreter/Interpreter.java
+++ b/src/main/java/org/zwobble/couscous/interpreter/Interpreter.java
@@ -2,14 +2,12 @@ package org.zwobble.couscous.interpreter;
import java.util.List;
import java.util.Optional;
-import java.util.stream.Collectors;
+
import org.zwobble.couscous.ast.TypeName;
-import org.zwobble.couscous.ast.ExpressionNode;
+import org.zwobble.couscous.interpreter.values.ConcreteType;
import org.zwobble.couscous.interpreter.values.InterpreterValue;
+
import com.google.common.collect.ImmutableMap;
-import static org.zwobble.couscous.ast.LiteralNode.literal;
-import static org.zwobble.couscous.ast.StaticMethodCallNode.staticMethodCall;
-import static org.zwobble.couscous.interpreter.Evaluator.eval;
public class Interpreter {
private Project project;
@@ -19,14 +17,12 @@ public class Interpreter {
}
public InterpreterValue run(TypeName className, String methodName, List<InterpreterValue> arguments) {
- List<ExpressionNode> argumentExpressions = arguments.stream()
- .map(argument -> literal(argument.toPrimitiveValue().get()))
- .collect(Collectors.toList());
- return eval(
- new Environment(
- project,
- Optional.empty(),
- ImmutableMap.of()),
- staticMethodCall(className, methodName, argumentExpressions));
+ final Environment environment = new Environment(
+ project,
+ Optional.empty(),
+ ImmutableMap.of());
+
+ ConcreteType clazz = environment.findClass(className);
+ return clazz.callStaticMethod(environment, methodName, arguments);
}
} \ No newline at end of file
diff --git a/src/main/java/org/zwobble/couscous/interpreter/JavaProject.java b/src/main/java/org/zwobble/couscous/interpreter/JavaProject.java
index e6b6df1..50e4508 100644
--- a/src/main/java/org/zwobble/couscous/interpreter/JavaProject.java
+++ b/src/main/java/org/zwobble/couscous/interpreter/JavaProject.java
@@ -5,12 +5,18 @@ import java.util.List;
import org.zwobble.couscous.ast.ClassNode;
import org.zwobble.couscous.interpreter.values.BoxedIntegerInterpreterValue;
import org.zwobble.couscous.interpreter.values.ConcreteType;
+import org.zwobble.couscous.interpreter.values.InternalCouscousInterpeterValue;
import com.google.common.collect.Iterables;
public class JavaProject {
+ private static final ConcreteType OBJECT_TYPE = ConcreteType.classBuilder("java.lang.Object")
+ .build();
+
public static MapBackedProject.Builder builder() {
return MapBackedProject.builder()
+ .addClass(InternalCouscousInterpeterValue.TYPE)
+ .addClass(OBJECT_TYPE)
.addClass(BoxedIntegerInterpreterValue.TYPE);
}
diff --git a/src/main/java/org/zwobble/couscous/interpreter/values/InternalCouscousInterpeterValue.java b/src/main/java/org/zwobble/couscous/interpreter/values/InternalCouscousInterpeterValue.java
new file mode 100644
index 0000000..30645d6
--- /dev/null
+++ b/src/main/java/org/zwobble/couscous/interpreter/values/InternalCouscousInterpeterValue.java
@@ -0,0 +1,14 @@
+package org.zwobble.couscous.interpreter.values;
+
+import org.zwobble.couscous.values.ObjectValue;
+
+import static java.util.Arrays.asList;
+
+public class InternalCouscousInterpeterValue {
+ public static final ConcreteType TYPE = ConcreteType.classBuilder("_couscous")
+ .staticMethod("same", asList(ObjectValue.REF, ObjectValue.REF),
+ (environment, arguments) ->
+ new BooleanInterpreterValue(arguments.get(0) == arguments.get(1)))
+
+ .build();
+}
diff --git a/src/main/java/org/zwobble/couscous/values/InternalCouscousValue.java b/src/main/java/org/zwobble/couscous/values/InternalCouscousValue.java
new file mode 100644
index 0000000..c08104f
--- /dev/null
+++ b/src/main/java/org/zwobble/couscous/values/InternalCouscousValue.java
@@ -0,0 +1,7 @@
+package org.zwobble.couscous.values;
+
+import org.zwobble.couscous.ast.TypeName;
+
+public class InternalCouscousValue {
+ public static final TypeName REF = TypeName.of("_couscous");
+}
diff --git a/src/main/java/org/zwobble/couscous/values/ObjectValue.java b/src/main/java/org/zwobble/couscous/values/ObjectValue.java
new file mode 100644
index 0000000..ea59ae0
--- /dev/null
+++ b/src/main/java/org/zwobble/couscous/values/ObjectValue.java
@@ -0,0 +1,7 @@
+package org.zwobble.couscous.values;
+
+import org.zwobble.couscous.ast.TypeName;
+
+public class ObjectValue {
+ public static final TypeName REF = TypeName.of("java.lang.Object");
+}
diff --git a/src/main/resources/python/runtime/java/lang/Object.py b/src/main/resources/python/runtime/java/lang/Object.py
new file mode 100644
index 0000000..29a8fba
--- /dev/null
+++ b/src/main/resources/python/runtime/java/lang/Object.py
@@ -0,0 +1 @@
+Object = object