From: John Hodge Date: Sat, 14 Apr 2012 11:34:49 +0000 (+0800) Subject: Usermode/libspiderscript - Fixing a multitude of bugs X-Git-Tag: rel0.15~714^2~11 X-Git-Url: https://git.ucc.asn.au/?a=commitdiff_plain;h=4e478b213ff6d79d87da816443d35e7a5fd9d7a3;p=tpg%2Facess2.git Usermode/libspiderscript - Fixing a multitude of bugs --- diff --git a/Usermode/Libraries/libspiderscript.so_src/ast.c b/Usermode/Libraries/libspiderscript.so_src/ast.c index 12f9f775..9532adb7 100644 --- a/Usermode/Libraries/libspiderscript.so_src/ast.c +++ b/Usermode/Libraries/libspiderscript.so_src/ast.c @@ -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); diff --git a/Usermode/Libraries/libspiderscript.so_src/ast.h b/Usermode/Libraries/libspiderscript.so_src/ast.h index 8ee56d77..6548ad72 100644 --- a/Usermode/Libraries/libspiderscript.so_src/ast.h +++ b/Usermode/Libraries/libspiderscript.so_src/ast.h @@ -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 diff --git a/Usermode/Libraries/libspiderscript.so_src/ast_to_bytecode.c b/Usermode/Libraries/libspiderscript.so_src/ast_to_bytecode.c index 58cc5f82..d9992221 100644 --- a/Usermode/Libraries/libspiderscript.so_src/ast_to_bytecode.c +++ b/Usermode/Libraries/libspiderscript.so_src/ast_to_bytecode.c @@ -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 diff --git a/Usermode/Libraries/libspiderscript.so_src/bytecode_gen.c b/Usermode/Libraries/libspiderscript.so_src/bytecode_gen.c index b089b9ae..d6e8ab03 100644 --- a/Usermode/Libraries/libspiderscript.so_src/bytecode_gen.c +++ b/Usermode/Libraries/libspiderscript.so_src/bytecode_gen.c @@ -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) diff --git a/Usermode/Libraries/libspiderscript.so_src/bytecode_gen.h b/Usermode/Libraries/libspiderscript.so_src/bytecode_gen.h index 0d901ebd..b82b3b44 100644 --- a/Usermode/Libraries/libspiderscript.so_src/bytecode_gen.h +++ b/Usermode/Libraries/libspiderscript.so_src/bytecode_gen.h @@ -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); diff --git a/Usermode/Libraries/libspiderscript.so_src/bytecode_ops.h b/Usermode/Libraries/libspiderscript.so_src/bytecode_ops.h index 59c58bea..00df615f 100644 --- a/Usermode/Libraries/libspiderscript.so_src/bytecode_ops.h +++ b/Usermode/Libraries/libspiderscript.so_src/bytecode_ops.h @@ -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, diff --git a/Usermode/Libraries/libspiderscript.so_src/exec.c b/Usermode/Libraries/libspiderscript.so_src/exec.c index b073cbf0..53793578 100644 --- a/Usermode/Libraries/libspiderscript.so_src/exec.c +++ b/Usermode/Libraries/libspiderscript.so_src/exec.c @@ -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; } diff --git a/Usermode/Libraries/libspiderscript.so_src/exec_ast.c b/Usermode/Libraries/libspiderscript.so_src/exec_ast.c index 7a94dc42..46749aef 100644 --- a/Usermode/Libraries/libspiderscript.so_src/exec_ast.c +++ b/Usermode/Libraries/libspiderscript.so_src/exec_ast.c @@ -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; diff --git a/Usermode/Libraries/libspiderscript.so_src/exec_bytecode.c b/Usermode/Libraries/libspiderscript.so_src/exec_bytecode.c index 4673bd28..d12cb731 100644 --- a/Usermode/Libraries/libspiderscript.so_src/exec_bytecode.c +++ b/Usermode/Libraries/libspiderscript.so_src/exec_bytecode.c @@ -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 diff --git a/Usermode/Libraries/libspiderscript.so_src/lex.c b/Usermode/Libraries/libspiderscript.so_src/lex.c index 2d16bcfb..b659e34c 100644 --- a/Usermode/Libraries/libspiderscript.so_src/lex.c +++ b/Usermode/Libraries/libspiderscript.so_src/lex.c @@ -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 diff --git a/Usermode/Libraries/libspiderscript.so_src/parse.c b/Usermode/Libraries/libspiderscript.so_src/parse.c index e6d96942..fdd54746 100644 --- a/Usermode/Libraries/libspiderscript.so_src/parse.c +++ b/Usermode/Libraries/libspiderscript.so_src/parse.c @@ -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; diff --git a/Usermode/Libraries/libspiderscript.so_src/tokens.h b/Usermode/Libraries/libspiderscript.so_src/tokens.h index 44176b0b..0139fc6c 100644 --- a/Usermode/Libraries/libspiderscript.so_src/tokens.h +++ b/Usermode/Libraries/libspiderscript.so_src/tokens.h @@ -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", diff --git a/Usermode/Libraries/libspiderscript.so_src/values.c b/Usermode/Libraries/libspiderscript.so_src/values.c index f72e2903..2b878415 100644 --- a/Usermode/Libraries/libspiderscript.so_src/values.c +++ b/Usermode/Libraries/libspiderscript.so_src/values.c @@ -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