loop arity checking
This commit is contained in:
parent
e9b52e1488
commit
dde9ac4bff
|
@ -167,7 +167,9 @@ pub fn run(src: &'static str) {
|
||||||
|
|
||||||
pub fn main() {
|
pub fn main() {
|
||||||
let src = "
|
let src = "
|
||||||
do 42 > recur ()
|
loop () with {
|
||||||
|
() -> :baz
|
||||||
|
}
|
||||||
";
|
";
|
||||||
run(src);
|
run(src);
|
||||||
// struct_scalpel::print_dissection_info::<value::Value>()
|
// struct_scalpel::print_dissection_info::<value::Value>()
|
||||||
|
|
|
@ -18,6 +18,7 @@ impl VErr {
|
||||||
struct VStatus {
|
struct VStatus {
|
||||||
tail_position: bool,
|
tail_position: bool,
|
||||||
in_loop: bool,
|
in_loop: bool,
|
||||||
|
loop_arity: u8,
|
||||||
last_term: bool,
|
last_term: bool,
|
||||||
has_placeholder: bool,
|
has_placeholder: bool,
|
||||||
used_bindings: Vec<String>,
|
used_bindings: Vec<String>,
|
||||||
|
@ -60,6 +61,7 @@ impl<'a> Validator<'a> {
|
||||||
status: VStatus {
|
status: VStatus {
|
||||||
tail_position: false,
|
tail_position: false,
|
||||||
in_loop: false,
|
in_loop: false,
|
||||||
|
loop_arity: 0,
|
||||||
last_term: false,
|
last_term: false,
|
||||||
has_placeholder: false,
|
has_placeholder: false,
|
||||||
used_bindings: vec![],
|
used_bindings: vec![],
|
||||||
|
@ -429,15 +431,19 @@ impl<'a> Validator<'a> {
|
||||||
self.ast = expr;
|
self.ast = expr;
|
||||||
self.validate();
|
self.validate();
|
||||||
|
|
||||||
let in_loop = self.status.in_loop;
|
let Ast::Tuple(input) = expr else {
|
||||||
self.status.in_loop = true;
|
unreachable!()
|
||||||
|
};
|
||||||
|
|
||||||
// let (expr, span) = body;
|
let in_loop = self.status.in_loop;
|
||||||
// self.span = span;
|
let arity = self.status.loop_arity;
|
||||||
// self.expr = expr;
|
self.status.in_loop = true;
|
||||||
// self.validate();
|
self.status.loop_arity = input.len() as u8;
|
||||||
|
|
||||||
|
// for clause in body {}
|
||||||
|
|
||||||
self.status.in_loop = in_loop;
|
self.status.in_loop = in_loop;
|
||||||
|
self.status.loop_arity = arity;
|
||||||
}
|
}
|
||||||
Ast::Recur(args) => {
|
Ast::Recur(args) => {
|
||||||
if !self.status.in_loop {
|
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());
|
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;
|
self.status.tail_position = false;
|
||||||
for arg in args {
|
for arg in args {
|
||||||
let (expr, span) = arg;
|
let (expr, span) = arg;
|
||||||
|
|
Loading…
Reference in New Issue
Block a user