summaryrefslogtreecommitdiff
path: root/evaluator/src
diff options
context:
space:
mode:
authorGravatar Uko Kokņevičs2024-08-24 03:54:25 +0800
committerGravatar Uko Kokņevičs2024-08-24 03:54:25 +0800
commit16a20ee8b08df919e93ea1b878013f9a2ad709fa (patch)
tree80d59e93c566ddba1e2116e8d64222b8036b216e /evaluator/src
parentAdd tuples. (diff)
downloadorang-16a20ee8b08df919e93ea1b878013f9a2ad709fa.tar.gz
orang-16a20ee8b08df919e93ea1b878013f9a2ad709fa.tar.xz
orang-16a20ee8b08df919e93ea1b878013f9a2ad709fa.zip
Added fancier tuple argument specs.
Made ArgSpec use visitor pattern to avoid problems the best way. Merged empty tuple and non-empty tuple classes.
Diffstat (limited to 'evaluator/src')
-rw-r--r--evaluator/src/main/java/lv/enes/orang/evaluator/EmptyTuple.java21
-rw-r--r--evaluator/src/main/java/lv/enes/orang/evaluator/Evaluator.java8
-rw-r--r--evaluator/src/main/java/lv/enes/orang/evaluator/PartialFunction.java45
-rw-r--r--evaluator/src/main/java/lv/enes/orang/evaluator/Tuple.java12
-rw-r--r--evaluator/src/main/java/lv/enes/orang/evaluator/Value.java2
5 files changed, 48 insertions, 40 deletions
diff --git a/evaluator/src/main/java/lv/enes/orang/evaluator/EmptyTuple.java b/evaluator/src/main/java/lv/enes/orang/evaluator/EmptyTuple.java
deleted file mode 100644
index f8e043b..0000000
--- a/evaluator/src/main/java/lv/enes/orang/evaluator/EmptyTuple.java
+++ /dev/null
@@ -1,21 +0,0 @@
1package lv.enes.orang.evaluator;
2
3import lombok.EqualsAndHashCode;
4
5@EqualsAndHashCode
6public final class EmptyTuple implements Value {
7 public static final EmptyTuple INSTANCE = new EmptyTuple();
8
9 private EmptyTuple() {
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/Evaluator.java b/evaluator/src/main/java/lv/enes/orang/evaluator/Evaluator.java
index f0299b4..1f51b9d 100644
--- a/evaluator/src/main/java/lv/enes/orang/evaluator/Evaluator.java
+++ b/evaluator/src/main/java/lv/enes/orang/evaluator/Evaluator.java
@@ -2,7 +2,6 @@ package lv.enes.orang.evaluator;
2 2
3import lv.enes.orang.ast.*; 3import lv.enes.orang.ast.*;
4import lv.enes.orang.core.OrangRuntimeException; 4import lv.enes.orang.core.OrangRuntimeException;
5import lv.enes.orang.utils.NonEmptyList;
6 5
7import java.util.ArrayList; 6import java.util.ArrayList;
8import java.util.Collections; 7import java.util.Collections;
@@ -72,11 +71,6 @@ public record Evaluator(Map<String, Value> scope, Value lastResult) implements E
72 } 71 }
73 72
74 @Override 73 @Override
75 public Value visitEmptyTupleExpression() {
76 return EmptyTuple.INSTANCE;
77 }
78
79 @Override
80 public Evaluator visitExpression(ExpressionStatement expr) throws OrangRuntimeException { 74 public Evaluator visitExpression(ExpressionStatement expr) throws OrangRuntimeException {
81 return new Evaluator(this.scope(), visit(expr.expr())); 75 return new Evaluator(this.scope(), visit(expr.expr()));
82 } 76 }
@@ -148,7 +142,7 @@ public record Evaluator(Map<String, Value> scope, Value lastResult) implements E
148 for (var tailExpr : expr.children()) { 142 for (var tailExpr : expr.children()) {
149 values.add(visit(tailExpr)); 143 values.add(visit(tailExpr));
150 } 144 }
151 return new Tuple(new NonEmptyList<>(values)); 145 return new Tuple(values);
152 } 146 }
153 147
154 @Override 148 @Override
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 7c0ca20..bea3d02 100644
--- a/evaluator/src/main/java/lv/enes/orang/evaluator/PartialFunction.java
+++ b/evaluator/src/main/java/lv/enes/orang/evaluator/PartialFunction.java
@@ -1,7 +1,6 @@
1package lv.enes.orang.evaluator; 1package lv.enes.orang.evaluator;
2 2
3import lv.enes.orang.ast.ArgSpec; 3import lv.enes.orang.ast.*;
4import lv.enes.orang.ast.Expression;
5import lv.enes.orang.core.OrangRuntimeException; 4import lv.enes.orang.core.OrangRuntimeException;
6import lv.enes.orang.utils.NonEmptyList; 5import lv.enes.orang.utils.NonEmptyList;
7 6
@@ -10,17 +9,45 @@ import java.util.Map;
10 9
11public record PartialFunction(Map<String, Value> scope, NonEmptyList<ArgSpec> remainingArgs, Expression body) implements Value { 10public 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 { 11 public static Value of(Map<String, Value> scope, NonEmptyList<ArgSpec> remainingArgs, Expression body, Value param) throws OrangRuntimeException {
13 var spec = remainingArgs.getFirst(); 12 class Helper implements ArgSpecVisitor<Void, OrangRuntimeException> {
14 var newScope = new HashMap<>(scope); 13 private final HashMap<String, Value> newScope;
15 switch (spec.getType()) { 14 private final Value param;
16 case NAMED -> newScope.put(((ArgSpec.Named)spec).name(), param); 15
17 case NOTHING -> { 16 public Helper(HashMap<String, Value> newScope, Value param) {
18 if (!(param instanceof EmptyTuple)) { 17 this.newScope = newScope;
19 throw new OrangRuntimeException(STR."Expected () as a parameter but got \{param.typeName()}"); 18 this.param = param;
19 }
20
21 @Override
22 public Void visitIgnored() {
23 // Do nothing :3
24 return null;
25 }
26
27 @Override
28 public Void visitNamed(ArgSpecNamed named) {
29 newScope.put(named.name(), param);
30 return null;
31 }
32
33 @Override
34 public Void visitTuple(ArgSpecTuple tuple) throws OrangRuntimeException {
35 if (param instanceof Tuple(var children)) {
36 if (children.size() == tuple.children().size()) {
37 for (var i = 0; i < children.size(); i++) {
38 new Helper(newScope, children.get(i)).visit(tuple.children().get(i));
39 }
40 return null;
41 }
20 } 42 }
43 throw new OrangRuntimeException(STR."Expected a tuple with \{tuple.children().size()} members as a parameter but got \{param.typeName()}");
21 } 44 }
22 } 45 }
23 46
47 var spec = remainingArgs.getFirst();
48 var newScope = new HashMap<>(scope);
49 new Helper(newScope, param).visit(spec);
50
24 if (remainingArgs.size() == 1) { 51 if (remainingArgs.size() == 1) {
25 return new Evaluator(newScope).visit(body); 52 return new Evaluator(newScope).visit(body);
26 } else { 53 } else {
diff --git a/evaluator/src/main/java/lv/enes/orang/evaluator/Tuple.java b/evaluator/src/main/java/lv/enes/orang/evaluator/Tuple.java
index d5a1df5..fb607db 100644
--- a/evaluator/src/main/java/lv/enes/orang/evaluator/Tuple.java
+++ b/evaluator/src/main/java/lv/enes/orang/evaluator/Tuple.java
@@ -1,10 +1,14 @@
1package lv.enes.orang.evaluator; 1package lv.enes.orang.evaluator;
2 2
3import lv.enes.orang.utils.NonEmptyList; 3import java.util.List;
4 4
5public record Tuple(NonEmptyList<Value> contents) implements Value { 5public record Tuple(List<Value> contents) implements Value {
6 @Override 6 @Override
7 public String typeName() { 7 public String typeName() {
8 if (contents.isEmpty()) {
9 return "()";
10 }
11
8 var sb = new StringBuilder("("); 12 var sb = new StringBuilder("(");
9 sb.append(contents.getFirst().typeName()); 13 sb.append(contents.getFirst().typeName());
10 for (var i = 1; i < contents.size(); i++) { 14 for (var i = 1; i < contents.size(); i++) {
@@ -15,6 +19,10 @@ public record Tuple(NonEmptyList<Value> contents) implements Value {
15 19
16 @Override 20 @Override
17 public String stringify() { 21 public String stringify() {
22 if (contents.isEmpty()) {
23 return "()";
24 }
25
18 var sb = new StringBuilder("("); 26 var sb = new StringBuilder("(");
19 sb.append(contents.getFirst().stringify()); 27 sb.append(contents.getFirst().stringify());
20 for (var i = 1; i < contents.size(); i++) { 28 for (var i = 1; i < contents.size(); i++) {
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 2ef5136..1a1aad6 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, EmptyTuple, Function, OrangBoolean, OrangInteger, OrangString, 6 permits Array, BuiltinFunction, Function, OrangBoolean, OrangInteger, OrangString,
7 PartialBuiltinFunction, PartialFunction, Tuple, Undefined { 7 PartialBuiltinFunction, PartialFunction, Tuple, Undefined {
8 String typeName(); 8 String typeName();
9 String stringify(); 9 String stringify();