notes and comments
This commit is contained in:
parent
ef0ac40dbe
commit
40d4f48878
|
@ -229,3 +229,11 @@ struct StackFrame<'a> {
|
||||||
|
|
||||||
This gives us a way to access everything we need: where to return to, the root of the stack, the chunk (function->chunk), the closures (function->closures).
|
This gives us a way to access everything we need: where to return to, the root of the stack, the chunk (function->chunk), the closures (function->closures).
|
||||||
|
|
||||||
|
### 2024-12-26
|
||||||
|
One particular concern here, which needs some work: recursion is challenging.
|
||||||
|
|
||||||
|
In particular, the issue is that if, as I have been planning, a function closes over all its values at the moment it is compiled, the only value type that requires updating is a function. A function can be declared but not yet defined, and then when another function that uses that function is defined, the closed-over value will be to the declaration but not the definition.
|
||||||
|
|
||||||
|
One way to handle this, I think is using `std::cell::OnceCell`. Rather than a `RefCell`, `OnceCell` has no runtime overhead. Instead, what happens is you effectively put a `None` in the cell. Then, once you have the value you want to put in there, you call `set` on the `OnceCell`, and it does what it needs to.
|
||||||
|
|
||||||
|
This allows for the closures to be closed over right after compilation.
|
||||||
|
|
|
@ -4,6 +4,7 @@ use crate::value::*;
|
||||||
use chumsky::prelude::SimpleSpan;
|
use chumsky::prelude::SimpleSpan;
|
||||||
use num_derive::{FromPrimitive, ToPrimitive};
|
use num_derive::{FromPrimitive, ToPrimitive};
|
||||||
use num_traits::FromPrimitive;
|
use num_traits::FromPrimitive;
|
||||||
|
use std::cell::OnceCell;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, FromPrimitive, ToPrimitive)]
|
#[derive(Copy, Clone, Debug, PartialEq, Eq, FromPrimitive, ToPrimitive)]
|
||||||
|
@ -434,23 +435,35 @@ impl Chunk {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Fn(name, body, doc) => {
|
Fn(name, body, doc) => {
|
||||||
|
// first, declare the function
|
||||||
|
// TODO: or, check if the function has already been declared!
|
||||||
|
let init_val = Value::Fn(Rc::new(OnceCell::new()));
|
||||||
|
self.emit_constant(init_val);
|
||||||
|
self.bind(name);
|
||||||
|
|
||||||
|
// compile the function
|
||||||
let mut chunk = Chunk::new(body, self.name, self.src);
|
let mut chunk = Chunk::new(body, self.name, self.src);
|
||||||
chunk.compile();
|
chunk.compile();
|
||||||
if crate::DEBUG_COMPILE {
|
if crate::DEBUG_COMPILE {
|
||||||
println!("==function: {name}==");
|
println!("==function: {name}==");
|
||||||
chunk.disassemble();
|
chunk.disassemble();
|
||||||
}
|
}
|
||||||
|
|
||||||
let lfn = crate::value::LFn {
|
let lfn = crate::value::LFn {
|
||||||
name,
|
name,
|
||||||
doc: *doc,
|
doc: *doc,
|
||||||
chunk,
|
chunk,
|
||||||
|
closed: vec![],
|
||||||
};
|
};
|
||||||
let fn_val = Value::Fn(Rc::new(lfn));
|
|
||||||
self.emit_constant(fn_val);
|
// TODO: close over everything accessed in the function
|
||||||
self.bind(name);
|
|
||||||
|
// TODO: pull the function off the stack, and set the OnceCell.
|
||||||
}
|
}
|
||||||
FnDeclaration(name) => {
|
FnDeclaration(name) => {
|
||||||
todo!()
|
let lfn = Value::Fn(Rc::new(OnceCell::new()));
|
||||||
|
self.emit_constant(lfn);
|
||||||
|
self.bind(name);
|
||||||
}
|
}
|
||||||
FnBody(clauses) => {
|
FnBody(clauses) => {
|
||||||
self.emit_op(Op::ResetMatch);
|
self.emit_op(Op::ResetMatch);
|
||||||
|
|
|
@ -2,7 +2,7 @@ use crate::compiler::Chunk;
|
||||||
use crate::parser::Ast;
|
use crate::parser::Ast;
|
||||||
use crate::spans::Spanned;
|
use crate::spans::Spanned;
|
||||||
use imbl::{HashMap, Vector};
|
use imbl::{HashMap, Vector};
|
||||||
use std::cell::RefCell;
|
use std::cell::{OnceCell, RefCell};
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq)]
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
|
@ -37,7 +37,7 @@ pub enum Value {
|
||||||
List(Box<Vector<Value>>),
|
List(Box<Vector<Value>>),
|
||||||
Dict(Box<HashMap<usize, Value>>),
|
Dict(Box<HashMap<usize, Value>>),
|
||||||
Box(Rc<RefCell<Value>>),
|
Box(Rc<RefCell<Value>>),
|
||||||
Fn(Rc<LFn>),
|
Fn(Rc<OnceCell<LFn>>),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl std::fmt::Display for Value {
|
impl std::fmt::Display for Value {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user