SpiderScript - For loop, #if'd out experimental code
[tpg/acess2.git] / Usermode / Libraries / libspiderscript.so_src / ast.c
index 1a6c3e9..b662e32 100644 (file)
@@ -65,6 +65,260 @@ void AST_SetFunctionCode(tAST_Function *Function, tAST_Node *Root)
  * \name Node Manipulation
  * \{
  */
+/**
+ * \brief Get the in-memory size of a node
+ */
+size_t AST_GetNodeSize(tAST_Node *Node)
+{
+       size_t  ret;
+       tAST_Node       *node;
+       
+       if(!Node)
+               return 0;
+       
+       ret = sizeof(tAST_Node*) + sizeof(tAST_NodeType)
+               + sizeof(const char *) + sizeof(int);
+       
+       switch(Node->Type)
+       {
+       // Block of code
+       case NODETYPE_BLOCK:
+               ret += sizeof(Node->Block);
+               for( node = Node->Block.FirstChild; node; )
+               {
+                       ret += AST_GetNodeSize(node);
+                       node = node->NextSibling;
+               }
+               break;
+       
+       // Function Call
+       case NODETYPE_FUNCTIONCALL:
+               ret += sizeof(Node->FunctionCall) + strlen(Node->FunctionCall.Name) + 1;
+               for( node = Node->FunctionCall.FirstArg; node; )
+               {
+                       ret += AST_GetNodeSize(node);
+                       node = node->NextSibling;
+               }
+               break;
+       
+       // If node
+       case NODETYPE_IF:
+               ret += sizeof(Node->If);
+               ret += AST_GetNodeSize(Node->If.Condition);
+               ret += AST_GetNodeSize(Node->If.True);
+               ret += AST_GetNodeSize(Node->If.False);
+               break;
+       
+       // Looping Construct (For loop node)
+       case NODETYPE_LOOP:
+               ret += sizeof(Node->For);
+               ret += AST_GetNodeSize(Node->For.Init);
+               ret += AST_GetNodeSize(Node->For.Condition);
+               ret += AST_GetNodeSize(Node->For.Increment);
+               ret += AST_GetNodeSize(Node->For.Code);
+               break;
+       
+       // Asignment
+       case NODETYPE_ASSIGN:
+               ret += sizeof(Node->Assign);
+               ret += AST_GetNodeSize(Node->Assign.Dest);
+               ret += AST_GetNodeSize(Node->Assign.Value);
+               break;
+       
+       // Casting
+       case NODETYPE_CAST:
+               ret += sizeof(Node->Cast);
+               ret += AST_GetNodeSize(Node->Cast.Value);
+               break;
+       
+       // Define a variable
+       case NODETYPE_DEFVAR:
+               ret += sizeof(Node->DefVar) + strlen(Node->DefVar.Name) + 1;
+               for( node = Node->DefVar.LevelSizes; node; )
+               {
+                       ret += AST_GetNodeSize(node);
+                       node = node->NextSibling;
+               }
+               break;
+       
+       // Unary Operations
+       case NODETYPE_RETURN:
+               ret += sizeof(Node->UniOp);
+               ret += AST_GetNodeSize(Node->UniOp.Value);
+               break;
+       
+       // Binary Operations
+       case NODETYPE_INDEX:
+       case NODETYPE_ADD:
+       case NODETYPE_SUBTRACT:
+       case NODETYPE_MULTIPLY:
+       case NODETYPE_DIVIDE:
+       case NODETYPE_MODULO:
+       case NODETYPE_BITSHIFTLEFT:
+       case NODETYPE_BITSHIFTRIGHT:
+       case NODETYPE_BITROTATELEFT:
+       case NODETYPE_BWAND:    case NODETYPE_LOGICALAND:
+       case NODETYPE_BWOR:     case NODETYPE_LOGICALOR:
+       case NODETYPE_BWXOR:    case NODETYPE_LOGICALXOR:
+       case NODETYPE_EQUALS:
+       case NODETYPE_LESSTHAN:
+       case NODETYPE_GREATERTHAN:
+               ret += sizeof(Node->BinOp);
+               ret += AST_GetNodeSize( Node->BinOp.Left );
+               ret += AST_GetNodeSize( Node->BinOp.Right );
+               break;
+       
+       // Node types with no children
+       case NODETYPE_NOP:
+               break;
+       case NODETYPE_VARIABLE:
+       case NODETYPE_CONSTANT:
+               ret += sizeof(Node->Variable) + strlen(Node->Variable.Name) + 1;
+               break;
+       case NODETYPE_STRING:
+               ret += sizeof(Node->String) + Node->String.Length;
+               break;
+       case NODETYPE_INTEGER:
+               ret += sizeof(Node->Integer);
+               break;
+       case NODETYPE_REAL:
+               ret += sizeof(Node->Real);
+               break;
+       }
+       return ret;
+}
+
+#if 0
+/**
+ * \brief Write a node to a file
+ */
+void AST_WriteNode(FILE *FP, tAST_Node *Node)
+{
+       tAST_Node       *node;
+       intptr_t        ptr;
+        int    ret;
+       
+       if(!Node)       return ;
+       
+       ptr = ftell(FP) + AST_GetNodeSize(Node);
+       fwrite(&ptr, sizeof(ptr), 1, FP);
+       fwrite(&Node->Type, sizeof(Node->Type), 1, FP);
+       ptr = 0;        fwrite(&ptr, sizeof(ptr), 1, FP);       // File
+       fwrite(&Node->Line, sizeof(Node->Line), 1, FP);
+       
+       ret = sizeof(tAST_Node*) + sizeof(tAST_NodeType)
+               + sizeof(const char *) + sizeof(int);
+       
+       switch(Node->Type)
+       {
+       // Block of code
+       case NODETYPE_BLOCK:
+               ret += sizeof(Node->Block);
+               for( node = Node->Block.FirstChild; node; )
+               {
+                       ret += AST_GetNodeSize(node);
+                       node = node->NextSibling;
+               }
+               break;
+       
+       // Function Call
+       case NODETYPE_FUNCTIONCALL:
+               ret += sizeof(Node->FunctionCall) + strlen(Node->FunctionCall.Name) + 1;
+               for( node = Node->FunctionCall.FirstArg; node; )
+               {
+                       ret += AST_GetNodeSize(node);
+                       node = node->NextSibling;
+               }
+               break;
+       
+       // If node
+       case NODETYPE_IF:
+               ret += sizeof(Node->If);
+               ret += AST_GetNodeSize(Node->If.Condition);
+               ret += AST_GetNodeSize(Node->If.True);
+               ret += AST_GetNodeSize(Node->If.False);
+               break;
+       
+       // Looping Construct (For loop node)
+       case NODETYPE_LOOP:
+               ret += sizeof(Node->For);
+               ret += AST_GetNodeSize(Node->For.Init);
+               ret += AST_GetNodeSize(Node->For.Condition);
+               ret += AST_GetNodeSize(Node->For.Increment);
+               ret += AST_GetNodeSize(Node->For.Code);
+               break;
+       
+       // Asignment
+       case NODETYPE_ASSIGN:
+               ret += sizeof(Node->Assign);
+               ret += AST_GetNodeSize(Node->Assign.Dest);
+               ret += AST_GetNodeSize(Node->Assign.Value);
+               break;
+       
+       // Casting
+       case NODETYPE_CAST:
+               ret += sizeof(Node->Cast);
+               ret += AST_GetNodeSize(Node->Cast.Value);
+               break;
+       
+       // Define a variable
+       case NODETYPE_DEFVAR:
+               ret += sizeof(Node->DefVar) + strlen(Node->DefVar.Name) + 1;
+               for( node = Node->DefVar.LevelSizes; node; )
+               {
+                       ret += AST_GetNodeSize(node);
+                       node = node->NextSibling;
+               }
+               break;
+       
+       // Unary Operations
+       case NODETYPE_RETURN:
+               ret += sizeof(Node->UniOp);
+               ret += AST_GetNodeSize(Node->UniOp.Value);
+               break;
+       
+       // Binary Operations
+       case NODETYPE_INDEX:
+       case NODETYPE_ADD:
+       case NODETYPE_SUBTRACT:
+       case NODETYPE_MULTIPLY:
+       case NODETYPE_DIVIDE:
+       case NODETYPE_MODULO:
+       case NODETYPE_BITSHIFTLEFT:
+       case NODETYPE_BITSHIFTRIGHT:
+       case NODETYPE_BITROTATELEFT:
+       case NODETYPE_BWAND:    case NODETYPE_LOGICALAND:
+       case NODETYPE_BWOR:     case NODETYPE_LOGICALOR:
+       case NODETYPE_BWXOR:    case NODETYPE_LOGICALXOR:
+       case NODETYPE_EQUALS:
+       case NODETYPE_LESSTHAN:
+       case NODETYPE_GREATERTHAN:
+               ret += sizeof(Node->BinOp);
+               ret += AST_GetNodeSize( Node->BinOp.Left );
+               ret += AST_GetNodeSize( Node->BinOp.Right );
+               break;
+       
+       // Node types with no children
+       case NODETYPE_NOP:
+               break;
+       case NODETYPE_VARIABLE:
+       case NODETYPE_CONSTANT:
+               ret += sizeof(Node->Variable) + strlen(Node->Variable.Name) + 1;
+               break;
+       case NODETYPE_STRING:
+               ret += sizeof(Node->String) + Node->String.Length;
+               break;
+       case NODETYPE_INTEGER:
+               ret += sizeof(Node->Integer);
+               break;
+       case NODETYPE_REAL:
+               ret += sizeof(Node->Real);
+               break;
+       }
+       return ret;
+}
+#endif
+
 /**
  * \brief Free a node and all subnodes
  */
@@ -173,7 +427,7 @@ tAST_Node *AST_NewCodeBlock(void)
        tAST_Node       *ret = malloc( sizeof(tAST_Node) );
        
        ret->NextSibling = NULL;
-       //ret->Line = giLineNumber;
+       //ret->Line = Parser->CurLine;
        ret->Type = NODETYPE_BLOCK;
        ret->Block.FirstChild = NULL;
        ret->Block.LastChild = NULL;
@@ -210,11 +464,11 @@ void AST_AppendNode(tAST_Node *Parent, tAST_Node *Child)
        }
 }
 
