Compare commits
3 Commits
4a4b2b22ed
...
4f7ba56d1f
Author | SHA1 | Date | |
---|---|---|---|
|
4f7ba56d1f | ||
|
ce1612a30c | ||
|
1ef0da5dd1 |
|
@ -355,6 +355,7 @@ 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);
|
||||
|
@ -365,6 +366,7 @@ 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);
|
||||
|
@ -375,17 +377,19 @@ 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 {
|
||||
self.pop();
|
||||
// self.emit_op(Op::Pop);
|
||||
self.bindings.pop();
|
||||
let binding = self.bindings.pop().unwrap();
|
||||
println!("popping: {:?}", binding);
|
||||
} 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) => {
|
||||
|
@ -600,24 +604,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 = stack_depth;
|
||||
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;
|
||||
self.chunk.bytecode[idx] = self.len() as u8 - idx as u8 - 1;
|
||||
}
|
||||
self.stack_depth += 1;
|
||||
}
|
||||
WhenClause(..) => unreachable!(),
|
||||
Match(scrutinee, clauses) => {
|
||||
|
@ -635,43 +639,45 @@ impl Compiler {
|
|||
// conditional compilation of guards
|
||||
// hard to DRY out
|
||||
match guard.as_ref() {
|
||||
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(_) => 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;
|
||||
// }
|
||||
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);
|
||||
|
@ -679,14 +685,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,18 +67,14 @@ 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