Usermode/libspiderscript - Fixing a multitude of bugs
authorJohn Hodge <[email protected]>
Sat, 14 Apr 2012 11:34:49 +0000 (19:34 +0800)
committerJohn Hodge <[email protected]>
Sat, 14 Apr 2012 11:34:49 +0000 (19:34 +0800)
13 files changed:
Usermode/Libraries/libspiderscript.so_src/ast.c
Usermode/Libraries/libspiderscript.so_src/ast.h
Usermode/Libraries/libspiderscript.so_src/ast_to_bytecode.c
Usermode/Libraries/libspiderscript.so_src/bytecode_gen.c
Usermode/Libraries/libspiderscript.so_src/bytecode_gen.h
Usermode/Libraries/libspiderscript.so_src/bytecode_ops.h
Usermode/Libraries/libspiderscript.so_src/exec.c
Usermode/Libraries/libspiderscript.so_src/exec_ast.c
Usermode/Libraries/libspiderscript.so_src/exec_bytecode.c
Usermode/Libraries/libspiderscript.so_src/lex.c
Usermode/Libraries/libspiderscript.so_src/parse.c
Usermode/Libraries/libspiderscript.so_src/tokens.h
Usermode/Libraries/libspiderscript.so_src/values.c

index 12f9f77..9532adb 100644 (file)
@@ -254,7 +254,7 @@ size_t AST_WriteNode(void *Buffer, size_t Offset, tAST_Node *Node)
        case NODETYPE_BWAND:    case NODETYPE_LOGICALAND:
        case NODETYPE_BWOR:     case NODETYPE_LOGICALOR:
        case NODETYPE_BWXOR:    case NODETYPE_LOGICALXOR:
-       case NODETYPE_EQUALS:
+       case NODETYPE_EQUALS:   case NODETYPE_NOTEQUALS:
        case NODETYPE_LESSTHAN: case NODETYPE_LESSTHANEQUAL:
        case NODETYPE_GREATERTHAN:      case NODETYPE_GREATERTHANEQUAL:
                Offset += AST_WriteNode(Buffer, Offset, Node->BinOp.Left);
@@ -394,7 +394,7 @@ void AST_FreeNode(tAST_Node *Node)
        case NODETYPE_BWAND:    case NODETYPE_LOGICALAND:
        case NODETYPE_BWOR:     case NODETYPE_LOGICALOR:
        case NODETYPE_BWXOR:    case NODETYPE_LOGICALXOR:
-       case NODETYPE_EQUALS:
+       case NODETYPE_EQUALS:   case NODETYPE_NOTEQUALS:
        case NODETYPE_LESSTHAN: case NODETYPE_LESSTHANEQUAL:
        case NODETYPE_GREATERTHAN:      case NODETYPE_GREATERTHANEQUAL:
                AST_FreeNode( Node->BinOp.Left );