-tAST_Node *AST_NewIf(tAST_Node *Condition, tAST_Node *True, tAST_Node *False)
+tAST_Node *AST_NewIf(tParser *Parser, tAST_Node *Condition, tAST_Node *True, tAST_Node *False)
 {
        tAST_Node       *ret = malloc( sizeof(tAST_Node) );
        ret->NextSibling = NULL;
-       //ret->Line = giLineNumber;
+       ret->Line = Parser->CurLine;
        ret->Type = NODETYPE_IF;
        ret->If.Condition = Condition;
        ret->If.True = True;
@@ -222,11 +476,11 @@ tAST_Node *AST_NewIf(tAST_Node *Condition, tAST_Node *True, tAST_Node *False)
        return ret;
 }
 
-tAST_Node *AST_NewLoop(tAST_Node *Init, int bPostCheck, tAST_Node *Condition, tAST_Node *Increment, tAST_Node *Code)
+tAST_Node *AST_NewLoop(tParser *Parser, tAST_Node *Init, int bPostCheck, tAST_Node *Condition, tAST_Node *Increment, tAST_Node *Code)
 {
        tAST_Node       *ret = malloc( sizeof(tAST_Node) );
        ret->NextSibling = NULL;
-       //ret->Line = giLineNumber;
+       ret->Line = Parser->CurLine;
        ret->Type = NODETYPE_LOOP;
        ret->For.Init = Init;
        ret->For.bCheckAfter = !!bPostCheck;
@@ -236,12 +490,12 @@ tAST_Node *AST_NewLoop(tAST_Node *Init, int bPostCheck, tAST_Node *Condition, tA
        return ret;
 }
 
-tAST_Node *AST_NewAssign(int Operation, tAST_Node *Dest, tAST_Node *Value)
+tAST_Node *AST_NewAssign(tParser *Parser, int Operation, tAST_Node *Dest, tAST_Node *Value)
 {
        tAST_Node       *ret = malloc( sizeof(tAST_Node) );
        
        ret->NextSibling = NULL;
-       //ret->Line = giLineNumber;
+       ret->Line = Parser->CurLine;
        ret->Type = NODETYPE_ASSIGN;
        ret->Assign.Operation = Operation;
        ret->Assign.Dest = Dest;
@@ -250,12 +504,12 @@ tAST_Node *AST_NewAssign(int Operation, tAST_Node *Dest, tAST_Node *Value)
        return ret;
 }
 
-tAST_Node *AST_NewCast(int Target, tAST_Node *Value)
+tAST_Node *AST_NewCast(tParser *Parser, int Target, tAST_Node *Value)
 {
        tAST_Node       *ret = malloc( sizeof(tAST_Node) );
        
        ret->NextSibling = NULL;
-       //ret->Line = giLineNumber;
+       ret->Line = Parser->CurLine;
        ret->Type = NODETYPE_CAST;
        ret->Cast.DataType = Target;
        ret->Cast.Value = Value;
@@ -263,12 +517,12 @@ tAST_Node *AST_NewCast(int Target, tAST_Node *Value)
        return ret;
 }
 
-tAST_Node *AST_NewBinOp(int Operation, tAST_Node *Left, tAST_Node *Right)
+tAST_Node *AST_NewBinOp(tParser *Parser, int Operation, tAST_Node *Left, tAST_Node *Right)
 {
        tAST_Node       *ret = malloc( sizeof(tAST_Node) );
        
        ret->NextSibling = NULL;
-       //ret->Line = giLineNumber;
+       ret->Line = Parser->CurLine;
        ret->Type = Operation;
        ret->BinOp.Left = Left;
        ret->BinOp.Right = Right;
@@ -278,12 +532,12 @@ tAST_Node *AST_NewBinOp(int Operation, tAST_Node *Left, tAST_Node *Right)
 
 /**
  */
-tAST_Node *AST_NewUniOp(int Operation, tAST_Node *Value)
+tAST_Node *AST_NewUniOp(tParser *Parser, int Operation, tAST_Node *Value)
 {
        tAST_Node       *ret = malloc( sizeof(tAST_Node) );
        
        ret->NextSibling = NULL;
-       //ret->Line = giLineNumber;
+       ret->Line = Parser->CurLine;
        ret->Type = Operation;
        ret->UniOp.Value = Value;
        
@@ -293,12 +547,12 @@ tAST_Node *AST_NewUniOp(int Operation, tAST_Node *Value)
 /**
  * \brief Create a new string node
  */
-tAST_Node *AST_NewString(const char *String, int Length)
+tAST_Node *AST_NewString(tParser *Parser, const char *String, int Length)
 {
        tAST_Node       *ret = malloc( sizeof(tAST_Node) + Length + 1 );
        
        ret->NextSibling = NULL;
-       //ret->Line = giLineNumber;
+       ret->Line = Parser->CurLine;
        ret->Type = NODETYPE_STRING;
        ret->String.Length = Length;
        memcpy(ret->String.Data, String, Length);
@@ -310,11 +564,11 @@ tAST_Node *AST_NewString(const char *String, int Length)
 /**
  * \brief Create a new integer node
  */
-tAST_Node *AST_NewInteger(uint64_t Value)
+tAST_Node *AST_NewInteger(tParser *Parser, uint64_t Value)
 {
        tAST_Node       *ret = malloc( sizeof(tAST_Node) );
        ret->NextSibling = NULL;
-       //ret->Line = giLineNumber;
+       ret->Line = Parser->CurLine;
        ret->Type = NODETYPE_INTEGER;
        ret->Integer = Value;
        return ret;
@@ -323,11 +577,11 @@ tAST_Node *AST_NewInteger(uint64_t Value)
 /**
  * \brief Create a new variable reference node
  */
-tAST_Node *AST_NewVariable(const char *Name)
+tAST_Node *AST_NewVariable(tParser *Parser, const char *Name)
 {
        tAST_Node       *ret = malloc( sizeof(tAST_Node) + strlen(Name) + 1 );
        ret->NextSibling = NULL;
-       //ret->Line = giLineNumber;
+       ret->Line = Parser->CurLine;
        ret->Type = NODETYPE_VARIABLE;
        strcpy(ret->Variable.Name, Name);
        return ret;
@@ -336,11 +590,11 @@ tAST_Node *AST_NewVariable(const char *Name)
 /**
  * \brief Create a new variable definition node
  */
-tAST_Node *AST_NewDefineVar(int Type, const char *Name)
+tAST_Node *AST_NewDefineVar(tParser *Parser, int Type, const char *Name)
 {
        tAST_Node       *ret = malloc( sizeof(tAST_Node) + strlen(Name) + 1 );
        ret->NextSibling = NULL;
-       //ret->Line = giLineNumber;
+       ret->Line = Parser->CurLine;
        ret->Type = NODETYPE_DEFVAR;
        ret->DefVar.DataType = Type;
        ret->DefVar.LevelSizes = NULL;
@@ -351,11 +605,11 @@ tAST_Node *AST_NewDefineVar(int Type, const char *Name)
 /**
  * \brief Create a new runtime constant reference node
  */
-tAST_Node *AST_NewConstant(const char *Name)
+tAST_Node *AST_NewConstant(tParser *Parser, const char *Name)
 {
        tAST_Node       *ret = malloc( sizeof(tAST_Node) + strlen(Name) + 1 );
        ret->NextSibling = NULL;
-       //ret->Line = giLineNumber;
+       ret->Line = Parser->CurLine;
        ret->Type = NODETYPE_CONSTANT;
        strcpy(ret->Variable.Name, Name);
        return ret;
@@ -365,12 +619,12 @@ tAST_Node *AST_NewConstant(const char *Name)
  * \brief Create a function call node
  * \note Argument list is manipulated using AST_AppendFunctionCallArg
  */
-tAST_Node *AST_NewFunctionCall(const char *Name)
+tAST_Node *AST_NewFunctionCall(tParser *Parser, const char *Name)
 {
        tAST_Node       *ret = malloc( sizeof(tAST_Node) + strlen(Name) + 1 );
        
        ret->NextSibling = NULL;
-       //ret->Line = giLineNumber;
+       ret->Line = Parser->CurLine;
        ret->Type = NODETYPE_FUNCTIONCALL;
        ret->FunctionCall.FirstArg = NULL;
        ret->FunctionCall.LastArg = NULL;

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