~starkingdoms/starkingdoms

337e611348882db2bf9cd0616169c2aebeb2d6ee — ghostly_zsh 1 year, 4 months ago cd7053c
mul and div
4 files changed, 55 insertions(+), 7 deletions(-)

M kabel/src/codegen.rs
M kabel/src/lib.rs
M kabel/src/vm.rs
M kabel_test/src/main.rs
M kabel/src/codegen.rs => kabel/src/codegen.rs +12 -0
@@ 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") }
        }
    }

M kabel/src/lib.rs => kabel/src/lib.rs +1 -1
@@ 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(),
    }

M kabel/src/vm.rs => kabel/src/vm.rs +40 -4
@@ 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";
                }
                _ => {}
            }

M kabel_test/src/main.rs => kabel_test/src/main.rs +2 -2
@@ 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(),
    }