aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/org/zwobble/couscous/interpreter/Evaluator.java
diff options
context:
space:
mode:
authorMichael Williamson <mike@zwobble.org>2015-10-06 16:24:37 +0100
committerMichael Williamson <mike@zwobble.org>2015-10-06 16:24:37 +0100
commite6f463257720bee91a1b4954d97684dbb3398cbf (patch)
treec8d1f04dfe8928d33361108aefee7e7572dae1c7 /src/main/java/org/zwobble/couscous/interpreter/Evaluator.java
parent9685c8fb7fa14d5b75d828f8443dd948715ac4af (diff)
Add support for constructors and fields
Diffstat (limited to 'src/main/java/org/zwobble/couscous/interpreter/Evaluator.java')
-rw-r--r--src/main/java/org/zwobble/couscous/interpreter/Evaluator.java34
1 files changed, 33 insertions, 1 deletions
diff --git a/src/main/java/org/zwobble/couscous/interpreter/Evaluator.java b/src/main/java/org/zwobble/couscous/interpreter/Evaluator.java
index ee67da0..18d7109 100644
--- a/src/main/java/org/zwobble/couscous/interpreter/Evaluator.java
+++ b/src/main/java/org/zwobble/couscous/interpreter/Evaluator.java
@@ -6,15 +6,20 @@ import java.util.stream.Collectors;
import org.zwobble.couscous.ast.AssignmentNode;
import org.zwobble.couscous.ast.ConstructorCallNode;
import org.zwobble.couscous.ast.ExpressionNode;
+import org.zwobble.couscous.ast.FieldAccessNode;
import org.zwobble.couscous.ast.LiteralNode;
import org.zwobble.couscous.ast.MethodCallNode;
import org.zwobble.couscous.ast.StaticMethodCallNode;
import org.zwobble.couscous.ast.TernaryConditionalNode;
+import org.zwobble.couscous.ast.ThisReferenceNode;
import org.zwobble.couscous.ast.VariableReferenceNode;
+import org.zwobble.couscous.ast.visitors.AssignableExpressionNodeVisitor;
import org.zwobble.couscous.ast.visitors.ExpressionNodeMapper;
import org.zwobble.couscous.interpreter.values.BooleanInterpreterValue;
import org.zwobble.couscous.interpreter.values.InterpreterValue;
import org.zwobble.couscous.interpreter.values.InterpreterValues;
+import org.zwobble.couscous.interpreter.values.ObjectInterpreterValue;
+import org.zwobble.couscous.util.Casts;
import lombok.val;
@@ -44,9 +49,28 @@ public class Evaluator implements ExpressionNodeMapper<InterpreterValue> {
}
@Override
+ public InterpreterValue visit(ThisReferenceNode reference) {
+ return environment.getThis().get();
+ }
+
+ @Override
public InterpreterValue visit(AssignmentNode assignment) {
val value = eval(assignment.getValue());
- environment.put(assignment.getTarget().getReferentId(), value);
+ assignment.getTarget().accept(new AssignableExpressionNodeVisitor() {
+ @Override
+ public void visit(FieldAccessNode fieldAccess) {
+ val maybeLeft = Casts.tryCast(
+ ObjectInterpreterValue.class,
+ eval(fieldAccess.getLeft()));
+ val left = maybeLeft.orElseThrow(() -> new UnsupportedOperationException());
+ left.setField(fieldAccess.getFieldName(), value);
+ }
+
+ @Override
+ public void visit(VariableReferenceNode reference) {
+ environment.put(reference.getReferentId(), value);
+ }
+ });
return value;
}
@@ -84,6 +108,14 @@ public class Evaluator implements ExpressionNodeMapper<InterpreterValue> {
return clazz.callConstructor(environment, arguments);
}
+ @Override
+ public InterpreterValue visit(FieldAccessNode fieldAccess) {
+ // TODO: handle unbound fields
+ // TODO: handle non-existent fields
+ val left = eval(fieldAccess.getLeft());
+ return left.getField(fieldAccess.getFieldName());
+ }
+
private List<InterpreterValue> evalArguments(List<ExpressionNode> arguments) {
return arguments
.stream()