fix loop validation bugs

This commit is contained in:
Scott Richmond 2024-12-12 19:28:55 -05:00
parent ac4bd0fb55
commit 49a0b0f8a7
4 changed files with 30 additions and 13 deletions

View File

@ -52,7 +52,6 @@ fn ordered? {
fn assoc? {
"Returns true if a value is an associative collection: a dict or a pkg."
(d as :dict) -> true
(p as :pkg) -> true
(_) -> false
}

View File

@ -10,6 +10,6 @@ fn dec (n as :number) -> base :sub (n, 1)
fn sub (x as :number, y as :number) -> base :sub (x, y)
fn panics! () -> add ("foo", "bar")
fn print!(x) -> base :print! (x)
#{add, dec, sub, panics!}
#{add, dec, sub, print!}

View File

@ -169,6 +169,11 @@ pub fn run(src: &'static str) {
v6or.validate();
if !v6or.errors.is_empty() {
report_invalidation(v6or.errors);
return;
}
prelude_fn_info.extend(&mut v6or.fn_info.into_iter());
let mut proc = Process {
@ -191,8 +196,13 @@ pub fn run(src: &'static str) {
pub fn main() {
let src = "
fn foo () -> panics! ()
foo ()
loop (10) with {
(0) -> :done
(n) -> {
print! (n)
recur (dec (n))
}
}
";
run(src);
// struct_scalpel::print_dissection_info::<value::Value>()

View File

@ -536,32 +536,40 @@ impl<'a, 'src: 'a> Validator<'a, 'src> {
unreachable!()
};
dbg!(&input);
let tailpos = self.status.tail_position;
self.status.tail_position = true;
let in_loop = self.status.in_loop;
let arity = self.status.loop_arity;
let outer_arity = self.status.loop_arity;
self.status.in_loop = true;
self.status.loop_arity = input.len() as u8;
let loop_arity = input.len() as u8;
self.status.loop_arity = loop_arity;
for clause in body {
let (expr, span) = clause;
self.ast = expr;
self.span = *span;
match self.arity() {
let arity = self.arity();
dbg!(&arity);
match arity {
Arity::Fixed(clause_arity) => {
if clause_arity != arity {
self.err(format!("mismatched arity: expected {arity} arguments in `loop` clause; got {clause_arity}"))
if clause_arity != loop_arity {
self.err(format!("mismatched arity: expected {loop_arity} arguments in `loop` clause; got {clause_arity}"))
}
}
Arity::Splat(clause_arity) => {
if clause_arity > arity {
self.err(format!("mismathced arity: expected {arity} arguments in `loop` clause; this clause takes {clause_arity} or more"))
if clause_arity > loop_arity {
self.err(format!("mismathced arity: expected {loop_arity} arguments in `loop` clause; this clause takes {clause_arity} or more"))
}
}
};
self.validate();
}
self.status.tail_position = tailpos;
self.status.in_loop = in_loop;
self.status.loop_arity = arity;
self.status.loop_arity = outer_arity;
}
Recur(args) => {
if !self.status.in_loop {