diff --git a/src/vm/inst.rs b/src/vm/inst.rs index 72d621b..275d384 100644 --- a/src/vm/inst.rs +++ b/src/vm/inst.rs @@ -26,15 +26,16 @@ instructions! { SUB = 0x0001, MUL = 0x0002, DIV = 0x0003, - MOD = 0x0004, - AND = 0x0005, - OR = 0x0006, - XOR = 0x0007, - SHL = 0x0008, - SHR = 0x0009, - INEG = 0x000a, - INV = 0x000b, - NOT = 0x000c, + IDIV = 0x0004, + MOD = 0x0005, + AND = 0x0006, + OR = 0x0007, + XOR = 0x0008, + SHL = 0x0009, + SHR = 0x000a, + INEG = 0x000b, + INV = 0x000c, + NOT = 0x000d, CMPEQ = 0x1000, CMPLT = 0x1001, JMP = 0x1002, @@ -52,6 +53,7 @@ pub enum Inst { Sub(Dest, Source), Mul(Dest, Source), Div(Dest, Source), + IDiv(Dest, Source), Mod(Dest, Source), And(Dest, Source), Or(Dest, Source), @@ -79,6 +81,7 @@ impl Inst { Inst::Sub(_, _) => SUB, Inst::Mul(_, _) => MUL, Inst::Div(_, _) => DIV, + Inst::IDiv(_, _) => IDIV, Inst::Mod(_, _) => MOD, Inst::And(_, _) => AND, Inst::Or(_, _) => OR, @@ -106,6 +109,7 @@ impl Inst { | Inst::Sub(dest, source) | Inst::Mul(dest, source) | Inst::Div(dest, source) + | Inst::IDiv(dest, source) | Inst::Mod(dest, source) | Inst::And(dest, source) | Inst::Or(dest, source) diff --git a/src/vm/mem.rs b/src/vm/mem.rs index 8224e3c..8d84ea7 100644 --- a/src/vm/mem.rs +++ b/src/vm/mem.rs @@ -95,6 +95,7 @@ impl MemCursor SUB => dest_source!(Sub), MUL => dest_source!(Mul), DIV => dest_source!(Div), + IDIV => dest_source!(IDiv), MOD => dest_source!(Mod), AND => dest_source!(And), OR => dest_source!(Or), diff --git a/src/vm/obj/assemble.rs b/src/vm/obj/assemble.rs index 19bc71e..cc22ebe 100644 --- a/src/vm/obj/assemble.rs +++ b/src/vm/obj/assemble.rs @@ -284,6 +284,7 @@ impl Assemble for Inst { Inst::Sub(v1, v2) => map_inst!(inst::SUB, v1, v2), Inst::Mul(v1, v2) => map_inst!(inst::MUL, v1, v2), Inst::Div(v1, v2) => map_inst!(inst::DIV, v1, v2), + Inst::IDiv(v1, v2) => map_inst!(inst::IDIV, v1, v2), Inst::Mod(v1, v2) => map_inst!(inst::MOD, v1, v2), Inst::And(v1, v2) => map_inst!(inst::AND, v1, v2), Inst::Or(v1, v2) => map_inst!(inst::OR, v1, v2), diff --git a/src/vm/obj/syn/ast.rs b/src/vm/obj/syn/ast.rs index d2c408d..e222235 100644 --- a/src/vm/obj/syn/ast.rs +++ b/src/vm/obj/syn/ast.rs @@ -182,6 +182,7 @@ pub enum Inst { Sub(Value, Value), Mul(Value, Value), Div(Value, Value), + IDiv(Value, Value), Mod(Value, Value), And(Value, Value), Or(Value, Value), @@ -209,6 +210,7 @@ impl Inst { | Inst::Sub(v1, v2) | Inst::Mul(v1, v2) | Inst::Div(v1, v2) + | Inst::IDiv(v1, v2) | Inst::Mod(v1, v2) | Inst::And(v1, v2) | Inst::Or(v1, v2) diff --git a/src/vm/obj/syn/lexer.l b/src/vm/obj/syn/lexer.l index 8a3923f..7bd52ff 100644 --- a/src/vm/obj/syn/lexer.l +++ b/src/vm/obj/syn/lexer.l @@ -25,6 +25,7 @@ add "ADD" sub "SUB" mul "MUL" div "DIV" +idiv "IDIV" mod "MOD" and "AND" or "OR" diff --git a/src/vm/obj/syn/parser.y b/src/vm/obj/syn/parser.y index 29323f1..6f2ced3 100644 --- a/src/vm/obj/syn/parser.y +++ b/src/vm/obj/syn/parser.y @@ -62,13 +62,22 @@ Value -> Value: | 'LPAREN' Value 'RPAREN' 'U16' { Value::Addr(Box::new($2), IntSize::U16) } | 'LPAREN' Value 'RPAREN' 'U32' { Value::Addr(Box::new($2), IntSize::U32) } | 'LPAREN' Value 'RPAREN' 'U64' { Value::Addr(Box::new($2), IntSize::U64) } + //| 'LBRACKET' ArrayValues 'RBRACKET' { Value::Array($2) } ; +/* +ArrayValues -> Vec: + ArrayValues Value { $1.push($2); $1 } + | { Vec::new() } + ; +*/ + Inst -> Inst: 'ADD' Value 'COMMA' Value { Inst::Add($2, $4) } | 'SUB' Value 'COMMA' Value { Inst::Sub($2, $4) } | 'MUL' Value 'COMMA' Value { Inst::Mul($2, $4) } | 'DIV' Value 'COMMA' Value { Inst::Div($2, $4) } + | 'IDIV' Value 'COMMA' Value { Inst::IDiv($2, $4) } | 'MOD' Value 'COMMA' Value { Inst::Mod($2, $4) } | 'AND' Value 'COMMA' Value { Inst::And($2, $4) } | 'OR' Value 'COMMA' Value { Inst::Or($2, $4) } diff --git a/src/vm/state.rs b/src/vm/state.rs index be1b820..e2ab226 100644 --- a/src/vm/state.rs +++ b/src/vm/state.rs @@ -155,6 +155,13 @@ impl State { let value = self.load_dest(d)?.wrapping_div(self.load_source(s)?); self.store_dest(d, value)?; } + Inst::IDiv(d, s) => { + // TODO : catch divide by zero + let dest = self.load_dest(d)? as i64; + let source = self.load_source(s)? as i64; + let value = dest.wrapping_div(source); + self.store_dest(d, value as u64)?; + } Inst::Mod(d, s) => { let value = self.load_dest(d)? % self.load_source(s)?; self.store_dest(d, value)?;