-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Scaffold with https://craftinginterpreters.com/chunks-of-bytecode.html chapter of clox.
- Loading branch information
1 parent
e40bcfa
commit 565ed49
Showing
10 changed files
with
174 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
/target |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
[package] | ||
name = "rvm" | ||
version = "0.1.0" | ||
authors = ["Jaime <[email protected]>"] | ||
edition = "2018" | ||
|
||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html | ||
|
||
[dependencies] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
# RVM [Rust VM] | ||
Reference Bytecode Virtual Machine implemented in Rust. | ||
|
||
WIP experiment based off Clox. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
use crate::opcode::OpCode; | ||
use crate::value::Value; | ||
|
||
#[derive(Debug)] | ||
pub struct Chunk { | ||
pub codes: Vec<OpCode>, | ||
|
||
// Constant Pool: Vector storing all the constant values dynamically and accessed using index stored in 'codes' vector | ||
pub constants: Vec<Value>, | ||
|
||
// Optimize storing line info: https://en.wikipedia.org/wiki/Run-length_encoding | ||
pub lines: Vec<usize>, | ||
} | ||
|
||
impl Chunk { | ||
// Associated function to create a new Chunk | ||
pub fn new() -> Chunk { | ||
Chunk { | ||
// codes: Vec::<OpCode>::new(), | ||
codes: Vec::<OpCode>::with_capacity(6), | ||
constants: Vec::new(), | ||
lines: Vec::new(), | ||
} | ||
} | ||
|
||
// Method to write a new OpCode | ||
pub fn write(&mut self, byte: OpCode, line_number: usize) { | ||
self.codes.push(byte); | ||
self.lines.push(line_number); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
use crate::chunk::Chunk; | ||
use crate::opcode::OpCode; | ||
|
||
// pub fn disassemble_chunk(chunk: Chunk, name: &String) { | ||
pub fn disassemble_chunk(chunk: &Chunk, name: &str) { | ||
// println!("{:?} ", chunk); | ||
println!("== {} ==", name); | ||
|
||
let mut offset: usize = 0; | ||
while offset < chunk.codes.len() { | ||
offset = disassemble_instruction(&chunk, offset); | ||
} | ||
} | ||
|
||
fn disassemble_instruction(chunk: &Chunk, offset: usize) -> usize { | ||
// Prints the offset (bytecode index of a chunk) with 0 padding up to 3 digits | ||
// https://stackoverflow.com/a/41821049 | ||
print!("{:0width$}", offset, width = 3); | ||
|
||
// Print line number or | for bytecodes on the same line | ||
if offset > 0 && chunk.lines[offset] == chunk.lines[offset - 1] { | ||
print!(" | "); | ||
} else { | ||
print!("{:4} ", chunk.lines[offset]); | ||
} | ||
|
||
match chunk.codes[offset] { | ||
OpCode::RETURN => simple_instruction("RETURN", &chunk, offset), | ||
OpCode::CONSTANT => constant_instruction("CONSTANT", &chunk, offset), | ||
// OpCode::ConstantIndex(index) => simple_instruction("ConstantIndex", offset), | ||
// | ||
ref instruction => { | ||
println!("Unknown opcode {:?}\n", instruction); | ||
offset + 1 | ||
} | ||
} | ||
} | ||
/* | ||
Printing should be of the format | ||
Line number OpCode index OpCode string representation add. data if any | ||
*/ | ||
|
||
// fn simple_instruction(name: &str, offset: usize) -> usize { | ||
// println!("{}", name); | ||
// offset + 1 | ||
// } | ||
fn simple_instruction(name: &str, chunk: &Chunk, offset: usize) -> usize { | ||
println!("{:?}", chunk.codes[offset]); | ||
offset + 1 | ||
} | ||
|
||
fn constant_instruction(name: &str, chunk: &Chunk, offset: usize) -> usize { | ||
let constant = &chunk.constants[offset]; | ||
|
||
// println!("{} -> {:?}", name, constant); | ||
println!("{:?} -> {:?}", chunk.codes[offset], constant); | ||
offset + 2 | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
mod chunk; | ||
mod debug; | ||
mod opcode; | ||
mod value; | ||
mod vm; | ||
|
||
use chunk::Chunk; | ||
use debug::disassemble_chunk; | ||
use opcode::OpCode; | ||
use value::Value; | ||
use vm::VM; | ||
|
||
fn main() { | ||
let mut chunk = Chunk::new(); | ||
|
||
chunk.write(OpCode::CONSTANT, 2); | ||
chunk.constants.push(Value::Number(1.2)); | ||
chunk.write(OpCode::ConstantIndex(chunk.constants.len()), 2); | ||
|
||
chunk.write(OpCode::RETURN, 2); | ||
|
||
disassemble_chunk(&chunk, "test"); | ||
// println!("{:?}", chunk); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
// There are 2 types of OpCodes | ||
// First type are the instruction OpCodes, that are denoted by their all CAPS spelling | ||
// Secondly there are special OpCodes, that are variants with additional values like 'ConstantIndex(usize)' | ||
// | ||
// Clox differentiate OpCode from Data using OP_ prefix, and also all their data types is just a single byte anyways | ||
|
||
#[derive(Debug)] | ||
pub enum OpCode { | ||
RETURN, | ||
CONSTANT, | ||
|
||
ConstantIndex(usize), | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
// type Value = f64; | ||
|
||
#[derive(Debug)] | ||
pub enum Value { | ||
Number(f64), | ||
String(String), | ||
Bool(bool), | ||
Null, | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
use crate::chunk::Chunk; | ||
use crate::opcode::OpCode; | ||
|
||
pub struct VM { | ||
pub chunks: Vec<Chunk>, | ||
} | ||
|
||
// Change this to error or something | ||
pub enum InterpretResult { | ||
Ok, | ||
CompileError, | ||
RuntimeError, | ||
} | ||
|
||
impl VM { | ||
// CHange this to result type | ||
pub fn interpret(chunk: &Chunk) -> InterpretResult { | ||
InterpretResult::Ok | ||
} | ||
} |