diff --git a/VaninVM/Main.c b/VaninVM/Main.c index 1aaf41e..0ef1a76 100644 --- a/VaninVM/Main.c +++ b/VaninVM/Main.c @@ -6,7 +6,7 @@ int main(int argc, char** argv) { double d1, d2; - int i1, i2; + long long i1, i2; char* code; int ip; @@ -22,6 +22,19 @@ int main(int argc, char** argv) { switch (code[ip]) { + case INVALID: + //DO(INVALID, "Invalid instruction.", 1) + ip++; break; + case DLOAD: + //DO(DLOAD, "Load double on TOS, inlined into insn stream.", 9) + d1 = *((double*)(code+(++ip))); + push_double(d1); + ip+=8; break; + case ILOAD: + //DO(ILOAD, "Load int on TOS, inlined into insn stream.", 9) + i1 = *((long long*)(code+(++ip))); + push_int(i1); + ip++; break; case DLOAD0: // DO(DLOAD0, "Load double 0 on TOS.", 1) push_double(0); @@ -145,6 +158,29 @@ int main(int argc, char** argv) push_double(d1); printf("%f", d1); ip++; break; + case I2D: + //DO(I2D, "Convert int on TOS to double.", 1) + i1 = pop_int(); + d1 = (double)i1; + push_double(d1); + ip++; break; + case D2I: + //DO(D2I, "Convert double on TOS to int.", 1) + d1 = pop_double(); + i1 = (int)d1; + push_int(i1); + ip++; break; + case SWAP: + //DO(SWAP, "Swap 2 topmost values.", 1) + i1 = pop_int(); + i2 = pop_int(); + push_int(i1); + push_int(i2); + ip++; break; + case POP: + //DO(POP, "Remove topmost value.", 1) + TOS--; + ip++; break; case STOP: //DO(STOP, "Stop execution.", 1) exec_status = 0; diff --git a/VaninVM/OpCode.h b/VaninVM/OpCode.h index 1654e82..49eca60 100644 --- a/VaninVM/OpCode.h +++ b/VaninVM/OpCode.h @@ -2,6 +2,9 @@ #define OPCODE_H enum opcode { + INVALID, + DLOAD, + ILOAD, DLOAD0, ILOAD0, DLOAD1, @@ -24,6 +27,10 @@ enum opcode IAXOR, IPRINT, DPRINT, + I2D, + D2I, + SWAP, + POP, STOP }; #endif \ No newline at end of file diff --git a/VaninVM/TOS.c b/VaninVM/TOS.c index 27f4ab5..25f398b 100644 --- a/VaninVM/TOS.c +++ b/VaninVM/TOS.c @@ -1,18 +1,18 @@ #include #include "TOS.h" -void push_int(int num) +void push_int(long long num) { tos_num number; - number.num_i[1] = num; + number.num_i = num; TOS[tp++] = number.num_d; } -int pop_int() +long long pop_int() { tos_num number; number.num_d = TOS[--tp]; - return number.num_i[1]; + return number.num_i; } void push_double(double num) diff --git a/VaninVM/TOS.h b/VaninVM/TOS.h index b95f1a2..68a909c 100644 --- a/VaninVM/TOS.h +++ b/VaninVM/TOS.h @@ -4,15 +4,15 @@ typedef union { double num_d; - int num_i[2]; + long long num_i; } tos_num; double* TOS; int tp; int initTOS(); -void push_int(int); +void push_int(long long); void push_double(double); -int pop_int(); +long long pop_int(); double pop_double(); #endif \ No newline at end of file diff --git a/VaninVM/opc.txt b/VaninVM/opc.txt index 3980373..51b882b 100644 --- a/VaninVM/opc.txt +++ b/VaninVM/opc.txt @@ -1,7 +1,7 @@ #define FOR_BYTECODES(DO) \ - DO(INVALID, "Invalid instruction.", 1) \ - DO(DLOAD, "Load double on TOS, inlined into insn stream.", 9) \ - DO(ILOAD, "Load int on TOS, inlined into insn stream.", 9) \ + -DO(INVALID, "Invalid instruction.", 1) \ + +DO(DLOAD, "Load double on TOS, inlined into insn stream.", 9) \ + +DO(ILOAD, "Load int on TOS, inlined into insn stream.", 9) \ DO(SLOAD, "Load string reference on TOS, next two bytes - constant id.", 3) \ +DO(DLOAD0, "Load double 0 on TOS.", 1) \ +DO(ILOAD0, "Load int 0 on TOS.", 1) \ @@ -22,16 +22,16 @@ +DO(DNEG, "Negate double on TOS.", 1) \ +DO(INEG, "Negate int on TOS.", 1) \ +DO(IAOR, "Arithmetic OR of 2 ints on TOS, push value back.", 1) \ - DO(IAAND, "Arithmetic AND of 2 ints on TOS, push value back.", 1) \ - DO(IAXOR, "Arithmetic XOR of 2 ints on TOS, push value back.", 1) \ + +DO(IAAND, "Arithmetic AND of 2 ints on TOS, push value back.", 1) \ + +DO(IAXOR, "Arithmetic XOR of 2 ints on TOS, push value back.", 1) \ +DO(IPRINT, "Pop and print integer TOS.", 1) \ +DO(DPRINT, "Pop and print double TOS.", 1) \ DO(SPRINT, "Pop and print string TOS.", 1) \ - DO(I2D, "Convert int on TOS to double.", 1) \ - DO(D2I, "Convert double on TOS to int.", 1) \ + +DO(I2D, "Convert int on TOS to double.", 1) \ + +DO(D2I, "Convert double on TOS to int.", 1) \ DO(S2I, "Convert string on TOS to int.", 1) \ - DO(SWAP, "Swap 2 topmost values.", 1) \ - DO(POP, "Remove topmost value.", 1) \ + +DO(SWAP, "Swap 2 topmost values.", 1) \ + +DO(POP, "Remove topmost value.", 1) \ DO(LOADDVAR0, "Load double from variable 0, push on TOS.", 1) \ DO(LOADDVAR1, "Load double from variable 1, push on TOS.", 1) \ DO(LOADDVAR2, "Load double from variable 2, push on TOS.", 1) \ @@ -68,7 +68,7 @@ DO(STORECTXDVAR, "Pop TOS and store to double variable, whose 2-byte context and 2-byte id is inlined to insn stream.", 5) \ DO(STORECTXIVAR, "Pop TOS and store to int variable, whose 2-byte context and 2-byte id is inlined to insn stream.", 5) \ DO(STORECTXSVAR, "Pop TOS and store to string variable, whose 2-byte context and 2-byte id is inlined to insn stream.", 5) \ - DO(DCMP, "Compare 2 topmost doubles, pushing libc-stryle comparator value cmp(upper, lower) as integer.", 1) \ + DO(DCMP, "Compare 2 topmost doubles, pushing libc-style comparator value cmp(upper, lower) as integer.", 1) \ DO(ICMP, "Compare 2 topmost ints, pushing libc-style comparator value cmp(upper, lower) as integer.", 1) \ DO(JA, "Jump always, next two bytes - signed offset of jump destination.", 3) \ DO(IFICMPNE, "Compare two topmost integers and jump if upper != lower, next two bytes - signed offset of jump destination.", 3) \