diff --git a/blspc/src/compiler/compile.rs b/blspc/src/compiler/compile.rs index 12a255f..73f07fc 100644 --- a/blspc/src/compiler/compile.rs +++ b/blspc/src/compiler/compile.rs @@ -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)?); } diff --git a/blspc/src/vm/instr.rs b/blspc/src/vm/instr.rs index dff6341..3f9b6d0 100644 --- a/blspc/src/vm/instr.rs +++ b/blspc/src/vm/instr.rs @@ -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"), } } } \ No newline at end of file diff --git a/blspc/src/vm/parser.rs b/blspc/src/vm/parser.rs index cdab8c0..51a5dad 100644 --- a/blspc/src/vm/parser.rs +++ b/blspc/src/vm/parser.rs @@ -16,10 +16,7 @@ pub fn parse_instr(src: &str) -> Vec { 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]) }); }, diff --git a/blspc/src/vm/vm.rs b/blspc/src/vm/vm.rs index 1630f85..762cc0c 100644 --- a/blspc/src/vm/vm.rs +++ b/blspc/src/vm/vm.rs @@ -28,6 +28,7 @@ pub struct VM { jumped_from: isize, registers: Vec, stack: Vec, + 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 { for (idx, (n, _)) in self.function_pointer.iter().enumerate() { if n == &name { diff --git a/example/var.blsp b/example/var.blsp new file mode 100644 index 0000000..478851d --- /dev/null +++ b/example/var.blsp @@ -0,0 +1,2 @@ +(fun main + (def name "bobby")) \ No newline at end of file