From 337e611348882db2bf9cd0616169c2aebeb2d6ee Mon Sep 17 00:00:00 2001 From: ghostly_zsh Date: Thu, 8 Aug 2024 22:42:39 -0500 Subject: [PATCH] mul and div --- kabel/src/codegen.rs | 12 ++++++++++++ kabel/src/lib.rs | 2 +- kabel/src/vm.rs | 44 ++++++++++++++++++++++++++++++++++++++---- kabel_test/src/main.rs | 4 ++-- 4 files changed, 55 insertions(+), 7 deletions(-) diff --git a/kabel/src/codegen.rs b/kabel/src/codegen.rs index 18c9fe1826995562a3fd9d162180941cf1bc5c08..7882222b098a375f98373fbe81f580bd7a5892ca 100644 --- a/kabel/src/codegen.rs +++ b/kabel/src/codegen.rs @@ -57,6 +57,18 @@ impl Codegen { self.vm.chunk.push(OpCode::SUB.into()); self.vm.lines.last_mut().unwrap().1 += 1; } + Mul => { + self.visit(right); + self.visit(left); + self.vm.chunk.push(OpCode::MUL.into()); + self.vm.lines.last_mut().unwrap().1 += 1; + } + Div => { + self.visit(right); + self.visit(left); + self.vm.chunk.push(OpCode::DIV.into()); + self.vm.lines.last_mut().unwrap().1 += 1; + } _ => { panic!("not implemented") } } } diff --git a/kabel/src/lib.rs b/kabel/src/lib.rs index 9e84185dd5f4d236508ec52caa8c54b0088ee0fd..8e468ff92e9a310204e317f31a9ec230e3d4c07b 100644 --- a/kabel/src/lib.rs +++ b/kabel/src/lib.rs @@ -112,7 +112,7 @@ pub fn compile(program: String) -> String { #[cfg(feature = "timer")] let vm_instant = Instant::now(); let mut vm = codegen.vm; - match vm.run() { + match vm.run(&mut output) { Ok(()) => {} Err(e) => output += &e.to_string(), } diff --git a/kabel/src/vm.rs b/kabel/src/vm.rs index b57889ec279d26b9b192f000dfb97aa1bdf0f3ec..e6395a7d3136559bb17199fb06c3276071acdaca 100644 --- a/kabel/src/vm.rs +++ b/kabel/src/vm.rs @@ -20,7 +20,7 @@ impl VM { text: text.lines().map(|s| s.to_string()).collect(), } } - pub fn run(&mut self) -> Result<(), KabelRuntimeError> { + pub fn run(&mut self, output: &mut String) -> Result<(), KabelRuntimeError> { use Value::*; while self.ip < self.chunk.len() { match self.read() { @@ -56,14 +56,50 @@ impl VM { } } } + 0x03 => { // MUL + match (self.stack.pop().unwrap(), self.stack.pop().unwrap()) { + (Num(v1), Num(v2)) => self.stack.push(Num(v1 * v2)), + (Str(v1), Num(v2)) => { + if v2.fract() == 0.0 { + self.stack.push(Str(v1.repeat(v2 as usize))); + } else { + return Err(wrong_type!(self, "Number must be an integer")) + } + } + (Str(_v1), Str(_v2)) => { + return Err(wrong_type!(self, "Cannot multiply strings")) + }, + (Bool(_v1), Bool(_v2)) => { + return Err(wrong_type!(self, "Cannot multiply booleans")) + } + (v1, v2) => { + return Err(mismatched_types!(self, "Mismatched types: {} and {}", v1.type_str(), v2.type_str())) + } + } + } + 0x04 => { // DIV + match (self.stack.pop().unwrap(), self.stack.pop().unwrap()) { + (Num(v1), Num(v2)) => self.stack.push(Num(v1 / v2)), + (Str(_v1), Str(_v2)) => { + return Err(wrong_type!(self, "Cannot divide strings")) + }, + (Bool(_v1), Bool(_v2)) => { + return Err(wrong_type!(self, "Cannot divide booleans")) + } + (v1, v2) => { + return Err(mismatched_types!(self, "Mismatched types: {} and {}", v1.type_str(), v2.type_str())) + } + } + } 0xFE => { // PRINT let value = self.stack.pop().unwrap(); match value { - Num(v) => println!("{}", v), - Str(v) => println!("{}", v.to_string()), - Bool(v) => println!("{}", v), + Num(v) => *output += &v.to_string(), + Str(v) => *output += &v, + Bool(v) => *output += &v.to_string(), } + *output += "\n"; } _ => {} } diff --git a/kabel_test/src/main.rs b/kabel_test/src/main.rs index 805790acaf30ba2d01b5c85fb41022efcfe1727a..6af09de45c9508765aae3000f3ba12c200fe4809 100644 --- a/kabel_test/src/main.rs +++ b/kabel_test/src/main.rs @@ -9,7 +9,7 @@ fn main() { let program = fs::read_to_string(args[1].clone()).unwrap();*/ - let program = "print \"hello, \" + \"world\";".to_string(); + let program = "print 4 / 5;".to_string(); let mut output = "".to_string(); @@ -47,7 +47,7 @@ fn main() { let codegen = run_codegen(program, ast); let mut vm = codegen.vm; - match vm.run() { + match vm.run(&mut output) { Ok(()) => {} Err(e) => output += &e.to_string(), }