diff --git a/src/main.rs b/src/main.rs index b30d8fa..85a51d6 100644 --- a/src/main.rs +++ b/src/main.rs @@ -167,7 +167,9 @@ pub fn run(src: &'static str) { pub fn main() { let src = " -do 42 > recur () +loop () with { + () -> :baz +} "; run(src); // struct_scalpel::print_dissection_info::() diff --git a/src/validator.rs b/src/validator.rs index 64b77e9..f73a5e4 100644 --- a/src/validator.rs +++ b/src/validator.rs @@ -18,6 +18,7 @@ impl VErr { struct VStatus { tail_position: bool, in_loop: bool, + loop_arity: u8, last_term: bool, has_placeholder: bool, used_bindings: Vec, @@ -60,6 +61,7 @@ impl<'a> Validator<'a> { status: VStatus { tail_position: false, in_loop: false, + loop_arity: 0, last_term: false, has_placeholder: false, used_bindings: vec![], @@ -429,15 +431,19 @@ impl<'a> Validator<'a> { self.ast = expr; self.validate(); - let in_loop = self.status.in_loop; - self.status.in_loop = true; + let Ast::Tuple(input) = expr else { + unreachable!() + }; - // let (expr, span) = body; - // self.span = span; - // self.expr = expr; - // self.validate(); + let in_loop = self.status.in_loop; + let arity = self.status.loop_arity; + self.status.in_loop = true; + self.status.loop_arity = input.len() as u8; + + // for clause in body {} self.status.in_loop = in_loop; + self.status.loop_arity = arity; } Ast::Recur(args) => { if !self.status.in_loop { @@ -448,6 +454,12 @@ impl<'a> Validator<'a> { self.err("you may only use `recur` in tail position".to_string()); } + let num_args = args.len() as u8; + let loop_arity = self.status.loop_arity; + if num_args != loop_arity { + self.err(format!("loop arity mismatch: loop has arity of {loop_arity}; `recur` called with {num_args} arguments")) + } + self.status.tail_position = false; for arg in args { let (expr, span) = arg;