diff options
| author | 2024-08-22 22:04:14 +0800 | |
|---|---|---|
| committer | 2024-08-22 22:04:14 +0800 | |
| commit | 1fd741f7d5019b929affd29741b5ce92d7993f0f (patch) | |
| tree | 01aa4d15f44f6fd698767606e0d7b8b4d5877b46 | |
| parent | Simplify build scripts (diff) | |
| download | orang-1fd741f7d5019b929affd29741b5ce92d7993f0f.tar.gz orang-1fd741f7d5019b929affd29741b5ce92d7993f0f.tar.xz orang-1fd741f7d5019b929affd29741b5ce92d7993f0f.zip | |
Fix bug in checker that made it not execute and made ArgSpec less likely to cause accidental errors.
3 files changed, 32 insertions, 23 deletions
diff --git a/ast/src/main/java/lv/enes/orang/ast/ArgSpec.java b/ast/src/main/java/lv/enes/orang/ast/ArgSpec.java index 7fea2f4..8fa52be 100644 --- a/ast/src/main/java/lv/enes/orang/ast/ArgSpec.java +++ b/ast/src/main/java/lv/enes/orang/ast/ArgSpec.java | |||
| @@ -1,34 +1,39 @@ | |||
| 1 | package lv.enes.orang.ast; | 1 | package lv.enes.orang.ast; |
| 2 | 2 | ||
| 3 | public class ArgSpec { | 3 | public sealed interface ArgSpec { |
| 4 | public final Type type; | 4 | enum Type { |
| 5 | IGNORED, | ||
| 6 | NOTHING, | ||
| 7 | NAMED, | ||
| 8 | } | ||
| 5 | 9 | ||
| 6 | // non-null if NAMED | 10 | Type getType(); |
| 7 | public final String name; | ||
| 8 | 11 | ||
| 9 | private static final ArgSpec NOTHING = new ArgSpec(Type.NOTHING, null); | 12 | static Ignored ignored() { |
| 10 | private static final ArgSpec IGNORED = new ArgSpec(Type.IGNORED, null); | 13 | return Ignored.INSTANCE; |
| 14 | } | ||
| 11 | 15 | ||
| 12 | public static ArgSpec ignored() { | 16 | static Named named(String name) { |
| 13 | return IGNORED; | 17 | return new Named(name); |
| 14 | } | 18 | } |
| 15 | 19 | ||
| 16 | public static ArgSpec nothing() { | 20 | static Nothing nothing() { |
| 17 | return NOTHING; | 21 | return Nothing.INSTANCE; |
| 18 | } | 22 | } |
| 19 | 23 | ||
| 20 | public static ArgSpec named(String name) { | 24 | final class Ignored implements ArgSpec { |
| 21 | return new ArgSpec(Type.NAMED, name); | 25 | public static final Ignored INSTANCE = new Ignored(); |
| 26 | private Ignored() {} | ||
| 27 | @Override public Type getType() { return Type.IGNORED; } | ||
| 22 | } | 28 | } |
| 23 | 29 | ||
| 24 | private ArgSpec(Type type, String name) { | 30 | record Named(String name) implements ArgSpec { |
| 25 | this.type = type; | 31 | @Override public Type getType() { return Type.NAMED; } |
| 26 | this.name = name; | ||
| 27 | } | 32 | } |
| 28 | 33 | ||
| 29 | public enum Type { | 34 | final class Nothing implements ArgSpec { |
| 30 | IGNORED, | 35 | public static final Nothing INSTANCE = new Nothing(); |
| 31 | NOTHING, | 36 | private Nothing() {} |
| 32 | NAMED, | 37 | @Override public Type getType() { return Type.NOTHING; } |
| 33 | } | 38 | } |
| 34 | } | 39 | } |
diff --git a/checker/src/main/java/lv/enes/orang/checker/Checker.java b/checker/src/main/java/lv/enes/orang/checker/Checker.java index 446d3f1..14604b8 100644 --- a/checker/src/main/java/lv/enes/orang/checker/Checker.java +++ b/checker/src/main/java/lv/enes/orang/checker/Checker.java | |||
| @@ -58,7 +58,9 @@ public class Checker implements ExpressionVisitor<Void, CheckerException>, State | |||
| 58 | if (definitions.hasDefinition(def.name())) { | 58 | if (definitions.hasDefinition(def.name())) { |
| 59 | throw new CheckerException(STR."Top-level definition '\{def.name()}' redefined!"); | 59 | throw new CheckerException(STR."Top-level definition '\{def.name()}' redefined!"); |
| 60 | } | 60 | } |
| 61 | return new Checker(ImmutableScope.of(definitions, def.name(), true)); | 61 | var ch = new Checker(ImmutableScope.of(definitions, def.name(), true)); |
| 62 | ch.visit(def.body()); | ||
| 63 | return ch; | ||
| 62 | } | 64 | } |
| 63 | 65 | ||
| 64 | @Override | 66 | @Override |
| @@ -79,7 +81,9 @@ public class Checker implements ExpressionVisitor<Void, CheckerException>, State | |||
| 79 | public Void visitFnExpression(FnExpression expr) throws CheckerException { | 81 | public Void visitFnExpression(FnExpression expr) throws CheckerException { |
| 80 | var args = new HashMap<String, Boolean>(); | 82 | var args = new HashMap<String, Boolean>(); |
| 81 | for (var arg : expr.args()) { | 83 | for (var arg : expr.args()) { |
| 82 | args.put(arg.name, true); | 84 | if (arg instanceof ArgSpec.Named(String name)) { |
| 85 | args.put(name, true); | ||
| 86 | } | ||
| 83 | } | 87 | } |
| 84 | new Checker(ImmutableScope.of(definitions, args)).visit(expr.body()); | 88 | new Checker(ImmutableScope.of(definitions, args)).visit(expr.body()); |
| 85 | return null; | 89 | return null; |
diff --git a/orang/src/main/java/lv/enes/orang/value/PartialFunction.java b/orang/src/main/java/lv/enes/orang/value/PartialFunction.java index e73ba0c..d03bb13 100644 --- a/orang/src/main/java/lv/enes/orang/value/PartialFunction.java +++ b/orang/src/main/java/lv/enes/orang/value/PartialFunction.java | |||
| @@ -12,8 +12,8 @@ public record PartialFunction(Scope<Value> scope, NonEmptyList<ArgSpec> remainin | |||
| 12 | public static Value of(Scope<Value> scope, NonEmptyList<ArgSpec> remainingArgs, Expression body, Value param) throws OrangRuntimeException { | 12 | public static Value of(Scope<Value> scope, NonEmptyList<ArgSpec> remainingArgs, Expression body, Value param) throws OrangRuntimeException { |
| 13 | var spec = remainingArgs.getFirst(); | 13 | var spec = remainingArgs.getFirst(); |
| 14 | var newScope = MutableScope.of(scope); | 14 | var newScope = MutableScope.of(scope); |
| 15 | switch (spec.type) { | 15 | switch (spec.getType()) { |
| 16 | case NAMED -> newScope.setDefinition(spec.name, param); | 16 | case NAMED -> newScope.setDefinition(((ArgSpec.Named)spec).name(), param); |
| 17 | case NOTHING -> { | 17 | case NOTHING -> { |
| 18 | if (!(param instanceof Nothing)) { | 18 | if (!(param instanceof Nothing)) { |
| 19 | throw new OrangRuntimeException(STR."Expected () as a parameter but got \{param.typeName()}"); | 19 | throw new OrangRuntimeException(STR."Expected () as a parameter but got \{param.typeName()}"); |