summaryrefslogtreecommitdiff
path: root/evaluator
diff options
context:
space:
mode:
authorGravatar Uko Kokņevičs2024-08-22 22:55:13 +0800
committerGravatar Uko Kokņevičs2024-08-22 22:55:13 +0800
commit5f4b45ec7634f2728693e93f862419e495db6979 (patch)
tree300f9acaddcfa4a63365bec4952dcb585be0a282 /evaluator
parentGet rid of that Scope mess (diff)
downloadorang-5f4b45ec7634f2728693e93f862419e495db6979.tar.gz
orang-5f4b45ec7634f2728693e93f862419e495db6979.tar.xz
orang-5f4b45ec7634f2728693e93f862419e495db6979.zip
Move Evaluator to a new module
Diffstat (limited to 'evaluator')
-rw-r--r--evaluator/build.gradle.kts9
-rw-r--r--evaluator/src/main/java/lv/enes/orang/evaluator/Array.java65
-rw-r--r--evaluator/src/main/java/lv/enes/orang/evaluator/BuiltinFunction.java31
-rw-r--r--evaluator/src/main/java/lv/enes/orang/evaluator/Evaluator.java152
-rw-r--r--evaluator/src/main/java/lv/enes/orang/evaluator/Function.java25
-rw-r--r--evaluator/src/main/java/lv/enes/orang/evaluator/Nothing.java21
-rw-r--r--evaluator/src/main/java/lv/enes/orang/evaluator/OrangBoolean.java55
-rw-r--r--evaluator/src/main/java/lv/enes/orang/evaluator/OrangInteger.java70
-rw-r--r--evaluator/src/main/java/lv/enes/orang/evaluator/OrangString.java49
-rw-r--r--evaluator/src/main/java/lv/enes/orang/evaluator/PartialBuiltinFunction.java32
-rw-r--r--evaluator/src/main/java/lv/enes/orang/evaluator/PartialFunction.java45
-rw-r--r--evaluator/src/main/java/lv/enes/orang/evaluator/Undefined.java21
-rw-r--r--evaluator/src/main/java/lv/enes/orang/evaluator/Value.java76
-rw-r--r--evaluator/src/main/java/module-info.java9
14 files changed, 660 insertions, 0 deletions
diff --git a/evaluator/build.gradle.kts b/evaluator/build.gradle.kts
new file mode 100644
index 0000000..9172259
--- /dev/null
+++ b/evaluator/build.gradle.kts
@@ -0,0 +1,9 @@
1plugins {
2 id("orang.java-conventions")
3}
4
5dependencies {
6 implementation(project(":ast"))
7 implementation(project(":core"))
8 implementation(project(":utils"))
9} \ No newline at end of file
diff --git a/evaluator/src/main/java/lv/enes/orang/evaluator/Array.java b/evaluator/src/main/java/lv/enes/orang/evaluator/Array.java
new file mode 100644
index 0000000..4c76eff
--- /dev/null
+++ b/evaluator/src/main/java/lv/enes/orang/evaluator/Array.java
@@ -0,0 +1,65 @@
1package lv.enes.orang.evaluator;
2
3import lv.enes.orang.core.OrangRuntimeException;
4
5import java.util.ArrayList;
6import java.util.Collections;
7import java.util.List;
8
9public record Array(List<Value> items) implements Value {
10 @Override
11 public String typeName() {
12 return "Array";
13 }
14
15 @Override
16 public String stringify() {
17 if (items.isEmpty()) {
18 return "[]";
19 }
20 var sb = new StringBuilder("[");
21 sb.append(items.getFirst().stringify());
22 for (int i = 1; i < items.size(); i++) {
23 sb.append(", ").append(items.get(i).stringify());
24 }
25 sb.append("]");
26 return sb.toString();
27 }
28
29 @Override
30 public String display() {
31 if (items.isEmpty()) {
32 return "";
33 }
34 var sb = new StringBuilder();
35 sb.append(items.getFirst().display());
36 for (var i = 1; i < items.size(); i++) {
37 sb.append(" ").append(items.get(i).display());
38 }
39 return sb.toString();
40 }
41
42 @Override
43 public Value add(Value rhs) throws OrangRuntimeException {
44 if (rhs instanceof Array(var rhsi)) {
45 var newItems = new ArrayList<>(this.items);
46 newItems.addAll(rhsi);
47 return new Array(Collections.unmodifiableList(newItems));
48 } else {
49 throw new OrangRuntimeException(STR."add not implemented for Array and \{rhs.typeName()}");
50 }
51 }
52
53 @Override
54 public Value multiply(Value rhs) throws OrangRuntimeException {
55 if (rhs instanceof OrangInteger(var repeat)) {
56 var newItems = new ArrayList<Value>(items.size() * repeat);
57 for (var i = 0; i < repeat; i++) {
58 newItems.addAll(items);
59 }
60 return new Array(Collections.unmodifiableList(newItems));
61 } else {
62 throw new OrangRuntimeException(STR."multiply not implemented for Array and \{rhs.typeName()}");
63 }
64 }
65}
diff --git a/evaluator/src/main/java/lv/enes/orang/evaluator/BuiltinFunction.java b/evaluator/src/main/java/lv/enes/orang/evaluator/BuiltinFunction.java
new file mode 100644
index 0000000..1f37280
--- /dev/null
+++ b/evaluator/src/main/java/lv/enes/orang/evaluator/BuiltinFunction.java
@@ -0,0 +1,31 @@
1package lv.enes.orang.evaluator;
2
3import lv.enes.orang.core.OrangRuntimeException;
4
5import java.util.List;
6
7public record BuiltinFunction(int argCount, Impl impl) implements Value {
8 @FunctionalInterface
9 public interface Impl {
10 Value apply(List<Value> args) throws OrangRuntimeException;
11 }
12
13 @Override
14 public String typeName() {
15 return "BuiltinFunction";
16 }
17
18 @Override
19 public String stringify() {
20 return "#builtinFunction";
21 }
22
23 @Override
24 public Value call(Value param) throws OrangRuntimeException {
25 if (argCount == 1) {
26 return impl.apply(List.of(param));
27 } else {
28 return new PartialBuiltinFunction(argCount, List.of(param), impl);
29 }
30 }
31}
diff --git a/evaluator/src/main/java/lv/enes/orang/evaluator/Evaluator.java b/evaluator/src/main/java/lv/enes/orang/evaluator/Evaluator.java
new file mode 100644
index 0000000..6925bac
--- /dev/null
+++ b/evaluator/src/main/java/lv/enes/orang/evaluator/Evaluator.java
@@ -0,0 +1,152 @@
1package lv.enes.orang.evaluator;
2
3import lv.enes.orang.ast.*;
4import lv.enes.orang.core.OrangRuntimeException;
5
6import java.util.ArrayList;
7import java.util.Collections;
8import java.util.HashMap;
9import java.util.Map;
10
11public record Evaluator(Map<String, Value> scope, Value lastResult) implements ExpressionVisitor<Value, OrangRuntimeException>, StatementVisitor<Evaluator, OrangRuntimeException> {
12 public Evaluator(Map<String, Value> scope) {
13 this(scope, Undefined.INSTANCE);
14 }
15
16 @Override
17 public Value visitArray(ArrayExpression expr) throws OrangRuntimeException {
18 var values = new ArrayList<Value>(expr.items().size());
19 for (var item : expr.items()) {
20 values.add(visit(item));
21 }
22 values.trimToSize();
23 return new Array(Collections.unmodifiableList(values));
24 }
25
26 @Override
27 public Value visitBinaryExpression(BinaryExpression expr) throws OrangRuntimeException {
28 var lhs = visit(expr.lhs());
29 var rhs = visit(expr.rhs());
30 return switch (expr.operator()) {
31 case EQUALS -> lhs.orangEquals(rhs);
32 case NOT_EQUALS -> lhs.notEquals(rhs);
33 case GT -> lhs.greaterThan(rhs);
34 case GTE -> lhs.greaterThanOrEqual(rhs);
35 case LT -> lhs.lessThan(rhs);
36 case LTE -> lhs.lessThanOrEqual(rhs);
37 case ADD -> lhs.add(rhs);
38 case SUBTRACT -> lhs.subtract(rhs);
39 case MULTIPLY -> lhs.multiply(rhs);
40 case DIVIDE -> lhs.divide(rhs);
41 };
42 }
43
44 @Override
45 public Value visitBoolean(BooleanLiteral expr) {
46 return OrangBoolean.of(expr.value());
47 }
48
49 @Override
50 public Value visitCallExpression(CallExpression expr) throws OrangRuntimeException {
51 var arg = visit(expr.arg());
52 return visit(expr.callee()).call(arg);
53 }
54
55 @Override
56 public Evaluator visitDefinition(Definition def) throws OrangRuntimeException {
57 var newScope = new HashMap<>(scope);
58 newScope.put(def.name(), Undefined.INSTANCE);
59 var newEvaluator = new Evaluator(newScope);
60 newScope.put(def.name(), newEvaluator.visit(def.body()));
61 return newEvaluator;
62 }
63
64 @Override
65 public Value visitDoExpression(DoExpression expr) throws OrangRuntimeException {
66 Value value = Undefined.INSTANCE;
67 for (var child : expr.body()) {
68 value = visit(child);
69 }
70 return value;
71 }
72
73 @Override
74 public Evaluator visitExpression(ExpressionStatement expr) throws OrangRuntimeException {
75 return new Evaluator(this.scope(), visit(expr.expr()));
76 }
77
78 @Override
79 public Value visitFnExpression(FnExpression expr) {
80 return new Function(this.scope, expr.args(), expr.body());
81 }
82
83 @Override
84 public Value visitIfElseExpression(IfElseExpression expr) throws OrangRuntimeException {
85 var cond = visit(expr.condition());
86 if (cond instanceof OrangBoolean value) {
87 if (value.value()) {
88 return visit(expr.trueBranch());
89 } else {
90 return visit(expr.falseBranch());
91 }
92 } else {
93 throw new OrangRuntimeException(STR."Condition in an if-else statement should be a boolean not a \{cond.typeName()}");
94 }
95 }
96
97 @Override
98 public Value visitIntLiteral(IntLiteral expr) {
99 return new OrangInteger(expr.value());
100 }
101
102 @Override
103 public Value visitLetInExpression(LetInExpression expr) throws OrangRuntimeException {
104 var newScope = new HashMap<>(scope);
105 for (var binding : expr.bindings()) {
106 newScope.put(binding.name(), Undefined.INSTANCE);
107 }
108 var newEvaluator = new Evaluator(newScope);
109 for (var binding : expr.bindings()) {
110 newScope.put(binding.name(), newEvaluator.visit(binding.value()));
111 }
112 return newEvaluator.visit(expr.body());
113 }
114
115 @Override
116 public Evaluator visitProgram(Program prog) throws OrangRuntimeException {
117 var evaluator = this;
118 for (var statement : prog.statements()) {
119 evaluator = evaluator.visit(statement);
120 }
121 return evaluator;
122 }
123
124 @Override
125 public Value visitUnaryExpression(UnaryExpression expr) throws OrangRuntimeException {
126 var child = visit(expr.child());
127 return switch (expr.operator()) {
128 case PLUS -> child.plus();
129 case NEGATE -> child.negate();
130 case NOT -> child.not();
131 };
132 }
133
134 @Override
135 public Value visitStringLiteral(StringLiteral expr) {
136 return new OrangString(expr.value());
137 }
138
139 @Override
140 public Value visitVariable(VariableExpression expr) throws OrangRuntimeException {
141 if (scope.containsKey(expr.name())) {
142 return scope.get(expr.name());
143 }
144
145 throw new OrangRuntimeException(STR."Value named \{expr.name()} is not defined!");
146 }
147
148 @Override
149 public Value visitVoidExpression() {
150 return Nothing.INSTANCE;
151 }
152}
diff --git a/evaluator/src/main/java/lv/enes/orang/evaluator/Function.java b/evaluator/src/main/java/lv/enes/orang/evaluator/Function.java
new file mode 100644
index 0000000..33102fb
--- /dev/null
+++ b/evaluator/src/main/java/lv/enes/orang/evaluator/Function.java
@@ -0,0 +1,25 @@
1package lv.enes.orang.evaluator;
2
3import lv.enes.orang.ast.ArgSpec;
4import lv.enes.orang.ast.Expression;
5import lv.enes.orang.core.OrangRuntimeException;
6import lv.enes.orang.utils.NonEmptyList;
7
8import java.util.Map;
9
10public record Function(Map<String, Value> scope, NonEmptyList<ArgSpec> args, Expression body) implements Value {
11 @Override
12 public String typeName() {
13 return "Function";
14 }
15
16 @Override
17 public String stringify() {
18 return "#function";
19 }
20
21 @Override
22 public Value call(Value param) throws OrangRuntimeException {
23 return PartialFunction.of(scope, args, body, param);
24 }
25}
diff --git a/evaluator/src/main/java/lv/enes/orang/evaluator/Nothing.java b/evaluator/src/main/java/lv/enes/orang/evaluator/Nothing.java
new file mode 100644
index 0000000..c971649
--- /dev/null
+++ b/evaluator/src/main/java/lv/enes/orang/evaluator/Nothing.java
@@ -0,0 +1,21 @@
1package lv.enes.orang.evaluator;
2
3import lombok.EqualsAndHashCode;
4
5@EqualsAndHashCode
6public final class Nothing implements Value {
7 public static final Nothing INSTANCE = new Nothing();
8
9 private Nothing() {
10 }
11
12 @Override
13 public String typeName() {
14 return "Nothing";
15 }
16
17 @Override
18 public String stringify() {
19 return "()";
20 }
21}
diff --git a/evaluator/src/main/java/lv/enes/orang/evaluator/OrangBoolean.java b/evaluator/src/main/java/lv/enes/orang/evaluator/OrangBoolean.java
new file mode 100644
index 0000000..3564a9c
--- /dev/null
+++ b/evaluator/src/main/java/lv/enes/orang/evaluator/OrangBoolean.java
@@ -0,0 +1,55 @@
1package lv.enes.orang.evaluator;
2
3import lombok.EqualsAndHashCode;
4import lv.enes.orang.core.OrangRuntimeException;
5
6@EqualsAndHashCode
7public final class OrangBoolean implements Value {
8 public final static OrangBoolean TRUE = new OrangBoolean(true);
9 public final static OrangBoolean FALSE = new OrangBoolean(false);
10
11 private final boolean value;
12
13 private OrangBoolean(boolean value) {
14 this.value = value;
15 }
16
17 public static OrangBoolean of(boolean value) {
18 if (value) {
19 return TRUE;
20 }
21 return FALSE;
22 }
23
24 public boolean value() {
25 return value;
26 }
27
28 @Override
29 public String typeName() {
30 return "Boolean";
31 }
32
33 @Override
34 public String stringify() {
35 if (value) {
36 return "true";
37 } else {
38 return "false";
39 }
40 }
41
42 @Override
43 public OrangBoolean not() {
44 return new OrangBoolean(!value);
45 }
46
47 @Override
48 public OrangBoolean or(Value rhs) throws OrangRuntimeException {
49 if (rhs instanceof OrangBoolean rhsb) {
50 return new OrangBoolean(value || rhsb.value);
51 } else {
52 throw new OrangRuntimeException(STR."or is not implemented for Boolean and \{rhs.typeName()}");
53 }
54 }
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
new file mode 100644
index 0000000..90de0b5
--- /dev/null
+++ b/evaluator/src/main/java/lv/enes/orang/evaluator/OrangInteger.java
@@ -0,0 +1,70 @@
1package lv.enes.orang.evaluator;
2
3import lv.enes.orang.core.OrangRuntimeException;
4
5public record OrangInteger(int value) implements Value {
6 @Override
7 public String typeName() {
8 return "Integer";
9 }
10
11 @Override
12 public String stringify() {
13 return Integer.toString(value);
14 }
15
16 @Override
17 public OrangInteger negate() {
18 return new OrangInteger(-value);
19 }
20
21 @Override
22 public OrangInteger plus() {
23 return this;
24 }
25
26 @Override
27 public OrangInteger add(Value rhs) throws OrangRuntimeException {
28 if (rhs instanceof OrangInteger(int rhsi)) {
29 return new OrangInteger(value + rhsi);
30 } else {
31 throw new OrangRuntimeException(STR."add is not implemented for Integer and \{rhs.typeName()}");
32 }
33 }
34
35 @Override
36 public OrangInteger divide(Value rhs) throws OrangRuntimeException {
37 if (rhs instanceof OrangInteger(int rhsi)) {
38 return new OrangInteger(value / rhsi);
39 } else {
40 throw new OrangRuntimeException(STR."divide is not implemented for Integer and \{rhs.typeName()}");
41 }
42 }
43
44 @Override
45 public OrangInteger multiply(Value rhs) throws OrangRuntimeException {
46 if (rhs instanceof OrangInteger(int rhsi)) {
47 return new OrangInteger(value * rhsi);
48 } else {
49 throw new OrangRuntimeException(STR."multiply is not implemented for Integer and \{rhs.typeName()}");
50 }
51 }
52
53 @Override
54 public OrangInteger subtract(Value rhs) throws OrangRuntimeException {
55 if (rhs instanceof OrangInteger(int rhsi)) {
56 return new OrangInteger(value - rhsi);
57 } else {
58 throw new OrangRuntimeException(STR."subtract is not implemented for Integer and \{rhs.typeName()}");
59 }
60 }
61
62 @Override
63 public OrangBoolean greaterThan(Value rhs) throws OrangRuntimeException {
64 if (rhs instanceof OrangInteger(int rhsi)) {
65 return OrangBoolean.of(value > rhsi);
66 } else {
67 throw new OrangRuntimeException(STR."greaterThan is not implemented for Integer and \{rhs.typeName()}");
68 }
69 }
70}
diff --git a/evaluator/src/main/java/lv/enes/orang/evaluator/OrangString.java b/evaluator/src/main/java/lv/enes/orang/evaluator/OrangString.java
new file mode 100644
index 0000000..5c38842
--- /dev/null
+++ b/evaluator/src/main/java/lv/enes/orang/evaluator/OrangString.java
@@ -0,0 +1,49 @@
1package lv.enes.orang.evaluator;
2
3import lv.enes.orang.core.OrangRuntimeException;
4
5public record OrangString(String value) implements Value {
6 @Override
7 public String typeName() {
8 return "String";
9 }
10
11 @Override
12 public String stringify() {
13 var sb = new StringBuilder("\"");
14 var cps = value.codePoints().iterator();
15 while (cps.hasNext()) {
16 var cp = cps.next();
17 if (cp == '"') {
18 sb.append("\\\"");
19 } else {
20 sb.appendCodePoint(cp);
21 }
22 }
23 sb.append('"');
24 return sb.toString();
25 }
26
27 @Override
28 public String display() {
29 return value;
30 }
31
32 @Override
33 public OrangString add(Value rhs) throws OrangRuntimeException {
34 if (rhs instanceof OrangString(String rhss)) {
35 return new OrangString(value + rhss);
36 } else {
37 throw new OrangRuntimeException(STR."add is not implemented for Integer and \{rhs.typeName()}");
38 }
39 }
40
41 @Override
42 public Value multiply(Value rhs) throws OrangRuntimeException {
43 if (rhs instanceof OrangInteger(var repeat)) {
44 return new OrangString(value.repeat(Math.max(0, repeat)));
45 } else {
46 throw new OrangRuntimeException(STR."multiply not implemented for Array and \{rhs.typeName()}");
47 }
48 }
49}
diff --git a/evaluator/src/main/java/lv/enes/orang/evaluator/PartialBuiltinFunction.java b/evaluator/src/main/java/lv/enes/orang/evaluator/PartialBuiltinFunction.java
new file mode 100644
index 0000000..f1e8cc6
--- /dev/null
+++ b/evaluator/src/main/java/lv/enes/orang/evaluator/PartialBuiltinFunction.java
@@ -0,0 +1,32 @@
1package lv.enes.orang.evaluator;
2
3import lv.enes.orang.core.OrangRuntimeException;
4
5import java.util.ArrayList;
6import java.util.Collections;
7import java.util.List;
8
9public record PartialBuiltinFunction(int argCount, List<Value> params, BuiltinFunction.Impl impl) implements Value {
10 @Override
11 public String typeName() {
12 return "BuiltinFunction";
13 }
14
15 @Override
16 public String stringify() {
17 return "#builtinFunction";
18 }
19
20 @Override
21 public Value call(Value param) throws OrangRuntimeException {
22 List<Value> newParams = new ArrayList<>(params);
23 newParams.add(param);
24 newParams = Collections.unmodifiableList(newParams);
25
26 if (newParams.size() == argCount) {
27 return impl.apply(newParams);
28 } else {
29 return new PartialBuiltinFunction(argCount, newParams, impl);
30 }
31 }
32}
diff --git a/evaluator/src/main/java/lv/enes/orang/evaluator/PartialFunction.java b/evaluator/src/main/java/lv/enes/orang/evaluator/PartialFunction.java
new file mode 100644
index 0000000..d0125f6
--- /dev/null
+++ b/evaluator/src/main/java/lv/enes/orang/evaluator/PartialFunction.java
@@ -0,0 +1,45 @@
1package lv.enes.orang.evaluator;
2
3import lv.enes.orang.ast.ArgSpec;
4import lv.enes.orang.ast.Expression;
5import lv.enes.orang.core.OrangRuntimeException;
6import lv.enes.orang.utils.NonEmptyList;
7
8import java.util.HashMap;
9import java.util.Map;
10
11public record PartialFunction(Map<String, Value> scope, NonEmptyList<ArgSpec> remainingArgs, Expression body) implements Value {
12 public static Value of(Map<String, Value> scope, NonEmptyList<ArgSpec> remainingArgs, Expression body, Value param) throws OrangRuntimeException {
13 var spec = remainingArgs.getFirst();
14 var newScope = new HashMap<>(scope);
15 switch (spec.getType()) {
16 case NAMED -> newScope.put(((ArgSpec.Named)spec).name(), param);
17 case NOTHING -> {
18 if (!(param instanceof Nothing)) {
19 throw new OrangRuntimeException(STR."Expected () as a parameter but got \{param.typeName()}");
20 }
21 }
22 }
23
24 if (remainingArgs.size() == 1) {
25 return new Evaluator(newScope).visit(body);
26 } else {
27 return new PartialFunction(newScope, new NonEmptyList<>(remainingArgs.subList(1, remainingArgs.size())), body);
28 }
29 }
30
31 @Override
32 public String typeName() {
33 return "Function";
34 }
35
36 @Override
37 public String stringify() {
38 return "#function";
39 }
40
41 @Override
42 public Value call(Value param) throws OrangRuntimeException {
43 return PartialFunction.of(scope, remainingArgs, body, param);
44 }
45}
diff --git a/evaluator/src/main/java/lv/enes/orang/evaluator/Undefined.java b/evaluator/src/main/java/lv/enes/orang/evaluator/Undefined.java
new file mode 100644
index 0000000..2aec74b
--- /dev/null
+++ b/evaluator/src/main/java/lv/enes/orang/evaluator/Undefined.java
@@ -0,0 +1,21 @@
1package lv.enes.orang.evaluator;
2
3import lombok.EqualsAndHashCode;
4
5@EqualsAndHashCode
6public final class Undefined implements Value {
7 public static final Undefined INSTANCE = new Undefined();
8
9 private Undefined() {
10 }
11
12 @Override
13 public String typeName() {
14 return "Undefined";
15 }
16
17 @Override
18 public String stringify() {
19 return "#undefined";
20 }
21}
diff --git a/evaluator/src/main/java/lv/enes/orang/evaluator/Value.java b/evaluator/src/main/java/lv/enes/orang/evaluator/Value.java
new file mode 100644
index 0000000..d8c8b9c
--- /dev/null
+++ b/evaluator/src/main/java/lv/enes/orang/evaluator/Value.java
@@ -0,0 +1,76 @@
1package lv.enes.orang.evaluator;
2
3import lv.enes.orang.core.OrangRuntimeException;
4
5public sealed interface Value
6 permits Array, BuiltinFunction, Function, Nothing, OrangBoolean, OrangInteger, OrangString, PartialBuiltinFunction, PartialFunction, Undefined {
7 String typeName();
8 String stringify();
9
10 default String display() {
11 return stringify();
12 }
13
14
15 default Value negate() throws OrangRuntimeException {
16 throw new OrangRuntimeException(STR."negate is not implemented for \{typeName()}");
17 }
18
19 default Value not() throws OrangRuntimeException {
20 throw new OrangRuntimeException(STR."not is not implemented for \{typeName()}");
21 }
22
23 default Value plus() throws OrangRuntimeException {
24 throw new OrangRuntimeException(STR."plus is not implemented for \{typeName()}");
25 }
26
27
28 default Value add(Value rhs) throws OrangRuntimeException {
29 throw new OrangRuntimeException(STR."add is not implemented for \{typeName()} and \{rhs.typeName()}");
30 }
31
32 default Value call(Value rhs) throws OrangRuntimeException {
33 throw new OrangRuntimeException(STR."call is not implemented for \{typeName()} and \{rhs.typeName()}");
34 }
35
36 default Value divide(Value rhs) throws OrangRuntimeException {
37 throw new OrangRuntimeException(STR."divide is not implemented for \{typeName()} and \{rhs.typeName()}");
38 }
39
40 default Value multiply(Value rhs) throws OrangRuntimeException {
41 throw new OrangRuntimeException(STR."multiply is not implemented for \{typeName()} and \{rhs.typeName()}");
42 }
43
44 default Value or(Value rhs) throws OrangRuntimeException {
45 throw new OrangRuntimeException(STR."or is not implemented for \{typeName()} and \{rhs.typeName()}");
46 }
47
48 default Value subtract(Value rhs) throws OrangRuntimeException {
49 throw new OrangRuntimeException(STR."subtract is not implemented for \{typeName()} and \{rhs.typeName()}");
50 }
51
52
53 default OrangBoolean greaterThan(Value rhs) throws OrangRuntimeException {
54 throw new OrangRuntimeException(STR."greater than is not implemented for \{typeName()} and \{rhs.typeName()}");
55 }
56
57 default OrangBoolean greaterThanOrEqual(Value rhs) throws OrangRuntimeException {
58 return greaterThan(rhs).or(orangEquals(rhs));
59 }
60
61 default OrangBoolean lessThan(Value rhs) throws OrangRuntimeException {
62 return greaterThanOrEqual(rhs).not();
63 }
64
65 default OrangBoolean lessThanOrEqual(Value rhs) throws OrangRuntimeException {
66 return greaterThan(rhs).not();
67 }
68
69 default OrangBoolean orangEquals(Value rhs) {
70 return OrangBoolean.of(this.equals(rhs));
71 }
72
73 default OrangBoolean notEquals(Value rhs) {
74 return orangEquals(rhs).not();
75 }
76}
diff --git a/evaluator/src/main/java/module-info.java b/evaluator/src/main/java/module-info.java
new file mode 100644
index 0000000..4cb992c
--- /dev/null
+++ b/evaluator/src/main/java/module-info.java
@@ -0,0 +1,9 @@
1module lv.enes.orang.evaluator {
2 exports lv.enes.orang.evaluator;
3
4 requires lv.enes.orang.ast;
5 requires lv.enes.orang.core;
6 requires lv.enes.orang.utils;
7
8 requires static lombok;
9} \ No newline at end of file