find a bug in function bindings; TCO is maybe complete?; things are in a shambles
This commit is contained in:
parent
7e4ddd3dc4
commit
8b004b45fa
|
@ -250,8 +250,8 @@ To reiterate the punch list that *I would have needed for Computer Class 1*:
|
||||||
- [ ] Identify others
|
- [ ] Identify others
|
||||||
* [x] add guards to loop forms
|
* [x] add guards to loop forms
|
||||||
* [x] check loop forms against function calls: do they still work the way we want them to?
|
* [x] check loop forms against function calls: do they still work the way we want them to?
|
||||||
* [ ] tail call elimination
|
* [x] tail call elimination
|
||||||
* [ ] stack traces in panics
|
* [x] stack traces in panics
|
||||||
* [ ] actually good error messages
|
* [ ] actually good error messages
|
||||||
- [ ] parsing
|
- [ ] parsing
|
||||||
- [ ] my memory is that validator messages are already good?
|
- [ ] my memory is that validator messages are already good?
|
||||||
|
@ -277,3 +277,14 @@ Just trying to get a sense of what needs to happen for CC2:
|
||||||
- [ ] Makey makey for alternate input?
|
- [ ] Makey makey for alternate input?
|
||||||
* [ ] Saving and loading data into Ludus (perceptrons, dissociated press)
|
* [ ] Saving and loading data into Ludus (perceptrons, dissociated press)
|
||||||
* [ ] Finding corpuses for Dissociated Press
|
* [ ] Finding corpuses for Dissociated Press
|
||||||
|
|
||||||
|
### Final touches on semantics, or lots of bugs
|
||||||
|
#### 2025-06-19
|
||||||
|
* Main code is fucking up bindings in functions
|
||||||
|
* 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
|
||||||
|
* 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
|
||||||
|
|
|
@ -1095,10 +1095,7 @@ impl<'a> Compiler<'a> {
|
||||||
}
|
}
|
||||||
self.resolve_binding(fn_name);
|
self.resolve_binding(fn_name);
|
||||||
// if we're in tail position AND there aren't any rest args, this should be a tail call (I think)
|
// if we're in tail position AND there aren't any rest args, this should be a tail call (I think)
|
||||||
if rest.is_empty() {
|
if rest.is_empty() && tail_pos {
|
||||||
self.tail_pos = tail_pos;
|
|
||||||
}
|
|
||||||
if self.tail_pos {
|
|
||||||
self.emit_op(Op::TailCall);
|
self.emit_op(Op::TailCall);
|
||||||
} else {
|
} else {
|
||||||
self.emit_op(Op::Call);
|
self.emit_op(Op::Call);
|
||||||
|
@ -1112,7 +1109,8 @@ impl<'a> Compiler<'a> {
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
}
|
}
|
||||||
// the last term in rest should be in tail position if we are in tail position
|
// the last term in rest should be in tail position if we are in tail position
|
||||||
for (term, _) in rest {
|
let num_rest_terms = rest.len();
|
||||||
|
for (i, (term, _)) in rest.iter().enumerate() {
|
||||||
match term {
|
match term {
|
||||||
Keyword(str) => {
|
Keyword(str) => {
|
||||||
self.emit_constant(Value::Keyword(str));
|
self.emit_constant(Value::Keyword(str));
|
||||||
|
@ -1127,13 +1125,18 @@ impl<'a> Compiler<'a> {
|
||||||
self.visit(arg);
|
self.visit(arg);
|
||||||
}
|
}
|
||||||
self.emit_op(Op::Load);
|
self.emit_op(Op::Load);
|
||||||
self.emit_op(Op::Call);
|
if tail_pos && i == num_rest_terms - 1 {
|
||||||
|
self.emit_op(Op::TailCall)
|
||||||
|
} else {
|
||||||
|
self.emit_op(Op::Call);
|
||||||
|
}
|
||||||
self.emit_byte(arity);
|
self.emit_byte(arity);
|
||||||
self.stack_depth -= arity;
|
self.stack_depth -= arity;
|
||||||
}
|
}
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
self.tail_pos = tail_pos;
|
||||||
}
|
}
|
||||||
When(clauses) => {
|
When(clauses) => {
|
||||||
let tail_pos = self.tail_pos;
|
let tail_pos = self.tail_pos;
|
||||||
|
@ -1497,10 +1500,14 @@ impl<'a> Compiler<'a> {
|
||||||
self.emit_byte(1);
|
self.emit_byte(1);
|
||||||
self.stack_depth -= 1;
|
self.stack_depth -= 1;
|
||||||
}
|
}
|
||||||
self.tail_pos = tail_pos;
|
|
||||||
self.visit(last);
|
self.visit(last);
|
||||||
self.emit_op(Op::Call);
|
if tail_pos {
|
||||||
|
self.emit_op(Op::TailCall)
|
||||||
|
} else {
|
||||||
|
self.emit_op(Op::Call);
|
||||||
|
}
|
||||||
self.emit_byte(1);
|
self.emit_byte(1);
|
||||||
|
self.tail_pos = tail_pos;
|
||||||
self.stack_depth -= 1;
|
self.stack_depth -= 1;
|
||||||
}
|
}
|
||||||
Placeholder => {
|
Placeholder => {
|
||||||
|
|
10
src/main.rs
10
src/main.rs
|
@ -75,12 +75,12 @@ 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 recursive {
|
fn add_one (x) -> add (x, 1)
|
||||||
(0) -> :done
|
fn double (x) -> add (x, x)
|
||||||
(n) -> recursive (0)
|
fn square (x) -> mult (x, x)
|
||||||
}
|
|
||||||
|
double (2)
|
||||||
|
|
||||||
recursive (1)
|
|
||||||
";
|
";
|
||||||
run(src);
|
run(src);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user