From fd0769bde1ffad49ca74a404f18aae5d7226c558 Mon Sep 17 00:00:00 2001 From: Michael Williamson Date: Fri, 1 Jan 2016 15:33:57 +0000 Subject: Get interpreter compiler tests working --- .../values/BoxedIntegerInterpreterValue.java | 18 +++++++++- .../couscous/interpreter/values/ConcreteType.java | 38 +++++++++++++++++----- .../values/IntegerInterpreterValue.java | 6 ++++ .../values/InternalCouscousInterpreterValue.java | 6 ++-- 4 files changed, 56 insertions(+), 12 deletions(-) (limited to 'src/main/java/org/zwobble/couscous/interpreter/values') diff --git a/src/main/java/org/zwobble/couscous/interpreter/values/BoxedIntegerInterpreterValue.java b/src/main/java/org/zwobble/couscous/interpreter/values/BoxedIntegerInterpreterValue.java index 458eca7..3ffa244 100644 --- a/src/main/java/org/zwobble/couscous/interpreter/values/BoxedIntegerInterpreterValue.java +++ b/src/main/java/org/zwobble/couscous/interpreter/values/BoxedIntegerInterpreterValue.java @@ -1,16 +1,32 @@ package org.zwobble.couscous.interpreter.values; +import org.zwobble.couscous.ast.Operator; +import org.zwobble.couscous.values.IntegerValue; +import org.zwobble.couscous.values.ObjectValues; import org.zwobble.couscous.values.StringValue; import static java.util.Arrays.asList; public class BoxedIntegerInterpreterValue { public static final ConcreteType TYPE = ConcreteType.classBuilder("java.lang.Integer") + .field("value", IntegerValue.REF) + .staticMethod("parseInt", asList(StringValue.REF), (environment, arguments) -> { StringInterpreterValue value = (StringInterpreterValue)arguments.get(0); return new IntegerInterpreterValue(Integer.parseInt(value.getValue())); }) - + + .method(Operator.EQUALS.getMethodName(), asList(ObjectValues.OBJECT), + (environment, arguments) -> { + InterpreterValue right = arguments.getPositionalArguments().get(0); + if (right.getType().getName().equals(ObjectValues.BOXED_INT)) { + IntegerInterpreterValue leftValue = (IntegerInterpreterValue)arguments.getReceiver().getField("value"); + IntegerInterpreterValue rightValue = (IntegerInterpreterValue)right.getField("value"); + return new BooleanInterpreterValue(leftValue.getValue() == rightValue.getValue()); + } else { + return new BooleanInterpreterValue(false); + } + }) .build(); } diff --git a/src/main/java/org/zwobble/couscous/interpreter/values/ConcreteType.java b/src/main/java/org/zwobble/couscous/interpreter/values/ConcreteType.java index 8d2c2d5..c053739 100644 --- a/src/main/java/org/zwobble/couscous/interpreter/values/ConcreteType.java +++ b/src/main/java/org/zwobble/couscous/interpreter/values/ConcreteType.java @@ -1,8 +1,6 @@ package org.zwobble.couscous.interpreter.values; -import java.util.List; -import java.util.Map; -import java.util.Optional; +import java.util.*; import java.util.function.BiFunction; import java.util.stream.Collectors; import org.zwobble.couscous.ast.ClassNode; @@ -34,6 +32,7 @@ public class ConcreteType { } public static class Builder { + private final ImmutableMap.Builder fields = ImmutableMap.builder(); private final ImmutableMap.Builder methods = ImmutableMap.builder(); private final ImmutableMap.Builder staticMethods = ImmutableMap.builder(); private final Class interpreterValueType; @@ -43,7 +42,12 @@ public class ConcreteType { this.interpreterValueType = interpreterValueType; this.name = name; } - + + public Builder field(String name, TypeName type) { + fields.put(name, new FieldValue(name, type)); + return this; + } + public Builder method(String name, List argumentsTypes, BiFunction, InterpreterValue> method) { methods.put(name, new MethodValue(argumentsTypes, (environment, arguments) -> { return Casts.tryCast(interpreterValueType, arguments.getReceiver()).map(typedReceiver -> method.apply(environment, MethodCallArguments.of(typedReceiver, arguments.getPositionalArguments()))).orElseThrow(() -> new RuntimeException("receiver is of wrong type")); @@ -57,7 +61,13 @@ public class ConcreteType { } public ConcreteType build() { - return new ConcreteType(name, ImmutableMap.of(), new MethodValue(ImmutableList.of(), (environment, arguments) -> InterpreterValues.UNIT), methods.build(), staticMethods.build()); + return new ConcreteType( + name, + Collections.emptySet(), + fields.build(), + new MethodValue(ImmutableList.of(), (environment, arguments) -> InterpreterValues.UNIT), + methods.build(), + staticMethods.build()); } } @@ -76,20 +86,28 @@ public class ConcreteType { return Executor.callMethod(environment, method, Optional.empty(), arguments); }); })); - return new ConcreteType(classNode.getName(), fields, constructor, methods, staticMethods); + return new ConcreteType(classNode.getName(), classNode.getSuperTypes(), fields, constructor, methods, staticMethods); } private static List getArgumentTypes(List arguments) { return arguments.stream().map(arg -> arg.getType()).collect(Collectors.toList()); } private final TypeName name; + private final Set superTypes; private final Map fields; private final MethodValue constructor; private final Map methods; private final Map staticMethods; - private ConcreteType(TypeName name, Map fields, MethodValue constructor, Map methods, Map staticMethods) { + private ConcreteType( + TypeName name, + Set superTypes, + Map fields, + MethodValue constructor, + Map methods, + Map staticMethods) { this.name = name; + this.superTypes = superTypes; this.fields = fields; this.constructor = constructor; this.methods = methods; @@ -99,7 +117,11 @@ public class ConcreteType { public TypeName getName() { return name; } - + + public Set getSuperTypes() { + return superTypes; + } + public Optional getField(String fieldName) { return Optional.ofNullable(fields.get(fieldName)); } 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 da28bc5..3bcb41a 100644 --- a/src/main/java/org/zwobble/couscous/interpreter/values/IntegerInterpreterValue.java +++ b/src/main/java/org/zwobble/couscous/interpreter/values/IntegerInterpreterValue.java @@ -97,6 +97,12 @@ public final class IntegerInterpreterValue implements InterpreterValue { public int getValue() { return this.value; } + + public InterpreterValue box() { + ObjectInterpreterValue box = new ObjectInterpreterValue(BoxedIntegerInterpreterValue.TYPE); + box.setField("value", this); + return box; + } @java.lang.Override public boolean equals(final java.lang.Object o) { diff --git a/src/main/java/org/zwobble/couscous/interpreter/values/InternalCouscousInterpreterValue.java b/src/main/java/org/zwobble/couscous/interpreter/values/InternalCouscousInterpreterValue.java index ef4c37b..4d3f33a 100644 --- a/src/main/java/org/zwobble/couscous/interpreter/values/InternalCouscousInterpreterValue.java +++ b/src/main/java/org/zwobble/couscous/interpreter/values/InternalCouscousInterpreterValue.java @@ -19,10 +19,10 @@ public class InternalCouscousInterpreterValue { ((environment, arguments) -> arguments.get(0))) .staticMethod("boxInt", asList(IntegerValue.REF), - ((environment, arguments) -> arguments.get(0))) + ((environment, arguments) -> ((IntegerInterpreterValue)arguments.get(0)).box())) - .staticMethod("unboxInt", asList(IntegerValue.REF), - ((environment, arguments) -> arguments.get(0))) + .staticMethod("unboxInt", asList(ObjectValues.BOXED_INT), + ((environment, arguments) -> arguments.get(0).getField("value"))) .build(); } -- cgit v1.2.3