aboutsummaryrefslogtreecommitdiff
path: root/src/main/java
diff options
context:
space:
mode:
authorMichael Williamson <mike@zwobble.org>2015-10-31 11:14:31 +0000
committerMichael Williamson <mike@zwobble.org>2015-10-31 11:14:31 +0000
commit5e01b55caf49ddbed0f9abdf8ca6592303001985 (patch)
tree87fc9906f2c8bfd49565797a2de3fe519f5029d9 /src/main/java
parent292834a886ff6a2263ad9878500edec35efb5d60 (diff)
Add evaluation of some int operations
Diffstat (limited to 'src/main/java')
-rw-r--r--src/main/java/org/zwobble/couscous/backends/python/PrimitiveMethods.java35
-rw-r--r--src/main/java/org/zwobble/couscous/backends/python/PythonCodeGenerator.java13
-rw-r--r--src/main/java/org/zwobble/couscous/interpreter/values/IntegerInterpreterValue.java58
3 files changed, 92 insertions, 14 deletions
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 02db3b2..1da18f9 100644
--- a/src/main/java/org/zwobble/couscous/backends/python/PrimitiveMethods.java
+++ b/src/main/java/org/zwobble/couscous/backends/python/PrimitiveMethods.java
@@ -6,11 +6,14 @@ import java.util.Optional;
import org.zwobble.couscous.ast.TypeName;
import org.zwobble.couscous.backends.python.ast.PythonExpressionNode;
+import org.zwobble.couscous.values.IntegerValue;
import org.zwobble.couscous.values.StringValue;
import com.google.common.collect.ImmutableMap;
+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.PythonCallNode.pythonCall;
import static org.zwobble.couscous.backends.python.ast.PythonGetSliceNode.pythonGetSlice;
import static org.zwobble.couscous.backends.python.ast.PythonVariableReferenceNode.pythonVariableReference;
@@ -29,15 +32,45 @@ public class PrimitiveMethods {
.build();
+ private static final Map<String, PrimitiveMethodGenerator> INT_METHODS;
+
+ static {
+ ImmutableMap.Builder<String, PrimitiveMethodGenerator> methods = ImmutableMap.builder();
+
+ addMethod(methods, "add", "__add__");
+ addMethod(methods, "subtract", "__sub__");
+ addMethod(methods, "multiply", "__mul__");
+ addMethod(methods, "divide", "__floordiv__");
+ addMethod(methods, "mod", "__mod__");
+
+ addMethod(methods, "greaterThan", "__gt__");
+ addMethod(methods, "greaterThanOrEqual", "__ge__");
+ addMethod(methods, "lessThan", "__lt__");
+ addMethod(methods, "lessThanOrEqual", "__le__");
+
+ INT_METHODS = methods.build();
+ }
+
+ private static void addMethod(
+ Builder<String, PrimitiveMethodGenerator> methods,
+ String methodName,
+ String pythonMethodName) {
+ methods.put(methodName, (receiver, arguments) ->
+ pythonCall(
+ pythonAttributeAccess(receiver, pythonMethodName),
+ arguments));
+ }
+
private static final Map<TypeName, Map<String, PrimitiveMethodGenerator>> METHODS =
ImmutableMap.<TypeName, Map<String, PrimitiveMethodGenerator>>builder()
.put(StringValue.REF, STRING_METHODS)
+ .put(IntegerValue.REF, INT_METHODS)
.build();
public static boolean isPrimitive(TypeName type) {
return METHODS.containsKey(type);
}
-
+
public static Optional<PrimitiveMethodGenerator> getPrimitiveMethod(TypeName type, String methodName) {
return Optional.ofNullable(METHODS.get(type))
.flatMap(methodsForType -> Optional.ofNullable(methodsForType.get(methodName)));
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 85858ad..a10c54d 100644
--- a/src/main/java/org/zwobble/couscous/backends/python/PythonCodeGenerator.java
+++ b/src/main/java/org/zwobble/couscous/backends/python/PythonCodeGenerator.java
@@ -28,6 +28,7 @@ import org.zwobble.couscous.ast.visitors.ExpressionNodeMapper;
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.PythonBlock;
import org.zwobble.couscous.backends.python.ast.PythonClassNode;
import org.zwobble.couscous.backends.python.ast.PythonExpressionNode;
@@ -65,8 +66,6 @@ import static org.zwobble.couscous.backends.python.ast.PythonStringLiteralNode.p
import static org.zwobble.couscous.backends.python.ast.PythonVariableReferenceNode.pythonVariableReference;
public class PythonCodeGenerator {
-
-
public static PythonModuleNode generateCode(ClassNode classNode) {
Iterator<org.zwobble.couscous.backends.python.ast.PythonImportNode> imports = generateImports(classNode).iterator();
PythonFunctionDefinitionNode constructor = generateConstructor(classNode.getConstructor());
@@ -155,8 +154,6 @@ public class PythonCodeGenerator {
}
private static class StatementGenerator implements StatementNodeMapper<PythonStatementNode> {
-
-
@Override
public PythonStatementNode visit(ReturnNode returnNode) {
return pythonReturn(generateExpression(returnNode.getValue()));
@@ -188,8 +185,6 @@ public class PythonCodeGenerator {
private static final ExpressionGenerator EXPRESSION_GENERATOR = new ExpressionGenerator();
private static class ExpressionGenerator implements ExpressionNodeMapper<PythonExpressionNode> {
-
-
@Override
public PythonExpressionNode visit(LiteralNode literal) {
return generateCode(literal.getValue());
@@ -217,10 +212,10 @@ public class PythonCodeGenerator {
@Override
public PythonExpressionNode visit(MethodCallNode methodCall) {
- final org.zwobble.couscous.backends.python.ast.PythonExpressionNode receiver = generateExpression(methodCall.getReceiver());
- final java.util.List<org.zwobble.couscous.backends.python.ast.PythonExpressionNode> arguments = generateExpressions(methodCall.getArguments());
+ PythonExpressionNode receiver = generateExpression(methodCall.getReceiver());
+ List<PythonExpressionNode> arguments = generateExpressions(methodCall.getArguments());
if (isPrimitive(methodCall.getReceiver())) {
- final org.zwobble.couscous.backends.python.PrimitiveMethods.PrimitiveMethodGenerator primitiveMethodGenerator = PrimitiveMethods.getPrimitiveMethod(methodCall.getReceiver().getType(), methodCall.getMethodName()).get();
+ PrimitiveMethodGenerator primitiveMethodGenerator = PrimitiveMethods.getPrimitiveMethod(methodCall.getReceiver().getType(), methodCall.getMethodName()).get();
return primitiveMethodGenerator.generate(receiver, arguments);
} else {
return pythonCall(pythonAttributeAccess(receiver, methodCall.getMethodName()), arguments);
diff --git a/src/main/java/org/zwobble/couscous/interpreter/values/IntegerInterpreterValue.java b/src/main/java/org/zwobble/couscous/interpreter/values/IntegerInterpreterValue.java
index bd214cb..823e873 100644
--- a/src/main/java/org/zwobble/couscous/interpreter/values/IntegerInterpreterValue.java
+++ b/src/main/java/org/zwobble/couscous/interpreter/values/IntegerInterpreterValue.java
@@ -1,6 +1,9 @@
package org.zwobble.couscous.interpreter.values;
import java.util.Optional;
+import java.util.function.BiFunction;
+
+import org.zwobble.couscous.interpreter.Environment;
import org.zwobble.couscous.interpreter.NoSuchField;
import org.zwobble.couscous.values.IntegerValue;
import org.zwobble.couscous.values.PrimitiveValue;
@@ -9,10 +12,57 @@ import org.zwobble.couscous.values.StringValue;
import static java.util.Arrays.asList;
public final class IntegerInterpreterValue implements InterpreterValue {
- public static final ConcreteType TYPE = ConcreteType.builder(IntegerInterpreterValue.class, IntegerValue.REF).staticMethod("parseInt", asList(StringValue.REF), (environment, arguments) -> {
- StringInterpreterValue value = (StringInterpreterValue)arguments.get(0);
- return new IntegerInterpreterValue(Integer.parseInt(value.getValue()));
- }).build();
+ public static final ConcreteType TYPE = ConcreteType.builder(IntegerInterpreterValue.class, IntegerValue.REF)
+ .staticMethod("parseInt", asList(StringValue.REF), (environment, arguments) -> {
+ StringInterpreterValue value = (StringInterpreterValue)arguments.get(0);
+ return new IntegerInterpreterValue(Integer.parseInt(value.getValue()));
+ })
+ .method("add", asList(IntegerValue.REF),
+ infixReturningInteger((left, right) -> left + right))
+ .method("subtract", asList(IntegerValue.REF),
+ infixReturningInteger((left, right) -> left - right))
+ .method("multiply", asList(IntegerValue.REF),
+ infixReturningInteger((left, right) -> left * right))
+ .method("divide", asList(IntegerValue.REF),
+ infixReturningInteger((left, right) -> left / right))
+ .method("mod", asList(IntegerValue.REF),
+ infixReturningInteger((left, right) -> left % right))
+ .method("greaterThan", asList(IntegerValue.REF),
+ infixReturningBoolean((left, right) -> left > right))
+ .method("greaterThanOrEqual", asList(IntegerValue.REF),
+ infixReturningBoolean((left, right) -> left >= right))
+ .method("lessThan", asList(IntegerValue.REF),
+ infixReturningBoolean((left, right) -> left < right))
+ .method("lessThanOrEqual", asList(IntegerValue.REF),
+ infixReturningBoolean((left, right) -> left <= right))
+ .build();
+
+ private static
+ BiFunction<Environment, MethodCallArguments<IntegerInterpreterValue>, InterpreterValue>
+ infixReturningInteger(BiFunction<Integer, Integer, Integer> func) {
+ return infix((left, right) -> {
+ return new IntegerInterpreterValue(func.apply(left, right));
+ });
+ }
+
+ private static
+ BiFunction<Environment, MethodCallArguments<IntegerInterpreterValue>, InterpreterValue>
+ infixReturningBoolean(BiFunction<Integer, Integer, Boolean> func) {
+ return infix((left, right) -> {
+ return new BooleanInterpreterValue(func.apply(left, right));
+ });
+ }
+
+ private static
+ BiFunction<Environment, MethodCallArguments<IntegerInterpreterValue>, InterpreterValue>
+ infix(BiFunction<Integer, Integer, InterpreterValue> func) {
+ return (environment, arguments) -> {
+ IntegerInterpreterValue left = arguments.getReceiver();
+ IntegerInterpreterValue right = (IntegerInterpreterValue) arguments.get(0);
+ return func.apply(left.getValue(), right.getValue());
+ };
+ }
+
private final int value;
@Override