Compare commits
No commits in common. "4f7ba56d1f7c683129aace6ab1516a6e277e0b3d" and "4a4b2b22ed8365dc58df0b1136a634e26e06e18b" have entirely different histories.
4f7ba56d1f
...
4a4b2b22ed
|
@ -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
|
self.pop();
|
||||||
while self.stack_depth > stack_depth + 1 {
|
// self.emit_op(Op::Pop);
|
||||||
self.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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user