diff --git a/blspc/src/compiler/compile.rs b/blspc/src/compiler/compile.rs index fa7068e..e5576be 100644 --- a/blspc/src/compiler/compile.rs +++ b/blspc/src/compiler/compile.rs @@ -1,6 +1,10 @@ use crate::{vm::instr::*, compiler::parser::Sexpr::{self, *}}; pub struct Compiler { + // Compiled instructions pub instructions: Vec, + // Compiled variables's register address + pub variables: Vec<(String, Register)>, + // Current register index pub register_pointer: usize, } @@ -8,6 +12,7 @@ impl Compiler { pub fn new() -> Compiler { Compiler { instructions: Vec::new(), + variables: Vec::new(), register_pointer: 1, } } @@ -68,8 +73,11 @@ impl Compiler { }; let body = &cdr[1]; + let var_pointer = self.next_register(); + self.variables.push((var_name, var_pointer)); + result.append(&mut self.compile(body.clone())?); - result.push(Instr::Store { name: var_name }); + result.push(Instr::Store { address: var_pointer }); }, _ => { result.append(&mut self.compile_intrinsic(call, &cdr)?); @@ -162,7 +170,8 @@ impl Compiler { result.push(Instr::Push { value: Type::Boolean(*b) }); }, Symbol(s) => { - result.push(Instr::Load { name: s.clone() }); + let var_pointer = self.variables.iter().find(|&(ref name, _)| name == s).unwrap().1; + result.push(Instr::Load { address: var_pointer }); }, _ => { result.append(&mut self.compile(atom.clone())?); } } diff --git a/blspc/src/vm/instr.rs b/blspc/src/vm/instr.rs index 08a5755..60b2be3 100644 --- a/blspc/src/vm/instr.rs +++ b/blspc/src/vm/instr.rs @@ -181,7 +181,7 @@ impl FromStr for Register { pub enum Instr { Label { name: String }, Comment { text: String }, // Variable declaration - Load { name: String }, Store { name: String }, + Load { address: Register }, Store { address: Register }, // Call intrinsic function. Call, // Stack operations. @@ -204,8 +204,8 @@ impl Display for Instr { // ----------20--------- Parameter start Instr::Label { name } => write!(f, ".{}:", name), Instr::Comment { text } => write!(f, ";{}", text), - Instr::Load { name } => write!(f, " LOAD {}", name), - Instr::Store { name } => write!(f, " STORE {}", name), + Instr::Load { address } => write!(f, " LOAD {}", address), + Instr::Store { address } => write!(f, " STORE {}", address), Instr::Call => write!(f, " CALL"), Instr::Push { value } => write!(f, " PUSH {}", value), Instr::Pop { address } => write!(f, " POP {}", address), diff --git a/blspc/src/vm/parser.rs b/blspc/src/vm/parser.rs index 4037ebe..90c4647 100644 --- a/blspc/src/vm/parser.rs +++ b/blspc/src/vm/parser.rs @@ -16,8 +16,8 @@ pub fn parse_instr(src: &str) -> Vec { if tokens[0].starts_with(";") { continue; } match tokens[0] { - "LOAD" => { result.push(Instr::Load { name : tokens[1].to_string() }); }, - "STORE" => { result.push(Instr::Store { name: tokens[1].to_string() }); }, + "LOAD" => { result.push(Instr::Load { address: register!(tokens[1].to_string()) }); }, + "STORE" => { result.push(Instr::Store { address: register!(tokens[1].to_string()) }); }, "CALL" => { result.push(Instr::Call); }, "PUSH" => { result.push(Instr::Push { value: value!(tokens[1]) }); }, "POP" => { result.push(Instr::Pop { address: register!(tokens[1]) }); }, diff --git a/blspc/src/vm/vm.rs b/blspc/src/vm/vm.rs index d850fe8..be02918 100644 --- a/blspc/src/vm/vm.rs +++ b/blspc/src/vm/vm.rs @@ -30,7 +30,6 @@ pub struct VM { jumped_from: isize, registers: Vec, stack: Vec, - variables: Vec<(String, Type)>, function_pointer: Vec<(String, isize)>, // (name, index) } @@ -43,7 +42,6 @@ impl VM { jumped_from: 0, registers: vec![Type::Null; 1024], stack: Vec::new(), - variables: Vec::new(), function_pointer: Vec::new(), } } @@ -73,13 +71,13 @@ impl VM { let instr = &instrs[(self.instr_pointer - 1) as usize]; if debug { print_debug(self, &instr); } match instr { - Load { name } => { - self.load(name)?; + Load { address } => { + self.load(address)?; continue 'tco; - } - Store { name } => { + }, + Store { address } => { let value = &self.stack.pop().unwrap(); - self.store(name, value)?; + self.store(address, value)?; continue 'tco; }, Call => { @@ -164,16 +162,12 @@ impl VM { Ok(self.registers[address.value()] = value.clone()) } - fn store(&mut self, name: &String, value: &Type) -> Result<(), Error> { - Ok(self.variables.push((name.clone(), value.clone()))) + fn store(&mut self, address: &Register, value: &Type) -> Result<(), Error> { + Ok(self.registers[address.value()] = value.clone()) } - fn load(&mut self, name: &String) -> Result<(), Error> { - let value = self.variables.iter().find(|(n, _)| n == name); - if value.is_none() { return Err(Error::UnknownVariable(name.clone())); } - let value = value.unwrap(); - self.stack.push(value.1.clone()); - Ok(()) + fn load(&mut self, address: &Register) -> Result<(), Error> { + Ok(self.stack.push(self.registers[address.value()].clone())) } fn get_function_pointer(&mut self, name: String) -> Result {