From e9b52e14882e149588d27e58772df18bdd843234 Mon Sep 17 00:00:00 2001 From: Scott Richmond Date: Tue, 10 Dec 2024 17:39:02 -0500 Subject: [PATCH] improve do & recur errs --- src/main.rs | 5 +---- src/validator.rs | 19 +++++++++++++++++-- 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/src/main.rs b/src/main.rs index 01c2d7b..b30d8fa 100644 --- a/src/main.rs +++ b/src/main.rs @@ -167,10 +167,7 @@ pub fn run(src: &'static str) { pub fn main() { let src = " -match foo with { - :a -> :b - :c -> :d -} +do 42 > recur () "; run(src); // struct_scalpel::print_dissection_info::() diff --git a/src/validator.rs b/src/validator.rs index d9e737e..64b77e9 100644 --- a/src/validator.rs +++ b/src/validator.rs @@ -282,6 +282,8 @@ impl<'a> Validator<'a> { self.ast = expr; self.span = *span; self.validate(); + + //TODO: check arity of call } _ => unreachable!(), } @@ -389,13 +391,25 @@ impl<'a> Validator<'a> { self.validate(); self.status.tail_position = tailpos; } + // TODO: fix the tail call here? Ast::Do(terms) => { - for term in terms { + if terms.len() < 2 { + return self.err("do expressions must have at least two terms".to_string()); + } + for term in terms.iter().take(terms.len() - 1) { let (expr, span) = term; self.ast = expr; self.span = *span; self.validate(); } + + let (expr, span) = terms.last().unwrap(); + self.ast = expr; + self.span = *span; + if matches!(expr, Ast::Recur(_)) { + self.err("`recur` may not be used in `do` forms".to_string()); + } + self.validate(); } Ast::Repeat(times, body) => { self.status.tail_position = false; @@ -427,7 +441,8 @@ impl<'a> Validator<'a> { } Ast::Recur(args) => { if !self.status.in_loop { - self.err("you may only use `recur` in a loop form".to_string()); + self.err("you may only use `recur` in a `loop` form".to_string()); + return; } if !self.status.tail_position { self.err("you may only use `recur` in tail position".to_string());