Skip to content

Commit

Permalink
feat: addition and subtraction works on VM
Browse files Browse the repository at this point in the history
  • Loading branch information
Mateusz Russak committed Dec 3, 2023
1 parent a6776a6 commit 71a6db5
Show file tree
Hide file tree
Showing 5 changed files with 35 additions and 82 deletions.
98 changes: 24 additions & 74 deletions crates/compiler/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,56 +2,11 @@ use std::{fmt::{Display, Formatter}};

use lexer::PError;
use parser::{Node, Op, Value};
use vm::OpCode;

struct Instruction {
op_code: OpCode,
arg0: Option<u8>,
arg1: Option<u8>,
arg2: Option<u8>,
}


impl Instruction {
pub fn new(op_code: OpCode) -> Instruction {
Instruction {
op_code,
arg0: None,
arg1: None,
arg2: None,
}
}
pub fn with_arg0(mut self, arg0: u8) -> Instruction {
self.arg0 = Some(arg0);
self
}
pub fn with_arg1(mut self, arg1: u8) -> Instruction {
self.arg1 = Some(arg1);
self
}
pub fn with_arg2(mut self, arg2: u8) -> Instruction {
self.arg2 = Some(arg2);
self
}
pub fn to_bytes(&self) -> Vec<u8> {
let mut bytes = Vec::new();
bytes.push(self.op_code as u8);
if let Some(arg0) = self.arg0 {
bytes.push(arg0);
}
if let Some(arg1) = self.arg1 {
bytes.push(arg1);
}
if let Some(arg2) = self.arg2 {
bytes.push(arg2);
}
bytes
}
}
use vm::{Instr, Instrs, OpCode};


struct Code {
code: Vec<Instruction>,
code: Vec<Instr>,
}

impl Code {
Expand All @@ -60,11 +15,11 @@ impl Code {
code: Vec::new(),
}
}
pub fn push(&mut self, inst: Instruction) {
pub fn push(&mut self, inst: Instr) {
self.code.push(inst);
}
pub fn to_bytes(&self) -> Vec<u8> {
self.code.iter().flat_map(|i| i.to_bytes()).collect::<Vec<_>>()
Instrs(self.code.iter().map(|c| c.byte_description()).collect()).into()
}
}

