get closing working?

This commit is contained in:
Scott Richmond 2024-12-11 16:43:13 -05:00
parent 65492d0810
commit 567d3da4be
3 changed files with 41 additions and 16 deletions

View File

@ -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 = &ast;
let mut proc = prelude();
proc.ast = &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);

View File

@ -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<String>,
@ -28,11 +30,13 @@ impl LErr {
type LResult<'src> = Result<Value<'src>, 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)

View File

@ -12,6 +12,7 @@ pub struct Fn<'src> {
pub name: String,
pub body: &'src Vec<Spanned<Ast>>,
pub doc: Option<String>,
pub enclosing: Vec<(String, Value<'src>)>,
}
#[derive(Debug, Dissectible)]