rough draft of new version of loop w/ 16 bit jumps

This commit is contained in:
Scott Richmond 2025-06-18 19:03:45 -04:00
parent f6bfe0975b
commit fb2488c850
2 changed files with 54 additions and 30 deletions

View File

@ -1275,36 +1275,51 @@ impl<'a> Compiler<'a> {
//next, compile each clause: //next, compile each clause:
let mut clauses = clauses.iter(); let mut clauses = clauses.iter();
let mut jump_idxes = vec![]; let mut jump_idxes = vec![];
while let Some((Ast::MatchClause(pattern, _, body), _)) = clauses.next() { while let Some((Ast::MatchClause(pattern, guard, body), _)) = clauses.next() {
self.emit_op(Op::ResetMatch); self.emit_op(Op::ResetMatch);
self.scope_depth += 1; self.scope_depth += 1;
let (Ast::TuplePattern(members), _) = pattern.as_ref() else { let (Ast::TuplePattern(members), _) = pattern.as_ref() else {
unreachable!() unreachable!()
}; };
self.match_depth = arity; self.match_depth = arity;
let mut tup_jump_idxes = vec![]; let mut jnm_idxes = vec![];
for member in members { for member in members {
self.match_depth -= 1; self.match_depth -= 1;
self.emit_op(Op::MatchDepth); self.emit_op(Op::MatchDepth);
self.emit_byte(self.match_depth); self.emit_byte(self.match_depth);
self.visit(member); self.visit(member);
self.emit_op(Op::JumpIfNoMatch); jnm_idxes.push(self.stub_jump(Op::JumpIfNoMatch));
tup_jump_idxes.push(self.len()); // self.emit_op(Op::JumpIfNoMatch);
self.emit_byte(0xff); // tup_jump_idxes.push(self.len());
// self.emit_byte(0xff);
} }
self.emit_op(Op::Jump); // let jump_idx = self.stub_jump(Op::Jump);
let jump_idx = self.len(); // self.emit_op(Op::Jump);
self.emit_byte(0xff); // let jump_idx = self.len();
for idx in tup_jump_idxes { // self.emit_byte(0xff);
self.chunk.bytecode[idx] = (self.len() - idx) as u8 - 2; // for idx in jnm_idxes {
// self.patch_jump(idx, self.len() - idx - 3);
// // self.chunk.bytecode[idx] = (self.len() - idx) as u8 - 2;
// }
// self.emit_op(Op::PopN);
// self.emit_byte(arity);
// for _ in 0..arity {
// self.emit_op(Op::Pop);
// }
// self.patch_jump(jump_idx, self.len() - jump_idx - 3);
// self.chunk.bytecode[jump_idx] = (self.len() - jump_idx) as u8 - 1;
// let mut no_match_jumps = vec![];
// no_match_jumps.push(self.stub_jump(Op::JumpIfNoMatch));
// self.emit_op(Op::JumpIfNoMatch);
// let jnm_idx = self.len();
// self.emit_byte(0xff);
if guard.is_some() {
let guard_expr: &'static Spanned<Ast> =
Box::leak(Box::new(guard.clone().unwrap()));
self.visit(guard_expr);
jnm_idxes.push(self.stub_jump(Op::JumpIfFalse));
self.stack_depth -= 1;
} }
for _ in 0..arity {
self.emit_op(Op::Pop);
}
self.chunk.bytecode[jump_idx] = (self.len() - jump_idx) as u8 - 1;
self.emit_op(Op::JumpIfNoMatch);
let jnm_idx = self.len();
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;
@ -1315,23 +1330,29 @@ impl<'a> Compiler<'a> {
break; break;
} }
} }
while self.stack_depth > stack_depth + arity { while self.stack_depth > stack_depth {
self.pop(); self.pop();
} }
self.stack_depth -= arity; // self.stack_depth -= arity;
self.emit_op(Op::Jump); jump_idxes.push(self.stub_jump(Op::Jump));
jump_idxes.push(self.len()); // self.emit_op(Op::Jump);
self.emit_byte(0xff); // jump_idxes.push(self.len());
self.chunk.bytecode[jnm_idx] = (self.len() - jnm_idx) as u8; // self.emit_byte(0xff);
for idx in jnm_idxes {
self.patch_jump(idx, self.len() - idx - 3);
}
// self.chunk.bytecode[jnm_idx] = (self.len() - jnm_idx) as u8;
self.scope_depth -= 1; self.scope_depth -= 1;
} }
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() - idx) as u8 - 1; self.patch_jump(idx, self.len() - idx - 3);
// self.chunk.bytecode[idx] = (self.len() - idx) as u8 - 1;
} }
self.emit_op(Op::PopN); // self.emit_op(Op::PopN);
self.emit_byte(arity); // self.emit_byte(arity);
self.stack_depth -= arity; self.stack_depth -= arity;
// println!("Op::Load at end of loop at byte {}", self.len());
self.emit_op(Op::Load); self.emit_op(Op::Load);
self.stack_depth += 1; self.stack_depth += 1;
self.leave_loop(); self.leave_loop();
@ -1344,8 +1365,10 @@ impl<'a> Compiler<'a> {
} }
self.emit_op(Op::PopN); self.emit_op(Op::PopN);
self.emit_byte(self.loop_root()); self.emit_byte(self.loop_root());
self.emit_op(Op::JumpBack); self.emit_op(Op::Load);
self.emit_byte(self.len() - self.loop_idx()); self.jump(Op::JumpBack, self.len() - self.loop_idx());
// self.emit_op(Op::JumpBack);
// self.emit_byte(self.len() - self.loop_idx());
} }
Panic(msg) => { Panic(msg) => {
self.visit(msg); self.visit(msg);

View File

@ -75,8 +75,9 @@ 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 = "
repeat 4 { loop (1) with {
:foo (0) -> :done
(1) -> recur (0)
} }
"; ";
run(src); run(src);