Просмотр исходного кода

Add back ++,-- pre inc, dec operators

gdouglas 13 лет назад
Родитель
Сommit
b6b9360593

+ 3 - 0
gmsrc/doc/ChangeLog.txt

@@ -404,3 +404,6 @@ o Added experimental project gmddotnet (gmDebuggerNet) which is gmd ported to C#
   
   
 12/05/12
 12/05/12
 o Fixed Fork stack growth bug. Thanks funkbot.
 o Fixed Fork stack growth bug. Thanks funkbot.
+
+09/06/12
+o Add back ++,-- pre inc, dec operators (Experimental, code restored from v0.9)

+ 2 - 1
gmsrc/doc/ToDoList.txt

@@ -8,7 +8,8 @@ frame for changes or features, so effectively a wish list.
 o Fix issue where reported error line is not exact.  Occurs due to instruction pointer increment before exception handling.
 o Fix issue where reported error line is not exact.  Occurs due to instruction pointer increment before exception handling.
 o Fix empty / commented out script from producing parse error. Work around: Add a ';' semicolon to end of source, or ignore known empty scripts.
 o Fix empty / commented out script from producing parse error. Work around: Add a ';' semicolon to end of source, or ignore known empty scripts.
 o Change overide 'this' syntax from this:func() to func<this>() to support member chains eg. a.b.c<t>()
 o Change overide 'this' syntax from this:func() to func<this>() to support member chains eg. a.b.c<t>()
