SpiderScript - Moved header to directory, ready to remove from tree
[tpg/acess2.git] / Usermode / Libraries / libspiderscript.so_src / ast_to_bytecode.c
index 66437bc..c45e7a5 100644 (file)
@@ -47,6 +47,7 @@ typedef struct sAST_BlockInfo
  int   BC_Variable_Define(tAST_BlockInfo *Block, int Type, const char *Name);
  int   BC_Variable_SetValue(tAST_BlockInfo *Block, tAST_Node *VarNode);
  int   BC_Variable_GetValue(tAST_BlockInfo *Block, tAST_Node *VarNode);
+void   BC_Variable_Clear(tAST_BlockInfo *Block);
 // - Errors
 void   AST_RuntimeMessage(tAST_Node *Node, const char *Type, const char *Format, ...);
 void   AST_RuntimeError(tAST_Node *Node, const char *Format, ...);
@@ -76,6 +77,7 @@ tBC_Function *Bytecode_ConvertFunction(tScript_Function *Fcn)
 {
        tBC_Function    *ret;
        tAST_BlockInfo bi = {0};
+        int    i;
 
        // TODO: Return BCFcn instead?
        if(Fcn->BCFcn)  return Fcn->BCFcn;
@@ -84,12 +86,22 @@ tBC_Function *Bytecode_ConvertFunction(tScript_Function *Fcn)
        if(!ret)        return NULL;
        
        bi.Handle = ret;
+       
+       // Parse arguments
+       for( i = 0; i < Fcn->ArgumentCount; i ++ )
+       {
+               BC_Variable_Define(&bi, Fcn->Arguments[i].Type, Fcn->Arguments[i].Name);
+       }
+
        if( AST_ConvertNode(&bi, Fcn->ASTFcn, 0) )
        {
                AST_RuntimeError(Fcn->ASTFcn, "Error in converting function");
                Bytecode_DeleteFunction(ret);
+               BC_Variable_Clear(&bi);
                return NULL;
        }
+       BC_Variable_Clear(&bi);
+
 
        Bytecode_AppendConstInt(ret, 0);        // TODO: NULL
        Bytecode_AppendReturn(ret);
@@ -136,12 +148,15 @@ int AST_ConvertNode(tAST_BlockInfo *Block, tAST_Node *Node, int bKeepValue)
                                node;
                                node = node->NextSibling )
                        {
-                               ret = AST_ConvertNode(Block, node, 0);
+                               ret = AST_ConvertNode(&blockInfo, node, 0);
                                if(ret) return ret;
                                if( blockInfo.StackDepth != 0 ) {
                                        AST_RuntimeError(node, "Stack not reset at end of node");
+                                       blockInfo.StackDepth = 0;
                                }
                        }
+                       
+                       BC_Variable_Clear(&blockInfo);
                }
                Bytecode_AppendLeaveContext(Block->Handle);     // Leave this context
                break;
@@ -275,16 +290,18 @@ int AST_ConvertNode(tAST_BlockInfo *Block, tAST_Node *Node, int bKeepValue)
                for( i = 0; i < Block->NamespaceDepth; i ++ )
                        newnamelen += strlen(Block->CurNamespaceStack[i]) + 1;
                newnamelen += strlen(Node->FunctionCall.Name) + 1;
+//             newnamelen += 1;
+               
                manglename = alloca(newnamelen);
-               manglename[0] = 0;
+               newnamelen = 0;
                for( i = 0; i < Block->NamespaceDepth; i ++ ) {
-                        int    pos;
-                       strcat(manglename, Block->CurNamespaceStack[i]);
-                       pos = strlen(manglename);
-                       manglename[pos] = BC_NS_SEPARATOR;
-                       manglename[pos+1] = '\0';
+                       strcpy(manglename+newnamelen, Block->CurNamespaceStack[i]);
+                       newnamelen += strlen(Block->CurNamespaceStack[i]) + 1;
+                       manglename[ newnamelen - 1 ] = BC_NS_SEPARATOR;
                }
