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

feat: variable definition

This commit is contained in:
azur 2022-02-04 08:58:46 +07:00 committed by Natapat Samutpong
parent b168d29648
commit c8a79e87ef
5 changed files with 43 additions and 27 deletions

View file

@ -60,7 +60,17 @@ impl Compiler {
result.append(&mut then); result.append(&mut then);
result.push(Instr::Jump { to: len(&else_) }); result.push(Instr::Jump { to: len(&else_) });
result.append(&mut else_); result.append(&mut else_);
} },
"def" => {
let var_name = match &cdr[0] {
Symbol(ref name) => name.clone(),
_ => return Err(format!("Expected variable name, got {}", cdr[0])),
};
let body = &cdr[1];
result.append(&mut self.compile(body.clone())?);
result.push(Instr::Store { name: var_name });
},
_ => { _ => {
result.append(&mut self.compile_intrinsic(call, &cdr)?); result.append(&mut self.compile_intrinsic(call, &cdr)?);
} }

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 },
// Store a literal value into a register. // Store a literal value into a register.
Store { address: Register, value: Type }, Store { name: String },
// Call intrinsic function. // Call intrinsic function.
Call, Call,
// Stack operations. // Stack operations.
@ -204,7 +204,7 @@ 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::Store { address, value } => write!(f, " STORE {} {}", address, value), Instr::Store { name } => write!(f, " STORE {}", name),
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,10 +16,7 @@ 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] {
"STORE" => { result.push(Instr::Store { "STORE" => { result.push(Instr::Store { name: tokens[1].to_string() }); },
address: register!(tokens[1]),
value: value!(tokens[2]),
}); },
"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

@ -28,6 +28,7 @@ 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)
} }
@ -40,6 +41,7 @@ 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(),
} }
} }
@ -69,8 +71,9 @@ 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 {
Store { address, value, .. } => { Store { name } => {
self.store(&address, &value)?; let value = &self.stack.pop().unwrap();
self.store(name, value)?;
continue 'tco; continue 'tco;
}, },
Call => { Call => {
@ -85,7 +88,7 @@ impl VM {
}, },
Pop { address } => { Pop { address } => {
let value = self.stack.pop(); let value = self.stack.pop();
self.store(&address, &value.unwrap())?; self.pop(&address, &value.unwrap())?;
continue 'tco; continue 'tco;
}, },
Swap => { Swap => {
@ -150,11 +153,15 @@ impl VM {
Ok(self.stack.push(value)) Ok(self.stack.push(value))
} }
fn store(&mut self, address: &Register, value: &Type) -> Result<(), Error> { fn pop(&mut self, address: &Register, value: &Type) -> Result<(), Error> {
// TODO: Remove .clone() // TODO: Remove .clone()
Ok(self.registers[address.value()] = value.clone()) 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 get_function_pointer(&mut self, name: String) -> Result<isize, Error> { fn get_function_pointer(&mut self, name: String) -> Result<isize, Error> {
for (idx, (n, _)) in self.function_pointer.iter().enumerate() { for (idx, (n, _)) in self.function_pointer.iter().enumerate() {
if n == &name { if n == &name {

2
example/var.blsp Normal file
View file

@ -0,0 +1,2 @@
(fun main
(def name "bobby"))