X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=Usermode%2FLibraries%2Flibspiderscript.so_src%2Fast.c;h=94d697cce55b547ef235531e4144a52efea3f519;hb=c967d91a4794ec9c0ec7dab438c033f4c0b49952;hp=1ea7e3e5ad9a5a4f8718aafef547b755e15909e3;hpb=0f81e4f273cdf1032e9bca55b4185ca9113596cc;p=tpg%2Facess2.git diff --git a/Usermode/Libraries/libspiderscript.so_src/ast.c b/Usermode/Libraries/libspiderscript.so_src/ast.c index 1ea7e3e5..94d697cc 100644 --- a/Usermode/Libraries/libspiderscript.so_src/ast.c +++ b/Usermode/Libraries/libspiderscript.so_src/ast.c @@ -7,6 +7,9 @@ #include #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; @@ -121,6 +127,7 @@ size_t AST_WriteScript(void *Buffer, tAST_Script *Script) for( fcn = Script->Functions; fcn; fcn = fcn->Next ) { +// printf("fcn = %p, fcn->Name = %p\n", fcn, fcn->Name); ptr = ret; WRITE_32(Buffer, ret, 0); // Next WRITE_STR(Buffer, ret, fcn->Name); @@ -145,7 +152,10 @@ size_t AST_WriteNode(void *Buffer, size_t Offset, tAST_Node *Node) size_t baseOfs = Offset; if(!Node) { - fprintf(stderr, "Possible Bug - NULL passed to AST_WriteNode\n"); + //fprintf(stderr, "Possible Bug - NULL passed to AST_WriteNode\n"); + WRITE_32(Buffer, Offset, 0); + WRITE_16(Buffer, Offset, NODETYPE_NOP); + WRITE_16(Buffer, Offset, 0); // Line (0) return 0; } @@ -183,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); @@ -210,6 +220,7 @@ size_t AST_WriteNode(void *Buffer, size_t Offset, tAST_Node *Node) WRITE_STR(Buffer, Offset, Node->DefVar.Name); WRITE_NODELIST(Buffer, Offset, Node->DefVar.LevelSizes); + Offset += AST_WriteNode(Buffer, Offset, Node->DefVar.InitialValue); break; // Scope Reference @@ -254,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; @@ -285,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 @@ -349,6 +367,7 @@ void AST_FreeNode(tAST_Node *Node) AST_FreeNode(node); node = savedNext; } + AST_FreeNode(Node->DefVar.InitialValue); break; // Unary Operations @@ -385,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: @@ -401,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 = ""; + ret->File = Parser->Filename; *(int*)(Parser->Filename - sizeof(int)) += 1; ret->Line = Parser->CurLine; ret->Type = Type; @@ -425,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 ) { @@ -461,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; } @@ -476,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; @@ -514,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); @@ -580,6 +627,8 @@ tAST_Node *AST_NewDefineVar(tParser *Parser, int Type, const char *Name) ret->DefVar.DataType = Type; ret->DefVar.LevelSizes = NULL; + ret->DefVar.LevelSizes_Last = NULL; + ret->DefVar.InitialValue = NULL; strcpy(ret->DefVar.Name, Name); return ret;