~starkingdoms/starkingdoms

719300aa0298afb2f83fd1532d3bfcaaa5f09a72 — ghostly_zsh 1 year, 4 months ago 11293ac
run unary expressions
5 files changed, 54 insertions(+), 3 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 +8 -1
@@ 1,4 1,4 @@
use crate::{codegen_binary, opcodes::OpCode, parser::{BinOp, Lit, AST}, vm::{Value, VM}};
use crate::{codegen_binary, codegen_unary, opcodes::OpCode, parser::{BinOp, Lit, UnOp, AST}, vm::{Value, VM}};

pub struct Codegen {
    pub vm: VM


@@ 26,6 26,9 @@ impl Codegen {
            Binary(left, oper, right) => {
                self.visit_binary(*left, oper, *right);
            }
            Unary(oper, right) => {
                self.visit_unary(oper, *right);
            }
            Lit(ref lit) => {
                self.visit_lit(&ast, lit.clone());
            }


@@ 48,6 51,10 @@ impl Codegen {
            Div, DIV, Mod, MOD, 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::*;
        codegen_unary!(self, right, oper, Not, NOT, Neg, NEG);
    }
    pub fn visit_lit(&mut self, ast: &AST, lit: Lit) {
        match lit {
            Lit::Num(value) => {

M kabel/src/macros.rs => kabel/src/macros.rs +12 -0
@@ 190,6 190,18 @@ macro_rules! codegen_binary {
        }
    };
}
#[macro_export]
macro_rules! codegen_unary {
    ($self:expr, $right:expr, $match_to:expr, $( $oper:tt, $code:tt ),*) => {
        match $match_to {
            $( $oper => {
                $self.visit($right);
                $self.vm.chunk.push(OpCode::$code.into());
                $self.vm.lines.last_mut().unwrap().1 += 1;
            } )*
        }
    };
}

#[macro_export]
macro_rules! vm_boolean_binary {

M kabel/src/opcodes.rs => kabel/src/opcodes.rs +12 -0
@@ 1,5 1,6 @@
pub enum OpCode {
    CONSTANT,

    ADD,
    SUB,
    MUL,


@@ 13,6 14,9 @@ pub enum OpCode {
    LE,
    OR,
    AND,

    NOT,
    NEG,
    PRINT,
    ERR,
}


@@ 22,6 26,7 @@ impl From<OpCode> for u8 {
        use OpCode::*;
        match value {
            CONSTANT => 0x00,

            ADD => 0x01,
            SUB => 0x02,
            MUL => 0x03,


@@ 35,6 40,9 @@ impl From<OpCode> for u8 {
            LE => 0x0B,
            OR => 0x0C,
            AND => 0x0D,

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


@@ 45,6 53,7 @@ impl From<u8> for OpCode {
        use OpCode::*;
        match value {
            0x00 => CONSTANT,

            0x01 => ADD,
            0x02 => SUB,
            0x03 => MUL,


@@ 58,6 67,9 @@ impl From<u8> for OpCode {
            0x0B => LE,
            0x0C => OR,
            0x0D => AND,

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

M kabel/src/vm.rs => kabel/src/vm.rs +20 -0
@@ 143,6 143,26 @@ impl VM {
                        return Err(mismatched_types!(self, "Mismatched types: {} and {}", v1.type_str(), v2.type_str()))
                    }
                }
                // NOT
                0x0E => match self.stack.pop().unwrap() {
                    Num(_v1) => {
                        return Err(wrong_type!(self, "Cannot perform logical NOT on numbers"))
                    }
                    Str(_v1) => {
                        return Err(wrong_type!(self, "Cannot perform logical NOT on strings"))
                    }
                    Bool(v1) => self.stack.push(Bool(!v1)),
                }
                // NEG
                0x0F => match self.stack.pop().unwrap() {
                    Num(v1) => self.stack.push(Num(-v1)),
                    Str(_v1) => {
                        return Err(wrong_type!(self, "Cannot negate strings"))
                    }
                    Bool(_v1) => {
                        return Err(wrong_type!(self, "Cannot negate bools"))
                    }
                }

                0xFE => { // PRINT
                    let value = self.stack.pop().unwrap();

M kabel_test/src/main.rs => kabel_test/src/main.rs +2 -2
@@ 2,14 2,14 @@

//use kabel::{debug::{debug_ast, debug_token_array}, run_lexer, run_parser, run_semantic_analysis};

use kabel::{run_codegen, run_lexer, run_parser, run_semantic_analysis, vm::{Value, VM}};
use kabel::{run_codegen, run_lexer, run_parser, run_semantic_analysis};

fn main() {
    /*let args: Vec<String> = env::args().collect();
    let program =
        fs::read_to_string(args[1].clone()).unwrap();*/

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

    let mut output = "".to_string();