X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=Usermode%2FLibraries%2Flibspiderscript.so_src%2Fmain.c;h=e5c225ce425640e2798f2bcba574d755a126c0e4;hb=1529dadb6c2170bf9899fbde46d06a3d9a392b52;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..e5c225ce 100644 --- a/Usermode/Libraries/libspiderscript.so_src/main.c +++ b/Usermode/Libraries/libspiderscript.so_src/main.c @@ -10,6 +10,10 @@ // === IMPORTS === extern tAST_Script *Parse_Buffer(tSpiderVariant *Variant, char *Buffer); +extern const int giSpiderScript_NumExports; +extern tSpiderFunction gaSpiderScript_Exports[]; +extern tAST_Variable *Variable_Define(tAST_BlockState *Block, int Type, const char *Name); +extern void Variable_SetValue(tAST_BlockState *Block, const char *Name, tSpiderObject *Value); // === CODE === /** @@ -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,105 @@ 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) +tSpiderObject *SpiderScript_ExecuteMethod(tSpiderScript *Script, + const char *Function, int NArguments, tSpiderObject **Arguments) { - tAST_Function *fcn = Script->Script->Functions; + char *trueName = NULL; + int i; + int bFound = 0; // Used to keep nesting levels down + tSpiderObject *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; //< TODO: Parameters + 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); + bFound = 1; + } + } + + // Didn't find it in script? + if(!bFound) + { + // Second: Search the variant's exports + for( i = 0; i < Script->Variant->NFunctions; i ++ ) + { + if( strcmp( Script->Variant->Functions[i].Name, trueName) == 0 ) + break; + } + // Execute! + if(i < Script->Variant->NFunctions) { + ret = Script->Variant->Functions[i].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) + { + for( i = 0; i < giSpiderScript_NumExports; i ++ ) + { + if( strcmp( gaSpiderScript_Exports[i].Name, trueName ) == 0 ) + break; + } + // Execute! + if(i < giSpiderScript_NumExports) { + ret = gaSpiderScript_Exports[i].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 +195,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); }