diff --git a/may_2025_thoughts.md b/may_2025_thoughts.md index 5b2ebff..3c15c47 100644 --- a/may_2025_thoughts.md +++ b/may_2025_thoughts.md @@ -252,6 +252,7 @@ To reiterate the punch list that *I would have needed for Computer Class 1*: * [x] check loop forms against function calls: do they still work the way we want them to? * [x] tail call elimination * [x] stack traces in panics + * [ ] actually good error messages - [ ] parsing - [ ] my memory is that validator messages are already good? @@ -284,7 +285,51 @@ Just trying to get a sense of what needs to happen for CC2: * Why? * In the middle of doing TCO, looks like it works for `do` forms based on the bytecode, but I ran into these weird binding problems while trying to test that in the vm * Once that's put to bed, I believe TCO fully works + +_Edited to add: all the above is, I think, fixed._ + * But then I need to test it actually works in its intended use case: recursive calls * Which means I need to test recursive calls * And, once that's done, I think I have a COMPLETE SEMANTICALLY CORRECT INTERPRETER. * After that, jesus, it's time for base > prelude > test cases + +#### 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 + - 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 + - [ ] write a mock prelude with a few key functions from real prelude + - [ ] a prelude should be loaded into every context + - [ ] the full prelude should run properly +* [ ] packaging things up + - [ ] add a `to_json` method for values + - [ ] teach Rudus to speak our protocols (stdout and turtle graphics) + - [ ] there should be a Rust function that takes Ludus source and returns valid Ludus status json + - [ ] compile Rust to WASM + - [ ] wire Rust-based WASM into JS + - [ ] FINALLY, test Rudus against Ludus test cases + +And then: quality of life improvements: +* [ ] improve validator + - [ ] Tuples may not be longer than n members + - [ ] Loops may not have splatterns + - [ ] Identify others + - [ ] Splats in functions must be the same arity, and greater than any explicit arity +* [ ] actually good error messages + - [ ] parsing + - [ ] my memory is that validator messages are already good? + - [ ] panics, esp. no match panics + * [ ] panics should be able to refernce the line number where they fail + * [ ] that suggests that we need a mapping from bytecodes to AST nodes + * The way I had been planning on doing this is having a vec that moves in lockstep with bytecode that's just references to ast nodes, which are `'static`, so that shouldn't be too bad. But this is per-chunk, which means we need a reference to that vec in the VM. My sense is that what we want is actually a separate data structure that holds the AST nodes--we'll only need them in the sad path, which can be slow. + + diff --git a/src/compiler.rs b/src/compiler.rs index 9b43db2..e4e267a 100644 --- a/src/compiler.rs +++ b/src/compiler.rs @@ -1336,8 +1336,8 @@ impl<'a> Compiler<'a> { }; // TODO: check if the function is already declared, and pull out the relevant OnceCell if need be - let init_val = Value::Fn(Rc::new(lfn)); - self.emit_constant(init_val); + let the_fn = Value::Fn(Rc::new(lfn)); + self.emit_constant(the_fn); self.bind(name); for upvalue in upvalues { diff --git a/src/main.rs b/src/main.rs index 8b0185f..f673ee9 100644 --- a/src/main.rs +++ b/src/main.rs @@ -75,12 +75,7 @@ pub fn run(src: &'static str) { pub fn main() { env::set_var("RUST_BACKTRACE", "1"); let src = " -let whatevs = nil -let mult_factor = 3 -fn mymult (x) -> mult (x, mult_factor) -fn thing (x) -> mymult (x) - -thing (2) + "; run(src); }