summaryrefslogtreecommitdiff
path: root/evaluator
diff options
context:
space:
mode:
Diffstat (limited to 'evaluator')
-rw-r--r--evaluator/src/main/java/lv/enes/orang/evaluator/Array.java6
-rw-r--r--evaluator/src/main/java/lv/enes/orang/evaluator/Evaluator.java11
-rw-r--r--evaluator/src/main/java/lv/enes/orang/evaluator/OrangBoolean.java8
-rw-r--r--evaluator/src/main/java/lv/enes/orang/evaluator/OrangInteger.java20
-rw-r--r--evaluator/src/main/java/lv/enes/orang/evaluator/OrangMap.java42
-rw-r--r--evaluator/src/main/java/lv/enes/orang/evaluator/OrangString.java6
-rw-r--r--evaluator/src/main/java/lv/enes/orang/evaluator/Value.java10
7 files changed, 78 insertions, 25 deletions
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<Value> items) implements Value {
46 newItems.addAll(rhsi); 46 newItems.addAll(rhsi);
47 return new Array(Collections.unmodifiableList(newItems)); 47 return new Array(Collections.unmodifiableList(newItems));
48 } else { 48 } else {
49 throw new OrangRuntimeException(STR."add not implemented for Array and \{rhs.typeName()}"); 49 return Value.super.add(rhs);
50 } 50 }
51 } 51 }
52 52
@@ -58,7 +58,7 @@ public record Array(List<Value> items) implements Value {
58 } 58 }
59 return items.get(i); 59 return items.get(i);
60 } else { 60 } else {
61 throw new OrangRuntimeException(STR."array access not implemented for Array and \{idx.typeName()}"); 61 return Value.super.arrayAccess(idx);
62 } 62 }
63 } 63 }
64 64
@@ -71,7 +71,7 @@ public record Array(List<Value> items) implements Value {
71 } 71 }
72 return new Array(Collections.unmodifiableList(newItems)); 72 return new Array(Collections.unmodifiableList(newItems));
73 } else { 73 } else {
74 throw new OrangRuntimeException(STR."multiply not implemented for Array and \{rhs.typeName()}"); 74 return Value.super.multiply(rhs);
75 } 75 }
76 } 76 }
77} 77}
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
@@ -120,6 +120,17 @@ public record Evaluator(Map<String, Value> scope, Value lastResult) implements E
120 } 120 }
121 121
122 @Override 122 @Override
123 public Value visitMap(MapExpression expr) throws OrangRuntimeException {
124 var map = new HashMap<Value, Value>();
125 for (var entry : expr.entries()) {
126 var from = visit(entry.from());
127 var to = visit(entry.to());
128 map.put(from, to);
129 }
130 return new OrangMap(Collections.unmodifiableMap(map));
131 }
132
133 @Override
123 public Evaluator visitProgram(Program prog) throws OrangRuntimeException { 134 public Evaluator visitProgram(Program prog) throws OrangRuntimeException {
124 var evaluator = this; 135 var evaluator = this;
125 for (var statement : prog.statements()) { 136 for (var statement : prog.statements()) {
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;
5 5
6@EqualsAndHashCode 6@EqualsAndHashCode
7public final class OrangBoolean implements Value { 7public final class OrangBoolean implements Value {
8 public final static OrangBoolean TRUE = new OrangBoolean(true); 8 public static final OrangBoolean TRUE = new OrangBoolean(true);
9 public final static OrangBoolean FALSE = new OrangBoolean(false); 9 public static final OrangBoolean FALSE = new OrangBoolean(false);
10 10
11 private final boolean value; 11 private final boolean value;
12 12
@@ -45,11 +45,11 @@ public final class OrangBoolean implements Value {
45 } 45 }
46 46
47 @Override 47 @Override
48 public OrangBoolean or(Value rhs) throws OrangRuntimeException { 48 public Value or(Value rhs) throws OrangRuntimeException {
49 if (rhs instanceof OrangBoolean rhsb) { 49 if (rhs instanceof OrangBoolean rhsb) {
50 return new OrangBoolean(value || rhsb.value); 50 return new OrangBoolean(value || rhsb.value);
51 } else { 51 } else {
52 throw new OrangRuntimeException(STR."or is not implemented for Boolean and \{rhs.typeName()}"); 52 return Value.super.or(rhs);
53 } 53 }
54 } 54 }
55} 55}
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 {
24 } 24 }
25 25
26 @Override 26 @Override
27 public OrangInteger add(Value rhs) throws OrangRuntimeException { 27 public Value add(Value rhs) throws OrangRuntimeException {
28 if (rhs instanceof OrangInteger(int rhsi)) { 28 if (rhs instanceof OrangInteger(int rhsi)) {
29 return new OrangInteger(value + rhsi); 29 return new OrangInteger(value + rhsi);
30 } else { 30 } else {
31 throw new OrangRuntimeException(STR."add is not implemented for Integer and \{rhs.typeName()}"); 31 return Value.super.add(rhs);
32 } 32 }
33 } 33 }
34 34
35 @Override 35 @Override
36 public OrangInteger divide(Value rhs) throws OrangRuntimeException { 36 public Value divide(Value rhs) throws OrangRuntimeException {
37 if (rhs instanceof OrangInteger(int rhsi)) { 37 if (rhs instanceof OrangInteger(int rhsi)) {
38 return new OrangInteger(value / rhsi); 38 return new OrangInteger(value / rhsi);
39 } else { 39 } else {
40 throw new OrangRuntimeException(STR."divide is not implemented for Integer and \{rhs.typeName()}"); 40 return Value.super.divide(rhs);
41 } 41 }
42 } 42 }
43 43
44 @Override 44 @Override
45 public OrangInteger multiply(Value rhs) throws OrangRuntimeException { 45 public Value multiply(Value rhs) throws OrangRuntimeException {
46 if (rhs instanceof OrangInteger(int rhsi)) { 46 if (rhs instanceof OrangInteger(int rhsi)) {
47 return new OrangInteger(value * rhsi); 47 return new OrangInteger(value * rhsi);
48 } else { 48 } else {
49 throw new OrangRuntimeException(STR."multiply is not implemented for Integer and \{rhs.typeName()}"); 49 return Value.super.multiply(rhs);
50 } 50 }
51 } 51 }
52 52
53 @Override 53 @Override
54 public OrangInteger subtract(Value rhs) throws OrangRuntimeException { 54 public Value subtract(Value rhs) throws OrangRuntimeException {
55 if (rhs instanceof OrangInteger(int rhsi)) { 55 if (rhs instanceof OrangInteger(int rhsi)) {
56 return new OrangInteger(value - rhsi); 56 return new OrangInteger(value - rhsi);
57 } else { 57 } else {
58 throw new OrangRuntimeException(STR."subtract is not implemented for Integer and \{rhs.typeName()}"); 58 return Value.super.subtract(rhs);
59 } 59 }
60 } 60 }
61 61
62 @Override 62 @Override
63 public OrangBoolean greaterThan(Value rhs) throws OrangRuntimeException { 63 public Value greaterThan(Value rhs) throws OrangRuntimeException {
64 if (rhs instanceof OrangInteger(int rhsi)) { 64 if (rhs instanceof OrangInteger(int rhsi)) {
65 return OrangBoolean.of(value > rhsi); 65 return OrangBoolean.of(value > rhsi);
66 } else { 66 } else {
67 throw new OrangRuntimeException(STR."greaterThan is not implemented for Integer and \{rhs.typeName()}"); 67 return Value.super.greaterThan(rhs);
68 } 68 }
69 } 69 }
70} 70}
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 @@
1package lv.enes.orang.evaluator;
2
3import lv.enes.orang.core.OrangRuntimeException;
4
5import java.util.HashMap;
6import java.util.Map;
7
8public record OrangMap(Map<Value, Value> map) implements Value {
9 @Override
10 public String typeName() {
11 return "Map";
12 }
13
14 @Override
15 public String stringify() {
16 var sb = new StringBuilder("{ ");
17 for (var entry : map.entrySet()) {
18 sb.append(entry.getKey().stringify()).append(" -> ").append(entry.getValue().stringify()).append(", ");
19 }
20 return sb.append("}").toString();
21 }
22
23 @Override
24 public Value add(Value rhs) throws OrangRuntimeException {
25 if (rhs instanceof OrangMap(var rhsm)) {
26 var newMap = new HashMap<>(map);
27 newMap.putAll(rhsm);
28 return new OrangMap(newMap);
29 } else {
30 return Value.super.add(rhs);
31 }
32 }
33
34 @Override
35 public Value arrayAccess(Value idx) throws OrangRuntimeException {
36 if (map.containsKey(idx)) {
37 return map.get(idx);
38 } else {
39 throw new OrangRuntimeException(STR."No value associated with key \{idx.stringify()} in \{stringify()}");
40 }
41 }
42}
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 {
30 } 30 }
31 31
32 @Override 32 @Override
33 public OrangString add(Value rhs) throws OrangRuntimeException { 33 public Value add(Value rhs) throws OrangRuntimeException {
34 if (rhs instanceof OrangString(String rhss)) { 34 if (rhs instanceof OrangString(String rhss)) {
35 return new OrangString(value + rhss); 35 return new OrangString(value + rhss);
36 } else { 36 } else {
37 throw new OrangRuntimeException(STR."add is not implemented for Integer and \{rhs.typeName()}"); 37 return Value.super.add(rhs);
38 } 38 }
39 } 39 }
40 40
@@ -43,7 +43,7 @@ public record OrangString(String value) implements Value {
43 if (rhs instanceof OrangInteger(var repeat)) { 43 if (rhs instanceof OrangInteger(var repeat)) {
44 return new OrangString(value.repeat(Math.max(0, repeat))); 44 return new OrangString(value.repeat(Math.max(0, repeat)));
45 } else { 45 } else {
46 throw new OrangRuntimeException(STR."multiply not implemented for Array and \{rhs.typeName()}"); 46 return Value.super.multiply(rhs);
47 } 47 }
48 } 48 }
49} 49}
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;
3import lv.enes.orang.core.OrangRuntimeException; 3import lv.enes.orang.core.OrangRuntimeException;
4 4
5public sealed interface Value 5public sealed interface Value
6 permits Array, BuiltinFunction, Function, OrangBoolean, OrangInteger, OrangString, 6 permits Array, BuiltinFunction, Function, OrangBoolean, OrangInteger, OrangMap, OrangString,
7 PartialBuiltinFunction, PartialFunction, Tuple, Undefined { 7 PartialBuiltinFunction, PartialFunction, Tuple, Undefined {
8 String typeName(); 8 String typeName();
9 String stringify(); 9 String stringify();
@@ -56,19 +56,19 @@ public sealed interface Value
56 } 56 }
57 57
58 58
59 default OrangBoolean greaterThan(Value rhs) throws OrangRuntimeException { 59 default Value greaterThan(Value rhs) throws OrangRuntimeException {
60 throw new OrangRuntimeException(STR."greater than is not implemented for \{typeName()} and \{rhs.typeName()}"); 60 throw new OrangRuntimeException(STR."greater than is not implemented for \{typeName()} and \{rhs.typeName()}");
61 } 61 }
62 62
63 default OrangBoolean greaterThanOrEqual(Value rhs) throws OrangRuntimeException { 63 default Value greaterThanOrEqual(Value rhs) throws OrangRuntimeException {
64 return greaterThan(rhs).or(orangEquals(rhs)); 64 return greaterThan(rhs).or(orangEquals(rhs));
65 } 65 }
66 66
67 default OrangBoolean lessThan(Value rhs) throws OrangRuntimeException { 67 default Value lessThan(Value rhs) throws OrangRuntimeException {
68 return greaterThanOrEqual(rhs).not(); 68 return greaterThanOrEqual(rhs).not();
69 } 69 }
70 70
71 default OrangBoolean lessThanOrEqual(Value rhs) throws OrangRuntimeException { 71 default Value lessThanOrEqual(Value rhs) throws OrangRuntimeException {
72 return greaterThan(rhs).not(); 72 return greaterThan(rhs).not();
73 } 73 }
74 74