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/MethodCallNode.java5
-rw-r--r--src/main/java/org/zwobble/couscous/ast/MethodNode.java3
-rw-r--r--src/main/java/org/zwobble/couscous/ast/MethodSignature.java23
-rw-r--r--src/main/java/org/zwobble/couscous/interpreter/Evaluator.java6
-rw-r--r--src/main/java/org/zwobble/couscous/interpreter/Interpreter.java12
-rw-r--r--src/main/java/org/zwobble/couscous/interpreter/values/BooleanInterpreterValue.java6
-rw-r--r--src/main/java/org/zwobble/couscous/interpreter/values/BoxedIntegerInterpreterValue.java9
-rw-r--r--src/main/java/org/zwobble/couscous/interpreter/values/ConcreteType.java18
-rw-r--r--src/main/java/org/zwobble/couscous/interpreter/values/IntegerInterpreterValue.java23
-rw-r--r--src/main/java/org/zwobble/couscous/interpreter/values/InternalCouscousInterpreterValue.java3
-rw-r--r--src/main/java/org/zwobble/couscous/interpreter/values/StringInterpreterValue.java10
11 files changed, 70 insertions, 48 deletions
diff --git a/src/main/java/org/zwobble/couscous/ast/MethodCallNode.java b/src/main/java/org/zwobble/couscous/ast/MethodCallNode.java
index c284d1f..c4e0321 100644
--- a/src/main/java/org/zwobble/couscous/ast/MethodCallNode.java
+++ b/src/main/java/org/zwobble/couscous/ast/MethodCallNode.java
@@ -78,7 +78,10 @@ public class MethodCallNode implements ExpressionNode {
}
public MethodSignature signature() {
- return new MethodSignature(methodName, eagerMap(arguments, argument -> argument.getType()));
+ return new MethodSignature(
+ methodName,
+ eagerMap(arguments, argument -> argument.getType()),
+ type);
}
@Override
diff --git a/src/main/java/org/zwobble/couscous/ast/MethodNode.java b/src/main/java/org/zwobble/couscous/ast/MethodNode.java
index e0b2432..dd970c5 100644
--- a/src/main/java/org/zwobble/couscous/ast/MethodNode.java
+++ b/src/main/java/org/zwobble/couscous/ast/MethodNode.java
@@ -140,7 +140,8 @@ public class MethodNode implements CallableNode {
public MethodSignature signature() {
return new MethodSignature(
name,
- eagerMap(arguments, argument -> argument.getType()));
+ eagerMap(arguments, argument -> argument.getType()),
+ returnType);
}
public MethodNode mapBody(Function<List<StatementNode>, List<StatementNode>> function) {
diff --git a/src/main/java/org/zwobble/couscous/ast/MethodSignature.java b/src/main/java/org/zwobble/couscous/ast/MethodSignature.java
index fb2dc64..d7bc725 100644
--- a/src/main/java/org/zwobble/couscous/ast/MethodSignature.java
+++ b/src/main/java/org/zwobble/couscous/ast/MethodSignature.java
@@ -1,15 +1,16 @@
package org.zwobble.couscous.ast;
import java.util.List;
-import java.util.Objects;
public class MethodSignature {
- private String name;
- private List<TypeName> arguments;
+ private final String name;
+ private final List<TypeName> arguments;
+ private final TypeName returnType;
- public MethodSignature(String name, List<TypeName> arguments) {
+ public MethodSignature(String name, List<TypeName> arguments, TypeName returnType) {
this.name = name;
this.arguments = arguments;
+ this.returnType = returnType;
}
public String getName() {
@@ -25,6 +26,7 @@ public class MethodSignature {
return "MethodSignature(" +
"name='" + name + '\'' +
", arguments=" + arguments +
+ ", returnType=" + returnType +
')';
}
@@ -32,13 +34,20 @@ public class MethodSignature {
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
+
MethodSignature that = (MethodSignature) o;
- return Objects.equals(name, that.name) &&
- Objects.equals(arguments, that.arguments);
+
+ if (!name.equals(that.name)) return false;
+ if (!arguments.equals(that.arguments)) return false;
+ return returnType.equals(that.returnType);
+
}
@Override
public int hashCode() {
- return Objects.hash(name, arguments);
+ int result = name.hashCode();
+ result = 31 * result + arguments.hashCode();
+ result = 31 * result + returnType.hashCode();
+ return result;
}
}
diff --git a/src/main/java/org/zwobble/couscous/interpreter/Evaluator.java b/src/main/java/org/zwobble/couscous/interpreter/Evaluator.java
index dbb02c8..815bf10 100644
--- a/src/main/java/org/zwobble/couscous/interpreter/Evaluator.java
+++ b/src/main/java/org/zwobble/couscous/interpreter/Evaluator.java
@@ -12,8 +12,6 @@ import org.zwobble.couscous.values.IntegerValue;
import java.util.List;
import java.util.stream.Collectors;
-import static org.zwobble.couscous.util.ExtraLists.eagerMap;
-
public class Evaluator implements ExpressionNodeMapper<InterpreterValue> {
public static InterpreterValue eval(Environment environment, ExpressionNode expression) {
return new Evaluator(environment).eval(expression);
@@ -87,9 +85,7 @@ public class Evaluator implements ExpressionNodeMapper<InterpreterValue> {
@Override
public InterpreterValue visit(MethodCallNode methodCall) {
List<InterpreterValue> arguments = evalArguments(methodCall.getArguments());
- MethodSignature signature = new MethodSignature(
- methodCall.getMethodName(),
- eagerMap(methodCall.getArguments(), argument -> argument.getType()));
+ MethodSignature signature = methodCall.signature();
return methodCall.getReceiver().accept(new Receiver.Mapper<InterpreterValue>() {
@Override
diff --git a/src/main/java/org/zwobble/couscous/interpreter/Interpreter.java b/src/main/java/org/zwobble/couscous/interpreter/Interpreter.java
index da84de0..5493e52 100644
--- a/src/main/java/org/zwobble/couscous/interpreter/Interpreter.java
+++ b/src/main/java/org/zwobble/couscous/interpreter/Interpreter.java
@@ -1,14 +1,13 @@
package org.zwobble.couscous.interpreter;
-import java.util.List;
-import java.util.Optional;
-
+import com.google.common.collect.ImmutableMap;
import org.zwobble.couscous.ast.MethodSignature;
import org.zwobble.couscous.ast.TypeName;
import org.zwobble.couscous.interpreter.values.ConcreteType;
import org.zwobble.couscous.interpreter.values.InterpreterValue;
-import com.google.common.collect.ImmutableMap;
+import java.util.List;
+import java.util.Optional;
import static org.zwobble.couscous.util.ExtraLists.eagerMap;
@@ -19,7 +18,7 @@ public class Interpreter {
this.project = project;
}
- public InterpreterValue run(TypeName className, String methodName, List<InterpreterValue> arguments) {
+ public InterpreterValue run(TypeName className, String methodName, List<InterpreterValue> arguments, TypeName returnType) {
final Environment environment = new Environment(
project,
Optional.empty(),
@@ -28,7 +27,8 @@ public class Interpreter {
ConcreteType clazz = environment.findClass(className);
MethodSignature signature = new MethodSignature(
methodName,
- eagerMap(arguments, argument -> argument.getType().getName()));
+ eagerMap(arguments, argument -> argument.getType().getName()),
+ returnType);
return clazz.callStaticMethod(environment, signature, arguments);
}
} \ No newline at end of file
diff --git a/src/main/java/org/zwobble/couscous/interpreter/values/BooleanInterpreterValue.java b/src/main/java/org/zwobble/couscous/interpreter/values/BooleanInterpreterValue.java
index bb60863..2ac6e3a 100644
--- a/src/main/java/org/zwobble/couscous/interpreter/values/BooleanInterpreterValue.java
+++ b/src/main/java/org/zwobble/couscous/interpreter/values/BooleanInterpreterValue.java
@@ -20,15 +20,15 @@ public final class BooleanInterpreterValue implements InterpreterValue {
private static final ConcreteType TYPE = ConcreteType.builder(BooleanInterpreterValue.class, "boolean")
- .method(Operator.BOOLEAN_NOT.getSymbol(), list(), (environment, arguments) ->
+ .method(Operator.BOOLEAN_NOT.getSymbol(), list(), BooleanValue.REF, (environment, arguments) ->
of(!arguments.getReceiver().getValue()))
- .method(Operator.BOOLEAN_AND.getSymbol(), list(BooleanValue.REF), (environment, arguments) -> {
+ .method(Operator.BOOLEAN_AND.getSymbol(), list(BooleanValue.REF), BooleanValue.REF, (environment, arguments) -> {
BooleanInterpreterValue right = (BooleanInterpreterValue)arguments.get(0);
return of(arguments.getReceiver().getValue() && right.getValue());
})
- .method(Operator.BOOLEAN_OR.getSymbol(), list(BooleanValue.REF), (environment, arguments) -> {
+ .method(Operator.BOOLEAN_OR.getSymbol(), list(BooleanValue.REF), BooleanValue.REF, (environment, arguments) -> {
BooleanInterpreterValue right = (BooleanInterpreterValue)arguments.get(0);
return of(arguments.getReceiver().getValue() || right.getValue());
})
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 2aa7024..951d57d 100644
--- a/src/main/java/org/zwobble/couscous/interpreter/values/BoxedIntegerInterpreterValue.java
+++ b/src/main/java/org/zwobble/couscous/interpreter/values/BoxedIntegerInterpreterValue.java
@@ -1,5 +1,6 @@
package org.zwobble.couscous.interpreter.values;
+import org.zwobble.couscous.values.BooleanValue;
import org.zwobble.couscous.values.IntegerValue;
import org.zwobble.couscous.values.ObjectValues;
import org.zwobble.couscous.values.StringValue;
@@ -20,19 +21,19 @@ public class BoxedIntegerInterpreterValue {
public static final ConcreteType TYPE = ConcreteType.classBuilder("java.lang.Integer")
.field("value", IntegerValue.REF)
- .staticMethod("parseInt", list(StringValue.REF),
+ .staticMethod("parseInt", list(StringValue.REF), IntegerValue.REF,
(environment, arguments) -> {
StringInterpreterValue value = (StringInterpreterValue)arguments.get(0);
return new IntegerInterpreterValue(Integer.parseInt(value.getValue()));
})
- .staticMethod("valueOf", list(IntegerValue.REF),
+ .staticMethod("valueOf", list(IntegerValue.REF), ObjectValues.BOXED_INT,
(environment, arguments) -> {
IntegerInterpreterValue value = (IntegerInterpreterValue)arguments.get(0);
return of(value);
})
- .method("equals", list(ObjectValues.OBJECT),
+ .method("equals", list(ObjectValues.OBJECT), BooleanValue.REF,
(environment, arguments) -> {
InterpreterValue right = arguments.getPositionalArguments().get(0);
if (right.getType().getName().equals(ObjectValues.BOXED_INT)) {
@@ -44,7 +45,7 @@ public class BoxedIntegerInterpreterValue {
}
})
- .method("toString", list(),
+ .method("toString", list(), StringValue.REF,
(environment, arguments) -> {
IntegerInterpreterValue value = (IntegerInterpreterValue)arguments.getReceiver().getField("value");
return StringInterpreterValue.of(Integer.toString(value.getValue()));
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 9a9fde8..41c0445 100644
--- a/src/main/java/org/zwobble/couscous/interpreter/values/ConcreteType.java
+++ b/src/main/java/org/zwobble/couscous/interpreter/values/ConcreteType.java
@@ -54,8 +54,13 @@ public class ConcreteType {
return this;
}
- public Builder<T> method(String name, List<TypeName> argumentsTypes, BiFunction<Environment, MethodCallArguments<T>, InterpreterValue> method) {
- methods.put(new MethodSignature(name, argumentsTypes), toMethodValue(argumentsTypes, method));
+ public Builder<T> method(
+ String name,
+ List<TypeName> argumentsTypes,
+ TypeName returnType,
+ BiFunction<Environment, MethodCallArguments<T>, InterpreterValue> method)
+ {
+ methods.put(new MethodSignature(name, argumentsTypes, returnType), toMethodValue(argumentsTypes, method));
return this;
}
@@ -68,8 +73,13 @@ public class ConcreteType {
.orElseThrow(() -> new RuntimeException("receiver is of wrong type")));
}
- public Builder<T> staticMethod(String name, List<TypeName> argumentsTypes, BiFunction<Environment, PositionalArguments, InterpreterValue> method) {
- staticMethods.put(new MethodSignature(name, argumentsTypes), new StaticMethodValue(argumentsTypes, method));
+ public Builder<T> staticMethod(
+ String name,
+ List<TypeName> argumentsTypes,
+ TypeName returnType,
+ BiFunction<Environment, PositionalArguments, InterpreterValue> method)
+ {
+ staticMethods.put(new MethodSignature(name, argumentsTypes, returnType), new StaticMethodValue(argumentsTypes, method));
return this;
}
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 8c6af74..78da460 100644
--- a/src/main/java/org/zwobble/couscous/interpreter/values/IntegerInterpreterValue.java
+++ b/src/main/java/org/zwobble/couscous/interpreter/values/IntegerInterpreterValue.java
@@ -3,6 +3,7 @@ package org.zwobble.couscous.interpreter.values;
import org.zwobble.couscous.ast.Operator;
import org.zwobble.couscous.interpreter.Environment;
import org.zwobble.couscous.interpreter.errors.NoSuchField;
+import org.zwobble.couscous.values.BooleanValue;
import org.zwobble.couscous.values.IntegerValue;
import org.zwobble.couscous.values.PrimitiveValue;
import org.zwobble.couscous.values.PrimitiveValues;
@@ -14,30 +15,30 @@ import static org.zwobble.couscous.util.ExtraLists.list;
public final class IntegerInterpreterValue implements InterpreterValue {
public static final ConcreteType TYPE = ConcreteType.builder(IntegerInterpreterValue.class, IntegerValue.REF)
- .method(Operator.ADD.getSymbol(), list(IntegerValue.REF),
+ .method(Operator.ADD.getSymbol(), list(IntegerValue.REF), IntegerValue.REF,
infixReturningInteger((left, right) -> left + right))
- .method(Operator.SUBTRACT.getSymbol(), list(IntegerValue.REF),
+ .method(Operator.SUBTRACT.getSymbol(), list(IntegerValue.REF), IntegerValue.REF,
infixReturningInteger((left, right) -> left - right))
- .method(Operator.MULTIPLY.getSymbol(), list(IntegerValue.REF),
+ .method(Operator.MULTIPLY.getSymbol(), list(IntegerValue.REF), IntegerValue.REF,
infixReturningInteger((left, right) -> left * right))
- .method(Operator.DIVIDE.getSymbol(), list(IntegerValue.REF),
+ .method(Operator.DIVIDE.getSymbol(), list(IntegerValue.REF), IntegerValue.REF,
infixReturningInteger((left, right) -> left / right))
- .method(Operator.MOD.getSymbol(), list(IntegerValue.REF),
+ .method(Operator.MOD.getSymbol(), list(IntegerValue.REF), IntegerValue.REF,
infixReturningInteger((left, right) -> left % right))
- .method(Operator.EQUALS.getSymbol(), list(IntegerValue.REF),
+ .method(Operator.EQUALS.getSymbol(), list(IntegerValue.REF), BooleanValue.REF,
(environment, arguments) -> {
IntegerInterpreterValue right = (IntegerInterpreterValue)arguments.getPositionalArguments().get(0);
return integerEquals(arguments, right);
})
- .method(Operator.NOT_EQUALS.getSymbol(), list(IntegerValue.REF),
+ .method(Operator.NOT_EQUALS.getSymbol(), list(IntegerValue.REF), BooleanValue.REF,
infixReturningBoolean((left, right) -> !left.equals(right)))
- .method(Operator.GREATER_THAN.getSymbol(), list(IntegerValue.REF),
+ .method(Operator.GREATER_THAN.getSymbol(), list(IntegerValue.REF), BooleanValue.REF,
infixReturningBoolean((left, right) -> left > right))
- .method(Operator.GREATER_THAN_OR_EQUAL.getSymbol(), list(IntegerValue.REF),
+ .method(Operator.GREATER_THAN_OR_EQUAL.getSymbol(), list(IntegerValue.REF), BooleanValue.REF,
infixReturningBoolean((left, right) -> left >= right))
- .method(Operator.LESS_THAN.getSymbol(), list(IntegerValue.REF),
+ .method(Operator.LESS_THAN.getSymbol(), list(IntegerValue.REF), BooleanValue.REF,
infixReturningBoolean((left, right) -> left < right))
- .method(Operator.LESS_THAN_OR_EQUAL.getSymbol(), list(IntegerValue.REF),
+ .method(Operator.LESS_THAN_OR_EQUAL.getSymbol(), list(IntegerValue.REF), BooleanValue.REF,
infixReturningBoolean((left, right) -> left <= right))
.build();
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 75f8af4..e39f576 100644
--- a/src/main/java/org/zwobble/couscous/interpreter/values/InternalCouscousInterpreterValue.java
+++ b/src/main/java/org/zwobble/couscous/interpreter/values/InternalCouscousInterpreterValue.java
@@ -1,12 +1,13 @@
package org.zwobble.couscous.interpreter.values;
+import org.zwobble.couscous.values.BooleanValue;
import org.zwobble.couscous.values.ObjectValues;
import static org.zwobble.couscous.util.ExtraLists.list;
public class InternalCouscousInterpreterValue {
public static final ConcreteType TYPE = ConcreteType.classBuilder("_couscous")
- .staticMethod("same", list(ObjectValues.OBJECT, ObjectValues.OBJECT),
+ .staticMethod("same", list(ObjectValues.OBJECT, ObjectValues.OBJECT), BooleanValue.REF,
(environment, arguments) ->
BooleanInterpreterValue.of(arguments.get(0) == arguments.get(1)))
diff --git a/src/main/java/org/zwobble/couscous/interpreter/values/StringInterpreterValue.java b/src/main/java/org/zwobble/couscous/interpreter/values/StringInterpreterValue.java
index 55a17cc..ae7d141 100644
--- a/src/main/java/org/zwobble/couscous/interpreter/values/StringInterpreterValue.java
+++ b/src/main/java/org/zwobble/couscous/interpreter/values/StringInterpreterValue.java
@@ -10,24 +10,24 @@ import static org.zwobble.couscous.util.ExtraLists.list;
public final class StringInterpreterValue implements InterpreterValue {
public static final ConcreteType TYPE = ConcreteType.builder(StringInterpreterValue.class, StringValue.REF)
- .method("length", list(), (environment, arguments) ->
+ .method("length", list(), IntegerValue.REF, (environment, arguments) ->
new IntegerInterpreterValue(arguments.getReceiver().value.length()))
- .method("substring", list(IntegerValue.REF, IntegerValue.REF), (environment, arguments) -> {
+ .method("substring", list(IntegerValue.REF, IntegerValue.REF), StringValue.REF, (environment, arguments) -> {
IntegerInterpreterValue startIndex = (IntegerInterpreterValue)arguments.get(0);
IntegerInterpreterValue endIndex = (IntegerInterpreterValue)arguments.get(1);
return of(arguments.getReceiver().value.substring(startIndex.getValue(), endIndex.getValue()));
})
- .method(Operator.ADD.getSymbol(), list(StringValue.REF), (environment, arguments) -> {
+ .method(Operator.ADD.getSymbol(), list(StringValue.REF), StringValue.REF, (environment, arguments) -> {
StringInterpreterValue right = (StringInterpreterValue)arguments.get(0);
return of(arguments.getReceiver().value + right.value);
})
- .method("toLowerCase", list(), (environment, arguments) ->
+ .method("toLowerCase", list(), StringValue.REF, (environment, arguments) ->
of(arguments.getReceiver().value.toLowerCase()))
- .method("equals", list(ObjectValues.OBJECT), (environment, arguments) -> {
+ .method("equals", list(ObjectValues.OBJECT), BooleanValue.REF, (environment, arguments) -> {
InterpreterValue right = arguments.get(0);
if (right instanceof StringInterpreterValue) {
return BooleanInterpreterValue.of(arguments.getReceiver().value.equals(((StringInterpreterValue)right).value));