function calls: first draft, worked out the obvious bugs

This commit is contained in:
Scott Richmond 2025-06-03 17:30:00 -04:00
parent 86992078e9
commit 615fef6ebc
3 changed files with 31 additions and 18 deletions

View File

@ -27,10 +27,10 @@ pub enum Op {
Stash, Stash,
Load, Load,
ResetMatch, ResetMatch,
Match,
MatchNil, MatchNil,
MatchTrue, MatchTrue,
MatchFalse, MatchFalse,
MatchWord,
PanicIfNoMatch, PanicIfNoMatch,
MatchConstant, MatchConstant,
MatchType, MatchType,
@ -135,10 +135,10 @@ impl std::fmt::Display for Op {
StoreAt => "store_at", StoreAt => "store_at",
Stash => "stash", Stash => "stash",
Load => "load", Load => "load",
Match => "match",
MatchNil => "match_nil", MatchNil => "match_nil",
MatchTrue => "match_true", MatchTrue => "match_true",
MatchFalse => "match_false", MatchFalse => "match_false",
MatchWord => "match_word",
ResetMatch => "reset_match", ResetMatch => "reset_match",
PanicIfNoMatch => "panic_if_no_match", PanicIfNoMatch => "panic_if_no_match",
MatchConstant => "match_constant", MatchConstant => "match_constant",
@ -211,10 +211,10 @@ impl Chunk {
use Op::*; use Op::*;
match op { match op {
Pop | Store | Stash | Load | Nil | True | False | MatchNil | MatchTrue | MatchFalse Pop | Store | Stash | Load | Nil | True | False | MatchNil | MatchTrue | MatchFalse
| PanicIfNoMatch | MatchWord | ResetMatch | GetKey | PanicNoWhen | PanicNoMatch | PanicIfNoMatch | ResetMatch | GetKey | PanicNoWhen | PanicNoMatch | TypeOf
| TypeOf | Duplicate | Decrement | Truncate | Noop | LoadTuple | LoadList | Eq | Duplicate | Decrement | Truncate | Noop | LoadTuple | LoadList | Eq | Add | Sub
| Add | Sub | Mult | Div | Unbox | BoxStore | Assert | Get | At | Not | Panic | Mult | Div | Unbox | BoxStore | Assert | Get | At | Not | Panic | EmptyString
| EmptyString | ConcatStrings | Stringify | MatchType | Return => { | ConcatStrings | Stringify | MatchType | Return | Match => {
println!("{i:04}: {op}") println!("{i:04}: {op}")
} }
Constant | MatchConstant => { Constant | MatchConstant => {
@ -551,7 +551,7 @@ impl Compiler {
self.emit_op(Op::PanicIfNoMatch); self.emit_op(Op::PanicIfNoMatch);
} }
WordPattern(name) => { WordPattern(name) => {
self.emit_op(Op::MatchWord); self.emit_op(Op::Match);
self.bind(name); self.bind(name);
} }
Word(name) => { Word(name) => {
@ -566,7 +566,7 @@ impl Compiler {
} }
} }
PlaceholderPattern => { PlaceholderPattern => {
self.emit_op(Op::MatchWord); self.emit_op(Op::Match);
} }
NilPattern => { NilPattern => {
self.emit_op(Op::MatchNil); self.emit_op(Op::MatchNil);
@ -838,6 +838,7 @@ impl Compiler {
// visit all the args // visit all the args
// then store them // then store them
// then call the function // then call the function
let arity = args.len();
for arg in args { for arg in args {
self.visit(arg); self.visit(arg);
} }
@ -852,7 +853,8 @@ impl Compiler {
} }
} }
self.emit_op(Op::Call); self.emit_op(Op::Call);
self.emit_byte(args.len()); self.emit_byte(arity);
self.stack_depth -= arity;
} }
}, },
_ => unreachable!(), _ => unreachable!(),
@ -982,15 +984,16 @@ impl Compiler {
None => { None => {
let mut compiler = Compiler::new(clause, self.name, self.src); let mut compiler = Compiler::new(clause, self.name, self.src);
// compiler.emit_op(Op::Load); // compiler.emit_op(Op::Load);
compiler.stack_depth += arity;
compiler.scope_depth += 1;
compiler.emit_op(Op::ResetMatch); compiler.emit_op(Op::ResetMatch);
compiler.match_depth = arity;
compilers.insert(arity, compiler); compilers.insert(arity, compiler);
compilers.get_mut(&arity).unwrap() compilers.get_mut(&arity).unwrap()
} }
}; };
compiler.stack_depth += arity;
compiler.scope_depth += 1;
compiler.match_depth = arity;
let mut tup_jump_idxes = vec![]; let mut tup_jump_idxes = vec![];
for member in pattern { for member in pattern {
compiler.match_depth -= 1; compiler.match_depth -= 1;
@ -1001,6 +1004,9 @@ impl Compiler {
tup_jump_idxes.push(compiler.len()); tup_jump_idxes.push(compiler.len());
compiler.emit_byte(0xff); compiler.emit_byte(0xff);
} }
if pattern.is_empty() {
compiler.emit_op(Op::Match);
}
compiler.emit_op(Op::Jump); compiler.emit_op(Op::Jump);
let jump_idx = compiler.len(); let jump_idx = compiler.len();
compiler.emit_byte(0xff); compiler.emit_byte(0xff);
@ -1024,12 +1030,12 @@ impl Compiler {
break; break;
} }
} }
while compiler.stack_depth > arity { while compiler.stack_depth > 0 {
compiler.pop(); compiler.pop();
} }
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; compiler.chunk.bytecode[jnm_idx] = compiler.len() as u8 - jnm_idx as u8 - 1;
compiler.scope_depth -= 1; compiler.scope_depth -= 1;
} }
@ -1054,7 +1060,7 @@ impl Compiler {
for (arity, mut compiler) in compilers.into_iter() { for (arity, mut compiler) in compilers.into_iter() {
compiler.emit_op(Op::PanicNoMatch); compiler.emit_op(Op::PanicNoMatch);
let mut chunk = compiler.chunk; let chunk = compiler.chunk;
if crate::DEBUG_COMPILE { if crate::DEBUG_COMPILE {
println!("=== function chuncktion: {name}/{arity} ==="); println!("=== function chuncktion: {name}/{arity} ===");
chunk.dissasemble(); chunk.dissasemble();

View File

@ -76,9 +76,16 @@ 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 = "
fn foo (_) -> :foo fn foo () -> {
let x = :foo
let y = :bar
(x, y)
}
foo (nil) let x = foo ()
let y = foo ()
(x, y)
"; ";
run(src); run(src);
} }

View File

@ -294,7 +294,7 @@ impl Vm {
self.match_depth = 0; self.match_depth = 0;
self.ip += 1; self.ip += 1;
} }
MatchWord => { Match => {
self.matches = true; self.matches = true;
self.ip += 1; self.ip += 1;
} }