2 * Acess2 - SpiderScript
8 #include <spiderscript.h>
12 extern tAST_Script *Parse_Buffer(tSpiderVariant *Variant, char *Buffer);
13 extern tSpiderFunction *gpExports_First;
14 extern tAST_Variable *Variable_Define(tAST_BlockState *Block, int Type, const char *Name);
15 extern void Variable_SetValue(tAST_BlockState *Block, const char *Name, tSpiderValue *Value);
16 extern void Variable_Destroy(tAST_Variable *Variable);
20 * \brief Library Entry Point
28 * \brief Parse a script
30 tSpiderScript *SpiderScript_ParseFile(tSpiderVariant *Variant, const char *Filename)
32 char cacheFilename[strlen(Filename)+6+1];
38 strcpy(cacheFilename, Filename);
39 strcat(cacheFilename, ".cache");
41 fp = fopen(Filename, "r");
47 ret = malloc(sizeof(tSpiderScript));
48 ret->Variant = Variant;
50 fseek(fp, 0, SEEK_END);
52 fseek(fp, 0, SEEK_SET);
54 // Allocate and read data
55 data = malloc(fLen + 1);
56 if(!data) return NULL;
57 fread(data, fLen, 1, fp);
62 ret->CurNamespace = NULL;
63 ret->Script = Parse_Buffer(Variant, data);
64 if( ret->Script == NULL ) {
77 printf("Total Size: "); fflush(stdout);
78 size = AST_WriteScript(NULL, ret->Script);
79 printf("0x%x bytes\n", (unsigned)size);
81 fp = fopen(cacheFilename, "wb");
85 AST_WriteScript(data, ret->Script);
86 fwrite(data, size, 1, fp);
95 * \brief Execute a script function
96 * \param Script Script context to execute in
97 * \param Function Function name to execute
98 * \param NArguments Number of arguments to pass
99 * \param Arguments Arguments passed
101 tSpiderValue *SpiderScript_ExecuteMethod(tSpiderScript *Script,
102 const char *Function, int NArguments, tSpiderValue **Arguments)
104 char *trueName = NULL;
105 int bFound = 0; // Used to keep nesting levels down
106 tSpiderValue *ret = ERRPTR;
109 if( Function[0] == '.' ) {
110 trueName = (char*)&Function[1];
112 else if( !Script->CurNamespace ) {
113 trueName = (char*)Function;
116 int len = strlen(Script->CurNamespace) + 1 + strlen(Function);
117 trueName = malloc( len + 1 );
118 strcpy(trueName, Script->CurNamespace);
119 strcat(trueName, ".");
120 strcat(trueName, Function);
123 // First: Find the function in the script
125 tAST_Function *fcn = Script->Script->Functions;
126 for( ; fcn; fcn = fcn->Next ) {
127 if( strcmp(fcn->Name, trueName) == 0 )
140 for( arg = fcn->Arguments; arg; arg = arg->NextSibling, i++ )
143 Variable_Define(&bs, arg->DefVar.DataType, arg->DefVar.Name);
144 if( i >= NArguments ) break; // TODO: Return gracefully
145 Variable_SetValue(&bs, arg->DefVar.Name, Arguments[i]);
148 ret = AST_ExecuteNode(&bs, fcn->Code);
149 Object_Dereference(ret);
155 tAST_Variable *nextVar = bs.FirstVar->Next;
156 Variable_Destroy( bs.FirstVar );
157 bs.FirstVar = nextVar;
162 // Didn't find it in script?
165 tSpiderFunction *fcn;
166 // Second: Search the variant's exports
167 for( fcn = Script->Variant->Functions; fcn; fcn = fcn->Next )
169 if( strcmp( fcn->Name, trueName ) == 0 )
174 // TODO: Type Checking
175 ret = fcn->Handler( Script, NArguments, Arguments );
180 // Not in variant exports? Search the language internal ones
183 tSpiderFunction *fcn;
184 // Third: Search language exports
185 for( fcn = gpExports_First; fcn; fcn = fcn->Next )
187 if( strcmp( fcn->Name, trueName ) == 0 )
192 ret = fcn->Handler( Script, NArguments, Arguments );
200 fprintf(stderr, "Undefined reference to '%s'\n", trueName);
203 if( trueName != Function && trueName != &Function[1] )
211 * \brief Free a script
213 void SpiderScript_Free(tSpiderScript *Script)
215 tAST_Function *fcn = Script->Script->Functions;
216 tAST_Function *nextFcn;
217 tAST_Node *var, *nextVar;
223 AST_FreeNode( fcn->Code );
225 var = fcn->Arguments;
228 nextVar = var->NextSibling;
238 // TODO: Pass this off to AST for a proper cleanup
239 free(Script->Script);