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

feat: variable calling

This commit is contained in:
azur 2022-02-04 09:12:14 +07:00 committed by Natapat Samutpong
parent c8a79e87ef
commit 6424d4fc9f
6 changed files with 26 additions and 8 deletions

View file

@ -136,7 +136,10 @@ impl Compiler {
result.push(Instr::Swap); result.push(Instr::Swap);
result.push(Instr::Div); result.push(Instr::Div);
}, },
_ => return Err(format!("Unknown intrinsic: {}", intrinsic)), _ => {
result.push(Instr::Comment { text: format!("{} function", intrinsic) });
result.push(Instr::JumpLabel { to: format!("function_{}", intrinsic), });
}
} }
Ok(result) Ok(result)
@ -144,7 +147,6 @@ impl Compiler {
fn compile_atom(&mut self, atom: &Sexpr) -> Result<Vec<Instr>, String> { fn compile_atom(&mut self, atom: &Sexpr) -> Result<Vec<Instr>, String> {
let mut result = Vec::new(); let mut result = Vec::new();
let comp = atom.clone(); // Used for commenting
match atom { match atom {
Int(i) => { Int(i) => {
@ -160,8 +162,7 @@ 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::Comment { text: format!("{} variable", comp) }); result.push(Instr::Load { name: s.clone() });
result.push(Instr::JumpLabel { to: format!("function_{}", s), });
}, },
_ => { result.append(&mut self.compile(atom.clone())?); } _ => { result.append(&mut self.compile(atom.clone())?); }
} }

View file

@ -180,8 +180,8 @@ impl FromStr for Register {
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
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. // Variable declaration
Store { name: String }, Load { name: String }, Store { name: String },
// Call intrinsic function. // Call intrinsic function.
Call, Call,
// Stack operations. // Stack operations.
@ -204,6 +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::Load { name } => write!(f, " LOAD {}", name),
Instr::Store { name } => write!(f, " STORE {}", name), 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),

View file

@ -16,6 +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] {
"LOAD" => { result.push(Instr::Load { name : tokens[1].to_string() }); },
"STORE" => { result.push(Instr::Store { name: tokens[1].to_string() }); }, "STORE" => { result.push(Instr::Store { name: 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]) }); },

View file

@ -7,6 +7,7 @@ pub enum Error {
StackOverflow, StackOverflow,
UnknownFunction(String), UnknownFunction(String),
UnknownFunctionCall(isize, isize), UnknownFunctionCall(isize, isize),
UnknownVariable(String),
InvalidAriphmeticOperation, InvalidAriphmeticOperation,
} }
@ -17,6 +18,7 @@ impl Display for Error {
Error::StackOverflow => write!(f, "Stack overflow"), Error::StackOverflow => write!(f, "Stack overflow"),
Error::UnknownFunction(name) => write!(f, "Unknown function: {}", name), Error::UnknownFunction(name) => write!(f, "Unknown function: {}", name),
Error::UnknownFunctionCall(l, e) => write!(f, "Unknown function call at {}: {}", l, e), Error::UnknownFunctionCall(l, e) => write!(f, "Unknown function call at {}: {}", l, e),
Error::UnknownVariable(name) => write!(f, "Unknown variable: {}", name),
Error::InvalidAriphmeticOperation => write!(f, "Invalid ariphmetic operation"), Error::InvalidAriphmeticOperation => write!(f, "Invalid ariphmetic operation"),
} }
} }
@ -71,6 +73,10 @@ 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 } => {
self.load(name)?;
continue 'tco;
}
Store { name } => { Store { name } => {
let value = &self.stack.pop().unwrap(); let value = &self.stack.pop().unwrap();
self.store(name, value)?; self.store(name, value)?;
@ -162,6 +168,14 @@ impl VM {
Ok(self.variables.push((name.clone(), value.clone()))) Ok(self.variables.push((name.clone(), 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 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 {

View file

@ -1,4 +1,4 @@
(fun str "Hello, world!") (fun str "Hello, world!")
(fun main (fun main
(print str)) (print (str)))

View file

@ -1,2 +1,3 @@
(fun main (fun main
(def name "bobby")) (do (def name "Bobby")
(print name)))