Compare commits

..

No commits in common. "4f7ba56d1f7c683129aace6ab1516a6e277e0b3d" and "4a4b2b22ed8365dc58df0b1136a634e26e06e18b" have entirely different histories.

3 changed files with 47 additions and 49 deletions

View File

@ -355,7 +355,6 @@ impl Compiler {
} }
Block(lines) => { Block(lines) => {
self.scope_depth += 1; self.scope_depth += 1;
let stack_depth = self.stack_depth;
for expr in lines.iter().take(lines.len() - 1) { for expr in lines.iter().take(lines.len() - 1) {
if is_binding(expr) { if is_binding(expr) {
self.visit(expr); self.visit(expr);
@ -366,7 +365,6 @@ impl Compiler {
} }
} }
let last_expr = lines.last().unwrap(); let last_expr = lines.last().unwrap();
// TODO: make sure this actually returns the RHS of the expression
if is_binding(last_expr) { if is_binding(last_expr) {
self.visit(last_expr); self.visit(last_expr);
self.emit_op(Op::Duplicate); self.emit_op(Op::Duplicate);
@ -377,19 +375,17 @@ impl Compiler {
} }
self.emit_op(Op::Store); self.emit_op(Op::Store);
self.scope_depth -= 1; self.scope_depth -= 1;
// reset bindings
while let Some(binding) = self.bindings.last() { while let Some(binding) = self.bindings.last() {
if binding.depth > self.scope_depth { if binding.depth > self.scope_depth {
let binding = self.bindings.pop().unwrap(); self.pop();
println!("popping: {:?}", binding); // self.emit_op(Op::Pop);
self.bindings.pop();
} else { } else {
break; break;
} }
} }
// reset stack
while self.stack_depth > stack_depth + 1 {
self.pop(); self.pop();
} // self.emit_op(Op::Pop);
self.emit_op(Op::Load); self.emit_op(Op::Load);
} }
If(cond, then, r#else) => { If(cond, then, r#else) => {
@ -604,24 +600,24 @@ impl Compiler {
When(clauses) => { When(clauses) => {
let mut jump_idxes = vec![]; let mut jump_idxes = vec![];
let mut clauses = clauses.iter(); let mut clauses = clauses.iter();
let stack_depth = self.stack_depth;
while let Some((WhenClause(cond, body), _)) = clauses.next() { while let Some((WhenClause(cond, body), _)) = clauses.next() {
self.visit(cond.as_ref()); self.visit(cond.as_ref());
self.emit_op(Op::JumpIfFalse); self.emit_op(Op::JumpIfFalse);
let jif_jump_idx = self.len(); let jif_jump_idx = self.len();
self.emit_byte(0xff); self.emit_byte(0xff);
self.stack_depth -= 1;
self.visit(body); self.visit(body);
self.emit_op(Op::Jump); self.emit_op(Op::Jump);
jump_idxes.push(self.len()); jump_idxes.push(self.len());
self.emit_byte(0xff); self.emit_byte(0xff);
self.chunk.bytecode[jif_jump_idx] = self.len() as u8 - jif_jump_idx as u8 - 1; self.chunk.bytecode[jif_jump_idx] = self.len() as u8 - jif_jump_idx as u8 - 1;
self.stack_depth -= 1; self.stack_depth = stack_depth;
}
self.emit_op(Op::PanicNoWhen);
for idx in jump_idxes {
self.chunk.bytecode[idx] = self.len() as u8 - idx as u8 - 1;
} }
self.stack_depth += 1; self.stack_depth += 1;
self.emit_op(Op::PanicNoWhen);
for idx in jump_idxes {
self.chunk.bytecode[idx] = self.len() as u8 - idx as u8 + 1;
}
} }
WhenClause(..) => unreachable!(), WhenClause(..) => unreachable!(),
Match(scrutinee, clauses) => { Match(scrutinee, clauses) => {
@ -639,45 +635,43 @@ impl Compiler {
// conditional compilation of guards // conditional compilation of guards
// hard to DRY out // hard to DRY out
match guard.as_ref() { match guard.as_ref() {
Some(_) => todo!(), Some(expr) => {
// Some(expr) => { self.visit(expr);
// self.visit(expr); self.emit_op(Op::JumpIfFalse);
// self.emit_op(Op::JumpIfFalse); let jif_idx = self.len();
// let jif_idx = self.len(); self.emit_byte(0xff);
// self.emit_byte(0xff); self.visit(body);
// self.visit(body); self.emit_op(Op::Store);
// self.emit_op(Op::Store); self.scope_depth -= 1;
// self.scope_depth -= 1; while let Some(binding) = self.bindings.last() {
// while let Some(binding) = self.bindings.last() { if binding.depth > self.scope_depth {
// if binding.depth > self.scope_depth { self.pop();
// self.pop(); // self.emit_op(Op::Pop);
// // self.emit_op(Op::Pop); self.bindings.pop();
// self.bindings.pop(); } else {
// } else { break;
// break; }
// } }
// } self.emit_op(Op::Jump);
// self.emit_op(Op::Jump); jump_idxes.push(self.len());
// jump_idxes.push(self.len()); self.emit_byte(0xff);
// self.emit_byte(0xff); self.chunk.bytecode[jnm_jump_idx] =
// self.chunk.bytecode[jnm_jump_idx] = self.len() as u8 - jnm_jump_idx as u8 - 1;
// self.len() as u8 - jnm_jump_idx as u8 - 1; self.chunk.bytecode[jif_idx] = self.len() as u8 - jif_idx as u8 - 1;
// self.chunk.bytecode[jif_idx] = self.len() as u8 - jif_idx as u8 - 1; }
// }
None => { None => {
self.visit(body); self.visit(body);
self.emit_op(Op::Store); self.emit_op(Op::Store);
self.scope_depth -= 1; self.scope_depth -= 1;
while let Some(binding) = self.bindings.last() { while let Some(binding) = self.bindings.last() {
if binding.depth > self.scope_depth { if binding.depth > self.scope_depth {
self.pop();
// self.emit_op(Op::Pop);
self.bindings.pop(); self.bindings.pop();
} else { } else {
break; break;
} }
} }
while self.stack_depth > stack_depth {
self.pop();
}
self.emit_op(Op::Jump); self.emit_op(Op::Jump);
jump_idxes.push(self.len()); jump_idxes.push(self.len());
self.emit_byte(0xff); self.emit_byte(0xff);
@ -685,14 +679,14 @@ impl Compiler {
self.len() as u8 - jnm_jump_idx as u8 - 1; self.len() as u8 - jnm_jump_idx as u8 - 1;
} }
} }
self.stack_depth = stack_depth;
} }
self.emit_op(Op::PanicNoMatch); self.emit_op(Op::PanicNoMatch);
for idx in jump_idxes { for idx in jump_idxes {
self.chunk.bytecode[idx] = self.len() as u8 - idx as u8 - 1; self.chunk.bytecode[idx] = self.len() as u8 - idx as u8 - 1;
} }
while self.stack_depth > stack_depth {
self.pop(); self.pop();
} // self.emit_op(Op::Pop);
self.emit_op(Op::Load); self.emit_op(Op::Load);
self.stack_depth += 1; self.stack_depth += 1;
} }

View File

@ -67,14 +67,18 @@ pub fn run(src: &'static str) {
Ok(val) => val.show(&compiler.chunk), Ok(val) => val.show(&compiler.chunk),
Err(panic) => format!("{:?}", panic), Err(panic) => format!("{:?}", panic),
}; };
vm.print_stack();
println!("{output}"); println!("{output}");
} }
pub fn main() { pub fn main() {
env::set_var("RUST_BACKTRACE", "1"); env::set_var("RUST_BACKTRACE", "1");
let src = " let src = "
match (-1, (2)) with {
(0) -> :nope
(1) -> :yup
(x, (1)) -> :thing
(x, (y)) -> y
}
"; ";
run(src); run(src);
} }

View File

@ -65,7 +65,7 @@ impl<'a> Vm<'a> {
self.stack.last().unwrap() self.stack.last().unwrap()
} }
pub fn print_stack(&self) { fn print_stack(&self) {
let inner = self let inner = self
.stack .stack
.iter() .iter()