From 567d3da4bed59e61ece7e0a816e5de7aae32b4a9 Mon Sep 17 00:00:00 2001 From: Scott Richmond Date: Wed, 11 Dec 2024 16:43:13 -0500 Subject: [PATCH] get closing working? --- src/main.rs | 31 ++++++++++++++++--------------- src/process.rs | 25 ++++++++++++++++++++++++- src/value.rs | 1 + 3 files changed, 41 insertions(+), 16 deletions(-) diff --git a/src/main.rs b/src/main.rs index 5188a66..52868d0 100644 --- a/src/main.rs +++ b/src/main.rs @@ -87,14 +87,20 @@ pub fn prelude<'src>() -> Process<'src> { panic!(); } - let p_ast = Box::leak(Box::new(p_ast.unwrap().0)); + let (p_ast, p_span) = Box::leak(Box::new(p_ast.unwrap())); let base_pkg = base(); + let base_names = base_pkg.iter().map(|binding| binding.0.clone()).collect(); + + let mut v6or = Validator::new(p_ast, *p_span, &base_names); + v6or.validate(); + let mut base_ctx = Process::<'src> { locals: vec![], ast: p_ast, prelude: base_pkg, args: Value::Nil, + fn_info: v6or.fn_info, }; let prelude = base_ctx.eval(); @@ -123,6 +129,7 @@ pub fn prelude<'src>() -> Process<'src> { ast: &Ast::Nil, prelude: p_ctx, args: Value::Nil, + fn_info: base_ctx.fn_info, } } @@ -147,16 +154,17 @@ pub fn run(src: &'static str) { let dummy_prelude = vec![]; - let mut v6or = validator::Validator::new(&ast, span, &dummy_prelude); + let mut v6or = Validator::new(&ast, span, &dummy_prelude); v6or.validate(); - dbg!(v6or); + dbg!(&v6or); - let mut ctx = prelude(); - ctx.ast = * + let mut proc = prelude(); + proc.ast = * + proc.fn_info.extend(&mut v6or.fn_info.into_iter()); - let result = ctx.eval(); + let result = proc.eval(); match result { Ok(result) => println!("{}", result), @@ -166,15 +174,8 @@ pub fn run(src: &'static str) { pub fn main() { let src = " -fn bar - -fn foo { - () -> bar(:foo) - (:bar) -> :done -} - -fn bar (_) -> :bar - +let bar = :bar +fn foo () -> bar foo () "; run(src); diff --git a/src/process.rs b/src/process.rs index a948427..d53f356 100644 --- a/src/process.rs +++ b/src/process.rs @@ -1,12 +1,14 @@ use crate::base::*; use crate::parser::*; use crate::spans::*; +use crate::validator::FnInfo; use crate::value::Value; use imbl::HashMap; use imbl::Vector; use std::cell::RefCell; use std::rc::Rc; +#[derive(Debug)] pub struct LErr { pub msg: String, pub trace: Vec, @@ -28,11 +30,13 @@ impl LErr { type LResult<'src> = Result, LErr>; +#[derive(Debug)] pub struct Process<'src> { pub locals: Vec<(String, Value<'src>)>, pub prelude: Vec<(String, Value<'src>)>, pub ast: &'src Ast, pub args: Value<'src>, + pub fn_info: std::collections::HashMap<*const Ast, FnInfo>, } impl<'src> Process<'src> { @@ -255,8 +259,14 @@ impl<'src> Process<'src> { } (Fn(f), Tuple(args)) => { let args = Tuple(args); - self.match_clauses(&args, f.body) + let to = self.locals.len(); + let mut enclosing = f.enclosing.clone(); + self.locals.append(&mut enclosing); + let result = self.match_clauses(&args, f.body); + self.locals.truncate(to); + result } + // TODO: partially applied functions shnould work! In #15 (Fn(_f), Args(_args)) => todo!(), (_, Keyword(_)) => Ok(Nil), (_, Args(_)) => Err(LErr::new("you may only call a function".to_string())), @@ -491,10 +501,23 @@ impl<'src> Process<'src> { } Fn(name, clauses, doc) => { let doc = doc.map(|s| s.to_string()); + let ptr: *const Ast = root; + dbg!(&root); + dbg!(&ptr); + dbg!(&self.fn_info); + let info = self.fn_info.get(&ptr).unwrap(); + let FnInfo::Defined(_, enclosing) = info else { + unreachable!() + }; + let enclosing = enclosing + .iter() + .map(|name| (name.clone(), self.resolve(name).unwrap().clone())) + .collect(); let the_fn = Value::Fn::<'src>(Rc::new(crate::value::Fn::<'src> { name: name.to_string(), body: clauses, doc, + enclosing, })); self.bind(name.to_string(), &the_fn); Ok(the_fn) diff --git a/src/value.rs b/src/value.rs index fa3456a..d8fb62b 100644 --- a/src/value.rs +++ b/src/value.rs @@ -12,6 +12,7 @@ pub struct Fn<'src> { pub name: String, pub body: &'src Vec>, pub doc: Option, + pub enclosing: Vec<(String, Value<'src>)>, } #[derive(Debug, Dissectible)]