aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/org/zwobble/couscous/interpreter/Evaluator.java
diff options
context:
space:
mode:
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()