-               strcat(manglename, Node->FunctionCall.Name);
+               strcpy(manglename + newnamelen, Node->FunctionCall.Name);
+               newnamelen += strlen(Node->FunctionCall.Name) + 1;
+//             manglename[ newnamelen ] = '\0';        // Zero length terminator
                Block->NamespaceDepth = 0;
 
                // Push arguments to the stack
@@ -356,7 +373,7 @@ int AST_ConvertNode(tAST_BlockInfo *Block, tAST_Node *Node, int bKeepValue)
        
        // Loop
        case NODETYPE_LOOP: {
-                int    loop_start, loop_end;
+                int    loop_start, loop_end, code_end;
                 int    saved_break, saved_continue;
                const char      *saved_tag;
 
@@ -365,13 +382,14 @@ int AST_ConvertNode(tAST_BlockInfo *Block, tAST_Node *Node, int bKeepValue)
                if(ret) return ret;
                
                loop_start = Bytecode_AllocateLabel(Block->Handle);
+               code_end = Bytecode_AllocateLabel(Block->Handle);
                loop_end = Bytecode_AllocateLabel(Block->Handle);
 
                saved_break = Block->BreakTarget;
                saved_continue = Block->ContinueTarget;
                saved_tag = Block->Tag;
                Block->BreakTarget = loop_end;
-               Block->ContinueTarget = loop_end;
+               Block->ContinueTarget = code_end;
                Block->Tag = Node->For.Tag;
 
                Bytecode_SetLabel(Block->Handle, loop_start);
@@ -390,7 +408,9 @@ int AST_ConvertNode(tAST_BlockInfo *Block, tAST_Node *Node, int bKeepValue)
                // Code
                ret = AST_ConvertNode(Block, Node->For.Code, 0);
                if(ret) return ret;
-               
+
+               Bytecode_SetLabel(Block->Handle, code_end);
+       
                // Increment
                ret = AST_ConvertNode(Block, Node->For.Increment, 0);
                if(ret) return ret;
@@ -431,7 +451,12 @@ int AST_ConvertNode(tAST_BlockInfo *Block, tAST_Node *Node, int bKeepValue)
        case NODETYPE_CONTINUE: {
                tAST_BlockInfo  *bi = Block;
                if( Node->Variable.Name[0] ) {
-                       while(bi && strcmp(bi->Tag, Node->Variable.Name) == 0)  bi = bi->Parent;
+                       while(bi && (!bi->Tag || strcmp(bi->Tag, Node->Variable.Name) != 0))
+                               bi = bi->Parent;
+               }
+               else {
+                       while(bi && !bi->Tag)
+                               bi = bi->Parent;
                }
                if( !bi )       return 1;
                // TODO: Check if BreakTarget/ContinueTarget are valid
@@ -484,10 +509,13 @@ int AST_ConvertNode(tAST_BlockInfo *Block, tAST_Node *Node, int bKeepValue)
                ret = AST_ConvertNode( Block, Node->Scope.Element, 1 );
                if(ret) return ret;
 
+               // TODO: Support elements for non-objects
                ret = _StackPop(Block, Node, SS_DATATYPE_OBJECT);
                if(ret < 0)     return -1;
 
                Bytecode_AppendElement(Block->Handle, Node->Scope.Name);
+               
+               // TODO: Somehow know this at compile time?
                ret = _StackPush(Block, Node, SS_DATATYPE_UNDEF);
                if(ret < 0)     return -1;
                CHECK_IF_NEEDED(1);
@@ -514,7 +542,7 @@ int AST_ConvertNode(tAST_BlockInfo *Block, tAST_Node *Node, int bKeepValue)
                //  > Type check
                ret = _StackPop(Block, Node, SS_DATATYPE_UNDEF);
                if(ret < 0)     return -1;
-               if(ret != SS_DATATYPE_ARRAY && (ret >> 16) == 0) {
+               if(ret != SS_DATATYPE_ARRAY && SS_GETARRAYDEPTH(ret) == 0) {
                        AST_RuntimeError(Node, "Type mismatch, Expected an array, got %i",
                                ret);
                        return -2;
@@ -531,7 +559,7 @@ int AST_ConvertNode(tAST_BlockInfo *Block, tAST_Node *Node, int bKeepValue)
                
                // Update the array depth
                if( i != SS_DATATYPE_ARRAY ) {
-                       i -= 0x10000;   // Decrease the array level
+                       i = SS_DOWNARRAY(i);    // Decrease the array level
                }
                ret = _StackPush(Block, Node, i);
                if(ret < 0)     return -1;
@@ -544,8 +572,7 @@ int AST_ConvertNode(tAST_BlockInfo *Block, tAST_Node *Node, int bKeepValue)
                // TODO: Scan namespace for constant name
                AST_RuntimeError(Node, "TODO - Runtime Constants");
                Block->NamespaceDepth = 0;
-               ret = -1;
-               break;
+               return -1;
        
        // Constant Values
        case NODETYPE_STRING:
@@ -566,7 +593,13 @@ int AST_ConvertNode(tAST_BlockInfo *Block, tAST_Node *Node, int bKeepValue)
                if(ret < 0)     return -1;
                CHECK_IF_NEEDED(1);
                break;
-       
+       case NODETYPE_NULL:
+               Bytecode_AppendConstNull(Block->Handle);
+               ret = _StackPush(Block, Node, SS_DATATYPE_UNDEF);
+               if(ret < 0)     return -1;
+               CHECK_IF_NEEDED(1);
+               break;
+
        // --- Operations ---
        // Boolean Operations
        case NODETYPE_LOGICALNOT:       // Logical NOT (!)
@@ -635,12 +668,13 @@ int AST_ConvertNode(tAST_BlockInfo *Block, tAST_Node *Node, int bKeepValue)
 
 int BC_SaveValue(tAST_BlockInfo *Block, tAST_Node *DestNode)
 {
-        int    ret;
+        int    ret, type;
        switch(DestNode->Type)
        {
        // Variable, simple
        case NODETYPE_VARIABLE:
                ret = BC_Variable_SetValue( Block, DestNode );
+               if(ret) return ret;
                break;
        // Array index
        case NODETYPE_INDEX:
@@ -648,11 +682,12 @@ int BC_SaveValue(tAST_BlockInfo *Block, tAST_Node *DestNode)
                if(ret) return ret;
                ret = _StackPop(Block, DestNode->BinOp.Left, SS_DATATYPE_UNDEF);
                if(ret < 0)     return -1;
-               if(ret != SS_DATATYPE_ARRAY && (ret >> 16) == 0) {
+               if(ret != SS_DATATYPE_ARRAY && SS_GETARRAYDEPTH(ret) == 0) {
                        AST_RuntimeError(DestNode, "Type mismatch, Expected an array, got %i",
                                ret);
                        return -2;
                }
+               type = SS_DOWNARRAY(ret);
                
                ret = AST_ConvertNode(Block, DestNode->BinOp.Right, 1); // Offset
                if(ret) return ret;
@@ -660,6 +695,7 @@ int BC_SaveValue(tAST_BlockInfo *Block, tAST_Node *DestNode)
                if(ret < 0)     return -1;
                
                Bytecode_AppendSetIndex( Block->Handle );
+               _StackPop(Block, DestNode, type);
                break;
        // Object element
        case NODETYPE_ELEMENT:
@@ -724,7 +760,7 @@ tAST_Variable *BC_Variable_Lookup(tAST_BlockInfo *Block, tAST_Node *VarNode, int
                }
                if(var) break;
        }
-       
+
        if( !var )
        {
 //             if( Block->Script->Variant->bDyamicTyped && CreateType != SS_DATATYPE_UNDEF ) {
@@ -780,6 +816,18 @@ int BC_Variable_GetValue(tAST_BlockInfo *Block, tAST_Node *VarNode)
        return 0;
 }
 
+void BC_Variable_Clear(tAST_BlockInfo *Block)
+{
+       tAST_Variable   *var;
+       for( var = Block->FirstVar; var; )
+       {
+               tAST_Variable   *tv = var->Next;
+               free( var );
+               var = tv;
+       }
+       Block->FirstVar = NULL;
+}
+
 #if 0
 void AST_RuntimeMessage(tAST_Node *Node, const char *Type, const char *Format, ...)
 {

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