Skip to content

Commit

Permalink
Update readme and run rustfmt
Browse files Browse the repository at this point in the history
  • Loading branch information
rctcwyvrn committed Aug 12, 2020
1 parent 05cf746 commit c72df7e
Show file tree
Hide file tree
Showing 7 changed files with 28 additions and 17 deletions.
14 changes: 12 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,20 @@ Considering this was my first project in rust and it was translating from a lang

rlox is fast and reasonably well structured. Some things that were difficult for clox to implement basically dropped out for free because of my design (superclasses), but some things were a nightmare to implement due to not knowing this sort of structure would be needed (closures).

Overall a very fun experience and a nice projec that I feel quite proud of
Overall a very fun experience and a nice project that I feel quite proud of

Todo:
- Clean up all the fixme and todos in the code
- Set up a proper test suite for rlox using the craftinginterpreters test harness
- Bench rlox against clox
- Start profiling and doing optimizations
- Start profiling and doing optimizations

Main differences between my rlox and clox
---
1. Functions are compiled into FunctionChunks that live on a vector in the compiler, runtime references to them are LoxFunction opcodes that hold an index into that vector
2. Same idea for classes with ClassChunks. Due to this we can inherit superclasses at compile time instead of runtime
3. Variable resolution was moved into it's own struct, Resolver, to manage the recursive nature of it. It doesn't 100% work to Lox spec, but it works for simple closures
4. For both the Resolver and the Compiler, the linked-list structure of Compilers in clox is replaced with a vector acting as a stack of compilers, and a few "currently targetting this" struct values and functions.
5. Only closures and class instances are "heap" allocated. The other values (double, string, bool) live on the rust stack and are automatically dropped by the rust runtime when they leave the lox vm stack. The heap allocated values use a "pointer" value which indexes into the "heap", which is just a vector that gets shuffled around a bit
6. The gc ended up being quite different due to my choice of a vector to hold the HeapObj values, but it still implements mark-sweep and it works :).
7. The VM is split into two parts, one that holds all the compilation information and reads off instructions from it (VM) and one that holds the stack and the heap and is responsible for all the execution state (VMState)
4 changes: 1 addition & 3 deletions src/chunk.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,9 +67,7 @@ impl Chunk {
}

pub fn new() -> Chunk {
Chunk {
code: Vec::new(),
}
Chunk { code: Vec::new() }
}
}

Expand Down
9 changes: 7 additions & 2 deletions src/compiler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ impl Compiler<'_> {
None => {
self.constants.push(value);
self.constants.len() - 1
},
}
}
}

Expand Down Expand Up @@ -919,7 +919,12 @@ impl Compiler<'_> {
}

for class_chunk in self.classes.iter() {
disassemble_class_chunk(&class_chunk, &self.functions, &self.classes, &self.constants);
disassemble_class_chunk(
&class_chunk,
&self.functions,
&self.classes,
&self.constants,
);
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/debug.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ pub fn disassemble_class_chunk(
}
}

pub fn disassemble_fn_chunk(fn_chunk: &FunctionChunk, constants:&Vec<Value>) {
pub fn disassemble_fn_chunk(fn_chunk: &FunctionChunk, constants: &Vec<Value>) {
match &fn_chunk.name {
Some(name) => eprintln!("== <fn {}> ==============", name),
None => eprintln!("== <script> =============="),
Expand Down
10 changes: 4 additions & 6 deletions src/vm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -385,7 +385,7 @@ impl VM {
}

fn get_variable_name(&self, index: usize) -> String {
let name_val = self.constants[index].clone();
let name_val = self.constants[index].clone();
if let Value::LoxString(var_name) = name_val {
return var_name;
} else {
Expand Down Expand Up @@ -512,8 +512,8 @@ impl VM {
let value = instance.fields.get(&name).unwrap().clone();
let index = state.stack.len() - 1 - arg_count;
state.stack[index] = value; // Remove the instance and replace with the value
state.call_value(arg_count, &self.functions, &self.classes) // Perform the call

state.call_value(arg_count, &self.functions, &self.classes)
// Perform the call
} else if class_def.methods.contains_key(&name) {
// We know that the top of the stack is LoxPointer | arg1 | arg2
// So we can go ahead and call
Expand Down Expand Up @@ -674,9 +674,7 @@ impl VM {

OpCode::OpClass(index) => state.push(Value::LoxClass(index)),

OpCode::OpConstant(index) => {
state.push(self.constants[index].clone())
} // FIXME
OpCode::OpConstant(index) => state.push(self.constants[index].clone()), // FIXME
OpCode::OpTrue => state.push(Value::Bool(true)),
OpCode::OpFalse => state.push(Value::Bool(false)),
OpCode::OpNil => state.push(Value::Nil),
Expand Down
4 changes: 2 additions & 2 deletions tool/.dart_tool/package_config.json
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,7 @@
"packageUri": "lib/"
}
],
"generated": "2020-08-10T19:52:56.169127Z",
"generated": "2020-08-12T01:35:02.401599Z",
"generator": "pub",
"generatorVersion": "2.8.4"
"generatorVersion": "2.9.0"
}
2 changes: 1 addition & 1 deletion tool/.packages
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Generated by pub on 2020-08-10 12:52:56.150376.
# Generated by pub on 2020-08-11 18:35:02.374374.
args:file:///home/lily/.pub-cache/hosted/pub.dartlang.org/args-1.6.0/lib/
async:file:///home/lily/.pub-cache/hosted/pub.dartlang.org/async-2.4.1/lib/
charcode:file:///home/lily/.pub-cache/hosted/pub.dartlang.org/charcode-1.1.3/lib/
Expand Down

0 comments on commit c72df7e

Please sign in to comment.