diff options
| author | 2024-08-24 03:54:25 +0800 | |
|---|---|---|
| committer | 2024-08-24 03:54:25 +0800 | |
| commit | 16a20ee8b08df919e93ea1b878013f9a2ad709fa (patch) | |
| tree | 80d59e93c566ddba1e2116e8d64222b8036b216e /checker/src | |
| parent | Add tuples. (diff) | |
| download | orang-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 'checker/src')
| -rw-r--r-- | checker/src/main/java/lv/enes/orang/checker/Checker.java | 43 |
1 files changed, 32 insertions, 11 deletions
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 66b7dac..f926f59 100644 --- a/checker/src/main/java/lv/enes/orang/checker/Checker.java +++ b/checker/src/main/java/lv/enes/orang/checker/Checker.java | |||
| @@ -65,12 +65,6 @@ public class Checker implements ExpressionVisitor<Void, CheckerException>, State | |||
| 65 | } | 65 | } |
| 66 | 66 | ||
| 67 | @Override | 67 | @Override |
| 68 | public Void visitEmptyTupleExpression() { | ||
| 69 | // Always ok | ||
| 70 | return null; | ||
| 71 | } | ||
| 72 | |||
| 73 | @Override | ||
| 74 | public Checker visitExpression(ExpressionStatement expr) throws CheckerException { | 68 | public Checker visitExpression(ExpressionStatement expr) throws CheckerException { |
| 75 | visit(expr.expr()); | 69 | visit(expr.expr()); |
| 76 | return this; | 70 | return this; |
| @@ -78,13 +72,40 @@ public class Checker implements ExpressionVisitor<Void, CheckerException>, State | |||
| 78 | 72 | ||
| 79 | @Override | 73 | @Override |
| 80 | public Void visitFnExpression(FnExpression expr) throws CheckerException { | 74 | public Void visitFnExpression(FnExpression expr) throws CheckerException { |
| 81 | var newScope = new HashSet<>(definitions); | 75 | class Helper implements ArgSpecVisitor<HashSet<String>, CheckerException> { |
| 82 | for (var arg : expr.args()) { | 76 | private final HashSet<String> scope = new HashSet<>(); |
| 83 | if (arg instanceof ArgSpec.Named(String name)) { | 77 | |
| 84 | newScope.add(name); | 78 | @Override |
| 79 | public HashSet<String> visitIgnored() { | ||
| 80 | // do nothing | ||
| 81 | return scope; | ||
| 82 | } | ||
| 83 | |||
| 84 | @Override | ||
| 85 | public HashSet<String> visitNamed(ArgSpecNamed named) throws CheckerException { | ||
| 86 | if (scope.contains(named.name())) { | ||
| 87 | throw new CheckerException(STR."Redefined argument \{named.name()}!"); | ||
| 88 | } | ||
| 89 | scope.add(named.name()); | ||
| 90 | return scope; | ||
| 91 | } | ||
| 92 | |||
| 93 | @Override | ||
| 94 | public HashSet<String> visitTuple(ArgSpecTuple tuple) throws CheckerException { | ||
| 95 | for (var child : tuple.children()) { | ||
| 96 | visit(child); | ||
| 97 | } | ||
| 98 | return scope; | ||
| 85 | } | 99 | } |
| 86 | } | 100 | } |
| 87 | new Checker(newScope).visit(expr.body()); | 101 | |
| 102 | var helper = new Helper(); | ||
| 103 | for (var arg : expr.args()) { | ||
| 104 | helper.visit(arg); | ||
| 105 | } | ||
| 106 | |||
| 107 | helper.scope.addAll(definitions); | ||
| 108 | new Checker(helper.scope).visit(expr.body()); | ||
| 88 | return null; | 109 | return null; |
| 89 | } | 110 | } |
| 90 | 111 | ||