IPStack - Firewall cleanups and speedups (now shoudl at least work)
[tpg/acess2.git] / Usermode / Libraries / libspiderscript.so_src / ast.c
index 0c7e2df..94d697c 100644 (file)
@@ -7,6 +7,9 @@
 #include <string.h>
 #include "ast.h"
 
+// === IMPORTS ===
+extern void    SyntaxError(tParser *Parser, int bFatal, const char *Message, ...);
+
 // === CODE ===
 tAST_Script *AST_NewScript(void)
 {
@@ -21,15 +24,18 @@ tAST_Script *AST_NewScript(void)
 /**
  * \brief Append a function to a script
  */
-tAST_Function *AST_AppendFunction(tAST_Script *Script, const char *Name)
+tAST_Function *AST_AppendFunction(tAST_Script *Script, const char *Name, int ReturnType)
 {
        tAST_Function   *ret;
        
        ret = malloc( sizeof(tAST_Function) + strlen(Name) + 1 );
+       if(!ret)        return NULL;
+       
        ret->Next = NULL;
        strcpy(ret->Name, Name);
        ret->Code = NULL;
        ret->Arguments = NULL;
+       ret->ReturnType = ReturnType;
        
        if(Script->LastFunction == NULL) {
                Script->Functions = Script->LastFunction = ret;
@@ -187,7 +193,7 @@ size_t AST_WriteNode(void *Buffer, size_t Offset, tAST_Node *Node)
        // Looping Construct (For loop node)
        case NODETYPE_LOOP:
                WRITE_8(Buffer, Offset, Node->For.bCheckAfter);
-               
+               WRITE_STR(Buffer, Offset, Node->For.Tag);
                Offset += AST_WriteNode(Buffer, Offset, Node->For.Init);
                Offset += AST_WriteNode(Buffer, Offset, Node->For.Condition);
                Offset += AST_WriteNode(Buffer, Offset, Node->For.Increment);
@@ -259,6 +265,8 @@ size_t AST_WriteNode(void *Buffer, size_t Offset, tAST_Node *Node)
                break;
        case NODETYPE_VARIABLE:
        case NODETYPE_CONSTANT:
+       case NODETYPE_BREAK:
+       case NODETYPE_CONTINUE:
                // TODO: De-Duplicate the strings
                WRITE_STR(Buffer, Offset, Node->Variable.Name);
                break;
@@ -290,6 +298,11 @@ void AST_FreeNode(tAST_Node *Node)
        
        if(!Node)       return ;
        
+       // Referenced counted file name
+       (*(int*)(Node->File - sizeof(int))) -= 1;
+       if( *(int*)(Node->File - sizeof(int)) == 0 )
+               free( (void*)(Node->File - sizeof(int)) );
+       
        switch(Node->Type)
        {
        // Block of code
@@ -391,6 +404,8 @@ void AST_FreeNode(tAST_Node *Node)
        case NODETYPE_NOP:      break;
        case NODETYPE_VARIABLE: break;
        case NODETYPE_CONSTANT: break;
+       case NODETYPE_BREAK:    break;
+       case NODETYPE_CONTINUE: break;
        
        case NODETYPE_STRING:
        case NODETYPE_INTEGER:
@@ -407,7 +422,7 @@ tAST_Node *AST_int_AllocateNode(tParser *Parser, int Type, int ExtraSize)
 {
        tAST_Node       *ret = malloc( sizeof(tAST_Node) + ExtraSize );
        ret->NextSibling = NULL;
-       ret->File = "<unk>";
+       ret->File = Parser->Filename;   *(int*)(Parser->Filename - sizeof(int)) += 1;
        ret->Line = Parser->CurLine;
        ret->Type = Type;
        
@@ -431,6 +446,9 @@ tAST_Node *AST_NewCodeBlock(tParser *Parser)
 
 void AST_AppendNode(tAST_Node *Parent, tAST_Node *Child)
 {
+       // Ignore NULL children
+       if( !Child )    return ;
+       
        Child->NextSibling = NULL;
        switch( Parent->Type )
        {
@@ -467,14 +485,15 @@ tAST_Node *AST_NewIf(tParser *Parser, tAST_Node *Condition, tAST_Node *True, tAS
        return ret;
 }
 
-tAST_Node *AST_NewLoop(tParser *Parser, tAST_Node *Init, int bPostCheck, tAST_Node *Condition, tAST_Node *Increment, tAST_Node *Code)
+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, 0);
+       tAST_Node       *ret = AST_int_AllocateNode(Parser, NODETYPE_LOOP, strlen(Tag) + 1);
        ret->For.Init = Init;
        ret->For.bCheckAfter = !!bPostCheck;
        ret->For.Condition = Condition;
        ret->For.Increment = Increment;
        ret->For.Code = Code;
+       strcpy(ret->For.Tag, Tag);
        return ret;
 }
 
@@ -482,6 +501,15 @@ 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 ) {
+               free(ret);
+               SyntaxError(Parser, 1, "Assign target is not a variable or attribute (instead %i)",
+                       Dest->Type);
+               AST_FreeNode(Dest);
+               AST_FreeNode(Value);
+               return NULL;
+       }
+       
        ret->Assign.Operation = Operation;
        ret->Assign.Dest = Dest;
        ret->Assign.Value = Value;
@@ -520,6 +548,19 @@ tAST_Node *AST_NewUniOp(tParser *Parser, int Operation, tAST_Node *Value)
        return ret;
 }
 
+tAST_Node *AST_NewBreakout(tParser *Parser, int Type, const char *DestTag)
+{
+        int    len = (DestTag ? strlen(DestTag) : 0);
+       tAST_Node       *ret = AST_int_AllocateNode(Parser, Type, len + 1);
+       
+       if( DestTag )
+               strcpy(ret->Variable.Name, DestTag);
+       else
+               ret->Variable.Name[0] = '\0';
+       
+       return ret;
+}
+
 tAST_Node *AST_NewNop(tParser *Parser)
 {
        tAST_Node       *ret = AST_int_AllocateNode(Parser, NODETYPE_NOP, 0);

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