From f37d49367c1ce59ae35dda124d85f9732d0cb484 Mon Sep 17 00:00:00 2001 From: Uko Kokņevičs Date: Sat, 24 Aug 2024 03:08:23 +0800 Subject: Add tuples. --- .../java/lv/enes/orang/evaluator/EmptyTuple.java | 21 ++++++++++++++++++ .../java/lv/enes/orang/evaluator/Evaluator.java | 24 +++++++++++++++------ .../main/java/lv/enes/orang/evaluator/Nothing.java | 21 ------------------ .../lv/enes/orang/evaluator/PartialFunction.java | 2 +- .../main/java/lv/enes/orang/evaluator/Tuple.java | 25 ++++++++++++++++++++++ .../main/java/lv/enes/orang/evaluator/Value.java | 3 ++- 6 files changed, 66 insertions(+), 30 deletions(-) create mode 100644 evaluator/src/main/java/lv/enes/orang/evaluator/EmptyTuple.java delete mode 100644 evaluator/src/main/java/lv/enes/orang/evaluator/Nothing.java create mode 100644 evaluator/src/main/java/lv/enes/orang/evaluator/Tuple.java (limited to 'evaluator/src/main/java/lv') diff --git a/evaluator/src/main/java/lv/enes/orang/evaluator/EmptyTuple.java b/evaluator/src/main/java/lv/enes/orang/evaluator/EmptyTuple.java new file mode 100644 index 0000000..f8e043b --- /dev/null +++ b/evaluator/src/main/java/lv/enes/orang/evaluator/EmptyTuple.java @@ -0,0 +1,21 @@ +package lv.enes.orang.evaluator; + +import lombok.EqualsAndHashCode; + +@EqualsAndHashCode +public final class EmptyTuple implements Value { + public static final EmptyTuple INSTANCE = new EmptyTuple(); + + private EmptyTuple() { + } + + @Override + public String typeName() { + return "Nothing"; + } + + @Override + public String stringify() { + return "()"; + } +} diff --git a/evaluator/src/main/java/lv/enes/orang/evaluator/Evaluator.java b/evaluator/src/main/java/lv/enes/orang/evaluator/Evaluator.java index 6925bac..f0299b4 100644 --- a/evaluator/src/main/java/lv/enes/orang/evaluator/Evaluator.java +++ b/evaluator/src/main/java/lv/enes/orang/evaluator/Evaluator.java @@ -2,6 +2,7 @@ package lv.enes.orang.evaluator; import lv.enes.orang.ast.*; import lv.enes.orang.core.OrangRuntimeException; +import lv.enes.orang.utils.NonEmptyList; import java.util.ArrayList; import java.util.Collections; @@ -70,6 +71,11 @@ public record Evaluator(Map scope, Value lastResult) implements E return value; } + @Override + public Value visitEmptyTupleExpression() { + return EmptyTuple.INSTANCE; + } + @Override public Evaluator visitExpression(ExpressionStatement expr) throws OrangRuntimeException { return new Evaluator(this.scope(), visit(expr.expr())); @@ -121,6 +127,11 @@ public record Evaluator(Map scope, Value lastResult) implements E return evaluator; } + @Override + public Value visitStringLiteral(StringLiteral expr) { + return new OrangString(expr.value()); + } + @Override public Value visitUnaryExpression(UnaryExpression expr) throws OrangRuntimeException { var child = visit(expr.child()); @@ -132,8 +143,12 @@ public record Evaluator(Map scope, Value lastResult) implements E } @Override - public Value visitStringLiteral(StringLiteral expr) { - return new OrangString(expr.value()); + public Value visitTupleExpression(TupleExpression expr) throws OrangRuntimeException { + var values = new ArrayList(); + for (var tailExpr : expr.children()) { + values.add(visit(tailExpr)); + } + return new Tuple(new NonEmptyList<>(values)); } @Override @@ -144,9 +159,4 @@ public record Evaluator(Map scope, Value lastResult) implements E throw new OrangRuntimeException(STR."Value named \{expr.name()} is not defined!"); } - - @Override - public Value visitVoidExpression() { - return Nothing.INSTANCE; - } } diff --git a/evaluator/src/main/java/lv/enes/orang/evaluator/Nothing.java b/evaluator/src/main/java/lv/enes/orang/evaluator/Nothing.java deleted file mode 100644 index c971649..0000000 --- a/evaluator/src/main/java/lv/enes/orang/evaluator/Nothing.java +++ /dev/null @@ -1,21 +0,0 @@ -package lv.enes.orang.evaluator; - -import lombok.EqualsAndHashCode; - -@EqualsAndHashCode -public final class Nothing implements Value { - public static final Nothing INSTANCE = new Nothing(); - - private Nothing() { - } - - @Override - public String typeName() { - return "Nothing"; - } - - @Override - public String stringify() { - return "()"; - } -} diff --git a/evaluator/src/main/java/lv/enes/orang/evaluator/PartialFunction.java b/evaluator/src/main/java/lv/enes/orang/evaluator/PartialFunction.java index d0125f6..7c0ca20 100644 --- a/evaluator/src/main/java/lv/enes/orang/evaluator/PartialFunction.java +++ b/evaluator/src/main/java/lv/enes/orang/evaluator/PartialFunction.java @@ -15,7 +15,7 @@ public record PartialFunction(Map scope, NonEmptyList re switch (spec.getType()) { case NAMED -> newScope.put(((ArgSpec.Named)spec).name(), param); case NOTHING -> { - if (!(param instanceof Nothing)) { + if (!(param instanceof EmptyTuple)) { throw new OrangRuntimeException(STR."Expected () as a parameter but got \{param.typeName()}"); } } diff --git a/evaluator/src/main/java/lv/enes/orang/evaluator/Tuple.java b/evaluator/src/main/java/lv/enes/orang/evaluator/Tuple.java new file mode 100644 index 0000000..d5a1df5 --- /dev/null +++ b/evaluator/src/main/java/lv/enes/orang/evaluator/Tuple.java @@ -0,0 +1,25 @@ +package lv.enes.orang.evaluator; + +import lv.enes.orang.utils.NonEmptyList; + +public record Tuple(NonEmptyList contents) implements Value { + @Override + public String typeName() { + var sb = new StringBuilder("("); + sb.append(contents.getFirst().typeName()); + for (var i = 1; i < contents.size(); i++) { + sb.append(", ").append(contents.get(i).typeName()); + } + return sb.append(")").toString(); + } + + @Override + public String stringify() { + var sb = new StringBuilder("("); + sb.append(contents.getFirst().stringify()); + for (var i = 1; i < contents.size(); i++) { + sb.append(", ").append(contents.get(i).stringify()); + } + return sb.append(")").toString(); + } +} diff --git a/evaluator/src/main/java/lv/enes/orang/evaluator/Value.java b/evaluator/src/main/java/lv/enes/orang/evaluator/Value.java index d8c8b9c..2ef5136 100644 --- a/evaluator/src/main/java/lv/enes/orang/evaluator/Value.java +++ b/evaluator/src/main/java/lv/enes/orang/evaluator/Value.java @@ -3,7 +3,8 @@ package lv.enes.orang.evaluator; import lv.enes.orang.core.OrangRuntimeException; public sealed interface Value - permits Array, BuiltinFunction, Function, Nothing, OrangBoolean, OrangInteger, OrangString, PartialBuiltinFunction, PartialFunction, Undefined { + permits Array, BuiltinFunction, EmptyTuple, Function, OrangBoolean, OrangInteger, OrangString, + PartialBuiltinFunction, PartialFunction, Tuple, Undefined { String typeName(); String stringify(); -- cgit v1.2.3