From 615fef6ebc5823a2b3031eddb023eb877712b122 Mon Sep 17 00:00:00 2001 From: Scott Richmond Date: Tue, 3 Jun 2025 17:30:00 -0400 Subject: [PATCH] function calls: first draft, worked out the obvious bugs --- src/compiler.rs | 36 +++++++++++++++++++++--------------- src/main.rs | 11 +++++++++-- src/vm.rs | 2 +- 3 files changed, 31 insertions(+), 18 deletions(-) diff --git a/src/compiler.rs b/src/compiler.rs index 4539827..0c83131 100644 --- a/src/compiler.rs +++ b/src/compiler.rs @@ -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(); diff --git a/src/main.rs b/src/main.rs index 11573f0..59e3c08 100644 --- a/src/main.rs +++ b/src/main.rs @@ -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); } diff --git a/src/vm.rs b/src/vm.rs index f8a697f..688c61d 100644 --- a/src/vm.rs +++ b/src/vm.rs @@ -294,7 +294,7 @@ impl Vm { self.match_depth = 0; self.ip += 1; } - MatchWord => { + Match => { self.matches = true; self.ip += 1; }