SpiderScript - Restructured to be able to keep bytecode and AST in memory at one...
[tpg/acess2.git] / Usermode / Libraries / libspiderscript.so_src / main.c
index 106ce23..d6cd722 100644 (file)
@@ -6,13 +6,15 @@
 #include <stdio.h>
 #include <string.h>
 #include <spiderscript.h>
+#include "common.h"
 #include "ast.h"
+#include "bytecode_gen.h"
 
 // === IMPORTS ===
-extern tAST_Script     *Parse_Buffer(tSpiderVariant *Variant, char *Buffer);
-extern tSpiderFunction *gpExports_First;
+extern  int    Parse_Buffer(tSpiderScript *Script, const char *Buffer, const char *Filename);
 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);
+extern void    Variable_Destroy(tAST_Variable *Variable);
 
 // === CODE ===
 /**
@@ -28,20 +30,20 @@ int SoMain()
  */
 tSpiderScript *SpiderScript_ParseFile(tSpiderVariant *Variant, const char *Filename)
 {
+       char    cacheFilename[strlen(Filename)+6+1];
        char    *data;
         int    fLen;
        FILE    *fp;
        tSpiderScript   *ret;
        
+       strcpy(cacheFilename, Filename);
+       strcat(cacheFilename, ".cache");
+       
        fp = fopen(Filename, "r");
        if( !fp ) {
                return NULL;
        }
        
-       // Create the script
-       ret = malloc(sizeof(tSpiderScript));
-       ret->Variant = Variant;
-       
        fseek(fp, 0, SEEK_END);
        fLen = ftell(fp);
        fseek(fp, 0, SEEK_SET);
@@ -49,14 +51,23 @@ tSpiderScript *SpiderScript_ParseFile(tSpiderVariant *Variant, const char *Filen
        // Allocate and read data
        data = malloc(fLen + 1);
        if(!data)       return NULL;
-       fread(data, fLen, 1, fp);
+       fLen = fread(data, 1, fLen, fp);
+       fclose(fp);
+       if( fLen < 0 ) {
+               free(data);
+               return NULL;
+       }
        data[fLen] = '\0';
        
-       fclose(fp);
+       
+       // Create the script
+       ret = malloc(sizeof(tSpiderScript));
+       ret->Variant = Variant;
+       ret->Functions = NULL;
+       ret->LastFunction = NULL;
        
        ret->CurNamespace = NULL;
-       ret->Script = Parse_Buffer(Variant, data);
-       if( ret->Script == NULL ) {
+       if( Parse_Buffer(ret, data, Filename) ) {
                free(data);
                free(ret);
                return NULL;
@@ -64,116 +75,31 @@ tSpiderScript *SpiderScript_ParseFile(tSpiderVariant *Variant, const char *Filen
        
        free(data);
        
-       return ret;
-}
-
-/**
- * \brief Execute a script function
- * \param Script       Script context to execute in
- * \param Function     Function name to execute
- * \param NArguments   Number of arguments to pass
- * \param Arguments    Arguments passed
- */
-tSpiderValue *SpiderScript_ExecuteMethod(tSpiderScript *Script,
-       const char *Function, int NArguments, tSpiderValue **Arguments)
-{
-       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
+       // HACK!!
        {
-               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;
-               }
-       }
-       
-       // 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;
-               }
-       }
-       
-       // Not found?
-       if(!bFound)
-       {
-               fprintf(stderr, "Undefined reference to '%s'\n", trueName);
+               size_t  size;
+               
+               printf("Total Size: "); fflush(stdout);
+               size = AST_WriteScript(NULL, ret);
+               printf("0x%x bytes\n", (unsigned)size);
+               
+               fp = fopen(cacheFilename, "wb");
+               if(!fp) return ret;
+               
+               data = malloc(size);
+               size = AST_WriteScript(data, ret);
+               fwrite(data, size, 1, fp);
+               free(data);
+               fclose(fp);
        }
        
-       if( trueName != Function && trueName != &Function[1] )
-               free(trueName);
-       
        return ret;
-       
+}
+
+int SpiderScript_SaveBytecode(tSpiderScript *Script, const char *DestFile)
+{
+       return Bytecode_ConvertScript(Script, DestFile);
 }
 
 /**
@@ -181,29 +107,19 @@ tSpiderValue *SpiderScript_ExecuteMethod(tSpiderScript *Script,
  */
 void SpiderScript_Free(tSpiderScript *Script)
 {
-       tAST_Function   *fcn = Script->Script->Functions;
-       tAST_Function   *nextFcn;
-       tAST_Node       *var, *nextVar;
+       tScript_Function        *fcn = Script->Functions;
+       tScript_Function        *nextFcn;
        
        // Free functions
-       while(fcn) {
-               AST_FreeNode( fcn->Code );
-               
-               var = fcn->Arguments;
-               while(var)
-               {
-                       nextVar = var->NextSibling;
-                       AST_FreeNode( var );
-                       var = nextVar;
-               }
-               
+       while(fcn)
+       {
+               if(fcn->ASTFcn) AST_FreeNode( fcn->ASTFcn );
+               if(fcn->BCFcn)  Bytecode_DeleteFunction( fcn->BCFcn );
+
                nextFcn = fcn->Next;
                free( fcn );
                fcn = nextFcn;
        }
        
-       // TODO: Pass this off to AST for a proper cleanup
-       free(Script->Script);
-       
        free(Script);
 }

UCC git Repository :: git.ucc.asn.au