Compare commits
3 Commits
2ce2e2c2d3
...
5ae4742840
Author | SHA1 | Date | |
---|---|---|---|
|
5ae4742840 | ||
|
0f8645d2eb | ||
|
01ce043379 |
|
@ -5,6 +5,7 @@ use crate::value::*;
|
||||||
use chumsky::prelude::SimpleSpan;
|
use chumsky::prelude::SimpleSpan;
|
||||||
use num_derive::{FromPrimitive, ToPrimitive};
|
use num_derive::{FromPrimitive, ToPrimitive};
|
||||||
use num_traits::FromPrimitive;
|
use num_traits::FromPrimitive;
|
||||||
|
use std::borrow::Borrow;
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
@ -911,61 +912,41 @@ impl<'a> Compiler<'a> {
|
||||||
let mut jump_idxes = vec![];
|
let mut jump_idxes = vec![];
|
||||||
let mut clauses = clauses.iter();
|
let mut clauses = clauses.iter();
|
||||||
while let Some((MatchClause(pattern, guard, body), _)) = clauses.next() {
|
while let Some((MatchClause(pattern, guard, body), _)) = clauses.next() {
|
||||||
|
let mut no_match_jumps = vec![];
|
||||||
self.scope_depth += 1;
|
self.scope_depth += 1;
|
||||||
self.match_depth = 0;
|
self.match_depth = 0;
|
||||||
self.visit(pattern);
|
self.visit(pattern);
|
||||||
self.emit_op(Op::JumpIfNoMatch);
|
self.emit_op(Op::JumpIfNoMatch);
|
||||||
let jnm_jump_idx = self.len();
|
no_match_jumps.push(self.len());
|
||||||
self.emit_byte(0xff);
|
self.emit_byte(0xff);
|
||||||
// conditional compilation of guards
|
if guard.is_some() {
|
||||||
// hard to DRY out
|
let guard_expr: &'static Spanned<Ast> =
|
||||||
match guard.as_ref() {
|
Box::leak(Box::new(guard.clone().unwrap()));
|
||||||
Some(_) => todo!(),
|
self.visit(guard_expr);
|
||||||
// Some(expr) => {
|
self.emit_op(Op::JumpIfFalse);
|
||||||
// self.visit(expr);
|
no_match_jumps.push(self.len());
|
||||||
// self.emit_op(Op::JumpIfFalse);
|
self.emit_byte(0xff);
|
||||||
// let jif_idx = self.len();
|
self.stack_depth -= 1;
|
||||||
// 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.bindings.pop();
|
||||||
// // self.emit_op(Op::Pop);
|
} else {
|
||||||
// self.bindings.pop();
|
break;
|
||||||
// } 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.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);
|
|
||||||
self.chunk.bytecode[jnm_jump_idx] =
|
|
||||||
self.len() as u8 - jnm_jump_idx as u8 - 1;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
while self.stack_depth > stack_depth {
|
||||||
|
self.pop();
|
||||||
|
}
|
||||||
|
self.emit_op(Op::Jump);
|
||||||
|
jump_idxes.push(self.len());
|
||||||
|
self.emit_byte(0xff);
|
||||||
|
for idx in no_match_jumps {
|
||||||
|
self.chunk.bytecode[idx] = self.len() as u8 - idx as u8 - 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
self.emit_op(Op::PanicNoMatch);
|
self.emit_op(Op::PanicNoMatch);
|
||||||
for idx in jump_idxes {
|
for idx in jump_idxes {
|
||||||
|
@ -991,7 +972,7 @@ impl<'a> Compiler<'a> {
|
||||||
let mut upvalues = vec![];
|
let mut upvalues = vec![];
|
||||||
|
|
||||||
for clause in fn_body {
|
for clause in fn_body {
|
||||||
let MatchClause(pattern, _, clause_body) = &clause.0 else {
|
let MatchClause(pattern, guard, clause_body) = &clause.0 else {
|
||||||
unreachable!()
|
unreachable!()
|
||||||
};
|
};
|
||||||
let TuplePattern(pattern) = &pattern.0 else {
|
let TuplePattern(pattern) = &pattern.0 else {
|
||||||
|
@ -1040,9 +1021,20 @@ impl<'a> Compiler<'a> {
|
||||||
compiler.emit_op(Op::Pop);
|
compiler.emit_op(Op::Pop);
|
||||||
}
|
}
|
||||||
compiler.chunk.bytecode[jump_idx] = compiler.len() as u8 - jump_idx as u8 - 1;
|
compiler.chunk.bytecode[jump_idx] = compiler.len() as u8 - jump_idx as u8 - 1;
|
||||||
|
let mut no_match_jumps = vec![];
|
||||||
compiler.emit_op(Op::JumpIfNoMatch);
|
compiler.emit_op(Op::JumpIfNoMatch);
|
||||||
let jnm_idx = compiler.len();
|
// let jnm_idx = compiler.len();
|
||||||
|
no_match_jumps.push(compiler.len());
|
||||||
compiler.emit_byte(0xff);
|
compiler.emit_byte(0xff);
|
||||||
|
if guard.is_some() {
|
||||||
|
let guard_expr: &'static Spanned<Ast> =
|
||||||
|
Box::leak(Box::new(guard.clone().unwrap()));
|
||||||
|
compiler.visit(guard_expr);
|
||||||
|
compiler.emit_op(Op::JumpIfFalse);
|
||||||
|
no_match_jumps.push(self.len());
|
||||||
|
compiler.emit_byte(0xff);
|
||||||
|
compiler.stack_depth -= 1;
|
||||||
|
}
|
||||||
compiler.visit(clause_body);
|
compiler.visit(clause_body);
|
||||||
compiler.emit_op(Op::Store);
|
compiler.emit_op(Op::Store);
|
||||||
compiler.scope_depth -= 1;
|
compiler.scope_depth -= 1;
|
||||||
|
@ -1058,7 +1050,10 @@ impl<'a> Compiler<'a> {
|
||||||
}
|
}
|
||||||
compiler.stack_depth = 0;
|
compiler.stack_depth = 0;
|
||||||
compiler.emit_op(Op::Return);
|
compiler.emit_op(Op::Return);
|
||||||
compiler.chunk.bytecode[jnm_idx] = compiler.len() as u8 - jnm_idx as u8 - 1;
|
for idx in no_match_jumps {
|
||||||
|
compiler.chunk.bytecode[idx] = compiler.len() as u8 - idx as u8 - 1;
|
||||||
|
}
|
||||||
|
// compiler.chunk.bytecode[jnm_idx] = compiler.len() as u8 - jnm_idx as u8 - 1;
|
||||||
compiler.scope_depth -= 1;
|
compiler.scope_depth -= 1;
|
||||||
|
|
||||||
std::mem::swap(&mut compiler.upvalues, &mut upvalues);
|
std::mem::swap(&mut compiler.upvalues, &mut upvalues);
|
||||||
|
@ -1088,7 +1083,6 @@ impl<'a> Compiler<'a> {
|
||||||
self.emit_constant(init_val);
|
self.emit_constant(init_val);
|
||||||
self.bind(name);
|
self.bind(name);
|
||||||
|
|
||||||
// TODO: close over everything accessed in the function
|
|
||||||
for upvalue in upvalues {
|
for upvalue in upvalues {
|
||||||
self.emit_op(Op::SetUpvalue);
|
self.emit_op(Op::SetUpvalue);
|
||||||
self.emit_byte(upvalue.stack_pos);
|
self.emit_byte(upvalue.stack_pos);
|
||||||
|
|
|
@ -76,12 +76,11 @@ 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 = "
|
||||||
let bar = 42
|
fn foo () -> :foo
|
||||||
let foo = {
|
|
||||||
let (1, 2, 3) = (1, 2, 3)
|
|
||||||
}
|
|
||||||
|
|
||||||
foo
|
foo
|
||||||
|
|
||||||
|
|
||||||
";
|
";
|
||||||
run(src);
|
run(src);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user