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 #### Later
So this is my near-term TODO: So this is my near-term TODO:
* [ ] recursive calls * [x] recursive calls
- [ ] direct recursive calls - [x] direct recursive calls
* [ ] stash a function declaration before compiling the function, hang onto that declaration * [x] stash a function declaration before compiling the function, hang onto that declaration
* [ ] update that declaration to a definition after compiling the function * [x] update that declaration to a definition after compiling the function
- [ ] mutual recursive - [x] mutual recursive
* [ ] check to make sure a function has already been declared, hang onto that declaration * [x] check to make sure a function has already been declared, hang onto that declaration
* [ ] update that declaration to a definition after compiling the function... * [x] 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] 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. - 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 * [ ] getting to prelude
- [ ] `base` should load into 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 { pub fn assoc(dict: &Value, key: &Value, value: &Value) -> Value {
match (dict, key) { match (dict, key) {
(Value::Dict(d), Value::Keyword(k)) => Value::Dict(Box::new(d.update(k, value.clone()))), (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![ let members = vec![
("add", Value::BaseFn(BaseFn::Binary(add))), ("add", Value::BaseFn(BaseFn::Binary(add))),
("append", Value::BaseFn(BaseFn::Binary(append))), ("append", Value::BaseFn(BaseFn::Binary(append))),

View File

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

View File

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

View File

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