summaryrefslogtreecommitdiff
path: root/checker/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 /checker/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 'checker/src')
-rw-r--r--checker/src/main/java/lv/enes/orang/checker/Checker.java43
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