SpiderScript - More changes, cleaning up
authorJohn Hodge <[email protected]>
Sat, 17 Sep 2011 14:57:15 +0000 (22:57 +0800)
committerJohn Hodge <[email protected]>
Sat, 17 Sep 2011 14:57:15 +0000 (22:57 +0800)
- Bytecode still doesn't run, but getting there
- Fixed some memory leaks about the place

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.h
Usermode/Libraries/libspiderscript.so_src/bytecode_gen.c
Usermode/Libraries/libspiderscript.so_src/bytecode_gen.h
Usermode/Libraries/libspiderscript.so_src/bytecode_makefile.c
Usermode/Libraries/libspiderscript.so_src/exec_ast.c
Usermode/Libraries/libspiderscript.so_src/exec_bytecode.c
Usermode/Libraries/libspiderscript.so_src/parse.c

index ce04195..bafdd12 100644 (file)
@@ -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;
index aa44862..39c23b1 100644 (file)
@@ -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
index 5cffd79..7afd0c0 100644 (file)
@@ -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;
index bff4cae..045f896 100644 (file)
@@ -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
index 8ae7f32..078f2df 100644 (file)
 #include <stdio.h>
 #include "bytecode_gen.h"
 #include <string.h>
+#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))
 }
index b2f19cf..19d240c 100644 (file)
@@ -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;
index a4c9b71..033f8d7 100644 (file)
@@ -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;
 }
 
index 0c1a402..be2c1c5 100644 (file)
@@ -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)
index b938424..a88670c 100644 (file)
@@ -6,28 +6,30 @@
  * - Generate a bytecode file
  */
 #include <stdlib.h>
-#include "bytecode_ops.h"
+#include <stdint.h>
+#include <spiderscript.h>
+#include "bytecode.h"
+#include <string.h>
+#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;
 }
+
index 7ed079e..503379d 100644 (file)
@@ -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;
        

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