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:
parent
b168d29648
commit
c8a79e87ef
|
@ -60,7 +60,17 @@ impl Compiler {
|
|||
result.append(&mut then);
|
||||
result.push(Instr::Jump { to: len(&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)?);
|
||||
}
|
||||
|
|
|
@ -181,7 +181,7 @@ impl FromStr for Register {
|
|||
pub enum Instr {
|
||||
Label { name: String }, Comment { text: String },
|
||||
// Store a literal value into a register.
|
||||
Store { address: Register, value: Type },
|
||||
Store { name: String },
|
||||
// Call intrinsic function.
|
||||
Call,
|
||||
// Stack operations.
|
||||
|
@ -200,23 +200,23 @@ pub enum Instr {
|
|||
impl Display for Instr {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
match self {
|
||||
// --4-- Padding
|
||||
// ----------20--------- Parameter start
|
||||
Instr::Label { name } => write!(f, ".{}:", name),
|
||||
Instr::Comment { text } => write!(f, ";{}", text),
|
||||
Instr::Store { address, value } => write!(f, " STORE {} {}", address, value),
|
||||
Instr::Call => write!(f, " CALL"),
|
||||
Instr::Push { value } => write!(f, " PUSH {}", value),
|
||||
Instr::Pop { address } => write!(f, " POP {}", address),
|
||||
Instr::Swap => write!(f, " SWAP"),
|
||||
Instr::Add => write!(f, " ADD"),
|
||||
Instr::Sub => write!(f, " SUB"),
|
||||
Instr::Mul => write!(f, " MUL"),
|
||||
Instr::Div => write!(f, " DIV"),
|
||||
Instr::JumpLabel { to } => write!(f, " JMPL {}", to),
|
||||
Instr::Jump { to } => write!(f, " JMP {}", to),
|
||||
Instr::JumpIfFalse { to } => write!(f, " JMPF {}", to),
|
||||
Instr::Return => write!(f, " RET"),
|
||||
// --4-- Padding
|
||||
// ----------20--------- Parameter start
|
||||
Instr::Label { name } => write!(f, ".{}:", name),
|
||||
Instr::Comment { text } => write!(f, ";{}", text),
|
||||
Instr::Store { name } => write!(f, " STORE {}", name),
|
||||
Instr::Call => write!(f, " CALL"),
|
||||
Instr::Push { value } => write!(f, " PUSH {}", value),
|
||||
Instr::Pop { address } => write!(f, " POP {}", address),
|
||||
Instr::Swap => write!(f, " SWAP"),
|
||||
Instr::Add => write!(f, " ADD"),
|
||||
Instr::Sub => write!(f, " SUB"),
|
||||
Instr::Mul => write!(f, " MUL"),
|
||||
Instr::Div => write!(f, " DIV"),
|
||||
Instr::JumpLabel { to } => write!(f, " JMPL {}", to),
|
||||
Instr::Jump { to } => write!(f, " JMP {}", to),
|
||||
Instr::JumpIfFalse { to } => write!(f, " JMPF {}", to),
|
||||
Instr::Return => write!(f, " RET"),
|
||||
}
|
||||
}
|
||||
}
|
|
@ -16,10 +16,7 @@ pub fn parse_instr(src: &str) -> Vec<Instr> {
|
|||
if tokens[0].starts_with(";") { continue; }
|
||||
|
||||
match tokens[0] {
|
||||
"STORE" => { result.push(Instr::Store {
|
||||
address: register!(tokens[1]),
|
||||
value: value!(tokens[2]),
|
||||
}); },
|
||||
"STORE" => { result.push(Instr::Store { name: tokens[1].to_string() }); },
|
||||
"CALL" => { result.push(Instr::Call); },
|
||||
"PUSH" => { result.push(Instr::Push { value: value!(tokens[1]) }); },
|
||||
"POP" => { result.push(Instr::Pop { address: register!(tokens[1]) }); },
|
||||
|
|
|
@ -28,6 +28,7 @@ pub struct VM {
|
|||
jumped_from: isize,
|
||||
registers: Vec<Type>,
|
||||
stack: Vec<Type>,
|
||||
variables: Vec<(String, Type)>,
|
||||
function_pointer: Vec<(String, isize)>, // (name, index)
|
||||
}
|
||||
|
||||
|
@ -40,6 +41,7 @@ impl VM {
|
|||
jumped_from: 0,
|
||||
registers: vec![Type::Null; 1024],
|
||||
stack: Vec::new(),
|
||||
variables: Vec::new(),
|
||||
function_pointer: Vec::new(),
|
||||
}
|
||||
}
|
||||
|
@ -69,8 +71,9 @@ impl VM {
|
|||
let instr = &instrs[(self.instr_pointer - 1) as usize];
|
||||
if debug { print_debug(self, &instr); }
|
||||
match instr {
|
||||
Store { address, value, .. } => {
|
||||
self.store(&address, &value)?;
|
||||
Store { name } => {
|
||||
let value = &self.stack.pop().unwrap();
|
||||
self.store(name, value)?;
|
||||
continue 'tco;
|
||||
},
|
||||
Call => {
|
||||
|
@ -85,7 +88,7 @@ impl VM {
|
|||
},
|
||||
Pop { address } => {
|
||||
let value = self.stack.pop();
|
||||
self.store(&address, &value.unwrap())?;
|
||||
self.pop(&address, &value.unwrap())?;
|
||||
continue 'tco;
|
||||
},
|
||||
Swap => {
|
||||
|
@ -150,11 +153,15 @@ impl VM {
|
|||
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()
|
||||
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> {
|
||||
for (idx, (n, _)) in self.function_pointer.iter().enumerate() {
|
||||
if n == &name {
|
||||
|
|
2
example/var.blsp
Normal file
2
example/var.blsp
Normal file
|
@ -0,0 +1,2 @@
|
|||
(fun main
|
||||
(def name "bobby"))
|
Loading…
Reference in a new issue