validator validates recursive functions

This commit is contained in:
Scott Richmond 2024-12-11 15:36:23 -05:00
parent 35e9d0373d
commit 36c5d125fb
2 changed files with 13 additions and 6 deletions

View File

@ -161,15 +161,16 @@ pub fn run(src: &'static str) {
match result { match result {
Ok(result) => println!("{}", result), Ok(result) => println!("{}", result),
Err(LErr { msg, .. }) => println!("Errors!\n{}", msg), Err(LErr { msg, .. }) => println!("Ludus panicked!\n{}", msg),
} }
} }
pub fn main() { pub fn main() {
let src = " let src = "
let bar = :foo fn foo () -> {
fn foo (foo, bar, ...) -> bar foo
foo (42) }
foo () () () ()
"; ";
run(src); run(src);
// struct_scalpel::print_dissection_info::<value::Value>() // struct_scalpel::print_dissection_info::<value::Value>()

View File

@ -85,7 +85,9 @@ impl<'a> Validator<'a> {
} }
fn define_fn(&mut self, name: String, info: FnInfo) { fn define_fn(&mut self, name: String, info: FnInfo) {
self.locals.push((name, self.span, info)); let i = self.locals.iter().position(|(n, ..)| *n == name).unwrap();
let new_binding = (name, self.locals[i].1, info);
self.locals[i] = new_binding;
} }
fn resolved(&self, name: &str) -> bool { fn resolved(&self, name: &str) -> bool {
@ -415,8 +417,9 @@ impl<'a> Validator<'a> {
self.status.tail_position = tailpos; self.status.tail_position = tailpos;
} }
Fn(name, clauses, ..) => { Fn(name, clauses, ..) => {
let mut is_declared = false;
match self.bound(name) { match self.bound(name) {
Some((_, _, FnInfo::Declared)) => (), Some((_, _, FnInfo::Declared)) => is_declared = true,
None => (), None => (),
_ => { _ => {
self.err(format!("name `{name}` is already bound")); self.err(format!("name `{name}` is already bound"));
@ -424,6 +427,9 @@ impl<'a> Validator<'a> {
} }
// TODO: devise a placeholder binding for recursive functions // TODO: devise a placeholder binding for recursive functions
if !is_declared {
self.declare_fn(name.to_string());
}
let from = self.status.used_bindings.len(); let from = self.status.used_bindings.len();
let mut arities = HashSet::new(); let mut arities = HashSet::new();