|
|
|
@ -1,12 +1,13 @@
|
|
|
|
|
#[repr(u8)]
|
|
|
|
|
pub enum OpCode {
|
|
|
|
|
Constant,
|
|
|
|
|
Return,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
type Value = f32;
|
|
|
|
|
|
|
|
|
|
pub struct Chunk {
|
|
|
|
|
code: Vec<OpCode>,
|
|
|
|
|
code: Vec<u8>,
|
|
|
|
|
constants: Vec<Value>,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -19,13 +20,16 @@ impl Chunk {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// https://doc.rust-lang.org/nomicon/vec/vec-push-pop.html
|
|
|
|
|
pub fn write(&mut self, op_code: OpCode) {
|
|
|
|
|
self.code.push(op_code);
|
|
|
|
|
pub fn write(&mut self, byte: u8) {
|
|
|
|
|
self.code.push(byte);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub fn add_constant(&mut self, value: Value) -> usize{
|
|
|
|
|
pub fn add_constant(&mut self, value: Value) -> u8 {
|
|
|
|
|
self.constants.push(value);
|
|
|
|
|
self.constants.len() - 1
|
|
|
|
|
|
|
|
|
|
assert!(self.constants.len() <= u8::MAX.into(), "Too many constants");
|
|
|
|
|
|
|
|
|
|
(self.constants.len() - 1) as u8
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub fn disassemble(&self, name: &str) {
|
|
|
|
@ -41,7 +45,9 @@ impl Chunk {
|
|
|
|
|
print!("{:04} ", offset);
|
|
|
|
|
|
|
|
|
|
match self.code[offset] {
|
|
|
|
|
OpCode::Return => self.simple_instruction("OP_RETURN", offset),
|
|
|
|
|
0 => self.constant_instruction("OP_CONSTANT", offset),
|
|
|
|
|
1 => self.simple_instruction("OP_RETURN", offset),
|
|
|
|
|
_ => unreachable!(),
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -49,6 +55,13 @@ impl Chunk {
|
|
|
|
|
println!("{}", name);
|
|
|
|
|
offset + 1
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn constant_instruction(&self, name: &str, offset: usize) -> usize {
|
|
|
|
|
let constant_index = self.code[offset+1];
|
|
|
|
|
let value = self.constants[constant_index as usize];
|
|
|
|
|
println!("{:<16} {:04} '{}'", name, constant_index, value);
|
|
|
|
|
offset + 2
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl Default for Chunk {
|
|
|
|
|