1
1
Fork 0
mirror of https://github.com/azur1s/bobbylisp.git synced 2024-10-16 02:37:40 -05:00

refactor: use register instead of names

This commit is contained in:
azur 2022-02-04 09:33:57 +07:00 committed by Natapat Samutpong
parent 6424d4fc9f
commit a08f3ee5f0
4 changed files with 25 additions and 22 deletions

View file

@ -1,6 +1,10 @@
use crate::{vm::instr::*, compiler::parser::Sexpr::{self, *}}; use crate::{vm::instr::*, compiler::parser::Sexpr::{self, *}};
pub struct Compiler { pub struct Compiler {
// Compiled instructions
pub instructions: Vec<Instr>, pub instructions: Vec<Instr>,
// Compiled variables's register address
pub variables: Vec<(String, Register)>,
// Current register index
pub register_pointer: usize, pub register_pointer: usize,
} }
@ -8,6 +12,7 @@ impl Compiler {
pub fn new() -> Compiler { pub fn new() -> Compiler {
Compiler { Compiler {
instructions: Vec::new(), instructions: Vec::new(),
variables: Vec::new(),
register_pointer: 1, register_pointer: 1,
} }
} }
@ -68,8 +73,11 @@ impl Compiler {
}; };
let body = &cdr[1]; 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.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)?); result.append(&mut self.compile_intrinsic(call, &cdr)?);
@ -162,7 +170,8 @@ impl Compiler {
result.push(Instr::Push { value: Type::Boolean(*b) }); result.push(Instr::Push { value: Type::Boolean(*b) });
}, },
Symbol(s) => { 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())?); } _ => { result.append(&mut self.compile(atom.clone())?); }
} }

View file

@ -181,7 +181,7 @@ impl FromStr for Register {
pub enum Instr { pub enum Instr {
Label { name: String }, Comment { text: String }, Label { name: String }, Comment { text: String },
// Variable declaration // Variable declaration
Load { name: String }, Store { name: String }, Load { address: Register }, Store { address: Register },
// Call intrinsic function. // Call intrinsic function.
Call, Call,
// Stack operations. // Stack operations.
@ -204,8 +204,8 @@ impl Display for Instr {
// ----------20--------- Parameter start // ----------20--------- Parameter start
Instr::Label { name } => write!(f, ".{}:", name), Instr::Label { name } => write!(f, ".{}:", name),
Instr::Comment { text } => write!(f, ";{}", text), Instr::Comment { text } => write!(f, ";{}", text),
Instr::Load { name } => write!(f, " LOAD {}", name), Instr::Load { address } => write!(f, " LOAD {}", address),
Instr::Store { name } => write!(f, " STORE {}", name), Instr::Store { address } => write!(f, " STORE {}", address),
Instr::Call => write!(f, " CALL"), Instr::Call => write!(f, " CALL"),
Instr::Push { value } => write!(f, " PUSH {}", value), Instr::Push { value } => write!(f, " PUSH {}", value),
Instr::Pop { address } => write!(f, " POP {}", address), Instr::Pop { address } => write!(f, " POP {}", address),

View file

@ -16,8 +16,8 @@ pub fn parse_instr(src: &str) -> Vec<Instr> {
if tokens[0].starts_with(";") { continue; } if tokens[0].starts_with(";") { continue; }
match tokens[0] { match tokens[0] {
"LOAD" => { result.push(Instr::Load { name : tokens[1].to_string() }); }, "LOAD" => { result.push(Instr::Load { address: register!(tokens[1].to_string()) }); },
"STORE" => { result.push(Instr::Store { name: tokens[1].to_string() }); }, "STORE" => { result.push(Instr::Store { address: register!(tokens[1].to_string()) }); },
"CALL" => { result.push(Instr::Call); }, "CALL" => { result.push(Instr::Call); },
"PUSH" => { result.push(Instr::Push { value: value!(tokens[1]) }); }, "PUSH" => { result.push(Instr::Push { value: value!(tokens[1]) }); },
"POP" => { result.push(Instr::Pop { address: register!(tokens[1]) }); }, "POP" => { result.push(Instr::Pop { address: register!(tokens[1]) }); },

View file

@ -30,7 +30,6 @@ pub struct VM {
jumped_from: isize, jumped_from: isize,
registers: Vec<Type>, registers: Vec<Type>,
stack: Vec<Type>, stack: Vec<Type>,
variables: Vec<(String, Type)>,
function_pointer: Vec<(String, isize)>, // (name, index) function_pointer: Vec<(String, isize)>, // (name, index)
} }
@ -43,7 +42,6 @@ impl VM {
jumped_from: 0, jumped_from: 0,
registers: vec![Type::Null; 1024], registers: vec![Type::Null; 1024],
stack: Vec::new(), stack: Vec::new(),
variables: Vec::new(),
function_pointer: Vec::new(), function_pointer: Vec::new(),
} }
} }
@ -73,13 +71,13 @@ impl VM {
let instr = &instrs[(self.instr_pointer - 1) as usize]; let instr = &instrs[(self.instr_pointer - 1) as usize];
if debug { print_debug(self, &instr); } if debug { print_debug(self, &instr); }
match instr { match instr {
Load { name } => { Load { address } => {
self.load(name)?; self.load(address)?;
continue 'tco; continue 'tco;
} },
Store { name } => { Store { address } => {
let value = &self.stack.pop().unwrap(); let value = &self.stack.pop().unwrap();
self.store(name, value)?; self.store(address, value)?;
continue 'tco; continue 'tco;
}, },
Call => { Call => {
@ -164,16 +162,12 @@ impl VM {
Ok(self.registers[address.value()] = value.clone()) Ok(self.registers[address.value()] = value.clone())
} }
fn store(&mut self, name: &String, value: &Type) -> Result<(), Error> { fn store(&mut self, address: &Register, value: &Type) -> Result<(), Error> {
Ok(self.variables.push((name.clone(), value.clone()))) Ok(self.registers[address.value()] = value.clone())
} }
fn load(&mut self, name: &String) -> Result<(), Error> { fn load(&mut self, address: &Register) -> Result<(), Error> {
let value = self.variables.iter().find(|(n, _)| n == name); Ok(self.stack.push(self.registers[address.value()].clone()))
if value.is_none() { return Err(Error::UnknownVariable(name.clone())); }
let value = value.unwrap();
self.stack.push(value.1.clone());
Ok(())
} }
fn get_function_pointer(&mut self, name: String) -> Result<isize, Error> { fn get_function_pointer(&mut self, name: String) -> Result<isize, Error> {