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:
parent
6424d4fc9f
commit
a08f3ee5f0
|
@ -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())?); }
|
||||||
}
|
}
|
||||||
|
|
|
@ -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),
|
||||||
|
|
|
@ -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]) }); },
|
||||||
|
|
|
@ -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> {
|
||||||
|
|
Loading…
Reference in a new issue