From 97b4f889cd2c3a692da98e681016414587ebf204 Mon Sep 17 00:00:00 2001 From: Uko Kokņevičs Date: Sun, 25 Aug 2024 17:56:34 +0800 Subject: Added maps --- .../main/java/lv/enes/orang/evaluator/Array.java | 6 ++-- .../java/lv/enes/orang/evaluator/Evaluator.java | 11 ++++++ .../java/lv/enes/orang/evaluator/OrangBoolean.java | 8 ++--- .../java/lv/enes/orang/evaluator/OrangInteger.java | 20 +++++------ .../java/lv/enes/orang/evaluator/OrangMap.java | 42 ++++++++++++++++++++++ .../java/lv/enes/orang/evaluator/OrangString.java | 6 ++-- .../main/java/lv/enes/orang/evaluator/Value.java | 10 +++--- 7 files changed, 78 insertions(+), 25 deletions(-) create mode 100644 evaluator/src/main/java/lv/enes/orang/evaluator/OrangMap.java (limited to 'evaluator/src') diff --git a/evaluator/src/main/java/lv/enes/orang/evaluator/Array.java b/evaluator/src/main/java/lv/enes/orang/evaluator/Array.java index ab0d896..265bbd9 100644 --- a/evaluator/src/main/java/lv/enes/orang/evaluator/Array.java +++ b/evaluator/src/main/java/lv/enes/orang/evaluator/Array.java @@ -46,7 +46,7 @@ public record Array(List items) implements Value { newItems.addAll(rhsi); return new Array(Collections.unmodifiableList(newItems)); } else { - throw new OrangRuntimeException(STR."add not implemented for Array and \{rhs.typeName()}"); + return Value.super.add(rhs); } } @@ -58,7 +58,7 @@ public record Array(List items) implements Value { } return items.get(i); } else { - throw new OrangRuntimeException(STR."array access not implemented for Array and \{idx.typeName()}"); + return Value.super.arrayAccess(idx); } } @@ -71,7 +71,7 @@ public record Array(List items) implements Value { } return new Array(Collections.unmodifiableList(newItems)); } else { - throw new OrangRuntimeException(STR."multiply not implemented for Array and \{rhs.typeName()}"); + return Value.super.multiply(rhs); } } } 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 69c03e8..8fd61e8 100644 --- a/evaluator/src/main/java/lv/enes/orang/evaluator/Evaluator.java +++ b/evaluator/src/main/java/lv/enes/orang/evaluator/Evaluator.java @@ -119,6 +119,17 @@ public record Evaluator(Map scope, Value lastResult) implements E return newEvaluator.visit(expr.body()); } + @Override + public Value visitMap(MapExpression expr) throws OrangRuntimeException { + var map = new HashMap(); + for (var entry : expr.entries()) { + var from = visit(entry.from()); + var to = visit(entry.to()); + map.put(from, to); + } + return new OrangMap(Collections.unmodifiableMap(map)); + } + @Override public Evaluator visitProgram(Program prog) throws OrangRuntimeException { var evaluator = this; diff --git a/evaluator/src/main/java/lv/enes/orang/evaluator/OrangBoolean.java b/evaluator/src/main/java/lv/enes/orang/evaluator/OrangBoolean.java index 3564a9c..46c887c 100644 --- a/evaluator/src/main/java/lv/enes/orang/evaluator/OrangBoolean.java +++ b/evaluator/src/main/java/lv/enes/orang/evaluator/OrangBoolean.java @@ -5,8 +5,8 @@ import lv.enes.orang.core.OrangRuntimeException; @EqualsAndHashCode public final class OrangBoolean implements Value { - public final static OrangBoolean TRUE = new OrangBoolean(true); - public final static OrangBoolean FALSE = new OrangBoolean(false); + public static final OrangBoolean TRUE = new OrangBoolean(true); + public static final OrangBoolean FALSE = new OrangBoolean(false); private final boolean value; @@ -45,11 +45,11 @@ public final class OrangBoolean implements Value { } @Override - public OrangBoolean or(Value rhs) throws OrangRuntimeException { + public Value or(Value rhs) throws OrangRuntimeException { if (rhs instanceof OrangBoolean rhsb) { return new OrangBoolean(value || rhsb.value); } else { - throw new OrangRuntimeException(STR."or is not implemented for Boolean and \{rhs.typeName()}"); + return Value.super.or(rhs); } } } diff --git a/evaluator/src/main/java/lv/enes/orang/evaluator/OrangInteger.java b/evaluator/src/main/java/lv/enes/orang/evaluator/OrangInteger.java index 90de0b5..872fce2 100644 --- a/evaluator/src/main/java/lv/enes/orang/evaluator/OrangInteger.java +++ b/evaluator/src/main/java/lv/enes/orang/evaluator/OrangInteger.java @@ -24,47 +24,47 @@ public record OrangInteger(int value) implements Value { } @Override - public OrangInteger add(Value rhs) throws OrangRuntimeException { + public Value add(Value rhs) throws OrangRuntimeException { if (rhs instanceof OrangInteger(int rhsi)) { return new OrangInteger(value + rhsi); } else { - throw new OrangRuntimeException(STR."add is not implemented for Integer and \{rhs.typeName()}"); + return Value.super.add(rhs); } } @Override - public OrangInteger divide(Value rhs) throws OrangRuntimeException { + public Value divide(Value rhs) throws OrangRuntimeException { if (rhs instanceof OrangInteger(int rhsi)) { return new OrangInteger(value / rhsi); } else { - throw new OrangRuntimeException(STR."divide is not implemented for Integer and \{rhs.typeName()}"); + return Value.super.divide(rhs); } } @Override - public OrangInteger multiply(Value rhs) throws OrangRuntimeException { + public Value multiply(Value rhs) throws OrangRuntimeException { if (rhs instanceof OrangInteger(int rhsi)) { return new OrangInteger(value * rhsi); } else { - throw new OrangRuntimeException(STR."multiply is not implemented for Integer and \{rhs.typeName()}"); + return Value.super.multiply(rhs); } } @Override - public OrangInteger subtract(Value rhs) throws OrangRuntimeException { + public Value subtract(Value rhs) throws OrangRuntimeException { if (rhs instanceof OrangInteger(int rhsi)) { return new OrangInteger(value - rhsi); } else { - throw new OrangRuntimeException(STR."subtract is not implemented for Integer and \{rhs.typeName()}"); + return Value.super.subtract(rhs); } } @Override - public OrangBoolean greaterThan(Value rhs) throws OrangRuntimeException { + public Value greaterThan(Value rhs) throws OrangRuntimeException { if (rhs instanceof OrangInteger(int rhsi)) { return OrangBoolean.of(value > rhsi); } else { - throw new OrangRuntimeException(STR."greaterThan is not implemented for Integer and \{rhs.typeName()}"); + return Value.super.greaterThan(rhs); } } } diff --git a/evaluator/src/main/java/lv/enes/orang/evaluator/OrangMap.java b/evaluator/src/main/java/lv/enes/orang/evaluator/OrangMap.java new file mode 100644 index 0000000..27f9f35 --- /dev/null +++ b/evaluator/src/main/java/lv/enes/orang/evaluator/OrangMap.java @@ -0,0 +1,42 @@ +package lv.enes.orang.evaluator; + +import lv.enes.orang.core.OrangRuntimeException; + +import java.util.HashMap; +import java.util.Map; + +public record OrangMap(Map map) implements Value { + @Override + public String typeName() { + return "Map"; + } + + @Override + public String stringify() { + var sb = new StringBuilder("{ "); + for (var entry : map.entrySet()) { + sb.append(entry.getKey().stringify()).append(" -> ").append(entry.getValue().stringify()).append(", "); + } + return sb.append("}").toString(); + } + + @Override + public Value add(Value rhs) throws OrangRuntimeException { + if (rhs instanceof OrangMap(var rhsm)) { + var newMap = new HashMap<>(map); + newMap.putAll(rhsm); + return new OrangMap(newMap); + } else { + return Value.super.add(rhs); + } + } + + @Override + public Value arrayAccess(Value idx) throws OrangRuntimeException { + if (map.containsKey(idx)) { + return map.get(idx); + } else { + throw new OrangRuntimeException(STR."No value associated with key \{idx.stringify()} in \{stringify()}"); + } + } +} diff --git a/evaluator/src/main/java/lv/enes/orang/evaluator/OrangString.java b/evaluator/src/main/java/lv/enes/orang/evaluator/OrangString.java index 5c38842..fe03c1f 100644 --- a/evaluator/src/main/java/lv/enes/orang/evaluator/OrangString.java +++ b/evaluator/src/main/java/lv/enes/orang/evaluator/OrangString.java @@ -30,11 +30,11 @@ public record OrangString(String value) implements Value { } @Override - public OrangString add(Value rhs) throws OrangRuntimeException { + public Value add(Value rhs) throws OrangRuntimeException { if (rhs instanceof OrangString(String rhss)) { return new OrangString(value + rhss); } else { - throw new OrangRuntimeException(STR."add is not implemented for Integer and \{rhs.typeName()}"); + return Value.super.add(rhs); } } @@ -43,7 +43,7 @@ public record OrangString(String value) implements Value { if (rhs instanceof OrangInteger(var repeat)) { return new OrangString(value.repeat(Math.max(0, repeat))); } else { - throw new OrangRuntimeException(STR."multiply not implemented for Array and \{rhs.typeName()}"); + return Value.super.multiply(rhs); } } } 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 35af35b..da44a19 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,7 @@ package lv.enes.orang.evaluator; import lv.enes.orang.core.OrangRuntimeException; public sealed interface Value - permits Array, BuiltinFunction, Function, OrangBoolean, OrangInteger, OrangString, + permits Array, BuiltinFunction, Function, OrangBoolean, OrangInteger, OrangMap, OrangString, PartialBuiltinFunction, PartialFunction, Tuple, Undefined { String typeName(); String stringify(); @@ -56,19 +56,19 @@ public sealed interface Value } - default OrangBoolean greaterThan(Value rhs) throws OrangRuntimeException { + default Value greaterThan(Value rhs) throws OrangRuntimeException { throw new OrangRuntimeException(STR."greater than is not implemented for \{typeName()} and \{rhs.typeName()}"); } - default OrangBoolean greaterThanOrEqual(Value rhs) throws OrangRuntimeException { + default Value greaterThanOrEqual(Value rhs) throws OrangRuntimeException { return greaterThan(rhs).or(orangEquals(rhs)); } - default OrangBoolean lessThan(Value rhs) throws OrangRuntimeException { + default Value lessThan(Value rhs) throws OrangRuntimeException { return greaterThanOrEqual(rhs).not(); } - default OrangBoolean lessThanOrEqual(Value rhs) throws OrangRuntimeException { + default Value lessThanOrEqual(Value rhs) throws OrangRuntimeException { return greaterThan(rhs).not(); } -- cgit v1.2.3