From 16a20ee8b08df919e93ea1b878013f9a2ad709fa Mon Sep 17 00:00:00 2001 From: Uko Kokņevičs Date: Sat, 24 Aug 2024 03:54:25 +0800 Subject: Added fancier tuple argument specs. Made ArgSpec use visitor pattern to avoid problems the best way. Merged empty tuple and non-empty tuple classes. --- .../main/java/lv/enes/orang/checker/Checker.java | 43 ++++++++++++++++------ 1 file changed, 32 insertions(+), 11 deletions(-) (limited to 'checker/src/main/java') 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 @@ -64,12 +64,6 @@ public class Checker implements ExpressionVisitor, State return null; } - @Override - public Void visitEmptyTupleExpression() { - // Always ok - return null; - } - @Override public Checker visitExpression(ExpressionStatement expr) throws CheckerException { visit(expr.expr()); @@ -78,13 +72,40 @@ public class Checker implements ExpressionVisitor, State @Override public Void visitFnExpression(FnExpression expr) throws CheckerException { - var newScope = new HashSet<>(definitions); - for (var arg : expr.args()) { - if (arg instanceof ArgSpec.Named(String name)) { - newScope.add(name); + class Helper implements ArgSpecVisitor, CheckerException> { + private final HashSet scope = new HashSet<>(); + + @Override + public HashSet visitIgnored() { + // do nothing + return scope; + } + + @Override + public HashSet visitNamed(ArgSpecNamed named) throws CheckerException { + if (scope.contains(named.name())) { + throw new CheckerException(STR."Redefined argument \{named.name()}!"); + } + scope.add(named.name()); + return scope; + } + + @Override + public HashSet visitTuple(ArgSpecTuple tuple) throws CheckerException { + for (var child : tuple.children()) { + visit(child); + } + return scope; } } - new Checker(newScope).visit(expr.body()); + + var helper = new Helper(); + for (var arg : expr.args()) { + helper.visit(arg); + } + + helper.scope.addAll(definitions); + new Checker(helper.scope).visit(expr.body()); return null; } -- cgit v1.2.3