From b3e0af41bb4a666843a01cecd60cd2aaf24d1c0e Mon Sep 17 00:00:00 2001 From: Scott Richmond Date: Fri, 20 Jun 2025 15:56:13 -0400 Subject: [PATCH] constants need 16 bits --- src/compiler.rs | 32 +++++++++++++++++++++++--------- src/main.rs | 13 +------------ src/vm.rs | 16 ++++++++++------ 3 files changed, 34 insertions(+), 27 deletions(-) diff --git a/src/compiler.rs b/src/compiler.rs index 3acb33f..f35cab5 100644 --- a/src/compiler.rs +++ b/src/compiler.rs @@ -272,9 +272,11 @@ impl Chunk { println!("{i:04}: {op}") } Constant | MatchConstant => { - let next = self.bytecode[*i + 1]; - let value = &self.constants[next as usize].show(); - println!("{i:04}: {:16} {next:03}: {value}", op.to_string()); + let high = self.bytecode[*i + 1]; + let low = self.bytecode[*i + 2]; + let idx = ((high as usize) << 8) + low as usize; + let value = &self.constants[idx].show(); + println!("{i:04}: {:16} {idx:05}: {value}", op.to_string()); *i += 1; } PushBinding | MatchTuple | MatchSplattedTuple | LoadSplattedTuple | MatchList @@ -381,6 +383,12 @@ fn has_placeholder(args: &[Spanned]) -> bool { args.iter().any(|arg| matches!(arg, (Ast::Placeholder, _))) } +fn as_two_bytes(x: usize) -> (u8, u8) { + let low = x as u8; + let high = (x >> 8) as u8; + (high, low) +} + impl<'a> Compiler<'a> { pub fn new( ast: &'static Spanned, @@ -457,33 +465,39 @@ impl<'a> Compiler<'a> { self.chunk.constants.len() - 1 }; - if const_idx > u8::MAX as usize { + if const_idx > u16::MAX as usize { panic!( "internal Ludus compiler error: too many constants in chunk:{}:: {}", self.span, self.ast ) } self.emit_op(Op::Constant); - self.emit_byte(const_idx); + let low = const_idx as u8; + let high = (const_idx >> 8) as u8; + self.chunk.bytecode.push(high); + self.chunk.bytecode.push(low); self.stack_depth += 1; } fn match_constant(&mut self, val: Value) { - let constant_index = match self.chunk.constants.iter().position(|v| *v == val) { + let const_idx = match self.chunk.constants.iter().position(|v| *v == val) { Some(idx) => idx, None => { self.chunk.constants.push(val); self.chunk.constants.len() - 1 } }; - if constant_index > u8::MAX as usize { + if const_idx > u16::MAX as usize { panic!( "internal Ludus compiler error: too many constants in chunk:{}:: {}", self.span, self.ast ) } self.emit_op(Op::MatchConstant); - self.emit_byte(constant_index); + let low = const_idx as u8; + let high = (const_idx >> 8) as u8; + self.chunk.bytecode.push(high); + self.chunk.bytecode.push(low); } fn emit_op(&mut self, op: Op) { @@ -1500,7 +1514,7 @@ impl<'a> Compiler<'a> { self.tail_pos = tail_pos; self.visit(body); self.emit_op(Op::Store); - self.scope_depth -= 1; + // self.scope_depth -= 1; while let Some(binding) = self.bindings.last() { if binding.depth > self.scope_depth { self.bindings.pop(); diff --git a/src/main.rs b/src/main.rs index 39fd265..e8ff73f 100644 --- a/src/main.rs +++ b/src/main.rs @@ -114,18 +114,7 @@ pub fn run(src: &'static str) { pub fn main() { env::set_var("RUST_BACKTRACE", "1"); let src = " -fn one { - (x as :number) -> { - fn two () -> :number - two - } - (x as :bool) -> { - fn two () -> :bool - two - } -} - -one (true) () +let (1, 2, 3) = (1, 2, 3) "; run(src); } diff --git a/src/vm.rs b/src/vm.rs index 4a43650..64c84e0 100644 --- a/src/vm.rs +++ b/src/vm.rs @@ -220,10 +220,12 @@ impl Vm { self.ip += 1; } Constant => { - let const_idx = self.chunk().bytecode[self.ip + 1]; - let value = self.chunk().constants[const_idx as usize].clone(); + let high = self.chunk().bytecode[self.ip + 1]; + let low = self.chunk().bytecode[self.ip + 2]; + let const_idx = combine_bytes(high, low); + let value = self.chunk().constants[const_idx].clone(); self.push(value); - self.ip += 2; + self.ip += 3; } Jump => { let high = self.chunk().bytecode[self.ip + 1]; @@ -382,10 +384,12 @@ impl Vm { } } MatchConstant => { - let const_idx = self.chunk().bytecode[self.ip + 1]; + let high = self.chunk().bytecode[self.ip + 1]; + let low = self.chunk().bytecode[self.ip + 2]; + let const_idx = combine_bytes(high, low); let idx = self.stack.len() - self.match_depth as usize - 1; - self.matches = self.stack[idx] == self.chunk().constants[const_idx as usize]; - self.ip += 2; + self.matches = self.stack[idx] == self.chunk().constants[const_idx]; + self.ip += 3; } MatchString => { let pattern_idx = self.chunk().bytecode[self.ip + 1];