aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/main/java/org/zwobble/couscous/ast/AssignmentNode.java6
-rw-r--r--src/main/java/org/zwobble/couscous/ast/ExpressionNode.java2
-rw-r--r--src/main/java/org/zwobble/couscous/ast/LiteralNode.java15
-rw-r--r--src/main/java/org/zwobble/couscous/ast/MethodCallNode.java12
-rw-r--r--src/main/java/org/zwobble/couscous/ast/StaticMethodCallNode.java6
-rw-r--r--src/main/java/org/zwobble/couscous/ast/TernaryConditionalNode.java6
-rw-r--r--src/main/java/org/zwobble/couscous/ast/VariableReferenceNode.java6
-rw-r--r--src/main/java/org/zwobble/couscous/values/BooleanValue.java9
-rw-r--r--src/main/java/org/zwobble/couscous/values/IntegerValue.java5
-rw-r--r--src/main/java/org/zwobble/couscous/values/PrimitiveValue.java1
-rw-r--r--src/main/java/org/zwobble/couscous/values/StringValue.java5
-rw-r--r--src/main/java/org/zwobble/couscous/values/UnitValue.java7
-rw-r--r--src/test/java/org/zwobble/couscous/tests/BackendEvalTests.java8
-rw-r--r--src/test/java/org/zwobble/couscous/tests/interpreter/EvaluatorTests.java25
14 files changed, 99 insertions, 14 deletions
diff --git a/src/main/java/org/zwobble/couscous/ast/AssignmentNode.java b/src/main/java/org/zwobble/couscous/ast/AssignmentNode.java
index 861e847..8989ef3 100644
--- a/src/main/java/org/zwobble/couscous/ast/AssignmentNode.java
+++ b/src/main/java/org/zwobble/couscous/ast/AssignmentNode.java
@@ -1,6 +1,7 @@
package org.zwobble.couscous.ast;
import org.zwobble.couscous.ast.visitors.ExpressionNodeVisitor;
+import org.zwobble.couscous.values.TypeReference;
import static org.zwobble.couscous.ast.VariableReferenceNode.reference;
@@ -19,4 +20,9 @@ public class AssignmentNode implements ExpressionNode {
public <T> T accept(ExpressionNodeVisitor<T> visitor) {
return visitor.visit(this);
}
+
+ @Override
+ public TypeReference getType() {
+ return value.getType();
+ }
}
diff --git a/src/main/java/org/zwobble/couscous/ast/ExpressionNode.java b/src/main/java/org/zwobble/couscous/ast/ExpressionNode.java
index 097377a..bc27a99 100644
--- a/src/main/java/org/zwobble/couscous/ast/ExpressionNode.java
+++ b/src/main/java/org/zwobble/couscous/ast/ExpressionNode.java
@@ -1,7 +1,9 @@
package org.zwobble.couscous.ast;
import org.zwobble.couscous.ast.visitors.ExpressionNodeVisitor;
+import org.zwobble.couscous.values.TypeReference;
public interface ExpressionNode {
+ TypeReference getType();
<T> T accept(ExpressionNodeVisitor<T> visitor);
}
diff --git a/src/main/java/org/zwobble/couscous/ast/LiteralNode.java b/src/main/java/org/zwobble/couscous/ast/LiteralNode.java
index 05a599c..2d77cd4 100644
--- a/src/main/java/org/zwobble/couscous/ast/LiteralNode.java
+++ b/src/main/java/org/zwobble/couscous/ast/LiteralNode.java
@@ -1,31 +1,36 @@
package org.zwobble.couscous.ast;
import org.zwobble.couscous.ast.visitors.ExpressionNodeVisitor;
+import org.zwobble.couscous.values.BooleanValue;
+import org.zwobble.couscous.values.IntegerValue;
import org.zwobble.couscous.values.PrimitiveValue;
+import org.zwobble.couscous.values.StringValue;
+import org.zwobble.couscous.values.TypeReference;
import static org.zwobble.couscous.values.PrimitiveValues.value;
import lombok.Value;
-@Value
+@Value(staticConstructor="of")
public class LiteralNode implements ExpressionNode {
public static LiteralNode literal(PrimitiveValue value) {
- return new LiteralNode(value);
+ return new LiteralNode(value, value.getType());
}
public static LiteralNode literal(String value) {
- return new LiteralNode(value(value));
+ return new LiteralNode(value(value), StringValue.REF);
}
public static LiteralNode literal(int value) {
- return new LiteralNode(value(value));
+ return new LiteralNode(value(value), IntegerValue.REF);
}
public static LiteralNode literal(boolean value) {
- return new LiteralNode(value(value));
+ return new LiteralNode(value(value), BooleanValue.REF);
}
PrimitiveValue value;
+ TypeReference type;
@Override
public <T> T accept(ExpressionNodeVisitor<T> visitor) {
diff --git a/src/main/java/org/zwobble/couscous/ast/MethodCallNode.java b/src/main/java/org/zwobble/couscous/ast/MethodCallNode.java
index 09058fc..f240971 100644
--- a/src/main/java/org/zwobble/couscous/ast/MethodCallNode.java
+++ b/src/main/java/org/zwobble/couscous/ast/MethodCallNode.java
@@ -3,8 +3,7 @@ package org.zwobble.couscous.ast;
import java.util.List;
import org.zwobble.couscous.ast.visitors.ExpressionNodeVisitor;
-
-import static java.util.Arrays.asList;
+import org.zwobble.couscous.values.TypeReference;
import lombok.Value;
@@ -13,9 +12,14 @@ public class MethodCallNode implements ExpressionNode {
ExpressionNode receiver;
String methodName;
List<ExpressionNode> arguments;
+ TypeReference type;
- public static MethodCallNode methodCall(ExpressionNode receiver, String methodName, ExpressionNode... arguments) {
- return new MethodCallNode(receiver, methodName, asList(arguments));
+ public static MethodCallNode methodCall(
+ ExpressionNode receiver,
+ String methodName,
+ List<ExpressionNode> arguments,
+ TypeReference type) {
+ return new MethodCallNode(receiver, methodName, arguments, type);
}
@Override
diff --git a/src/main/java/org/zwobble/couscous/ast/StaticMethodCallNode.java b/src/main/java/org/zwobble/couscous/ast/StaticMethodCallNode.java
index 4f1e9ff..0228514 100644
--- a/src/main/java/org/zwobble/couscous/ast/StaticMethodCallNode.java
+++ b/src/main/java/org/zwobble/couscous/ast/StaticMethodCallNode.java
@@ -3,6 +3,7 @@ package org.zwobble.couscous.ast;
import java.util.List;
import org.zwobble.couscous.ast.visitors.ExpressionNodeVisitor;
+import org.zwobble.couscous.values.TypeReference;
import static java.util.Arrays.asList;
@@ -26,4 +27,9 @@ public class StaticMethodCallNode implements ExpressionNode {
public <T> T accept(ExpressionNodeVisitor<T> visitor) {
return visitor.visit(this);
}
+
+ @Override
+ public TypeReference getType() {
+ throw new UnsupportedOperationException();
+ }
}
diff --git a/src/main/java/org/zwobble/couscous/ast/TernaryConditionalNode.java b/src/main/java/org/zwobble/couscous/ast/TernaryConditionalNode.java
index 0386a32..8b30024 100644
--- a/src/main/java/org/zwobble/couscous/ast/TernaryConditionalNode.java
+++ b/src/main/java/org/zwobble/couscous/ast/TernaryConditionalNode.java
@@ -1,6 +1,7 @@
package org.zwobble.couscous.ast;
import org.zwobble.couscous.ast.visitors.ExpressionNodeVisitor;
+import org.zwobble.couscous.values.TypeReference;
import lombok.Value;
@@ -14,4 +15,9 @@ public class TernaryConditionalNode implements ExpressionNode {
public <T> T accept(ExpressionNodeVisitor<T> visitor) {
return visitor.visit(this);
}
+
+ @Override
+ public TypeReference getType() {
+ return ifTrue.getType();
+ }
}
diff --git a/src/main/java/org/zwobble/couscous/ast/VariableReferenceNode.java b/src/main/java/org/zwobble/couscous/ast/VariableReferenceNode.java
index afd3918..5499d50 100644
--- a/src/main/java/org/zwobble/couscous/ast/VariableReferenceNode.java
+++ b/src/main/java/org/zwobble/couscous/ast/VariableReferenceNode.java
@@ -1,6 +1,7 @@
package org.zwobble.couscous.ast;
import org.zwobble.couscous.ast.visitors.ExpressionNodeVisitor;
+import org.zwobble.couscous.values.TypeReference;
import lombok.Value;
@@ -20,4 +21,9 @@ public class VariableReferenceNode implements ExpressionNode {
public int getReferentId() {
return referent.getId();
}
+
+ @Override
+ public TypeReference getType() {
+ return referent.getType();
+ }
}
diff --git a/src/main/java/org/zwobble/couscous/values/BooleanValue.java b/src/main/java/org/zwobble/couscous/values/BooleanValue.java
index e05c246..76f828e 100644
--- a/src/main/java/org/zwobble/couscous/values/BooleanValue.java
+++ b/src/main/java/org/zwobble/couscous/values/BooleanValue.java
@@ -1,11 +1,15 @@
package org.zwobble.couscous.values;
+import static org.zwobble.couscous.values.TypeReference.typeRef;
+
import lombok.AccessLevel;
import lombok.Getter;
import lombok.Value;
@Value
public class BooleanValue implements PrimitiveValue {
+ public static final TypeReference REF = typeRef("java.lang.Boolean");
+
@Getter(value = AccessLevel.NONE)
boolean value;
@@ -17,4 +21,9 @@ public class BooleanValue implements PrimitiveValue {
public <T> T accept(PrimitiveValueVisitor<T> visitor) {
return visitor.visit(this);
}
+
+ @Override
+ public TypeReference getType() {
+ return REF;
+ }
}
diff --git a/src/main/java/org/zwobble/couscous/values/IntegerValue.java b/src/main/java/org/zwobble/couscous/values/IntegerValue.java
index 71c7a41..5c272a0 100644
--- a/src/main/java/org/zwobble/couscous/values/IntegerValue.java
+++ b/src/main/java/org/zwobble/couscous/values/IntegerValue.java
@@ -14,4 +14,9 @@ public class IntegerValue implements PrimitiveValue {
public <T> T accept(PrimitiveValueVisitor<T> visitor) {
return visitor.visit(this);
}
+
+ @Override
+ public TypeReference getType() {
+ return REF;
+ }
}
diff --git a/src/main/java/org/zwobble/couscous/values/PrimitiveValue.java b/src/main/java/org/zwobble/couscous/values/PrimitiveValue.java
index 2cfe40a..56da066 100644
--- a/src/main/java/org/zwobble/couscous/values/PrimitiveValue.java
+++ b/src/main/java/org/zwobble/couscous/values/PrimitiveValue.java
@@ -2,4 +2,5 @@ package org.zwobble.couscous.values;
public interface PrimitiveValue {
<T> T accept(PrimitiveValueVisitor<T> visitor);
+ TypeReference getType();
}
diff --git a/src/main/java/org/zwobble/couscous/values/StringValue.java b/src/main/java/org/zwobble/couscous/values/StringValue.java
index 256d6d1..ba0b1b5 100644
--- a/src/main/java/org/zwobble/couscous/values/StringValue.java
+++ b/src/main/java/org/zwobble/couscous/values/StringValue.java
@@ -14,4 +14,9 @@ public class StringValue implements PrimitiveValue {
public <T> T accept(PrimitiveValueVisitor<T> visitor) {
return visitor.visit(this);
}
+
+ @Override
+ public TypeReference getType() {
+ return REF;
+ }
}
diff --git a/src/main/java/org/zwobble/couscous/values/UnitValue.java b/src/main/java/org/zwobble/couscous/values/UnitValue.java
index 14bf327..b4f6974 100644
--- a/src/main/java/org/zwobble/couscous/values/UnitValue.java
+++ b/src/main/java/org/zwobble/couscous/values/UnitValue.java
@@ -1,6 +1,8 @@
package org.zwobble.couscous.values;
public class UnitValue implements PrimitiveValue {
+ public static final TypeReference REF = TypeReference.typeRef("org.zwobble.couscous.runtime.Unit");
+
static final UnitValue UNIT = new UnitValue();
private UnitValue() {
@@ -10,4 +12,9 @@ public class UnitValue implements PrimitiveValue {
public <T> T accept(PrimitiveValueVisitor<T> visitor) {
return visitor.visit(this);
}
+
+ @Override
+ public TypeReference getType() {
+ return REF;
+ }
}
diff --git a/src/test/java/org/zwobble/couscous/tests/BackendEvalTests.java b/src/test/java/org/zwobble/couscous/tests/BackendEvalTests.java
index 68e9761..c6b7ba2 100644
--- a/src/test/java/org/zwobble/couscous/tests/BackendEvalTests.java
+++ b/src/test/java/org/zwobble/couscous/tests/BackendEvalTests.java
@@ -3,8 +3,10 @@ package org.zwobble.couscous.tests;
import org.junit.Test;
import org.zwobble.couscous.ast.ExpressionNode;
import org.zwobble.couscous.ast.TernaryConditionalNode;
+import org.zwobble.couscous.values.IntegerValue;
import org.zwobble.couscous.values.PrimitiveValue;
+import static java.util.Arrays.asList;
import static org.junit.Assert.assertEquals;
import static org.zwobble.couscous.ast.LiteralNode.literal;
import static org.zwobble.couscous.ast.MethodCallNode.methodCall;
@@ -35,7 +37,11 @@ public abstract class BackendEvalTests {
@Test
public void canCallMethodWithNoArgumentsOnBuiltin() {
- val result = evalExpression(methodCall(literal("hello"), "length"));
+ val result = evalExpression(methodCall(
+ literal("hello"),
+ "length",
+ asList(),
+ IntegerValue.REF));
assertEquals(value(5), result);
}
diff --git a/src/test/java/org/zwobble/couscous/tests/interpreter/EvaluatorTests.java b/src/test/java/org/zwobble/couscous/tests/interpreter/EvaluatorTests.java
index 766cf3c..fab65ef 100644
--- a/src/test/java/org/zwobble/couscous/tests/interpreter/EvaluatorTests.java
+++ b/src/test/java/org/zwobble/couscous/tests/interpreter/EvaluatorTests.java
@@ -24,6 +24,7 @@ import org.zwobble.couscous.values.StringValue;
import com.google.common.collect.ImmutableMap;
+import static java.util.Arrays.asList;
import static org.junit.Assert.assertEquals;
import static org.zwobble.couscous.ast.AssignmentNode.assign;
import static org.zwobble.couscous.ast.FormalArgumentNode.formalArg;
@@ -59,7 +60,11 @@ public class EvaluatorTests extends BackendEvalTests {
@Test
public void canCallMethodWithArgumentsOnBuiltin() {
val result = eval(emptyEnvironment(),
- methodCall(literal("hello"), "substring", literal(1), literal(4)));
+ methodCall(
+ literal("hello"),
+ "substring",
+ asList(literal(1), literal(4)),
+ StringValue.REF));
assertEquals(new StringInterpreterValue("ell"), result);
}
@@ -67,7 +72,11 @@ public class EvaluatorTests extends BackendEvalTests {
public void errorIfMethodDoesNotExist() {
val exception = assertThrows(NoSuchMethod.class,
() -> eval(emptyEnvironment(),
- methodCall(literal("hello"), "size")));
+ methodCall(
+ literal("hello"),
+ "size",
+ asList(),
+ IntegerValue.REF)));
assertEquals(new NoSuchMethod("size"), exception);
}
@@ -75,7 +84,11 @@ public class EvaluatorTests extends BackendEvalTests {
public void errorIfWrongNumberOfArgumentsArePassed() {
val exception = assertThrows(WrongNumberOfArguments.class,
() -> eval(emptyEnvironment(),
- methodCall(literal("hello"), "substring", literal(1))));
+ methodCall(
+ literal("hello"),
+ "substring",
+ asList(literal(1)),
+ StringValue.REF)));
assertEquals(new WrongNumberOfArguments(2, 1), exception);
}
@@ -83,7 +96,11 @@ public class EvaluatorTests extends BackendEvalTests {
public void errorIfArgumentIsWrongType() {
val exception = assertThrows(UnexpectedValueType.class,
() -> eval(emptyEnvironment(),
- methodCall(literal("hello"), "substring", literal(0), literal(""))));
+ methodCall(
+ literal("hello"),
+ "substring",
+ asList(literal(0), literal("")),
+ StringValue.REF)));
assertEquals(new UnexpectedValueType(IntegerValue.REF, StringValue.REF), exception);
}