Expand Down Expand Up @@ -104,33 +59,40 @@ pub fn compile_node(node: &Node, mut consts: &mut Mem, inst: &mut Code) -> Resul
match node.op {
Op::Add => {
compile_node(&node.children[0], &mut consts, inst)?;
inst.push(Instr::Mov(2, 0));
compile_node(&node.children[1], &mut consts, inst)?;
inst.push(Instr::Mov(1, 0));
inst.push(Instr::Add(0,1,2));
},
Op::Sub => {
compile_node(&node.children[0], &mut consts, inst)?;
inst.push(Instr::Mov(2, 0));
compile_node(&node.children[1], &mut consts, inst)?;
inst.push(Instruction::new(OpCode::Add));
inst.push(Instr::Mov(1, 0));
inst.push(Instr::Sub(0,2,1));
},
Op::Value => {
match &node.value {
Some(Value::Number(0)) => inst.push(Instruction::new(OpCode::Load0)),
Some(Value::Number(1)) => inst.push(Instruction::new(OpCode::Load1)),
Some(Value::Number(0)) => inst.push(Instr::Load0(0)),
Some(Value::Number(1)) => inst.push(Instr::Load1(0)),
Some(Value::Number(val)) => {
let addr = consts.write(*val as u32);
if addr < 256 {
inst.push(Instruction::new(OpCode::Load).with_arg0(addr.try_into().unwrap()));
}
inst.push(Instr::Load(0, *val as u16));
},
Some(..) => {
panic!("Unknown value: {}", node);
},
None => panic!("No value"),
}
},
Op::Scope => {
Op::Scope | Op::Paren => {
for child in &node.children {
println!("child: {}", child.op);
compile_node(child, &mut consts, inst)?;
}
inst.push(Instruction::new(OpCode::Exit));
inst.push(Instr::Exit);
},
_ => {
panic!("Unknown op: {}", node);
panic!("Unknown op: {} {}", node, node.op);
}
}
Ok(())
Expand All @@ -141,11 +103,7 @@ pub fn compile(node: &Node) -> Result<Vec<u8>, PError> {
let mut consts = Mem::new();
compile_node(node, &mut consts, &mut inst)?;
let code = inst.to_bytes();
let mem = consts.to_bytes();
let mut bytes = Vec::new();
bytes.extend_from_slice(&code);
bytes.extend_from_slice(&mem);
Ok(bytes)
Ok(code)
}

#[cfg(test)]
Expand All @@ -155,21 +113,13 @@ mod tests {

use super::*;

#[test]
fn compile_simple() {
let mut node = Node::new(Op::Scope, Location::Eof);
node.add(Node::new(Op::Value, Location::Eof).set_value(1.into()));
let bytes = compile(&node).unwrap();
assert_eq!(bytes, vec![3, 5]);
assert_eq!(bytes, vec![OpCode::Load1.into(), 0, OpCode::Exit.into()]);
}

fn compile_binary_op() {
let mut node = Node::new(Op::Scope, Location::Eof);
let mut add = Node::new(Op::Add, Location::Eof);
add.add(Node::new(Op::Value, Location::Eof).set_value(1.into()));
add.add(Node::new(Op::Value, Location::Eof).set_value(2.into()));
node.add(add);
let bytes = compile(&node).unwrap();
assert_eq!(bytes, vec![3, 2, 0, 6, 5]);
}
}

1 change: 0 additions & 1 deletion crates/vm/src/instr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,6 @@ impl Instr {
bytes[i] = data[pc+i];
}

println!("val: {:?}", bytes);
let val = u32::from_be_bytes(bytes.try_into().unwrap());
match code {
OpCode::Load => parse_instr!(val; tr value -> Load),
Expand Down
3 changes: 0 additions & 3 deletions crates/vm/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,6 @@ extern crate num_derive;
#[macro_use]
extern crate enum_display;

use std::{fmt::{Display, Formatter}};

use lexer::PError;
pub use instr::{Instr, Instrs};
pub use op_code::OpCode;
pub use vm::VM;
3 changes: 2 additions & 1 deletion crates/vm/src/vm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ impl VM {
pub fn new(prog: Vec<u8>) -> VM {
VM {
prog,
regs: vec![0; 32],
regs: vec![0; 16],
stack: Vec::new(),
pc: 0,
}
Expand All @@ -79,6 +79,7 @@ impl VM {
while let Some(inst) = self.next() {
xx -= 1;
if xx < 0 {break;}
println!("regs: {:?}", self.regs);
println!("inst: {}", inst);
match inst {
Instr::Sub(target, v1, v2) => {
Expand Down
12 changes: 9 additions & 3 deletions tests/compute_compiled_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,11 @@ macro_rules! test_return_code{
let node = parse(text).unwrap_or_else(|e| {
panic!("\nError:\n{}\n", e.format_error($i, "file.lum", false));
});
//println!("{}", node);
println!("{}", node);
let bytes = compiler::compile(&node).unwrap_or_else(|e| {
panic!("\nError:\n{}\n", e.format_error($i, "file.lum", false));
});

println!("{:?}", bytes);
let mut vm = vm::VM::new(bytes);
let val = vm.run().unwrap_or_else(|e| {
panic!("\nError:\n{}\n", e.format_error($i, "file.lum", false));
Expand All @@ -29,7 +29,13 @@ macro_rules! test_return_code{
};
}

//test_return_code!(simple, "1", 1);
test_return_code!(vm_return_1, "1", 1);
test_return_code!(vm_compute_add, "1+2", 3);
test_return_code!(vm_compute_add_2, "1+2+2", 5);
test_return_code!(vm_compute_sub, "4-2", 2);
test_return_code!(vm_compute_sub_overflow, "2-4", (-2i32) as u32);
test_return_code!(vm_compute_add_and_sub, "1+2-2", 1);
test_return_code!(vm_compute_branch, "if(1){2}else{3}", 2);
/*
test_return_code!(simple, "1 + 2", 3);
test_return_code!(with_braces, "2 * (3 + 4) ", 14);
Expand Down

0 comments on commit 71a6db5

Please sign in to comment.