@@ -506,7 +506,8 @@ tAST_Node *AST_NewAssign(tParser *Parser, int Operation, tAST_Node *Dest, tAST_N
 {
        tAST_Node       *ret = AST_int_AllocateNode(Parser, NODETYPE_ASSIGN, 0);
        
-       if( Dest->Type != NODETYPE_VARIABLE && Dest->Type != NODETYPE_ELEMENT ) {
+       if( Dest->Type != NODETYPE_VARIABLE && Dest->Type != NODETYPE_ELEMENT && Dest->Type != NODETYPE_INDEX )
+       {
                free(ret);
                SyntaxError(Parser, 1, "Assign target is not a variable or attribute (instead %i)",
                        Dest->Type);
index 8ee56d7..6548ad7 100644 (file)
@@ -54,6 +54,7 @@ enum eAST_NodeTypes
        NODETYPE_LOGICALXOR,    //!< Logical XOR operator
        
        NODETYPE_EQUALS,        //!< Comparison Equals
+       NODETYPE_NOTEQUALS,     //!< Comparison Not Equals
        NODETYPE_LESSTHAN,      //!< Comparison Less Than
        NODETYPE_LESSTHANEQUAL, //!< Comparison Less Than or Equal
        NODETYPE_GREATERTHAN,   //!< Comparison Greater Than
index 58cc5f8..d999222 100644 (file)
@@ -35,6 +35,7 @@ typedef struct sAST_BlockInfo
 // === PROTOTYPES ===
 // Node Traversal
  int   AST_ConvertNode(tAST_BlockInfo *Block, tAST_Node *Node, int bKeepValue);
+ int   BC_SaveValue(tAST_BlockInfo *Block, tAST_Node *DestNode);
 // Variables
  int   BC_Variable_Define(tAST_BlockInfo *Block, int Type, const char *Name);
  int   BC_Variable_SetValue(tAST_BlockInfo *Block, tAST_Node *VarNode);
@@ -131,17 +132,10 @@ int AST_ConvertNode(tAST_BlockInfo *Block, tAST_Node *Node, int bKeepValue)
        
        // Assignment
        case NODETYPE_ASSIGN:
-               // TODO: Support assigning to object attributes
-               if( Node->Assign.Dest->Type != NODETYPE_VARIABLE ) {
-                       AST_RuntimeError(Node, "LVALUE of assignment is not a variable");
-                       return -1;
-               }
-               
                // Perform assignment operation
                if( Node->Assign.Operation != NODETYPE_NOP )
                {
-                       
-                       ret = BC_Variable_GetValue(Block, Node->Assign.Dest);
+                       ret = AST_ConvertNode(Block, Node->Assign.Dest, 1);
                        if(ret) return ret;
                        ret = AST_ConvertNode(Block, Node->Assign.Value, 1);
                        if(ret) return ret;
@@ -164,7 +158,7 @@ int AST_ConvertNode(tAST_BlockInfo *Block, tAST_Node *Node, int bKeepValue)
                                AST_RuntimeError(Node, "Unknown operation in ASSIGN %i", Node->Assign.Operation);
                                break;
                        }
-                       printf("assign, op = %i\n", op);
+//                     printf("assign, op = %i\n", op);
                        Bytecode_AppendBinOp(Block->Handle, op);
                }
                else
@@ -175,19 +169,13 @@ int AST_ConvertNode(tAST_BlockInfo *Block, tAST_Node *Node, int bKeepValue)
                
                if( bKeepValue )
                        Bytecode_AppendDuplicate(Block->Handle);
-               // Set the variable value
-               ret = BC_Variable_SetValue( Block, Node->Assign.Dest );
+               
+               ret = BC_SaveValue(Block, Node->Assign.Dest);
                break;
        
        // Post increment/decrement
        case NODETYPE_POSTINC:
        case NODETYPE_POSTDEC:
-               // TODO: Support assigning to object attributes
-               if( Node->UniOp.Value->Type != NODETYPE_VARIABLE ) {
-                       AST_RuntimeError(Node, "LVALUE of assignment is not a variable");
-                       return -1;
-               }
-
                // Save original value if requested
                if(bKeepValue) {
                        ret = BC_Variable_GetValue(Block, Node->UniOp.Value);
@@ -196,7 +184,7 @@ int AST_ConvertNode(tAST_BlockInfo *Block, tAST_Node *Node, int bKeepValue)
                
                Bytecode_AppendConstInt(Block->Handle, 1);
                
-               ret = BC_Variable_GetValue(Block, Node->UniOp.Value);
+               ret = AST_ConvertNode(Block, Node->UniOp.Value, 1);
                if(ret) return ret;
 
                if( Node->Type == NODETYPE_POSTDEC )
@@ -205,12 +193,9 @@ int AST_ConvertNode(tAST_BlockInfo *Block, tAST_Node *Node, int bKeepValue)
                        Bytecode_AppendBinOp(Block->Handle, BC_OP_ADD);
                if(ret) return ret;
 
-
-               ret = BC_Variable_SetValue(Block, Node->UniOp.Value);
-               if(ret) return ret;
-               // Doesn't push unless needed
+               ret = BC_SaveValue(Block, Node->UniOp.Value);
                break;
-       
+
        // Function Call
        case NODETYPE_METHODCALL:
        case NODETYPE_FUNCTIONCALL:
@@ -481,8 +466,9 @@ int AST_ConvertNode(tAST_BlockInfo *Block, tAST_Node *Node, int bKeepValue)
        case NODETYPE_LOGICALOR:        if(!op) op = BC_OP_LOGICOR;
        case NODETYPE_LOGICALXOR:       if(!op) op = BC_OP_LOGICXOR;
        // Comparisons
-       case NODETYPE_EQUALS:   if(!op) op = BC_OP_EQUALS;
-       case NODETYPE_LESSTHAN: if(!op) op = BC_OP_LESSTHAN;
+       case NODETYPE_EQUALS:           if(!op) op = BC_OP_EQUALS;
+       case NODETYPE_NOTEQUALS:        if(!op) op = BC_OP_NOTEQUALS;
+       case NODETYPE_LESSTHAN:         if(!op) op = BC_OP_LESSTHAN;
        case NODETYPE_GREATERTHAN:      if(!op) op = BC_OP_GREATERTHAN;
        case NODETYPE_LESSTHANEQUAL:    if(!op) op = BC_OP_LESSTHANOREQUAL;
        case NODETYPE_GREATERTHANEQUAL: if(!op) op = BC_OP_GREATERTHANOREQUAL;
@@ -525,6 +511,38 @@ int AST_ConvertNode(tAST_BlockInfo *Block, tAST_Node *Node, int bKeepValue)
        return ret;
 }
 
+int BC_SaveValue(tAST_BlockInfo *Block, tAST_Node *DestNode)
+{
+        int    ret;
+       switch(DestNode->Type)
+       {
+       // Variable, simple
+       case NODETYPE_VARIABLE:
+               ret = BC_Variable_SetValue( Block, DestNode );
+               break;
+       // Array index
+       case NODETYPE_INDEX:
+               ret = AST_ConvertNode(Block, DestNode->BinOp.Left, 1);  // Array
+               if(ret) return ret;
+               ret = AST_ConvertNode(Block, DestNode->BinOp.Right, 1); // Offset
+               if(ret) return ret;
+               Bytecode_AppendSetIndex( Block->Handle );
+               break;
+       // Object element
+       case NODETYPE_ELEMENT:
+               ret = AST_ConvertNode(Block, DestNode->Scope.Element, 1);
+               if(ret) return ret;
+               Bytecode_AppendSetElement( Block->Handle, DestNode->Scope.Name );
+               break;
+       // Anything else
+       default:
+               // TODO: Support assigning to object attributes
+               AST_RuntimeError(DestNode, "Assignment target is not a LValue");
+               return -1;
+       }
+       return ret;
+}
+
 /**
  * \brief Define a variable
  * \param Block        Current block state
index b089b9a..d6e8ab0 100644 (file)
@@ -377,8 +377,12 @@ void Bytecode_AppendConstString(tBC_Function *Handle, const void *Data, size_t L
 // --- Indexing / Scoping
 void Bytecode_AppendElement(tBC_Function *Handle, const char *Name)
        DEF_BC_STR(BC_OP_ELEMENT, Name)
+void Bytecode_AppendSetElement(tBC_Function *Handle, const char *Name)
+       DEF_BC_STR(BC_OP_SETELEMENT, Name)
 void Bytecode_AppendIndex(tBC_Function *Handle)
        DEF_BC_NONE(BC_OP_INDEX)
+void Bytecode_AppendSetIndex(tBC_Function *Handle)
+       DEF_BC_NONE(BC_OP_SETINDEX);
 
 void Bytecode_AppendCreateObj(tBC_Function *Handle, const char *Name, int ArgumentCount)
        DEF_BC_STRINT(BC_OP_CREATEOBJ, Name, ArgumentCount)
index 0d901eb..b82b3b4 100644 (file)
@@ -57,7 +57,9 @@ extern void   Bytecode_AppendConstReal(tBC_Function *Handle, double Value);
 extern void    Bytecode_AppendConstString(tBC_Function *Handle, const void *Data, size_t Length);
 //  > Scoping
 extern void    Bytecode_AppendElement(tBC_Function *Handle, const char *Name); // Obj->SubObj
+extern void    Bytecode_AppendSetElement(tBC_Function *Handle, const char *Name);      // Set an object member
 extern void    Bytecode_AppendIndex(tBC_Function *Handle);     // Index into an array
+extern void    Bytecode_AppendSetIndex(tBC_Function *Handle);  // Write an array element
 //  > Function Calls
 extern void    Bytecode_AppendCreateObj(tBC_Function *Handle, const char *Name, int ArgumentCount);
 extern void    Bytecode_AppendMethodCall(tBC_Function *Handle, const char *Name, int ArgumentCount);
index 59c58be..00df615 100644 (file)
@@ -28,35 +28,37 @@ enum eBC_Ops
        BC_OP_CAST,     //
        
        BC_OP_ELEMENT,  // = 16
+       BC_OP_SETELEMENT,
        BC_OP_INDEX,
+       BC_OP_SETINDEX,
 
-       BC_OP_ENTERCONTEXT,     // = 18
+       BC_OP_ENTERCONTEXT,     // = 20
        BC_OP_LEAVECONTEXT,
        BC_OP_DEFINEVAR,
 
        // Operations
-       BC_OP_LOGICNOT, // 21
+       BC_OP_LOGICNOT, // 23
        BC_OP_LOGICAND,
        BC_OP_LOGICOR,
        BC_OP_LOGICXOR,
 
-       BC_OP_BITNOT,   // 25
+       BC_OP_BITNOT,   // 27
        BC_OP_BITAND,
        BC_OP_BITOR,
        BC_OP_BITXOR,
 
-       BC_OP_BITSHIFTLEFT,     // 29
+       BC_OP_BITSHIFTLEFT,     // 31
        BC_OP_BITSHIFTRIGHT,
        BC_OP_BITROTATELEFT,
 
-       BC_OP_NEG,      // 32
+       BC_OP_NEG,      // 34
        BC_OP_ADD,
        BC_OP_SUBTRACT,
        BC_OP_MULTIPLY,
        BC_OP_DIVIDE,
        BC_OP_MODULO,
 
-       BC_OP_EQUALS,   // 38
+       BC_OP_EQUALS,   // 40
        BC_OP_NOTEQUALS,
        BC_OP_LESSTHAN,
        BC_OP_LESSTHANOREQUAL,
index b073cbf..5379357 100644 (file)
@@ -48,9 +48,11 @@ tSpiderValue *SpiderScript_ExecuteFunction(tSpiderScript *Script,
                // Execute!
                if(fcn)
                {
+                       #if 1
                        if( fcn->BCFcn )
                                ret = Bytecode_ExecuteFunction(Script, fcn, NArguments, Arguments);
                        else
+                       #endif
                                ret = AST_ExecuteFunction(Script, fcn, NArguments, Arguments);
                        bFound = 1;
                }
index 7a94dc4..46749ae 100644 (file)
@@ -592,6 +592,7 @@ tSpiderValue *AST_ExecuteNode(tAST_BlockState *Block, tAST_Node *Node)
        case NODETYPE_BITSHIFTRIGHT:
        case NODETYPE_BITROTATELEFT:
        case NODETYPE_EQUALS:
+       case NODETYPE_NOTEQUALS:
        case NODETYPE_LESSTHAN:
        case NODETYPE_GREATERTHAN:
        case NODETYPE_LESSTHANEQUAL:
@@ -760,6 +761,7 @@ tSpiderValue *AST_ExecuteNode_BinOp(tSpiderScript *Script, tAST_Node *Node, int
        switch(Operation)
        {
        case NODETYPE_EQUALS:
+       case NODETYPE_NOTEQUALS:
        case NODETYPE_LESSTHAN:
        case NODETYPE_GREATERTHAN:
        case NODETYPE_LESSTHANEQUAL:
@@ -818,6 +820,7 @@ tSpiderValue *AST_ExecuteNode_BinOp(tSpiderScript *Script, tAST_Node *Node, int
                        switch(Operation)
                        {
                        case NODETYPE_EQUALS:   ret->Integer = (cmp == 0);      break;
+                       case NODETYPE_NOTEQUALS:        ret->Integer = (cmp != 0);      break;
                        case NODETYPE_LESSTHAN: ret->Integer = (cmp < 0);       break;
                        case NODETYPE_GREATERTHAN:      ret->Integer = (cmp > 0);       break;
                        case NODETYPE_LESSTHANEQUAL:    ret->Integer = (cmp <= 0);      break;
index 4673bd2..d12cb73 100644 (file)
@@ -84,7 +84,7 @@ int Bytecode_int_IsStackEntTrue(tBC_StackEnt *Ent)
        case SS_DATATYPE_INTEGER:
                return !!Ent->Integer;
        case SS_DATATYPE_REAL:
-               return (-.5f < Ent->Real && Ent->Real < 0.5f);
+               return !(-.5f < Ent->Real && Ent->Real < 0.5f);
        case SS_DATATYPE_OBJECT:
                return Ent->Object != NULL;
        case ET_FUNCTION_START:
@@ -521,11 +521,14 @@ int Bytecode_int_ExecuteFunction(tSpiderScript *Script, tScript_Function *Fcn, t
                        Bytecode_int_StackPush(Stack, &val2);
                        Bytecode_int_DerefStackValue(&val1);
                        break;
+               
                case BC_OP_BITNOT:
-                       if(!ast_op)     ast_op = NODETYPE_BWNOT;
+                       if(!ast_op)     ast_op = NODETYPE_BWNOT,        opstr = "BITNOT";
+               case BC_OP_NEG:
+                       if(!ast_op)     ast_op = NODETYPE_NEGATE,       opstr = "NEG";
 
                        STATE_HDR();
-                       DEBUG_F("UNIOP %i\n", ast_op);
+                       DEBUG_F("%s\n", opstr);
 
                        GET_STACKVAL(val1);
                        pval1 = Bytecode_int_GetSpiderValue(&val1, &tmpVal1);
@@ -600,6 +603,8 @@ int Bytecode_int_ExecuteFunction(tSpiderScript *Script, tScript_Function *Fcn, t
 
                case BC_OP_EQUALS:
                        if(!ast_op)     ast_op = NODETYPE_EQUALS,       opstr = "EQUALS";
+               case BC_OP_NOTEQUALS:
+                       if(!ast_op)     ast_op = NODETYPE_NOTEQUALS,    opstr = "NOTEQUALS";
                case BC_OP_LESSTHAN:
                        if(!ast_op)     ast_op = NODETYPE_LESSTHAN,     opstr = "LESSTHAN";
                case BC_OP_LESSTHANOREQUAL:
@@ -615,17 +620,22 @@ int Bytecode_int_ExecuteFunction(tSpiderScript *Script, tScript_Function *Fcn, t
                        GET_STACKVAL(val2);     // Right
                        GET_STACKVAL(val1);     // Left
 
+                       DEBUG_F(" ("); PRINT_STACKVAL(val1); DEBUG_F(")");
+                       DEBUG_F(" ("); PRINT_STACKVAL(val2); DEBUG_F(")\n");
+
                        #define PERFORM_NUM_OP(_type, _field) if(val1.Type == _type && val1.Type == val2.Type) { \
                                switch(op->Operation) { \
                                case BC_OP_ADD: val1._field = val1._field + val2._field;        break; \
                                case BC_OP_SUBTRACT:    val1._field = val1._field - val2._field;        break; \
                                case BC_OP_MULTIPLY:    val1._field = val1._field * val2._field;        break; \
                                case BC_OP_DIVIDE:      val1._field = val1._field / val2._field;        break; \
-                               case BC_OP_EQUALS:      val1._field = val1._field == val2._field;       break; \
-                               case BC_OP_LESSTHAN:    val1._field = val1._field < val2._field;        break; \
-                               case BC_OP_LESSTHANOREQUAL:     val1._field = val1._field <= val2._field;       break; \
-                               case BC_OP_GREATERTHAN: val1._field = val1._field > val2._field;        break; \
-                               case BC_OP_GREATERTHANOREQUAL:  val1._field = val1._field >= val2._field;       break; \
+                               \
+                               case BC_OP_EQUALS:      val1.Type=SS_DATATYPE_INTEGER; val1.Integer = (val1._field == val2._field);     break; \
+                               case BC_OP_NOTEQUALS:   val1.Type=SS_DATATYPE_INTEGER; val1.Integer = (val1._field != val2._field);     break; \
+                               case BC_OP_LESSTHAN:    val1.Type=SS_DATATYPE_INTEGER; val1.Integer = val1._field < val2._field;        break; \
+                               case BC_OP_LESSTHANOREQUAL:     val1.Type=SS_DATATYPE_INTEGER; val1.Integer = val1._field <= val2._field;       break; \
+                               case BC_OP_GREATERTHAN: val1.Type=SS_DATATYPE_INTEGER; val1.Integer = val1._field > val2._field;        break; \
+                               case BC_OP_GREATERTHANOREQUAL:  val1.Type=SS_DATATYPE_INTEGER; val1.Integer = val1._field >= val2._field;       break; \
                                \
                                case BC_OP_BITAND:      val1._field = (int64_t)val1._field & (int64_t)val2._field;      break; \
                                case BC_OP_BITOR:       val1._field = (int64_t)val1._field | (int64_t)val2._field;      break; \
@@ -633,6 +643,7 @@ int Bytecode_int_ExecuteFunction(tSpiderScript *Script, tScript_Function *Fcn, t
                                case BC_OP_MODULO:      val1._field = (int64_t)val1._field % (int64_t)val2._field;      break; \
                                default:        AST_RuntimeError(NULL, "Invalid operation on datatype %i", _type); nextop = NULL; break;\
                                }\
+                               DEBUG_F(" - Fast local op\n");\
                                PUT_STACKVAL(val1);\
                                break;\
                        }
@@ -728,7 +739,7 @@ int Bytecode_int_ExecuteFunction(tSpiderScript *Script, tScript_Function *Fcn, t
                                        
                                        if(val1.Type == SS_DATATYPE_OBJECT)
                                                obj = val1.Object;
-                                       else if(val1.Type == ET_REFERENCE && val1.Reference->Type == SS_DATATYPE_OBJECT)
+                                       else if(val1.Type == ET_REFERENCE && val1.Reference && val1.Reference->Type == SS_DATATYPE_OBJECT)
                                                obj = val1.Reference->Object;
                                        else {
                                                // Error
index 2d16bcf..b659e34 100644 (file)
@@ -274,6 +274,11 @@ int GetToken(tParser *File)
        
        // Logical NOT
        case '!':
+               if( *File->CurPos == '=' ) {
+                       File->CurPos ++;
+                       ret = TOK_NOTEQUALS;
+                       break;
+               }
                ret = TOK_LOGICNOT;
                break;
        // Bitwise NOT
index e6d9694..fdd5474 100644 (file)
@@ -581,6 +581,9 @@ tAST_Node *Parse_DoExpr2(tParser *Parser)
                case TOK_EQUALS:
                        ret = AST_NewBinOp(Parser, NODETYPE_EQUALS, ret, _next(Parser));
                        break;
+               case TOK_NOTEQUALS:
+                       ret = AST_NewBinOp(Parser, NODETYPE_NOTEQUALS, ret, _next(Parser));
+                       break;
                case TOK_LT:
                        ret = AST_NewBinOp(Parser, NODETYPE_LESSTHAN, ret, _next(Parser));
                        break;
index 44176b0..0139fc6 100644 (file)
@@ -85,7 +85,7 @@ enum eTokens
        TOK_ELEMENT,
        
        // Comparisons
-       TOK_EQUALS,
+       TOK_EQUALS, TOK_NOTEQUALS,
        TOK_LT, TOK_LTE,
        TOK_GT, TOK_GTE,
        
@@ -171,7 +171,7 @@ const char * const csaTOKEN_NAMES[] = {
        "TOK_SCOPE",
        "TOK_ELEMENT",
        
-       "TOK_EQUALS",
+       "TOK_EQUALS",   "TOK_NOTEQUALS",
        "TOK_LT",       "TOK_LTE",
        "TOK_GT",       "TOK_GTE",
        
index f72e290..2b87841 100644 (file)
@@ -24,10 +24,10 @@ tSpiderValue        *SpiderScript_CastValueTo(int Type, tSpiderValue *Source);
 void   SpiderScript_FreeValue(tSpiderValue *Value);
 char   *SpiderScript_DumpValue(tSpiderValue *Value);
 // --- Operations
-tSpiderValue   *SpiderScript_DoOp(tSpiderValue *Left, int Operation, int bCanCast, tSpiderValue *Right);
-tSpiderValue   *SpiderScript_int_DoOpInt(tSpiderValue *Left, int Operation, int bCanCast, tSpiderValue *Right);
-tSpiderValue   *SpiderScript_int_DoOpReal(tSpiderValue *Left, int Operation, int bCanCast, tSpiderValue *Right);
-tSpiderValue   *SpiderScript_int_DoOpString(tSpiderValue *Left, int Operation, int bCanCast, tSpiderValue *Right);
+tSpiderValue   *SpiderScript_DoOp(tSpiderValue *Left, enum eSpiderValueOps, int bCanCast, tSpiderValue *Right);
+tSpiderValue   *SpiderScript_int_DoOpInt(tSpiderValue *Left, enum eSpiderValueOps, int bCanCast, tSpiderValue *Right);
+tSpiderValue   *SpiderScript_int_DoOpReal(tSpiderValue *Left, enum eSpiderValueOps, int bCanCast, tSpiderValue *Right);
+tSpiderValue   *SpiderScript_int_DoOpString(tSpiderValue *Left, enum eSpiderValueOps, int bCanCast, tSpiderValue *Right);
 
 
 // === CODE ===
@@ -405,26 +405,28 @@ char *SpiderScript_DumpValue(tSpiderValue *Value)
 }
 
 // ---
-tSpiderValue *SpiderScript_DoOp(tSpiderValue *Left, int Operation, int bCanCast, tSpiderValue *Right)
+tSpiderValue *SpiderScript_DoOp(tSpiderValue *Left, enum eSpiderValueOps Operation, int bCanCast, tSpiderValue *Right)
 {
        switch(Left->Type)
        {
        case SS_DATATYPE_INTEGER:
                return SpiderScript_int_DoOpInt(Left, Operation, bCanCast, Right);
+       default:
+               return NULL;
        }
        return NULL;
 }
 
-tSpiderValue *SpiderScript_int_DoOpInt(tSpiderValue *Left, int Operation, int bCanCast, tSpiderValue *Right)
+tSpiderValue *SpiderScript_int_DoOpInt(tSpiderValue *Left, enum eSpiderValueOps Operation, int bCanCast, tSpiderValue *Right)
 {
        tSpiderValue    *oldright = Right;
        tSpiderValue    *ret = NULL;
-        int64_t        rv;
+        int64_t        rv = 0;
 
        // Casting
        if(Right && Right->Type != SS_DATATYPE_INTEGER) {
                if(!bCanCast)   return ERRPTR;
-               Right = SpiderScript_CastValueTo(Right, SS_DATATYPE_INTEGER);
+               Right = SpiderScript_CastValueTo(SS_DATATYPE_INTEGER, Right);
        }
 
        // Do the operation
@@ -438,6 +440,14 @@ tSpiderValue *SpiderScript_int_DoOpInt(tSpiderValue *Left, int Operation, int bC
                if(!Right)      ret = ERRPTR;
                else    rv = Left->Integer + Right->Integer;
                break;
+       case SS_VALUEOP_SUBTRACT:
+               if(!Right)      ret = ERRPTR;
+               else    rv = Left->Integer - Right->Integer;
+               break;
+       default:
+               ret = ERRPTR;
+               AST_RuntimeError(NULL, "BUG - BUG REPORT: Unimplemented integer operation %i", Operation);
+               break;
        }
 
        // Delete temporary value

UCC git Repository :: git.ucc.asn.au