fix loop validation bugs
This commit is contained in:
parent
ac4bd0fb55
commit
49a0b0f8a7
|
@ -52,7 +52,6 @@ fn ordered? {
|
||||||
fn assoc? {
|
fn assoc? {
|
||||||
"Returns true if a value is an associative collection: a dict or a pkg."
|
"Returns true if a value is an associative collection: a dict or a pkg."
|
||||||
(d as :dict) -> true
|
(d as :dict) -> true
|
||||||
(p as :pkg) -> true
|
|
||||||
(_) -> false
|
(_) -> false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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 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!}
|
||||||
|
|
14
src/main.rs
14
src/main.rs
|
@ -169,6 +169,11 @@ pub fn run(src: &'static str) {
|
||||||
|
|
||||||
v6or.validate();
|
v6or.validate();
|
||||||
|
|
||||||
|
if !v6or.errors.is_empty() {
|
||||||
|
report_invalidation(v6or.errors);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
prelude_fn_info.extend(&mut v6or.fn_info.into_iter());
|
prelude_fn_info.extend(&mut v6or.fn_info.into_iter());
|
||||||
|
|
||||||
let mut proc = Process {
|
let mut proc = Process {
|
||||||
|
@ -191,8 +196,13 @@ pub fn run(src: &'static str) {
|
||||||
|
|
||||||
pub fn main() {
|
pub fn main() {
|
||||||
let src = "
|
let src = "
|
||||||
fn foo () -> panics! ()
|
loop (10) with {
|
||||||
foo ()
|
(0) -> :done
|
||||||
|
(n) -> {
|
||||||
|
print! (n)
|
||||||
|
recur (dec (n))
|
||||||
|
}
|
||||||
|
}
|
||||||
";
|
";
|
||||||
run(src);
|
run(src);
|
||||||
// struct_scalpel::print_dissection_info::<value::Value>()
|
// struct_scalpel::print_dissection_info::<value::Value>()
|
||||||
|
|
|
@ -536,32 +536,40 @@ impl<'a, 'src: 'a> Validator<'a, 'src> {
|
||||||
unreachable!()
|
unreachable!()
|
||||||
};
|
};
|
||||||
|
|
||||||
|
dbg!(&input);
|
||||||
|
|
||||||
|
let tailpos = self.status.tail_position;
|
||||||
|
self.status.tail_position = true;
|
||||||
let in_loop = self.status.in_loop;
|
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.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 {
|
for clause in body {
|
||||||
let (expr, span) = clause;
|
let (expr, span) = clause;
|
||||||
self.ast = expr;
|
self.ast = expr;
|
||||||
self.span = *span;
|
self.span = *span;
|
||||||
match self.arity() {
|
let arity = self.arity();
|
||||||
|
dbg!(&arity);
|
||||||
|
match arity {
|
||||||
Arity::Fixed(clause_arity) => {
|
Arity::Fixed(clause_arity) => {
|
||||||
if clause_arity != arity {
|
if clause_arity != loop_arity {
|
||||||
self.err(format!("mismatched arity: expected {arity} arguments in `loop` clause; got {clause_arity}"))
|
self.err(format!("mismatched arity: expected {loop_arity} arguments in `loop` clause; got {clause_arity}"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Arity::Splat(clause_arity) => {
|
Arity::Splat(clause_arity) => {
|
||||||
if clause_arity > arity {
|
if clause_arity > loop_arity {
|
||||||
self.err(format!("mismathced arity: expected {arity} arguments in `loop` clause; this clause takes {clause_arity} or more"))
|
self.err(format!("mismathced arity: expected {loop_arity} arguments in `loop` clause; this clause takes {clause_arity} or more"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
self.validate();
|
self.validate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
self.status.tail_position = tailpos;
|
||||||
self.status.in_loop = in_loop;
|
self.status.in_loop = in_loop;
|
||||||
self.status.loop_arity = arity;
|
self.status.loop_arity = outer_arity;
|
||||||
}
|
}
|
||||||
Recur(args) => {
|
Recur(args) => {
|
||||||
if !self.status.in_loop {
|
if !self.status.in_loop {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user