From 2c8989ea0849b0e207e6c357626d41c991dc423f Mon Sep 17 00:00:00 2001 From: John Hodge Date: Sat, 17 Sep 2011 22:57:15 +0800 Subject: [PATCH] SpiderScript - More changes, cleaning up - Bytecode still doesn't run, but getting there - Fixed some memory leaks about the place --- .../Libraries/libspiderscript.so_src/ast.c | 6 +- .../Libraries/libspiderscript.so_src/ast.h | 2 + .../libspiderscript.so_src/ast_to_bytecode.c | 2 +- .../libspiderscript.so_src/bytecode.h | 54 ++++-- .../libspiderscript.so_src/bytecode_gen.c | 82 +++------ .../libspiderscript.so_src/bytecode_gen.h | 2 +- .../bytecode_makefile.c | 10 +- .../libspiderscript.so_src/exec_ast.c | 20 +-- .../libspiderscript.so_src/exec_bytecode.c | 155 ++++++++++++++++-- .../Libraries/libspiderscript.so_src/parse.c | 4 +- 10 files changed, 235 insertions(+), 102 deletions(-) diff --git a/Usermode/Libraries/libspiderscript.so_src/ast.c b/Usermode/Libraries/libspiderscript.so_src/ast.c index ce04195d..bafdd12c 100644 --- a/Usermode/Libraries/libspiderscript.so_src/ast.c +++ b/Usermode/Libraries/libspiderscript.so_src/ast.c @@ -407,7 +407,7 @@ void AST_FreeNode(tAST_Node *Node) case NODETYPE_NOP: break; case NODETYPE_VARIABLE: break; case NODETYPE_CONSTANT: break; - case NODETYPE_BREAK: break; + case NODETYPE_BREAK: case NODETYPE_CONTINUE: break; case NODETYPE_STRING: @@ -490,7 +490,9 @@ tAST_Node *AST_NewIf(tParser *Parser, tAST_Node *Condition, tAST_Node *True, tAS tAST_Node *AST_NewLoop(tParser *Parser, const char *Tag, tAST_Node *Init, int bPostCheck, tAST_Node *Condition, tAST_Node *Increment, tAST_Node *Code) { - tAST_Node *ret = AST_int_AllocateNode(Parser, NODETYPE_LOOP, strlen(Tag) + 1); + tAST_Node *ret; + if(!Tag) Tag = ""; + ret = AST_int_AllocateNode(Parser, NODETYPE_LOOP, strlen(Tag) + 1); ret->For.Init = Init; ret->For.bCheckAfter = !!bPostCheck; ret->For.Condition = Condition; diff --git a/Usermode/Libraries/libspiderscript.so_src/ast.h b/Usermode/Libraries/libspiderscript.so_src/ast.h index aa448625..39c23b1f 100644 --- a/Usermode/Libraries/libspiderscript.so_src/ast.h +++ b/Usermode/Libraries/libspiderscript.so_src/ast.h @@ -256,5 +256,7 @@ extern void AST_FreeNode(tAST_Node *Node); extern void Object_Dereference(tSpiderValue *Object); extern void Object_Reference(tSpiderValue *Object); extern tSpiderValue *AST_ExecuteNode(tAST_BlockState *Block, tAST_Node *Node); +extern tSpiderValue *AST_ExecuteNode_BinOp(tSpiderScript *Script, tAST_Node *Node, int Operation, tSpiderValue *Left, tSpiderValue *Right); +extern tSpiderValue *AST_ExecuteNode_UniOp(tSpiderScript *Script, tAST_Node *Node, int Operation, tSpiderValue *Value); #endif diff --git a/Usermode/Libraries/libspiderscript.so_src/ast_to_bytecode.c b/Usermode/Libraries/libspiderscript.so_src/ast_to_bytecode.c index 5cffd796..7afd0c03 100644 --- a/Usermode/Libraries/libspiderscript.so_src/ast_to_bytecode.c +++ b/Usermode/Libraries/libspiderscript.so_src/ast_to_bytecode.c @@ -57,7 +57,7 @@ tBC_Function *Bytecode_ConvertFunction(tAST_Function *ASTFcn) char *arg_names[ASTFcn->ArgumentCount]; int arg_types[ASTFcn->ArgumentCount]; - for(arg = ASTFcn->Arguments; arg; arg = arg->NextSibling) + for(arg = ASTFcn->Arguments, i = 0; arg; arg = arg->NextSibling, i ++) { arg_names[i] = arg->DefVar.Name; arg_types[i] = arg->DefVar.DataType; diff --git a/Usermode/Libraries/libspiderscript.so_src/bytecode.h b/Usermode/Libraries/libspiderscript.so_src/bytecode.h index bff4caec..045f896f 100644 --- a/Usermode/Libraries/libspiderscript.so_src/bytecode.h +++ b/Usermode/Libraries/libspiderscript.so_src/bytecode.h @@ -5,25 +5,51 @@ #ifndef _BYTECODE_H_ #define _BYTECODE_H_ -struct sBytecodeHeader +#include "bytecode_ops.h" + +typedef struct sBC_Op tBC_Op; +typedef struct sBC_Function tBC_Function; + +struct sBC_Op { - uint32_t Magic; //!< Magic Value (identifier) "\x8FSS\r" - uint32_t NFunctions; //!< Number of functions - struct { - uint32_t NameOffset; //!< Offset to the name - uint32_t CodeOffset; //!< Offset to the code - } Functions[]; + tBC_Op *Next; + int Operation; + int bUseInteger; // Used for serialisation + union { + struct { + const char *String; + int Integer; + } StringInt; + + uint64_t Integer; + double Real; + } Content; }; -enum eBytecodeOperations +struct sBC_Function { - BCOP_UNDEF, - BCOP_NOP, + const char *Name; - BCOP_DEFVAR, - BCOP_RETURN, + int LabelCount; + int LabelSpace; + tBC_Op **Labels; - NUM_BCOP -} + int MaxVariableCount; + // NOTE: These fields are invalid after compilation + int VariableCount; + int VariableSpace; + const char **VariableNames; // Only type needs to be stored + int CurContextDepth; // Used to get the real var count + + int OperationCount; + tBC_Op *Operations; + tBC_Op *OperationsEnd; + + int ArgumentCount; + struct { + char *Name; + int Type; + } Arguments[]; +}; #endif diff --git a/Usermode/Libraries/libspiderscript.so_src/bytecode_gen.c b/Usermode/Libraries/libspiderscript.so_src/bytecode_gen.c index 8ae7f32a..078f2df1 100644 --- a/Usermode/Libraries/libspiderscript.so_src/bytecode_gen.c +++ b/Usermode/Libraries/libspiderscript.so_src/bytecode_gen.c @@ -11,56 +11,15 @@ #include #include "bytecode_gen.h" #include +#include "bytecode.h" // === IMPORTS === // === STRUCTURES === -typedef struct sBC_Op tBC_Op; - -struct sBC_Op -{ - tBC_Op *Next; - int Operation; - int bUseInteger; - union { - struct { - const char *String; - int Integer; - } StringInt; - - uint64_t Integer; - double Real; - } Content; -}; - -struct sBC_Function -{ - const char *Name; - - int LabelCount; - int LabelSpace; - tBC_Op **Labels; - - int MaxVariableCount; - // NOTE: These fields are invalid after compilation - int VariableCount; - int VariableSpace; - const char **VariableNames; // Only type needs to be stored - int CurContextDepth; // Used to get the real var count - - int OperationCount; - tBC_Op *Operations; - tBC_Op *OperationsEnd; - - int ArgumentCount; - struct { - char *Name; - int Type; - } Arguments[]; -}; // === PROTOTYPES === tBC_Op *Bytecode_int_AllocateOp(int Operation); + int Bytecode_int_AddVariable(tBC_Function *Handle, const char *Name); // === GLOBALS === @@ -90,7 +49,9 @@ tBC_Function *Bytecode_CreateFunction(const char *Name, int ArgCount, char **Arg ret->Name = Name; ret->LabelSpace = ret->LabelCount = 0; ret->Labels = NULL; - + + ret->MaxVariableCount = 0; + ret->CurContextDepth = 0; ret->VariableCount = ret->VariableSpace = 0; ret->VariableNames = NULL; @@ -103,6 +64,7 @@ tBC_Function *Bytecode_CreateFunction(const char *Name, int ArgCount, char **Arg { ret->Arguments[i].Name = strdup(ArgNames[i]); ret->Arguments[i].Type = ArgTypes[i]; + Bytecode_int_AddVariable(ret, ret->Arguments[i].Name); } return ret; @@ -316,13 +278,13 @@ void Bytecode_int_AppendOp(tBC_Function *Fcn, tBC_Op *Op) Fcn->OperationsEnd = Op; } -void Bytecode_int_AddVariable(tBC_Function *Handle, const char *Name) +int Bytecode_int_AddVariable(tBC_Function *Handle, const char *Name) { if(Handle->VariableCount == Handle->VariableSpace) { void *tmp; Handle->VariableSpace += 10; tmp = realloc(Handle->VariableNames, Handle->VariableSpace * sizeof(Handle->VariableNames[0])); - if(!tmp) return ; // TODO: Error + if(!tmp) return -1; // TODO: Error Handle->VariableNames = tmp; } Handle->VariableNames[Handle->VariableCount] = Name; @@ -330,6 +292,7 @@ void Bytecode_int_AddVariable(tBC_Function *Handle, const char *Name) // Get max count (used when executing to get the frame size) if(Handle->VariableCount - Handle->CurContextDepth >= Handle->MaxVariableCount) Handle->MaxVariableCount = Handle->VariableCount - Handle->CurContextDepth; + return Handle->VariableCount - 1; } int Bytecode_int_GetVarIndex(tBC_Function *Handle, const char *Name) @@ -338,12 +301,7 @@ int Bytecode_int_GetVarIndex(tBC_Function *Handle, const char *Name) // Get the start of this context for( i = Handle->VariableCount; i --; ) { - if( Handle->VariableNames[i] == NULL ) break; - } - // Check for duplicate allocation - for( ; i < Handle->VariableCount; i ++ ) - { - if( strcmp(Name, Handle->VariableNames[i]) == 0 ) + if( Handle->VariableNames[i] && strcmp(Name, Handle->VariableNames[i]) == 0 ) return i; } return -1; @@ -440,6 +398,7 @@ void Bytecode_AppendLeaveContext(tBC_Function *Handle) if( Handle->VariableNames[i] == NULL ) break; } Handle->CurContextDepth --; + Handle->VariableCount = i; DEF_BC_NONE(BC_OP_LEAVECONTEXT) } @@ -447,13 +406,22 @@ void Bytecode_AppendLeaveContext(tBC_Function *Handle) // DEF_BC_STRINT(BC_OP_IMPORTNS, Name, 0) void Bytecode_AppendDefineVar(tBC_Function *Handle, const char *Name, int Type) { + int i; #if 1 - // Check for duplicates - if( Bytecode_int_GetVarIndex(Handle, Name) ) - return ; // TODO: Error + // Get the start of this context + for( i = Handle->VariableCount; i --; ) + { + if( Handle->VariableNames[i] == NULL ) break; + } + // Check for duplicate allocation + for( i ++; i < Handle->VariableCount; i ++ ) + { + if( strcmp(Name, Handle->VariableNames[i]) == 0 ) + return ; + } #endif - Bytecode_int_AddVariable(Handle, Name); + i = Bytecode_int_AddVariable(Handle, Name); - DEF_BC_STRINT(BC_OP_DEFINEVAR, Name, Type) + DEF_BC_STRINT(BC_OP_DEFINEVAR, Name, (Type&0xFFFF) | (i << 16)) } diff --git a/Usermode/Libraries/libspiderscript.so_src/bytecode_gen.h b/Usermode/Libraries/libspiderscript.so_src/bytecode_gen.h index b2f19cf2..19d240c8 100644 --- a/Usermode/Libraries/libspiderscript.so_src/bytecode_gen.h +++ b/Usermode/Libraries/libspiderscript.so_src/bytecode_gen.h @@ -9,8 +9,8 @@ #define _BYTECODE_GEN_H_ #include "ast.h" +#include "bytecode.h" -typedef struct sBC_Function tBC_Function; typedef struct sStringList tStringList; typedef struct sString tString; //typedef struct sAST_Function tAST_Function; diff --git a/Usermode/Libraries/libspiderscript.so_src/bytecode_makefile.c b/Usermode/Libraries/libspiderscript.so_src/bytecode_makefile.c index a4c9b717..033f8d72 100644 --- a/Usermode/Libraries/libspiderscript.so_src/bytecode_makefile.c +++ b/Usermode/Libraries/libspiderscript.so_src/bytecode_makefile.c @@ -94,6 +94,7 @@ int Bytecode_ConvertScript(tSpiderScript *Script, const char *DestFile) code = Bytecode_SerialiseFunction(bc_fcn, &len, &strings); Bytecode_DeleteFunction(bc_fcn); fwrite(code, len, 1, fp); + free(code); } // String table @@ -109,11 +110,16 @@ int Bytecode_ConvertScript(tSpiderScript *Script, const char *DestFile) string_offset += str->Length + 1; } // Data - for(str = strings.Head; str; str = str->Next) + for(str = strings.Head; str;) { + tString *nextstr = str->Next; fwrite(str->Data, str->Length, 1, fp); _put8(0); + free(str); + str = nextstr; } + strings.Head = NULL; + strings.Tail = NULL; } // Fix header @@ -122,6 +128,8 @@ int Bytecode_ConvertScript(tSpiderScript *Script, const char *DestFile) _put32(strings.Count); _put32(strtab_ofs); + fclose(fp); + return 0; } diff --git a/Usermode/Libraries/libspiderscript.so_src/exec_ast.c b/Usermode/Libraries/libspiderscript.so_src/exec_ast.c index 0c1a4021..be2c1c50 100644 --- a/Usermode/Libraries/libspiderscript.so_src/exec_ast.c +++ b/Usermode/Libraries/libspiderscript.so_src/exec_ast.c @@ -18,8 +18,8 @@ extern tSpiderFunction *gpExports_First; // === PROTOTYPES === // - Node Execution tSpiderValue *AST_ExecuteNode(tAST_BlockState *Block, tAST_Node *Node); -tSpiderValue *AST_ExecuteNode_BinOp(tAST_BlockState *Block, tAST_Node *Node, int Operation, tSpiderValue *Left, tSpiderValue *Right); -tSpiderValue *AST_ExecuteNode_UniOp(tAST_BlockState *Block, tAST_Node *Node, int Operation, tSpiderValue *Value); +tSpiderValue *AST_ExecuteNode_BinOp(tSpiderScript *Script, tAST_Node *Node, int Operation, tSpiderValue *Left, tSpiderValue *Right); +tSpiderValue *AST_ExecuteNode_UniOp(tSpiderScript *Script, tAST_Node *Node, int Operation, tSpiderValue *Value); // - Variables tAST_Variable *Variable_Define(tAST_BlockState *Block, int Type, const char *Name, tSpiderValue *Value); int Variable_SetValue(tAST_BlockState *Block, tAST_Node *VarNode, tSpiderValue *Value); @@ -450,7 +450,7 @@ tSpiderValue *AST_ExecuteNode(tAST_BlockState *Block, tAST_Node *Node) // varVal->ReferenceCount); } #endif - value = AST_ExecuteNode_BinOp(Block, Node, Node->Assign.Operation, varVal, ret); + value = AST_ExecuteNode_BinOp(Block->Script, Node, Node->Assign.Operation, varVal, ret); if(value == ERRPTR) return ERRPTR; if(ret) SpiderScript_DereferenceValue(ret); @@ -495,9 +495,9 @@ tSpiderValue *AST_ExecuteNode(tAST_BlockState *Block, tAST_Node *Node) varVal = Variable_GetValue(Block, Node->UniOp.Value); if( Node->Type == NODETYPE_POSTDEC ) - value = AST_ExecuteNode_BinOp(Block, Node, NODETYPE_SUBTRACT, varVal, &one); + value = AST_ExecuteNode_BinOp(Block->Script, Node, NODETYPE_SUBTRACT, varVal, &one); else - value = AST_ExecuteNode_BinOp(Block, Node, NODETYPE_ADD, varVal, &one); + value = AST_ExecuteNode_BinOp(Block->Script, Node, NODETYPE_ADD, varVal, &one); if( value == ERRPTR ) return ERRPTR; @@ -967,7 +967,7 @@ tSpiderValue *AST_ExecuteNode(tAST_BlockState *Block, tAST_Node *Node) case NODETYPE_NEGATE: // Negation (-) op1 = AST_ExecuteNode(Block, Node->UniOp.Value); if(op1 == ERRPTR) return ERRPTR; - ret = AST_ExecuteNode_UniOp(Block, Node, Node->Type, op1); + ret = AST_ExecuteNode_UniOp(Block->Script, Node, Node->Type, op1); SpiderScript_DereferenceValue(op1); break; @@ -992,7 +992,7 @@ tSpiderValue *AST_ExecuteNode(tAST_BlockState *Block, tAST_Node *Node) return ERRPTR; } - ret = AST_ExecuteNode_BinOp(Block, Node, Node->Type, op1, op2); + ret = AST_ExecuteNode_BinOp(Block->Script, Node, Node->Type, op1, op2); // Free intermediate objects SpiderScript_DereferenceValue(op1); @@ -1021,7 +1021,7 @@ _return: return ret; } -tSpiderValue *AST_ExecuteNode_UniOp(tAST_BlockState *Block, tAST_Node *Node, int Operation, tSpiderValue *Value) +tSpiderValue *AST_ExecuteNode_UniOp(tSpiderScript *Script, tAST_Node *Node, int Operation, tSpiderValue *Value) { tSpiderValue *ret; #if 0 @@ -1083,7 +1083,7 @@ tSpiderValue *AST_ExecuteNode_UniOp(tAST_BlockState *Block, tAST_Node *Node, int return ret; } -tSpiderValue *AST_ExecuteNode_BinOp(tAST_BlockState *Block, tAST_Node *Node, int Operation, tSpiderValue *Left, tSpiderValue *Right) +tSpiderValue *AST_ExecuteNode_BinOp(tSpiderScript *Script, tAST_Node *Node, int Operation, tSpiderValue *Left, tSpiderValue *Right) { tSpiderValue *preCastValue = Right; tSpiderValue *ret; @@ -1124,7 +1124,7 @@ tSpiderValue *AST_ExecuteNode_BinOp(tAST_BlockState *Block, tAST_Node *Node, int #endif // If implicit casts are allowed, convert Right to Left's type - if(Block->Script->Variant->bImplicitCasts) + if(Script->Variant->bImplicitCasts) { Right = SpiderScript_CastValueTo(Left->Type, Right); if(Right == ERRPTR) diff --git a/Usermode/Libraries/libspiderscript.so_src/exec_bytecode.c b/Usermode/Libraries/libspiderscript.so_src/exec_bytecode.c index b9384245..a88670ca 100644 --- a/Usermode/Libraries/libspiderscript.so_src/exec_bytecode.c +++ b/Usermode/Libraries/libspiderscript.so_src/exec_bytecode.c @@ -6,28 +6,30 @@ * - Generate a bytecode file */ #include -#include "bytecode_ops.h" +#include +#include +#include "bytecode.h" +#include +#include "ast.h" -typedef sBC_StackEnt tBC_StackEnt; +typedef struct sBC_StackEnt tBC_StackEnt; +typedef struct sBC_Stack tBC_Stack; enum eBC_StackEntTypes { ET_NULL, // Start of the stack - ET_FUNCTION_START, // Start of the function - ET_INTEGER, // Integer / Boolean - ET_REAL, // Real number - ET_OBJECT, // Object + // SS_DATATYPE_* + ET_FUNCTION_START = NUM_SS_DATATYPES, ET_REFERENCE // Reference to a tSpiderValue }; struct sBC_StackEnt { - uint8_t EntType; - uint8_t _padding[3]; + uint8_t Type; union { uint64_t Integer; double Real; - tSpiderValue *Reference; + tSpiderValue *Reference; // Used for everything else tSpiderObject *Object; }; }; @@ -56,38 +58,153 @@ int Bytecode_int_StackPush(tBC_Stack *Stack, tBC_StackEnt *Src) return 0; } +int Bytecode_int_IsStackEntTrue(tBC_StackEnt *Ent) +{ + switch(Ent->Type) + { + case SS_DATATYPE_INTEGER: + return !!Ent->Integer; + case SS_DATATYPE_REAL: + return (-.5f < Ent->Real && Ent->Real < 0.5f); + case SS_DATATYPE_OBJECT: + return Ent->Object != NULL; + case ET_FUNCTION_START: + return -1; + default: + return SpiderScript_IsValueTrue(Ent->Reference); + } +} + +tSpiderValue *Bytecode_int_GetSpiderValue(tBC_StackEnt *Ent, tSpiderValue *tmp) +{ + switch(Ent->Type) + { + case SS_DATATYPE_INTEGER: + tmp->Type = SS_DATATYPE_INTEGER; + tmp->ReferenceCount = 2; // Stops it being freed + tmp->Integer = Ent->Integer; + return tmp; + case SS_DATATYPE_REAL: + tmp->Type = SS_DATATYPE_REAL; + tmp->ReferenceCount = 2; // Stops it being freed + tmp->Real = Ent->Real; + return tmp; + case SS_DATATYPE_OBJECT: + tmp->Type = SS_DATATYPE_OBJECT; + tmp->ReferenceCount = 2; + tmp->Object = Ent->Object; + return tmp; + case ET_FUNCTION_START: + return NULL; + default: + return Ent->Reference; + } +} + +void Bytecode_int_SetSpiderValue(tBC_StackEnt *Ent, tSpiderValue *Value) +{ + switch(Value->Type) + { + case SS_DATATYPE_INTEGER: + Ent->Type = SS_DATATYPE_INTEGER; + Ent->Integer = Value->Integer; + break; + case SS_DATATYPE_REAL: + Ent->Type = SS_DATATYPE_REAL; + Ent->Real = Value->Real; + break; + case SS_DATATYPE_OBJECT: + Ent->Type = SS_DATATYPE_OBJECT; + Ent->Object = Value->Object; + break; + default: + SpiderScript_ReferenceValue(Value); + Ent->Reference = Value; + break; + } +} + #define GET_STACKVAL(dst) if((ret = Bytecode_int_StackPop(Stack, &dst))) return ret; +#define OP_INDX(op_ptr) ((op_ptr)->Content.StringInt.Integer) +#define OP_STRING(op_ptr) ((op_ptr)->Content.StringInt.String) -int Bytecode_ExecuteFunction(tBC_Function *Fcn, tBC_Stack *Stack, int ArgCount); +int Bytecode_ExecuteFunction(tSpiderScript *Script, tBC_Function *Fcn, tBC_Stack *Stack, int ArgCount) { + int ret, ast_op, i; tBC_Op *op; tBC_StackEnt val1, val2; - tBC_StackEnt local_vars[Fcn->MaxVariableCount+Fcn->ArgumentCount]; + tBC_StackEnt local_vars[Fcn->MaxVariableCount]; // Includes arguments + tSpiderValue tmpVal1, tmpVal2; // temp storage + tSpiderValue *pval1, *pval2, *ret_val; // Pop off arguments + if( ArgCount > Fcn->ArgumentCount ) return -1; + for( i = Fcn->ArgumentCount; --i != ArgCount; ) + { + local_vars[i].Integer = 0; + local_vars[i].Type = Fcn->Arguments[i].Type; + } + for( ; i --; ) + { + GET_STACKVAL(local_vars[i]); + // TODO: Type checks / enforcing + } // Mark the start + memset(&val1, 0, sizeof(val1)); + val1.Type = ET_FUNCTION_START; + Bytecode_int_StackPush(Stack, &val1); // Execute! op = Fcn->Operations; while(op) { tBC_Op *nextop = op->Next; - switch(op->Type) + ast_op = 0; + switch(op->Operation) { + // Jumps case BC_OP_JUMP: - nextop = Fcn->Labels[op->StringInt.Integer]; + nextop = Fcn->Labels[ OP_INDX(op) ]; break; case BC_OP_JUMPIF: GET_STACKVAL(val1); if( Bytecode_int_IsStackEntTrue(&val1) ) - nextop = Fcn->Labels[op->StringInt.Integer]; + nextop = Fcn->Labels[op->Content.StringInt.Integer]; break; case BC_OP_JUMPIFNOT: GET_STACKVAL(val1); if( !Bytecode_int_IsStackEntTrue(&val1) ) - nextop = Fcn->Labels[op->StringInt.Integer]; + nextop = Fcn->Labels[op->Content.StringInt.Integer]; + break; + + // Define variables + case BC_OP_DEFINEVAR: { + int type, slot; + type = OP_INDX(op) & 0xFFFF; + slot = OP_INDX(op) >> 16; + if(slot < 0 || slot >= sizeof(local_vars)/sizeof(local_vars[0])) return -1; + memset(&local_vars[slot], 0, sizeof(local_vars[0])); + local_vars[slot].Type = type; + } break; + + // Operations + case BC_OP_ADD: + ast_op = NODETYPE_ADD; + case BC_OP_SUBTRACT: + if(!ast_op) ast_op = NODETYPE_SUBTRACT; + + GET_STACKVAL(val2); + GET_STACKVAL(val1); + pval1 = Bytecode_int_GetSpiderValue(&val1, &tmpVal1); + pval2 = Bytecode_int_GetSpiderValue(&val2, &tmpVal2); + ret_val = AST_ExecuteNode_BinOp(Script, NULL, ast_op, pval1, pval2); + if(pval1 != &tmpVal1) SpiderScript_DereferenceValue(pval1); + if(pval2 != &tmpVal2) SpiderScript_DereferenceValue(pval2); + Bytecode_int_SetSpiderValue(&val1, ret_val); + if(ret_val != &tmpVal1) SpiderScript_DereferenceValue(ret_val); break; + default: // TODO: break; @@ -96,4 +213,12 @@ int Bytecode_ExecuteFunction(tBC_Function *Fcn, tBC_Stack *Stack, int ArgCount); } // Clean up + // - Delete local vars + + + // - Restore stack + + + return 0; } + diff --git a/Usermode/Libraries/libspiderscript.so_src/parse.c b/Usermode/Libraries/libspiderscript.so_src/parse.c index 7ed079ea..503379d8 100644 --- a/Usermode/Libraries/libspiderscript.so_src/parse.c +++ b/Usermode/Libraries/libspiderscript.so_src/parse.c @@ -306,6 +306,7 @@ tAST_Node *Parse_DoBlockLine(tParser *Parser) csaTOKEN_NAMES[tok]); return NULL; } + if(ident) free(ident); } break; @@ -331,7 +332,7 @@ tAST_Node *Parse_DoBlockLine(tParser *Parser) case TOK_RWD_FOR: { - const char *tag = ""; + char *tag = NULL; tAST_Node *init=NULL, *cond=NULL, *inc=NULL, *code; GetToken(Parser); // Eat 'for' @@ -364,6 +365,7 @@ tAST_Node *Parse_DoBlockLine(tParser *Parser) code = Parse_DoCodeBlock(Parser); ret = AST_NewLoop(Parser, tag, init, 0, cond, inc, code); + if(tag) free(tag); } return ret; -- 2.20.1