-o Put ++, -- operators back, but perhaps don't let them be used in conditions for consistency.
+Part o Put ++, -- operators back, but perhaps don't let them be used in conditions for consistency.
+  (pre inc/dec are back in, but post inc/dec should be added also.
 
 
 o Make string hash table resize for efficiency in string intensive applications.
 o Make string hash table resize for efficiency in string intensive applications.
 o Make compiler thread safe.  Probably by moving to Lemon parser and Flex++.
 o Make compiler thread safe.  Probably by moving to Lemon parser and Flex++.

+ 4 - 0
gmsrc/src/gm/gmByteCode.h

@@ -32,6 +32,10 @@ enum gmByteCode
   BC_OP_MUL,
   BC_OP_MUL,
   BC_OP_DIV,
   BC_OP_DIV,
   BC_OP_REM,
   BC_OP_REM,
+#if GM_USE_INCDECOPERATORS
+  BC_OP_INC,
+  BC_OP_DEC,
+#endif //GM_USE_INCDECOPERATORS
 
 
   // bit
   // bit
   BC_BIT_OR,
   BC_BIT_OR,

+ 4 - 0
gmsrc/src/gm/gmByteCodeGen.cpp

@@ -129,6 +129,10 @@ void gmByteCodeGen::AdjustStack(gmByteCode a_instruction)
     case BC_OP_MUL : --m_tos; break;
     case BC_OP_MUL : --m_tos; break;
     case BC_OP_DIV : --m_tos; break;
     case BC_OP_DIV : --m_tos; break;
     case BC_OP_REM : --m_tos; break;
     case BC_OP_REM : --m_tos; break;
+#if GM_USE_INCDECOPERATORS
+    case BC_OP_INC : --m_tos; break;
+    case BC_OP_DEC : --m_tos; break;
+#endif //GM_USE_INCDECOPERATORS
 
 
     case BC_BIT_OR : --m_tos; break;
     case BC_BIT_OR : --m_tos; break;
     case BC_BIT_XOR : --m_tos; break;
     case BC_BIT_XOR : --m_tos; break;

+ 124 - 1
gmsrc/src/gm/gmCodeGen.cpp

@@ -16,7 +16,9 @@
 #include "gmListDouble.h"
 #include "gmListDouble.h"
 
 
 
 
-//static const char * s_tempVarName0 = "__t0"; // Currently not used
+#if GM_USE_INCDECOPERATORS
+static const char * s_tempVarName0 = "__t0";
+#endif //GM_USE_INCDECOPERATORS
 static const char * s_tempVarName1 = "__t1";
 static const char * s_tempVarName1 = "__t1";
 
 
 #define SIZEOF_BC_BRA   (sizeof(gmuint32)+sizeof(gmptr)) // instruction + address
 #define SIZEOF_BC_BRA   (sizeof(gmuint32)+sizeof(gmptr)) // instruction + address
@@ -94,6 +96,9 @@ public:
   bool GenStmtCompound(const gmCodeTreeNode * a_node, gmByteCodeGen * a_byteCode);
   bool GenStmtCompound(const gmCodeTreeNode * a_node, gmByteCodeGen * a_byteCode);
   bool GenExprOpDot(const gmCodeTreeNode * a_node, gmByteCodeGen * a_byteCode);
   bool GenExprOpDot(const gmCodeTreeNode * a_node, gmByteCodeGen * a_byteCode);
   bool GenExprOpUnary(const gmCodeTreeNode * a_node, gmByteCodeGen * a_byteCode);
   bool GenExprOpUnary(const gmCodeTreeNode * a_node, gmByteCodeGen * a_byteCode);
+  #if GM_USE_INCDECOPERATORS
+  bool GenExprOpPreIncDec(const gmCodeTreeNode * a_node, gmByteCodeGen * a_byteCode);
+  #endif //GM_USE_INCDECOPERATORS
   bool GenExprOpArrayIndex(const gmCodeTreeNode * a_node, gmByteCodeGen * a_byteCode);
   bool GenExprOpArrayIndex(const gmCodeTreeNode * a_node, gmByteCodeGen * a_byteCode);
   bool GenExprOpAr(const gmCodeTreeNode * a_node, gmByteCodeGen * a_byteCode);
   bool GenExprOpAr(const gmCodeTreeNode * a_node, gmByteCodeGen * a_byteCode);
   bool GenExprOpShift(const gmCodeTreeNode * a_node, gmByteCodeGen * a_byteCode);
   bool GenExprOpShift(const gmCodeTreeNode * a_node, gmByteCodeGen * a_byteCode);
@@ -420,6 +425,10 @@ bool gmCodeGenPrivate::Generate(const gmCodeTreeNode * a_node, gmByteCodeGen * a
               case CTNOT_UNARY_MINUS :
               case CTNOT_UNARY_MINUS :
               case CTNOT_UNARY_COMPLEMENT :
               case CTNOT_UNARY_COMPLEMENT :
               case CTNOT_UNARY_NOT : res = GenExprOpUnary(a_node, a_byteCode); break;
               case CTNOT_UNARY_NOT : res = GenExprOpUnary(a_node, a_byteCode); break;
+#if GM_USE_INCDECOPERATORS
+              case CTNOT_PRE_DEC :
+              case CTNOT_PRE_INC :          res = GenExprOpPreIncDec(a_node, a_byteCode); break;
+#endif //GM_USE_INCDECOPERATORS
               case CTNOT_ARRAY_INDEX :      res = GenExprOpArrayIndex(a_node, a_byteCode); break;
               case CTNOT_ARRAY_INDEX :      res = GenExprOpArrayIndex(a_node, a_byteCode); break;
               case CTNOT_TIMES :
               case CTNOT_TIMES :
               case CTNOT_DIVIDE :
               case CTNOT_DIVIDE :
@@ -1011,6 +1020,120 @@ bool gmCodeGenPrivate::GenExprOpUnary(const gmCodeTreeNode * a_node, gmByteCodeG
 }
 }
 
 
 
 
+#if GM_USE_INCDECOPERATORS
+bool gmCodeGenPrivate::GenExprOpPreIncDec(const gmCodeTreeNode * a_node, gmByteCodeGen * a_byteCode)
+{
+  GM_ASSERT(a_node->m_type == CTNT_EXPRESSION && a_node->m_subType == CTNET_OPERATION);
+
+  // Make sure child 0 is an l-value
+  const gmCodeTreeNode * lValue = a_node->m_children[0];
+  int type = 0;
+
+  if(lValue->m_type == CTNT_EXPRESSION && lValue->m_subType == CTNET_OPERATION && lValue->m_subTypeType == CTNOT_DOT)
+  {
+    // Generate half l-value
+    if(!Generate(lValue->m_children[0], a_byteCode)) return false;
+    a_byteCode->Emit(BC_DUP);
+    a_byteCode->EmitPtr(BC_GETDOT, m_hooks->GetSymbolId(lValue->m_children[1]->m_data.m_string));
+    type = 0;
+  }
+  else if(lValue->m_type == CTNT_EXPRESSION && lValue->m_subType == CTNET_OPERATION && lValue->m_subTypeType == CTNOT_ARRAY_INDEX)
+  {
+    // Generate half l-value
+    if(!Generate(lValue->m_children[0], a_byteCode)) return false;
+    if(!Generate(lValue->m_children[1], a_byteCode)) return false;
+    a_byteCode->Emit(BC_DUP2);
+    a_byteCode->Emit(BC_GETIND);
+    type = 1;
+  }
+  else if(lValue->m_type == CTNT_EXPRESSION && lValue->m_subType == CTNET_IDENTIFIER)
+  {
+    if(!Generate(lValue, a_byteCode)) return false;
+    type = 2;
+  }
+  else
+  {
+    if(m_log) m_log->LogEntry("illegal l-value for '++/--' operator, line %d", a_node->m_lineNumber);
+    return false;
+  }
+
+  // Perform inc/dec
+  switch(a_node->m_subTypeType)
+  {
+    case CTNOT_PRE_INC : a_byteCode->Emit(BC_OP_INC); break;
+    case CTNOT_PRE_DEC : a_byteCode->Emit(BC_OP_DEC); break;
+    default :
+    {
+      if(m_log) m_log->LogEntry("unkown operator");
+      return false;
+    }
+  }
+
+  // Write back the value
+  if(type == 0)
+  {
+    int offset = m_currentFunction->SetVariableType(s_tempVarName0, CTVT_LOCAL);
+    a_byteCode->Emit(BC_DUP);
+    a_byteCode->Emit(BC_SETLOCAL, (gmuint32) offset);
+    a_byteCode->EmitPtr(BC_SETDOT, m_hooks->GetSymbolId(lValue->m_children[1]->m_data.m_string));
+    a_byteCode->Emit(BC_GETLOCAL, (gmuint32) offset);
+  }
+  else if(type == 1)
+  {
+    int offset = m_currentFunction->SetVariableType(s_tempVarName0, CTVT_LOCAL);
+    a_byteCode->Emit(BC_DUP);
+    a_byteCode->Emit(BC_SETLOCAL, (gmuint32) offset);
+    a_byteCode->Emit(BC_SETIND);
+    a_byteCode->Emit(BC_GETLOCAL, (gmuint32) offset);
+  }
+  else if(type == 2)
+  {
+    a_byteCode->Emit(BC_DUP);
+    gmCodeTreeVariableType vtype;
+    int offset = m_currentFunction->GetVariableOffset(lValue->m_data.m_string, vtype);
+
+    // if local, set local regardless
+    // if member set this
+    // if global, set global
+    // set and add local
+
+    if((lValue->m_flags & gmCodeTreeNode::CTN_MEMBER) > 0)
+    {
+      return a_byteCode->EmitPtr(BC_SETTHIS, m_hooks->GetSymbolId(lValue->m_data.m_string));
+    }
+
+    if(offset >= 0 && vtype == CTVT_LOCAL)
+    {
+      return a_byteCode->Emit(BC_SETLOCAL, (gmuint32) offset);
+    }
+    else if(offset == -1)
+    {
+      if(vtype == CTVT_MEMBER)
+      {
+        return a_byteCode->EmitPtr(BC_SETTHIS, m_hooks->GetSymbolId(lValue->m_data.m_string));
+      }
+      else if(vtype == CTVT_GLOBAL)
+      {
+        return a_byteCode->EmitPtr(BC_SETGLOBAL, m_hooks->GetSymbolId(lValue->m_data.m_string));
+      }
+      if(m_log) m_log->LogEntry("internal error");
+      return false;
+    }
+
+    offset = m_currentFunction->SetVariableType(lValue->m_data.m_string, CTVT_LOCAL);
+    return a_byteCode->Emit(BC_SETLOCAL, (gmuint32) offset);
+  }
+  else
+  {
+    // paranoia
+    if(m_log) m_log->LogEntry("internal error");
+    return false;
+  }
+
+  return true;
+}
+#endif
+
 
 
 bool gmCodeGenPrivate::GenExprOpArrayIndex(const gmCodeTreeNode * a_node, gmByteCodeGen * a_byteCode)
 bool gmCodeGenPrivate::GenExprOpArrayIndex(const gmCodeTreeNode * a_node, gmByteCodeGen * a_byteCode)
 {
 {

+ 4 - 0
gmsrc/src/gm/gmCodeTree.cpp

@@ -113,6 +113,10 @@ const char * gmGetOperatorTypeName(gmCodeTreeNodeOperationType a_type)
     case CTNOT_UNARY_MINUS : return "CTNOT_UNARY_MINUS";
     case CTNOT_UNARY_MINUS : return "CTNOT_UNARY_MINUS";
     case CTNOT_UNARY_NOT : return "CTNOT_UNARY_NOT";
     case CTNOT_UNARY_NOT : return "CTNOT_UNARY_NOT";
     case CTNOT_UNARY_COMPLEMENT : return "CTNOT_UNARY_COMPLEMENT";
     case CTNOT_UNARY_COMPLEMENT : return "CTNOT_UNARY_COMPLEMENT";
+#if GM_USE_INCDECOPERATORS
+    case CTNOT_PRE_DEC : return "CTNOT_PRE_DEC";
+    case CTNOT_PRE_INC : return "CTNOT_PRE_INC";
+#endif //GM_USE_INCDECOPERATORS
     case CTNOT_ARRAY_INDEX : return "CTNOT_ARRAY_INDEX";
     case CTNOT_ARRAY_INDEX : return "CTNOT_ARRAY_INDEX";
     case CTNOT_TIMES : return "CTNOT_TIMES";
     case CTNOT_TIMES : return "CTNOT_TIMES";
     case CTNOT_DIVIDE : return "CTNOT_DIVIDE";
     case CTNOT_DIVIDE : return "CTNOT_DIVIDE";

+ 4 - 0
gmsrc/src/gm/gmCodeTree.h

@@ -159,6 +159,10 @@ enum gmCodeTreeNodeOperationType
   CTNOT_UNARY_MINUS,
   CTNOT_UNARY_MINUS,
   CTNOT_UNARY_COMPLEMENT,
   CTNOT_UNARY_COMPLEMENT,
   CTNOT_UNARY_NOT, 
   CTNOT_UNARY_NOT, 
+#if GM_USE_INCDECOPERATORS
+  CTNOT_PRE_DEC,
+  CTNOT_PRE_INC,
+#endif //GM_USE_INCDECOPERATORS
   CTNOT_ARRAY_INDEX,
   CTNOT_ARRAY_INDEX,
   CTNOT_TIMES,
   CTNOT_TIMES,
   CTNOT_DIVIDE,
   CTNOT_DIVIDE,

+ 1 - 0
gmsrc/src/gm/gmConfig.h

@@ -106,5 +106,6 @@ enum gmEndian
 #define GM_USE_FORK                 1         // Support fork instruction 
 #define GM_USE_FORK                 1         // Support fork instruction 
 #define GM_USER_FOREACH             1         // Support foreach for user types
 #define GM_USER_FOREACH             1         // Support foreach for user types
 #define GM_USE_ENDON                1         // Support endon() to kill thread when signalled
 #define GM_USE_ENDON                1         // Support endon() to kill thread when signalled
+#define GM_USE_INCDECOPERATORS      1         // Support operator ++ and --
 
 
 #endif // _GMCONFIG_H_
 #endif // _GMCONFIG_H_

+ 26 - 0
gmsrc/src/gm/gmOperators.cpp

@@ -28,6 +28,10 @@ const char * gmGetOperatorName(gmOperator a_operator)
     case O_MUL : return "mul";
     case O_MUL : return "mul";
     case O_DIV : return "div";
     case O_DIV : return "div";
     case O_REM : return "mod";
     case O_REM : return "mod";
+#if GM_USE_INCDECOPERATORS
+    case O_INC : return "inc";
+    case O_DEC : return "dec";
+#endif //GM_USE_INCDECOPERATORS
     case O_BIT_OR : return "bitor";
     case O_BIT_OR : return "bitor";
     case O_BIT_XOR : return "bitxor";
     case O_BIT_XOR : return "bitxor";
     case O_BIT_AND : return "bitand";
     case O_BIT_AND : return "bitand";
@@ -62,6 +66,10 @@ gmOperator gmGetOperator(const char * a_operatorName)
   if(_gmstricmp(a_operatorName, "mul") == 0) return O_MUL;
   if(_gmstricmp(a_operatorName, "mul") == 0) return O_MUL;
   if(_gmstricmp(a_operatorName, "div") == 0) return O_DIV;
   if(_gmstricmp(a_operatorName, "div") == 0) return O_DIV;
   if(_gmstricmp(a_operatorName, "mod") == 0) return O_REM;
   if(_gmstricmp(a_operatorName, "mod") == 0) return O_REM;
+#if GM_USE_INCDECOPERATORS
+  if(_gmstricmp(a_operatorName, "inc") == 0) return O_INC;
+  if(_gmstricmp(a_operatorName, "dec") == 0) return O_DEC;
+#endif //GM_USE_INCDECOPERATORS
   if(_gmstricmp(a_operatorName, "bitor") == 0) return O_BIT_OR;
   if(_gmstricmp(a_operatorName, "bitor") == 0) return O_BIT_OR;
   if(_gmstricmp(a_operatorName, "bitxor") == 0) return O_BIT_XOR;
   if(_gmstricmp(a_operatorName, "bitxor") == 0) return O_BIT_XOR;
   if(_gmstricmp(a_operatorName, "bitand") == 0) return O_BIT_AND;
   if(_gmstricmp(a_operatorName, "bitand") == 0) return O_BIT_AND;
@@ -138,6 +146,16 @@ void GM_CDECL gmIntOpRem(gmThread * a_thread, gmVariable * a_operands)
   a_operands[0].m_value.m_int %= a_operands[1].m_value.m_int;
   a_operands[0].m_value.m_int %= a_operands[1].m_value.m_int;
 #endif // GMMACHINE_GMCHECKDIVBYZERO
 #endif // GMMACHINE_GMCHECKDIVBYZERO
 }
 }
+#if GM_USE_INCDECOPERATORS
+void GM_CDECL gmIntOpInc(gmThread * a_thread, gmVariable * a_operands)
+{
+  ++a_operands[0].m_value.m_int;
+}
+void GM_CDECL gmIntOpDec(gmThread * a_thread, gmVariable * a_operands)
+{
+  --a_operands[0].m_value.m_int;
+}
+#endif //GM_USE_INCDECOPERATORS
 void GM_CDECL gmIntOpBitOr(gmThread * a_thread, gmVariable * a_operands)
 void GM_CDECL gmIntOpBitOr(gmThread * a_thread, gmVariable * a_operands)
 {
 {
   a_operands[0].m_value.m_int |= a_operands[1].m_value.m_int;
   a_operands[0].m_value.m_int |= a_operands[1].m_value.m_int;
@@ -529,6 +547,10 @@ void gmInitBasicType(gmType a_type, gmOperatorFunction * a_operators)
     a_operators[O_MUL]            = gmIntOpMul;
     a_operators[O_MUL]            = gmIntOpMul;
     a_operators[O_DIV]            = gmIntOpDiv;
     a_operators[O_DIV]            = gmIntOpDiv;
     a_operators[O_REM]            = gmIntOpRem;
     a_operators[O_REM]            = gmIntOpRem;
+#if GM_USE_INCDECOPERATORS	
+    a_operators[O_INC]            = gmIntOpInc;
+    a_operators[O_DEC]            = gmIntOpDec;
+#endif //GM_USE_INCDECOPERATORS
     a_operators[O_BIT_OR]         = gmIntOpBitOr;
     a_operators[O_BIT_OR]         = gmIntOpBitOr;
     a_operators[O_BIT_XOR]        = gmIntOpBitXor;
     a_operators[O_BIT_XOR]        = gmIntOpBitXor;
     a_operators[O_BIT_AND]        = gmIntOpBitAnd;
     a_operators[O_BIT_AND]        = gmIntOpBitAnd;
@@ -552,6 +574,10 @@ void gmInitBasicType(gmType a_type, gmOperatorFunction * a_operators)
     a_operators[O_MUL]    = gmFloatOpMul;
     a_operators[O_MUL]    = gmFloatOpMul;
     a_operators[O_DIV]    = gmFloatOpDiv;
     a_operators[O_DIV]    = gmFloatOpDiv;
     a_operators[O_REM]    = gmFloatOpRem;
     a_operators[O_REM]    = gmFloatOpRem;
+#if GM_USE_INCDECOPERATORS
+    a_operators[O_INC]    = gmFloatOpInc;
+    a_operators[O_DEC]    = gmFloatOpDec;
+#endif //GM_USE_INCDECOPERATORS
     a_operators[O_LT]     = gmFloatOpLT;
     a_operators[O_LT]     = gmFloatOpLT;
     a_operators[O_GT]     = gmFloatOpGT;
     a_operators[O_GT]     = gmFloatOpGT;
     a_operators[O_LTE]    = gmFloatOpLTE;
     a_operators[O_LTE]    = gmFloatOpLTE;

+ 4 - 0
gmsrc/src/gm/gmOperators.h

@@ -35,6 +35,10 @@ enum gmOperator
   O_MUL,              // op1, op2
   O_MUL,              // op1, op2
   O_DIV,              // op1, op2
   O_DIV,              // op1, op2
   O_REM,              // op1, op2
   O_REM,              // op1, op2
+#if GM_USE_INCDECOPERATORS
+  O_INC,              // op1                       (tos is a_operands + 1)
+  O_DEC,              // op1
+#endif //GM_USE_INCDECOPERATORS
 
 
   O_BIT_OR,           // op1, op2
   O_BIT_OR,           // op1, op2
   O_BIT_XOR,          // op1, op2
   O_BIT_XOR,          // op1, op2

+ 10 - 0
gmsrc/src/gm/gmParser.y

@@ -110,6 +110,8 @@ gmCodeTreeNode * CreateAsignExpression(int a_subTypeType, gmCodeTreeNode * a_lef
 %token SYMBOL_ASGN_BXOR
 %token SYMBOL_ASGN_BXOR
 %token SYMBOL_RIGHT_SHIFT
 %token SYMBOL_RIGHT_SHIFT
 %token SYMBOL_LEFT_SHIFT
 %token SYMBOL_LEFT_SHIFT
+%token SYMBOL_INC
+%token SYMBOL_DEC
 %token SYMBOL_LTE
 %token SYMBOL_LTE
 %token SYMBOL_GTE
 %token SYMBOL_GTE
 %token SYMBOL_EQ
 %token SYMBOL_EQ
@@ -619,6 +621,14 @@ unary_expression
     {
     {
       $$ = $1;
       $$ = $1;
     }
     }
+  | SYMBOL_INC unary_expression
+    {
+      $$ = CreateOperation(CTNOT_PRE_INC, $2);
+    }
+  | SYMBOL_DEC unary_expression
+    {
+      $$ = CreateOperation(CTNOT_PRE_DEC, $2);
+    }
   | unary_operator unary_expression
   | unary_operator unary_expression
     {
     {
       $$ = $1;
       $$ = $1;

+ 2 - 0
gmsrc/src/gm/gmScanner.l

@@ -94,6 +94,8 @@ FL		    (f|F)
 "^="                              { return(SYMBOL_ASGN_BXOR);   }
 "^="                              { return(SYMBOL_ASGN_BXOR);   }
 ">>"                              { return(SYMBOL_RIGHT_SHIFT); }
 ">>"                              { return(SYMBOL_RIGHT_SHIFT); }
 "<<"                              { return(SYMBOL_LEFT_SHIFT);  }
 "<<"                              { return(SYMBOL_LEFT_SHIFT);  }
+"++"                              { return(SYMBOL_INC);         }
+"--"                              { return(SYMBOL_DEC);         }
 "<="                              { return(SYMBOL_LTE);         }
 "<="                              { return(SYMBOL_LTE);         }
 ">="                              { return(SYMBOL_GTE);         }
 ">="                              { return(SYMBOL_GTE);         }
 "=="                              { return(SYMBOL_EQ);          }
 "=="                              { return(SYMBOL_EQ);          }

+ 4 - 0
gmsrc/src/gm/gmThread.cpp

@@ -229,6 +229,10 @@ gmThread::State gmThread::Sys_Execute(gmVariable * a_return)
       // unary operator
       // unary operator
       //
       //
 
 
+#if GM_USE_INCDECOPERATORS
+      case BC_OP_INC :
+      case BC_OP_DEC :
+#endif
       case BC_BIT_INV :
       case BC_BIT_INV :
       case BC_OP_NEG :
       case BC_OP_NEG :
       case BC_OP_POS :
       case BC_OP_POS :

+ 4 - 2
gmsrc/src/gml/main.cpp

@@ -123,8 +123,10 @@ static void PrintByteCode(FILE * a_fp, const void * a_byteCode, int a_byteCodeLe
       case BC_OP_MUL : cp = "mul"; break;
       case BC_OP_MUL : cp = "mul"; break;
       case BC_OP_DIV : cp = "div"; break;
       case BC_OP_DIV : cp = "div"; break;
       case BC_OP_REM : cp = "rem"; break;
       case BC_OP_REM : cp = "rem"; break;
-      //case BC_OP_INC : cp = "inc"; break;
-      //case BC_OP_DEC : cp = "dec"; break;
+#if GM_USE_INCDECOPERATORS
+      case BC_OP_INC : cp = "inc"; break;
+      case BC_OP_DEC : cp = "dec"; break;
+#endif //GM_USE_INCDECOPERATORS
 
 
       case BC_BIT_OR : cp = "bor"; break;
       case BC_BIT_OR : cp = "bor"; break;
       case BC_BIT_XOR : cp = "bxor"; break;
       case BC_BIT_XOR : cp = "bxor"; break;