fix upvalue resolution for forward-declared functions
This commit is contained in:
parent
f2bae26e1c
commit
42a5f599f7
|
@ -968,8 +968,7 @@ fn err? {
|
|||
fn unwrap! {
|
||||
"Takes a result tuple. If it's :ok, then returns the value. If it's not :ok, then it panics. If it's not a result tuple, it also panics."
|
||||
((:ok, value)) -> value
|
||||
((:err, msg)) -> panic! string ("Unwrapped :err! ", msg)
|
||||
(_) -> panic! "Cannot unwrap something that's not an error tuple."
|
||||
((:err, msg)) -> panic! "Unwrapped :err! {msg}"
|
||||
}
|
||||
|
||||
fn unwrap_or {
|
||||
|
|
|
@ -494,6 +494,7 @@ Here's a list of things that need doing:
|
|||
- I need this fixed for optimization reasons.
|
||||
- I _think_ I just fixed this by fixing tail position tracking in collections
|
||||
- [ ] test this
|
||||
- I did not fix it.
|
||||
* [x] Dict patterns are giving me stack discipline grief. Why is stack discipline so hard?
|
||||
* [ ] This is in the service of getting turtle graphics working
|
||||
* Other forms in the language need help:
|
||||
|
@ -505,4 +506,15 @@ My solution to closures wasn't quite right.
|
|||
I can't use Uncle Bob's strategy of the recursive call, since Rust's ownership semantics make this onerous at best.
|
||||
My solution: introduce the concept of a "compiler depth," with 0 being the global scope.
|
||||
If the compiler's at 0 depth, we can pull it out of the environment.
|
||||
If the compiler's at a depth > 0, then we can ask the enclosing
|
||||
If the compiler's at a depth > 0, then we can ask the enclosing compiler to stash the upvalue.
|
||||
And thus we get what we need.
|
||||
|
||||
But: some functions in prelude aren't properly getting their closures, and I don't know why, since they *are* getting them properly in user scripts.
|
||||
Take `apply_command`.
|
||||
|
||||
Next step: sort out if any other functions aren't getting things closed over properly.
|
||||
|
||||
PROBLEM: forward-declared functions weren't at the top of the stack when `Op::SetUpvalue` was called.
|
||||
So all of `apply_command`'s upvalues were being attached to the function declared before it (which was sitting right there at the top of the stack.)
|
||||
|
||||
SOLUTION: test to see if the function has been forward-declared, and if it has, bring it to the top fo the stack.
|
||||
|
|
11
sandbox.ld
11
sandbox.ld
|
@ -1,9 +1,2 @@
|
|||
let nil? = :foo
|
||||
let mult = :bar
|
||||
|
||||
fn foo () -> {
|
||||
let fold = :baz
|
||||
fn quux () -> (nil?, mult, fold)
|
||||
}
|
||||
|
||||
foo () ()
|
||||
let state = unbox (turtle_state)
|
||||
apply_command(state, (:penup))
|
||||
|
|
10780
sandbox_run.txt
10780
sandbox_run.txt
File diff suppressed because it is too large
Load Diff
|
@ -1197,7 +1197,6 @@ impl Compiler {
|
|||
closed: RefCell::new(vec![]),
|
||||
};
|
||||
|
||||
// TODO: check if the function is already declared, and pull out the relevant OnceCell if need be
|
||||
let the_fn = Value::Fn(Rc::new(lfn));
|
||||
// self.emit_constant(the_fn);
|
||||
// self.bind(name);
|
||||
|
@ -1219,6 +1218,10 @@ impl Compiler {
|
|||
})
|
||||
.unwrap();
|
||||
self.chunk.constants[declaration_idx] = the_fn;
|
||||
// if the function been forward-declared, bring it to the top of the stack
|
||||
if declaration_idx < self.chunk.constants.len() - 1 {
|
||||
self.resolve_binding(name);
|
||||
}
|
||||
} else {
|
||||
self.emit_constant(the_fn)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user