X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=Usermode%2FLibraries%2Flibspiderscript.so_src%2Fmain.c;h=106ce232039eb55f95cb6df4048ee7192c580d95;hb=3ac178949c57e5cbd0cfe59915da9840ecefa68e;hp=ce39c0809d06aa1c20dc418493532a31059e1977;hpb=efa38e0d56b1b620b6f4e5c4f91abc483a3065e2;p=tpg%2Facess2.git diff --git a/Usermode/Libraries/libspiderscript.so_src/main.c b/Usermode/Libraries/libspiderscript.so_src/main.c index ce39c080..106ce232 100644 --- a/Usermode/Libraries/libspiderscript.so_src/main.c +++ b/Usermode/Libraries/libspiderscript.so_src/main.c @@ -10,6 +10,9 @@ // === IMPORTS === extern tAST_Script *Parse_Buffer(tSpiderVariant *Variant, char *Buffer); +extern tSpiderFunction *gpExports_First; +extern tAST_Variable *Variable_Define(tAST_BlockState *Block, int Type, const char *Name); +extern void Variable_SetValue(tAST_BlockState *Block, const char *Name, tSpiderValue *Value); // === CODE === /** @@ -35,6 +38,7 @@ tSpiderScript *SpiderScript_ParseFile(tSpiderVariant *Variant, const char *Filen return NULL; } + // Create the script ret = malloc(sizeof(tSpiderScript)); ret->Variant = Variant; @@ -42,13 +46,21 @@ tSpiderScript *SpiderScript_ParseFile(tSpiderVariant *Variant, const char *Filen fLen = ftell(fp); fseek(fp, 0, SEEK_SET); - data = malloc(fLen); + // Allocate and read data + data = malloc(fLen + 1); if(!data) return NULL; fread(data, fLen, 1, fp); + data[fLen] = '\0'; fclose(fp); + ret->CurNamespace = NULL; ret->Script = Parse_Buffer(Variant, data); + if( ret->Script == NULL ) { + free(data); + free(ret); + return NULL; + } free(data); @@ -57,21 +69,111 @@ tSpiderScript *SpiderScript_ParseFile(tSpiderVariant *Variant, const char *Filen /** * \brief Execute a script function - * \todo Arguments? + * \param Script Script context to execute in + * \param Function Function name to execute + * \param NArguments Number of arguments to pass + * \param Arguments Arguments passed */ -tSpiderVariable *SpiderScript_ExecuteMethod(tSpiderScript *Script, const char *Function) +tSpiderValue *SpiderScript_ExecuteMethod(tSpiderScript *Script, + const char *Function, int NArguments, tSpiderValue **Arguments) { - tAST_Function *fcn = Script->Script->Functions; + char *trueName = NULL; + int bFound = 0; // Used to keep nesting levels down + tSpiderValue *ret = ERRPTR; + + // Handle namespaces + if( Function[0] == '.' ) { + trueName = (char*)&Function[1]; + } + else if( !Script->CurNamespace ) { + trueName = (char*)Function; + } + else { + int len = strlen(Script->CurNamespace) + 1 + strlen(Function); + trueName = malloc( len + 1 ); + strcpy(trueName, Script->CurNamespace); + strcat(trueName, "."); + strcat(trueName, Function); + } + + // First: Find the function in the script + { + tAST_Function *fcn = Script->Script->Functions; + for( ; fcn; fcn = fcn->Next ) { + if( strcmp(fcn->Name, trueName) == 0 ) + break; + } + // Execute! + if(fcn) { + tAST_BlockState bs; + bs.FirstVar = NULL; + bs.RetVal = NULL; + bs.Parent = NULL; + bs.Script = Script; + { + tAST_Node *arg; + int i = 0; + for( arg = fcn->Arguments; arg; arg = arg->NextSibling, i++ ) + { + // TODO: Type checks + Variable_Define(&bs, arg->DefVar.DataType, arg->DefVar.Name); + if( i >= NArguments ) break; // TODO: Return gracefully + Variable_SetValue(&bs, arg->DefVar.Name, Arguments[i]); + } + } + ret = AST_ExecuteNode(&bs, fcn->Code); + Object_Dereference(ret); + ret = bs.RetVal; + bFound = 1; + } + } + + // Didn't find it in script? + if(!bFound) + { + tSpiderFunction *fcn; + // Second: Search the variant's exports + for( fcn = Script->Variant->Functions; fcn; fcn = fcn->Next ) + { + if( strcmp( fcn->Name, trueName ) == 0 ) + break; + } + // Execute! + if(fcn) { + // TODO: Type Checking + ret = fcn->Handler( Script, NArguments, Arguments ); + bFound = 1; + } + } - // Find the function - for( ; fcn; fcn = fcn->Next ) { - if( strcmp(fcn->Name, Function) == 0 ) - break; + // Not in variant exports? Search the language internal ones + if(!bFound) + { + tSpiderFunction *fcn; + // Third: Search language exports + for( fcn = gpExports_First; fcn; fcn = fcn->Next ) + { + if( strcmp( fcn->Name, trueName ) == 0 ) + break; + } + // Execute! + if(fcn) { + ret = fcn->Handler( Script, NArguments, Arguments ); + bFound = 1; + } } - if(!fcn) return NULL; - // Execute! - return AST_ExecuteNode(Script, fcn->Code); + // Not found? + if(!bFound) + { + fprintf(stderr, "Undefined reference to '%s'\n", trueName); + } + + if( trueName != Function && trueName != &Function[1] ) + free(trueName); + + return ret; + } /** @@ -99,4 +201,9 @@ void SpiderScript_Free(tSpiderScript *Script) free( fcn ); fcn = nextFcn; } + + // TODO: Pass this off to AST for a proper cleanup + free(Script->Script); + + free(Script); }