add return and const instructions.
This commit is contained in:
commit
5cee345e8b
|
@ -0,0 +1 @@
|
|||
/target
|
|
@ -0,0 +1,7 @@
|
|||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "mox"
|
||||
version = "0.1.0"
|
|
@ -0,0 +1,8 @@
|
|||
[package]
|
||||
name = "mox"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
|
@ -0,0 +1,44 @@
|
|||
use mox::value::Value;
|
||||
use mox::{Chunk, ConversionError, OptCode};
|
||||
|
||||
pub fn disassemble_chunk(chunk: &Chunk, name: &str) {
|
||||
// println!("{:?}", chunk);
|
||||
println!("== {} ==", name);
|
||||
let mut offset = 0;
|
||||
while offset < chunk.code.len() {
|
||||
offset = disassemble_instruction(&chunk, offset);
|
||||
}
|
||||
}
|
||||
fn disassemble_instruction(chunk: &Chunk, offset: usize) -> usize {
|
||||
print!("{:04} ", offset);
|
||||
let instruction: Result<OptCode, ConversionError> = chunk.code[offset].try_into();
|
||||
match instruction {
|
||||
Ok(code) => match code {
|
||||
OptCode::OpConstant => {
|
||||
return constant_instruction("OpConstant", chunk, offset);
|
||||
}
|
||||
OptCode::OpReturn => {
|
||||
return simple_instruction("OpReturn", offset);
|
||||
}
|
||||
},
|
||||
Err(e) => {
|
||||
println!("Unknown optcode {:?}", e);
|
||||
return offset + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn simple_instruction(name: &str, offset: usize) -> usize {
|
||||
println!("{}", name);
|
||||
return offset + 1;
|
||||
}
|
||||
fn constant_instruction(name: &str, chunk: &Chunk, offset: usize) -> usize {
|
||||
let constant: u8 = chunk.code[offset + 1];
|
||||
print!("{:<16} {:>4} ", name, constant);
|
||||
print_value(chunk.constants[constant as usize]);
|
||||
println!();
|
||||
return offset + 2;
|
||||
}
|
||||
fn print_value(value: Value) {
|
||||
print!("{:}", value);
|
||||
}
|
|
@ -0,0 +1,82 @@
|
|||
pub mod value;
|
||||
|
||||
use value::Value;
|
||||
|
||||
#[derive(Debug, PartialEq, Eq)]
|
||||
pub enum OptCode {
|
||||
OpReturn,
|
||||
OpConstant,
|
||||
}
|
||||
#[derive(Debug)]
|
||||
pub struct Chunk {
|
||||
pub code: Vec<u8>,
|
||||
pub constants: Vec<Value>,
|
||||
}
|
||||
|
||||
impl From<OptCode> for u8 {
|
||||
fn from(code: OptCode) -> Self {
|
||||
match code {
|
||||
OptCode::OpReturn => 0,
|
||||
OptCode::OpConstant => 1,
|
||||
}
|
||||
}
|
||||
}
|
||||
#[derive(Debug)]
|
||||
pub struct ConversionError;
|
||||
|
||||
impl TryFrom<u8> for OptCode {
|
||||
type Error = ConversionError;
|
||||
fn try_from(code: u8) -> Result<Self, Self::Error> {
|
||||
match code {
|
||||
0 => Ok(OptCode::OpReturn),
|
||||
1 => Ok(OptCode::OpConstant),
|
||||
_ => Err(ConversionError),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Chunk {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
code: vec![],
|
||||
constants: vec![],
|
||||
}
|
||||
}
|
||||
pub fn write(&mut self, byte: u8) {
|
||||
self.code.push(byte);
|
||||
}
|
||||
pub fn write_value(&mut self, add: Value) -> u8 {
|
||||
self.constants.push(add);
|
||||
return (self.constants.len() - 1).try_into().unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn u8_to_optcode() {
|
||||
let pred: OptCode = 0.try_into().unwrap();
|
||||
assert_eq!(pred, OptCode::OpReturn);
|
||||
let pred: OptCode = 1.try_into().unwrap();
|
||||
assert_eq!(pred, OptCode::OpConstant);
|
||||
}
|
||||
#[test]
|
||||
fn basic_write() {
|
||||
let mut chunk = Chunk::new();
|
||||
let constant_idx: u8 = chunk.write_value(1.2);
|
||||
assert_eq!(constant_idx, 0);
|
||||
chunk.write(OptCode::OpConstant.into());
|
||||
chunk.write(constant_idx);
|
||||
let pred: OptCode = chunk.code[0].try_into().unwrap();
|
||||
assert_eq!(pred, OptCode::OpConstant);
|
||||
}
|
||||
#[test]
|
||||
fn try_into_constant() {
|
||||
let mut chunk = Chunk::new();
|
||||
let constant_idx: u8 = chunk.write_value(1.2);
|
||||
chunk.write(OptCode::OpConstant.into());
|
||||
chunk.write(constant_idx);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
use mox::Chunk;
|
||||
use mox::OptCode;
|
||||
mod debug;
|
||||
|
||||
use debug::disassemble_chunk;
|
||||
|
||||
fn main() {
|
||||
let mut chunk = Chunk::new();
|
||||
let constant_idx: u8 = chunk.write_value(1.2);
|
||||
chunk.write(OptCode::OpConstant.into());
|
||||
chunk.write(constant_idx);
|
||||
chunk.write(OptCode::OpReturn.into());
|
||||
|
||||
disassemble_chunk(&chunk, "test chunk");
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
pub type Value = f64;
|
Loading…
Reference in New Issue