Added support for modulo operator.
authorDavid Anderson <dvander@alliedmods.net>
Wed Jul 18 21:46:29 2012 -0700 (2012-07-18)
changeset 82f99bc938522a
parent 81 77c318a4badd
child 83 79265b56316e
Added support for modulo operator.
jitcraft/BytecodeCompiler.cpp
jitcraft/Interpreter.cpp
jitcraft/Opcodes.cpp
jitcraft/Opcodes.tbl
jitcraft/Parser.cpp
jitcraft/Scanner.cpp
jitcraft/Token.h
     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,      "^=")                         \