Compare commits
No commits in common. "4f7ba56d1f7c683129aace6ab1516a6e277e0b3d" and "4a4b2b22ed8365dc58df0b1136a634e26e06e18b" have entirely different histories.
4f7ba56d1f
...
4a4b2b22ed
|
@ -355,7 +355,6 @@ impl Compiler {
|
|||
}
|
||||
Block(lines) => {
|
||||
self.scope_depth += 1;
|
||||
let stack_depth = self.stack_depth;
|
||||
for expr in lines.iter().take(lines.len() - 1) {
|
||||
if is_binding(expr) {
|
||||
self.visit(expr);
|
||||
|
@ -366,7 +365,6 @@ impl Compiler {
|
|||
}
|
||||
}
|
||||
let last_expr = lines.last().unwrap();
|
||||
// TODO: make sure this actually returns the RHS of the expression
|
||||
if is_binding(last_expr) {
|
||||
self.visit(last_expr);
|
||||
self.emit_op(Op::Duplicate);
|
||||
|
@ -377,19 +375,17 @@ impl Compiler {
|
|||
}
|
||||
self.emit_op(Op::Store);
|
||||
self.scope_depth -= 1;
|
||||
// reset bindings
|
||||
while let Some(binding) = self.bindings.last() {
|
||||
if binding.depth > self.scope_depth {
|
||||
let binding = self.bindings.pop().unwrap();
|
||||
println!("popping: {:?}", binding);
|
||||
self.pop();
|
||||
// self.emit_op(Op::Pop);
|
||||
self.bindings.pop();
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
// reset stack
|
||||
while self.stack_depth > stack_depth + 1 {
|
||||
self.pop();
|
||||
}
|
||||
// self.emit_op(Op::Pop);
|
||||
self.emit_op(Op::Load);
|
||||
}
|
||||
If(cond, then, r#else) => {
|
||||
|
@ -604,24 +600,24 @@ impl Compiler {
|
|||
When(clauses) => {
|
||||
let mut jump_idxes = vec![];
|
||||
let mut clauses = clauses.iter();
|
||||
let stack_depth = self.stack_depth;
|
||||
while let Some((WhenClause(cond, body), _)) = clauses.next() {
|
||||
self.visit(cond.as_ref());
|
||||
self.emit_op(Op::JumpIfFalse);
|
||||
let jif_jump_idx = self.len();
|
||||
self.emit_byte(0xff);
|
||||
self.stack_depth -= 1;
|
||||
self.visit(body);
|
||||
self.emit_op(Op::Jump);
|
||||
jump_idxes.push(self.len());
|
||||
self.emit_byte(0xff);
|
||||
self.chunk.bytecode[jif_jump_idx] = self.len() as u8 - jif_jump_idx as u8 - 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;
|
||||
self.stack_depth = stack_depth;
|
||||
}
|
||||
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!(),
|
||||
Match(scrutinee, clauses) => {
|
||||
|
@ -639,45 +635,43 @@ impl Compiler {
|
|||
// conditional compilation of guards
|
||||
// hard to DRY out
|
||||
match guard.as_ref() {
|
||||
Some(_) => todo!(),
|
||||
// Some(expr) => {
|
||||
// self.visit(expr);
|
||||
// self.emit_op(Op::JumpIfFalse);
|
||||
// let jif_idx = self.len();
|
||||
// self.emit_byte(0xff);
|
||||
// self.visit(body);
|
||||
// self.emit_op(Op::Store);
|
||||
// self.scope_depth -= 1;
|
||||
// while let Some(binding) = self.bindings.last() {
|
||||
// if binding.depth > self.scope_depth {
|
||||
// self.pop();
|
||||
// // self.emit_op(Op::Pop);
|
||||
// self.bindings.pop();
|
||||
// } else {
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
// self.emit_op(Op::Jump);
|
||||
// jump_idxes.push(self.len());
|
||||
// self.emit_byte(0xff);
|
||||
// self.chunk.bytecode[jnm_jump_idx] =
|
||||
// self.len() as u8 - jnm_jump_idx as u8 - 1;
|
||||
// self.chunk.bytecode[jif_idx] = self.len() as u8 - jif_idx as u8 - 1;
|
||||
// }
|
||||
Some(expr) => {
|
||||
self.visit(expr);
|
||||
self.emit_op(Op::JumpIfFalse);
|
||||
let jif_idx = self.len();
|
||||
self.emit_byte(0xff);
|
||||
self.visit(body);
|
||||
self.emit_op(Op::Store);
|
||||
self.scope_depth -= 1;
|
||||
while let Some(binding) = self.bindings.last() {
|
||||
if binding.depth > self.scope_depth {
|
||||
self.pop();
|
||||
// self.emit_op(Op::Pop);
|
||||
self.bindings.pop();
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
self.emit_op(Op::Jump);
|
||||
jump_idxes.push(self.len());
|
||||
self.emit_byte(0xff);
|
||||
self.chunk.bytecode[jnm_jump_idx] =
|
||||
self.len() as u8 - jnm_jump_idx as u8 - 1;
|
||||
self.chunk.bytecode[jif_idx] = self.len() as u8 - jif_idx as u8 - 1;
|
||||
}
|
||||
None => {
|
||||
self.visit(body);
|
||||
self.emit_op(Op::Store);
|
||||
self.scope_depth -= 1;
|
||||
while let Some(binding) = self.bindings.last() {
|
||||
if binding.depth > self.scope_depth {
|
||||
self.pop();
|
||||
// self.emit_op(Op::Pop);
|
||||
self.bindings.pop();
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
while self.stack_depth > stack_depth {
|
||||
self.pop();
|
||||
}
|
||||
self.emit_op(Op::Jump);
|
||||
jump_idxes.push(self.len());
|
||||
self.emit_byte(0xff);
|
||||
|
@ -685,14 +679,14 @@ impl Compiler {
|
|||
self.len() as u8 - jnm_jump_idx as u8 - 1;
|
||||
}
|
||||
}
|
||||
self.stack_depth = stack_depth;
|
||||
}
|
||||
self.emit_op(Op::PanicNoMatch);
|
||||
for idx in jump_idxes {
|
||||
self.chunk.bytecode[idx] = self.len() as u8 - idx as u8 - 1;
|
||||
}
|
||||
while self.stack_depth > stack_depth {
|
||||
self.pop();
|
||||
}
|
||||
// self.emit_op(Op::Pop);
|
||||
self.emit_op(Op::Load);
|
||||
self.stack_depth += 1;
|
||||
}
|
||||
|
|
|
@ -67,14 +67,18 @@ pub fn run(src: &'static str) {
|
|||
Ok(val) => val.show(&compiler.chunk),
|
||||
Err(panic) => format!("{:?}", panic),
|
||||
};
|
||||
vm.print_stack();
|
||||
println!("{output}");
|
||||
}
|
||||
|
||||
pub fn main() {
|
||||
env::set_var("RUST_BACKTRACE", "1");
|
||||
let src = "
|
||||
|
||||
match (-1, (2)) with {
|
||||
(0) -> :nope
|
||||
(1) -> :yup
|
||||
(x, (1)) -> :thing
|
||||
(x, (y)) -> y
|
||||
}
|
||||
";
|
||||
run(src);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user