X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=Usermode%2FLibraries%2Flibspiderscript.so_src%2Fparse.c;h=e6d9694227adea7a43606fdef8535a8ae0d89fd2;hb=c43c05ef3234d6118ce601d299df60383d54ac7b;hp=7ed079ea772b5c4ce2286d3929bd992cd8765c98;hpb=cafb65b48663d2851ed4330b4731c20f9b2bfaae;p=tpg%2Facess2.git diff --git a/Usermode/Libraries/libspiderscript.so_src/parse.c b/Usermode/Libraries/libspiderscript.so_src/parse.c index 7ed079ea..e6d96942 100644 --- a/Usermode/Libraries/libspiderscript.so_src/parse.c +++ b/Usermode/Libraries/libspiderscript.so_src/parse.c @@ -10,13 +10,14 @@ #define WANT_TOKEN_STRINGS 1 #include "tokens.h" #include "ast.h" +#include "common.h" #define DEBUG 0 #define SUPPORT_BREAK_TAGS 1 // === PROTOTYPES === -tAST_Script *Parse_Buffer(tSpiderVariant *Variant, const char *Buffer, const char *Filename); -void *Parse_FunctionDefinition(tAST_Script *Script, tSpiderVariant *Variant, tParser *Parser, int Type); + int Parse_Buffer(tSpiderScript *Script, const char *Buffer, const char *Filename); +void *Parse_FunctionDefinition(tSpiderScript *Script, tParser *Parser, int Type); tAST_Node *Parse_DoCodeBlock(tParser *Parser); tAST_Node *Parse_DoBlockLine(tParser *Parser); tAST_Node *Parse_GetVarDef(tParser *Parser, int Type); @@ -60,14 +61,13 @@ void SyntaxError(tParser *Parser, int bFatal, const char *Message, ...); /** * \brief Parse a buffer into a syntax tree */ -tAST_Script *Parse_Buffer(tSpiderVariant *Variant, const char *Buffer, const char *Filename) +int Parse_Buffer(tSpiderScript *Script, const char *Buffer, const char *Filename) { tParser parser = {0}; tParser *Parser = &parser; //< Keeps code consistent - tAST_Script *ret; tAST_Node *mainCode, *node; int type; - tAST_Function *fcn; + tScript_Function *fcn; #if DEBUG >= 2 printf("Parse_Buffer: (Variant=%p, Buffer=%p)\n", Variant, Buffer); @@ -86,7 +86,6 @@ tAST_Script *Parse_Buffer(tSpiderVariant *Variant, const char *Buffer, const cha parser.Filename += sizeof(int); // Move filename parser.ErrorHit = 0; - ret = AST_NewScript(); mainCode = AST_NewCodeBlock(&parser); // Give us an error fallback @@ -94,24 +93,17 @@ tAST_Script *Parse_Buffer(tSpiderVariant *Variant, const char *Buffer, const cha { AST_FreeNode( mainCode ); - for(fcn = ret->Functions; fcn; ) + for(fcn = Script->Functions; fcn; ) { - tAST_Node *var; - tAST_Function *nextFcn; - AST_FreeNode( fcn->Code ); - for(var = fcn->Arguments; var;) - { - tAST_Node *nextVar = var->NextSibling; - AST_FreeNode( var ); - var = nextVar; - } + tScript_Function *nextFcn; + + AST_FreeNode( fcn->ASTFcn ); nextFcn = fcn->Next; free( fcn ); fcn = nextFcn; } - free(ret); - return NULL; + return -1; } // Parse the file! @@ -131,7 +123,7 @@ tAST_Script *Parse_Buffer(tSpiderVariant *Variant, const char *Buffer, const cha // Define a function (pass on to the other function definition code) case TOK_IDENT: PutBack(Parser); - if( Parse_FunctionDefinition(ret, Variant, Parser, type) == NULL ) + if( Parse_FunctionDefinition(Script, Parser, type) == NULL ) longjmp(Parser->JmpTarget, -1); break ; // Define a variable @@ -156,14 +148,14 @@ tAST_Script *Parse_Buffer(tSpiderVariant *Variant, const char *Buffer, const cha // Define a function case TOK_RWD_FUNCTION: - if( !Variant->bDyamicTyped ) { + if( !Script->Variant->bDyamicTyped ) { SyntaxError(Parser, 1, "Dynamic functions are invalid in static mode"); longjmp(Parser->JmpTarget, -1); } type = SS_DATATYPE_DYNAMIC; - if( Parse_FunctionDefinition(ret, Variant, Parser, SS_DATATYPE_DYNAMIC) == NULL ) + if( Parse_FunctionDefinition(Script, Parser, SS_DATATYPE_DYNAMIC) == NULL ) longjmp(Parser->JmpTarget, -1); break; @@ -182,51 +174,66 @@ tAST_Script *Parse_Buffer(tSpiderVariant *Variant, const char *Buffer, const cha longjmp(Parser->JmpTarget, -1); } - fcn = AST_AppendFunction( ret, "", SS_DATATYPE_INTEGER ); - AST_SetFunctionCode( fcn, mainCode ); + AST_AppendFunction( Script, "", SS_DATATYPE_INTEGER, NULL, mainCode ); //printf("---- %p parsed as SpiderScript ----\n", Buffer); - return ret; + return 0; } -void *Parse_FunctionDefinition(tAST_Script *Script, tSpiderVariant *Variant, tParser *Parser, int Type) +void *Parse_FunctionDefinition(tSpiderScript *Script, tParser *Parser, int Type) { - tAST_Function *fcn; char *name; - int type; + int rv; + tAST_Node *first_arg, *last_arg, *code; + + last_arg = (void*)&first_arg; // HACK SyntaxAssert(Parser, GetToken(Parser), TOK_IDENT ); name = strndup( Parser->TokenStr, Parser->TokenLen ); - fcn = AST_AppendFunction( Script, name, Type ); #if DEBUG printf("DefFCN %s\n", name); #endif - free(name); // Get arguments SyntaxAssert(Parser, GetToken(Parser), TOK_PAREN_OPEN ); if( LookAhead(Parser) != TOK_PAREN_CLOSE ) { do { - type = SS_DATATYPE_DYNAMIC; + int type = SS_DATATYPE_DYNAMIC; GetToken(Parser); // Non dynamic typed variants must use data types - if( !Variant->bDyamicTyped ) { + if( !Script->Variant->bDyamicTyped ) { TOKEN_GET_DATATYPE(type, Parser->Token); GetToken(Parser); } - AST_AppendFunctionArg(fcn, Parse_GetVarDef(Parser, type)); + last_arg->NextSibling = Parse_GetVarDef(Parser, type); + last_arg = last_arg->NextSibling; + last_arg->NextSibling = NULL; } while(GetToken(Parser) == TOK_COMMA); } else GetToken(Parser); SyntaxAssert(Parser, Parser->Token, TOK_PAREN_CLOSE ); + + code = Parse_DoCodeBlock(Parser); + + rv = AST_AppendFunction( Script, name, Type, first_arg, code ); + + // Clean up argument definition nodes + { + tAST_Node *nextarg; + for( ; first_arg; first_arg = nextarg ) + { + nextarg = first_arg->NextSibling; + AST_FreeNode(first_arg); + } + } + + free(name); - AST_SetFunctionCode( fcn, Parse_DoCodeBlock(Parser) ); - - return fcn; + return rv == 0 ? (void*)1 : NULL; } /** @@ -306,6 +313,7 @@ tAST_Node *Parse_DoBlockLine(tParser *Parser) csaTOKEN_NAMES[tok]); return NULL; } + if(ident) free(ident); } break; @@ -331,7 +339,7 @@ tAST_Node *Parse_DoBlockLine(tParser *Parser) case TOK_RWD_FOR: { - const char *tag = ""; + char *tag = NULL; tAST_Node *init=NULL, *cond=NULL, *inc=NULL, *code; GetToken(Parser); // Eat 'for' @@ -364,6 +372,7 @@ tAST_Node *Parse_DoBlockLine(tParser *Parser) code = Parse_DoCodeBlock(Parser); ret = AST_NewLoop(Parser, tag, init, 0, cond, inc, code); + if(tag) free(tag); } return ret;