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

View File

@ -76,9 +76,16 @@ pub fn run(src: &'static str) {
pub fn main() {
env::set_var("RUST_BACKTRACE", "1");
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);
}

View File

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