From 6424d4fc9fade84cad065eb775f998c34a83da16 Mon Sep 17 00:00:00 2001 From: azur <73991665+azur1s@users.noreply.github.com> Date: Fri, 4 Feb 2022 09:12:14 +0700 Subject: [PATCH] feat: variable calling --- blspc/src/compiler/compile.rs | 9 +++++---- blspc/src/vm/instr.rs | 5 +++-- blspc/src/vm/parser.rs | 1 + blspc/src/vm/vm.rs | 14 ++++++++++++++ example/hello.blsp | 2 +- example/var.blsp | 3 ++- 6 files changed, 26 insertions(+), 8 deletions(-) diff --git a/blspc/src/compiler/compile.rs b/blspc/src/compiler/compile.rs index 73f07fc..fa7068e 100644 --- a/blspc/src/compiler/compile.rs +++ b/blspc/src/compiler/compile.rs @@ -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, 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())?); } } diff --git a/blspc/src/vm/instr.rs b/blspc/src/vm/instr.rs index 3f9b6d0..08a5755 100644 --- a/blspc/src/vm/instr.rs +++ b/blspc/src/vm/instr.rs @@ -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), diff --git a/blspc/src/vm/parser.rs b/blspc/src/vm/parser.rs index 51a5dad..4037ebe 100644 --- a/blspc/src/vm/parser.rs +++ b/blspc/src/vm/parser.rs @@ -16,6 +16,7 @@ pub fn parse_instr(src: &str) -> Vec { 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]) }); }, diff --git a/blspc/src/vm/vm.rs b/blspc/src/vm/vm.rs index 762cc0c..d850fe8 100644 --- a/blspc/src/vm/vm.rs +++ b/blspc/src/vm/vm.rs @@ -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 { for (idx, (n, _)) in self.function_pointer.iter().enumerate() { if n == &name { diff --git a/example/hello.blsp b/example/hello.blsp index 800e785..6f02d2e 100644 --- a/example/hello.blsp +++ b/example/hello.blsp @@ -1,4 +1,4 @@ (fun str "Hello, world!") (fun main - (print str)) \ No newline at end of file + (print (str))) \ No newline at end of file diff --git a/example/var.blsp b/example/var.blsp index 478851d..fdf9e43 100644 --- a/example/var.blsp +++ b/example/var.blsp @@ -1,2 +1,3 @@ (fun main - (def name "bobby")) \ No newline at end of file + (do (def name "Bobby") + (print name))) \ No newline at end of file