constants need 16 bits
This commit is contained in:
parent
121861cc8e
commit
b3e0af41bb
|
@ -272,9 +272,11 @@ impl Chunk {
|
||||||
println!("{i:04}: {op}")
|
println!("{i:04}: {op}")
|
||||||
}
|
}
|
||||||
Constant | MatchConstant => {
|
Constant | MatchConstant => {
|
||||||
let next = self.bytecode[*i + 1];
|
let high = self.bytecode[*i + 1];
|
||||||
let value = &self.constants[next as usize].show();
|
let low = self.bytecode[*i + 2];
|
||||||
println!("{i:04}: {:16} {next:03}: {value}", op.to_string());
|
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;
|
*i += 1;
|
||||||
}
|
}
|
||||||
PushBinding | MatchTuple | MatchSplattedTuple | LoadSplattedTuple | MatchList
|
PushBinding | MatchTuple | MatchSplattedTuple | LoadSplattedTuple | MatchList
|
||||||
|
@ -381,6 +383,12 @@ fn has_placeholder(args: &[Spanned<Ast>]) -> bool {
|
||||||
args.iter().any(|arg| matches!(arg, (Ast::Placeholder, _)))
|
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> {
|
impl<'a> Compiler<'a> {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
ast: &'static Spanned<Ast>,
|
ast: &'static Spanned<Ast>,
|
||||||
|
@ -457,33 +465,39 @@ impl<'a> Compiler<'a> {
|
||||||
self.chunk.constants.len() - 1
|
self.chunk.constants.len() - 1
|
||||||
};
|
};
|
||||||
|
|
||||||
if const_idx > u8::MAX as usize {
|
if const_idx > u16::MAX as usize {
|
||||||
panic!(
|
panic!(
|
||||||
"internal Ludus compiler error: too many constants in chunk:{}:: {}",
|
"internal Ludus compiler error: too many constants in chunk:{}:: {}",
|
||||||
self.span, self.ast
|
self.span, self.ast
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
self.emit_op(Op::Constant);
|
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;
|
self.stack_depth += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn match_constant(&mut self, val: Value) {
|
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,
|
Some(idx) => idx,
|
||||||
None => {
|
None => {
|
||||||
self.chunk.constants.push(val);
|
self.chunk.constants.push(val);
|
||||||
self.chunk.constants.len() - 1
|
self.chunk.constants.len() - 1
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
if constant_index > u8::MAX as usize {
|
if const_idx > u16::MAX as usize {
|
||||||
panic!(
|
panic!(
|
||||||
"internal Ludus compiler error: too many constants in chunk:{}:: {}",
|
"internal Ludus compiler error: too many constants in chunk:{}:: {}",
|
||||||
self.span, self.ast
|
self.span, self.ast
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
self.emit_op(Op::MatchConstant);
|
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) {
|
fn emit_op(&mut self, op: Op) {
|
||||||
|
@ -1500,7 +1514,7 @@ impl<'a> Compiler<'a> {
|
||||||
self.tail_pos = tail_pos;
|
self.tail_pos = tail_pos;
|
||||||
self.visit(body);
|
self.visit(body);
|
||||||
self.emit_op(Op::Store);
|
self.emit_op(Op::Store);
|
||||||
self.scope_depth -= 1;
|
// self.scope_depth -= 1;
|
||||||
while let Some(binding) = self.bindings.last() {
|
while let Some(binding) = self.bindings.last() {
|
||||||
if binding.depth > self.scope_depth {
|
if binding.depth > self.scope_depth {
|
||||||
self.bindings.pop();
|
self.bindings.pop();
|
||||||
|
|
13
src/main.rs
13
src/main.rs
|
@ -114,18 +114,7 @@ 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 one {
|
let (1, 2, 3) = (1, 2, 3)
|
||||||
(x as :number) -> {
|
|
||||||
fn two () -> :number
|
|
||||||
two
|
|
||||||
}
|
|
||||||
(x as :bool) -> {
|
|
||||||
fn two () -> :bool
|
|
||||||
two
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
one (true) ()
|
|
||||||
";
|
";
|
||||||
run(src);
|
run(src);
|
||||||
}
|
}
|
||||||
|
|
16
src/vm.rs
16
src/vm.rs
|
@ -220,10 +220,12 @@ impl Vm {
|
||||||
self.ip += 1;
|
self.ip += 1;
|
||||||
}
|
}
|
||||||
Constant => {
|
Constant => {
|
||||||
let const_idx = self.chunk().bytecode[self.ip + 1];
|
let high = self.chunk().bytecode[self.ip + 1];
|
||||||
let value = self.chunk().constants[const_idx as usize].clone();
|
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.push(value);
|
||||||
self.ip += 2;
|
self.ip += 3;
|
||||||
}
|
}
|
||||||
Jump => {
|
Jump => {
|
||||||
let high = self.chunk().bytecode[self.ip + 1];
|
let high = self.chunk().bytecode[self.ip + 1];
|
||||||
|
@ -382,10 +384,12 @@ impl Vm {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
MatchConstant => {
|
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;
|
let idx = self.stack.len() - self.match_depth as usize - 1;
|
||||||
self.matches = self.stack[idx] == self.chunk().constants[const_idx as usize];
|
self.matches = self.stack[idx] == self.chunk().constants[const_idx];
|
||||||
self.ip += 2;
|
self.ip += 3;
|
||||||
}
|
}
|
||||||
MatchString => {
|
MatchString => {
|
||||||
let pattern_idx = self.chunk().bytecode[self.ip + 1];
|
let pattern_idx = self.chunk().bytecode[self.ip + 1];
|
||||||
|
|
Loading…
Reference in New Issue
Block a user