Added support for modulo operator.
Added support for modulo operator.
1.1 --- a/jitcraft/BytecodeCompiler.cpp Tue Jul 17 23:10:54 2012 -0700
1.2 +++ b/jitcraft/BytecodeCompiler.cpp Wed Jul 18 21:46:29 2012 -0700
1.3 @@ -89,6 +89,8 @@
1.4 return OP_MUL;
1.5 case TOK_SLASH:
1.6 return OP_DIV;
1.7 + case TOK_PERCENT:
1.8 + return OP_MOD;
1.9 case TOK_SHR:
1.10 return OP_SHR;
1.11 case TOK_USHR:
2.1 --- a/jitcraft/Interpreter.cpp Tue Jul 17 23:10:54 2012 -0700
2.2 +++ b/jitcraft/Interpreter.cpp Wed Jul 18 21:46:29 2012 -0700
2.3 @@ -379,6 +379,17 @@
2.4 break;
2.5 }
2.6
2.7 +case OP_MOD:
2.8 +{
2.9 + if (top.sp[-1].i32 == 0) {
2.10 + zone->reportError(Message_IntegerDivideByZero);
2.11 + goto error;
2.12 + }
2.13 + top.sp[-2].i32 = top.sp[-2].i32 % top.sp[-1].i32;
2.14 + top.sp--;
2.15 + break;
2.16 +}
2.17 +
2.18 case OP_LT:
2.19 {
2.20 top.sp[-2].i32 = top.sp[-2].i32 < top.sp[-1].i32;
3.1 --- a/jitcraft/Opcodes.cpp Tue Jul 17 23:10:54 2012 -0700
3.2 +++ b/jitcraft/Opcodes.cpp Wed Jul 18 21:46:29 2012 -0700
3.3 @@ -203,6 +203,7 @@
3.4 case OP_NOT_F:
3.5 case OP_NEG:
3.6 case OP_NEG_F:
3.7 + case OP_MOD:
3.8 break;
3.9
3.10 case OP_STOP:
4.1 --- a/jitcraft/Opcodes.tbl Tue Jul 17 23:10:54 2012 -0700
4.2 +++ b/jitcraft/Opcodes.tbl Wed Jul 18 21:46:29 2012 -0700
4.3 @@ -77,50 +77,51 @@
4.4 OPDEF(OP_SUB, 23, "sub", 1, 2, 1)
4.5 OPDEF(OP_MUL, 24, "mul", 1, 2, 1)
4.6 OPDEF(OP_DIV, 25, "div", 1, 2, 1)
4.7 +OPDEF(OP_MOD, 26, "mod", 1, 2, 1)
4.8
4.9 -OPDEF(OP_LT, 26, "lt", 1, 2, 1)
4.10 -OPDEF(OP_LE, 27, "le", 1, 2, 1)
4.11 -OPDEF(OP_GE, 28, "ge", 1, 2, 1)
4.12 -OPDEF(OP_GT, 29, "gt", 1, 2, 1)
4.13 -OPDEF(OP_EQ, 30, "eq", 1, 2, 1)
4.14 -OPDEF(OP_NE, 31, "ne", 1, 2, 1)
4.15 +OPDEF(OP_LT, 27, "lt", 1, 2, 1)
4.16 +OPDEF(OP_LE, 28, "le", 1, 2, 1)
4.17 +OPDEF(OP_GE, 29, "ge", 1, 2, 1)
4.18 +OPDEF(OP_GT, 30, "gt", 1, 2, 1)
4.19 +OPDEF(OP_EQ, 31, "eq", 1, 2, 1)
4.20 +OPDEF(OP_NE, 32, "ne", 1, 2, 1)
4.21
4.22 -OPDEF(OP_NOT, 32, "not", 1, 1, 1)
4.23 -OPDEF(OP_NEG, 33, "neg", 1, 1, 1)
4.24 +OPDEF(OP_NOT, 33, "not", 1, 1, 1)
4.25 +OPDEF(OP_NEG, 34, "neg", 1, 1, 1)
4.26
4.27 -OPDEF(OP_POP, 34, "pop", 1, 1, 0)
4.28 +OPDEF(OP_POP, 35, "pop", 1, 1, 0)
4.29
4.30 // Unconditional terminator placed at the end of code. If a function returns
4.31 // void, this acts as a RETURNVOID. Otherwise, it must be unreachable.
4.32 -OPDEF(OP_STOP, 35, "stop", 1, 0, 0)
4.33 +OPDEF(OP_STOP, 36, "stop", 1, 0, 0)
4.34
4.35 // Call a function with N arguments. The target function must be the last item
4.36 // on the stack.
4.37 -OPDEF(OP_CALL, 36, "call", 1, -1, 1)
4.38 +OPDEF(OP_CALL, 37, "call", 1, -1, 1)
4.39
4.40 // Similar to GET/LOCAL, except for arguments.
4.41 -OPDEF(OP_GETARG, 37, "getarg", 5, 0, 1)
4.42 -OPDEF(OP_SETARG, 38, "setarg", 5, 1, 1)
4.43 +OPDEF(OP_GETARG, 38, "getarg", 5, 0, 1)
4.44 +OPDEF(OP_SETARG, 39, "setarg", 5, 1, 1)
4.45
4.46 // Reads or writes an integer element to an unsafe array.
4.47 // index = pop()
4.48 // ref = pop()
4.49 // ref[index]
4.50 //
4.51 -OPDEF(OP_GETARRAY_I, 39, "getarray.i", 1, 2, 1)
4.52 -OPDEF(OP_SETARRAY_I, 40, "setarray.i", 1, 3, 1)
4.53 -OPDEF(OP_GETARRAY_F, 41, "getarray.f", 1, 2, 1)
4.54 -OPDEF(OP_SETARRAY_F, 42, "setarray.f", 1, 3, 1)
4.55 -OPDEF(OP_GETARRAY_C, 43, "getarray.c", 1, 2, 1)
4.56 -OPDEF(OP_SETARRAY_C, 44, "setarray.c", 1, 3, 1)
4.57 -OPDEF(OP_GETARRAY_O, 45, "getarray.o", 1, 2, 1)
4.58 +OPDEF(OP_GETARRAY_I, 40, "getarray.i", 1, 2, 1)
4.59 +OPDEF(OP_SETARRAY_I, 41, "setarray.i", 1, 3, 1)
4.60 +OPDEF(OP_GETARRAY_F, 42, "getarray.f", 1, 2, 1)
4.61 +OPDEF(OP_SETARRAY_F, 43, "setarray.f", 1, 3, 1)
4.62 +OPDEF(OP_GETARRAY_C, 44, "getarray.c", 1, 2, 1)
4.63 +OPDEF(OP_SETARRAY_C, 45, "setarray.c", 1, 3, 1)
4.64 +OPDEF(OP_GETARRAY_O, 46, "getarray.o", 1, 2, 1)
4.65
4.66 // Allocate an array, info LIFO space if possible. The ArrayMap to use is
4.67 // specified as an index into the script's Map table.
4.68 //
4.69 // Format:
4.70 // [u8 op] [u32 index]
4.71 -OPDEF(OP_NEWARRAY_LIFO, 46, "newarray.lifo", 5, 0, 1)
4.72 +OPDEF(OP_NEWARRAY_LIFO, 47, "newarray.lifo", 5, 0, 1)
4.73
4.74 // Performs a bounds check on an unsafe array.
4.75 //
4.76 @@ -128,74 +129,75 @@
4.77 // array = pop()
4.78 // push(array)
4.79 // push(index)
4.80 -OPDEF(OP_BOUNDS, 47, "bounds", 1, 2, 2)
4.81 +OPDEF(OP_BOUNDS, 48, "bounds", 1, 2, 2)
4.82
4.83 // Pushes a 32-bit IEEE-754 floating point immediate onto the stack.
4.84 -OPDEF(OP_FLOAT, 48, "float", 5, 0, 1)
4.85 +OPDEF(OP_FLOAT, 49, "float", 5, 0, 1)
4.86
4.87 // Converts an integer to a 32-bit IEEE-754 floating point immediate.
4.88 -OPDEF(OP_CVT_I2F, 49, "cvt.i2f", 1, 1, 1)
4.89 +OPDEF(OP_CVT_I2F, 50, "cvt.i2f", 1, 1, 1)
4.90
4.91 // Stack transitions for these binary operators:
4.92 // rhs = pop()
4.93 // lhs = pop()
4.94 // push(lhs OP rhs)
4.95 -OPDEF(OP_ADD_F, 50, "add.f", 1, 2, 1)
4.96 -OPDEF(OP_SUB_F, 51, "sub.f", 1, 2, 1)
4.97 -OPDEF(OP_MUL_F, 52, "mul.f", 1, 2, 1)
4.98 -OPDEF(OP_DIV_F, 53, "div.f", 1, 2, 1)
4.99 +OPDEF(OP_ADD_F, 51, "add.f", 1, 2, 1)
4.100 +OPDEF(OP_SUB_F, 52, "sub.f", 1, 2, 1)
4.101 +OPDEF(OP_MUL_F, 53, "mul.f", 1, 2, 1)
4.102 +OPDEF(OP_DIV_F, 54, "div.f", 1, 2, 1)
4.103 +OPDEF(OP_UNUSED1, 55, "unused0", 1, 0, 0)
4.104
4.105 -OPDEF(OP_LT_F, 54, "lt.f", 1, 2, 1)
4.106 -OPDEF(OP_LE_F, 55, "le.f", 1, 2, 1)
4.107 -OPDEF(OP_GE_F, 56, "ge.f", 1, 2, 1)
4.108 -OPDEF(OP_GT_F, 57, "gt.f", 1, 2, 1)
4.109 -OPDEF(OP_EQ_F, 58, "eq.f", 1, 2, 1)
4.110 -OPDEF(OP_NE_F, 59, "ne.f", 1, 2, 1)
4.111 +OPDEF(OP_LT_F, 56, "lt.f", 1, 2, 1)
4.112 +OPDEF(OP_LE_F, 57, "le.f", 1, 2, 1)
4.113 +OPDEF(OP_GE_F, 58, "ge.f", 1, 2, 1)
4.114 +OPDEF(OP_GT_F, 59, "gt.f", 1, 2, 1)
4.115 +OPDEF(OP_EQ_F, 60, "eq.f", 1, 2, 1)
4.116 +OPDEF(OP_NE_F, 61, "ne.f", 1, 2, 1)
4.117
4.118 -OPDEF(OP_NOT_F, 60, "not.f", 1, 1, 1)
4.119 -OPDEF(OP_NEG_F, 61, "neg.f", 1, 1, 1)
4.120 +OPDEF(OP_NOT_F, 62, "not.f", 1, 1, 1)
4.121 +OPDEF(OP_NEG_F, 63, "neg.f", 1, 1, 1)
4.122
4.123 // Bitwise operators.
4.124 -OPDEF(OP_SHL, 62, "shl", 1, 2, 1)
4.125 -OPDEF(OP_SHR, 63, "shr", 1, 2, 1)
4.126 -OPDEF(OP_USHR, 64, "ushr", 1, 2, 1)
4.127 -OPDEF(OP_BITAND, 65, "bitand", 1, 2, 1)
4.128 -OPDEF(OP_BITOR, 66, "bitor", 1, 2, 1)
4.129 -OPDEF(OP_BITXOR, 67, "bitxor", 1, 2, 1)
4.130 -OPDEF(OP_BITNOT, 68, "bitnot", 1, 1, 1)
4.131 +OPDEF(OP_SHL, 64, "shl", 1, 2, 1)
4.132 +OPDEF(OP_SHR, 65, "shr", 1, 2, 1)
4.133 +OPDEF(OP_USHR, 66, "ushr", 1, 2, 1)
4.134 +OPDEF(OP_BITAND, 67, "bitand", 1, 2, 1)
4.135 +OPDEF(OP_BITOR, 68, "bitor", 1, 2, 1)
4.136 +OPDEF(OP_BITXOR, 69, "bitxor", 1, 2, 1)
4.137 +OPDEF(OP_BITNOT, 70, "bitnot", 1, 1, 1)
4.138
4.139 // Saves or restores the position of the LIFO heap to/from a local slot.
4.140 -OPDEF(OP_SAVELIFO, 69, "savelifo", 5, 0, 0)
4.141 -OPDEF(OP_UNWINDLIFO, 70, "unwindlifo", 5, 0, 0)
4.142 +OPDEF(OP_SAVELIFO, 71, "savelifo", 5, 0, 0)
4.143 +OPDEF(OP_UNWINDLIFO, 72, "unwindlifo", 5, 0, 0)
4.144
4.145 // Composes a variable reference to a stack slot or argument.
4.146 -OPDEF(OP_VARREF_LIFO, 71, "varref.lifo", 5, 0, 1)
4.147 -OPDEF(OP_ARGREF_LIFO, 72, "argref.lifo", 5, 0, 1)
4.148 -OPDEF(OP_SLOTREF_LIFO, 73, "slotref.lifo", 1, 1, 1)
4.149 -OPDEF(OP_ARRAYREF_LIFO, 74, "arrayref.lifo",1, 2, 1)
4.150 -OPDEF(OP_GETREF_I, 75, "getref.i", 1, 1, 1)
4.151 -OPDEF(OP_SETREF_I, 76, "setref.i", 1, 2, 1)
4.152 -OPDEF(OP_GETREF_F, 77, "getref.f", 1, 1, 1)
4.153 -OPDEF(OP_SETREF_F, 78, "setref.f", 1, 2, 1)
4.154 +OPDEF(OP_VARREF_LIFO, 73, "varref.lifo", 5, 0, 1)
4.155 +OPDEF(OP_ARGREF_LIFO, 74, "argref.lifo", 5, 0, 1)
4.156 +OPDEF(OP_SLOTREF_LIFO, 75, "slotref.lifo", 1, 1, 1)
4.157 +OPDEF(OP_ARRAYREF_LIFO, 76, "arrayref.lifo",1, 2, 1)
4.158 +OPDEF(OP_GETREF_I, 77, "getref.i", 1, 1, 1)
4.159 +OPDEF(OP_SETREF_I, 78, "setref.i", 1, 2, 1)
4.160 +OPDEF(OP_GETREF_F, 79, "getref.f", 1, 1, 1)
4.161 +OPDEF(OP_SETREF_F, 80, "setref.f", 1, 2, 1)
4.162
4.163 // Pushes an object reference onto the stack.
4.164 -OPDEF(OP_OBJECT, 79, "object", 5, 0, 1)
4.165 +OPDEF(OP_OBJECT, 81, "object", 5, 0, 1)
4.166
4.167 // Performs an array-to-array assignment.
4.168 // Left = pop()
4.169 // Right = pop()
4.170 // copy(Left, Right)
4.171 // push(Left)
4.172 -OPDEF(OP_ARRAYCOPY, 80, "arraycopy", 1, 2, 1)
4.173 +OPDEF(OP_ARRAYCOPY, 82, "arraycopy", 1, 2, 1)
4.174
4.175 // Duplicates the top item on the stack.
4.176 -OPDEF(OP_DUP, 81, "dup", 1, 1, 2)
4.177 +OPDEF(OP_DUP, 83, "dup", 1, 1, 2)
4.178
4.179 // Duplicates the top two items on the stack.
4.180 -OPDEF(OP_DUP2, 82, "dup2", 1, 2, 4)
4.181 +OPDEF(OP_DUP2, 84, "dup2", 1, 2, 4)
4.182
4.183 // Swaps the two items at the top of the stack.
4.184 -OPDEF(OP_SWAP, 83, "swap", 1, 2, 2)
4.185 +OPDEF(OP_SWAP, 85, "swap", 1, 2, 2)
4.186
4.187 // Roll operation is the same as Forth. It steals a value on the stack,
4.188 // shifting all stack values down, and then places the stolen value back at
4.189 @@ -205,14 +207,14 @@
4.190 // sp[-3] = sp[-2]
4.191 // sp[-2] = sp[-1]
4.192 // sp[-1] = p
4.193 -OPDEF(OP_ROLL3, 84, "roll3", 1, 3, 3)
4.194 +OPDEF(OP_ROLL3, 86, "roll3", 1, 3, 3)
4.195
4.196 // Pick operation is the same as Forth. It pushes a copy of a slot at a
4.197 // specific depth.
4.198 //
4.199 // push(sp[-n])
4.200 -OPDEF(OP_PICK2, 85, "pick2", 1, 2, 3)
4.201 -OPDEF(OP_PICK3, 86, "pick3", 1, 3, 4)
4.202 +OPDEF(OP_PICK2, 87, "pick2", 1, 2, 3)
4.203 +OPDEF(OP_PICK3, 88, "pick3", 1, 3, 4)
4.204
4.205 // Calls a native function. During the course of calling a native, arguments
4.206 // on the stack are re-pushed to match the cell-based native calling
4.207 @@ -223,14 +225,14 @@
4.208 //
4.209 // [u8 Opcode] [u32 Index] [u32 ArgCount]
4.210 //
4.211 -OPDEF(OP_CALLNATIVE, 87, "callnative", 9, -1, 1)
4.212 +OPDEF(OP_CALLNATIVE, 89, "callnative", 9, -1, 1)
4.213
4.214 // Returns from a function that does return a value.
4.215 -OPDEF(OP_RETURNVOID, 88, "returnvoid", 1, 0, 0)
4.216 +OPDEF(OP_RETURNVOID, 90, "returnvoid", 1, 0, 0)
4.217
4.218 // Loads the module of the running function.
4.219 -OPDEF(OP_MODULE, 89, "module", 1, 0, 1)
4.220 +OPDEF(OP_MODULE, 91, "module", 1, 0, 1)
4.221
4.222 // Loads a function from a module object. The operand is the slot number
4.223 // in the module.
4.224 -OPDEF(OP_GETMODULE_FN, 90, "getmodule.fn", 5, 1, 1)
4.225 +OPDEF(OP_GETMODULE_FN, 92, "getmodule.fn", 5, 1, 1)
5.1 --- a/jitcraft/Parser.cpp Tue Jul 17 23:10:54 2012 -0700
5.2 +++ b/jitcraft/Parser.cpp Wed Jul 18 21:46:29 2012 -0700
5.3 @@ -291,7 +291,7 @@
5.4 {
5.5 Expression *left = unary();
5.6 do {
5.7 - if (!match(TOK_SLASH) && !match(TOK_STAR))
5.8 + if (!match(TOK_SLASH) && !match(TOK_STAR) && !match(TOK_PERCENT))
5.9 break;
5.10 SourcePosition pos = scanner_.begin();
5.11 TokenKind kind = scanner_.last();
6.1 --- a/jitcraft/Scanner.cpp Tue Jul 17 23:10:54 2012 -0700
6.2 +++ b/jitcraft/Scanner.cpp Wed Jul 18 21:46:29 2012 -0700
6.3 @@ -469,6 +469,13 @@
6.4 putChar(c);
6.5 return TOK_BITXOR;
6.6
6.7 + case '%':
6.8 + c = getChar();
6.9 + if (c == '=')
6.10 + return TOK_ASSIGN_MOD;
6.11 + putChar(c);
6.12 + return TOK_PERCENT;
6.13 +
6.14 case '-':
6.15 c = getChar();
6.16 if (c == '=')
7.1 --- a/jitcraft/Token.h Tue Jul 17 23:10:54 2012 -0700
7.2 +++ b/jitcraft/Token.h Wed Jul 18 21:46:29 2012 -0700
7.3 @@ -69,6 +69,7 @@
7.4 _(MINUS, "-") \
7.5 _(STAR, "*") \
7.6 _(SLASH, "/") \
7.7 + _(PERCENT, "%") \
7.8 _(AMPERSAND, "&") \
7.9 _(BITOR, "|") \
7.10 _(BITXOR, "^") \
7.11 @@ -87,6 +88,7 @@
7.12 _(ASSIGN_SUB, "-=") \
7.13 _(ASSIGN_MUL, "*=") \
7.14 _(ASSIGN_DIV, "/=") \
7.15 + _(ASSIGN_MOD, "%=") \
7.16 _(ASSIGN_BITAND, "&=") \
7.17 _(ASSIGN_BITOR, "|=") \
7.18 _(ASSIGN_BITXOR, "^=") \