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:
parent
c8a79e87ef
commit
6424d4fc9f
|
@ -136,7 +136,10 @@ impl Compiler {
|
|||
result.push(Instr::Swap);
|
||||
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)
|
||||
|
@ -144,7 +147,6 @@ impl Compiler {
|
|||
|
||||
fn compile_atom(&mut self, atom: &Sexpr) -> Result<Vec<Instr>, String> {
|
||||
let mut result = Vec::new();
|
||||
let comp = atom.clone(); // Used for commenting
|
||||
|
||||
match atom {
|
||||
Int(i) => {
|
||||
|
@ -160,8 +162,7 @@ impl Compiler {
|
|||
result.push(Instr::Push { value: Type::Boolean(*b) });
|
||||
},
|
||||
Symbol(s) => {
|
||||
result.push(Instr::Comment { text: format!("{} variable", comp) });
|
||||
result.push(Instr::JumpLabel { to: format!("function_{}", s), });
|
||||
result.push(Instr::Load { name: s.clone() });
|
||||
},
|
||||
_ => { result.append(&mut self.compile(atom.clone())?); }
|
||||
}
|
||||
|
|
|
@ -180,8 +180,8 @@ impl FromStr for Register {
|
|||
#[derive(Clone, Debug)]
|
||||
pub enum Instr {
|
||||
Label { name: String }, Comment { text: String },
|
||||
// Store a literal value into a register.
|
||||
Store { name: String },
|
||||
// Variable declaration
|
||||
Load { name: String }, Store { name: String },
|
||||
// Call intrinsic function.
|
||||
Call,
|
||||
// Stack operations.
|
||||
|
@ -204,6 +204,7 @@ 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::Call => write!(f, " CALL"),
|
||||
Instr::Push { value } => write!(f, " PUSH {}", value),
|
||||
|
|
|
@ -16,6 +16,7 @@ pub fn parse_instr(src: &str) -> Vec<Instr> {
|
|||
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() }); },
|
||||
"CALL" => { result.push(Instr::Call); },
|
||||
"PUSH" => { result.push(Instr::Push { value: value!(tokens[1]) }); },
|
||||
|
|
|
@ -7,6 +7,7 @@ pub enum Error {
|
|||
StackOverflow,
|
||||
UnknownFunction(String),
|
||||
UnknownFunctionCall(isize, isize),
|
||||
UnknownVariable(String),
|
||||
InvalidAriphmeticOperation,
|
||||
}
|
||||
|
||||
|
@ -17,6 +18,7 @@ impl Display for Error {
|
|||
Error::StackOverflow => write!(f, "Stack overflow"),
|
||||
Error::UnknownFunction(name) => write!(f, "Unknown function: {}", name),
|
||||
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"),
|
||||
}
|
||||
}
|
||||
|
@ -71,6 +73,10 @@ impl VM {
|
|||
let instr = &instrs[(self.instr_pointer - 1) as usize];
|
||||
if debug { print_debug(self, &instr); }
|
||||
match instr {
|
||||
Load { name } => {
|
||||
self.load(name)?;
|
||||
continue 'tco;
|
||||
}
|
||||
Store { name } => {
|
||||
let value = &self.stack.pop().unwrap();
|
||||
self.store(name, value)?;
|
||||
|
@ -162,6 +168,14 @@ impl VM {
|
|||
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> {
|
||||
for (idx, (n, _)) in self.function_pointer.iter().enumerate() {
|
||||
if n == &name {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
(fun str "Hello, world!")
|
||||
|
||||
(fun main
|
||||
(print str))
|
||||
(print (str)))
|
|
@ -1,2 +1,3 @@
|
|||
(fun main
|
||||
(def name "bobby"))
|
||||
(do (def name "Bobby")
|
||||
(print name)))
|
Loading…
Reference in a new issue