~starkingdoms/starkingdoms

f9039c39c19642c713556245576794ab028da0e7 — ghostly_zsh 1 year, 4 months ago 719300a
bitwise operations
5 files changed, 111 insertions(+), 37 deletions(-)

M kabel/src/codegen.rs
M kabel/src/macros.rs
M kabel/src/opcodes.rs
M kabel/src/vm.rs
M kabel_test/src/main.rs
M kabel/src/codegen.rs => kabel/src/codegen.rs +2 -2
@@ 48,8 48,8 @@ impl Codegen {
    pub fn visit_binary(&mut self, left: AST, oper: BinOp, right: AST) {
        use crate::parser::BinOp::*;
        codegen_binary!(self, left, right, oper, Add, ADD, Sub, SUB, Mul, MUL,
            Div, DIV, Mod, MOD, Eq, EQ, Ne, NE, Gr, GR, Ge, GE, Ls, LS,
            Le, LE, Or, OR, And, AND);
            Div, DIV, Mod, MOD, BitAnd, BITAND, BitXor, BITXOR, BitOr, BITOR,
            Eq, EQ, Ne, NE, Gr, GR, Ge, GE, Ls, LS, Le, LE, Or, OR, And, AND);
    }
    pub fn visit_unary(&mut self, oper: UnOp, right: AST) {
        use crate::parser::UnOp::*;

M kabel/src/macros.rs => kabel/src/macros.rs +2 -3
@@ 156,12 156,12 @@ macro_rules! mismatched_types {
}
#[macro_export]
macro_rules! wrong_type {
    ($self:expr, $message:expr) => {
    ($self:expr, $message:expr $(, $args:expr )*) => {
        {
            let line = $self.find_line();
            $crate::runtime_error::KabelRuntimeError::new(
                $crate::runtime_error::RuntimeErrorKind::WrongType,
                $message.to_string(),
                format!($message, $( $args ),*),
                line,
                $self.text[line].to_string(),
            )


@@ 186,7 186,6 @@ macro_rules! codegen_binary {
                $self.vm.chunk.push(OpCode::$code.into());
                $self.vm.lines.last_mut().unwrap().1 += 1;
            } )*
            _ => { panic!("not implemented") }
        }
    };
}

M kabel/src/opcodes.rs => kabel/src/opcodes.rs +30 -21
@@ 6,6 6,9 @@ pub enum OpCode {
    MUL,
    DIV,
    MOD,
    BITAND,
    BITXOR,
    BITOR,
    EQ,
    NE,
    GR,


@@ 32,17 35,20 @@ impl From<OpCode> for u8 {
            MUL => 0x03,
            DIV => 0x04,
            MOD => 0x05,
            EQ => 0x06,
            NE => 0x07,
            GR => 0x08,
            GE => 0x09,
            LS => 0x0A,
            LE => 0x0B,
            OR => 0x0C,
            AND => 0x0D,
            BITAND => 0x06,
            BITXOR => 0x07,
            BITOR => 0x08,
            EQ => 0x09,
            NE => 0x0A,
            GR => 0x0B,
            GE => 0x0C,
            LS => 0x0D,
            LE => 0x0E,
            OR => 0x0F,
            AND => 0x10,

            NOT => 0x0E,
            NEG => 0x0F,
            NOT => 0x11,
            NEG => 0x12,
            PRINT => 0xFE,
            ERR => 0xFF
        }


@@ 59,18 65,21 @@ impl From<u8> for OpCode {
            0x03 => MUL,
            0x04 => DIV,
            0x05 => MOD,
            0x06 => EQ,
            0x07 => NE,
            0x08 => GR,
            0x09 => GE,
            0x0A => LS,
            0x0B => LE,
            0x0C => OR,
            0x0D => AND,
            0x06 => BITAND,
            0x07 => BITXOR,
            0x08 => BITOR,
            0x09 => EQ,
            0x0A => NE,
            0x0B => GR,
            0x0C => GE,
            0x0D => LS,
            0x0E => LE,
            0x0F => OR,
            0x10 => AND,

            0x0E => NOT,
            0x0F => NEG,
            0xFE => PRINT,
            0x11 => NOT,
            0x12 => NEG,
            0x13 => PRINT,
            _ => ERR
        }
    }

M kabel/src/vm.rs => kabel/src/vm.rs +76 -10
@@ 105,20 105,86 @@ impl VM {
                        }
                    }
                }
                0x06 => { // BITAND
                    match (self.stack.pop().unwrap(), self.stack.pop().unwrap()) {
                        (Num(v1), Num(v2)) => {
                            if v1.fract() != 0.0 {
                                return Err(wrong_type!(self, "Cannot perform bitwise AND on {}", v1))
                            }
                            if v2.fract() != 0.0 {
                                return Err(wrong_type!(self, "Cannot perform bitwise AND on {}", v2))
                            }
                            self.stack.push(Num((v1 as u32 & v2 as u32) as f32))
                        }
                        (Str(_v1), Str(_v2)) => {
                            return Err(wrong_type!(self, "Cannot perform bitwise AND on strings"))
                        },
                        (Bool(_v1), Bool(_v2)) => {
                            return Err(wrong_type!(self, "Cannot perform bitwise AND on booleans"))
                        }
                        (v1, v2) => {
                            return Err(mismatched_types!(self, "Mismatched types: {} and {}", v1.type_str(), v2.type_str()))
                        }
                    }
                }
                0x07 => { // BITXOR
                    match (self.stack.pop().unwrap(), self.stack.pop().unwrap()) {
                        (Num(v1), Num(v2)) => {
                            if v1.fract() != 0.0 {
                                return Err(wrong_type!(self, "Cannot perform bitwise XOR on {}", v1))
                            }
                            if v2.fract() != 0.0 {
                                return Err(wrong_type!(self, "Cannot perform bitwise XOR on {}", v2))
                            }
                            self.stack.push(Num((v1 as u32 ^ v2 as u32) as f32))
                        }
                        (Str(_v1), Str(_v2)) => {
                            return Err(wrong_type!(self, "Cannot perform bitwise XOR on strings"))
                        },
                        (Bool(_v1), Bool(_v2)) => {
                            return Err(wrong_type!(self, "Cannot perform bitwise XOR on booleans"))
                        }
                        (v1, v2) => {
                            return Err(mismatched_types!(self, "Mismatched types: {} and {}", v1.type_str(), v2.type_str()))
                        }
                    }
                }
                0x08 => { // BITOR
                    match (self.stack.pop().unwrap(), self.stack.pop().unwrap()) {
                        (Num(v1), Num(v2)) => {
                            if v1.fract() != 0.0 {
                                return Err(wrong_type!(self, "Cannot perform bitwise OR on {}", v1))
                            }
                            if v2.fract() != 0.0 {
                                return Err(wrong_type!(self, "Cannot perform bitwise OR on {}", v2))
                            }
                            self.stack.push(Num((v1 as u32 | v2 as u32) as f32))
                        }
                        (Str(_v1), Str(_v2)) => {
                            return Err(wrong_type!(self, "Cannot perform bitwise OR on strings"))
                        },
                        (Bool(_v1), Bool(_v2)) => {
                            return Err(wrong_type!(self, "Cannot perform bitwise OR on booleans"))
                        }
                        (v1, v2) => {
                            return Err(mismatched_types!(self, "Mismatched types: {} and {}", v1.type_str(), v2.type_str()))
                        }
                    }
                }
                // EQ
                0x06 => vm_boolean_binary!(self, ==),
                0x09 => vm_boolean_binary!(self, ==),
                // NE
                0x07 => vm_boolean_binary!(self, !=),
                0x0A => vm_boolean_binary!(self, !=),
                // GR
                0x08 => vm_boolean_binary!(self, >),
                0x0B => vm_boolean_binary!(self, >),
                // GE
                0x09 => vm_boolean_binary!(self, >=),
                0x0C => vm_boolean_binary!(self, >=),
                // LS
                0x0A => vm_boolean_binary!(self, <),
                0x0D => vm_boolean_binary!(self, <),
                // LE
                0x0B => vm_boolean_binary!(self, <=),
                0x0E => vm_boolean_binary!(self, <=),
                // OR
                0x0C => match (self.stack.pop().unwrap(), self.stack.pop().unwrap()) {
                0x0F => match (self.stack.pop().unwrap(), self.stack.pop().unwrap()) {
                    (Num(_v1), Num(_v2)) => {
                        return Err(wrong_type!(self, "Cannot perform logical OR on numbers"))
                    }


@@ 131,7 197,7 @@ impl VM {
                    }
                }
                // AND
                0x0D => match (self.stack.pop().unwrap(), self.stack.pop().unwrap()) {
                0x10 => match (self.stack.pop().unwrap(), self.stack.pop().unwrap()) {
                    (Num(_v1), Num(_v2)) => {
                        return Err(wrong_type!(self, "Cannot perform logical AND on numbers"))
                    }


@@ 144,7 210,7 @@ impl VM {
                    }
                }
                // NOT
                0x0E => match self.stack.pop().unwrap() {
                0x11 => match self.stack.pop().unwrap() {
                    Num(_v1) => {
                        return Err(wrong_type!(self, "Cannot perform logical NOT on numbers"))
                    }


@@ 154,7 220,7 @@ impl VM {
                    Bool(v1) => self.stack.push(Bool(!v1)),
                }
                // NEG
                0x0F => match self.stack.pop().unwrap() {
                0x12 => match self.stack.pop().unwrap() {
                    Num(v1) => self.stack.push(Num(-v1)),
                    Str(_v1) => {
                        return Err(wrong_type!(self, "Cannot negate strings"))

M kabel_test/src/main.rs => kabel_test/src/main.rs +1 -1
@@ 9,7 9,7 @@ fn main() {
    let program =
        fs::read_to_string(args[1].clone()).unwrap();*/

    let program = "print !(false == true || 4 > 5);".to_string();
    let program = "print 4|5;".to_string();

    let mut output = "".to_string();