fix argument order in base fns

This commit is contained in:
Scott Richmond 2025-06-20 12:49:31 -04:00
parent e580d68809
commit ef134c0335
5 changed files with 29 additions and 19 deletions

View File

@ -296,14 +296,14 @@ _Edited to add: all the above is, I think, fixed._
#### Later
So this is my near-term TODO:
* [ ] recursive calls
- [ ] direct recursive calls
* [ ] stash a function declaration before compiling the function, hang onto that declaration
* [ ] update that declaration to a definition after compiling the function
- [ ] mutual recursive
* [ ] check to make sure a function has already been declared, hang onto that declaration
* [ ] update that declaration to a definition after compiling the function...
* [ ] but BEFORE we close over any upvalues, so the function will be an upvalue for itself
* [x] recursive calls
- [x] direct recursive calls
* [x] stash a function declaration before compiling the function, hang onto that declaration
* [x] update that declaration to a definition after compiling the function
- [x] mutual recursive
* [x] check to make sure a function has already been declared, hang onto that declaration
* [x] update that declaration to a definition after compiling the function...
* [x] but BEFORE we close over any upvalues, so the function will be an upvalue for itself
- I suspect this can be done not using anything other than an index into a chunk's `constants` vec--no fancy memory swapping or anything; and also--done in the compiler rather than the VM.
* [ ] getting to prelude
- [ ] `base` should load into Prelude

View File

@ -61,7 +61,7 @@ pub fn doc(f: &Value) -> Value {
pub fn assoc(dict: &Value, key: &Value, value: &Value) -> Value {
match (dict, key) {
(Value::Dict(d), Value::Keyword(k)) => Value::Dict(Box::new(d.update(k, value.clone()))),
_ => unreachable!("internal Ludus error"),
_ => unreachable!("internal Ludus error calling assoc with ({dict}, {key}, {value})"),
}
}
@ -579,7 +579,7 @@ pub fn r#mod(x: &Value, y: &Value) -> Value {
}
}
pub fn base() -> Value {
pub fn make_base() -> Value {
let members = vec![
("add", Value::BaseFn(BaseFn::Binary(add))),
("append", Value::BaseFn(BaseFn::Binary(append))),

View File

@ -443,7 +443,7 @@ impl<'a> Compiler<'a> {
self.chunk.bytecode[i + 2] = low;
}
fn emit_constant(&mut self, val: Value) {
pub fn emit_constant(&mut self, val: Value) {
let const_idx = if let Some(idx) = self.chunk.constants.iter().position(|v| *v == val) {
idx
} else {
@ -494,7 +494,7 @@ impl<'a> Compiler<'a> {
self.chunk.bytecode.len()
}
fn bind(&mut self, name: &'static str) {
pub fn bind(&mut self, name: &'static str) {
let binding = Binding {
name,
depth: self.scope_depth,

View File

@ -47,7 +47,12 @@ pub fn run(src: &'static str) {
// in any event, the AST should live forever
let parsed: &'static Spanned<Ast> = Box::leak(Box::new(parse_result.unwrap()));
let base = base::make_base();
let mut compiler = Compiler::new(parsed, "test", src, None);
compiler.emit_constant(base);
compiler.bind("base");
compiler.compile();
if DEBUG_COMPILE {
println!("=== source code ===");
@ -75,11 +80,7 @@ pub fn run(src: &'static str) {
pub fn main() {
env::set_var("RUST_BACKTRACE", "1");
let src = "
fn two
fn one (x, y) -> two (x, y)
fn two (:foo, x) -> (:done, x)
one (:fool, :bar)
base :assoc (#{:a 1}, :b, 2)
";
run(src);
}

View File

@ -1004,8 +1004,17 @@ impl Vm {
let value = match (arity, base_fn) {
(0, BaseFn::Nullary(f)) => f(),
(1, BaseFn::Unary(f)) => f(&self.pop()),
(2, BaseFn::Binary(f)) => f(&self.pop(), &self.pop()),
(3, BaseFn::Ternary(f)) => f(&self.pop(), &self.pop(), &self.pop()),
(2, BaseFn::Binary(f)) => {
let y = &self.pop();
let x = &self.pop();
f(x, y)
}
(3, BaseFn::Ternary(f)) => {
let z = &self.pop();
let y = &self.pop();
let x = &self.pop();
f(x, y, z)
}
_ => return self.panic("internal ludus error"),
};
self.push(value);