X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=Usermode%2FLibraries%2Flibspiderscript.so_src%2Fast.c;h=b662e320ffbcfd7155bf739d17f121dfb4add4b2;hb=3ac178949c57e5cbd0cfe59915da9840ecefa68e;hp=8df5469734d85612198caba4536746d72a9ee37f;hpb=ec6f426069129f0a3d207f743ecddceddb57db8e;p=tpg%2Facess2.git diff --git a/Usermode/Libraries/libspiderscript.so_src/ast.c b/Usermode/Libraries/libspiderscript.so_src/ast.c index 8df54697..b662e320 100644 --- a/Usermode/Libraries/libspiderscript.so_src/ast.c +++ b/Usermode/Libraries/libspiderscript.so_src/ast.c @@ -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,6 +427,7 @@ tAST_Node *AST_NewCodeBlock(void) tAST_Node *ret = malloc( sizeof(tAST_Node) ); ret->NextSibling = NULL; + //ret->Line = Parser->CurLine; ret->Type = NODETYPE_BLOCK; ret->Block.FirstChild = NULL; ret->Block.LastChild = NULL; @@ -209,10 +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 = Parser->CurLine; ret->Type = NODETYPE_IF; ret->If.Condition = Condition; ret->If.True = True; @@ -220,10 +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 = Parser->CurLine; ret->Type = NODETYPE_LOOP; ret->For.Init = Init; ret->For.bCheckAfter = !!bPostCheck; @@ -233,11 +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 = Parser->CurLine; ret->Type = NODETYPE_ASSIGN; ret->Assign.Operation = Operation; ret->Assign.Dest = Dest; @@ -246,11 +504,25 @@ tAST_Node *AST_NewAssign(int Operation, tAST_Node *Dest, tAST_Node *Value) return ret; } -tAST_Node *AST_NewBinOp(int Operation, tAST_Node *Left, tAST_Node *Right) +tAST_Node *AST_NewCast(tParser *Parser, int Target, tAST_Node *Value) +{ + tAST_Node *ret = malloc( sizeof(tAST_Node) ); + + ret->NextSibling = NULL; + ret->Line = Parser->CurLine; + ret->Type = NODETYPE_CAST; + ret->Cast.DataType = Target; + ret->Cast.Value = Value; + + return ret; +} + +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 = Parser->CurLine; ret->Type = Operation; ret->BinOp.Left = Left; ret->BinOp.Right = Right; @@ -260,11 +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 = Parser->CurLine; ret->Type = Operation; ret->UniOp.Value = Value; @@ -274,11 +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 = Parser->CurLine; ret->Type = NODETYPE_STRING; ret->String.Length = Length; memcpy(ret->String.Data, String, Length); @@ -290,10 +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 = Parser->CurLine; ret->Type = NODETYPE_INTEGER; ret->Integer = Value; return ret; @@ -302,10 +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 = Parser->CurLine; ret->Type = NODETYPE_VARIABLE; strcpy(ret->Variable.Name, Name); return ret; @@ -314,10 +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 = Parser->CurLine; ret->Type = NODETYPE_DEFVAR; ret->DefVar.DataType = Type; ret->DefVar.LevelSizes = NULL; @@ -328,10 +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 = Parser->CurLine; ret->Type = NODETYPE_CONSTANT; strcpy(ret->Variable.Name, Name); return ret; @@ -341,11 +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 = Parser->CurLine; ret->Type = NODETYPE_FUNCTIONCALL; ret->FunctionCall.FirstArg = NULL; ret->FunctionCall.LastArg = NULL;