Usermode - Removed SpiderScript
authorJohn Hodge <[email protected]>
Fri, 20 Apr 2012 14:18:51 +0000 (22:18 +0800)
committerJohn Hodge <[email protected]>
Fri, 20 Apr 2012 14:18:51 +0000 (22:18 +0800)
- It had outgrown Acess, and has been removed
 > Now at git.mutabah.net/spiderscript.git

25 files changed:
Usermode/Applications/init_src/Makefile
Usermode/Applications/init_src/main.c
Usermode/Libraries/libspiderscript.so_src/Makefile [deleted file]
Usermode/Libraries/libspiderscript.so_src/Scripts/sample.isc [deleted file]
Usermode/Libraries/libspiderscript.so_src/Scripts/sample_static.ssc [deleted file]
Usermode/Libraries/libspiderscript.so_src/ast.c [deleted file]
Usermode/Libraries/libspiderscript.so_src/ast.h [deleted file]
Usermode/Libraries/libspiderscript.so_src/ast_to_bytecode.c [deleted file]
Usermode/Libraries/libspiderscript.so_src/bytecode.h [deleted file]
Usermode/Libraries/libspiderscript.so_src/bytecode_gen.c [deleted file]
Usermode/Libraries/libspiderscript.so_src/bytecode_gen.h [deleted file]
Usermode/Libraries/libspiderscript.so_src/bytecode_makefile.c [deleted file]
Usermode/Libraries/libspiderscript.so_src/bytecode_ops.h [deleted file]
Usermode/Libraries/libspiderscript.so_src/bytecode_optimise.c [deleted file]
Usermode/Libraries/libspiderscript.so_src/common.h [deleted file]
Usermode/Libraries/libspiderscript.so_src/exec.c [deleted file]
Usermode/Libraries/libspiderscript.so_src/exec_ast.c [deleted file]
Usermode/Libraries/libspiderscript.so_src/exec_bytecode.c [deleted file]
Usermode/Libraries/libspiderscript.so_src/exports.c [deleted file]
Usermode/Libraries/libspiderscript.so_src/lex.c [deleted file]
Usermode/Libraries/libspiderscript.so_src/main.c [deleted file]
Usermode/Libraries/libspiderscript.so_src/parse.c [deleted file]
Usermode/Libraries/libspiderscript.so_src/spiderscript.h [deleted file]
Usermode/Libraries/libspiderscript.so_src/tokens.h [deleted file]
Usermode/Libraries/libspiderscript.so_src/values.c [deleted file]

index c8a6ddb..df032bc 100644 (file)
@@ -5,7 +5,6 @@
 CPPFLAGS += 
 CFLAGS  += -Wall -Werror -O3
 LDFLAGS  +=
-# -lspiderscript
 
 BIN = init
 OBJ = main.o
index 4d66654..c18e5f8 100644 (file)
@@ -4,50 +4,16 @@
 #include <acess/sys.h>
 #include <stdlib.h>
 #include <stdio.h>
-//#include <spiderscript.h>
 //#include "common.h"
 
 // === CONSTANTS ===
 #define NUM_TERMS      4
 #define        DEFAULT_TERMINAL        "/Devices/VTerm/0"
 #define DEFAULT_SHELL  "/Acess/SBin/login"
-#define DEFAULT_SCRIPT "/Acess/Conf/BootConf.isc"
 
 #define ARRAY_SIZE(x)  ((sizeof(x))/(sizeof((x)[0])))
 
 // === PROTOTYPES ===
-/*
-tSpiderVariable        *Script_System_IO_Open(tSpiderScript *, int, tSpiderVariable *);
-*/
-
-// === GLOBALS ===
-/*
-tSpiderFunction        gaScriptNS_IO_Fcns[] = {
-       {"Open", Script_System_IO_Open}
-};
-tSpiderNamespace       gaScriptNS_System[] = {
-       {
-               "IO",
-               0, NULL,
-               ARRAY_SIZE(gaScriptNS_IO_Fcns), gaScriptNS_IO_Fcns,
-               0, NULL
-       }
-};
-
-tSpiderNamespace       gaScriptNamespaces[] = {
-       {
-               "System",
-               ARRAY_SIZE(gaScriptNS_System), gaScriptNS_System,
-               0, NULL,
-               0, NULL
-       }
-};
-
-tSpiderVariant gScriptVariant = {
-       "init", 0,
-       ARRAY_SIZE(gaScriptNamespaces), gaScriptNamespaces
-};
-*/
 
 // === CODE ===
 /**
@@ -85,26 +51,3 @@ int main(int argc, char *argv[])
        return 42;
 }
 
-/**
- * \brief Reads and parses the boot configuration script
- * \param Filename     File to parse and execute
- */
-void ExecuteScript(const char *Filename)
-{
-       /*
-       tSpiderScript   *script;
-       script = SpiderScript_ParseFile(&gScriptVariant, Filename);
-       SpiderScript_ExecuteMethod(script, "");
-       SpiderScript_Free(script);
-       */
-}
-
-/**
- * \brief Open a file
- */
-/*
-tSpiderVariable        *Script_System_IO_Open(tSpiderScript *Script, int NArgs, tSpiderVariable *Args)
-{
-       return NULL;
-}
-*/
diff --git a/Usermode/Libraries/libspiderscript.so_src/Makefile b/Usermode/Libraries/libspiderscript.so_src/Makefile
deleted file mode 100644 (file)
index 8988c01..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-# Acess 2
-#
-
-include ../Makefile.cfg
-
-CPPFLAGS +=
-CFLAGS   += -Wall
-LDFLAGS  += -lc -lgcc -soname libspiderscript.so --no-allow-shlib-undefined
-
-OBJ  = main.o lex.o parse.o ast.o exports.o values.o
-OBJ += ast_to_bytecode.o bytecode_gen.o bytecode_makefile.o
-OBJ += exec.o exec_bytecode.o
-BIN = libspiderscript.so
-
-include ../Makefile.tpl
diff --git a/Usermode/Libraries/libspiderscript.so_src/Scripts/sample.isc b/Usermode/Libraries/libspiderscript.so_src/Scripts/sample.isc
deleted file mode 100644 (file)
index d9ec020..0000000
+++ /dev/null
@@ -1,44 +0,0 @@
-#<?php
-
-# Should I use brackets in this language?
-# Well, considering that all whitespace is ignored, it might be an idea
-
-# Well, it would make VVV a little simpler
-# Just define a funciton with the name 'Sys.IO.Open'
-# Not a namespace Sys, with a child Sys
-
-$fp = Sys.IO.Open( "/Devices/ipstack" );
-$ifname = Sys.IO.IOCtl( $fp, 4, "/Devices/ne2k/0" );
-Sys.IO.Close($fp);
-
-# Let's see:
-#   b - Signed 8-bit integer, B - unsigned
-#   w - 16 bit
-#   l - 32 bit
-#   q - 64 bit
-#   f - 32-bit float
-#   d - 64-bit double
-#   Fields can be prefixed by a size for arrays (taking only one argument)
-#   * indicates a variable size array
-# E.g.
-#  Sys.Mem.MakeStruct( "L*B", $len, $len, $str );
-# Hmm.. that would mean I will need arrays... fuck it, do them later
-
-/*
-function SetIPv4($ifaceName, $addr)
-{
-       $fp = Sys.IO.Open( "/Devices/ipstack/$ifaceName" );
-       $data = Lang.MakeStruct( "l", 4 );
-       Sys.IO.IOCtl( $fp, 4, $data );
-       $data = Lang.Struct( "BBBB", $addr[0],  $addr[1],  $addr[2], $addr[3] );
-       Sys.IO.IOCtl( $fp, 6, $data );
-       Sys.IO.Close( $fp );
-}
-
-SetIPv4( $ifname, Lang.Array(10, 0, 2, 55) );
-*/
-
-
-return 42;     // Script return value
-
-#?>
diff --git a/Usermode/Libraries/libspiderscript.so_src/Scripts/sample_static.ssc b/Usermode/Libraries/libspiderscript.so_src/Scripts/sample_static.ssc
deleted file mode 100644 (file)
index f490fb8..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-#<?php
-
-Object $fp;
-Integer        $ifname;
-
-$fp = Sys.IO.Open( "/Devices/ipstack" );
-$ifname = Sys.IO.IOCtl( $fp, 4, "/Devices/ne2k/0" );
-Sys.IO.Close($fp);
-
-
-// Set the IPv4 address of an interface
-//void SetIPv4(String $ifaceName, Integer $addr[4])
-void SetIPv4(String $ifaceName, Integer $addr0, Integer $addr1, Integer $addr2, Integer $addr3)
-{
-       Object  $fp;
-       Object  $data;
-       $fp = Sys.IO.Open( "/Devices/ipstack/"+$ifaceName );
-       $data = Lang.Struct( "l", 4 );
-       Sys.IO.IOCtl( $fp, 4, $data );
-       //$data = Lang.Struct( "BBBB", $addr[0],  $addr[1],  $addr[2], $addr[3] );
-       $data = Lang.Struct( "BBBB", $addr0,  $addr1,  $addr2, $addr3 );
-       Sys.IO.IOCtl( $fp, 6, $data );
-       Sys.IO.Close( $fp );
-}
-
-//SetIPv4( $ifname, Lang.IntArray(10, 0, 2, 55) );
-SetIPv4( $ifname, 10, 0, 2, 55 );
-
-#?>
diff --git a/Usermode/Libraries/libspiderscript.so_src/ast.c b/Usermode/Libraries/libspiderscript.so_src/ast.c
deleted file mode 100644 (file)
index eb83996..0000000
+++ /dev/null
@@ -1,739 +0,0 @@
-/*
- * Acess2 Init
- * - Script AST Manipulator
- */
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include "common.h"
-#include "ast.h"
-
-// === IMPORTS ===
-extern void    SyntaxError(tParser *Parser, int bFatal, const char *Message, ...);
-
-// === CODE ===
-/**
- * \brief Append a function to a script
- */
-int AST_AppendFunction(tSpiderScript *Script, const char *Name, int ReturnType, tAST_Node *Args, tAST_Node *Code)
-{
-       tScript_Function        *fcn;
-        int    arg_count = 0, arg_bytes = 0;
-       tAST_Node       *arg;
-
-       // Count and size arguments
-       for(arg = Args; arg; arg = arg->NextSibling)
-       {
-               arg_count ++;
-               arg_bytes += sizeof(fcn->Arguments[0]) + strlen(Args->DefVar.Name) + 1;
-       }
-
-       // Allocate information
-       fcn = malloc( sizeof(tScript_Function) + arg_bytes + strlen(Name) + 1 );
-       if(!fcn)        return -1;
-       fcn->Next = NULL;
-       fcn->Name = (char*)&fcn->Arguments[arg_count];
-       strcpy(fcn->Name, Name);
-       fcn->ReturnType = ReturnType;
-       fcn->ArgumentCount = arg_count;
-       fcn->ASTFcn = Code;
-       fcn->BCFcn = NULL;
-       
-       // Set arguments
-       arg_bytes = strlen(Name) + 1;   // Used as an offset into fcn->Name
-       arg_count = 0;
-       for(arg = Args; arg; arg = arg->NextSibling)
-       {
-               fcn->Arguments[arg_count].Name = fcn->Name + arg_bytes;
-               strcpy(fcn->Arguments[arg_count].Name, arg->DefVar.Name);
-               fcn->Arguments[arg_count].Type = arg->DefVar.DataType;
-               arg_bytes += strlen(arg->DefVar.Name) + 1;
-               arg_count ++;
-       }
-       
-       if(Script->LastFunction == NULL) {
-               Script->Functions = Script->LastFunction = fcn;
-       }
-       else {
-               Script->LastFunction->Next = fcn;
-               Script->LastFunction = fcn;
-       }
-       
-       return 0;
-}
-
-/**
- * \name Node Manipulation
- * \{
- */
-#define WRITE_N(_buffer, _offset, _len, _dataptr) do { \
-       if(_buffer)     memcpy((char*)_buffer + _offset, _dataptr, _len);\
-       _offset += _len; \
-} while(0)
-
-#define WRITE_8(_buffer, _offset, _val) do {\
-       uint8_t v = (_val);\
-       WRITE_N(_buffer, _offset, 1, &v);\
-} while(0)
-#define WRITE_16(_buffer, _offset, _val) do {\
-       uint16_t        v = (_val);\
-       WRITE_N(_buffer, _offset, 2, &v);\
-} while(0)
-#define WRITE_32(_buffer, _offset, _val) do {\
-       uint32_t        v = (_val);\
-       WRITE_N(_buffer, _offset, 4, &v);\
-} while(0)
-#define WRITE_64(_buffer, _offset, _val) do {\
-       uint64_t        v = (_val);\
-       WRITE_N(_buffer, _offset, 8, &v);\
-} while(0)
-#define WRITE_REAL(_buffer, _offset, _val) do {\
-       double  v = (_val);\
-       WRITE_N(_buffer, _offset, sizeof(double), &v);\
-} while(0)
-
-#define WRITE_STR(_buffer, _offset, _string) do {\
-       int len = strlen(_string);\
-       WRITE_16(_buffer, _offset, len);\
-       WRITE_N(_buffer, _offset, len, _string);\
-       if((_offset & 1) == 1)WRITE_8(_buffer, _offset, 0); \
-       if((_offset & 3) == 2)WRITE_16(_buffer, _offset, 0); \
-} while(0)
-#define WRITE_NODELIST(_buffer, _offset, _listHead)    do {\
-       tAST_Node *node; \
-       size_t ptr = -1;\
-       for(node=(_listHead); node; node = node->NextSibling) {\
-               ptr = _offset;\
-               _offset += AST_WriteNode(_buffer, _offset, node); \
-               WRITE_32(_buffer, ptr, ptr); \
-       } \
-       if(ptr != -1){ptr -= 4; WRITE_32(_buffer, ptr, 0);} \
-} while(0)
-
-/**
- * \brief Writes a script dump to a buffer
- * \return Size of encoded data
- * \note If \a Buffer is NULL, no write is done, but the size is still returned
- */
-size_t AST_WriteScript(void *Buffer, tSpiderScript *Script)
-{
-       tScript_Function        *fcn;
-       size_t  ret = 0, ptr = 0;
-        int    i;
-       
-       for( fcn = Script->Functions; fcn; fcn = fcn->Next )
-       {
-//             printf("fcn = %p, fcn->Name = %p\n", fcn, fcn->Name);
-               ptr = ret;
-               WRITE_32(Buffer, ret, 0);       // Next
-               WRITE_STR(Buffer, ret, fcn->Name);
-               WRITE_32(Buffer, ret, fcn->ArgumentCount);
-               for( i = 0; i < fcn->ArgumentCount; i ++ )
-               {
-                       WRITE_16(Buffer, ret, fcn->Arguments[i].Type);
-                       WRITE_STR(Buffer, ret, fcn->Arguments[i].Name);
-               }
-               ret += AST_WriteNode(Buffer, ret, fcn->ASTFcn);
-               WRITE_32(Buffer, ptr, ret);     // Actually set `Next`
-       }
-       if( ptr )
-       {
-               ptr -= 4;
-               WRITE_32(Buffer, ptr, 0);       // Clear next for final
-       }
-       
-       return ret;
-}
-
-/**
- * \brief Write a node to a file
- */
-size_t AST_WriteNode(void *Buffer, size_t Offset, tAST_Node *Node)
-{
-       size_t  baseOfs = Offset;
-       
-       if(!Node) {
-               //fprintf(stderr, "Possible Bug - NULL passed to AST_WriteNode\n");
-               WRITE_32(Buffer, Offset, 0);
-               WRITE_16(Buffer, Offset, NODETYPE_NOP);
-               WRITE_16(Buffer, Offset, 0);    // Line (0)
-               return 0;
-       }
-       
-       WRITE_32(Buffer, Offset, 0);    // Next
-       WRITE_16(Buffer, Offset, Node->Type);
-       // TODO: Scan the buffer for the location of the filename (with NULL byte)
-       //       else, write the string at the end of the node
-       WRITE_16(Buffer, Offset, Node->Line);   // Line
-       //WRITE_32(Buffer, Offset, 0);  // File
-       
-       switch(Node->Type)
-       {
-       // Block of code
-       case NODETYPE_BLOCK:
-               WRITE_NODELIST(Buffer, Offset, Node->Block.FirstChild);
-               break;
-       
-       // Function Call
-       case NODETYPE_METHODCALL:
-               Offset += AST_WriteNode(Buffer, Offset, Node->FunctionCall.Object);
-       case NODETYPE_FUNCTIONCALL:
-       case NODETYPE_CREATEOBJECT:
-               // TODO: Search for the same function name and add a pointer
-               WRITE_STR(Buffer, Offset, Node->FunctionCall.Name);
-               WRITE_NODELIST(Buffer, Offset, Node->FunctionCall.FirstArg);
-               break;
-       
-       // If node
-       case NODETYPE_IF:
-               Offset += AST_WriteNode(Buffer, Offset, Node->If.Condition);
-               Offset += AST_WriteNode(Buffer, Offset, Node->If.True);
-               Offset += AST_WriteNode(Buffer, Offset, Node->If.False);
-               break;
-       
-       // Looping Construct (For loop node)
-       case NODETYPE_LOOP:
-               WRITE_8(Buffer, Offset, Node->For.bCheckAfter);
-               WRITE_STR(Buffer, Offset, Node->For.Tag);
-               Offset += AST_WriteNode(Buffer, Offset, Node->For.Init);
-               Offset += AST_WriteNode(Buffer, Offset, Node->For.Condition);
-               Offset += AST_WriteNode(Buffer, Offset, Node->For.Increment);
-               Offset += AST_WriteNode(Buffer, Offset, Node->For.Code);
-               break;
-       
-       // Asignment
-       case NODETYPE_ASSIGN:
-               WRITE_8(Buffer, Offset, Node->Assign.Operation);
-               Offset += AST_WriteNode(Buffer, Offset, Node->Assign.Dest);
-               Offset += AST_WriteNode(Buffer, Offset, Node->Assign.Value);
-               break;
-       
-       // Casting
-       case NODETYPE_CAST:
-               WRITE_8(Buffer, Offset, Node->Cast.DataType);
-               Offset += AST_WriteNode(Buffer, Offset, Node->Cast.Value);
-               break;
-       
-       // Define a variable
-       case NODETYPE_DEFVAR:
-               WRITE_32(Buffer, Offset, Node->DefVar.DataType);
-               // TODO: Duplicate compress the strings
-               WRITE_STR(Buffer, Offset, Node->DefVar.Name);
-               Offset += AST_WriteNode(Buffer, Offset, Node->DefVar.InitialValue);
-               break;
-       
-       // Scope Reference
-       case NODETYPE_SCOPE:
-       case NODETYPE_ELEMENT:
-               WRITE_STR(Buffer, Offset, Node->Scope.Name);
-               Offset += AST_WriteNode(Buffer, Offset, Node->UniOp.Value);
-               break;
-       
-       // Unary Operations
-       case NODETYPE_RETURN:
-       case NODETYPE_BWNOT:
-       case NODETYPE_LOGICALNOT:
-       case NODETYPE_NEGATE:
-       case NODETYPE_POSTINC:
-       case NODETYPE_POSTDEC:
-               Offset += AST_WriteNode(Buffer, Offset, Node->UniOp.Value);
-               break;
-       
-       // Binary Operations
-       case NODETYPE_INDEX:
-       case NODETYPE_ADD:
-       case NODETYPE_SUBTRACT:
-       case NODETYPE_MULTIPLY:
-       case NODETYPE_DIVIDE:
-       case NODETYPE_MODULO:
-       case NODETYPE_BITSHIFTLEFT:
-       case NODETYPE_BITSHIFTRIGHT:
-       case NODETYPE_BITROTATELEFT:
-       case NODETYPE_BWAND:    case NODETYPE_LOGICALAND:
-       case NODETYPE_BWOR:     case NODETYPE_LOGICALOR:
-       case NODETYPE_BWXOR:    case NODETYPE_LOGICALXOR:
-       case NODETYPE_EQUALS:   case NODETYPE_NOTEQUALS:
-       case NODETYPE_LESSTHAN: case NODETYPE_LESSTHANEQUAL:
-       case NODETYPE_GREATERTHAN:      case NODETYPE_GREATERTHANEQUAL:
-               Offset += AST_WriteNode(Buffer, Offset, Node->BinOp.Left);
-               Offset += AST_WriteNode(Buffer, Offset, Node->BinOp.Right);
-               break;
-       
-       // Node types with no children
-       case NODETYPE_NOP:
-               break;
-       case NODETYPE_VARIABLE:
-       case NODETYPE_CONSTANT:
-       case NODETYPE_BREAK:
-       case NODETYPE_CONTINUE:
-               // TODO: De-Duplicate the strings
-               WRITE_STR(Buffer, Offset, Node->Variable.Name);
-               break;
-       case NODETYPE_STRING:
-               WRITE_32(Buffer, Offset, Node->Constant.String.Length);
-               WRITE_N(Buffer, Offset, Node->Constant.String.Length, Node->Constant.String.Data);
-               break;
-       case NODETYPE_INTEGER:
-               WRITE_64(Buffer, Offset, Node->Constant.Integer);
-               break;
-       case NODETYPE_REAL:
-               WRITE_REAL(Buffer, Offset, Node->Constant.Real);
-               break;
-       case NODETYPE_NULL:
-               break;
-       
-       //default:
-       //      fprintf(stderr, "AST_WriteNode: Unknown node type %i\n", Node->Type);
-       //      break;
-       }
-       
-       return Offset - baseOfs;
-}
-
-/**
- * \brief Free a node and all subnodes
- */
-void AST_FreeNode(tAST_Node *Node)
-{
-       tAST_Node       *node;
-       
-       if(!Node)       return ;
-       
-       // Referenced counted file name
-       (*(int*)(Node->File - sizeof(int))) -= 1;
-       if( *(int*)(Node->File - sizeof(int)) == 0 )
-               free( (void*)(Node->File - sizeof(int)) );
-       
-       switch(Node->Type)
-       {
-       // Block of code
-       case NODETYPE_BLOCK:
-               for( node = Node->Block.FirstChild; node; )
-               {
-                       tAST_Node       *savedNext = node->NextSibling;
-                       AST_FreeNode(node);
-                       node = savedNext;
-               }
-               break;
-       
-       // Function Call
-       case NODETYPE_METHODCALL:
-               AST_FreeNode(Node->FunctionCall.Object);
-       case NODETYPE_FUNCTIONCALL:
-       case NODETYPE_CREATEOBJECT:
-               for( node = Node->FunctionCall.FirstArg; node; )
-               {
-                       tAST_Node       *savedNext = node->NextSibling;
-                       AST_FreeNode(node);
-                       node = savedNext;
-               }
-               break;
-       
-       // If node
-       case NODETYPE_IF:
-               AST_FreeNode(Node->If.Condition);
-               AST_FreeNode(Node->If.True);
-               AST_FreeNode(Node->If.False);
-               break;
-       
-       // Looping Construct (For loop node)
-       case NODETYPE_LOOP:
-               AST_FreeNode(Node->For.Init);
-               AST_FreeNode(Node->For.Condition);
-               AST_FreeNode(Node->For.Increment);
-               AST_FreeNode(Node->For.Code);
-               break;
-       
-       // Asignment
-       case NODETYPE_ASSIGN:
-               AST_FreeNode(Node->Assign.Dest);
-               AST_FreeNode(Node->Assign.Value);
-               break;
-       
-       // Casting
-       case NODETYPE_CAST:
-               AST_FreeNode(Node->Cast.Value);
-               break;
-       
-       case NODETYPE_SCOPE:
-       case NODETYPE_ELEMENT:
-               AST_FreeNode(Node->Scope.Element);
-               break;
-       
-       // Define a variable
-       case NODETYPE_DEFVAR:
-               AST_FreeNode(Node->DefVar.InitialValue);
-               break;
-       
-       // Unary Operations
-       case NODETYPE_RETURN:
-       case NODETYPE_BWNOT:
-       case NODETYPE_LOGICALNOT:
-       case NODETYPE_NEGATE:
-       case NODETYPE_POSTINC:
-       case NODETYPE_POSTDEC:
-               AST_FreeNode(Node->UniOp.Value);
-               break;
-       
-       // Binary Operations
-       case NODETYPE_INDEX:
-       case NODETYPE_ADD:
-       case NODETYPE_SUBTRACT:
-       case NODETYPE_MULTIPLY:
-       case NODETYPE_DIVIDE:
-       case NODETYPE_MODULO:
-       case NODETYPE_BITSHIFTLEFT:
-       case NODETYPE_BITSHIFTRIGHT:
-       case NODETYPE_BITROTATELEFT:
-       case NODETYPE_BWAND:    case NODETYPE_LOGICALAND:
-       case NODETYPE_BWOR:     case NODETYPE_LOGICALOR:
-       case NODETYPE_BWXOR:    case NODETYPE_LOGICALXOR:
-       case NODETYPE_EQUALS:   case NODETYPE_NOTEQUALS:
-       case NODETYPE_LESSTHAN: case NODETYPE_LESSTHANEQUAL:
-       case NODETYPE_GREATERTHAN:      case NODETYPE_GREATERTHANEQUAL:
-               AST_FreeNode( Node->BinOp.Left );
-               AST_FreeNode( Node->BinOp.Right );
-               break;
-       
-       // Node types with no children
-       case NODETYPE_NOP:      break;
-       case NODETYPE_NULL:     break;
-       case NODETYPE_VARIABLE: break;
-       case NODETYPE_CONSTANT: break;
-       case NODETYPE_BREAK:
-       case NODETYPE_CONTINUE: break;
-       
-       case NODETYPE_STRING:
-       case NODETYPE_INTEGER:
-       case NODETYPE_REAL:
-               if( Node->ValueCache )
-                       SpiderScript_DereferenceValue(Node->ValueCache);
-               Node->ValueCache = NULL;
-               break;
-       }
-       free( Node );
-}
-
-tAST_Node *AST_int_AllocateNode(tParser *Parser, int Type, int ExtraSize)
-{
-       tAST_Node       *ret = malloc( sizeof(tAST_Node) + ExtraSize );
-       ret->NextSibling = NULL;
-       ret->File = Parser->Filename;   *(int*)(Parser->Filename - sizeof(int)) += 1;
-       ret->Line = Parser->CurLine;
-       ret->Type = Type;
-       
-       // Runtime Caching
-       ret->BlockState = NULL;
-       ret->BlockIdent = 0;
-       ret->ValueCache = NULL;
-       
-       return ret;
-}
-
-tAST_Node *AST_NewCodeBlock(tParser *Parser)
-{
-       tAST_Node       *ret = AST_int_AllocateNode(Parser, NODETYPE_BLOCK, 0 );
-       
-       ret->Block.FirstChild = NULL;
-       ret->Block.LastChild = NULL;
-       
-       return ret;
-}
-
-void AST_AppendNode(tAST_Node *Parent, tAST_Node *Child)
-{
-       // Ignore NULL children
-       if( !Child )    return ;
-       
-       Child->NextSibling = NULL;
-       switch( Parent->Type )
-       {
-       case NODETYPE_BLOCK:
-               if(Parent->Block.FirstChild == NULL) {
-                       Parent->Block.FirstChild = Parent->Block.LastChild = Child;
-               }
-               else {
-                       Parent->Block.LastChild->NextSibling = Child;
-                       Parent->Block.LastChild = Child;
-               }
-               break;
-       default:
-               fprintf(stderr, "BUG REPORT: AST_AppendNode on an invalid node type (%i)\n", Parent->Type);
-               break;
-       }
-}
-
-tAST_Node *AST_NewIf(tParser *Parser, tAST_Node *Condition, tAST_Node *True, tAST_Node *False)
-{
-       tAST_Node       *ret = AST_int_AllocateNode(Parser, NODETYPE_IF, 0);
-       ret->If.Condition = Condition;
-       ret->If.True = True;
-       ret->If.False = False;
-       return ret;
-}
-
-tAST_Node *AST_NewLoop(tParser *Parser, const char *Tag, tAST_Node *Init, int bPostCheck, tAST_Node *Condition, tAST_Node *Increment, tAST_Node *Code)
-{
-       tAST_Node       *ret;
-       if(!Tag)        Tag = "";
-       // NOTE: The +3) & ~3 is to align the size to 4 bytes, and shut valgrind up
-       // - GCC sometimes inlines strlen as a loop of dword reads, triggering valgrind
-       ret = AST_int_AllocateNode(Parser, NODETYPE_LOOP, (strlen(Tag) + 1 + 3) & ~3);
-       ret->For.Init = Init;
-       ret->For.bCheckAfter = !!bPostCheck;
-       ret->For.Condition = Condition;
-       ret->For.Increment = Increment;
-       ret->For.Code = Code;
-       strcpy(ret->For.Tag, Tag);
-       return ret;
-}
-
-tAST_Node *AST_NewAssign(tParser *Parser, int Operation, tAST_Node *Dest, tAST_Node *Value)
-{
-       tAST_Node       *ret = AST_int_AllocateNode(Parser, NODETYPE_ASSIGN, 0);
-       
-       if( Dest->Type != NODETYPE_VARIABLE && Dest->Type != NODETYPE_ELEMENT && Dest->Type != NODETYPE_INDEX )
-       {
-               free(ret);
-               SyntaxError(Parser, 1, "Assign target is not a variable or attribute (instead %i)",
-                       Dest->Type);
-               AST_FreeNode(Dest);
-               AST_FreeNode(Value);
-               return NULL;
-       }
-       
-       ret->Assign.Operation = Operation;
-       ret->Assign.Dest = Dest;
-       ret->Assign.Value = Value;
-       
-       return ret;
-}
-
-tAST_Node *AST_NewCast(tParser *Parser, int Target, tAST_Node *Value)
-{
-       tAST_Node       *ret = AST_int_AllocateNode(Parser, NODETYPE_CAST, 0);
-       
-       ret->Cast.DataType = Target;
-       ret->Cast.Value = Value;
-       
-       return ret;
-}
-
-tAST_Node *AST_NewBinOp(tParser *Parser, int Operation, tAST_Node *Left, tAST_Node *Right)
-{
-       tAST_Node       *ret = AST_int_AllocateNode(Parser, Operation, 0);
-       
-       ret->BinOp.Left = Left;
-       ret->BinOp.Right = Right;
-       
-       return ret;
-}
-
-/**
- */
-tAST_Node *AST_NewUniOp(tParser *Parser, int Operation, tAST_Node *Value)
-{
-       tAST_Node       *ret = AST_int_AllocateNode(Parser, Operation, 0);
-       
-       ret->UniOp.Value = Value;
-       
-       return ret;
-}
-
-tAST_Node *AST_NewBreakout(tParser *Parser, int Type, const char *DestTag)
-{
-        int    len = (DestTag ? strlen(DestTag) : 0);
-       tAST_Node       *ret = AST_int_AllocateNode(Parser, Type, len + 1);
-       
-       if( DestTag )
-               strcpy(ret->Variable.Name, DestTag);
-       else
-               ret->Variable.Name[0] = '\0';
-       
-       return ret;
-}
-
-tAST_Node *AST_NewNop(tParser *Parser)
-{
-       tAST_Node       *ret = AST_int_AllocateNode(Parser, NODETYPE_NOP, 0);
-       
-       return ret;
-}
-
-/**
- * \brief Create a new string node
- */
-tAST_Node *AST_NewString(tParser *Parser, const char *String, int Length)
-{
-       tAST_Node       *ret = AST_int_AllocateNode(Parser, NODETYPE_STRING, Length + 1);
-       
-       ret->Constant.Type = SS_DATATYPE_STRING;
-       ret->Constant.ReferenceCount = 1;
-       ret->Constant.String.Length = Length;
-       memcpy(ret->Constant.String.Data, String, Length);
-       ret->Constant.String.Data[Length] = '\0';
-       
-       return ret;
-}
-
-/**
- * \brief Create a new integer node
- */
-tAST_Node *AST_NewInteger(tParser *Parser, int64_t Value)
-{
-       tAST_Node       *ret = AST_int_AllocateNode(Parser, NODETYPE_INTEGER, 0);
-       ret->Constant.Type = SS_DATATYPE_INTEGER;
-       ret->Constant.ReferenceCount = 1;
-       ret->Constant.Integer = Value;
-       return ret;
-}
-
-/**
- * \brief Create a new real number node
- */
-tAST_Node *AST_NewReal(tParser *Parser, double Value)
-{
-       tAST_Node       *ret = AST_int_AllocateNode(Parser, NODETYPE_REAL, 0);
-       ret->Constant.Type = SS_DATATYPE_REAL;
-       ret->Constant.ReferenceCount = 1;
-       ret->Constant.Real = Value;
-       return ret;
-}
-
-/**
- * \brief Return a null value
- */
-tAST_Node *AST_NewNull(tParser *Parser)
-{
-       tAST_Node       *ret = AST_int_AllocateNode(Parser, NODETYPE_NULL, 0);
-       
-       return ret;
-}
-
-/**
- * \brief Create a new variable reference node
- */
-tAST_Node *AST_NewVariable(tParser *Parser, const char *Name)
-{
-       tAST_Node       *ret = AST_int_AllocateNode(Parser, NODETYPE_VARIABLE, strlen(Name) + 1 );
-       strcpy(ret->Variable.Name, Name);
-       return ret;
-}
-
-/**
- * \brief Create a new variable definition node
- */
-tAST_Node *AST_NewDefineVar(tParser *Parser, int Type, const char *Name)
-{
-       tAST_Node       *ret = AST_int_AllocateNode(Parser, NODETYPE_DEFVAR, strlen(Name) + 1 );
-       
-       ret->DefVar.DataType = Type;
-       ret->DefVar.InitialValue = NULL;
-       strcpy(ret->DefVar.Name, Name);
-       
-       return ret;
-}
-
-/**
- * \brief Create a new runtime constant reference node
- */
-tAST_Node *AST_NewConstant(tParser *Parser, const char *Name)
-{
-       tAST_Node       *ret = AST_int_AllocateNode(Parser, NODETYPE_CONSTANT, strlen(Name) + 1 );
-       
-       strcpy(ret->Variable.Name, Name);
-       
-       return ret;
-}
-
-/**
- * \brief Create a function call node
- * \note Argument list is manipulated using AST_AppendFunctionCallArg
- */
-tAST_Node *AST_NewFunctionCall(tParser *Parser, const char *Name)
-{
-       tAST_Node       *ret = AST_int_AllocateNode(Parser, NODETYPE_FUNCTIONCALL, strlen(Name) + 1 );
-       
-       ret->FunctionCall.Object = NULL;
-       ret->FunctionCall.FirstArg = NULL;
-       ret->FunctionCall.LastArg = NULL;
-       ret->FunctionCall.NumArgs = 0;
-       strcpy(ret->FunctionCall.Name, Name);
-       
-       return ret;
-}
-tAST_Node *AST_NewMethodCall(tParser *Parser, tAST_Node *Object, const char *Name)
-{
-       tAST_Node       *ret = AST_int_AllocateNode(Parser, NODETYPE_METHODCALL, strlen(Name) + 1 );
-       
-       ret->FunctionCall.Object = Object;
-       ret->FunctionCall.FirstArg = NULL;
-       ret->FunctionCall.LastArg = NULL;
-       ret->FunctionCall.NumArgs = 0;
-       strcpy(ret->FunctionCall.Name, Name);
-       
-       return ret;
-}
-
-tAST_Node *AST_NewCreateObject(tParser *Parser, const char *Name)
-{
-       tAST_Node       *ret = AST_int_AllocateNode(Parser, NODETYPE_CREATEOBJECT, strlen(Name) + 1 );
-       
-       ret->FunctionCall.Object = NULL;
-       ret->FunctionCall.FirstArg = NULL;
-       ret->FunctionCall.LastArg = NULL;
-       ret->FunctionCall.NumArgs = 0;
-       strcpy(ret->FunctionCall.Name, Name);
-       
-       return ret;
-}
-
-/**
- * \brief Append an argument to a function call
- */
-void AST_AppendFunctionCallArg(tAST_Node *Node, tAST_Node *Arg)
-{
-       if( Node->Type != NODETYPE_FUNCTIONCALL
-        && Node->Type != NODETYPE_CREATEOBJECT
-        && Node->Type != NODETYPE_METHODCALL)
-       {
-               fprintf(stderr, "BUG REPORT: AST_AppendFunctionCallArg on an invalid node type (%i)\n", Node->Type);
-               return ;
-       }
-       
-       if(Node->FunctionCall.LastArg) {
-               Node->FunctionCall.LastArg->NextSibling = Arg;
-               Node->FunctionCall.LastArg = Arg;
-       }
-       else {
-               Node->FunctionCall.FirstArg = Arg;
-               Node->FunctionCall.LastArg = Arg;
-       }
-       Node->FunctionCall.NumArgs ++;
-}
-
-/**
- * \brief Add a scope node
- */
-tAST_Node *AST_NewScopeDereference(tParser *Parser, const char *Name, tAST_Node *Child)
-{
-       tAST_Node       *ret = AST_int_AllocateNode(Parser, NODETYPE_SCOPE, strlen(Name) + 1 );
-       ret->Scope.Element = Child;
-       strcpy(ret->Scope.Name, Name);
-       return ret;
-}
-
-/**
- * \brief Add a scope node
- */
-tAST_Node *AST_NewClassElement(tParser *Parser, tAST_Node *Object, const char *Name)
-{
-       tAST_Node       *ret = AST_int_AllocateNode(Parser, NODETYPE_ELEMENT, strlen(Name) + 1 );
-       ret->Scope.Element = Object;
-       strcpy(ret->Scope.Name, Name);
-       return ret;
-}
-
-/**
- * \}
- */
diff --git a/Usermode/Libraries/libspiderscript.so_src/ast.h b/Usermode/Libraries/libspiderscript.so_src/ast.h
deleted file mode 100644 (file)
index a6620fc..0000000
+++ /dev/null
@@ -1,245 +0,0 @@
-/*
- */
-#ifndef _AST_H_
-#define _AST_H_
-
-#include <spiderscript.h>
-#include "tokens.h"
-
-typedef enum eAST_NodeTypes    tAST_NodeType;
-typedef struct sAST_Script     tAST_Script;
-typedef struct sAST_Function   tAST_Function;
-typedef struct sAST_Node       tAST_Node;
-typedef struct sAST_BlockState tAST_BlockState;
-typedef struct sAST_Variable   tAST_Variable;
-
-/**
- * \brief Node Types
- */
-enum eAST_NodeTypes
-{
-       NODETYPE_NOP,
-       
-       NODETYPE_BLOCK, //!< Node Block
-       
-       // 2
-       NODETYPE_VARIABLE,      //!< Variable
-       NODETYPE_CONSTANT,      //!< Runtime Constant
-       NODETYPE_STRING,        //!< String Constant
-       NODETYPE_INTEGER,       //!< Integer Constant
-       NODETYPE_REAL,  //!< Real Constant
-       NODETYPE_NULL,
-       
-       // 8
-       NODETYPE_DEFVAR,        //!< Define a variable (Variable)
-       NODETYPE_SCOPE, //!< Dereference a Namespace/Class static
-       NODETYPE_ELEMENT,       //!< Reference a class attribute
-       NODETYPE_CAST,  //!< Cast a value to another (Uniop)
-       
-       // 12
-       NODETYPE_RETURN,        //!< Return from a function (reserved word)
-       NODETYPE_BREAK,         //!< Break out of a loop
-       NODETYPE_CONTINUE,      //!< Next loop iteration
-       NODETYPE_ASSIGN,        //!< Variable assignment operator
-       NODETYPE_POSTINC,       //!< Post-increment (i++) - Uniop
-       NODETYPE_POSTDEC,       //!< Post-decrement (i--) - Uniop
-       NODETYPE_FUNCTIONCALL,  //!< Call a function
-       NODETYPE_METHODCALL,    //!< Call a class method
-       NODETYPE_CREATEOBJECT,  //!< Create an object
-       
-       // 21
-       NODETYPE_IF,    //!< Conditional
-       NODETYPE_LOOP,  //!< Looping Construct
-       
-       // 23
-       NODETYPE_INDEX, //!< Index into an array
-       
-       // 24
-       NODETYPE_LOGICALNOT,    //!< Logical NOT operator
-       NODETYPE_LOGICALAND,    //!< Logical AND operator
-       NODETYPE_LOGICALOR,     //!< Logical OR operator
-       NODETYPE_LOGICALXOR,    //!< Logical XOR operator
-       
-       NODETYPE_EQUALS,        //!< Comparison Equals
-       NODETYPE_NOTEQUALS,     //!< Comparison Not Equals
-       NODETYPE_LESSTHAN,      //!< Comparison Less Than
-       NODETYPE_LESSTHANEQUAL, //!< Comparison Less Than or Equal
-       NODETYPE_GREATERTHAN,   //!< Comparison Greater Than
-       NODETYPE_GREATERTHANEQUAL,      //!< Comparison Greater Than or Equal
-       
-       NODETYPE_BWNOT, //!< Bitwise NOT
-       NODETYPE_BWAND, //!< Bitwise AND
-       NODETYPE_BWOR,  //!< Bitwise OR
-       NODETYPE_BWXOR, //!< Bitwise XOR
-       
-       NODETYPE_BITSHIFTLEFT,  //!< Bitwise Shift Left (Grow)
-       NODETYPE_BITSHIFTRIGHT, //!< Bitwise Shift Right (Shrink)
-       NODETYPE_BITROTATELEFT, //!< Bitwise Rotate Left (Grow)
-       
-       NODETYPE_NEGATE,        //!< Negagte
-       NODETYPE_ADD,   //!< Add
-       NODETYPE_SUBTRACT,      //!< Subtract
-       NODETYPE_MULTIPLY,      //!< Multiply
-       NODETYPE_DIVIDE,        //!< Divide
-       NODETYPE_MODULO,        //!< Modulus
-};
-
-struct sAST_Node
-{
-       tAST_Node       *NextSibling;
-       tAST_NodeType   Type;
-
-       const char      *File;
-        int    Line;
-       
-       void    *BlockState;    //!< BlockState pointer (for cache integrity)
-        int    BlockIdent;     //!< Ident (same as above)
-       void    *ValueCache;    //!< Cached value / pointer
-       
-       union
-       {
-               struct {
-                       tAST_Node       *FirstChild;
-                       tAST_Node       *LastChild;
-               }       Block;
-               
-               struct {
-                        int    Operation;
-                       tAST_Node       *Dest;
-                       tAST_Node       *Value;
-               }       Assign;
-               
-               struct {
-                       tAST_Node       *Value;
-               }       UniOp;
-               
-               struct {
-                       tAST_Node       *Left;
-                       tAST_Node       *Right;
-               }       BinOp;
-               
-               struct {
-                       tAST_Node       *Object;
-                       tAST_Node       *FirstArg;
-                       tAST_Node       *LastArg;
-                        int    NumArgs;
-                       char    Name[];
-               }       FunctionCall;
-               
-               struct {
-                       tAST_Node       *Condition;
-                       tAST_Node       *True;
-                       tAST_Node       *False;
-               }       If;
-               
-               struct {
-                       tAST_Node       *Init;
-                        int    bCheckAfter;
-                       tAST_Node       *Condition;
-                       tAST_Node       *Increment;
-                       tAST_Node       *Code;
-                       char    Tag[];
-               }       For;
-               
-               /**
-                * \note Used for \a NODETYPE_VARIABLE and \a NODETYPE_CONSTANT
-                */
-               struct {
-                       char    _unused;        // Shut GCC up
-                       char    Name[];
-               }       Variable;
-               
-               struct {
-                       tAST_Node       *Element;
-                       char    Name[];
-               }       Scope;  // Used by NODETYPE_SCOPE and NODETYPE_ELEMENT
-               
-               struct {
-                        int    DataType;
-                       tAST_Node       *InitialValue;
-                       char    Name[];
-               }       DefVar;
-               
-               struct {
-                        int    DataType;
-                        tAST_Node      *Value;
-               }       Cast;
-               
-               // Used for NODETYPE_REAL, NODETYPE_INTEGER and NODETYPE_STRING
-               tSpiderValue    Constant;
-       };
-};
-
-/**
- * \brief Code Block state (stores local variables)
- */
-struct sAST_BlockState
-{
-       tAST_BlockState *Parent;
-       tSpiderScript   *Script;        //!< Script
-       tAST_Variable   *FirstVar;      //!< First variable in the list
-       tSpiderValue    *RetVal;
-       tSpiderNamespace        *BaseNamespace; //!< Base namespace (for entire block)
-       tSpiderNamespace        *CurNamespace;  //!< Currently selected namespace
-        int    Ident;  //!< ID number used for variable lookup caching
-       const char      *BreakTarget;
-        int    BreakType;
-};
-
-struct sAST_Variable
-{
-       tAST_Variable   *Next;
-        int    Type;   // Only used for static typing
-       tSpiderValue    *Object;
-       char    Name[];
-};
-
-// === FUNCTIONS ===
-extern tAST_Script     *AST_NewScript(void);
-extern size_t  AST_WriteScript(void *Buffer, tSpiderScript *Script);
-extern size_t  AST_WriteNode(void *Buffer, size_t Offset, tAST_Node *Node);
-
-extern int     AST_AppendFunction(tSpiderScript *Script, const char *Name, int ReturnType, tAST_Node *FirstArg, tAST_Node *Code);
-
-extern tAST_Node       *AST_NewNop(tParser *Parser);
-
-extern tAST_Node       *AST_NewString(tParser *Parser, const char *String, int Length);
-extern tAST_Node       *AST_NewInteger(tParser *Parser, int64_t Value);
-extern tAST_Node       *AST_NewReal(tParser *Parser, double Value);
-extern tAST_Node       *AST_NewNull(tParser *Parser);
-
-extern tAST_Node       *AST_NewVariable(tParser *Parser, const char *Name);
-extern tAST_Node       *AST_NewDefineVar(tParser *Parser, int Type, const char *Name);
-extern tAST_Node       *AST_NewConstant(tParser *Parser, const char *Name);
-extern tAST_Node       *AST_NewClassElement(tParser *Parser, tAST_Node *Object, const char *Name);
-
-extern tAST_Node       *AST_NewFunctionCall(tParser *Parser, const char *Name);
-extern tAST_Node       *AST_NewCreateObject(tParser *Parser, const char *Name);
-extern tAST_Node       *AST_NewMethodCall(tParser *Parser, tAST_Node *Object, const char *Name);
-extern void    AST_AppendFunctionCallArg(tAST_Node *Node, tAST_Node *Arg);
-
-extern tAST_Node       *AST_NewCodeBlock(tParser *Parser);
-extern void    AST_AppendNode(tAST_Node *Parent, tAST_Node *Child);
-
-extern tAST_Node       *AST_NewIf(tParser *Parser, tAST_Node *Condition, tAST_Node *True, tAST_Node *False);
-extern tAST_Node       *AST_NewLoop(tParser *Parser, const char *Tag, tAST_Node *Init, int bPostCheck, tAST_Node *Condition, tAST_Node *Increment, tAST_Node *Code);
-
-extern tAST_Node       *AST_NewAssign(tParser *Parser, int Operation, tAST_Node *Dest, tAST_Node *Value);
-extern tAST_Node       *AST_NewCast(tParser *Parser, int Target, tAST_Node *Value);
-extern tAST_Node       *AST_NewBinOp(tParser *Parser, int Operation, tAST_Node *Left, tAST_Node *Right);
-extern tAST_Node       *AST_NewUniOp(tParser *Parser, int Operation, tAST_Node *Value);
-extern tAST_Node       *AST_NewBreakout(tParser *Parser, int Type, const char *DestTag);
-extern tAST_Node       *AST_NewScopeDereference(tParser *Parser, const char *Name, tAST_Node *Child);
-
-extern void    AST_FreeNode(tAST_Node *Node);
-
-// exec_ast.h
-extern void    Object_Dereference(tSpiderValue *Object);
-extern void    Object_Reference(tSpiderValue *Object);
-extern tSpiderValue    *AST_ExecuteNode(tAST_BlockState *Block, tAST_Node *Node);
-extern tSpiderValue    *AST_ExecuteNode_BinOp(tSpiderScript *Script, tAST_Node *Node, int Operation, tSpiderValue *Left, tSpiderValue *Right);
-extern tSpiderValue    *AST_ExecuteNode_UniOp(tSpiderScript *Script, tAST_Node *Node, int Operation, tSpiderValue *Value);
-extern tSpiderValue    *AST_ExecuteNode_Index(tSpiderScript *Script, tAST_Node *Node, tSpiderValue *Array, int Index, tSpiderValue *SaveValue);
-extern tSpiderValue    *AST_ExecuteNode_Element(tSpiderScript *Script, tAST_Node *Node, tSpiderValue *Object, const char *Element, tSpiderValue *SaveValue);
-
-#endif
diff --git a/Usermode/Libraries/libspiderscript.so_src/ast_to_bytecode.c b/Usermode/Libraries/libspiderscript.so_src/ast_to_bytecode.c
deleted file mode 100644 (file)
index c45e7a5..0000000
+++ /dev/null
@@ -1,897 +0,0 @@
-/*
- * SpiderScript Library
- *
- * AST to Bytecode Conversion
- */
-#include <stdlib.h>
-#include <stdio.h>
-#include <stdarg.h>
-#include <string.h>
-#include "common.h"
-#include "ast.h"
-#include "bytecode_gen.h"
-#include "bytecode_ops.h"
-
-#define TRACE_VAR_LOOKUPS      0
-#define TRACE_TYPE_STACK       0
-#define MAX_NAMESPACE_DEPTH    10
-#define MAX_STACK_DEPTH        10      // This is for one function, so shouldn't need more
-
-// === IMPORTS ===
-extern tSpiderFunction *gpExports_First;
-
-// === TYPES ===
-typedef struct sAST_BlockInfo
-{
-       struct sAST_BlockInfo   *Parent;
-       void    *Handle;
-       const char      *Tag;
-
-        int    BreakTarget;
-        int    ContinueTarget;
-
-        int    NamespaceDepth;
-       const char      *CurNamespaceStack[MAX_NAMESPACE_DEPTH];
-       
-        int    StackDepth;
-        int    Stack[MAX_STACK_DEPTH]; // Stores types of stack values
-       
-       tAST_Variable   *FirstVar;
-} tAST_BlockInfo;
-
-// === PROTOTYPES ===
-// Node Traversal
- int   AST_ConvertNode(tAST_BlockInfo *Block, tAST_Node *Node, int bKeepValue);
- int   BC_SaveValue(tAST_BlockInfo *Block, tAST_Node *DestNode);
-// Variables
- int   BC_Variable_Define(tAST_BlockInfo *Block, int Type, const char *Name);
- int   BC_Variable_SetValue(tAST_BlockInfo *Block, tAST_Node *VarNode);
- int   BC_Variable_GetValue(tAST_BlockInfo *Block, tAST_Node *VarNode);
-void   BC_Variable_Clear(tAST_BlockInfo *Block);
-// - Errors
-void   AST_RuntimeMessage(tAST_Node *Node, const char *Type, const char *Format, ...);
-void   AST_RuntimeError(tAST_Node *Node, const char *Format, ...);
-// - Type stack
- int   _StackPush(tAST_BlockInfo *Block, tAST_Node *Node, int Type);
- int   _StackPop(tAST_BlockInfo *Block, tAST_Node *Node, int WantedType);
-
-// === GLOBALS ===
-// int giNextBlockIdent = 1;
-
-// === CODE ===
-int SpiderScript_BytecodeScript(tSpiderScript *Script)
-{
-       tScript_Function        *fcn;
-       for(fcn = Script->Functions; fcn; fcn = fcn->Next)
-       {
-               if( Bytecode_ConvertFunction(fcn) == 0 )
-                       return -1;
-       }
-       return 0;
-}
-
-/**
- * \brief Convert a function into bytecode
- */
-tBC_Function *Bytecode_ConvertFunction(tScript_Function *Fcn)
-{
-       tBC_Function    *ret;
-       tAST_BlockInfo bi = {0};
-        int    i;
-
-       // TODO: Return BCFcn instead?
-       if(Fcn->BCFcn)  return Fcn->BCFcn;
-       
-       ret = Bytecode_CreateFunction(Fcn);
-       if(!ret)        return NULL;
-       
-       bi.Handle = ret;
-       
-       // Parse arguments
-       for( i = 0; i < Fcn->ArgumentCount; i ++ )
-       {
-               BC_Variable_Define(&bi, Fcn->Arguments[i].Type, Fcn->Arguments[i].Name);
-       }
-
-       if( AST_ConvertNode(&bi, Fcn->ASTFcn, 0) )
-       {
-               AST_RuntimeError(Fcn->ASTFcn, "Error in converting function");
-               Bytecode_DeleteFunction(ret);
-               BC_Variable_Clear(&bi);
-               return NULL;
-       }
-       BC_Variable_Clear(&bi);
-
-
-       Bytecode_AppendConstInt(ret, 0);        // TODO: NULL
-       Bytecode_AppendReturn(ret);
-       Fcn->BCFcn = ret;
-
-       return ret;
-}
-
-// Indepotent operation
-#define CHECK_IF_NEEDED(b_warn) do { if(!bKeepValue) {\
-       if(b_warn)AST_RuntimeMessage(Node, "Bytecode", "Operation without saving");\
-       Bytecode_AppendDelete(Block->Handle);\
-       _StackPop(Block, Node, SS_DATATYPE_UNDEF);\
-} } while(0)
-
-/**
- * \brief Convert a node into bytecode
- * \param Block        Execution context
- * \param Node Node to execute
- */
-int AST_ConvertNode(tAST_BlockInfo *Block, tAST_Node *Node, int bKeepValue)
-{
-       tAST_Node       *node;
-        int    ret = 0;
-        int    i, op = 0;
-        int    bAddedValue = 1;        // Used to tell if the value needs to be deleted
-       
-       switch(Node->Type)
-       {
-       // No Operation
-       case NODETYPE_NOP:
-               bAddedValue = 0;
-               break;
-       
-       // Code block
-       case NODETYPE_BLOCK:
-               Bytecode_AppendEnterContext(Block->Handle);     // Create a new block
-               {
-                       tAST_BlockInfo  blockInfo = {0};
-                       blockInfo.Parent = Block;
-                       blockInfo.Handle = Block->Handle;
-                       // Loop over all nodes, or until the return value is set
-                       for(node = Node->Block.FirstChild;
-                               node;
-                               node = node->NextSibling )
-                       {
-                               ret = AST_ConvertNode(&blockInfo, node, 0);
-                               if(ret) return ret;
-                               if( blockInfo.StackDepth != 0 ) {
-                                       AST_RuntimeError(node, "Stack not reset at end of node");
-                                       blockInfo.StackDepth = 0;
-                               }
-                       }
-                       
-                       BC_Variable_Clear(&blockInfo);
-               }
-               Bytecode_AppendLeaveContext(Block->Handle);     // Leave this context
-               break;
-       
-       // Assignment
-       case NODETYPE_ASSIGN:
-               // Perform assignment operation
-               if( Node->Assign.Operation != NODETYPE_NOP )
-               {
-                        int    t1, t2;
-                       
-                       ret = AST_ConvertNode(Block, Node->Assign.Dest, 1);
-                       if(ret) return ret;
-                       t1 = _StackPop(Block, Node, SS_DATATYPE_UNDEF);
-                       if(t1 < 0)      return -1;
-                       
-                       ret = AST_ConvertNode(Block, Node->Assign.Value, 1);
-                       if(ret) return ret;
-                       t2 = _StackPop(Block, Node, SS_DATATYPE_UNDEF);
-                       if(t2 < 0)      return -1;
-
-
-                       switch(Node->Assign.Operation)
-                       {
-                       // General Binary Operations
-                       case NODETYPE_ADD:      op = BC_OP_ADD; break;
-                       case NODETYPE_SUBTRACT: op = BC_OP_SUBTRACT;    break;
-                       case NODETYPE_MULTIPLY: op = BC_OP_MULTIPLY;    break;
-                       case NODETYPE_DIVIDE:   op = BC_OP_DIVIDE;      break;
-                       case NODETYPE_MODULO:   op = BC_OP_MODULO;      break;
-                       case NODETYPE_BWAND:    op = BC_OP_BITAND;      break;
-                       case NODETYPE_BWOR:     op = BC_OP_BITOR;       break;
-                       case NODETYPE_BWXOR:    op = BC_OP_BITXOR;      break;
-                       case NODETYPE_BITSHIFTLEFT:     op = BC_OP_BITSHIFTLEFT;        break;
-                       case NODETYPE_BITSHIFTRIGHT:    op = BC_OP_BITSHIFTRIGHT;       break;
-                       case NODETYPE_BITROTATELEFT:    op = BC_OP_BITROTATELEFT;       break;
-
-                       default:
-                               AST_RuntimeError(Node, "Unknown operation in ASSIGN %i", Node->Assign.Operation);
-                               break;
-                       }
-//                     printf("assign, op = %i\n", op);
-                       ret = _StackPush(Block, Node, t1);
-                       if(ret < 0)     return -1;
-                       Bytecode_AppendBinOp(Block->Handle, op);
-               }
-               else
-               {
-                       ret = AST_ConvertNode(Block, Node->Assign.Value, 1);
-                       if(ret) return ret;
-               }
-               
-               if( bKeepValue ) {
-                       ret = _StackPop(Block, Node, SS_DATATYPE_UNDEF);
-                       if(ret < 0)     return -1;
-                       ret = _StackPush(Block, Node, ret);
-                       if(ret < 0)     return -1;
-                       ret = _StackPush(Block, Node, ret);
-                       if(ret < 0)     return -1;
-                       Bytecode_AppendDuplicate(Block->Handle);
-               }
-               
-               ret = BC_SaveValue(Block, Node->Assign.Dest);
-               if(ret) return ret;
-               break;
-       
-       // Post increment/decrement
-       case NODETYPE_POSTINC:
-       case NODETYPE_POSTDEC:
-               // Save original value if requested
-               if(bKeepValue) {
-                       ret = BC_Variable_GetValue(Block, Node->UniOp.Value);
-                       if(ret) return ret;
-               }
-               
-               Bytecode_AppendConstInt(Block->Handle, 1);
-               ret = _StackPush(Block, Node, SS_DATATYPE_INTEGER);
-               if(ret < 0)     return -1;
-               
-               ret = AST_ConvertNode(Block, Node->UniOp.Value, 1);
-               if(ret) return ret;
-
-               if( Node->Type == NODETYPE_POSTDEC )
-                       Bytecode_AppendBinOp(Block->Handle, BC_OP_SUBTRACT);
-               else
-                       Bytecode_AppendBinOp(Block->Handle, BC_OP_ADD);
-
-               ret = _StackPop(Block, Node, SS_DATATYPE_INTEGER);      // TODO: Check for objects too
-               if(ret < 0)     return -1;
-               ret = BC_SaveValue(Block, Node->UniOp.Value);
-               if(ret) return ret;
-               break;
-
-       // Function Call
-       case NODETYPE_METHODCALL: {
-                int    nargs = 0;
-               
-               ret = AST_ConvertNode(Block, Node->FunctionCall.Object, 1);
-               if(ret) return ret;
-
-               // Push arguments to the stack
-               for(node = Node->FunctionCall.FirstArg; node; node = node->NextSibling)
-               {
-                       ret = AST_ConvertNode(Block, node, 1);
-                       if(ret) return ret;
-                       nargs ++;
-                       
-                       // TODO: Check arguments? Need to get the types somehow
-                       ret = _StackPop(Block, Node, SS_DATATYPE_UNDEF);
-                       if(ret < 0)     return -1;
-               }
-               
-               ret = _StackPop(Block, Node, SS_DATATYPE_OBJECT);
-               if(ret < 0)     return -1;
-               Bytecode_AppendMethodCall(Block->Handle, Node->FunctionCall.Name, nargs);
-
-               ret = _StackPush(Block, Node, SS_DATATYPE_UNDEF);
-               if(ret < 0)     return -1;
-       
-               CHECK_IF_NEEDED(0);     // Don't warn
-               // TODO: Implement warn_unused_ret
-               
-               } break;
-       case NODETYPE_FUNCTIONCALL:
-       case NODETYPE_CREATEOBJECT: {
-                int    nargs = 0;
-               
-               // Get name (mangled into a single string)
-                int    newnamelen = 0;
-               char    *manglename;
-               for( i = 0; i < Block->NamespaceDepth; i ++ )
-                       newnamelen += strlen(Block->CurNamespaceStack[i]) + 1;
-               newnamelen += strlen(Node->FunctionCall.Name) + 1;
-//             newnamelen += 1;
-               
-               manglename = alloca(newnamelen);
-               newnamelen = 0;
-               for( i = 0; i < Block->NamespaceDepth; i ++ ) {
-                       strcpy(manglename+newnamelen, Block->CurNamespaceStack[i]);
-                       newnamelen += strlen(Block->CurNamespaceStack[i]) + 1;
-                       manglename[ newnamelen - 1 ] = BC_NS_SEPARATOR;
-               }
-               strcpy(manglename + newnamelen, Node->FunctionCall.Name);
-               newnamelen += strlen(Node->FunctionCall.Name) + 1;
-//             manglename[ newnamelen ] = '\0';        // Zero length terminator
-               Block->NamespaceDepth = 0;
-
-               // Push arguments to the stack
-               for(node = Node->FunctionCall.FirstArg; node; node = node->NextSibling)
-               {
-                       // TODO: Type Checking
-                       ret = AST_ConvertNode(Block, node, 1);
-                       if(ret) return ret;
-                       nargs ++;
-                       
-                       // TODO: Check arguments? Need to get the types somehow
-                       ret = _StackPop(Block, node, SS_DATATYPE_UNDEF);
-                       if(ret < 0)     return -1;
-               }
-               
-               // Call the function
-               if( Node->Type == NODETYPE_CREATEOBJECT )
-               {
-                       Bytecode_AppendCreateObj(Block->Handle, manglename, nargs);
-               }
-               else
-               {
-                       Bytecode_AppendFunctionCall(Block->Handle, manglename, nargs);
-               }
-               
-               // TODO: Get return type
-               ret = _StackPush(Block, Node, SS_DATATYPE_UNDEF);
-               if(ret < 0)     return -1;
-               
-               CHECK_IF_NEEDED(0);     // Don't warn
-               // TODO: Implement warn_unused_ret
-               } break;
-       
-       // Conditional
-       case NODETYPE_IF: {
-                int    if_end;
-               ret = AST_ConvertNode(Block, Node->If.Condition, 1);
-               if(ret) return ret;
-               // TODO: Should be boolean/integer, but meh
-               ret = _StackPop(Block, Node->If.Condition, SS_DATATYPE_UNDEF);
-               if(ret < 0)     return -1;
-               
-               if_end = Bytecode_AllocateLabel(Block->Handle);
-
-               if( Node->If.False->Type != NODETYPE_NOP )
-               {
-                        int    if_true = Bytecode_AllocateLabel(Block->Handle);
-                       
-                       Bytecode_AppendCondJump(Block->Handle, if_true);
-       
-                       // False
-                       ret = AST_ConvertNode(Block, Node->If.False, 0);
-                       if(ret) return ret;
-                       Bytecode_AppendJump(Block->Handle, if_end);
-                       Bytecode_SetLabel(Block->Handle, if_true);
-               }
-               else
-               {
-                       Bytecode_AppendCondJumpNot(Block->Handle, if_end);
-               }
-               
-               // True
-               ret = AST_ConvertNode(Block, Node->If.True, 0);
-               if(ret) return ret;
-
-               // End
-               Bytecode_SetLabel(Block->Handle, if_end);
-               } break;
-       
-       // Loop
-       case NODETYPE_LOOP: {
-                int    loop_start, loop_end, code_end;
-                int    saved_break, saved_continue;
-               const char      *saved_tag;
-
-               // Initialise
-               ret = AST_ConvertNode(Block, Node->For.Init, 0);
-               if(ret) return ret;
-               
-               loop_start = Bytecode_AllocateLabel(Block->Handle);
-               code_end = Bytecode_AllocateLabel(Block->Handle);
-               loop_end = Bytecode_AllocateLabel(Block->Handle);
-
-               saved_break = Block->BreakTarget;
-               saved_continue = Block->ContinueTarget;
-               saved_tag = Block->Tag;
-               Block->BreakTarget = loop_end;
-               Block->ContinueTarget = code_end;
-               Block->Tag = Node->For.Tag;
-
-               Bytecode_SetLabel(Block->Handle, loop_start);
-
-               // Check initial condition
-               if( !Node->For.bCheckAfter )
-               {
-                       ret = AST_ConvertNode(Block, Node->For.Condition, 1);
-                       if(ret) return ret;
-                       Bytecode_AppendUniOp(Block->Handle, BC_OP_LOGICNOT);
-                       ret = _StackPop(Block, Node->For.Condition, SS_DATATYPE_UNDEF); // Boolean?
-                       if(ret < 0)     return -1;
-                       Bytecode_AppendCondJump(Block->Handle, loop_end);
-               }
-       
-               // Code
-               ret = AST_ConvertNode(Block, Node->For.Code, 0);
-               if(ret) return ret;
-
-               Bytecode_SetLabel(Block->Handle, code_end);
-       
-               // Increment
-               ret = AST_ConvertNode(Block, Node->For.Increment, 0);
-               if(ret) return ret;
-//             ret = _StackPop(Block, Node->For.Increment, SS_DATATYPE_UNDEF); // TODO: Check if needed
-//             if(ret < 0)     return -1;
-
-               // Tail check
-               if( Node->For.bCheckAfter )
-               {
-                       ret = AST_ConvertNode(Block, Node->For.Condition, 1);
-                       if(ret) return ret;
-                       ret = _StackPop(Block, Node->If.Condition, SS_DATATYPE_UNDEF);  // Boolean?
-                       if(ret < 0)     return ret;
-                       Bytecode_AppendCondJump(Block->Handle, loop_start);
-               }
-               else
-               {
-                       Bytecode_AppendJump(Block->Handle, loop_start);
-               }
-
-               Bytecode_SetLabel(Block->Handle, loop_end);
-
-               Block->BreakTarget = saved_break;
-               Block->ContinueTarget = saved_continue;
-               Block->Tag = saved_tag;
-               } break;
-       
-       // Return
-       case NODETYPE_RETURN:
-               ret = AST_ConvertNode(Block, Node->UniOp.Value, 1);
-               if(ret) return ret;
-               Bytecode_AppendReturn(Block->Handle);
-               ret = _StackPop(Block, Node->UniOp.Value, SS_DATATYPE_UNDEF);   // 
-               if(ret < 0)     return -1;
-               break;
-       
-       case NODETYPE_BREAK:
-       case NODETYPE_CONTINUE: {
-               tAST_BlockInfo  *bi = Block;
-               if( Node->Variable.Name[0] ) {
-                       while(bi && (!bi->Tag || strcmp(bi->Tag, Node->Variable.Name) != 0))
-                               bi = bi->Parent;
-               }
-               else {
-                       while(bi && !bi->Tag)
-                               bi = bi->Parent;
-               }
-               if( !bi )       return 1;
-               // TODO: Check if BreakTarget/ContinueTarget are valid
-               if( Node->Type == NODETYPE_BREAK )
-                       Bytecode_AppendJump(Block->Handle, bi->BreakTarget);
-               else
-                       Bytecode_AppendJump(Block->Handle, bi->ContinueTarget);
-               } break;
-       
-       // Define a variable
-       case NODETYPE_DEFVAR:
-               ret = BC_Variable_Define(Block, Node->DefVar.DataType, Node->DefVar.Name);
-               if(ret) return ret;
-               
-               if( Node->DefVar.InitialValue )
-               {
-                       ret = AST_ConvertNode(Block, Node->DefVar.InitialValue, 1);
-                       if(ret) return ret;
-                       ret = _StackPop(Block, Node->DefVar.InitialValue, Node->DefVar.DataType);
-                       if(ret < 0)     return -1;
-                       Bytecode_AppendSaveVar(Block->Handle, Node->DefVar.Name);
-               }
-               break;
-       
-       // Scope
-       case NODETYPE_SCOPE:
-               if( Block->NamespaceDepth == MAX_NAMESPACE_DEPTH ) {
-                       AST_RuntimeError(Node, "Exceeded max explicit namespace depth (%i)", MAX_NAMESPACE_DEPTH);
-                       return 2;
-               }
-               Block->CurNamespaceStack[ Block->NamespaceDepth ] = Node->Scope.Name;
-               Block->NamespaceDepth ++;
-               ret = AST_ConvertNode(Block, Node->Scope.Element, bKeepValue);
-               if(ret) return ret;
-               if( Block->NamespaceDepth != 0 ) {
-                       AST_RuntimeError(Node, "Namespace scope used but no element at the end");
-               }
-               bAddedValue = 0;
-               break;
-       
-       // Variable
-       case NODETYPE_VARIABLE:
-               ret = BC_Variable_GetValue( Block, Node );
-               CHECK_IF_NEEDED(1);
-               if(ret) return ret;
-               break;
-       
-       // Element of an Object
-       case NODETYPE_ELEMENT:
-               ret = AST_ConvertNode( Block, Node->Scope.Element, 1 );
-               if(ret) return ret;
-
-               // TODO: Support elements for non-objects
-               ret = _StackPop(Block, Node, SS_DATATYPE_OBJECT);
-               if(ret < 0)     return -1;
-
-               Bytecode_AppendElement(Block->Handle, Node->Scope.Name);
-               
-               // TODO: Somehow know this at compile time?
-               ret = _StackPush(Block, Node, SS_DATATYPE_UNDEF);
-               if(ret < 0)     return -1;
-               CHECK_IF_NEEDED(1);
-               break;
-
-       // Cast a value to another
-       case NODETYPE_CAST:
-               ret = AST_ConvertNode(Block, Node->Cast.Value, 1);
-               if(ret) return ret;
-               ret = _StackPop(Block, Node, SS_DATATYPE_UNDEF);
-               if(ret < 0)     return -1;
-               
-               Bytecode_AppendCast(Block->Handle, Node->Cast.DataType);
-               ret = _StackPush(Block, Node, Node->Cast.DataType);
-               if(ret < 0)     return -1;
-               CHECK_IF_NEEDED(1);
-               break;
-
-       // Index into an array
-       case NODETYPE_INDEX:
-               // - Array
-               ret = AST_ConvertNode(Block, Node->BinOp.Left, 1);
-               if(ret) return ret;
-               //  > Type check
-               ret = _StackPop(Block, Node, SS_DATATYPE_UNDEF);
-               if(ret < 0)     return -1;
-               if(ret != SS_DATATYPE_ARRAY && SS_GETARRAYDEPTH(ret) == 0) {
-                       AST_RuntimeError(Node, "Type mismatch, Expected an array, got %i",
-                               ret);
-                       return -2;
-               }
-               i = ret;        // Hackily save the datatype
-
-               // - Offset
-               ret = AST_ConvertNode(Block, Node->BinOp.Right, 1);
-               if(ret) return ret;
-               ret = _StackPop(Block, Node, SS_DATATYPE_INTEGER);
-               if(ret < 0)     return -1;
-               
-               Bytecode_AppendIndex(Block->Handle);
-               
-               // Update the array depth
-               if( i != SS_DATATYPE_ARRAY ) {
-                       i = SS_DOWNARRAY(i);    // Decrease the array level
-               }
-               ret = _StackPush(Block, Node, i);
-               if(ret < 0)     return -1;
-               
-               CHECK_IF_NEEDED(1);
-               break;
-
-       // TODO: Implement runtime constants
-       case NODETYPE_CONSTANT:
-               // TODO: Scan namespace for constant name
-               AST_RuntimeError(Node, "TODO - Runtime Constants");
-               Block->NamespaceDepth = 0;
-               return -1;
-       
-       // Constant Values
-       case NODETYPE_STRING:
-               Bytecode_AppendConstString(Block->Handle, Node->Constant.String.Data, Node->Constant.String.Length);
-               ret = _StackPush(Block, Node, SS_DATATYPE_STRING);
-               if(ret < 0)     return -1;
-               CHECK_IF_NEEDED(1);
-               break;
-       case NODETYPE_INTEGER:
-               Bytecode_AppendConstInt(Block->Handle, Node->Constant.Integer);
-               ret = _StackPush(Block, Node, SS_DATATYPE_INTEGER);
-               if(ret < 0)     return -1;
-               CHECK_IF_NEEDED(1);
-               break;
-       case NODETYPE_REAL:
-               Bytecode_AppendConstReal(Block->Handle, Node->Constant.Real);
-               ret = _StackPush(Block, Node, SS_DATATYPE_REAL);
-               if(ret < 0)     return -1;
-               CHECK_IF_NEEDED(1);
-               break;
-       case NODETYPE_NULL:
-               Bytecode_AppendConstNull(Block->Handle);
-               ret = _StackPush(Block, Node, SS_DATATYPE_UNDEF);
-               if(ret < 0)     return -1;
-               CHECK_IF_NEEDED(1);
-               break;
-
-       // --- Operations ---
-       // Boolean Operations
-       case NODETYPE_LOGICALNOT:       // Logical NOT (!)
-               if(!op) op = BC_OP_LOGICNOT;
-       case NODETYPE_BWNOT:    // Bitwise NOT (~)
-               if(!op) op = BC_OP_BITNOT;
-       case NODETYPE_NEGATE:   // Negation (-)
-               if(!op) op = BC_OP_NEG;
-               ret = AST_ConvertNode(Block, Node->UniOp.Value, 1);
-               if(ret) return ret;
-               ret = _StackPop(Block, Node->UniOp.Value, SS_DATATYPE_UNDEF);   // TODO: Integer/Real/Undef
-               if(ret < 0)     return -1;
-
-               Bytecode_AppendUniOp(Block->Handle, op);
-               ret = _StackPush(Block, Node, ret);     // TODO: Logic = _INTEGER, Neg = No change
-               if(ret < 0)     return -1;
-               
-               CHECK_IF_NEEDED(1);
-               break;
-
-       // Logic
-       case NODETYPE_LOGICALAND:       if(!op) op = BC_OP_LOGICAND;
-       case NODETYPE_LOGICALOR:        if(!op) op = BC_OP_LOGICOR;
-       case NODETYPE_LOGICALXOR:       if(!op) op = BC_OP_LOGICXOR;
-       // Comparisons
-       case NODETYPE_EQUALS:           if(!op) op = BC_OP_EQUALS;
-       case NODETYPE_NOTEQUALS:        if(!op) op = BC_OP_NOTEQUALS;
-       case NODETYPE_LESSTHAN:         if(!op) op = BC_OP_LESSTHAN;
-       case NODETYPE_GREATERTHAN:      if(!op) op = BC_OP_GREATERTHAN;
-       case NODETYPE_LESSTHANEQUAL:    if(!op) op = BC_OP_LESSTHANOREQUAL;
-       case NODETYPE_GREATERTHANEQUAL: if(!op) op = BC_OP_GREATERTHANOREQUAL;
-       // General Binary Operations
-       case NODETYPE_ADD:      if(!op) op = BC_OP_ADD;
-       case NODETYPE_SUBTRACT: if(!op) op = BC_OP_SUBTRACT;
-       case NODETYPE_MULTIPLY: if(!op) op = BC_OP_MULTIPLY;
-       case NODETYPE_DIVIDE:   if(!op) op = BC_OP_DIVIDE;
-       case NODETYPE_MODULO:   if(!op) op = BC_OP_MODULO;
-       case NODETYPE_BWAND:    if(!op) op = BC_OP_BITAND;
-       case NODETYPE_BWOR:     if(!op) op = BC_OP_BITOR;
-       case NODETYPE_BWXOR:    if(!op) op = BC_OP_BITXOR;
-       case NODETYPE_BITSHIFTLEFT:     if(!op) op = BC_OP_BITSHIFTLEFT;
-       case NODETYPE_BITSHIFTRIGHT:    if(!op) op = BC_OP_BITSHIFTRIGHT;
-       case NODETYPE_BITROTATELEFT:    if(!op) op = BC_OP_BITROTATELEFT;
-               ret = AST_ConvertNode(Block, Node->BinOp.Left, 1);
-               if(ret) return ret;
-               ret = _StackPop(Block, Node->BinOp.Left, SS_DATATYPE_UNDEF);    // TODO: Integer/Real/Object
-               if(ret < 0)     return -1;
-       
-               ret = AST_ConvertNode(Block, Node->BinOp.Right, 1);
-               if(ret) return ret;
-               ret = _StackPop(Block, Node->BinOp.Right, SS_DATATYPE_UNDEF);   // TODO: Integer/Real/Object
-               if(ret < 0)     return -1;
-               
-               Bytecode_AppendBinOp(Block->Handle, op);
-               _StackPush(Block, Node, ret);
-               CHECK_IF_NEEDED(1);
-               break;
-       
-       default:
-               AST_RuntimeError(Node, "BUG - SpiderScript AST_ConvertNode Unimplemented %i", Node->Type);
-               return -1;
-       }
-
-       return 0;
-}
-
-int BC_SaveValue(tAST_BlockInfo *Block, tAST_Node *DestNode)
-{
-        int    ret, type;
-       switch(DestNode->Type)
-       {
-       // Variable, simple
-       case NODETYPE_VARIABLE:
-               ret = BC_Variable_SetValue( Block, DestNode );
-               if(ret) return ret;
-               break;
-       // Array index
-       case NODETYPE_INDEX:
-               ret = AST_ConvertNode(Block, DestNode->BinOp.Left, 1);  // Array
-               if(ret) return ret;
-               ret = _StackPop(Block, DestNode->BinOp.Left, SS_DATATYPE_UNDEF);
-               if(ret < 0)     return -1;
-               if(ret != SS_DATATYPE_ARRAY && SS_GETARRAYDEPTH(ret) == 0) {
-                       AST_RuntimeError(DestNode, "Type mismatch, Expected an array, got %i",
-                               ret);
-                       return -2;
-               }
-               type = SS_DOWNARRAY(ret);
-               
-               ret = AST_ConvertNode(Block, DestNode->BinOp.Right, 1); // Offset
-               if(ret) return ret;
-               ret = _StackPop(Block, DestNode->BinOp.Right, SS_DATATYPE_INTEGER);
-               if(ret < 0)     return -1;
-               
-               Bytecode_AppendSetIndex( Block->Handle );
-               _StackPop(Block, DestNode, type);
-               break;
-       // Object element
-       case NODETYPE_ELEMENT:
-               ret = AST_ConvertNode(Block, DestNode->Scope.Element, 1);
-               if(ret) return ret;
-               ret = _StackPop(Block, DestNode->Scope.Element, SS_DATATYPE_OBJECT);
-               if(ret < 0)     return -1;
-               
-               Bytecode_AppendSetElement( Block->Handle, DestNode->Scope.Name );
-               break;
-       // Anything else
-       default:
-               // TODO: Support assigning to object attributes
-               AST_RuntimeError(DestNode, "Assignment target is not a LValue");
-               return -1;
-       }
-       return 0;
-}
-
-/**
- * \brief Define a variable
- * \param Block        Current block state
- * \param Type Type of the variable
- * \param Name Name of the variable
- * \return Boolean Failure
- */
-int BC_Variable_Define(tAST_BlockInfo *Block, int Type, const char *Name)
-{
-       tAST_Variable   *var, *prev = NULL;
-       
-       for( var = Block->FirstVar; var; prev = var, var = var->Next )
-       {
-               if( strcmp(var->Name, Name) == 0 ) {
-                       AST_RuntimeError(NULL, "Redefinition of variable '%s'", Name);
-                       return -1;
-               }
-       }
-       
-       var = malloc( sizeof(tAST_Variable) + strlen(Name) + 1 );
-       var->Next = NULL;
-       var->Type = Type;
-       strcpy(var->Name, Name);
-       
-       if(prev)        prev->Next = var;
-       else    Block->FirstVar = var;
-       
-       Bytecode_AppendDefineVar(Block->Handle, Name, Type);
-       return 0;
-}
-
-tAST_Variable *BC_Variable_Lookup(tAST_BlockInfo *Block, tAST_Node *VarNode, int CreateType)
-{
-       tAST_Variable   *var = NULL;
-       tAST_BlockInfo  *bs;
-       
-       for( bs = Block; bs; bs = bs->Parent )
-       {
-               for( var = bs->FirstVar; var; var = var->Next )
-               {
-                       if( strcmp(var->Name, VarNode->Variable.Name) == 0 )
-                               break;
-               }
-               if(var) break;
-       }
-
-       if( !var )
-       {
-//             if( Block->Script->Variant->bDyamicTyped && CreateType != SS_DATATYPE_UNDEF ) {
-//                     // Define variable
-//                     var = BC_Variable_Define(Block, CreateType, VarNode->Variable.Name, NULL);
-//             }
-//             else
-//             {
-                       AST_RuntimeError(VarNode, "Variable '%s' is undefined", VarNode->Variable.Name);
-                       return NULL;
-//             }
-       }
-               
-       #if TRACE_VAR_LOOKUPS
-       AST_RuntimeMessage(VarNode, "debug", "Variable lookup of '%s' %p type %i",
-               VarNode->Variable.Name, var, var->Type);
-       #endif
-       
-       return var;
-}
-
-/**
- * \brief Set the value of a variable
- * \return Boolean Failure
- */
-int BC_Variable_SetValue(tAST_BlockInfo *Block, tAST_Node *VarNode)
-{
-       tAST_Variable   *var;
-       
-       // TODO: Implicit definition type
-       var = BC_Variable_Lookup(Block, VarNode, SS_DATATYPE_UNDEF);
-       if(!var)        return -1;
-
-       // TODO: Check types
-
-       _StackPop(Block, VarNode, var->Type);
-       Bytecode_AppendSaveVar(Block->Handle, VarNode->Variable.Name);
-       return 0;
-}
-
-/**
- * \brief Get the value of a variable
- */
-int BC_Variable_GetValue(tAST_BlockInfo *Block, tAST_Node *VarNode)
-{
-       tAST_Variable   *var;
-
-       var = BC_Variable_Lookup(Block, VarNode, 0);    
-       if(!var)        return -1;
-       
-       _StackPush(Block, VarNode, var->Type);
-       Bytecode_AppendLoadVar(Block->Handle, VarNode->Variable.Name);
-       return 0;
-}
-
-void BC_Variable_Clear(tAST_BlockInfo *Block)
-{
-       tAST_Variable   *var;
-       for( var = Block->FirstVar; var; )
-       {
-               tAST_Variable   *tv = var->Next;
-               free( var );
-               var = tv;
-       }
-       Block->FirstVar = NULL;
-}
-
-#if 0
-void AST_RuntimeMessage(tAST_Node *Node, const char *Type, const char *Format, ...)
-{
-       va_list args;
-       
-       if(Node) {
-               fprintf(stderr, "%s:%i: ", Node->File, Node->Line);
-       }
-       fprintf(stderr, "%s: ", Type);
-       va_start(args, Format);
-       vfprintf(stderr, Format, args);
-       va_end(args);
-       fprintf(stderr, "\n");
-}
-void AST_RuntimeError(tAST_Node *Node, const char *Format, ...)
-{
-       va_list args;
-       
-       if(Node) {
-               fprintf(stderr, "%s:%i: ", Node->File, Node->Line);
-       }
-       fprintf(stderr, "error: ");
-       va_start(args, Format);
-       vfprintf(stderr, Format, args);
-       va_end(args);
-       fprintf(stderr, "\n");
-}
-#endif
-
-int _StackPush(tAST_BlockInfo *Block, tAST_Node *Node, int Type)
-{
-       if(Block->StackDepth == MAX_STACK_DEPTH - 1) {
-               AST_RuntimeError(Node, "BUG - Stack overflow in AST-Bytecode conversion (node=%i)",
-                       Node->Type);
-               return -1;
-       }
-
-       #if TRACE_TYPE_STACK
-       AST_RuntimeMessage(Node, "_StackPush", "%x - NT%i", Type, Node->Type);
-       #endif
-       Block->Stack[ ++Block->StackDepth ] = Type;
-       return Type;
-}
-
-int _StackPop(tAST_BlockInfo *Block, tAST_Node *Node, int WantedType)
-{
-       if(Block->StackDepth == 0) {
-               AST_RuntimeError(Node, "BUG - Stack underflow in AST-Bytecode conversion (node=%i)",
-                       Node->Type);
-               return -1;
-       }
-       #if TRACE_TYPE_STACK
-       AST_RuntimeMessage(Node, "_StackPop", "%x(?==%x) - NT%i",
-               Block->Stack[ Block->StackDepth ], WantedType, Node->Type);
-       #endif
-       if(WantedType != SS_DATATYPE_UNDEF && Block->Stack[ Block->StackDepth ] != SS_DATATYPE_UNDEF)
-       {
-               if( Block->Stack[ Block->StackDepth ] != WantedType ) {
-                       AST_RuntimeError(Node, "AST-Bytecode - Type mismatch (wanted %x got %x)",
-                               WantedType, Block->Stack[ Block->StackDepth ]);
-                       // TODO: Message?
-                       return -2;
-               }
-       }
-       return Block->Stack[Block->StackDepth--];
-}
-
diff --git a/Usermode/Libraries/libspiderscript.so_src/bytecode.h b/Usermode/Libraries/libspiderscript.so_src/bytecode.h
deleted file mode 100644 (file)
index 6f3734d..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * SpiderScript
- * - Bytecode definitions
- */
-#ifndef _BYTECODE_H_
-#define _BYTECODE_H_
-
-#include "bytecode_ops.h"
-
-#define BC_NS_SEPARATOR        '@'
-
-typedef struct sBC_Op  tBC_Op;
-typedef struct sBC_Function    tBC_Function;
-
-struct sBC_Op
-{
-       tBC_Op  *Next;
-        int    Operation;
-       char    bUseInteger;    // Used for serialisation
-       char    bUseString;     // Used for serialisation
-
-       void    *CacheEnt;      // Used to runtime cache function calls
-
-       union {
-               struct {
-                        int    Integer;
-                       char    String[];
-               } StringInt;
-               
-               uint64_t        Integer;
-               double  Real;
-       } Content;
-};
-
-struct sBC_Function
-{
-        int    LabelCount;
-        int    LabelSpace;
-       tBC_Op  **Labels;
-       
-        int    MaxVariableCount;
-       // NOTE: These fields are invalid after compilation
-        int    VariableCount;
-        int    VariableSpace;
-       const char      **VariableNames;
-        int    CurContextDepth;        // Used to get the real var count
-
-        int    OperationCount;
-       tBC_Op  *Operations;
-       tBC_Op  *OperationsEnd;
-};
-
-#endif
diff --git a/Usermode/Libraries/libspiderscript.so_src/bytecode_gen.c b/Usermode/Libraries/libspiderscript.so_src/bytecode_gen.c
deleted file mode 100644 (file)
index aad172d..0000000
+++ /dev/null
@@ -1,490 +0,0 @@
-/*
- * SpiderScript Library
- * by John Hodge (thePowersGang)
- * 
- * bytecode_gen.c
- * - Generate bytecode
- */
-#include <stdlib.h>
-#include <stdint.h>
-#include "bytecode_ops.h"
-#include <stdio.h>
-#include "bytecode_gen.h"
-#include <string.h>
-#include "bytecode.h"
-
-// === IMPORTS ===
-
-// === STRUCTURES ===
-
-// === PROTOTYPES ===
-tBC_Op *Bytecode_int_AllocateOp(int Operation, int ExtraBytes);
- int   Bytecode_int_AddVariable(tBC_Function *Handle, const char *Name);
-
-// === GLOBALS ===
-
-// === CODE ===
-tBC_Op *Bytecode_int_AllocateOp(int Operation, int ExtraBytes)
-{
-       tBC_Op  *ret;
-
-       ret = malloc(sizeof(tBC_Op) + ExtraBytes);
-       if(!ret)        return NULL;
-
-       ret->Next = NULL;
-       ret->Operation = Operation;
-       ret->bUseInteger = 0;
-       ret->bUseString = (ExtraBytes > 0);
-       ret->CacheEnt = NULL;
-
-       return ret;
-}
-
-tBC_Function *Bytecode_CreateFunction(tScript_Function *Fcn)
-{
-       tBC_Function *ret;
-        int    i;
-
-       ret = malloc(sizeof(tBC_Function));
-       if(!ret)        return NULL;
-       
-       ret->LabelSpace = ret->LabelCount = 0;
-       ret->Labels = NULL;
-
-       ret->MaxVariableCount = 0;
-       ret->CurContextDepth = 0;       
-       ret->VariableCount = ret->VariableSpace = 0;
-       ret->VariableNames = NULL;
-
-       ret->OperationCount = 0;
-       ret->Operations = NULL;
-       ret->OperationsEnd = (void*)&ret->Operations;
-
-       for( i = 0; i < Fcn->ArgumentCount; i ++ )
-       {
-               Bytecode_int_AddVariable(ret, Fcn->Arguments[i].Name);
-       }
-
-       return ret;
-}
-
-void Bytecode_DeleteFunction(tBC_Function *Fcn)
-{
-       tBC_Op  *op;
-       for( op = Fcn->Operations; op; )
-       {
-               tBC_Op  *nextop = op->Next;
-               free(op);
-               op = nextop;
-       }
-       free(Fcn->VariableNames);
-       free(Fcn->Labels);
-       free(Fcn);
-}
-
-int StringList_GetString(tStringList *List, const char *String, int Length)
-{
-        int    strIdx = 0;
-       tString *ent;
-       for(ent = List->Head; ent; ent = ent->Next, strIdx ++)
-       {
-               if(ent->Length == Length && memcmp(ent->Data, String, Length) == 0)     break;
-       }
-       if( ent ) {
-               ent->RefCount ++;
-       }
-       else {
-               ent = malloc(sizeof(tString) + Length + 1);
-               if(!ent)        return -1;
-               ent->Next = NULL;
-               ent->Length = Length;
-               ent->RefCount = 1;
-               memcpy(ent->Data, String, Length);
-               ent->Data[Length] = '\0';
-               
-               if(List->Head)
-                       List->Tail->Next = ent;
-               else
-                       List->Head = ent;
-               List->Tail = ent;
-               List->Count ++;
-       }
-       return strIdx;
-}
-
-int Bytecode_int_Serialize(const tBC_Function *Function, void *Output, int *LabelOffsets, tStringList *Strings)
-{
-       tBC_Op  *op;
-        int    len = 0, idx = 0;
-        int    i;
-
-       void _put_byte(uint8_t byte)
-       {
-               uint8_t *buf = Output;
-               if(Output)      buf[len] = byte;
-               len ++;
-       }
-
-       void _put_dword(uint32_t value)
-       {
-               uint8_t *buf = Output;
-               if(Output) {
-                       buf[len+0] = value & 0xFF;
-                       buf[len+1] = value >> 8;
-                       buf[len+2] = value >> 16;
-                       buf[len+3] = value >> 24;
-               }
-               len += 4;
-       }
-
-       void _put_index(uint32_t value)
-       {
-               if( !Output && !value ) {
-                       len += 5;
-                       return ;
-               }
-               if( value < 0x8000 ) {
-                       _put_byte(value >> 8);
-                       _put_byte(value & 0xFF);
-               }
-               else if( value < 0x400000 ) {
-                       _put_byte( (value >> 16) | 0x80 );
-                       _put_byte(value >> 8);
-                       _put_byte(value & 0xFF);
-               }
-               else {
-                       _put_byte( 0xC0 );
-                       _put_byte(value >> 24);
-                       _put_byte(value >> 16);
-                       _put_byte(value >> 8 );
-                       _put_byte(value & 0xFF);
-               }
-       }       
-
-       void _put_qword(uint64_t value)
-       {
-               if( value < 0x80 ) {    // 7 bits into 1 byte
-                       _put_byte(value);
-               }
-               else if( !(value >> (8+6)) ) {  // 14 bits packed into 2 bytes
-                       _put_byte( 0x80 | ((value >> 8) & 0x3F) );
-                       _put_byte( value & 0xFF );
-               }
-               else if( !(value >> (32+5)) ) { // 37 bits into 5 bytes
-                       _put_byte( 0xC0 | ((value >> 32) & 0x1F) );
-                       _put_dword(value & 0xFFFFFFFF);
-               }
-               else {
-                       _put_byte( 0xE0 );      // 64 (actually 68) bits into 9 bytes
-                       _put_dword(value & 0xFFFFFFFF);
-                       _put_dword(value >> 32);
-               }
-       }
-
-       void _put_double(double value)
-       {
-               // TODO: Machine agnostic
-               if(Output) {
-                       *(double*)( (char*)Output + len ) = value;
-               }
-               len += sizeof(double);
-       }
-
-       void _put_string(const char *str, int len)
-       {
-                int    strIdx = 0;
-               if( Output ) {
-                       strIdx = StringList_GetString(Strings, str, len);
-               }
-       
-               // TODO: Relocations    
-               _put_index(strIdx);
-       }
-
-       for( op = Function->Operations; op; op = op->Next, idx ++ )
-       {
-               // If first run, convert labels into byte offsets
-               if( !Output )
-               {
-                       for( i = 0; i < Function->LabelCount; i ++ )
-                       {
-                               if(LabelOffsets[i])     continue;
-                               if(op != Function->Labels[i])   continue;
-                               
-                               LabelOffsets[i] = len;
-                       }
-               }
-
-               _put_byte(op->Operation);
-               switch(op->Operation)
-               {
-               // Relocate jumps (the value only matters if `Output` is non-NULL)
-               case BC_OP_JUMP:
-               case BC_OP_JUMPIF:
-               case BC_OP_JUMPIFNOT:
-                       // TODO: Relocations?
-                       _put_index( LabelOffsets[op->Content.StringInt.Integer] );
-                       break;
-               // Special case for inline values
-               case BC_OP_LOADINT:
-                       _put_qword(op->Content.Integer);
-                       break;
-               case BC_OP_LOADREAL:
-                       _put_double(op->Content.Real);
-                       break;
-               case BC_OP_LOADSTR:
-                       _put_string(op->Content.StringInt.String, op->Content.StringInt.Integer);
-                       break;
-               // Everthing else just gets handled nicely
-               default:
-                       if( op->bUseString )
-                               _put_string(op->Content.StringInt.String, strlen(op->Content.StringInt.String));
-                       if( op->bUseInteger )
-                               _put_index(op->Content.StringInt.Integer);
-                       break;
-               }
-       }
-
-       return len;
-}
-
-char *Bytecode_SerialiseFunction(const tBC_Function *Function, int *Length, tStringList *Strings)
-{
-        int    len;
-        int    *label_offsets;
-       char    *code;
-
-       label_offsets = calloc( sizeof(int), Function->LabelCount );
-       if(!label_offsets)      return NULL;
-
-       len = Bytecode_int_Serialize(Function, NULL, label_offsets, Strings);
-
-       code = malloc(len);
-
-       // Update length to the correct length (may decrease due to encoding)   
-       len = Bytecode_int_Serialize(Function, code, label_offsets, Strings);
-
-       free(label_offsets);
-
-       *Length = len;
-
-       return code;
-}
-
-int Bytecode_AllocateLabel(tBC_Function *Handle)
-{
-        int    ret;
-       
-       if( Handle->LabelCount == Handle->LabelSpace ) {
-               void *tmp;
-               Handle->LabelSpace += 20;       // TODO: Don't hardcode increment
-               tmp = realloc(Handle->Labels, Handle->LabelSpace * sizeof(Handle->Labels[0]));
-               if( !tmp ) {
-                       Handle->LabelSpace -= 20;
-                       return -1;
-               }
-               Handle->Labels = tmp;
-       }
-       ret = Handle->LabelCount ++;
-       Handle->Labels[ret] = 0;
-       return ret;
-}
-
-void Bytecode_SetLabel(tBC_Function *Handle, int Label)
-{
-       if(Label < 0)   return ;
-       
-       if(Label >= Handle->LabelCount) return ;
-
-       Handle->Labels[Label] = Handle->OperationsEnd;
-       return ;
-}
-
-void Bytecode_int_AppendOp(tBC_Function *Fcn, tBC_Op *Op)
-{
-       Op->Next = NULL;
-       if( Fcn->Operations )
-               Fcn->OperationsEnd->Next = Op;
-       else
-               Fcn->Operations = Op;
-       Fcn->OperationsEnd = Op;
-}
-
-int Bytecode_int_AddVariable(tBC_Function *Handle, const char *Name)
-{
-       if(Handle->VariableCount == Handle->VariableSpace) {
-               void    *tmp;
-               Handle->VariableSpace += 10;
-               tmp = realloc(Handle->VariableNames, Handle->VariableSpace * sizeof(Handle->VariableNames[0]));
-               if(!tmp)        return -1;      // TODO: Error
-               Handle->VariableNames = tmp;
-       }
-       Handle->VariableNames[Handle->VariableCount] = Name;
-       Handle->VariableCount ++;
-       // Get max count (used when executing to get the frame size)
-       if(Handle->VariableCount - Handle->CurContextDepth >= Handle->MaxVariableCount)
-               Handle->MaxVariableCount = Handle->VariableCount - Handle->CurContextDepth;
-//     printf("_AddVariable: %s given %i\n", Name, Handle->VariableCount - Handle->CurContextDepth - 1);
-       return Handle->VariableCount - Handle->CurContextDepth - 1;
-}
-
-int Bytecode_int_GetVarIndex(tBC_Function *Handle, const char *Name)
-{
-        int    i, context_depth = Handle->CurContextDepth;
-       // Get the start of this context
-       for( i = Handle->VariableCount; i --; )
-       {
-               if( !Handle->VariableNames[i] ) {
-                       context_depth --;
-                       continue ;
-               }
-               if( strcmp(Name, Handle->VariableNames[i]) == 0 )
-                       return i - context_depth;
-       }
-       return -1;
-}
-
-#define DEF_BC_NONE(_op) { \
-       tBC_Op *op = Bytecode_int_AllocateOp(_op, 0); \
-       op->Content.Integer = 0; \
-       op->bUseInteger = 0; \
-       Bytecode_int_AppendOp(Handle, op);\
-}
-
-#define DEF_BC_INT(_op, _int) {\
-       tBC_Op *op = Bytecode_int_AllocateOp(_op, 0);\
-       op->Content.StringInt.Integer = _int;\
-       op->bUseInteger = 1;\
-       op->bUseString = 0;\
-       Bytecode_int_AppendOp(Handle, op);\
-}
-
-#define DEF_BC_STRINT(_op, _str, _int) { \
-       tBC_Op *op = Bytecode_int_AllocateOp(_op, strlen(_str));\
-       op->Content.StringInt.Integer = _int;\
-       strcpy(op->Content.StringInt.String, _str);\
-       op->bUseInteger = 1;\
-       op->bUseString = 1;\
-       Bytecode_int_AppendOp(Handle, op);\
-}
-#define DEF_BC_STR(_op, _str) {\
-       tBC_Op *op = Bytecode_int_AllocateOp(_op, strlen(_str));\
-       strcpy(op->Content.StringInt.String, _str);\
-       op->bUseInteger = 0;\
-       Bytecode_int_AppendOp(Handle, op);\
-}
-
-// --- Flow Control
-void Bytecode_AppendJump(tBC_Function *Handle, int Label)
-       DEF_BC_INT(BC_OP_JUMP, Label)
-void Bytecode_AppendCondJump(tBC_Function *Handle, int Label)
-       DEF_BC_INT(BC_OP_JUMPIF, Label)
-void Bytecode_AppendCondJumpNot(tBC_Function *Handle, int Label)
-       DEF_BC_INT(BC_OP_JUMPIFNOT, Label)
-void Bytecode_AppendReturn(tBC_Function *Handle)
-       DEF_BC_NONE(BC_OP_RETURN);
-
-// --- Variables
-void Bytecode_AppendLoadVar(tBC_Function *Handle, const char *Name)
-       DEF_BC_INT(BC_OP_LOADVAR, Bytecode_int_GetVarIndex(Handle, Name))
-//     DEF_BC_STR(BC_OP_LOADVAR, Name)
-void Bytecode_AppendSaveVar(tBC_Function *Handle, const char *Name)    // (Obj->)?var = 
-       DEF_BC_INT(BC_OP_SAVEVAR, Bytecode_int_GetVarIndex(Handle, Name))
-//     DEF_BC_STR(BC_OP_SAVEVAR, Name)
-
-// --- Constants
-void Bytecode_AppendConstInt(tBC_Function *Handle, uint64_t Value)
-{
-       tBC_Op *op = Bytecode_int_AllocateOp(BC_OP_LOADINT, 0);
-       op->Content.Integer = Value;
-       Bytecode_int_AppendOp(Handle, op);
-}
-void Bytecode_AppendConstReal(tBC_Function *Handle, double Value)
-{
-       tBC_Op *op = Bytecode_int_AllocateOp(BC_OP_LOADREAL, 0);
-       op->Content.Real = Value;
-       Bytecode_int_AppendOp(Handle, op);
-}
-void Bytecode_AppendConstString(tBC_Function *Handle, const void *Data, size_t Length)
-{
-       tBC_Op *op = Bytecode_int_AllocateOp(BC_OP_LOADSTR, Length+1);
-       op->Content.StringInt.Integer = Length;
-       memcpy(op->Content.StringInt.String, Data, Length);
-       op->Content.StringInt.String[Length] = 0;
-       Bytecode_int_AppendOp(Handle, op);
-}
-void Bytecode_AppendConstNull(tBC_Function *Handle)
-       DEF_BC_NONE(BC_OP_LOADNULL)
-
-// --- Indexing / Scoping
-void Bytecode_AppendElement(tBC_Function *Handle, const char *Name)
-       DEF_BC_STR(BC_OP_ELEMENT, Name)
-void Bytecode_AppendSetElement(tBC_Function *Handle, const char *Name)
-       DEF_BC_STR(BC_OP_SETELEMENT, Name)
-void Bytecode_AppendIndex(tBC_Function *Handle)
-       DEF_BC_NONE(BC_OP_INDEX)
-void Bytecode_AppendSetIndex(tBC_Function *Handle)
-       DEF_BC_NONE(BC_OP_SETINDEX);
-
-void Bytecode_AppendCreateObj(tBC_Function *Handle, const char *Name, int ArgumentCount)
-       DEF_BC_STRINT(BC_OP_CREATEOBJ, Name, ArgumentCount)
-void Bytecode_AppendMethodCall(tBC_Function *Handle, const char *Name, int ArgumentCount)
-       DEF_BC_STRINT(BC_OP_CALLMETHOD, Name, ArgumentCount)
-void Bytecode_AppendFunctionCall(tBC_Function *Handle, const char *Name, int ArgumentCount)
-       DEF_BC_STRINT(BC_OP_CALLFUNCTION, Name, ArgumentCount)
-
-void Bytecode_AppendBinOp(tBC_Function *Handle, int Operation)
-       DEF_BC_NONE(Operation)
-void Bytecode_AppendUniOp(tBC_Function *Handle, int Operation)
-       DEF_BC_NONE(Operation)
-void Bytecode_AppendCast(tBC_Function *Handle, int Type)
-       DEF_BC_INT(BC_OP_CAST, Type)
-void Bytecode_AppendDuplicate(tBC_Function *Handle)
-       DEF_BC_NONE(BC_OP_DUPSTACK);
-void Bytecode_AppendDelete(tBC_Function *Handle)
-       DEF_BC_NONE(BC_OP_DELSTACK);
-
-// Does some bookeeping to allocate variable slots at compile time
-void Bytecode_AppendEnterContext(tBC_Function *Handle)
-{
-       Handle->CurContextDepth ++;
-       Bytecode_int_AddVariable(Handle, NULL); // NULL to record the extent of this    
-
-       DEF_BC_NONE(BC_OP_ENTERCONTEXT)
-}
-void Bytecode_AppendLeaveContext(tBC_Function *Handle)
-{
-        int    i;
-       for( i = Handle->VariableCount; i --; )
-       {
-               if( Handle->VariableNames[i] == NULL )  break;
-       }
-       Handle->CurContextDepth --;
-       Handle->VariableCount = i;
-
-       DEF_BC_NONE(BC_OP_LEAVECONTEXT);
-}
-//void Bytecode_AppendImportNamespace(tBC_Function *Handle, const char *Name);
-//     DEF_BC_STRINT(BC_OP_IMPORTNS, Name, 0)
-void Bytecode_AppendDefineVar(tBC_Function *Handle, const char *Name, int Type)
-{
-        int    i;
-       #if 1
-       // Get the start of this context
-       for( i = Handle->VariableCount; i --; )
-       {
-               if( Handle->VariableNames[i] == NULL )  break;
-       }
-       // Check for duplicate allocation
-       for( i ++; i < Handle->VariableCount; i ++ )
-       {
-               if( strcmp(Name, Handle->VariableNames[i]) == 0 )
-                       return ;
-       }
-       #endif
-
-       i = Bytecode_int_AddVariable(Handle, Name);
-//     printf("Variable %s given slot %i\n", Name, i); 
-
-       DEF_BC_STRINT(BC_OP_DEFINEVAR, Name, (Type&0xFFFF) | (i << 16))
-}
diff --git a/Usermode/Libraries/libspiderscript.so_src/bytecode_gen.h b/Usermode/Libraries/libspiderscript.so_src/bytecode_gen.h
deleted file mode 100644 (file)
index 71c5af1..0000000
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * SpiderScript Library
- * - By John Hodge (thePowersGang)
- *
- * bytecode_gen.h
- * - Bytecode Generation header
- */
-#ifndef _BYTECODE_GEN_H_
-#define _BYTECODE_GEN_H_
-
-#include "common.h"
-#include "ast.h"
-#include "bytecode.h"
-
-typedef struct sStringList     tStringList;
-typedef struct sString tString;
-
-struct sString
-{
-       tString *Next;
-        int    Length;
-        int    RefCount;
-       char    Data[];
-};
-
-struct sStringList
-{
-       tString *Head;
-       tString *Tail;
-        int    Count;
-};
-
-
-extern int     Bytecode_ConvertScript(tSpiderScript *Script, const char *DestFile);
-extern tBC_Function    *Bytecode_ConvertFunction(tScript_Function *Fcn);
-extern tBC_Function    *Bytecode_NewBlankFunction(void);
-extern void    Bytecode_DeleteFunction(tBC_Function *Fcn);
-
-extern char *Bytecode_SerialiseFunction(const tBC_Function *Function, int *Length, tStringList *Strings);
-extern int     StringList_GetString(tStringList *List, const char *String, int Length);
-extern tBC_Function    *Bytecode_CreateFunction(tScript_Function *Fcn);
-
-extern int     Bytecode_AllocateLabel(tBC_Function *Handle);
-extern void    Bytecode_SetLabel(tBC_Function *Handle, int Label);
-// Bytecode adding
-// - Flow Control
-extern void    Bytecode_AppendJump(tBC_Function *Handle, int Label);
-extern void    Bytecode_AppendCondJump(tBC_Function *Handle, int Label);
-extern void     Bytecode_AppendCondJumpNot(tBC_Function *Handle, int Label);
-extern void    Bytecode_AppendReturn(tBC_Function *Handle);
-// - Operation Stack
-//  > Load/Store
-extern void    Bytecode_AppendLoadVar(tBC_Function *Handle, const char *Name);
-extern void    Bytecode_AppendSaveVar(tBC_Function *Handle, const char *Name); // (Obj->)?var = 
-extern void    Bytecode_AppendConstInt(tBC_Function *Handle, uint64_t Value);
-extern void    Bytecode_AppendConstReal(tBC_Function *Handle, double Value);
-extern void    Bytecode_AppendConstString(tBC_Function *Handle, const void *Data, size_t Length);
-extern void    Bytecode_AppendConstNull(tBC_Function *Handle);
-//  > Scoping
-extern void    Bytecode_AppendElement(tBC_Function *Handle, const char *Name); // Obj->SubObj
-extern void    Bytecode_AppendSetElement(tBC_Function *Handle, const char *Name);      // Set an object member
-extern void    Bytecode_AppendIndex(tBC_Function *Handle);     // Index into an array
-extern void    Bytecode_AppendSetIndex(tBC_Function *Handle);  // Write an array element
-//  > Function Calls
-extern void    Bytecode_AppendCreateObj(tBC_Function *Handle, const char *Name, int ArgumentCount);
-extern void    Bytecode_AppendMethodCall(tBC_Function *Handle, const char *Name, int ArgumentCount);
-extern void    Bytecode_AppendFunctionCall(tBC_Function *Handle, const char *Name, int ArgumentCount);
-//  > Manipulation
-extern void    Bytecode_AppendBinOp(tBC_Function *Handle, int Operation);
-extern void    Bytecode_AppendUniOp(tBC_Function *Handle, int Operation);
-extern void    Bytecode_AppendCast(tBC_Function *Handlde, int Type);
-extern void    Bytecode_AppendDuplicate(tBC_Function *Handlde);
-extern void    Bytecode_AppendDelete(tBC_Function *Handle);
-// - Context
-//   TODO: Are contexts needed? Should variables be allocated like labels?
-extern void    Bytecode_AppendEnterContext(tBC_Function *Handle);
-extern void    Bytecode_AppendLeaveContext(tBC_Function *Handle);
-//extern void  Bytecode_AppendImportNamespace(tBC_Function *Handle, const char *Name);
-extern void    Bytecode_AppendDefineVar(tBC_Function *Handle, const char *Name, int Type);
-
-#endif
-
diff --git a/Usermode/Libraries/libspiderscript.so_src/bytecode_makefile.c b/Usermode/Libraries/libspiderscript.so_src/bytecode_makefile.c
deleted file mode 100644 (file)
index 3c0347b..0000000
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
- * SpiderScript Library
- * by John Hodge (thePowersGang)
- * 
- * bytecode_makefile.c
- * - Generate a bytecode file
- */
-#include <stdlib.h>
-#include "ast.h"
-#include "bytecode_gen.h"
-#include <stdio.h>
-#include <string.h>
-
-// === IMPORTS ===
-
-// === PROTOTYPES ===
-
-// === GLOBALS ===
-
-// === CODE ===
-int SpiderScript_SaveBytecode(tSpiderScript *Script, const char *DestFile)
-{
-       tStringList     strings = {0};
-       tScript_Function        *fcn;
-       FILE    *fp;
-        int    fcn_hdr_offset = 0;
-        int    fcn_count = 0;
-        int    strtab_ofs;
-        int    i;
-
-       void _put8(uint8_t val)
-       {
-               fwrite(&val, 1, 1, fp);
-       }
-       void _put32(uint32_t val)
-       {
-               _put8(val & 0xFF);
-               _put8(val >> 8);
-               _put8(val >> 16);
-               _put8(val >> 24);
-       }
-
-       fp = fopen(DestFile, "wb");
-       if(!fp) return 1;
-       // Create header
-       fwrite("SSBC\r\n\xBC\x55", 8, 1, fp);
-       _put32(0);      // Function count, to be filled
-       _put32(0);      // String count
-       _put32(0);      // String table offset
-       // TODO: Variant info
-
-       fcn_hdr_offset = ftell(fp);
-
-       // Create function descriptors
-       for(fcn = Script->Functions; fcn; fcn = fcn->Next, fcn_count ++)
-       {
-               _put32( StringList_GetString(&strings, fcn->Name, strlen(fcn->Name)) );
-               _put32( 0 );    // Code offset
-               // TODO: Namespace
-               _put8( fcn->ReturnType );
-               
-               if(fcn->ArgumentCount > 255) {
-                       // ERROR: Too many args
-                       return 2;
-               }
-               _put8( fcn->ArgumentCount );
-
-               // Argument types?
-               for( i = 0; i < fcn->ArgumentCount; i ++ )
-               {
-                       _put32( StringList_GetString(&strings, fcn->Arguments[i].Name, strlen(fcn->Arguments[i].Name)) );
-                       _put8( fcn->Arguments[i].Type );
-               }
-       }
-
-       // Put function code in
-       for(fcn = Script->Functions; fcn; fcn = fcn->Next)
-       {
-               char    *code;
-                int    len, code_pos;
-       
-               // Fix header   
-               code_pos = ftell(fp);
-               fseek(fp, SEEK_SET, fcn_hdr_offset + 4);
-               _put32( code_pos );
-               fseek(fp, SEEK_SET, code_pos );
-
-               fcn_hdr_offset += 4+4+1+1+(4+1)*fcn->ArgumentCount;
-               
-               // Write code
-               if( !fcn->BCFcn )
-                       Bytecode_ConvertFunction(fcn);
-               if( !fcn->BCFcn )
-               {
-                       fclose(fp);
-                       return 1;
-               }
-               code = Bytecode_SerialiseFunction(fcn->BCFcn, &len, &strings);
-               fwrite(code, len, 1, fp);
-               free(code);
-       }
-
-       // String table
-       strtab_ofs = ftell(fp);
-       {
-                int    string_offset = strtab_ofs + (4+4)*strings.Count;
-               tString *str;
-               // Array
-               for(str = strings.Head; str; str = str->Next)
-               {
-                       _put32(str->Length);
-                       _put32(string_offset);
-                       string_offset += str->Length + 1;
-               }
-               // Data
-               for(str = strings.Head; str;)
-               {
-                       tString *nextstr = str->Next;
-                       fwrite(str->Data, str->Length, 1, fp);
-                       _put8(0);       // NULL separator
-                       free(str);
-                       str = nextstr;
-               }
-               strings.Head = NULL;
-               strings.Tail = NULL;
-       }
-
-       // Fix header
-       fseek(fp, 8, SEEK_SET);
-       _put32(fcn_count);
-       _put32(strings.Count);
-       _put32(strtab_ofs);
-
-       fclose(fp);
-
-       return 0;
-}
-
diff --git a/Usermode/Libraries/libspiderscript.so_src/bytecode_ops.h b/Usermode/Libraries/libspiderscript.so_src/bytecode_ops.h
deleted file mode 100644 (file)
index 4db753e..0000000
+++ /dev/null
@@ -1,70 +0,0 @@
-/**
- */
-#ifndef _BYTECODE_OPS_H_
-#define _BYTECODE_OPS_H_
-
-enum eBC_Ops
-{
-       BC_OP_NOP,
-       
-       BC_OP_JUMP,
-       BC_OP_JUMPIF,
-       BC_OP_JUMPIFNOT,
-       
-       BC_OP_RETURN,   // = 4
-       BC_OP_CALLFUNCTION,
-       BC_OP_CALLMETHOD,
-       BC_OP_CREATEOBJ,        
-       
-       BC_OP_LOADVAR,  // = 8
-       BC_OP_SAVEVAR,
-
-       BC_OP_LOADINT,  // = 10
-       BC_OP_LOADREAL,
-       BC_OP_LOADSTR,
-       BC_OP_LOADNULL,
-
-       BC_OP_DUPSTACK, // = 14
-       BC_OP_DELSTACK, // 
-       BC_OP_CAST,     //
-       
-       BC_OP_ELEMENT,  // = 17
-       BC_OP_SETELEMENT,
-       BC_OP_INDEX,
-       BC_OP_SETINDEX,
-
-       BC_OP_ENTERCONTEXT,     // = 21
-       BC_OP_LEAVECONTEXT,
-       BC_OP_DEFINEVAR,
-
-       // Operations
-       BC_OP_LOGICNOT, // 24
-       BC_OP_LOGICAND,
-       BC_OP_LOGICOR,
-       BC_OP_LOGICXOR,
-
-       BC_OP_BITNOT,   // 28
-       BC_OP_BITAND,
-       BC_OP_BITOR,
-       BC_OP_BITXOR,
-
-       BC_OP_BITSHIFTLEFT,     // 32
-       BC_OP_BITSHIFTRIGHT,
-       BC_OP_BITROTATELEFT,
-
-       BC_OP_NEG,      // 35
-       BC_OP_ADD,
-       BC_OP_SUBTRACT,
-       BC_OP_MULTIPLY,
-       BC_OP_DIVIDE,
-       BC_OP_MODULO,
-
-       BC_OP_EQUALS,   // 41
-       BC_OP_NOTEQUALS,
-       BC_OP_LESSTHAN,
-       BC_OP_LESSTHANOREQUAL,
-       BC_OP_GREATERTHAN,
-       BC_OP_GREATERTHANOREQUAL
-};
-
-#endif
diff --git a/Usermode/Libraries/libspiderscript.so_src/bytecode_optimise.c b/Usermode/Libraries/libspiderscript.so_src/bytecode_optimise.c
deleted file mode 100644 (file)
index 3da6aa5..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * SpiderScript Library
- * by John Hodge (thePowersGang)
- * 
- * bytecode_gen.c
- * - Generate bytecode
- */
-#include <stdlib.h>
-#include "bytecode_ops.h"
-
-// Patterns:
-// TODO: Figure out what optimisations can be done
-
-int Bytecode_OptimizeFunction(tBC_Function *Function)
-{
-       for( op = Function->Operations; op; op = op->Next, idx ++ )
-       {
-       }
-}
diff --git a/Usermode/Libraries/libspiderscript.so_src/common.h b/Usermode/Libraries/libspiderscript.so_src/common.h
deleted file mode 100644 (file)
index f2bb3e6..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * SpiderScript
- * - By John Hodge (thePowersGang)
- */
-#ifndef _COMMON_H_
-#define _COMMON_H_
-
-#include <spiderscript.h>
-
-typedef struct sScript_Function        tScript_Function;
-typedef struct sScript_Arg     tScript_Arg;
-
-struct sSpiderScript
-{
-       tSpiderVariant  *Variant;
-       tScript_Function        *Functions;
-       tScript_Function        *LastFunction;
-       char    *CurNamespace;  //!< Current namespace prefix (NULL = Root) - No trailing .
-};
-
-struct sScript_Arg
-{
-        int    Type;
-       char    *Name;
-};
-
-struct sScript_Function
-{
-       tScript_Function        *Next;
-       // char *Namespace;
-       char    *Name;
-
-        int    ReturnType;
-       
-       struct sAST_Node        *ASTFcn;
-       struct sBC_Function     *BCFcn;
-
-        int    ArgumentCount;
-       tScript_Arg     Arguments[];
-};
-
-#endif
-
diff --git a/Usermode/Libraries/libspiderscript.so_src/exec.c b/Usermode/Libraries/libspiderscript.so_src/exec.c
deleted file mode 100644 (file)
index 5822d9d..0000000
+++ /dev/null
@@ -1,432 +0,0 @@
-/*
-* SpiderScript Library
-* by John Hodge (thePowersGang)
-* 
-* bytecode_makefile.c
-* - Generate a bytecode file
-*/
-#include <stdlib.h>
-#include "common.h"
-#include "ast.h"
-#include <stdio.h>
-#include <string.h>
-#include <stdarg.h>
-
-#define BC_NS_SEPARATOR        '@'
-
-// === IMPORTS ===
-extern tSpiderFunction *gpExports_First;
-extern tSpiderNamespace        gExportNamespaceRoot;
-extern tSpiderValue    *AST_ExecuteFunction(tSpiderScript *Script, tScript_Function *Fcn, int NArguments, tSpiderValue **Arguments);
-extern tSpiderValue    *Bytecode_ExecuteFunction(tSpiderScript *Script, tScript_Function *Fcn, int NArguments, tSpiderValue **Args);
-
-// === PROTOTYPES ===
-void   AST_RuntimeMessage(tAST_Node *Node, const char *Type, const char *Format, ...);
-void   AST_RuntimeError(tAST_Node *Node, const char *Format, ...);
-
-// === CODE ===
-void *SpiderScript_int_GetNamespace(tSpiderScript *Script, tSpiderNamespace *RootNamespace,
-       const char *BasePath, const char *ItemPath,
-       const char **ItemName
-       )
-{
-        int    len;
-       const char      *name;
-       const char      *end;
-        int    bTriedBase;
-       
-       tSpiderNamespace        *lastns, *ns;
-
-       // Prepend the base namespace
-       if( BasePath ) {
-               name = BasePath;
-               bTriedBase = 0;
-       }
-       else {
-               bTriedBase = 1;
-               name = ItemPath;
-       }
-       
-       // Scan
-       lastns = RootNamespace;
-       do {
-               end = strchr(name, BC_NS_SEPARATOR);
-               if(!end) {
-                       if( !bTriedBase )
-                               len = strlen(name);
-                       else
-                               break;
-               }
-               else {
-                       len = end - name;
-               }
-
-               // Check for this level
-               for( ns = lastns->FirstChild; ns; ns = ns->Next )
-               {
-//                     printf("%p %.*s == %s\n", lastns, len, name, ns->Name);
-                       if( strncmp(name, ns->Name, len) == 0 && ns->Name[len] == 0 )
-                               break ;
-               }
-               
-               if(!ns) return NULL;
-
-               if(!end && !bTriedBase) {
-                       end = ItemPath - 1;     // -1 to counter (name = end + 1)
-                       bTriedBase = 1;
-               }
-
-               lastns = ns;
-               name = end + 1;
-       } while( end );
-
-       *ItemName = name;
-
-       return lastns;
-}
-
-tSpiderFunction *SpiderScript_int_GetNativeFunction(tSpiderScript *Script, tSpiderNamespace *RootNamespace,
-       const char *BasePath, const char *FunctionPath)
-{
-       tSpiderNamespace *ns;
-       const char *name;
-       tSpiderFunction *fcn;
-
-       ns = SpiderScript_int_GetNamespace(Script, RootNamespace, BasePath, FunctionPath, &name);
-       if(!ns) return NULL;
-
-       for( fcn = ns->Functions; fcn; fcn = fcn->Next )
-       {
-               if( strcmp(name, fcn->Name) == 0 )
-                       return fcn;
-       }
-       
-       return NULL;
-}
-
-tSpiderObjectDef *SpiderScript_int_GetNativeClass(tSpiderScript *Script, tSpiderNamespace *RootNamespace,
-       const char *BasePath, const char *ClassPath
-       )
-{
-       tSpiderNamespace *ns;
-       const char *name;
-       tSpiderObjectDef *class;
-
-       ns = SpiderScript_int_GetNamespace(Script, RootNamespace, BasePath, ClassPath, &name);
-       if(!ns) return NULL;
-       
-       for( class = ns->Classes; class; class = class->Next )
-       {
-               if( strcmp(name, class->Name) == 0 )
-                       return class;
-       }
-
-       return NULL;
-}
-
-/**
- * \brief Execute a script function
- * \param Script       Script context to execute in
- * \param Namespace    Namespace to search for the function
- * \param Function     Function name to execute
- * \param NArguments   Number of arguments to pass
- * \param Arguments    Arguments passed
- */
-tSpiderValue *SpiderScript_ExecuteFunction(tSpiderScript *Script,
-       const char *Function,
-       const char *DefaultNamespaces[],
-       int NArguments, tSpiderValue **Arguments,
-       void **FunctionIdent
-       )
-{
-       tSpiderValue    *ret = ERRPTR;
-       tSpiderFunction *fcn = NULL;
-       tScript_Function        *sfcn;
-        int    i;
-
-       if( FunctionIdent && *FunctionIdent ) {
-               if( *(intptr_t*)FunctionIdent & 1 ) {
-                       sfcn = (void*)( *(intptr_t*)FunctionIdent & ~1 );
-                       goto _exec_sfcn;
-               }
-               else {
-                       fcn = *FunctionIdent;
-                       goto _exec_fcn;
-               }
-       }
-
-       // Scan list, Last item should always be NULL, so abuse that to check non-prefixed      
-       for( i = 0; i == 0 || (DefaultNamespaces && DefaultNamespaces[i-1]); i ++ )
-       {
-               const char *ns = DefaultNamespaces ? DefaultNamespaces[i] : NULL;
-               fcn = SpiderScript_int_GetNativeFunction(Script, &Script->Variant->RootNamespace, ns, Function);
-               if( fcn )       break;
-
-               fcn = SpiderScript_int_GetNativeFunction(Script, &gExportNamespaceRoot, ns, Function);
-               if( fcn )       break;
-       
-               // TODO: Script namespacing
-       }
-
-       // Search the variant's global exports
-       if( !fcn )
-       {
-               for( fcn = Script->Variant->Functions; fcn; fcn = fcn->Next )
-               {
-                       if( strcmp( fcn->Name, Function ) == 0 )
-                               break;
-               }
-       }
-       
-       // Fourth: Search language exports
-       if( !fcn )
-       {
-               for( fcn = gpExports_First; fcn; fcn = fcn->Next )
-               {
-                       if( strcmp( fcn->Name, Function ) == 0 )
-                               break;
-               }
-       }
-       
-       // Find the function in the script?
-       // TODO: Script namespacing
-       if( !fcn && strchr(Function, BC_NS_SEPARATOR) == NULL )
-       {
-               for( sfcn = Script->Functions; sfcn; sfcn = sfcn->Next )
-               {
-                       if( strcmp(sfcn->Name, Function) == 0 )
-                               break;
-               }
-       _exec_sfcn:
-               // Execute!
-               if(sfcn)
-               {
-                       if( sfcn->BCFcn )
-                               ret = Bytecode_ExecuteFunction(Script, sfcn, NArguments, Arguments);
-                       else
-                               ret = AST_ExecuteFunction(Script, sfcn, NArguments, Arguments);
-
-                       if( FunctionIdent ) {
-                               *FunctionIdent = sfcn;
-                               // Abuses alignment requirements on almost all platforms
-                               *(intptr_t*)FunctionIdent |= 1;
-                       }
-
-                       return ret;
-               }
-       }
-
-_exec_fcn:
-       if(fcn)
-       {
-               // Execute!
-               // TODO: Type Checking
-               ret = fcn->Handler( Script, NArguments, Arguments );
-       
-               if( FunctionIdent )
-                       *FunctionIdent = fcn;           
-
-               return ret;
-       }
-       else
-       {
-               fprintf(stderr, "Undefined reference to function '%s'\n", Function);
-               return ERRPTR;
-       }
-}
-
-/**
- * \brief Execute an object method function
- * \param Script       Script context to execute in
- * \param Object       Object in which to find the method
- * \param MethodName   Name of method to call
- * \param NArguments   Number of arguments to pass
- * \param Arguments    Arguments passed
- */
-tSpiderValue *SpiderScript_ExecuteMethod(tSpiderScript *Script,
-       tSpiderObject *Object, const char *MethodName,
-       int NArguments, tSpiderValue **Arguments)
-{
-       tSpiderFunction *fcn;
-       tSpiderValue    this;
-       tSpiderValue    *newargs[NArguments+1];
-        int    i;
-       
-       // TODO: Support program defined objects
-       
-       // Search for the function
-       for( fcn = Object->Type->Methods; fcn; fcn = fcn->Next )
-       {
-               if( strcmp(fcn->Name, MethodName) == 0 )
-                       break;
-       }
-       // Error
-       if( !fcn )
-       {
-               AST_RuntimeError(NULL, "Class '%s' does not have a method '%s'",
-                       Object->Type->Name, MethodName);
-               return ERRPTR;
-       }
-       
-       // Create the "this" argument
-       this.Type = SS_DATATYPE_OBJECT;
-       this.ReferenceCount = 1;
-       this.Object = Object;
-       newargs[0] = &this;
-       memcpy(&newargs[1], Arguments, NArguments*sizeof(tSpiderValue*));
-       
-       // Check the type of the arguments
-       for( i = 0; fcn->ArgTypes[i]; i ++ )
-       {
-               if( i >= NArguments ) {
-                       for( ; fcn->ArgTypes[i]; i ++ ) ;
-                       AST_RuntimeError(NULL, "Argument count mismatch (%i passed, %i expected)",
-                               NArguments, i);
-                       return ERRPTR;
-               }
-               if( Arguments[i] && Arguments[i]->Type != fcn->ArgTypes[i] )
-               {
-                       AST_RuntimeError(NULL, "Argument type mismatch (%i, expected %i)",
-                               Arguments[i]->Type, fcn->ArgTypes[i]);
-                       return ERRPTR;
-               }
-       }
-       
-       // Call handler
-       return fcn->Handler(Script, NArguments+1, newargs);
-}
-
-/**
- * \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_CreateObject(tSpiderScript *Script,
-       const char *ClassPath, const char *DefaultNamespaces[],
-       int NArguments, tSpiderValue **Arguments)
-{
-       tSpiderValue    *ret = ERRPTR;
-       tSpiderObjectDef        *class;
-        int    i;      
-
-       // Scan list, Last item should always be NULL, so abuse that to check non-prefixed      
-       for( i = 0; i == 0 || DefaultNamespaces[i-1]; i ++ )
-       {
-               const char *ns = DefaultNamespaces[i];
-               class = SpiderScript_int_GetNativeClass(Script, &Script->Variant->RootNamespace, ns, ClassPath);
-               if( class )     break;
-
-               class = SpiderScript_int_GetNativeClass(Script, &gExportNamespaceRoot, ns, ClassPath);
-               if( class )     break;
-               
-               // TODO: Language defined classes
-       }
-               
-       // First: Find the function in the script
-       // TODO: Implement script-defined classes
-       #if 0
-       {
-               tAST_Function   *astClass;
-               for( astClass = Script->Script->Classes; astClass; astClass = astClass->Next )
-               {
-                       if( strcmp(astClass->Name, ClassName) == 0 )
-                               break;
-               }
-               // Execute!
-               if(astClass)
-               {
-                       tAST_BlockState bs;
-                       tAST_Node       *arg;
-                        int    i = 0;
-                       
-                       // Build a block State
-                       bs.FirstVar = NULL;
-                       bs.RetVal = NULL;
-                       bs.Parent = NULL;
-                       bs.BaseNamespace = &Script->Variant->RootNamespace;
-                       bs.CurNamespace = NULL;
-                       bs.Script = Script;
-                       bs.Ident = giNextBlockIdent ++;
-                       
-                       for( arg = astFcn->Arguments; arg; arg = arg->NextSibling, i++ )
-                       {
-                               if( i >= NArguments )   break;  // TODO: Return gracefully
-                               // TODO: Type checks
-                               Variable_Define(&bs,
-                                       arg->DefVar.DataType, arg->DefVar.Name,
-                                       Arguments[i]);
-                       }
-                       
-                       // Execute function
-                       ret = AST_ExecuteNode(&bs, astFcn->Code);
-                       if( ret != ERRPTR )
-                       {
-                               SpiderScript_DereferenceValue(ret);     // Dereference output of last block statement
-                               ret = bs.RetVal;        // Set to return value of block
-                       }
-                       bFound = 1;
-                       
-                       while(bs.FirstVar)
-                       {
-                               tAST_Variable   *nextVar = bs.FirstVar->Next;
-                               Variable_Destroy( bs.FirstVar );
-                               bs.FirstVar = nextVar;
-                       }
-               }
-       }
-       #endif
-       
-       // Execute!
-       if(class)
-       {
-               tSpiderObject   *obj;
-               // TODO: Type Checking
-               
-               // Call constructor
-               obj = class->Constructor( NArguments, Arguments );
-               if( obj == NULL || obj == ERRPTR )
-                       return (void *)obj;
-               
-               // Creatue return object
-               ret = malloc( sizeof(tSpiderValue) );
-               ret->Type = SS_DATATYPE_OBJECT;
-               ret->ReferenceCount = 1;
-               ret->Object = obj;
-               
-               return ret;
-       }
-       else    // Not found?
-       {
-               fprintf(stderr, "Undefined reference to class '%s'\n", ClassPath);
-               return ERRPTR;
-       }
-}
-
-void AST_RuntimeMessage(tAST_Node *Node, const char *Type, const char *Format, ...)
-{
-       va_list args;
-       
-       if(Node) {
-               fprintf(stderr, "%s:%i: ", Node->File, Node->Line);
-       }
-       fprintf(stderr, "%s: ", Type);
-       va_start(args, Format);
-       vfprintf(stderr, Format, args);
-       va_end(args);
-       fprintf(stderr, "\n");
-}
-void AST_RuntimeError(tAST_Node *Node, const char *Format, ...)
-{
-       va_list args;
-       
-       if(Node) {
-               fprintf(stderr, "%s:%i: ", Node->File, Node->Line);
-       }
-       fprintf(stderr, "error: ");
-       va_start(args, Format);
-       vfprintf(stderr, Format, args);
-       va_end(args);
-       fprintf(stderr, "\n");
-}
diff --git a/Usermode/Libraries/libspiderscript.so_src/exec_ast.c b/Usermode/Libraries/libspiderscript.so_src/exec_ast.c
deleted file mode 100644 (file)
index a9970ee..0000000
+++ /dev/null
@@ -1,1146 +0,0 @@
-/*
- * SpiderScript Library
- *
- * AST Execution
- */
-#include <stdlib.h>
-#include <stdio.h>
-#include <stdarg.h>
-#include <string.h>
-#include "common.h"
-#include "ast.h"
-
-#define USE_AST_EXEC   1
-#define TRACE_VAR_LOOKUPS      0
-#define TRACE_NODE_RETURNS     0
-
-// === IMPORTS ===
-
-// === PROTOTYPES ===
-// - Node Execution
-tSpiderValue   *AST_ExecuteNode(tAST_BlockState *Block, tAST_Node *Node);
-tSpiderValue   *AST_ExecuteNode_BinOp(tSpiderScript *Script, tAST_Node *Node, int Operation, tSpiderValue *Left, tSpiderValue *Right);
-tSpiderValue   *AST_ExecuteNode_UniOp(tSpiderScript *Script, tAST_Node *Node, int Operation, tSpiderValue *Value);
-tSpiderValue   *AST_ExecuteNode_Index(tSpiderScript *Script, tAST_Node *Node, tSpiderValue *Array, int Index, tSpiderValue *SaveValue);
-// - Variables
-tAST_Variable *Variable_Define(tAST_BlockState *Block, int Type, const char *Name, tSpiderValue *Value);
- int   Variable_SetValue(tAST_BlockState *Block, tAST_Node *VarNode, tSpiderValue *Value);
-tSpiderValue   *Variable_GetValue(tAST_BlockState *Block, tAST_Node *VarNode);
-void   Variable_Destroy(tAST_Variable *Variable);
-// - Errors
-void   AST_RuntimeMessage(tAST_Node *Node, const char *Type, const char *Format, ...);
-void   AST_RuntimeError(tAST_Node *Node, const char *Format, ...);
-
-// === GLOBALS ===
- int   giNextBlockIdent = 1;
-
-// === CODE ===
-#if USE_AST_EXEC
-tSpiderValue *AST_ExecuteFunction(tSpiderScript *Script, tScript_Function *Fcn, int NArguments, tSpiderValue **Arguments)
-{
-       tAST_BlockState bs;
-       tSpiderValue    *ret;
-        int    i = 0;
-       
-       // Build a block State
-       bs.FirstVar = NULL;
-       bs.RetVal = NULL;
-       bs.Parent = NULL;
-       bs.BaseNamespace = &Script->Variant->RootNamespace;
-       bs.CurNamespace = NULL;
-       bs.Script = Script;
-       bs.Ident = giNextBlockIdent ++;
-       
-       // Parse arguments
-       for( i = 0; i < Fcn->ArgumentCount; i ++ )
-       {
-               if( i >= NArguments )   break;  // TODO: Return gracefully
-               // TODO: Type checks
-               Variable_Define(&bs,
-                       Fcn->Arguments[i].Type, Fcn->Arguments[i].Name,
-                       Arguments[i]);
-       }
-                       
-       // Execute function
-       ret = AST_ExecuteNode(&bs, Fcn->ASTFcn);
-       if(ret != ERRPTR)
-       {
-               SpiderScript_DereferenceValue(ret);     // Dereference output of last block statement
-               ret = bs.RetVal;        // Set to return value of block
-       }
-                       
-       while(bs.FirstVar)
-       {
-               tAST_Variable   *nextVar = bs.FirstVar->Next;
-               Variable_Destroy( bs.FirstVar );
-               bs.FirstVar = nextVar;
-       }
-       return ret;
-}
-
-/**
- * \brief Execute an AST node and return its value
- * \param Block        Execution context
- * \param Node Node to execute
- */
-tSpiderValue *AST_ExecuteNode(tAST_BlockState *Block, tAST_Node *Node)
-{
-       tAST_Node       *node;
-       tSpiderValue    *ret = NULL, *tmpobj;
-       tSpiderValue    *op1, *op2;     // Binary operations
-        int    i;
-       
-       switch(Node->Type)
-       {
-       // No Operation
-       case NODETYPE_NOP:
-               ret = NULL;
-               break;
-       
-       // Code block
-       case NODETYPE_BLOCK:
-               {
-                       tAST_BlockState blockInfo;
-                       blockInfo.Parent = Block;
-                       blockInfo.Script = Block->Script;
-                       blockInfo.FirstVar = NULL;
-                       blockInfo.RetVal = NULL;
-                       blockInfo.BaseNamespace = Block->BaseNamespace;
-                       blockInfo.CurNamespace = NULL;
-                       blockInfo.BreakTarget = NULL;
-                       blockInfo.Ident = giNextBlockIdent ++;
-                       ret = NULL;
-                       // Loop over all nodes, or until the return value is set
-                       for(node = Node->Block.FirstChild;
-                               node && !blockInfo.RetVal && !blockInfo.BreakTarget;
-                               node = node->NextSibling )
-                       {
-                               ret = AST_ExecuteNode(&blockInfo, node);
-                               if(ret == ERRPTR)       break;  // Error check
-                               if(ret != NULL) SpiderScript_DereferenceValue(ret);     // Free unused value
-                       }
-                       // Clean up variables
-                       while(blockInfo.FirstVar)
-                       {
-                               tAST_Variable   *nextVar = blockInfo.FirstVar->Next;
-                               Variable_Destroy( blockInfo.FirstVar );
-                               blockInfo.FirstVar = nextVar;
-                       }
-                       // Clear ret if not an error
-                       if(ret != ERRPTR)       ret = NULL;
-                       
-                       // Set parent's return value if needed
-                       if( blockInfo.RetVal )
-                               Block->RetVal = blockInfo.RetVal;
-                       if( blockInfo.BreakTarget ) {
-                               Block->BreakTarget = blockInfo.BreakTarget;
-                               Block->BreakType = blockInfo.BreakType;
-                       }
-                       
-                       // TODO: Unset break if break type deontes a block break
-               }
-               
-               break;
-       
-       // Assignment
-       case NODETYPE_ASSIGN:
-               // TODO: Support assigning to object attributes
-               if( Node->Assign.Dest->Type != NODETYPE_VARIABLE ) {
-                       AST_RuntimeError(Node, "LVALUE of assignment is not a variable");
-                       return ERRPTR;
-               }
-               ret = AST_ExecuteNode(Block, Node->Assign.Value);
-               if(ret == ERRPTR)       return ERRPTR;
-               
-               // Perform assignment operation
-               if( Node->Assign.Operation != NODETYPE_NOP )
-               {
-                       tSpiderValue    *varVal, *value;
-
-                       varVal = Variable_GetValue(Block, Node->Assign.Dest);
-                       if(varVal == ERRPTR)    return ERRPTR;
-                       #if 0
-                       #else
-                       if(varVal && varVal->ReferenceCount == 2) {
-                               SpiderScript_DereferenceValue(varVal);
-//                             printf("pre: (%s) varVal->ReferenceCount = %i\n",
-//                                     Node->Assign.Dest->Variable.Name,
-//                                     varVal->ReferenceCount);
-                       }
-                       #endif
-                       value = AST_ExecuteNode_BinOp(Block->Script, Node, Node->Assign.Operation, varVal, ret);
-                       if(value == ERRPTR)     return ERRPTR;
-
-                       if(ret) SpiderScript_DereferenceValue(ret);
-                       #if 0
-                       if(varVal)      SpiderScript_DereferenceValue(varVal);
-                       #else
-                       if(varVal && varVal->ReferenceCount == 1) {
-                               SpiderScript_ReferenceValue(varVal);
-//                             printf("post: varVal->ReferenceCount = %i\n", varVal->ReferenceCount);
-                               break;  // If varVal was non-null, it has been updated by _BinOp
-                       }
-                       #endif
-                       // Else, it was NULL, so has to be assigned
-                       ret = value;
-               }
-               
-               // Set the variable value
-               if( Variable_SetValue( Block, Node->Assign.Dest, ret ) ) {
-                       SpiderScript_DereferenceValue( ret );
-                       return ERRPTR;
-               }
-               break;
-       
-       // Post increment/decrement
-       case NODETYPE_POSTINC:
-       case NODETYPE_POSTDEC:
-               {
-                       tSpiderValue    *varVal, *value;
-                       static tSpiderValue     one = {
-                               .Type = SS_DATATYPE_INTEGER,
-                               .ReferenceCount = 1,
-                               {.Integer = 1}
-                               };
-                       
-                       // TODO: Support assigning to object attributes
-                       if( Node->UniOp.Value->Type != NODETYPE_VARIABLE ) {
-                               AST_RuntimeError(Node, "LVALUE of assignment is not a variable");
-                               return ERRPTR;
-                       }
-               
-                       // Get values (current variable contents and a static one)
-                       varVal = Variable_GetValue(Block, Node->UniOp.Value);
-                       
-                       if( Node->Type == NODETYPE_POSTDEC )
-                               value = AST_ExecuteNode_BinOp(Block->Script, Node, NODETYPE_SUBTRACT, varVal, &one);
-                       else
-                               value = AST_ExecuteNode_BinOp(Block->Script, Node, NODETYPE_ADD, varVal, &one);
-                       if( value == ERRPTR )
-                               return ERRPTR;
-                       
-                       ret = varVal;
-               
-                       if( Variable_SetValue( Block, Node->UniOp.Value, value ) ) {
-                               SpiderScript_DereferenceValue( ret );
-                               return ERRPTR;
-                       }
-                       SpiderScript_DereferenceValue( value );
-               }
-               break;
-       
-       // Function Call
-       case NODETYPE_METHODCALL:
-       case NODETYPE_FUNCTIONCALL:
-       case NODETYPE_CREATEOBJECT:
-               // Logical block (used to allocate `params`)
-               {
-                       const char      *namespaces[] = {NULL}; // TODO: Default namespaces?
-                       tSpiderValue    *params[Node->FunctionCall.NumArgs];
-                       i = 0;
-                       
-                       // Get arguments
-                       for(node = Node->FunctionCall.FirstArg; node; node = node->NextSibling)
-                       {
-                               params[i] = AST_ExecuteNode(Block, node);
-                               if( params[i] == ERRPTR ) {
-                                       while(i--)      SpiderScript_DereferenceValue(params[i]);
-                                       ret = ERRPTR;
-                                       goto _return;
-                               }
-                               i ++;
-                       }
-
-                       // TODO: Check for cached function reference                    
-
-                       // Call the function
-                       if( Node->Type == NODETYPE_CREATEOBJECT )
-                       {
-                               ret = SpiderScript_CreateObject(Block->Script,
-                                       Node->FunctionCall.Name,
-                                       namespaces,
-                                       Node->FunctionCall.NumArgs, params
-                                       );
-                       }
-                       else if( Node->Type == NODETYPE_METHODCALL )
-                       {
-                               tSpiderValue *obj = AST_ExecuteNode(Block, Node->FunctionCall.Object);
-                               if( !obj || obj == ERRPTR || obj->Type != SS_DATATYPE_OBJECT ) {
-                                       AST_RuntimeError(Node->FunctionCall.Object,
-                                               "Type Mismatch - Required SS_DATATYPE_OBJECT for method call");
-                                       while(i--)      SpiderScript_DereferenceValue(params[i]);
-                                       ret = ERRPTR;
-                                       break;
-                               }
-                               ret = SpiderScript_ExecuteMethod(Block->Script,
-                                       obj->Object, Node->FunctionCall.Name,
-                                       Node->FunctionCall.NumArgs, params
-                                       );
-                               SpiderScript_DereferenceValue(obj);
-                       }
-                       else
-                       {
-                               ret = SpiderScript_ExecuteFunction(Block->Script,
-                                       Node->FunctionCall.Name,
-                                       namespaces,
-                                       Node->FunctionCall.NumArgs, params,
-                                       NULL
-                                       );
-                       }
-
-                       
-                       // Dereference parameters
-                       while(i--)      SpiderScript_DereferenceValue(params[i]);
-                       
-                       // falls out
-               }
-               break;
-       
-       // Conditional
-       case NODETYPE_IF:
-               ret = AST_ExecuteNode(Block, Node->If.Condition);
-               if( ret == ERRPTR )     break;
-               if( SpiderScript_IsValueTrue(ret) ) {
-                       tmpobj = AST_ExecuteNode(Block, Node->If.True);
-               }
-               else {
-                       tmpobj = AST_ExecuteNode(Block, Node->If.False);
-               }
-               SpiderScript_DereferenceValue(ret);
-               if( tmpobj == ERRPTR )  return ERRPTR;
-               SpiderScript_DereferenceValue(tmpobj);
-               ret = NULL;
-               break;
-       
-       // Loop
-       case NODETYPE_LOOP:
-               // Initialise
-               ret = AST_ExecuteNode(Block, Node->For.Init);
-               if(ret == ERRPTR)       break;
-               
-               // Check initial condition
-               if( !Node->For.bCheckAfter )
-               {
-                       SpiderScript_DereferenceValue(ret);
-               
-                       ret = AST_ExecuteNode(Block, Node->For.Condition);
-                       if(ret == ERRPTR)       return ERRPTR;
-                       if(!SpiderScript_IsValueTrue(ret)) {
-                               SpiderScript_DereferenceValue(ret);
-                               ret = NULL;
-                               break;
-                       }
-               }
-       
-               // Perform loop
-               for( ;; )
-               {
-                       SpiderScript_DereferenceValue(ret);
-                       
-                       // Code
-                       ret = AST_ExecuteNode(Block, Node->For.Code);
-                       if(ret == ERRPTR)       return ERRPTR;
-                       SpiderScript_DereferenceValue(ret);
-                       
-                       if(Block->BreakTarget)
-                       {
-                               if( Block->BreakTarget[0] == '\0' || strcmp(Block->BreakTarget, Node->For.Tag) == 0 )
-                               {
-                                       // Ours
-                                       free((void*)Block->BreakTarget);        Block->BreakTarget = NULL;
-                                       if( Block->BreakType == NODETYPE_CONTINUE ) {
-                                               // Continue, just keep going
-                                       }
-                                       else
-                                               break;
-                               }
-                               else
-                                       break;  // Break out of this loop
-                       }
-                       
-                       // Increment
-                       ret = AST_ExecuteNode(Block, Node->For.Increment);
-                       if(ret == ERRPTR)       return ERRPTR;
-                       SpiderScript_DereferenceValue(ret);
-                       
-                       // Check condition
-                       ret = AST_ExecuteNode(Block, Node->For.Condition);
-                       if(ret == ERRPTR)       return ERRPTR;
-                       if(!SpiderScript_IsValueTrue(ret))      break;
-               }
-               SpiderScript_DereferenceValue(ret);
-               ret = NULL;
-               break;
-       
-       // Return
-       case NODETYPE_RETURN:
-               ret = AST_ExecuteNode(Block, Node->UniOp.Value);
-               if(ret == ERRPTR)       break;
-               Block->RetVal = ret;    // Return value set
-               ret = NULL;     // the `return` statement does not return a value
-               break;
-       
-       case NODETYPE_BREAK:
-       case NODETYPE_CONTINUE:
-               Block->BreakTarget = strdup(Node->Variable.Name);
-               Block->BreakType = Node->Type;
-               break;
-       
-       // Define a variable
-       case NODETYPE_DEFVAR:
-               if( Node->DefVar.InitialValue ) {
-                       tmpobj = AST_ExecuteNode(Block, Node->DefVar.InitialValue);
-                       if(tmpobj == ERRPTR)    return ERRPTR;
-               }
-               else {
-                       tmpobj = NULL;
-               }
-               // TODO: Handle arrays
-               ret = NULL;
-               if( Variable_Define(Block, Node->DefVar.DataType, Node->DefVar.Name, tmpobj) == ERRPTR )
-                       ret = ERRPTR;
-               SpiderScript_DereferenceValue(tmpobj);
-               break;
-       
-       // Scope
-       case NODETYPE_SCOPE:
-               {
-               tSpiderNamespace        *ns;
-               
-               // Set current namespace if unset
-               if( !Block->CurNamespace )
-                       Block->CurNamespace = Block->BaseNamespace;
-               
-               // Empty string means use the root namespace
-               if( Node->Scope.Name[0] == '\0' )
-               {
-                       ns = &Block->Script->Variant->RootNamespace;
-               }
-               else
-               {
-                       // Otherwise scan the current namespace for the element
-                       for( ns = Block->CurNamespace->FirstChild; ns; ns = ns->Next )
-                       {
-                               if( strcmp(ns->Name, Node->Scope.Name) == 0 )
-                                       break;
-                       }
-               }
-               if(!ns) {
-                       AST_RuntimeError(Node, "Unknown namespace '%s'", Node->Scope.Name);
-                       ret = ERRPTR;
-                       break;
-               }
-               Block->CurNamespace = ns;
-       
-               // TODO: Check type of child node (Scope, Constant or Function) 
-       
-               ret = AST_ExecuteNode(Block, Node->Scope.Element);
-               }
-               break;
-       
-       // Variable
-       case NODETYPE_VARIABLE:
-               ret = Variable_GetValue( Block, Node );
-               break;
-       
-       // Element of an Object
-       case NODETYPE_ELEMENT:
-               tmpobj = AST_ExecuteNode( Block, Node->Scope.Element );
-               if(tmpobj == ERRPTR)    return ERRPTR;
-
-               ret = AST_ExecuteNode_Element(Block->Script, Node, tmpobj, Node->Scope.Name, ERRPTR);
-               break;
-
-       // Cast a value to another
-       case NODETYPE_CAST:
-               {
-               tmpobj = AST_ExecuteNode(Block, Node->Cast.Value);
-               if(tmpobj == ERRPTR) return ERRPTR;
-               ret = SpiderScript_CastValueTo( Node->Cast.DataType, tmpobj );
-               SpiderScript_DereferenceValue(tmpobj);
-               }
-               break;
-
-       // Index into an array
-       case NODETYPE_INDEX:
-               op1 = AST_ExecuteNode(Block, Node->BinOp.Left); // Array
-               if(op1 == ERRPTR)       return ERRPTR;
-               op2 = AST_ExecuteNode(Block, Node->BinOp.Right);        // Offset
-               if(op2 == ERRPTR) {
-                       SpiderScript_DereferenceValue(op1);
-                       return ERRPTR;
-               }
-               
-               if( !op2 || op2->Type != SS_DATATYPE_INTEGER )
-               {
-                       if( !Block->Script->Variant->bImplicitCasts ) {
-                               AST_RuntimeError(Node, "Array index is not an integer");
-                               ret = ERRPTR;
-                               break;
-                       }
-                       else {
-                               tmpobj = SpiderScript_CastValueTo(SS_DATATYPE_INTEGER, op2);
-                               SpiderScript_DereferenceValue(op2);
-                               op2 = tmpobj;
-                       }
-               }
-       
-               if( !op1 )
-               {
-                       SpiderScript_DereferenceValue(op2);
-                       AST_RuntimeError(Node, "Indexing NULL value");
-                       ret = ERRPTR;
-                       break;
-               }
-
-               ret = AST_ExecuteNode_Index(Block->Script, Node, op1, op2->Integer, ERRPTR);
-
-               SpiderScript_DereferenceValue(op1);
-               SpiderScript_DereferenceValue(op2);
-               break;
-
-       // TODO: Implement runtime constants
-       case NODETYPE_CONSTANT:
-               // TODO: Scan namespace for constant name
-               AST_RuntimeError(Node, "TODO - Runtime Constants");
-               ret = ERRPTR;
-               break;
-       
-       // Constant Values
-       case NODETYPE_STRING:
-       case NODETYPE_INTEGER:
-       case NODETYPE_REAL:
-               ret = &Node->Constant;
-               SpiderScript_ReferenceValue(ret);
-               break;
-       case NODETYPE_NULL:
-               ret = NULL;
-               break;
-       
-       // --- Operations ---
-       // Boolean Operations
-       case NODETYPE_LOGICALNOT:       // Logical NOT (!)
-               op1 = AST_ExecuteNode(Block, Node->UniOp.Value);
-               if(op1 == ERRPTR)       return ERRPTR;
-               ret = SpiderScript_CreateInteger( !SpiderScript_IsValueTrue(op1) );
-               SpiderScript_DereferenceValue(op1);
-               break;
-       case NODETYPE_LOGICALAND:       // Logical AND (&&)
-       case NODETYPE_LOGICALOR:        // Logical OR (||)
-       case NODETYPE_LOGICALXOR:       // Logical XOR (^^)
-               op1 = AST_ExecuteNode(Block, Node->BinOp.Left);
-               if(op1 == ERRPTR)       return ERRPTR;
-               op2 = AST_ExecuteNode(Block, Node->BinOp.Right);
-               if(op2 == ERRPTR) {
-                       SpiderScript_DereferenceValue(op1);
-                       return ERRPTR;
-               }
-               
-               switch( Node->Type )
-               {
-               case NODETYPE_LOGICALAND:
-                       ret = SpiderScript_CreateInteger( SpiderScript_IsValueTrue(op1) && SpiderScript_IsValueTrue(op2) );
-                       break;
-               case NODETYPE_LOGICALOR:
-                       ret = SpiderScript_CreateInteger( SpiderScript_IsValueTrue(op1) || SpiderScript_IsValueTrue(op2) );
-                       break;
-               case NODETYPE_LOGICALXOR:
-                       ret = SpiderScript_CreateInteger( SpiderScript_IsValueTrue(op1) ^ SpiderScript_IsValueTrue(op2) );
-                       break;
-               default:        break;
-               }
-               
-               // Free intermediate objects
-               SpiderScript_DereferenceValue(op1);
-               SpiderScript_DereferenceValue(op2);
-               break;
-       
-       // General Unary Operations
-       case NODETYPE_BWNOT:    // Bitwise NOT (~)
-       case NODETYPE_NEGATE:   // Negation (-)
-               op1 = AST_ExecuteNode(Block, Node->UniOp.Value);
-               if(op1 == ERRPTR)       return ERRPTR;
-               ret = AST_ExecuteNode_UniOp(Block->Script, Node, Node->Type, op1);
-               SpiderScript_DereferenceValue(op1);
-               break;
-       
-       // General Binary Operations
-       case NODETYPE_ADD:
-       case NODETYPE_SUBTRACT:
-       case NODETYPE_MULTIPLY:
-       case NODETYPE_DIVIDE:
-       case NODETYPE_MODULO:
-       case NODETYPE_BWAND:
-       case NODETYPE_BWOR:
-       case NODETYPE_BWXOR:
-       case NODETYPE_BITSHIFTLEFT:
-       case NODETYPE_BITSHIFTRIGHT:
-       case NODETYPE_BITROTATELEFT:
-       case NODETYPE_EQUALS:
-       case NODETYPE_NOTEQUALS:
-       case NODETYPE_LESSTHAN:
-       case NODETYPE_GREATERTHAN:
-       case NODETYPE_LESSTHANEQUAL:
-       case NODETYPE_GREATERTHANEQUAL:
-               // Get operands
-               op1 = AST_ExecuteNode(Block, Node->BinOp.Left);
-               if(op1 == ERRPTR)       return ERRPTR;
-               op2 = AST_ExecuteNode(Block, Node->BinOp.Right);
-               if(op2 == ERRPTR) {
-                       SpiderScript_DereferenceValue(op1);
-                       return ERRPTR;
-               }
-               
-               ret = AST_ExecuteNode_BinOp(Block->Script, Node, Node->Type, op1, op2);
-               
-               // Free intermediate objects
-               SpiderScript_DereferenceValue(op1);
-               SpiderScript_DereferenceValue(op2);
-               break;
-       
-       //default:
-       //      ret = NULL;
-       //      AST_RuntimeError(Node, "BUG - SpiderScript AST_ExecuteNode Unimplemented %i", Node->Type);
-       //      break;
-       }
-_return:
-       // Reset namespace when no longer needed
-       if( Node->Type != NODETYPE_SCOPE )
-               Block->CurNamespace = NULL;
-
-       #if TRACE_NODE_RETURNS
-       if(ret && ret != ERRPTR) {
-               AST_RuntimeError(Node, "Ret type of %p %i is %i", Node, Node->Type, ret->Type);
-       }
-       else {
-               AST_RuntimeError(Node, "Ret type of %p %i is %p", Node, Node->Type, ret);
-       }
-       #endif
-
-       return ret;
-}
-#endif
-
-tSpiderValue *AST_ExecuteNode_UniOp(tSpiderScript *Script, tAST_Node *Node, int Operation, tSpiderValue *Value)
-{
-       tSpiderValue    *ret;
-       #if 0
-       if( Value->Type == SS_DATATYPE_OBJECT )
-       {
-               const char      *fcnname;
-               switch(Operation)
-               {
-               case NODETYPE_NEGATE:   fcnname = "-ve";        break;
-               case NODETYPE_BWNOT:    fcnname = "~";  break;
-               default:        fcnname = NULL; break;
-               }
-               
-               if( fcnname )
-               {
-                       ret = Object_ExecuteMethod(Value->Object, fcnname, );
-                       if( ret != ERRPTR )
-                               return ret;
-               }
-       }
-       #endif
-       switch(Value->Type)
-       {
-       // Integer Operations
-       case SS_DATATYPE_INTEGER:
-               if( Value->ReferenceCount == 1 )
-                       SpiderScript_ReferenceValue(ret = Value);
-               else
-                       ret = SpiderScript_CreateInteger(0);
-               switch(Operation)
-               {
-               case NODETYPE_NEGATE:   ret->Integer = -Value->Integer; break;
-               case NODETYPE_BWNOT:    ret->Integer = ~Value->Integer; break;
-               default:
-                       AST_RuntimeError(Node, "SpiderScript internal error: Exec,UniOP,Integer unknown op %i", Operation);
-                       SpiderScript_DereferenceValue(ret);
-                       ret = ERRPTR;
-                       break;
-               }
-               break;
-       // Real number Operations
-       case SS_DATATYPE_REAL:
-               switch(Operation)
-               {
-               case NODETYPE_NEGATE:   ret = SpiderScript_CreateInteger( -Value->Real );       break;
-               default:
-                       AST_RuntimeError(Node, "SpiderScript internal error: Exec,UniOP,Real unknown op %i", Operation);
-                       ret = ERRPTR;
-                       break;
-               }
-               break;
-       
-       default:
-               AST_RuntimeError(NULL, "Invalid operation (%i) on type (%i)", Operation, Value->Type);
-               ret = ERRPTR;
-               break;
-       }
-       
-       return ret;
-}
-
-tSpiderValue *AST_ExecuteNode_BinOp(tSpiderScript *Script, tAST_Node *Node, int Operation, tSpiderValue *Left, tSpiderValue *Right)
-{
-       tSpiderValue    *preCastValue = Right;
-       tSpiderValue    *ret;
-       
-       // Convert types
-       if( Left && Right && Left->Type != Right->Type )
-       {
-               #if 0
-               // Object types
-               // - Operator overload functions
-               if( Left->Type == SS_DATATYPE_OBJECT )
-               {
-                       const char      *fcnname;
-                       switch(Operation)
-                       {
-                       case NODETYPE_ADD:      fcnname = "+";  break;
-                       case NODETYPE_SUBTRACT: fcnname = "-";  break;
-                       case NODETYPE_MULTIPLY: fcnname = "*";  break;
-                       case NODETYPE_DIVIDE:   fcnname = "/";  break;
-                       case NODETYPE_MODULO:   fcnname = "%";  break;
-                       case NODETYPE_BWAND:    fcnname = "&";  break;
-                       case NODETYPE_BWOR:     fcnname = "|";  break;
-                       case NODETYPE_BWXOR:    fcnname = "^";  break;
-                       case NODETYPE_BITSHIFTLEFT:     fcnname = "<<"; break;
-                       case NODETYPE_BITSHIFTRIGHT:fcnname = ">>";     break;
-                       case NODETYPE_BITROTATELEFT:fcnname = "<<<";    break;
-                       default:        fcnname = NULL; break;
-                       }
-                       
-                       if( fcnname )
-                       {
-                               ret = Object_ExecuteMethod(Left->Object, fcnname, Right);
-                               if( ret != ERRPTR )
-                                       return ret;
-                               // Fall through and try casting (which will usually fail)
-                       }
-               }
-               #endif
-               
-               // If implicit casts are allowed, convert Right to Left's type
-               if(Script->Variant->bImplicitCasts)
-               {
-                       Right = SpiderScript_CastValueTo(Left->Type, Right);
-                       if(Right == ERRPTR)
-                               return ERRPTR;
-               }
-               // If statically typed, this should never happen, but catch it anyway
-               else {
-                       AST_RuntimeError(Node, "Implicit cast not allowed (from %i to %i)", Right->Type, Left->Type);
-                       return ERRPTR;
-               }
-       }
-       
-       // NULL Check
-       if( Left == NULL || Right == NULL ) {
-               if(Right && Right != preCastValue)      free(Right);
-               return NULL;
-       }
-
-       // Catch comparisons
-       switch(Operation)
-       {
-       case NODETYPE_EQUALS:
-       case NODETYPE_NOTEQUALS:
-       case NODETYPE_LESSTHAN:
-       case NODETYPE_GREATERTHAN:
-       case NODETYPE_LESSTHANEQUAL:
-       case NODETYPE_GREATERTHANEQUAL: {
-                int    cmp;
-               ret = NULL;
-               // Do operation
-               switch(Left->Type)
-               {
-               // - String Compare (does a strcmp, well memcmp)
-               case SS_DATATYPE_STRING:
-                       // Call memcmp to do most of the work
-                       cmp = memcmp(
-                               Left->String.Data, Right->String.Data,
-                               (Left->String.Length < Right->String.Length) ? Left->String.Length : Right->String.Length
-                               );
-                       // Handle reaching the end of the string
-                       if( cmp == 0 ) {
-                               if( Left->String.Length == Right->String.Length )
-                                       cmp = 0;
-                               else if( Left->String.Length < Right->String.Length )
-                                       cmp = 1;
-                               else
-                                       cmp = -1;
-                       }
-                       break;
-               
-               // - Integer Comparisons
-               case SS_DATATYPE_INTEGER:
-                       if( Left->Integer == Right->Integer )
-                               cmp = 0;
-                       else if( Left->Integer < Right->Integer )
-                               cmp = -1;
-                       else
-                               cmp = 1;
-                       break;
-               // - Real Number Comparisons
-               case SS_DATATYPE_REAL:
-                       cmp = (Left->Real - Right->Real) / Right->Real * 10000; // < 0.1% difference is equality
-                       break;
-               default:
-                       AST_RuntimeError(Node, "TODO - Comparison of type %i", Left->Type);
-                       ret = ERRPTR;
-                       break;
-               }
-               
-               // Error check
-               if( ret != ERRPTR )
-               {
-                       if(Left->ReferenceCount == 1 && Left->Type != SS_DATATYPE_STRING)
-                               SpiderScript_ReferenceValue(ret = Left);
-                       else
-                               ret = SpiderScript_CreateInteger(0);
-                       
-                       // Create return
-                       switch(Operation)
-                       {
-                       case NODETYPE_EQUALS:   ret->Integer = (cmp == 0);      break;
-                       case NODETYPE_NOTEQUALS:        ret->Integer = (cmp != 0);      break;
-                       case NODETYPE_LESSTHAN: ret->Integer = (cmp < 0);       break;
-                       case NODETYPE_GREATERTHAN:      ret->Integer = (cmp > 0);       break;
-                       case NODETYPE_LESSTHANEQUAL:    ret->Integer = (cmp <= 0);      break;
-                       case NODETYPE_GREATERTHANEQUAL: ret->Integer = (cmp >= 0);      break;
-                       default:
-                               AST_RuntimeError(Node, "Exec,CmpOp unknown op %i", Operation);
-                               SpiderScript_DereferenceValue(ret);
-                               ret = ERRPTR;
-                               break;
-                       }
-               }
-               if(Right && Right != preCastValue)      free(Right);
-               return ret;
-               }
-
-       // Fall through and sort by type instead
-       default:
-               break;
-       }
-       
-       // Do operation
-       switch(Left->Type)
-       {
-       // String Concatenation
-       case SS_DATATYPE_STRING:
-               switch(Operation)
-               {
-               case NODETYPE_ADD:      // Concatenate
-                       ret = SpiderScript_StringConcat(Left, Right);
-                       break;
-               // TODO: Support python style 'i = %i' % i ?
-               // Might do it via a function call
-               // Implement it via % with an array, but getting past the cast will be fun
-//             case NODETYPE_MODULUS:
-//                     break;
-               // TODO: Support string repititions
-//             case NODETYPE_MULTIPLY:
-//                     break;
-
-               default:
-                       AST_RuntimeError(Node, "SpiderScript internal error: Exec,BinOP,String unknown op %i", Operation);
-                       ret = ERRPTR;
-                       break;
-               }
-               break;
-       // Integer Operations
-       case SS_DATATYPE_INTEGER:
-               if( Left->ReferenceCount == 1 )
-                       SpiderScript_ReferenceValue(ret = Left);
-               else
-                       ret = SpiderScript_CreateInteger(0);
-               switch(Operation)
-               {
-               case NODETYPE_ADD:      ret->Integer = Left->Integer + Right->Integer;  break;
-               case NODETYPE_SUBTRACT: ret->Integer = Left->Integer - Right->Integer;  break;
-               case NODETYPE_MULTIPLY: ret->Integer = Left->Integer * Right->Integer;  break;
-               case NODETYPE_DIVIDE:   ret->Integer = Left->Integer / Right->Integer;  break;
-               case NODETYPE_MODULO:   ret->Integer = Left->Integer % Right->Integer;  break;
-               case NODETYPE_BWAND:    ret->Integer = Left->Integer & Right->Integer;  break;
-               case NODETYPE_BWOR:     ret->Integer = Left->Integer | Right->Integer;  break;
-               case NODETYPE_BWXOR:    ret->Integer = Left->Integer ^ Right->Integer;  break;
-               case NODETYPE_BITSHIFTLEFT: ret->Integer = Left->Integer << Right->Integer;     break;
-               case NODETYPE_BITSHIFTRIGHT:ret->Integer = Left->Integer >> Right->Integer;     break;
-               case NODETYPE_BITROTATELEFT:
-                       ret->Integer = (Left->Integer << Right->Integer) | (Left->Integer >> (64-Right->Integer));
-                       break;
-               default:
-                       AST_RuntimeError(Node, "SpiderScript internal error: Exec,BinOP,Integer unknown op %i", Operation);
-                       SpiderScript_DereferenceValue(ret);
-                       ret = ERRPTR;
-                       break;
-               }
-               break;
-       
-       // Real Numbers
-       case SS_DATATYPE_REAL:
-               if( Left->ReferenceCount == 1 )
-                       SpiderScript_ReferenceValue(ret = Left);
-               else
-                       ret = SpiderScript_CreateReal(0);
-               switch(Operation)
-               {
-               case NODETYPE_ADD:      ret->Real = Left->Real + Right->Real;   break;
-               case NODETYPE_SUBTRACT: ret->Real = Left->Real - Right->Real;   break;
-               case NODETYPE_MULTIPLY: ret->Real = Left->Real * Right->Real;   break;
-               case NODETYPE_DIVIDE:   ret->Real = Left->Real / Right->Real;   break;
-               default:
-                       AST_RuntimeError(Node, "SpiderScript internal error: Exec,BinOP,Real unknown op %i", Operation);
-                       SpiderScript_DereferenceValue(ret);
-                       ret = ERRPTR;
-                       break;
-               }
-               break;
-       
-       default:
-               AST_RuntimeError(Node, "BUG - Invalid operation (%i) on type (%i)", Operation, Left->Type);
-               ret = ERRPTR;
-               break;
-       }
-       
-       if(Right && Right != preCastValue)      free(Right);
-       
-       return ret;
-}
-
-tSpiderValue *AST_ExecuteNode_Index(tSpiderScript *Script, tAST_Node *Node,
-       tSpiderValue *Array, int Index, tSpiderValue *SaveValue)
-{
-       // Quick sanity check
-       if( !Array )
-       {
-               AST_RuntimeError(Node, "Indexing NULL, not a good idea");
-               return ERRPTR;
-       }
-
-       // Array?
-       if( SS_GETARRAYDEPTH(Array->Type) )
-       {
-               if( Index < 0 || Index >= Array->Array.Length ) {
-                       AST_RuntimeError(Node, "Array index out of bounds %i not in (0, %i]",
-                               Index, Array->Array.Length);
-                       return ERRPTR;
-               }
-               
-               if( SaveValue != ERRPTR )
-               {
-                       if( SaveValue && SaveValue->Type != SS_DOWNARRAY(Array->Type) ) {
-                               // TODO: Implicit casting
-                               AST_RuntimeError(Node, "Type mismatch assiging to array element");
-                               return ERRPTR;
-                       }
-                       SpiderScript_DereferenceValue( Array->Array.Items[Index] );
-                       Array->Array.Items[Index] = SaveValue;
-                       SpiderScript_ReferenceValue( Array->Array.Items[Index] );
-                       return NULL;
-               }
-               else
-               {
-                       SpiderScript_ReferenceValue( Array->Array.Items[Index] );
-                       return Array->Array.Items[Index];
-               }
-       }
-       else
-       {
-               AST_RuntimeError(Node, "TODO - Implement indexing on non-arrays (type = %x)",
-                       Array->Type);
-               return ERRPTR;
-       }
-}
-
-/**
- * \brief Get/Set the value of an element/attribute of a class
- * \param Script       Executing script
- * \param Node Current execution node (only used for AST_RuntimeError)
- * \param Object       Object value
- * \param ElementName  Name of the attribute to be accessed
- * \param SaveValue    Value to set the element to (if ERRPTR, element value is returned)
- */
-tSpiderValue *AST_ExecuteNode_Element(tSpiderScript *Script, tAST_Node *Node,
-       tSpiderValue *Object, const char *ElementName, tSpiderValue *SaveValue)
-{
-        int    i;
-       tSpiderValue    *ret;   
-
-       if( !Object ) {
-               AST_RuntimeError(Node, "Tried to access an element of NULL");
-               return ERRPTR;
-       }
-       
-       switch( Object->Type )
-       {
-       case SS_DATATYPE_OBJECT: {
-               tSpiderObjectDef        *class = Object->Object->Type;
-               for( i = 0; i < class->NAttributes; i ++ )
-               {
-                       if( strcmp(ElementName, class->AttributeDefs[i].Name) == 0 )
-                       {
-                               if( SaveValue != ERRPTR ) {
-                                       Object->Object->Attributes[i] = SaveValue;
-                                       SpiderScript_ReferenceValue(SaveValue);
-                                       return NULL;
-                               }
-                               else {
-                                       ret = Object->Object->Attributes[i];
-                                       SpiderScript_ReferenceValue(ret);
-                                       return ret;
-                               }
-                       }
-               }
-               AST_RuntimeError(Node, "Unknown attribute '%s' of class '%s'",
-                       ElementName, class->Name);
-               return ERRPTR; }
-       default:
-               AST_RuntimeError(Node, "Unable to get element of type %i", Object->Type);
-               return ERRPTR;
-       }
-}
-
-#if USE_AST_EXEC
-/**
- * \brief Define a variable
- * \param Block        Current block state
- * \param Type Type of the variable
- * \param Name Name of the variable
- * \return Boolean Failure
- */
-tAST_Variable *Variable_Define(tAST_BlockState *Block, int Type, const char *Name, tSpiderValue *Value)
-{
-       tAST_Variable   *var, *prev = NULL;
-       
-       for( var = Block->FirstVar; var; prev = var, var = var->Next )
-       {
-               if( strcmp(var->Name, Name) == 0 ) {
-                       AST_RuntimeError(NULL, "Redefinition of variable '%s'", Name);
-                       return ERRPTR;
-               }
-       }
-       
-       var = malloc( sizeof(tAST_Variable) + strlen(Name) + 1 );
-       var->Next = NULL;
-       var->Type = Type;
-       var->Object = Value;
-       if(Value)       SpiderScript_ReferenceValue(Value);
-       strcpy(var->Name, Name);
-       
-       if(prev)        prev->Next = var;
-       else    Block->FirstVar = var;
-       
-       //printf("Defined variable %s (%i)\n", Name, Type);
-       
-       return var;
-}
-
-tAST_Variable *Variable_Lookup(tAST_BlockState *Block, tAST_Node *VarNode, int CreateType)
-{      
-       tAST_Variable   *var = NULL;
-       
-       // Speed hack
-       if( VarNode->BlockState == Block && VarNode->BlockIdent == Block->Ident ) {
-               var = VarNode->ValueCache;
-               #if TRACE_VAR_LOOKUPS
-               AST_RuntimeMessage(VarNode, "debug", "Fast var fetch on '%s' %p (%p:%i)",
-                       VarNode->Variable.Name, var,
-                       VarNode->BlockState, VarNode->BlockIdent
-                       );
-               #endif
-       }
-       else
-       {
-               tAST_BlockState *bs;
-               for( bs = Block; bs; bs = bs->Parent )
-               {
-                       for( var = bs->FirstVar; var; var = var->Next )
-                       {
-                               if( strcmp(var->Name, VarNode->Variable.Name) == 0 )
-                                       break;
-                       }
-                       if(var) break;
-               }
-               
-               if( !var )
-               {
-                       if( Block->Script->Variant->bDyamicTyped && CreateType != SS_DATATYPE_UNDEF ) {
-                               // Define variable
-                               var = Variable_Define(Block, CreateType, VarNode->Variable.Name, NULL);
-                       }
-                       else
-                       {
-                               AST_RuntimeError(VarNode, "Variable '%s' is undefined", VarNode->Variable.Name);
-                               return NULL;
-                       }
-               }
-               
-               #if TRACE_VAR_LOOKUPS
-               AST_RuntimeMessage(VarNode, "debug", "Saved variable lookup of '%s' %p (%p:%i)",
-                       VarNode->Variable.Name, var,
-                       Block, Block->Ident);
-               #endif
-               
-               VarNode->ValueCache = var;
-               VarNode->BlockState = Block;
-               VarNode->BlockIdent = Block->Ident;
-       }
-       
-       return var;
-}
-
-/**
- * \brief Set the value of a variable
- * \return Boolean Failure
- */
-int Variable_SetValue(tAST_BlockState *Block, tAST_Node *VarNode, tSpiderValue *Value)
-{
-       tAST_Variable   *var;
-       
-       var = Variable_Lookup(Block, VarNode, (Value ? Value->Type : SS_DATATYPE_UNDEF));
-       
-       if( !var )      return -1;
-       
-       if( !Block->Script->Variant->bDyamicTyped && (Value && var->Type != Value->Type) )
-       {
-               AST_RuntimeError(VarNode, "Type mismatch assigning to '%s'",
-                       VarNode->Variable.Name);
-               return -2;
-       }
-
-//     printf("Assign %p to '%s'\n", Value, var->Name);
-       SpiderScript_ReferenceValue(Value);
-       SpiderScript_DereferenceValue(var->Object);
-       var->Object = Value;
-       return 0;
-}
-
-/**
- * \brief Get the value of a variable
- */
-tSpiderValue *Variable_GetValue(tAST_BlockState *Block, tAST_Node *VarNode)
-{
-       tAST_Variable   *var = Variable_Lookup(Block, VarNode, 0);
-       
-       if( !var )      return ERRPTR;
-       
-       SpiderScript_ReferenceValue(var->Object);
-       return var->Object;
-}
-
-/**
- * \brief Destorys a variable
- */
-void Variable_Destroy(tAST_Variable *Variable)
-{
-//     printf("Variable_Destroy: (%p'%s')\n", Variable, Variable->Name);
-       SpiderScript_DereferenceValue(Variable->Object);
-       free(Variable);
-}
-#endif
-
diff --git a/Usermode/Libraries/libspiderscript.so_src/exec_bytecode.c b/Usermode/Libraries/libspiderscript.so_src/exec_bytecode.c
deleted file mode 100644 (file)
index 9de7281..0000000
+++ /dev/null
@@ -1,984 +0,0 @@
-/*
- * SpiderScript Library
- * by John Hodge (thePowersGang)
- * 
- * exec_bytecode.c
- * - Execute bytecode
- */
-#include <stdlib.h>
-#include <stdint.h>
-#include "common.h"
-#include "bytecode.h"
-#include <stdio.h>
-#include <string.h>
-#include "ast.h"
-#include <inttypes.h>
-
-#define TRACE  0
-
-#if TRACE
-# define DEBUG_F(v...) printf(v)
-#else
-# define DEBUG_F(v...)
-#endif
-
-// === IMPORTS ===
-extern void    AST_RuntimeError(tAST_Node *Node, const char *Format, ...);
-
-// === TYPES ===
-typedef struct sBC_StackEnt    tBC_StackEnt;
-typedef struct sBC_Stack       tBC_Stack;
-
-enum eBC_StackEntTypes
-{
-       ET_NULL,        // Start of the stack
-       // SS_DATATYPE_*
-       ET_FUNCTION_START = NUM_SS_DATATYPES,
-       ET_REFERENCE    // Reference to a tSpiderValue
-};
-
-struct sBC_StackEnt
-{
-       uint8_t Type;
-       union {
-               int64_t Integer;
-               double  Real;
-               tSpiderValue    *Reference;     // Used for everything else
-               tSpiderObject   *Object;
-               tSpiderNamespace        *Namespace;
-       };
-};
-
-struct sBC_Stack
-{
-        int    EntrySpace;
-        int    EntryCount;
-       tBC_StackEnt    Entries[];
-};
-
-// === PROTOTYPES ===
-tSpiderValue   *Bytecode_ExecuteFunction(tSpiderScript *Script, tScript_Function *Fcn, int NArguments, tSpiderValue **Args);
- int   Bytecode_int_ExecuteFunction(tSpiderScript *Script, tScript_Function *Fcn, tBC_Stack *Stack, int ArgCount);
-
-// === CODE ===
-int Bytecode_int_StackPop(tBC_Stack *Stack, tBC_StackEnt *Dest)
-{
-       if( Stack->EntryCount == 0 )    return 1;
-       Stack->EntryCount --;
-       *Dest = Stack->Entries[Stack->EntryCount];
-       return 0;
-}
-
-int Bytecode_int_StackPush(tBC_Stack *Stack, tBC_StackEnt *Src)
-{
-       if( Stack->EntryCount == Stack->EntrySpace )    return 1;
-       Stack->Entries[Stack->EntryCount] = *Src;
-       Stack->EntryCount ++;
-       return 0;
-}
-
-int Bytecode_int_IsStackEntTrue(tBC_StackEnt *Ent)
-{
-       switch(Ent->Type)
-       {
-       case SS_DATATYPE_INTEGER:
-               return !!Ent->Integer;
-       case SS_DATATYPE_REAL:
-               return !(-.5f < Ent->Real && Ent->Real < 0.5f);
-       case SS_DATATYPE_OBJECT:
-               return Ent->Object != NULL;
-       case ET_FUNCTION_START:
-               return -1;
-       default:
-               return SpiderScript_IsValueTrue(Ent->Reference);
-       }
-}
-
-tSpiderValue *Bytecode_int_GetSpiderValue(tBC_StackEnt *Ent, tSpiderValue *tmp)
-{
-       switch(Ent->Type)
-       {
-       case SS_DATATYPE_INTEGER:
-       case SS_DATATYPE_REAL:
-       case SS_DATATYPE_OBJECT:
-               if(!tmp) {
-                       tmp = malloc(sizeof(tSpiderValue));
-                       tmp->ReferenceCount = 1;
-               } else {
-                       // Stops a stack value from having free() called on it
-                       tmp->ReferenceCount = 2;
-               }
-               break;
-       default:
-               break;
-       }
-       switch(Ent->Type)
-       {
-       case SS_DATATYPE_INTEGER:
-               tmp->Type = SS_DATATYPE_INTEGER;
-               tmp->Integer = Ent->Integer;
-               return tmp;
-       case SS_DATATYPE_REAL:
-               tmp->Type = SS_DATATYPE_REAL;
-               tmp->Real = Ent->Real;
-               return tmp;
-       case SS_DATATYPE_OBJECT:
-               tmp->Type = SS_DATATYPE_OBJECT;
-               tmp->Object = Ent->Object;
-               return tmp;
-       case ET_FUNCTION_START:
-               AST_RuntimeError(NULL, "_GetSpiderValue on ET_FUNCTION_START");
-               return NULL;
-       default:
-               SpiderScript_ReferenceValue(Ent->Reference);
-               return Ent->Reference;
-       }
-}
-
-void Bytecode_int_SetSpiderValue(tBC_StackEnt *Ent, tSpiderValue *Value)
-{
-       if(!Value) {
-               Ent->Type = ET_REFERENCE;
-               Ent->Reference = NULL;
-               return ;
-       }
-       switch(Value->Type)
-       {
-       case SS_DATATYPE_INTEGER:
-               Ent->Type = SS_DATATYPE_INTEGER;
-               Ent->Integer = Value->Integer;
-               break;
-       case SS_DATATYPE_REAL:
-               Ent->Type = SS_DATATYPE_REAL;
-               Ent->Real = Value->Real;
-               break;
-       case SS_DATATYPE_OBJECT:
-               Ent->Type = SS_DATATYPE_OBJECT;
-               Ent->Object = Value->Object;
-               Ent->Object->ReferenceCount ++;
-               break;
-       default:
-               SpiderScript_ReferenceValue(Value);
-               Ent->Type = ET_REFERENCE;
-               Ent->Reference = Value;
-               break;
-       }
-}
-
-void Bytecode_int_DerefStackValue(tBC_StackEnt *Ent)
-{
-       switch(Ent->Type)
-       {
-       case SS_DATATYPE_INTEGER:
-       case SS_DATATYPE_REAL:
-               break;
-       case SS_DATATYPE_OBJECT:
-               if(Ent->Object) {
-                       Ent->Object->ReferenceCount --;
-                       if(Ent->Object->ReferenceCount == 0) {
-                               Ent->Object->Type->Destructor( Ent->Object );
-                       }
-//                     printf("Object %p derefed (obj refcount = %i)\n", Ent->Object, Ent->Object->ReferenceCount);
-               }
-               Ent->Object = NULL;
-               break;
-       default:
-               if(Ent->Reference)
-                       SpiderScript_DereferenceValue(Ent->Reference);
-               Ent->Reference = NULL;
-               break;
-       }
-}
-void Bytecode_int_RefStackValue(tBC_StackEnt *Ent)
-{
-       switch(Ent->Type)
-       {
-       case SS_DATATYPE_INTEGER:
-       case SS_DATATYPE_REAL:
-               break;
-       case SS_DATATYPE_OBJECT:
-               if(Ent->Object) {
-                       Ent->Object->ReferenceCount ++;
-//                     printf("Object %p referenced (count = %i)\n", Ent->Object, Ent->Object->ReferenceCount);
-               }
-               break;
-       default:
-               if(Ent->Reference)
-                       SpiderScript_ReferenceValue(Ent->Reference);
-               break;
-       }
-}
-
-void Bytecode_int_PrintStackValue(tBC_StackEnt *Ent)
-{
-       switch(Ent->Type)
-       {
-       case SS_DATATYPE_INTEGER:
-               printf("0x%"PRIx64, Ent->Integer);
-               break;
-       case SS_DATATYPE_REAL:
-               printf("%lf", Ent->Real);
-               break;
-       case SS_DATATYPE_OBJECT:
-               printf("Obj %p", Ent->Object);
-               break;
-       default:
-               if( Ent->Reference )
-                       printf("*%p (%i refs)", Ent->Reference, Ent->Reference->ReferenceCount);
-               else
-                       printf("NULL");
-               break;
-       }
-}
-
-#if TRACE
-# define PRINT_STACKVAL(val)   Bytecode_int_PrintStackValue(&val)
-#else
-# define PRINT_STACKVAL(val)
-#endif
-
-#define GET_STACKVAL(dst)      if((ret = Bytecode_int_StackPop(Stack, &dst))) { \
-       AST_RuntimeError(NULL, "Stack pop failed, empty stack");\
-       return ret; \
-}
-#define PUT_STACKVAL(src)      if((ret = Bytecode_int_StackPush(Stack, &src))) { \
-       AST_RuntimeError(NULL, "Stack push failed, full stack");\
-       return ret; \
-}
-#define OP_INDX(op_ptr)        ((op_ptr)->Content.StringInt.Integer)
-#define OP_STRING(op_ptr)      ((op_ptr)->Content.StringInt.String)
-
-tSpiderValue *Bytecode_ExecuteFunction(tSpiderScript *Script, tScript_Function *Fcn, int NArguments, tSpiderValue **Args)
-{
-       const int       stack_size = 100;
-       tSpiderValue    *ret, tmpsval;
-       tBC_Stack       *stack;
-       tBC_StackEnt    val;
-        int    i;
-       
-       stack = malloc(sizeof(tBC_Stack) + stack_size*sizeof(tBC_StackEnt));
-       stack->EntrySpace = stack_size;
-       stack->EntryCount = 0;
-
-       // Push arguments in order (so top is last arg)
-       for( i = 0; i < NArguments; i ++ )
-       {
-               Bytecode_int_SetSpiderValue(&val, Args[i]);
-               Bytecode_int_StackPush(stack, &val);
-       }
-
-       // Call
-       Bytecode_int_ExecuteFunction(Script, Fcn, stack, NArguments);
-
-       // Get return value
-       if( Bytecode_int_StackPop(stack, &val) ) {
-               free(stack);
-               return NULL;
-       }
-       free(stack);
-       
-       ret = Bytecode_int_GetSpiderValue(&val, &tmpsval);
-       // Ensure it's a heap value
-       if(ret == &tmpsval) {
-               ret = malloc(sizeof(tSpiderValue));
-               memcpy(ret, &tmpsval, sizeof(tSpiderValue));
-               // Set to 2 in _GetSpiderValue, so stack doesn't have free() called
-               ret->ReferenceCount = 1;
-       }
-
-       return ret;
-}
-
-tSpiderNamespace *Bytecode_int_ResolveNamespace(tSpiderNamespace *Start, const char *Name, const char **FinalName)
-{
-       char    *pos;
-       tSpiderNamespace        *ns = Start;
-       while( (pos = strchr(Name, BC_NS_SEPARATOR)) )
-       {
-                int    len = pos - Name;
-               for( ns = ns->FirstChild; ns; ns = ns->Next )
-               {
-                       if(memcmp(ns->Name, Name, len) == 0 && ns->Name[len] == 0)
-                       break;
-               }
-               if(!ns) {
-                       return NULL;
-               }
-               Name += len + 1;
-       }
-       if(FinalName)   *FinalName = Name;
-       return ns;
-}
-
-/**
- * \brief Call an external function (may recurse into Bytecode_ExecuteFunction, but may not)
- */
-int Bytecode_int_CallExternFunction(tSpiderScript *Script, tBC_Stack *Stack, tSpiderNamespace *DefaultNS, tBC_Op *op )
-{
-       const char      *name = OP_STRING(op);
-        int    arg_count = OP_INDX(op);
-        int    i, ret = 0;
-       tSpiderValue    *args[arg_count];
-       tSpiderValue    *rv;
-       tBC_StackEnt    val1;
-       const char      *namespaces[] = {NULL}; // TODO: Default/imported namespaces
-
-       DEBUG_F("CALL (general) %s %i args\n", name, arg_count);
-       
-       // Read arguments
-       for( i = arg_count; i --; )
-       {
-               GET_STACKVAL(val1);
-               args[i] = Bytecode_int_GetSpiderValue(&val1, NULL);
-               Bytecode_int_DerefStackValue(&val1);
-       }
-       
-       // Call the function etc.
-       if( op->Operation == BC_OP_CALLFUNCTION )
-       {
-               rv = SpiderScript_ExecuteFunction(Script, name, namespaces, arg_count, args, &op->CacheEnt);
-       }
-       else if( op->Operation == BC_OP_CREATEOBJ )
-       {
-               rv = SpiderScript_CreateObject(Script, name, namespaces, arg_count, args);
-       }
-       else if( op->Operation == BC_OP_CALLMETHOD )
-       {
-               tSpiderObject   *obj;
-               GET_STACKVAL(val1);
-               
-               if(val1.Type == SS_DATATYPE_OBJECT)
-                       obj = val1.Object;
-               else if(val1.Type == ET_REFERENCE && val1.Reference && val1.Reference->Type == SS_DATATYPE_OBJECT)
-                       obj = val1.Reference->Object;
-               else {
-                       // Error
-                       AST_RuntimeError(NULL, "OP_CALLMETHOD on non object");
-                       return -1;
-               }
-               rv = SpiderScript_ExecuteMethod(Script, obj, name, arg_count, args);
-               Bytecode_int_DerefStackValue(&val1);
-       }
-       else
-       {
-               AST_RuntimeError(NULL, "BUG - Unknown operation for CALL/CREATEOBJ (%i)", op->Operation);
-               rv = ERRPTR;
-       }
-       if(rv == ERRPTR) {
-               AST_RuntimeError(NULL, "SpiderScript_ExecuteFunction returned ERRPTR");
-               return -1;
-       }
-       // Clean up args
-       for( i = arg_count; i --; )
-               SpiderScript_DereferenceValue(args[i]);
-       // Get and push return
-       Bytecode_int_SetSpiderValue(&val1, rv);
-       PUT_STACKVAL(val1);
-       // Deref return
-       SpiderScript_DereferenceValue(rv);
-
-       #if 0
-       if(!rv) {
-               printf("%s returned NULL\n", name);
-       }
-       if( rv && rv != ERRPTR && rv->ReferenceCount != 1 ) {
-               printf("Return value from %s reference count fail (%i)\n",
-                       name, rv->ReferenceCount);
-       }
-       #endif  
-
-       return 0;
-}
-
-int Bytecode_int_LocalBinOp_Integer(int Operation, tBC_StackEnt *Val1, tBC_StackEnt *Val2)
-{
-       switch(Operation)
-       {
-       case BC_OP_ADD:         Val1->Integer = Val1->Integer + Val2->Integer;  break;
-       case BC_OP_SUBTRACT:    Val1->Integer = Val1->Integer - Val2->Integer;  break;
-       case BC_OP_MULTIPLY:    Val1->Integer = Val1->Integer * Val2->Integer;  break;
-       case BC_OP_DIVIDE:      Val1->Integer = Val1->Integer / Val2->Integer;  break;
-       
-       case BC_OP_EQUALS:              Val1->Integer = (Val1->Integer == Val2->Integer);       break;
-       case BC_OP_NOTEQUALS:           Val1->Integer = (Val1->Integer != Val2->Integer);       break;
-       case BC_OP_LESSTHAN:            Val1->Integer = (Val1->Integer <  Val2->Integer);       break;
-       case BC_OP_LESSTHANOREQUAL:     Val1->Integer = (Val1->Integer <= Val2->Integer);       break;
-       case BC_OP_GREATERTHAN:         Val1->Integer = (Val1->Integer >  Val2->Integer);       break;
-       case BC_OP_GREATERTHANOREQUAL:  Val1->Integer = (Val1->Integer >= Val2->Integer);       break;
-       
-       case BC_OP_BITAND:      Val1->Integer = Val1->Integer & Val2->Integer;  break;
-       case BC_OP_BITOR:       Val1->Integer = Val1->Integer | Val2->Integer;  break;
-       case BC_OP_BITXOR:      Val1->Integer = Val1->Integer ^ Val2->Integer;  break;
-       case BC_OP_MODULO:      Val1->Integer = Val1->Integer % Val2->Integer;  break;
-       default:        AST_RuntimeError(NULL, "Invalid operation on datatype Integer"); return -1;
-       }
-       return 0;
-}
-
-int Bytecode_int_LocalBinOp_Real(int Operation, tBC_StackEnt *Val1, tBC_StackEnt *Val2)
-{
-       switch(Operation)
-       {
-       // Real = Real OP Real
-       case BC_OP_ADD:         Val1->Real = Val1->Real + Val2->Real;   return 0;
-       case BC_OP_SUBTRACT:    Val1->Real = Val1->Real - Val2->Real;   return 0;
-       case BC_OP_MULTIPLY:    Val1->Real = Val1->Real * Val2->Real;   return 0;
-       case BC_OP_DIVIDE:      Val1->Real = Val1->Real / Val2->Real;   return 0;
-
-       // Bool/Integer = Real OP Real
-       case BC_OP_EQUALS:              Val1->Integer = (Val1->Real == Val2->Real);     break;
-       case BC_OP_NOTEQUALS:           Val1->Integer = (Val1->Real != Val2->Real);     break;
-       case BC_OP_LESSTHAN:            Val1->Integer = (Val1->Real <  Val2->Real);     break;
-       case BC_OP_LESSTHANOREQUAL:     Val1->Integer = (Val1->Real <= Val2->Real);     break;
-       case BC_OP_GREATERTHAN:         Val1->Integer = (Val1->Real >  Val2->Real);     break;
-       case BC_OP_GREATERTHANOREQUAL:  Val1->Integer = (Val1->Real >= Val2->Real);     break;
-       
-       default:        AST_RuntimeError(NULL, "Invalid operation on datatype Real"); return -1;
-       }
-       Val1->Type = SS_DATATYPE_INTEGER;       // Becomes logical
-       return 0;
-}
-
-#define STATE_HDR()    DEBUG_F("%p %2i ", op, Stack->EntryCount)
-
-/**
- * \brief Execute a bytecode function with a stack
- */
-int Bytecode_int_ExecuteFunction(tSpiderScript *Script, tScript_Function *Fcn, tBC_Stack *Stack, int ArgCount)
-{
-        int    ret, ast_op, i;
-       tBC_Op  *op;
-       tBC_StackEnt    val1, val2;
-        int    local_var_count = Fcn->BCFcn->MaxVariableCount;
-       tBC_StackEnt    local_vars[local_var_count];    // Includes arguments
-       tSpiderValue    tmpVal1, tmpVal2;       // temp storage
-       tSpiderValue    *pval1, *pval2, *ret_val;
-       tSpiderNamespace        *default_namespace = &Script->Variant->RootNamespace;
-
-       // Initialise local vars
-       for( i = 0; i < local_var_count; i ++ )
-               local_vars[i].Type = ET_NULL;
-       
-       // Pop off arguments
-       if( ArgCount > Fcn->ArgumentCount )     return -1;
-       DEBUG_F("Fcn->ArgumentCount = %i\n", Fcn->ArgumentCount);
-       // - Handle optional arguments
-       for( i = Fcn->ArgumentCount; i > ArgCount; )
-       {
-               i --;
-               local_vars[i].Integer = 0;
-               local_vars[i].Type = Fcn->Arguments[i].Type;
-       }
-       for( ; i --; )
-       {
-               GET_STACKVAL(local_vars[i]);
-               // TODO: Type checks / enforcing
-       }
-       
-       // Mark the start
-       memset(&val1, 0, sizeof(val1));
-       val1.Type = ET_FUNCTION_START;
-       PUT_STACKVAL(val1);
-
-       // Execute!
-       op = Fcn->BCFcn->Operations;
-       while(op)
-       {
-               const char      *opstr = "";
-               tBC_Op  *nextop = op->Next, *jmp_target;
-               ast_op = 0;
-               switch(op->Operation)
-               {
-               case BC_OP_NOP:
-                       STATE_HDR();
-                       DEBUG_F("NOP\n");
-                       break;
-               // Jumps
-               case BC_OP_JUMP:
-                       STATE_HDR();
-                       jmp_target = Fcn->BCFcn->Labels[ OP_INDX(op) ]->Next;
-                       DEBUG_F("JUMP #%i %p\n", OP_INDX(op), jmp_target);
-                       nextop = jmp_target;
-                       break;
-               case BC_OP_JUMPIF:
-                       STATE_HDR();
-                       jmp_target = Fcn->BCFcn->Labels[ OP_INDX(op) ]->Next;
-                       DEBUG_F("JUMPIF #%i %p\n", OP_INDX(op), jmp_target);
-                       GET_STACKVAL(val1);
-                       if( Bytecode_int_IsStackEntTrue(&val1) )
-                               nextop = jmp_target;
-                       break;
-               case BC_OP_JUMPIFNOT:
-                       STATE_HDR();
-                       jmp_target = Fcn->BCFcn->Labels[ OP_INDX(op) ]->Next;
-                       DEBUG_F("JUMPIFNOT #%i %p\n", OP_INDX(op), jmp_target);
-                       GET_STACKVAL(val1);
-                       if( !Bytecode_int_IsStackEntTrue(&val1) )
-                               nextop = jmp_target;
-                       break;
-               
-               // Define variables
-               case BC_OP_DEFINEVAR: {
-                        int    type, slot;
-                       type = OP_INDX(op) & 0xFFFF;
-                       slot = OP_INDX(op) >> 16;
-                       if(slot < 0 || slot >= local_var_count) {
-                               DEBUG_F("ERROR: slot %i out of range (max %i)\n", slot, local_var_count);
-                               return -1;
-                       }
-                       STATE_HDR();
-                       DEBUG_F("DEFVAR %i of type %i\n", slot, type);
-                       if( local_vars[slot].Type != ET_NULL ) {
-                               Bytecode_int_DerefStackValue( &local_vars[slot] );
-                               local_vars[slot].Type = ET_NULL;
-                       }
-                       memset(&local_vars[slot], 0, sizeof(local_vars[0]));
-                       local_vars[slot].Type = type;
-                       } break;
-
-               // Enter/Leave context
-               // - NOP now            
-               case BC_OP_ENTERCONTEXT:
-                       STATE_HDR();
-                       DEBUG_F("ENTERCONTEXT\n");
-                       break;
-               case BC_OP_LEAVECONTEXT:
-                       STATE_HDR();
-                       DEBUG_F("LEAVECONTEXT\n");
-                       break;
-
-               // Variables
-               case BC_OP_LOADVAR: {
-                        int    slot = OP_INDX(op);
-                       STATE_HDR();
-                       DEBUG_F("LOADVAR %i ", slot);
-                       if( slot < 0 || slot >= local_var_count ) {
-                               AST_RuntimeError(NULL, "Loading from invalid slot %i", slot);
-                               return -1;
-                       }
-                       DEBUG_F("("); PRINT_STACKVAL(local_vars[slot]); DEBUG_F(")\n");
-                       PUT_STACKVAL(local_vars[slot]);
-                       Bytecode_int_RefStackValue( &local_vars[slot] );
-                       } break;
-               case BC_OP_SAVEVAR: {
-                        int    slot = OP_INDX(op);
-                       STATE_HDR();
-                       DEBUG_F("SAVEVAR %i = ", slot);
-                       if( slot < 0 || slot >= local_var_count ) {
-                               AST_RuntimeError(NULL, "Loading from invalid slot %i", slot);
-                               return -1;
-                       }
-                       // Remove whatever was in there before
-                       DEBUG_F("[Deref "); PRINT_STACKVAL(local_vars[slot]); DEBUG_F("] ");
-                       Bytecode_int_DerefStackValue( &local_vars[slot] );
-                       // Place new in
-                       GET_STACKVAL(local_vars[slot]);
-                       PRINT_STACKVAL(local_vars[slot]);
-                       DEBUG_F("\n");
-                       } break;
-
-               // Array index (get or set)
-               case BC_OP_INDEX:
-               case BC_OP_SETINDEX:
-                       STATE_HDR();
-                       GET_STACKVAL(val1);     // Index
-                       // TODO: Check that index is an integer
-                       if( val1.Type != SS_DATATYPE_INTEGER ) {
-                               nextop = NULL;
-                               break;
-                       }
-
-                       // Get array as raw spider value
-                       GET_STACKVAL(val2);     // Array
-                       pval1 = Bytecode_int_GetSpiderValue(&val2, &tmpVal1);
-                       Bytecode_int_DerefStackValue(&val2);
-
-                       if( op->Operation == BC_OP_SETINDEX ) {
-                               GET_STACKVAL(val2);
-                               pval2 = Bytecode_int_GetSpiderValue(&val2, NULL);
-                               Bytecode_int_DerefStackValue(&val2);
-                               
-                               DEBUG_F("SETINDEX %i ", val1.Integer); PRINT_STACKVAL(val2); DEBUG_F("\n");
-                       
-                               ret_val = AST_ExecuteNode_Index(Script, NULL, pval1, val1.Integer, pval2);
-                               if(ret_val == ERRPTR) { nextop = NULL; break; }
-                               SpiderScript_DereferenceValue(pval2);
-                       }
-                       else {
-                               DEBUG_F("INDEX %i ", val1.Integer);
-                               ret_val = AST_ExecuteNode_Index(Script, NULL, pval1, val1.Integer, ERRPTR);
-                               if(ret_val == ERRPTR) { nextop = NULL; break; }
-                               
-                               Bytecode_int_SetSpiderValue(&val1, ret_val);
-                               SpiderScript_DereferenceValue(ret_val);
-                               PUT_STACKVAL(val1);
-
-                               DEBUG_F("[Got "); PRINT_STACKVAL(val1); DEBUG_F("]\n");
-
-                       }
-                       // Dereference the array (or object, ...)
-                       if(pval1 != &tmpVal1)   SpiderScript_DereferenceValue(pval1);
-                       break;
-               
-               // Object element (get or set)
-               case BC_OP_ELEMENT:
-               case BC_OP_SETELEMENT:
-                       STATE_HDR();
-                       
-                       GET_STACKVAL(val1);
-                       // - Integers/Reals can't have elements :)
-                       if( val1.Type != ET_REFERENCE ) {
-                               nextop = NULL;
-                               break;
-                       }
-
-                       pval1 = Bytecode_int_GetSpiderValue(&val1, NULL);
-                       Bytecode_int_DerefStackValue(&val1);
-
-                       if( op->Operation == BC_OP_SETELEMENT ) {
-                               GET_STACKVAL(val2);
-                               pval2 = Bytecode_int_GetSpiderValue(&val2, &tmpVal2);
-                               Bytecode_int_DerefStackValue(&val2);
-                               
-                               DEBUG_F("SETELEMENT %s ", OP_STRING(op)); PRINT_STACKVAL(val2); DEBUG_F("\n");
-
-                               ret_val = AST_ExecuteNode_Element(Script, NULL, pval1, OP_STRING(op), pval2);
-                               if(ret_val == ERRPTR) { nextop = NULL; break; }
-                               
-                               if(pval2 != &tmpVal2)   SpiderScript_DereferenceValue(pval2);
-                       }
-                       else {
-                               DEBUG_F("ELEMENT %s ", OP_STRING(op));
-                               
-                               ret_val = AST_ExecuteNode_Element(Script, NULL, pval1, OP_STRING(op), ERRPTR);
-                               if(ret_val == ERRPTR) { nextop = NULL; break; }
-
-                               Bytecode_int_SetSpiderValue(&val2, ret_val);
-                               SpiderScript_DereferenceValue(ret_val);
-                               PUT_STACKVAL(val2);
-       
-                               DEBUG_F("[Got "); PRINT_STACKVAL(val2); DEBUG_F("]\n");
-                       }
-                       
-                       SpiderScript_DereferenceValue(pval1);
-                       break;
-
-               // Constants:
-               case BC_OP_LOADINT:
-                       STATE_HDR();
-                       DEBUG_F("LOADINT 0x%lx\n", op->Content.Integer);
-                       val1.Type = SS_DATATYPE_INTEGER;
-                       val1.Integer = op->Content.Integer;
-                       PUT_STACKVAL(val1);
-                       break;
-               case BC_OP_LOADREAL:
-                       STATE_HDR();
-                       DEBUG_F("LOADREAL %lf\n", op->Content.Real);
-                       val1.Type = SS_DATATYPE_REAL;
-                       val1.Real = op->Content.Real;
-                       PUT_STACKVAL(val1);
-                       break;
-               case BC_OP_LOADSTR:
-                       STATE_HDR();
-                       DEBUG_F("LOADSTR %i \"%s\"\n", OP_INDX(op), OP_STRING(op));
-                       val1.Type = SS_DATATYPE_STRING;
-                       val1.Reference = SpiderScript_CreateString(OP_INDX(op), OP_STRING(op));
-                       PUT_STACKVAL(val1);
-                       break;
-               case BC_OP_LOADNULL:
-                       STATE_HDR();
-                       DEBUG_F("LOADNULL\n");
-                       val1.Type = ET_REFERENCE;
-                       val1.Reference = NULL;
-                       PUT_STACKVAL(val1);
-                       break;
-
-               case BC_OP_CAST:
-                       STATE_HDR();
-                       val2.Type = OP_INDX(op);
-                       DEBUG_F("CAST to %i\n", val2.Type);
-                       GET_STACKVAL(val1);
-                       if(val1.Type == val2.Type) {
-                               PUT_STACKVAL(val1);
-                               break;
-                       }
-                       if( val2.Type == SS_DATATYPE_INTEGER && val1.Type == SS_DATATYPE_REAL ) {
-                               val2.Integer = val1.Real;
-                       }
-                       else if( val2.Type == SS_DATATYPE_REAL && val2.Type == SS_DATATYPE_INTEGER ) {
-                               val2.Real = val1.Integer;
-                       }
-                       else {
-                               pval1 = Bytecode_int_GetSpiderValue(&val1, &tmpVal1);
-                               pval2 = SpiderScript_CastValueTo(val2.Type, pval1);
-                               
-                               Bytecode_int_SetSpiderValue(&val2, pval2);
-                               SpiderScript_DereferenceValue(pval2);
-                               
-                               if(pval1 != &tmpVal1)   SpiderScript_DereferenceValue(pval1);
-                               Bytecode_int_DerefStackValue(&val1);
-//                             printf("CAST (%x->%x) - Original %i references remaining\n",
-//                                     pval1->Type, OP_INDX(op),
-//                                     pval1->ReferenceCount);
-                       }
-                       PUT_STACKVAL(val2);
-                       break;
-
-               case BC_OP_DUPSTACK:
-                       STATE_HDR();
-                       DEBUG_F("DUPSTACK ");
-                       GET_STACKVAL(val1);
-                       PRINT_STACKVAL(val1);
-                       DEBUG_F("\n");
-                       PUT_STACKVAL(val1);
-                       PUT_STACKVAL(val1);
-                       Bytecode_int_RefStackValue(&val1);
-                       break;
-
-               // Discard the top item from the stack
-               case BC_OP_DELSTACK:
-                       STATE_HDR();
-                       DEBUG_F("DELSTACK\n");
-                       GET_STACKVAL(val1);
-                       break;
-
-               // Unary Operations
-               case BC_OP_LOGICNOT:
-                       STATE_HDR();
-                       DEBUG_F("LOGICNOT\n");
-                       
-                       GET_STACKVAL(val1);
-                       val2.Type = SS_DATATYPE_INTEGER;
-                       val2.Integer = !Bytecode_int_IsStackEntTrue(&val1);
-                       Bytecode_int_StackPush(Stack, &val2);
-                       Bytecode_int_DerefStackValue(&val1);
-                       break;
-               
-               case BC_OP_BITNOT:
-                       if(!ast_op)     ast_op = NODETYPE_BWNOT,        opstr = "BITNOT";
-               case BC_OP_NEG:
-                       if(!ast_op)     ast_op = NODETYPE_NEGATE,       opstr = "NEG";
-
-                       STATE_HDR();
-                       DEBUG_F("%s\n", opstr);
-
-                       GET_STACKVAL(val1);
-                       pval1 = Bytecode_int_GetSpiderValue(&val1, &tmpVal1);
-                       Bytecode_int_DerefStackValue(&val1);                    
-
-                       ret_val = AST_ExecuteNode_UniOp(Script, NULL, ast_op, pval1);
-                       if(pval1 != &tmpVal1)   SpiderScript_DereferenceValue(pval1);
-                       Bytecode_int_SetSpiderValue(&val1, ret_val);
-                       if(ret_val != &tmpVal1) SpiderScript_DereferenceValue(ret_val);
-                       Bytecode_int_StackPush(Stack, &val1);
-                       
-                       break;
-
-               // Binary Operations
-               case BC_OP_LOGICAND:
-                       if(!ast_op)     ast_op = NODETYPE_LOGICALAND,   opstr = "LOGICAND";
-               case BC_OP_LOGICOR:
-                       if(!ast_op)     ast_op = NODETYPE_LOGICALOR,    opstr = "LOGICOR";
-               case BC_OP_LOGICXOR:
-                       if(!ast_op)     ast_op = NODETYPE_LOGICALXOR,   opstr = "LOGICXOR";
-       
-                       STATE_HDR();
-                       DEBUG_F("%s\n", opstr);
-
-                       GET_STACKVAL(val1);
-                       GET_STACKVAL(val2);
-                       
-                       switch(op->Operation)
-                       {
-                       case BC_OP_LOGICAND:
-                               i = Bytecode_int_IsStackEntTrue(&val1) && Bytecode_int_IsStackEntTrue(&val2);
-                               break;
-                       case BC_OP_LOGICOR:
-                               i = Bytecode_int_IsStackEntTrue(&val1) || Bytecode_int_IsStackEntTrue(&val2);
-                               break;
-                       case BC_OP_LOGICXOR:
-                               i = Bytecode_int_IsStackEntTrue(&val1) ^ Bytecode_int_IsStackEntTrue(&val2);
-                               break;
-                       }
-                       Bytecode_int_DerefStackValue(&val1);
-                       Bytecode_int_DerefStackValue(&val2);
-
-                       val1.Type = SS_DATATYPE_INTEGER;
-                       val1.Integer = i;
-                       Bytecode_int_StackPush(Stack, &val1);
-                       break;
-
-               case BC_OP_BITAND:
-                       if(!ast_op)     ast_op = NODETYPE_BWAND,        opstr = "BITAND";
-               case BC_OP_BITOR:
-                       if(!ast_op)     ast_op = NODETYPE_BWOR,         opstr = "BITOR";
-               case BC_OP_BITXOR:
-                       if(!ast_op)     ast_op = NODETYPE_BWXOR,        opstr = "BITXOR";
-
-               case BC_OP_BITSHIFTLEFT:
-                       if(!ast_op)     ast_op = NODETYPE_BITSHIFTLEFT, opstr = "BITSHIFTLEFT";
-               case BC_OP_BITSHIFTRIGHT:
-                       if(!ast_op)     ast_op = NODETYPE_BITSHIFTRIGHT, opstr = "BITSHIFTRIGHT";
-               case BC_OP_BITROTATELEFT:
-                       if(!ast_op)     ast_op = NODETYPE_BITROTATELEFT, opstr = "BITROTATELEFT";
-
-               case BC_OP_ADD:
-                       if(!ast_op)     ast_op = NODETYPE_ADD,  opstr = "ADD";
-               case BC_OP_SUBTRACT:
-                       if(!ast_op)     ast_op = NODETYPE_SUBTRACT,     opstr = "SUBTRACT";
-               case BC_OP_MULTIPLY:
-                       if(!ast_op)     ast_op = NODETYPE_MULTIPLY,     opstr = "MULTIPLY";
-               case BC_OP_DIVIDE:
-                       if(!ast_op)     ast_op = NODETYPE_DIVIDE,       opstr = "DIVIDE";
-               case BC_OP_MODULO:
-                       if(!ast_op)     ast_op = NODETYPE_MODULO,       opstr = "MODULO";
-
-               case BC_OP_EQUALS:
-                       if(!ast_op)     ast_op = NODETYPE_EQUALS,       opstr = "EQUALS";
-               case BC_OP_NOTEQUALS:
-                       if(!ast_op)     ast_op = NODETYPE_NOTEQUALS,    opstr = "NOTEQUALS";
-               case BC_OP_LESSTHAN:
-                       if(!ast_op)     ast_op = NODETYPE_LESSTHAN,     opstr = "LESSTHAN";
-               case BC_OP_LESSTHANOREQUAL:
-                       if(!ast_op)     ast_op = NODETYPE_LESSTHANEQUAL, opstr = "LESSTHANOREQUAL";
-               case BC_OP_GREATERTHAN:
-                       if(!ast_op)     ast_op = NODETYPE_GREATERTHAN,  opstr = "GREATERTHAN";
-               case BC_OP_GREATERTHANOREQUAL:
-                       if(!ast_op)     ast_op = NODETYPE_GREATERTHANEQUAL, opstr = "GREATERTHANOREQUAL";
-
-                       STATE_HDR();
-                       DEBUG_F("BINOP %i %s (bc %i)\n", ast_op, opstr, op->Operation);
-
-                       GET_STACKVAL(val2);     // Right
-                       GET_STACKVAL(val1);     // Left
-
-                       DEBUG_F(" ("); PRINT_STACKVAL(val1); DEBUG_F(")");
-                       DEBUG_F(" ("); PRINT_STACKVAL(val2); DEBUG_F(")\n");
-
-                       // Perform integer operations locally
-                       if( val1.Type == SS_DATATYPE_INTEGER && val2.Type == SS_DATATYPE_INTEGER )
-                       {
-                               if( Bytecode_int_LocalBinOp_Integer(op->Operation, &val1, &val2) ) {
-                                       nextop = NULL;
-                                       break;
-                               }
-                               PUT_STACKVAL(val1);
-                               break;
-                       }
-
-                       if(val1. Type == SS_DATATYPE_REAL && val2.Type == SS_DATATYPE_REAL )
-                       {
-                               if( Bytecode_int_LocalBinOp_Real(op->Operation, &val1, &val2) ) {
-                                       nextop = NULL;
-                                       break;
-                               }
-                               PUT_STACKVAL(val1);
-                               break;
-                       }
-               
-                       pval1 = Bytecode_int_GetSpiderValue(&val1, &tmpVal1);
-                       pval2 = Bytecode_int_GetSpiderValue(&val2, &tmpVal2);
-                       Bytecode_int_DerefStackValue(&val1);
-                       Bytecode_int_DerefStackValue(&val2);
-
-                       // Hand to AST execution code
-                       ret_val = AST_ExecuteNode_BinOp(Script, NULL, ast_op, pval1, pval2);
-                       if(pval1 != &tmpVal1)   SpiderScript_DereferenceValue(pval1);
-                       if(pval2 != &tmpVal2)   SpiderScript_DereferenceValue(pval2);
-
-                       if(ret_val == ERRPTR) {
-                               AST_RuntimeError(NULL, "_BinOp returned ERRPTR");
-                               nextop = NULL;
-                               break;
-                       }
-                       Bytecode_int_SetSpiderValue(&val1, ret_val);
-                       if(ret_val != &tmpVal1) SpiderScript_DereferenceValue(ret_val);
-                       PUT_STACKVAL(val1);
-                       break;
-
-               // Functions etc
-               case BC_OP_CREATEOBJ:
-               case BC_OP_CALLFUNCTION:
-               case BC_OP_CALLMETHOD:
-                       STATE_HDR();
-
-                       if( op->Operation == BC_OP_CALLFUNCTION )
-                       {
-                               tScript_Function        *fcn = NULL;
-                               const char      *name = OP_STRING(op);
-                                int    arg_count = OP_INDX(op);
-                               DEBUG_F("CALL (local) %s %i args\n", name, arg_count);
-                               // Check current script functions (for fast call)
-                               for(fcn = Script->Functions; fcn; fcn = fcn->Next)
-                               {
-                                       if(strcmp(name, fcn->Name) == 0) {
-                                               break;
-                                       }
-                               }
-                               if(fcn && fcn->BCFcn)
-                               {
-                                       DEBUG_F(" - Fast call\n");
-                                       Bytecode_int_ExecuteFunction(Script, fcn, Stack, arg_count);
-                                       break;
-                               }
-                       }
-               
-                       // Slower call
-                       if( Bytecode_int_CallExternFunction( Script, Stack, default_namespace, op ) ) {
-                               nextop = NULL;
-                               break;
-                       }
-                       break;
-
-               case BC_OP_RETURN:
-                       STATE_HDR();
-
-                       DEBUG_F("RETURN\n");
-                       nextop = NULL;
-                       break;
-
-               default:
-                       // TODO:
-                       STATE_HDR();
-                       AST_RuntimeError(NULL, "Unknown operation %i\n", op->Operation);
-                       nextop = NULL;
-                       break;
-               }
-               op = nextop;
-       }
-       
-       // Clean up
-       // - Delete local vars
-       for( i = 0; i < local_var_count; i ++ )
-       {
-               if( local_vars[i].Type != ET_NULL )
-               {
-                       DEBUG_F("Var %i - ", i); 
-                       PRINT_STACKVAL(local_vars[i]);
-                       Bytecode_int_DerefStackValue(&local_vars[i]);
-                       DEBUG_F("\n");
-               }
-               else
-                       DEBUG_F("Var %i - empty\n", i);
-       }
-       
-       // - Restore stack
-       if( Stack->Entries[Stack->EntryCount - 1].Type == ET_FUNCTION_START )
-               Stack->EntryCount --;
-       else
-       {
-                int    n_rolled = 1;
-               GET_STACKVAL(val1);
-               while( Stack->EntryCount && Stack->Entries[ --Stack->EntryCount ].Type != ET_FUNCTION_START )
-               {
-                       Bytecode_int_DerefStackValue( &Stack->Entries[Stack->EntryCount] );
-                       n_rolled ++;
-               }
-               PUT_STACKVAL(val1);
-               DEBUG_F("Rolled back %i entries\n", n_rolled);
-       }
-       
-
-       return 0;
-}
-
diff --git a/Usermode/Libraries/libspiderscript.so_src/exports.c b/Usermode/Libraries/libspiderscript.so_src/exports.c
deleted file mode 100644 (file)
index edf6439..0000000
+++ /dev/null
@@ -1,171 +0,0 @@
-/*
- * Acess2 - SpiderScript
- * - Script Exports (Lang. Namespace)
- */
-#define _GNU_SOURCE    // HACK!
-#include <string.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <spiderscript.h>
-
-// === PROTOTYPES ===
-tSpiderValue   *Exports_sizeof(tSpiderScript *Script, int NArgs, tSpiderValue **Args);
-tSpiderValue   *Exports_array(tSpiderScript *Script, int NArgs, tSpiderValue **Args);
-tSpiderValue   *Exports_Lang_Strings_Split(tSpiderScript *Script, int NArgs, tSpiderValue **Args);
-tSpiderValue   *Exports_Lang_Struct(tSpiderScript *Script, int NArgs, tSpiderValue **Args);
-
-// === GLOBALS ===
-tSpiderFunction        gExports_Lang_Strings_Split = {
-       .Name = "Split",
-       .Handler = Exports_Lang_Strings_Split,
-       .ReturnType = SS_MAKEARRAY(SS_DATATYPE_STRING),
-       .ArgTypes = {SS_DATATYPE_STRING, SS_DATATYPE_STRING, -1}
-};
-tSpiderNamespace       gExports_NS_Lang_Strings = {
-       .Name = "Strings",
-       .Functions = &gExports_Lang_Strings_Split
-       };
-
-tSpiderFunction        gExports_Lang_Struct = {
-       .Name = "Struct",
-       .Handler = Exports_Lang_Struct,
-       .ReturnType = SS_DATATYPE_OPAQUE,
-       .ArgTypes = {SS_DATATYPE_STRING, -1}
-};
-// - Lang Namespace
-tSpiderNamespace       gExports_NS_Lang = {
-       .Name = "Lang",
-       .Functions = &gExports_Lang_Struct,
-       .FirstChild = &gExports_NS_Lang_Strings
-       };
-tSpiderNamespace       gExportNamespaceRoot = {
-       .FirstChild = &gExports_NS_Lang
-};
-
-// -- Global Functions
-tSpiderFunction        gExports_array = {
-       .Next = NULL,
-       .Name = "array",
-       .Handler = Exports_array,
-       .ReturnType = SS_DATATYPE_DYNAMIC,
-       .ArgTypes = {SS_DATATYPE_INTEGER, -1}
-};
-tSpiderFunction        gExports_sizeof = {
-       .Next = &gExports_array,
-       .Name = "sizeof",
-       .Handler = Exports_sizeof,
-       .ReturnType = SS_DATATYPE_INTEGER,
-       .ArgTypes = {SS_DATATYPE_UNDEF, -1}
-};
-tSpiderFunction        *gpExports_First = &gExports_sizeof;
-
-// === CODE ===
-tSpiderValue *Exports_sizeof(tSpiderScript *Script, int NArgs, tSpiderValue **Args)
-{
-       if(NArgs != 1 || !Args[0])      return NULL;
-
-       switch( Args[0]->Type )
-       {
-       case SS_DATATYPE_STRING:
-               return SpiderScript_CreateInteger(Args[0]->String.Length);
-       case SS_DATATYPE_ARRAY:
-               return SpiderScript_CreateInteger(Args[0]->Array.Length);
-       default:
-               return NULL;
-       }
-}
-
-tSpiderValue *Exports_array(tSpiderScript *Script, int NArgs, tSpiderValue **Args)
-{
-       if(NArgs != 2)  return ERRPTR;
-       if(!Args[0] || !Args[1])        return ERRPTR;
-       
-       if(Args[0]->Type != SS_DATATYPE_INTEGER || Args[1]->Type != SS_DATATYPE_INTEGER)
-               return ERRPTR;
-
-        int    type = Args[1]->Integer;
-        int    size = Args[0]->Integer;
-
-       if( type != SS_DATATYPE_ARRAY )
-       {
-               if( !SS_GETARRAYDEPTH(type) ) {
-                       // ERROR - This should never happen
-                       return ERRPTR;
-               }
-               type = SS_DOWNARRAY(type);
-       }
-
-       return SpiderScript_CreateArray(type, size);
-}
-
-tSpiderValue *Exports_Lang_Strings_Split(tSpiderScript *Script, int NArgs, tSpiderValue **Args)
-{
-        int    len, ofs, slen;
-       void    *haystack, *end;
-        int    nSubStrs = 0;
-       tSpiderValue    **strings = NULL;
-       tSpiderValue    *ret;
-
-       // Error checking
-       if( NArgs != 2 )
-               return ERRPTR;
-       if( !Args[0] || !Args[1] )
-               return ERRPTR;
-       if( Args[0]->Type != SS_DATATYPE_STRING )
-               return ERRPTR;
-       if( Args[1]->Type != SS_DATATYPE_STRING )
-               return ERRPTR;
-
-       // Split the string
-       len = Args[0]->String.Length;
-       haystack = Args[0]->String.Data;
-       ofs = 0;
-       do {
-               end = memmem(haystack + ofs, len - ofs, Args[1]->String.Data, Args[1]->String.Length);
-               if( end )
-                       slen = end - (haystack + ofs);
-               else
-                       slen = len - ofs;
-               
-               strings = realloc(strings, (nSubStrs+1)*sizeof(tSpiderValue*));
-               strings[nSubStrs] = SpiderScript_CreateString(slen, haystack + ofs);
-               nSubStrs ++;
-
-               ofs += slen + Args[1]->String.Length;
-       } while(end);
-
-       // Create output array
-       ret = SpiderScript_CreateArray(SS_DATATYPE_STRING, nSubStrs);
-       memcpy(ret->Array.Items, strings, nSubStrs*sizeof(tSpiderValue*));
-       free(strings);
-
-       return ret;
-}
-
-tSpiderValue *Exports_Lang_Struct(tSpiderScript *Script, int NArgs, tSpiderValue **Args)
-{
-        int    i;
-       printf("Exports_Lang_Struct: (Script=%p, NArgs=%i, Args=%p)\n", Script, NArgs, Args);
-       
-       for( i = 0; i < NArgs; i ++ )
-       {
-               printf(" Args[%i] = {Type: %i, ", i, Args[i]->Type);
-               switch(Args[i]->Type)
-               {
-               case SS_DATATYPE_INTEGER:
-                       printf(" Integer: 0x%lx", Args[i]->Integer);
-                       break;
-               case SS_DATATYPE_REAL:
-                       printf(" Real: %f", Args[i]->Real);
-                       break;
-               case SS_DATATYPE_STRING:
-                       printf(" Length: %i, Data = '%s'", Args[i]->String.Length, Args[i]->String.Data);
-                       break;
-               default:
-                       break;
-               }
-               printf("}\n");
-       }
-       
-       return NULL;
-}
diff --git a/Usermode/Libraries/libspiderscript.so_src/lex.c b/Usermode/Libraries/libspiderscript.so_src/lex.c
deleted file mode 100644 (file)
index b659e34..0000000
+++ /dev/null
@@ -1,473 +0,0 @@
-/*
- * SpiderScript
- * - Script Lexer
- */
-#include "tokens.h"
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-
-#define DEBUG  0
-
-#define ARRAY_SIZE(x)  ((sizeof(x))/(sizeof((x)[0])))
-
-// === PROTOTYPES ===
- int   is_ident(char ch);
- int   isdigit(int ch);
- int   isspace(int ch);
- int   GetToken(tParser *File);
-
-// === CONSTANTS ===
-const struct {
-       const  int      Value;
-       const char      *Name;
-} csaReservedWords[] = {
-       {TOK_RWD_FUNCTION, "function"},
-       
-       {TOK_RWD_RETURN, "return"},
-       {TOK_RWD_BREAK, "break"},
-       {TOK_RWD_CONTINUE, "continue"},
-       {TOK_RWD_NEW, "new"},
-       
-       {TOK_RWD_IF, "if"},
-       {TOK_RWD_ELSE, "else"},
-       {TOK_RWD_DO, "do"},
-       {TOK_RWD_WHILE, "while"},
-       {TOK_RWD_FOR, "for"},
-       
-       {TOK_RWD_NULL, "null"},
-       {TOK_RWD_VOID, "void"},
-       {TOK_RWD_OBJECT, "Object"},
-       {TOK_RWD_OPAQUE, "Opaque"},
-       {TOK_RWD_INTEGER, "Integer"},
-       {TOK_RWD_REAL, "Real"},
-       {TOK_RWD_STRING, "String"}
-};
-
-// === CODE ===
-/**
- * \brief Read a token from a buffer
- * \param File Parser state
- */
-int GetToken(tParser *File)
-{
-        int    ret;
-       
-       if( File->NextToken != -1 ) {
-               // Save Last
-               File->LastToken = File->Token;
-               File->LastTokenStr = File->TokenStr;
-               File->LastTokenLen = File->TokenLen;
-               File->LastLine = File->CurLine;
-               // Restore Next
-               File->Token = File->NextToken;
-               File->TokenStr = File->NextTokenStr;
-               File->TokenLen = File->NextTokenLen;
-               File->CurLine = File->NextLine;
-               // Set State
-               File->CurPos = File->TokenStr + File->TokenLen;
-               File->NextToken = -1;
-               {
-                       char    buf[ File->TokenLen + 1];
-                       memcpy(buf, File->TokenStr, File->TokenLen);
-                       buf[File->TokenLen] = 0;
-                       #if DEBUG
-                       printf(" GetToken: FAST Return %i (%i long) (%s)\n", File->Token, File->TokenLen, buf);
-                       #endif
-               }
-               return File->Token;
-       }
-       
-       //printf("  GetToken: File=%p, File->CurPos = %p\n", File, File->CurPos);
-       
-       // Clear whitespace (including comments)
-       for( ;; )
-       {
-               // Whitespace
-               while( isspace( *File->CurPos ) )
-               {
-                       //printf("whitespace 0x%x, line = %i\n", *File->CurPos, File->CurLine);
-                       if( *File->CurPos == '\n' )
-                               File->CurLine ++;
-                       File->CurPos ++;
-               }
-               
-               // # Line Comments
-               if( *File->CurPos == '#' ) {
-                       while( *File->CurPos && *File->CurPos != '\n' )
-                               File->CurPos ++;
-                       continue ;
-               }
-               
-               // C-Style Line Comments
-               if( *File->CurPos == '/' && File->CurPos[1] == '/' ) {
-                       while( *File->CurPos && *File->CurPos != '\n' )
-                               File->CurPos ++;
-                       continue ;
-               }
-               
-               // C-Style Block Comments
-               if( *File->CurPos == '/' && File->CurPos[1] == '*' ) {
-                       File->CurPos += 2;      // Eat the '/*'
-                       while( *File->CurPos && !(File->CurPos[-1] == '*' && *File->CurPos == '/') )
-                       {
-                               if( *File->CurPos == '\n' )     File->CurLine ++;
-                               File->CurPos ++;
-                       }
-                       File->CurPos ++;        // Eat the '/'
-                       continue ;
-               }
-               
-               // No more "whitespace"
-               break;
-       }
-       
-       // Save previous tokens (speeds up PutBack and LookAhead)
-       File->LastToken = File->Token;
-       File->LastTokenStr = File->TokenStr;
-       File->LastTokenLen = File->TokenLen;
-       File->LastLine = File->CurLine;
-       
-       // Read token
-       File->TokenStr = File->CurPos;
-       switch( *File->CurPos++ )
-       {
-       case '\0':      ret = TOK_EOF;  break;
-       
-       // Operations
-       case '^':
-               if( *File->CurPos == '^' ) {
-                       File->CurPos ++;
-                       ret = TOK_LOGICXOR;
-                       break;
-               }
-               ret = TOK_XOR;
-               break;
-       
-       case '|':
-               if( *File->CurPos == '|' ) {
-                       File->CurPos ++;
-                       ret = TOK_LOGICOR;
-                       break;
-               }
-               ret = TOK_OR;
-               break;
-       
-       case '&':
-               if( *File->CurPos == '&' ) {
-                       File->CurPos ++;
-                       ret = TOK_LOGICAND;
-                       break;
-               }
-               ret = TOK_AND;
-               break;
-       
-       case '/':
-               if( *File->CurPos == '=' ) {
-                       File->CurPos ++;
-                       ret = TOK_ASSIGN_DIV;
-                       break;
-               }
-               ret = TOK_DIV;
-               break;
-       case '*':
-               if( *File->CurPos == '=' ) {
-                       File->CurPos ++;
-                       ret = TOK_ASSIGN_MUL;
-                       break;
-               }
-               ret = TOK_MUL;
-               break;
-       case '+':
-               if( *File->CurPos == '+' ) {
-                       File->CurPos ++;
-                       ret = TOK_INCREMENT;
-                       break;
-               }
-               if( *File->CurPos == '=' ) {
-                       File->CurPos ++;
-                       ret = TOK_ASSIGN_PLUS;
-                       break;
-               }
-               ret = TOK_PLUS;
-               break;
-       case '-':
-               if( *File->CurPos == '-' ) {
-                       File->CurPos ++;
-                       ret = TOK_DECREMENT;
-                       break;
-               }
-               if( *File->CurPos == '=' ) {
-                       File->CurPos ++;
-                       ret = TOK_ASSIGN_MINUS;
-                       break;
-               }
-               if( *File->CurPos == '>' ) {
-                       File->CurPos ++;
-                       ret = TOK_ELEMENT;
-                       break;
-               }
-               ret = TOK_MINUS;
-               break;
-       
-       // Strings
-       case '"':
-               while( *File->CurPos && !(*File->CurPos == '"' && *File->CurPos != '\\') )
-                       File->CurPos ++;
-               if( *File->CurPos )
-               {
-                       File->CurPos ++;
-                       ret = TOK_STR;
-               }
-               else
-                       ret = TOK_EOF;
-               break;
-       
-       // Brackets
-       case '(':       ret = TOK_PAREN_OPEN;   break;
-       case ')':       ret = TOK_PAREN_CLOSE;  break;
-       case '{':       ret = TOK_BRACE_OPEN;   break;
-       case '}':       ret = TOK_BRACE_CLOSE;  break;
-       case '[':       ret = TOK_SQUARE_OPEN;  break;
-       case ']':       ret = TOK_SQUARE_CLOSE; break;
-       
-       // Core symbols
-       case ';':       ret = TOK_SEMICOLON;    break;
-       case ',':       ret = TOK_COMMA;        break;
-       #if USE_SCOPE_CHAR
-       case '.':       ret = TOK_SCOPE;        break;
-       #endif
-       
-       // Equals
-       case '=':
-               // Comparison Equals
-               if( *File->CurPos == '=' ) {
-                       File->CurPos ++;
-                       ret = TOK_EQUALS;
-                       break;
-               }
-               // Assignment Equals
-               ret = TOK_ASSIGN;
-               break;
-       
-       // Less-Than
-       case '<':
-               // Less-Than or Equal
-               if( *File->CurPos == '=' ) {
-                       File->CurPos ++;
-                       ret = TOK_LTE;
-                       break;
-               }
-               ret = TOK_LT;
-               break;
-       
-       // Greater-Than
-       case '>':
-               // Greater-Than or Equal
-               if( *File->CurPos == '=' ) {
-                       File->CurPos ++;
-                       ret = TOK_GTE;
-                       break;
-               }
-               ret = TOK_GT;
-               break;
-       
-       // Logical NOT
-       case '!':
-               if( *File->CurPos == '=' ) {
-                       File->CurPos ++;
-                       ret = TOK_NOTEQUALS;
-                       break;
-               }
-               ret = TOK_LOGICNOT;
-               break;
-       // Bitwise NOT
-       case '~':
-               ret = TOK_BWNOT;
-               break;
-       
-       // Variables
-       // \$[0-9]+ or \$[_a-zA-Z][_a-zA-Z0-9]*
-       case '$':
-               // Numeric Variable
-               if( isdigit( *File->CurPos ) ) {
-                       while( isdigit(*File->CurPos) )
-                               File->CurPos ++;
-               }
-               // Ident Variable
-               else {
-                       while( is_ident(*File->CurPos) || isdigit(*File->CurPos) )
-                               File->CurPos ++;
-               }
-               ret = TOK_VARIABLE;
-               break;
-       
-       // Default (Numbers and Identifiers)
-       default:
-               File->CurPos --;
-               
-               // Numbers
-               if( isdigit(*File->CurPos) )
-               {
-                       ret = TOK_INTEGER;
-                       if( *File->CurPos == '0' && File->CurPos[1] == 'x' )
-                       {
-                               File->CurPos += 2;
-                               while(('0' <= *File->CurPos && *File->CurPos <= '9')
-                                  || ('A' <= *File->CurPos && *File->CurPos <= 'F')
-                                  || ('a' <= *File->CurPos && *File->CurPos <= 'f') )
-                               {
-                                       File->CurPos ++;
-                               }
-                       }
-                       else
-                       {
-                               while( isdigit(*File->CurPos) )
-                                       File->CurPos ++;
-                               
-//                             printf("*File->CurPos = '%c'\n", *File->CurPos);
-                               
-                               // Decimal
-                               if( *File->CurPos == '.' )
-                               {
-                                       ret = TOK_REAL;
-                                       File->CurPos ++;
-                                       while( isdigit(*File->CurPos) )
-                                               File->CurPos ++;
-                               }
-                               // Exponent
-                               if( *File->CurPos == 'e' || *File->CurPos == 'E' )
-                               {
-                                       ret = TOK_REAL;
-                                       File->CurPos ++;
-                                       if(*File->CurPos == '-' || *File->CurPos == '+')
-                                               File->CurPos ++;
-                                       while( isdigit(*File->CurPos) )
-                                               File->CurPos ++;
-                               }
-                               
-//                             printf(" ret = %i\n", ret);
-                       }
-                       break;
-               }
-       
-               // Identifier
-               if( is_ident(*File->CurPos) )
-               {
-                       ret = TOK_IDENT;
-                       
-                       // Identifier
-                       while( is_ident(*File->CurPos) || isdigit(*File->CurPos) )
-                               File->CurPos ++;
-                       
-                       // This is set later too, but we use it below
-                       File->TokenLen = File->CurPos - File->TokenStr;
-                       
-                       // Check if it's a reserved word
-                       {
-                               char    buf[File->TokenLen + 1];
-                                int    i;
-                               memcpy(buf, File->TokenStr, File->TokenLen);
-                               buf[File->TokenLen] = 0;
-                               for( i = 0; i < ARRAY_SIZE(csaReservedWords); i ++ )
-                               {
-                                       if(strcmp(csaReservedWords[i].Name, buf) == 0) {
-                                               ret = csaReservedWords[i].Value;
-                                               break ;
-                                       }
-                               }
-                       }
-                       // If there's no match, just keep ret as TOK_IDENT
-                       
-                       break;
-               }
-               // Syntax Error
-               File->Token = TOK_INVAL;
-               
-               fprintf(stderr, "Syntax Error: Unknown symbol '%c'\n", *File->CurPos);
-               longjmp(File->JmpTarget, 1);
-               
-               break;
-       }
-       // Return
-       File->Token = ret;
-       File->TokenLen = File->CurPos - File->TokenStr;
-       
-       #if DEBUG
-       {
-               char    buf[ File->TokenLen + 1];
-               memcpy(buf, File->TokenStr, File->TokenLen);
-               buf[File->TokenLen] = 0;
-               //printf("  GetToken: File->CurPos = %p\n", File->CurPos);
-               printf(" GetToken: Return %i (%i long) (%s)\n", ret, File->TokenLen, buf);
-       }
-       #endif
-       return ret;
-}
-
-void PutBack(tParser *File)
-{
-       if( File->LastToken == -1 ) {
-               // ERROR:
-               fprintf(stderr, "INTERNAL ERROR: Putback when LastToken==-1\n");
-               longjmp( File->JmpTarget, -1 );
-               return ;
-       }
-       #if DEBUG
-       printf(" PutBack: Was on %i\n", File->Token);
-       #endif
-       // Save
-       File->NextLine = File->CurLine;
-       File->NextToken = File->Token;
-       File->NextTokenStr = File->TokenStr;
-       File->NextTokenLen = File->TokenLen;
-       // Restore
-       File->CurLine = File->LastLine;
-       File->Token = File->LastToken;
-       File->TokenStr = File->LastTokenStr;
-       File->TokenLen = File->LastTokenLen;
-       File->CurPos = File->NextTokenStr;
-       // Invalidate
-       File->LastToken = -1;
-}
-
-int LookAhead(tParser *File)
-{
-       // TODO: Should I save the entire state here?
-        int    ret = GetToken(File);
-       PutBack(File);
-       return ret;
-}
-
-// --- Helpers ---
-/**
- * \brief Check for ident characters
- * \note Matches Regex [a-zA-Z_]
- */
-int is_ident(char ch)
-{
-       if('a' <= ch && ch <= 'z')      return 1;
-       if('A' <= ch && ch <= 'Z')      return 1;
-       if(ch == '_')   return 1;
-       #if !USE_SCOPE_CHAR
-       if(ch == '.')   return 1;
-       #endif
-       if(ch < 0)      return 1;
-       return 0;
-}
-
-int isdigit(int ch)
-{
-       if('0' <= ch && ch <= '9')      return 1;
-       return 0;
-}
-
-int isspace(int ch)
-{
-       if(' ' == ch)   return 1;
-       if('\t' == ch)  return 1;
-       if('\b' == ch)  return 1;
-       if('\n' == ch)  return 1;
-       if('\r' == ch)  return 1;
-       return 0;
-}
diff --git a/Usermode/Libraries/libspiderscript.so_src/main.c b/Usermode/Libraries/libspiderscript.so_src/main.c
deleted file mode 100644 (file)
index 17f5a3c..0000000
+++ /dev/null
@@ -1,143 +0,0 @@
-/*
- * Acess2 - SpiderScript
- * Interpreter Library
- */
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <spiderscript.h>
-#include "common.h"
-#include "ast.h"
-#include "bytecode_gen.h"
-
-// === IMPORTS ===
-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 ===
-/**
- * \brief Library Entry Point
- */
-int SoMain()
-{
-       return 0;
-}
-
-/**
- * \brief Parse a script
- */
-tSpiderScript *SpiderScript_ParseFile(tSpiderVariant *Variant, const char *Filename)
-{
-       char    *data;
-        int    fLen;
-       FILE    *fp;
-       tSpiderScript   *ret;
-       
-       fp = fopen(Filename, "r");
-       if( !fp ) {
-               return NULL;
-       }
-       
-       fseek(fp, 0, SEEK_END);
-       fLen = ftell(fp);
-       fseek(fp, 0, SEEK_SET);
-       
-       // Allocate and read data
-       data = malloc(fLen + 1);
-       if(!data)       return NULL;
-       fLen = fread(data, 1, fLen, fp);
-       fclose(fp);
-       if( fLen < 0 ) {
-               free(data);
-               return NULL;
-       }
-       data[fLen] = '\0';
-       
-       
-       // Create the script
-       ret = malloc(sizeof(tSpiderScript));
-       ret->Variant = Variant;
-       ret->Functions = NULL;
-       ret->LastFunction = NULL;
-       
-       ret->CurNamespace = NULL;
-       if( Parse_Buffer(ret, data, Filename) ) {
-               free(data);
-               free(ret);
-               return NULL;
-       }
-       
-       free(data);
-       
-       
-       // HACK!!
-       #if 1
-       // - Save AST to a file
-       {
-               char    cacheFilename[strlen(Filename)+6+1];
-               strcpy(cacheFilename, Filename);
-               strcat(cacheFilename, ".ast");
-       
-               SpiderScript_SaveAST(ret, cacheFilename);       
-       }
-       #endif
-       // - Save Bytecode too
-       {
-               char    cacheFilename[strlen(Filename)+6+1];
-               strcpy(cacheFilename, Filename);
-               strcat(cacheFilename, ".bc");
-       
-               SpiderScript_SaveBytecode(ret, cacheFilename);  
-       }
-       
-       return ret;
-}
-
-int SpiderScript_SaveAST(tSpiderScript *Script, const char *Filename)
-{
-       size_t  size;
-       FILE    *fp;
-       void    *data;
-       
-       size = AST_WriteScript(NULL, Script);
-       
-       fp = fopen(Filename, "wb");
-       if(!fp) return 1;
-
-       data = malloc(size);
-       if(!data) {
-               fclose(fp);
-               return -1;
-       }
-       
-       size = AST_WriteScript(data, Script);
-       fwrite(data, size, 1, fp);
-       free(data);
-
-       fclose(fp);
-       return 0;
-}
-
-/**
- * \brief Free a script
- */
-void SpiderScript_Free(tSpiderScript *Script)
-{
-       tScript_Function        *fcn = Script->Functions;
-       tScript_Function        *nextFcn;
-       
-       // Free functions
-       while(fcn)
-       {
-               if(fcn->ASTFcn) AST_FreeNode( fcn->ASTFcn );
-               if(fcn->BCFcn)  Bytecode_DeleteFunction( fcn->BCFcn );
-
-               nextFcn = fcn->Next;
-               free( fcn );
-               fcn = nextFcn;
-       }
-       
-       free(Script);
-}
diff --git a/Usermode/Libraries/libspiderscript.so_src/parse.c b/Usermode/Libraries/libspiderscript.so_src/parse.c
deleted file mode 100644 (file)
index 45eafb2..0000000
+++ /dev/null
@@ -1,1130 +0,0 @@
-/*
- * Acess2 - SpiderScript
- * - Parser
- */
-#include <string.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <stdarg.h>
-#include <spiderscript.h>
-#define WANT_TOKEN_STRINGS     1
-#include "tokens.h"
-#include "ast.h"
-#include "common.h"
-
-#define DEBUG  0
-#define        SUPPORT_BREAK_TAGS      1
-
-// === PROTOTYPES ===
- 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 *CodeNode);
-tAST_Node      *Parse_DoBlockLine(tParser *Parser, tAST_Node *CodeNode);
-tAST_Node      *Parse_VarDefList(tParser *Parser, tAST_Node *CodeNode, int Type);
-tAST_Node      *Parse_GetVarDef(tParser *Parser, int Type);
-
-tAST_Node      *Parse_DoExpr0(tParser *Parser);        // Assignment
-tAST_Node      *Parse_DoExpr1(tParser *Parser);        // Boolean Operators
-tAST_Node      *Parse_DoExpr2(tParser *Parser);        // Comparison Operators
-tAST_Node      *Parse_DoExpr3(tParser *Parser);        // Bitwise Operators
-tAST_Node      *Parse_DoExpr4(tParser *Parser);        // Bit Shifts
-tAST_Node      *Parse_DoExpr5(tParser *Parser);        // Arithmatic
-tAST_Node      *Parse_DoExpr6(tParser *Parser);        // Mult & Div
-tAST_Node      *Parse_DoExpr7(tParser *Parser);        // Right Unary Operations
-tAST_Node      *Parse_DoExpr8(tParser *Parser);        // Left Unary Operations
-
-tAST_Node      *Parse_DoParen(tParser *Parser);        // Parenthesis (Always Last)
-tAST_Node      *Parse_DoValue(tParser *Parser);        // Values
-
-tAST_Node      *Parse_GetString(tParser *Parser);
-tAST_Node      *Parse_GetNumeric(tParser *Parser);
-tAST_Node      *Parse_GetVariable(tParser *Parser);
-tAST_Node      *Parse_GetIdent(tParser *Parser, int bObjectCreate);
-
-void   SyntaxAssert(tParser *Parser, int Have, int Want);
-void   SyntaxError(tParser *Parser, int bFatal, const char *Message, ...);
-
-#if 0
-#define SyntaxAssert(_parser, _have, _want)    SyntaxAssertV(_parser, _have, _want, NULL)
-#define SyntaxAssertV(_parser, _have, _want, _rv) do { \
-       int have = (_have), want = (_want); \
-       if( (have) != (want) ) { \
-               SyntaxError(Parser, 1, "Unexpected %s(%i), expecting %s(%i)\n", \
-                       csaTOKEN_NAMES[have], have, csaTOKEN_NAMES[want], want); \
-               return _rv; \
-       } \
-}while(0)
-#endif
-
-#define TODO(Parser, message...) do {\
-       fprintf(stderr, "TODO: "message);\
-       longjmp(Parser->JmpTarget, -1);\
-}while(0)
-
-// === CODE ===
-/**
- * \brief Parse a buffer into a syntax tree
- */
-int Parse_Buffer(tSpiderScript *Script, const char *Buffer, const char *Filename)
-{
-       tParser parser = {0};
-       tParser *Parser = &parser;      //< Keeps code consistent
-       tAST_Node       *mainCode, *node;
-        int    type;
-       tScript_Function        *fcn;
-       
-       #if DEBUG >= 2
-       printf("Parse_Buffer: (Variant=%p, Buffer=%p)\n", Variant, Buffer);
-       #endif
-       
-       // Initialise parser
-       parser.LastToken = -1;
-       parser.NextToken = -1;
-       parser.CurLine = 1;
-       parser.BufStart = Buffer;
-       parser.CurPos = Buffer;
-       // hackery to do reference counting
-       parser.Filename = malloc(sizeof(int)+strlen(Filename)+1);
-       strcpy(parser.Filename + sizeof(int), Filename);
-       *(int*)(parser.Filename) = 0;   // Set reference count
-       parser.Filename += sizeof(int); // Move filename
-       parser.ErrorHit = 0;
-       parser.Variant = Script->Variant;
-       
-       mainCode = AST_NewCodeBlock(&parser);
-       
-       // Give us an error fallback
-       if( setjmp( parser.JmpTarget ) != 0 )
-       {
-               AST_FreeNode( mainCode );
-               
-               for(fcn = Script->Functions; fcn; )
-               {
-                       tScript_Function        *nextFcn;
-                       
-                       AST_FreeNode( fcn->ASTFcn );
-                       
-                       nextFcn = fcn->Next;
-                       free( fcn );
-                       fcn = nextFcn;
-               }
-               return -1;
-       }
-       
-       // Parse the file!
-       while(Parser->Token != TOK_EOF)
-       {
-               switch( GetToken(Parser) )
-               {
-               case TOK_EOF:
-                       break;
-               
-               // Typed variables/functions
-               case TOKEN_GROUP_TYPES:
-                       TOKEN_GET_DATATYPE(type, Parser->Token);
-                       
-                       switch(LookAhead(Parser))
-                       {
-                       // Define a function (pass on to the other function definition code)
-                       case TOK_IDENT:
-                               if( Parse_FunctionDefinition(Script, Parser, type) == NULL )
-                                       longjmp(Parser->JmpTarget, -1);
-                               break ;
-                       // Define a variable (pass back to _DoBlockLine)
-                       case TOK_VARIABLE:
-                               node = Parse_VarDefList(Parser, mainCode, type);
-                               AST_AppendNode(mainCode, node);
-                               SyntaxAssert(Parser, GetToken(Parser), TOK_SEMICOLON);
-                               break;
-                       default:
-                               SyntaxError(Parser, 1, "Unexpected %s, expected TOK_IDENT or TOK_VARIABLE\n",
-                                       csaTOKEN_NAMES[Parser->Token]);
-                               break;
-                       }
-                       break;
-               
-               // Define a function
-               case TOK_RWD_FUNCTION:
-                       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(Script, Parser, SS_DATATYPE_DYNAMIC) == NULL )
-                               longjmp(Parser->JmpTarget, -1);
-               
-                       break;
-               
-               // Ordinary Statement
-               default:
-                       PutBack(Parser);
-                       node = Parse_DoBlockLine(Parser, mainCode);
-                       if(!node)       longjmp(Parser->JmpTarget, -1);
-                       AST_AppendNode( mainCode, node );
-                       break;
-               }
-               
-               // Jump to error handler on error
-               if(Parser->ErrorHit)
-                       longjmp(Parser->JmpTarget, -1);
-       }
-       
-       AST_AppendFunction( Script, "", SS_DATATYPE_INTEGER, NULL, mainCode );
-       
-       //printf("---- %p parsed as SpiderScript ----\n", Buffer);
-       
-       return 0;
-}
-
-void *Parse_FunctionDefinition(tSpiderScript *Script, tParser *Parser, int Type)
-{
-       char    *name;
-        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 );
-       #if DEBUG
-       printf("DefFCN %s\n", name);
-       #endif
-       
-       // Get arguments
-       SyntaxAssert(Parser, GetToken(Parser), TOK_PAREN_OPEN );
-       if( LookAhead(Parser) != TOK_PAREN_CLOSE )
-       {
-               do {
-                        int    type = SS_DATATYPE_DYNAMIC;
-                       GetToken(Parser);
-                       // Non dynamic typed variants must use data types
-                       if( !Script->Variant->bDyamicTyped ) {
-                               TOKEN_GET_DATATYPE(type, Parser->Token);
-                               GetToken(Parser);
-                       }
-                       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, NULL);
-
-       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);
-       
-       return rv == 0 ? (void*)1 : NULL;
-}
-
-/**
- * \brief Parse a block of code surrounded by { }
- */
-tAST_Node *Parse_DoCodeBlock(tParser *Parser, tAST_Node *CodeNode)
-{
-       tAST_Node       *ret;
-       
-       // Check if we are being called for a one-liner
-       if( GetToken(Parser) != TOK_BRACE_OPEN ) {
-               PutBack(Parser);
-               return Parse_DoBlockLine(Parser, CodeNode);
-       }
-       
-       ret = AST_NewCodeBlock(Parser);
-       
-       while( LookAhead(Parser) != TOK_BRACE_CLOSE )
-       {
-               tAST_Node       *node = Parse_DoBlockLine(Parser, ret);
-               if(!node) {
-                       AST_FreeNode(ret);
-                       return NULL;
-               }
-               AST_AppendNode( ret, node );
-       }
-       GetToken(Parser);       // Omnomnom
-       return ret;
-}
-
-/**
- * \brief Parse a line in a block
- */
-tAST_Node *Parse_DoBlockLine(tParser *Parser, tAST_Node *CodeNode)
-{
-       tAST_Node       *ret;
-       
-       //printf("Parse_DoBlockLine: Line %i\n", Parser->CurLine);
-       
-       switch(LookAhead(Parser))
-       {
-       // New block
-       case TOK_BRACE_OPEN:
-               return Parse_DoCodeBlock(Parser, CodeNode);
-       
-       // Empty statement
-       case TOK_SEMICOLON:
-               GetToken(Parser);
-               return NULL;
-       
-       // Return from a method
-       case TOK_RWD_RETURN:
-               GetToken(Parser);
-               ret = AST_NewUniOp(Parser, NODETYPE_RETURN, Parse_DoExpr0(Parser));
-               break;
-       
-       // Break / Continue (end a loop / go to next iteration)
-       case TOK_RWD_CONTINUE:
-       case TOK_RWD_BREAK:
-               {
-                int    tok;
-               char    *ident = NULL;
-               tok = GetToken(Parser);
-               // Get the number of nesting levels to break
-               if(LookAhead(Parser) == TOK_IDENT)
-               {
-                       GetToken(Parser);
-                       ident = strndup(Parser->TokenStr, Parser->TokenLen);
-               }
-               // Get the action
-               switch(tok)
-               {
-               case TOK_RWD_BREAK:     ret = AST_NewBreakout(Parser, NODETYPE_BREAK, ident);   break;
-               case TOK_RWD_CONTINUE:  ret = AST_NewBreakout(Parser, NODETYPE_CONTINUE, ident);        break;
-               default:
-                       SyntaxError(Parser, 1, "BUG Unhandled break/continue (%s)",
-                               csaTOKEN_NAMES[tok]);
-                       return NULL;
-               }
-               if(ident)       free(ident);
-               }
-               break;
-       
-       // Control Statements
-       case TOK_RWD_IF:
-               {
-               tAST_Node       *cond, *true, *false = NULL;
-               GetToken(Parser);       // eat the if
-               
-               SyntaxAssert(Parser, GetToken(Parser), TOK_PAREN_OPEN);
-               cond = Parse_DoExpr0(Parser);   // Get condition
-               SyntaxAssert(Parser, GetToken(Parser), TOK_PAREN_CLOSE);
-               true = Parse_DoCodeBlock(Parser, CodeNode);
-               if( LookAhead(Parser) == TOK_RWD_ELSE ) {
-                       GetToken(Parser);
-                       false = Parse_DoCodeBlock(Parser, CodeNode);
-               }
-               else
-                       false = AST_NewNop(Parser);
-               ret = AST_NewIf(Parser, cond, true, false);
-               }
-               return ret;
-       
-       case TOK_RWD_FOR:
-               {
-               char    *tag = NULL;
-               tAST_Node       *init=NULL, *cond=NULL, *inc=NULL, *code;
-               GetToken(Parser);       // Eat 'for'
-               
-               #if SUPPORT_BREAK_TAGS
-               if(LookAhead(Parser) == TOK_LT)
-               {
-                       GetToken(Parser);
-                       SyntaxAssert(Parser, GetToken(Parser), TOK_IDENT);
-                       tag = strndup(Parser->TokenStr, Parser->TokenLen);
-                       SyntaxAssert(Parser, GetToken(Parser), TOK_GT);
-               }
-               #endif
-               
-               SyntaxAssert(Parser, GetToken(Parser), TOK_PAREN_OPEN);
-               
-               if(LookAhead(Parser) != TOK_SEMICOLON)
-                       init = Parse_DoExpr0(Parser);
-               
-               SyntaxAssert(Parser, GetToken(Parser), TOK_SEMICOLON);
-               
-               if(LookAhead(Parser) != TOK_SEMICOLON)
-                       cond = Parse_DoExpr0(Parser);
-               
-               SyntaxAssert(Parser, GetToken(Parser), TOK_SEMICOLON);
-               
-               if(LookAhead(Parser) != TOK_PAREN_CLOSE)
-                       inc = Parse_DoExpr0(Parser);
-               
-               SyntaxAssert(Parser, GetToken(Parser), TOK_PAREN_CLOSE);
-               
-               code = Parse_DoCodeBlock(Parser, CodeNode);
-               ret = AST_NewLoop(Parser, tag, init, 0, cond, inc, code);
-               if(tag) free(tag);
-               }
-               return ret;
-       
-       case TOK_RWD_DO:
-               {
-               const char      *tag = "";
-               tAST_Node       *code, *cond;
-               GetToken(Parser);       // Eat 'do'
-               
-               #if SUPPORT_BREAK_TAGS
-               if(LookAhead(Parser) == TOK_LT)
-               {
-                       GetToken(Parser);
-                       SyntaxAssert(Parser, GetToken(Parser), TOK_IDENT);
-                       tag = strndup(Parser->TokenStr, Parser->TokenLen);
-                       SyntaxAssert(Parser, GetToken(Parser), TOK_GT);
-               }
-               #endif
-               
-               code = Parse_DoCodeBlock(Parser, CodeNode);
-               SyntaxAssert( Parser, GetToken(Parser), TOK_RWD_WHILE );
-               SyntaxAssert( Parser, GetToken(Parser), TOK_PAREN_OPEN );
-               cond = Parse_DoExpr0(Parser);
-               SyntaxAssert( Parser, GetToken(Parser), TOK_PAREN_CLOSE );
-               ret = AST_NewLoop(Parser, tag, AST_NewNop(Parser), 1, cond, AST_NewNop(Parser), code);
-               }
-               break;
-       case TOK_RWD_WHILE:
-               {
-               const char      *tag = "";
-               tAST_Node       *code, *cond;
-               GetToken(Parser);       // Eat 'while'
-               
-               #if SUPPORT_BREAK_TAGS
-               if(LookAhead(Parser) == TOK_LT)
-               {
-                       GetToken(Parser);
-                       SyntaxAssert(Parser, GetToken(Parser), TOK_IDENT);
-                       tag = strndup(Parser->TokenStr, Parser->TokenLen);
-                       SyntaxAssert(Parser, GetToken(Parser), TOK_GT);
-               }
-               #endif
-               
-               SyntaxAssert( Parser, GetToken(Parser), TOK_PAREN_OPEN );
-               cond = Parse_DoExpr0(Parser);
-               SyntaxAssert( Parser, GetToken(Parser), TOK_PAREN_CLOSE );
-               code = Parse_DoCodeBlock(Parser, CodeNode);
-               ret = AST_NewLoop(Parser, tag, AST_NewNop(Parser), 0, cond, AST_NewNop(Parser), code);
-               }
-               return ret;
-       
-       // Define Variables
-       case TOKEN_GROUP_TYPES:
-               {
-                        int    type;
-                       GetToken(Parser);
-                       TOKEN_GET_DATATYPE(type, Parser->Token);
-                       ret = Parse_VarDefList(Parser, CodeNode, type);
-               }
-               break;
-       
-       // Default
-       default:
-               //printf("exp0\n");
-               ret = Parse_DoExpr0(Parser);
-               break;
-       }
-       
-       SyntaxAssert(Parser, GetToken(Parser), TOK_SEMICOLON );
-       return ret;
-}
-
-tAST_Node *Parse_VarDefList(tParser *Parser, tAST_Node *CodeNode, int Type)
-{
-       tAST_Node       *ret;
-       
-       ret = NULL;             
-       do {
-               if(ret) AST_AppendNode( CodeNode, ret );
-               SyntaxAssert(Parser, GetToken(Parser), TOK_VARIABLE);
-               
-               ret = Parse_GetVarDef(Parser, Type);
-               if(!ret)        longjmp(Parser->JmpTarget, -1);
-       } while(GetToken(Parser) == TOK_COMMA);
-       PutBack(Parser);        // Semicolon is checked by caller
-       
-       return ret;
-}
-
-/**
- * \brief Get a variable definition
- */
-tAST_Node *Parse_GetVarDef(tParser *Parser, int Type)
-{
-       char    name[Parser->TokenLen];
-       tAST_Node       *ret;
-        int    level;
-       
-       SyntaxAssert(Parser, Parser->Token, TOK_VARIABLE);
-       
-       // copy the name (trimming the $)
-       memcpy(name, Parser->TokenStr+1, Parser->TokenLen-1);
-       name[Parser->TokenLen-1] = 0;
-       
-       // Define the variable
-       ret = AST_NewDefineVar(Parser, Type, name);
-       // Handle arrays
-       level = 0;
-       if( LookAhead(Parser) == TOK_SQUARE_OPEN )
-       {
-               GetToken(Parser);
-               if( LookAhead(Parser) != TOK_SQUARE_CLOSE )
-               {
-                       ret->DefVar.InitialValue = AST_NewFunctionCall(Parser, "array");
-                       AST_AppendFunctionCallArg(ret->DefVar.InitialValue, Parse_DoExpr0(Parser));
-               }
-               SyntaxAssert(Parser, GetToken(Parser), TOK_SQUARE_CLOSE);
-       
-               level ++;
-       }
-       while( LookAhead(Parser) == TOK_SQUARE_OPEN )
-       {
-               GetToken(Parser);
-               SyntaxAssert(Parser, GetToken(Parser), TOK_SQUARE_CLOSE);
-               level ++;
-       }
-       
-       // Maul the type to denote the dereference level
-       if( Parser->Variant->bDyamicTyped ) {
-               ret->DefVar.DataType = SS_DATATYPE_ARRAY;
-       }
-       else {
-               ret->DefVar.DataType |= (level << 16);
-       }
-
-       // Initial value
-       if( LookAhead(Parser) == TOK_ASSIGN )
-       {
-               if( ret->DefVar.InitialValue )
-               {
-                       SyntaxError(Parser, 1, "Cannot assign and set array size at the same time");
-               }
-               GetToken(Parser);
-               ret->DefVar.InitialValue = Parse_DoExpr0(Parser);
-               if(!ret->DefVar.InitialValue) {
-                       AST_FreeNode(ret);
-                       return NULL;
-               }
-       }
-       else if( ret->DefVar.InitialValue )
-       {
-               AST_AppendFunctionCallArg(ret->DefVar.InitialValue, AST_NewInteger(Parser, ret->DefVar.DataType));
-       }
-       
-       return ret;
-}
-
-/**
- * \brief Assignment Operations
- */
-tAST_Node *Parse_DoExpr0(tParser *Parser)
-{
-       #define _next   Parse_DoExpr1
-       tAST_Node       *ret = _next(Parser);
-        int    cont = 1;
-
-       while( cont )
-       {
-               // Check Assignment
-               switch(GetToken(Parser))
-               {
-               case TOK_ASSIGN:
-                       ret = AST_NewAssign(Parser, NODETYPE_NOP, ret, _next(Parser));
-                       break;
-               case TOK_ASSIGN_DIV:
-                       ret = AST_NewAssign(Parser, NODETYPE_DIVIDE, ret, _next(Parser));
-                       break;
-               case TOK_ASSIGN_MUL:
-                       ret = AST_NewAssign(Parser, NODETYPE_MULTIPLY, ret, _next(Parser));
-                       break;
-               case TOK_ASSIGN_PLUS:
-                       ret = AST_NewAssign(Parser, NODETYPE_ADD, ret, _next(Parser));
-                       break;
-               case TOK_ASSIGN_MINUS:
-                       ret = AST_NewAssign(Parser, NODETYPE_SUBTRACT, ret, _next(Parser));
-                       break;
-               default:
-                       #if DEBUG >= 2
-                       printf("Parse_DoExpr0: Parser->Token = %i\n", Parser->Token);
-                       #endif
-                       PutBack(Parser);
-                       cont = 0;
-                       break;
-               }
-       }
-       return ret;
-       #undef _next
-}
-
-/**
- * \brief Logical/Boolean Operators
- */
-tAST_Node *Parse_DoExpr1(tParser *Parser)
-{
-       #define _next   Parse_DoExpr2
-       tAST_Node       *ret = _next(Parser);
-        int    cont = 1;
-
-       while( cont )
-       {
-               switch(GetToken(Parser))
-               {
-               case TOK_LOGICAND:
-                       ret = AST_NewBinOp(Parser, NODETYPE_LOGICALAND, ret, _next(Parser));
-                       break;
-               case TOK_LOGICOR:
-                       ret = AST_NewBinOp(Parser, NODETYPE_LOGICALOR, ret, _next(Parser));
-                       break;
-               case TOK_LOGICXOR:
-                       ret = AST_NewBinOp(Parser, NODETYPE_LOGICALXOR, ret, _next(Parser));
-                       break;
-               default:
-                       PutBack(Parser);
-                       cont = 0;
-                       break;
-               }
-       }
-       return ret;
-       #undef _next
-}
-
-// --------------------
-// Expression 2 - Comparison Operators
-// --------------------
-tAST_Node *Parse_DoExpr2(tParser *Parser)
-{
-       #define _next   Parse_DoExpr3
-       tAST_Node       *ret = _next(Parser);
-        int    cont = 1;
-
-       while( cont )
-       {
-               // Check token
-               switch(GetToken(Parser))
-               {
-               case TOK_EQUALS:
-                       ret = AST_NewBinOp(Parser, NODETYPE_EQUALS, ret, _next(Parser));
-                       break;
-               case TOK_NOTEQUALS:
-                       ret = AST_NewBinOp(Parser, NODETYPE_NOTEQUALS, ret, _next(Parser));
-                       break;
-               case TOK_LT:
-                       ret = AST_NewBinOp(Parser, NODETYPE_LESSTHAN, ret, _next(Parser));
-                       break;
-               case TOK_GT:
-                       ret = AST_NewBinOp(Parser, NODETYPE_GREATERTHAN, ret, _next(Parser));
-                       break;
-               case TOK_LTE:
-                       ret = AST_NewBinOp(Parser, NODETYPE_LESSTHANEQUAL, ret, _next(Parser));
-                       break;
-               case TOK_GTE:
-                       ret = AST_NewBinOp(Parser, NODETYPE_GREATERTHANEQUAL, ret, _next(Parser));
-                       break;
-               default:
-                       PutBack(Parser);
-                       cont = 0;
-                       break;
-               }
-       }
-       return ret;
-       #undef _next
-}
-
-/**
- * \brief Bitwise Operations
- */
-tAST_Node *Parse_DoExpr3(tParser *Parser)
-{
-       #define _next   Parse_DoExpr4
-       tAST_Node       *ret = _next(Parser);
-        int    cont = 1;
-
-       while( cont )
-       {
-               // Check Token
-               switch(GetToken(Parser))
-               {
-               case TOK_OR:
-                       ret = AST_NewBinOp(Parser, NODETYPE_BWOR, ret, _next(Parser));
-                       break;
-               case TOK_AND:
-                       ret = AST_NewBinOp(Parser, NODETYPE_BWAND, ret, _next(Parser));
-                       break;
-               case TOK_XOR:
-                       ret = AST_NewBinOp(Parser, NODETYPE_BWXOR, ret, _next(Parser));
-                       break;
-               default:
-                       PutBack(Parser);
-                       cont = 0;
-                       break;
-               }
-       }
-       return ret;
-       #undef _next
-}
-
-// --------------------
-// Expression 4 - Shifts
-// --------------------
-tAST_Node *Parse_DoExpr4(tParser *Parser)
-{
-       #define _next   Parse_DoExpr5
-       tAST_Node *ret = _next(Parser);
-        int    cont = 1;
-
-       while( cont )
-       {
-               switch(GetToken(Parser))
-               {
-               case TOK_SHL:
-                       ret = AST_NewBinOp(Parser, NODETYPE_BITSHIFTLEFT, ret, _next(Parser));
-                       break;
-               case TOK_SHR:
-                       ret = AST_NewBinOp(Parser, NODETYPE_BITSHIFTRIGHT, ret, _next(Parser));
-                       break;
-               default:
-                       PutBack(Parser);
-                       cont = 0;
-                       break;
-               }
-       }
-
-       return ret;
-       #undef _next
-}
-
-// --------------------
-// Expression 5 - Arithmatic
-// --------------------
-tAST_Node *Parse_DoExpr5(tParser *Parser)
-{
-       #define _next   Parse_DoExpr6
-       tAST_Node *ret = _next(Parser);
-        int    cont = 1;
-       
-       // While loop is added to ensure that the evaluation order ends up as
-       // right to left.
-       // E.g. a + b + c + d ends up as (((a + b) + c) + d) for casting
-       while( cont )
-       {
-               switch(GetToken(Parser))
-               {
-               case TOK_PLUS:
-                       ret = AST_NewBinOp(Parser, NODETYPE_ADD, ret, _next(Parser));
-                       break;
-               case TOK_MINUS:
-                       ret = AST_NewBinOp(Parser, NODETYPE_SUBTRACT, ret, _next(Parser));
-                       break;
-               default:
-                       PutBack(Parser);
-                       cont = 0;
-                       break;
-               }
-       }
-
-       return ret;
-       #undef _next
-}
-
-// --------------------
-// Expression 6 - Multiplcation & Division
-// --------------------
-tAST_Node *Parse_DoExpr6(tParser *Parser)
-{
-       #define _next   Parse_DoExpr7
-       tAST_Node *ret = _next(Parser);
-        int    cont = 1;
-
-       while( cont )
-       {
-               switch(GetToken(Parser))
-               {
-               case TOK_MUL:
-                       ret = AST_NewBinOp(Parser, NODETYPE_MULTIPLY, ret, _next(Parser));
-                       break;
-               case TOK_DIV:
-                       ret = AST_NewBinOp(Parser, NODETYPE_DIVIDE, ret, _next(Parser));
-                       break;
-               default:
-                       PutBack(Parser);
-                       cont = 0;
-                       break;
-               }
-       }
-
-       return ret;
-       #undef _next
-}
-
-// --------------------
-// Expression 7 - Right Unary Operations
-// --------------------
-tAST_Node *Parse_DoExpr7(tParser *Parser)
-{
-       tAST_Node *ret = Parse_DoExpr8(Parser);
-       
-       switch(GetToken(Parser))
-       {
-       case TOK_INCREMENT:
-               ret = AST_NewUniOp(Parser, NODETYPE_POSTINC, ret);
-               break;
-       case TOK_DECREMENT:
-               ret = AST_NewUniOp(Parser, NODETYPE_POSTDEC, ret);
-               break;
-       default:
-               PutBack(Parser);
-               break;
-       }
-       return ret;
-}
-
-// --------------------
-// Expression 8 - Left Unary Operations
-// --------------------
-tAST_Node *Parse_DoExpr8(tParser *Parser)
-{
-       switch(GetToken(Parser))
-       {
-       case TOK_INCREMENT:
-               return AST_NewAssign(Parser, NODETYPE_ADD, Parse_DoExpr8(Parser), AST_NewInteger(Parser, 1));
-       case TOK_DECREMENT:
-               return AST_NewAssign(Parser, NODETYPE_SUBTRACT, Parse_DoExpr8(Parser), AST_NewInteger(Parser, 1));
-       case TOK_MINUS:
-               return AST_NewUniOp(Parser, NODETYPE_NEGATE, Parse_DoExpr8(Parser));
-       case TOK_LOGICNOT:
-               return AST_NewUniOp(Parser, NODETYPE_LOGICALNOT, Parse_DoExpr8(Parser));
-       case TOK_BWNOT:
-               return AST_NewUniOp(Parser, NODETYPE_BWNOT, Parse_DoExpr8(Parser));
-       default:
-               PutBack(Parser);
-               return Parse_DoParen(Parser);
-       }
-}
-
-// --------------------
-// 2nd Last Expression - Parens
-// --------------------
-tAST_Node *Parse_DoParen(tParser *Parser)
-{
-       #if DEBUG >= 2
-       printf("Parse_DoParen: (Parser=%p)\n", Parser);
-       #endif
-       if(LookAhead(Parser) == TOK_PAREN_OPEN)
-       {
-               tAST_Node       *ret;
-                int    type;
-               GetToken(Parser);
-               
-               // TODO: Handle casts here
-               switch(LookAhead(Parser))
-               {
-               case TOKEN_GROUP_TYPES:
-                       GetToken(Parser);
-                       TOKEN_GET_DATATYPE(type, Parser->Token);
-                       SyntaxAssert(Parser, GetToken(Parser), TOK_PAREN_CLOSE);
-                       ret = AST_NewCast(Parser, type, Parse_DoParen(Parser));
-                       break;
-               default:                
-                       ret = Parse_DoExpr0(Parser);
-                       SyntaxAssert(Parser, GetToken(Parser), TOK_PAREN_CLOSE);
-                       break;
-               }
-               return ret;
-       }
-       else
-               return Parse_DoValue(Parser);
-}
-
-// --------------------
-// Last Expression - Value
-// --------------------
-tAST_Node *Parse_DoValue(tParser *Parser)
-{
-        int    tok = LookAhead(Parser);
-
-       #if DEBUG >= 2
-       printf("Parse_DoValue: tok = %i\n", tok);
-       #endif
-
-       switch(tok)
-       {
-       case TOK_STR:
-               return Parse_GetString(Parser);
-       case TOK_INTEGER:
-               return Parse_GetNumeric(Parser);
-       
-       case TOK_REAL:
-               GetToken(Parser);
-               return AST_NewReal( Parser, atof(Parser->TokenStr) );
-       
-       case TOK_IDENT:
-               return Parse_GetIdent(Parser, 0);
-       case TOK_VARIABLE:
-               return Parse_GetVariable(Parser);
-       case TOK_RWD_NULL:
-               GetToken(Parser);
-               return AST_NewNull(Parser);     // nODETYPE_NOP returns NULL
-       case TOK_RWD_NEW:
-               GetToken(Parser);
-               return Parse_GetIdent(Parser, 1);
-
-       default:
-               fprintf(stderr, "Syntax Error: Unexpected %s on line %i, Expected TOK_T_VALUE\n",
-                       csaTOKEN_NAMES[tok], Parser->CurLine);
-               longjmp( Parser->JmpTarget, -1 );
-       }
-}
-
-/**
- * \brief Get a string
- */
-tAST_Node *Parse_GetString(tParser *Parser)
-{
-       tAST_Node       *ret;
-        int    i, j;
-       GetToken( Parser );
-       
-       {
-               char    data[ Parser->TokenLen - 2 ];
-               j = 0;
-               
-               for( i = 1; i < Parser->TokenLen - 1; i++ )
-               {
-                       if( Parser->TokenStr[i] == '\\' ) {
-                               i ++;
-                               switch( Parser->TokenStr[i] )
-                               {
-                               case 'n':       data[j++] = '\n';       break;
-                               case 'r':       data[j++] = '\r';       break;
-                               default:
-                                       // TODO: Octal Codes
-                                       // TODO: Error/Warning?
-                                       break;
-                               }
-                       }
-                       else {
-                               data[j++] = Parser->TokenStr[i];
-                       }
-               }
-               
-               // TODO: Parse Escape Codes
-               ret = AST_NewString( Parser, data, j );
-       }
-       return ret;
-}
-
-/**
- * \brief Get a numeric value
- */
-tAST_Node *Parse_GetNumeric(tParser *Parser)
-{
-       uint64_t        value = 0;
-       const char      *pos;
-       SyntaxAssert( Parser, GetToken( Parser ), TOK_INTEGER );
-       pos = Parser->TokenStr;
-       //printf("pos = %p, *pos = %c\n", pos, *pos);
-               
-       if( *pos == '0' )
-       {
-               pos ++;
-               if(*pos == 'x') {
-                       pos ++;
-                       for( ;; pos++)
-                       {
-                               value *= 16;
-                               if( '0' <= *pos && *pos <= '9' ) {
-                                       value += *pos - '0';
-                                       continue;
-                               }
-                               if( 'A' <= *pos && *pos <= 'F' ) {
-                                       value += *pos - 'A' + 10;
-                                       continue;
-                               }
-                               if( 'a' <= *pos && *pos <= 'f' ) {
-                                       value += *pos - 'a' + 10;
-                                       continue;
-                               }
-                               break;
-                       }
-               }
-               else {
-                       while( '0' <= *pos && *pos <= '7' ) {
-                               value = value*8 + *pos - '0';
-                               pos ++;
-                       }
-               }
-       }
-       else {
-               while( '0' <= *pos && *pos <= '9' ) {
-                       value = value*10 + *pos - '0';
-                       pos ++;
-               }
-       }
-       
-       return AST_NewInteger( Parser, value );
-}
-
-/**
- * \brief Get a variable
- */
-tAST_Node *Parse_GetVariable(tParser *Parser)
-{
-       tAST_Node       *ret;
-       SyntaxAssert( Parser, GetToken(Parser), TOK_VARIABLE );
-       {
-               char    name[Parser->TokenLen];
-               memcpy(name, Parser->TokenStr+1, Parser->TokenLen-1);
-               name[Parser->TokenLen-1] = 0;
-               ret = AST_NewVariable( Parser, name );
-               #if DEBUG >= 2
-               printf("Parse_GetVariable: name = '%s'\n", name);
-               #endif
-       }
-       for(;;)
-       {
-               GetToken(Parser);
-               if( Parser->Token == TOK_SQUARE_OPEN )
-               {
-                       ret = AST_NewBinOp(Parser, NODETYPE_INDEX, ret, Parse_DoExpr0(Parser));
-                       SyntaxAssert(Parser, GetToken(Parser), TOK_SQUARE_CLOSE);
-                       continue ;
-               }
-               if( Parser->Token == TOK_ELEMENT )
-               {
-                       SyntaxAssert(Parser, GetToken(Parser), TOK_IDENT);
-                       // Method Call
-                       if( LookAhead(Parser) == TOK_PAREN_OPEN )
-                       {
-                               char    name[Parser->TokenLen+1];
-                               memcpy(name, Parser->TokenStr, Parser->TokenLen);
-                               name[Parser->TokenLen] = 0;
-                               ret = AST_NewMethodCall(Parser, ret, name);
-                               GetToken(Parser);       // Eat the '('
-                               // Read arguments
-                               if( GetToken(Parser) != TOK_PAREN_CLOSE )
-                               {
-                                       PutBack(Parser);
-                                       do {
-                                               AST_AppendFunctionCallArg( ret, Parse_DoExpr0(Parser) );
-                                       } while(GetToken(Parser) == TOK_COMMA);
-                                       SyntaxAssert( Parser, Parser->Token, TOK_PAREN_CLOSE );
-                               }
-                               
-                       }
-                       // Attribute
-                       else
-                       {
-                               char    name[Parser->TokenLen];
-                               memcpy(name, Parser->TokenStr+1, Parser->TokenLen-1);
-                               name[Parser->TokenLen-1] = 0;
-                               ret = AST_NewClassElement(Parser, ret, name);
-                       }
-                       continue ;
-               }
-               
-               break ;
-       }
-       PutBack(Parser);
-       return ret;
-}
-
-/**
- * \brief Get an identifier (constant or function call)
- */
-tAST_Node *Parse_GetIdent(tParser *Parser, int bObjectCreate)
-{
-       tAST_Node       *ret = NULL;
-       char    *name;
-       SyntaxAssert(Parser, GetToken(Parser), TOK_IDENT );
-       name = strndup( Parser->TokenStr, Parser->TokenLen );
-       
-       #if USE_SCOPE_CHAR
-       if( GetToken(Parser) == TOK_SCOPE )
-       {
-               ret = AST_NewScopeDereference( Parser, name, Parse_GetIdent(Parser, bObjectCreate) );
-               free(name);
-               return ret;
-       }
-       PutBack(Parser);
-       #endif
-       
-       if( GetToken(Parser) == TOK_PAREN_OPEN )
-       {
-               #if DEBUG >= 2
-               printf("Parse_GetIdent: Calling '%s'\n", name);
-               #endif
-               // Function Call
-               if( bObjectCreate )
-                       ret = AST_NewCreateObject( Parser, name );
-               else
-                       ret = AST_NewFunctionCall( Parser, name );
-               // Read arguments
-               if( GetToken(Parser) != TOK_PAREN_CLOSE )
-               {
-                       PutBack(Parser);
-                       do {
-                               #if DEBUG >= 2
-                               printf(" Parse_GetIdent: Argument\n");
-                               #endif
-                               AST_AppendFunctionCallArg( ret, Parse_DoExpr0(Parser) );
-                       } while(GetToken(Parser) == TOK_COMMA);
-                       SyntaxAssert( Parser, Parser->Token, TOK_PAREN_CLOSE );
-                       #if DEBUG >= 2
-                       printf(" Parse_GetIdent: All arguments parsed\n");
-                       #endif
-               }
-       }
-       else
-       {
-               // Runtime Constant / Variable (When implemented)
-               #if DEBUG >= 2
-               printf("Parse_GetIdent: Referencing '%s'\n", name);
-               #endif
-               PutBack(Parser);
-               if( bObjectCreate )     // Void constructor (TODO: Should this be an error?)
-                       ret = AST_NewCreateObject( Parser, name );
-               else
-                       ret = AST_NewConstant( Parser, name );
-       }
-       
-       free(name);
-       return ret;
-}
-
-
-void SyntaxError(tParser *Parser, int bFatal, const char *Message, ...)
-{
-       va_list args;
-       va_start(args, Message);
-       fprintf(stderr, "%s:%i: error: ", Parser->Filename, Parser->CurLine);
-       vfprintf(stderr, Message, args);
-       fprintf(stderr, "\n");
-       va_end(args);
-       
-       if( bFatal ) {
-               //longjmp(Parser->JmpTarget, -1);
-               Parser->ErrorHit = 1;
-       }
-}
-
-void SyntaxAssert(tParser *Parser, int Have, int Want)
-{
-       if( Have != Want )
-       {
-               SyntaxError(Parser, 1, "Unexpected %s(%i), expecting %s(%i)\n",
-                       csaTOKEN_NAMES[Have], Have, csaTOKEN_NAMES[Want], Want);
-       }
-}
diff --git a/Usermode/Libraries/libspiderscript.so_src/spiderscript.h b/Usermode/Libraries/libspiderscript.so_src/spiderscript.h
deleted file mode 100644 (file)
index 3d58a8c..0000000
+++ /dev/null
@@ -1,347 +0,0 @@
-/*
- * 
- */
-#ifndef _SPIDERSCRIPT_H_
-#define _SPIDERSCRIPT_H_
-
-#include <stdint.h>
-
-#define ERRPTR ((void*)((intptr_t)0-1))
-
-/**
- * \brief Opaque script handle
- */
-typedef struct sSpiderScript   tSpiderScript;
-
-typedef struct sSpiderVariant  tSpiderVariant;
-typedef struct sSpiderNamespace        tSpiderNamespace;
-typedef struct sSpiderFunction tSpiderFunction;
-typedef struct sSpiderValue    tSpiderValue;
-typedef struct sSpiderObjectDef        tSpiderObjectDef;
-typedef struct sSpiderObject   tSpiderObject;
-
-
-/**
- * \brief SpiderScript Variable Datatypes
- * \todo Expand the descriptions
- */
-enum eSpiderScript_DataTypes
-{
-       /**
-        * \brief Undefined data
-        * \note Default type of an undefined dynamic variable
-        */
-       SS_DATATYPE_UNDEF,
-       /**
-        * \brief Dynamically typed variable
-        * \note Used to dentote a non-fixed type for function parameters
-        */
-       SS_DATATYPE_DYNAMIC,
-       /**
-        * \brief Opaque Data Pointer
-        * 
-        * Opaque data types are used for resource handles or for system buffers.
-        */
-       SS_DATATYPE_OPAQUE,
-       /**
-        * \brief Object reference
-        * 
-        * A reference to a SpiderScript class instance. Can be accessed
-        * using the -> operator.
-        */
-       SS_DATATYPE_OBJECT,
-       /**
-        * \brief Array data type (invalid when using static typing)
-        */
-       SS_DATATYPE_ARRAY,
-       /**
-        * \brief Integer datatype
-        * 
-        * 64-bit integer
-        */
-       SS_DATATYPE_INTEGER,
-       SS_DATATYPE_REAL,       //!< Real Number (double)
-       SS_DATATYPE_STRING,     //!< String
-       NUM_SS_DATATYPES
-};
-
-#define SS_MAKEARRAY(_type)    ((_type) + 0x10000)
-#define SS_DOWNARRAY(_type)    ((_type) - 0x10000)
-#define SS_GETARRAYDEPTH(_type)        ((_type) >> 16)
-
-enum eSpiderValueOps
-{
-       SS_VALUEOP_NOP,
-
-       SS_VALUEOP_ADD,
-       SS_VALUEOP_SUBTRACT,
-       SS_VALUEOP_NEGATE,
-       SS_VALUEOP_MULIPLY,
-       SS_VALUEOP_DIVIDE,
-       SS_VALUEOP_MODULO,
-
-       SS_VALUEOP_BITNOT,
-       SS_VALUEOP_BITAND,
-       SS_VALUEOP_BITOR,
-       SS_VALUEOP_BITXOR,
-
-       SS_VALUEOP_SHIFTLEFT,
-       SS_VALUEOP_SHIFTRIGHT,
-       SS_VALUEOP_ROTATELEFT
-};
-
-/**
- * \brief Namespace definition
- */
-struct sSpiderNamespace
-{
-       tSpiderNamespace        *Next;
-       
-       tSpiderNamespace        *FirstChild;
-       
-       tSpiderFunction *Functions;
-       
-       tSpiderObjectDef        *Classes;
-       
-        int    NConstants;     //!< Number of constants
-       tSpiderValue    *Constants;     //!< Number of constants
-       
-       const char      Name[];
-};
-
-/**
- * \brief Variant of SpiderScript
- */
-struct sSpiderVariant
-{
-       const char      *Name;  // Just for debug
-       
-        int    bDyamicTyped;   //!< Use dynamic typing
-        int    bImplicitCasts; //!< Allow implicit casts (casts to lefthand side)
-       
-       tSpiderFunction *Functions;     //!< Functions (Linked List)
-       
-        int    NConstants;     //!< Number of constants
-       tSpiderValue    *Constants;     //!< Number of constants
-       
-       tSpiderNamespace        RootNamespace;
-};
-
-/**
- * \brief SpiderScript data object
- */
-struct sSpiderValue
-{
-       enum eSpiderScript_DataTypes    Type;   //!< Variable type
-        int    ReferenceCount; //!< Reference count
-       
-       union {
-               int64_t Integer;        //!< Integer data
-               double  Real;   //!< Real Number data
-               /**
-                * \brief String data
-                */
-               struct {
-                        int    Length; //!< Length
-                       char    Data[]; //!< Actual string (\a Length bytes)
-               }       String;
-               /**
-                * \brief Variable data
-                */
-               struct {
-                        int    Length; //!< Length of the array
-                       tSpiderValue    *Items[];       //!< Array elements (\a Length long)
-               }       Array;
-               
-               /**
-                * \brief Opaque data
-                */
-               struct {
-                       void    *Data;  //!< Data (can be anywhere)
-                       void    (*Destroy)(void *Data); //!< Called on GC
-               }       Opaque;
-               
-               /**
-                * \brief Object Instance
-                */
-               tSpiderObject   *Object;
-       };
-};
-
-/**
- * \brief Object Definition
- * 
- * Internal representation of an arbitary object.
- */
-struct sSpiderObjectDef
-{
-       /**
-        */
-       struct sSpiderObjectDef *Next;  //!< Internal linked list
-       /**
-        * \brief Object type name
-        */
-       const char * const      Name;
-       /**
-        * \brief Construct an instance of the object
-        * \param NArgs Number of arguments
-        * \param Args  Argument array
-        * \return Pointer to an object instance (which must be fully valid)
-        * \retval NULL Invalid parameter (usually, actually just a NULL value)
-        * \retval ERRPTR       Invalid parameter count
-        */
-       tSpiderObject   *(*Constructor)(int NArgs, tSpiderValue **Args);
-       
-       /**
-        * \brief Clean up and destroy the object
-        * \param This  Object instace
-        * \note The object pointer (\a This) should be invalidated and freed
-        *       by this function.
-        */
-       void    (*Destructor)(tSpiderObject *This);
-
-
-       /**
-        * \brief Get/Set an attribute's value
-        */
-       tSpiderValue    *(*GetSetAttribute)(tSpiderObject *This, int AttibuteID, tSpiderValue *NewValue);
-       
-       /**
-        * \brief Method Definitions (linked list)
-        */
-       tSpiderFunction *Methods;
-       
-       /**
-        * \brief Number of attributes
-        */
-        int    NAttributes;
-       
-       //! Attribute definitions
-       struct {
-               const char      *Name;  //!< Attribute Name
-                int    Type;   //!< Datatype
-               char    bReadOnly;      //!< Allow writes to the attribute?
-               char    bMethod;        //!< IO Goes via GetSetAttribute function
-       }       AttributeDefs[];
-};
-
-/**
- * \brief Object Instance
- */
-struct sSpiderObject
-{
-       tSpiderObjectDef        *Type;  //!< Object Type
-        int    ReferenceCount; //!< Number of references
-       void    *OpaqueData;    //!< Pointer to the end of the \a Attributes array
-       tSpiderValue    *Attributes[];  //!< Attribute Array
-};
-
-/**
- * \brief Represents a function avaliable to a script
- */
-struct sSpiderFunction
-{
-       /**
-        * \brief Next function in list
-        */
-       struct sSpiderFunction  *Next;
-       
-       /**
-        * \brief Function name
-        */
-       const char      *Name;
-       /**
-        * \brief Function handler
-        */
-       tSpiderValue    *(*Handler)(tSpiderScript *Script, int nParams, tSpiderValue **Parameters);
-
-       /**
-        * \brief What type is returned
-        */
-        int    ReturnType;     
-
-       /**
-        * \brief Argument types
-        * 
-        * Zero or -1 terminated array of \a eSpiderScript_DataTypes.
-        * If the final entry is zero, the function has a fixed number of
-        * parameters, if the final entry is -1, the function has a variable
-        * number of arguments.
-        */
-        int    ArgTypes[];     // Zero (or -1) terminated array of parameter types
-};
-
-
-// === FUNCTIONS ===
-/**
- * \brief Parse a file into a script
- * \param Variant      Variant structure
- * \param Filename     File to parse
- * \return Script suitable for execution
- */
-extern tSpiderScript   *SpiderScript_ParseFile(tSpiderVariant *Variant, const char *Filename);
-/**
- * \brief Execute a function from a script
- * \param Script       Script to run
- * \param Function     Name of function to run ("" for the 'main')
- * \return Return value
- */
-extern tSpiderValue    *SpiderScript_ExecuteFunction(tSpiderScript *Script,
-       const char *Function, const char *DefaultNamespaces[],
-       int NArguments, tSpiderValue **Arguments,
-       void **FunctionIdent
-       );
-/**
- * \brief Execute an object method
- */
-extern tSpiderValue    *SpiderScript_ExecuteMethod(tSpiderScript *Script,
-       tSpiderObject *Object, const char *MethodName,
-       int NArguments, tSpiderValue **Arguments
-       );
-/**
- * \brief Creates an object instance
- */
-extern tSpiderValue    *SpiderScript_CreateObject(tSpiderScript *Script,
-       const char *ClassName, const char *DefaultNamespaces[],
-       int NArguments, tSpiderValue **Arguments
-       );
-
-/**
- * \brief Convert a script to bytecode and save to a file
- */
-extern int     SpiderScript_SaveBytecode(tSpiderScript *Script, const char *DestFile);
-/**
- * \brief Save the AST of a script to a file
- */
-extern int     SpiderScript_SaveAST(tSpiderScript *Script, const char *Filename);
-
-/**
- * \brief Free a script
- * \param Script       Script structure to free
- */
-extern void    SpiderScript_Free(tSpiderScript *Script);
-
-extern tSpiderObject   *SpiderScript_AllocateObject(tSpiderObjectDef *Class, int ExtraBytes);
-
-/**
- * \name tSpiderValue Manipulation functions
- * \{
- */
-extern void    SpiderScript_DereferenceValue(tSpiderValue *Object);
-extern void    SpiderScript_ReferenceValue(tSpiderValue *Object);
-extern tSpiderValue    *SpiderScript_CreateInteger(uint64_t Value);
-extern tSpiderValue    *SpiderScript_CreateReal(double Value);
-extern tSpiderValue    *SpiderScript_CreateString(int Length, const char *Data);
-extern tSpiderValue    *SpiderScript_CreateArray(int InnerType, int ItemCount);
-extern tSpiderValue    *SpiderScript_StringConcat(const tSpiderValue *Str1, const tSpiderValue *Str2);
-extern tSpiderValue    *SpiderScript_CastValueTo(int Type, tSpiderValue *Source);
-extern int     SpiderScript_IsValueTrue(tSpiderValue *Value);
-extern void    SpiderScript_FreeValue(tSpiderValue *Value);
-extern char    *SpiderScript_DumpValue(tSpiderValue *Value);
-
-extern tSpiderValue    *SpiderScript_DoOp(tSpiderValue *Left, enum eSpiderValueOps Op, int bCanCast, tSpiderValue *Right);
-/**
- * \}
- */
-
-#endif
diff --git a/Usermode/Libraries/libspiderscript.so_src/tokens.h b/Usermode/Libraries/libspiderscript.so_src/tokens.h
deleted file mode 100644 (file)
index 4b2acb2..0000000
+++ /dev/null
@@ -1,202 +0,0 @@
-/*
- */
-#ifndef _TOKENS_H_
-#define _TOKENS_H_
-
-#include <setjmp.h>
-
-// Make the scope character ('.') be a symbol, otherwise it's just
-// a ident character
-#define USE_SCOPE_CHAR 1
-
-// === TYPES ===
-typedef struct
-{      
-       // Lexer State
-       const char      *BufStart;
-       const char      *CurPos;
-       
-       char    *Filename;
-       
-        int    LastLine;
-        int    LastToken, LastTokenLen;
-       const char      *LastTokenStr;
-       
-        int    NextLine;
-        int    NextToken, NextTokenLen;
-       const char      *NextTokenStr;
-       
-        int    CurLine;
-        int    Token, TokenLen;
-       const char      *TokenStr;
-       
-       jmp_buf JmpTarget;
-        int    ErrorHit;
-       
-       struct sSpiderVariant   *Variant;
-}      tParser;
-
-// === FUNCTIONS ===
- int   GetToken(tParser *File);
-void   PutBack(tParser *File);
- int   LookAhead(tParser *File);
-
-// === CONSTANTS ===
-enum eTokens
-{
-       TOK_INVAL,
-       TOK_EOF,
-       
-       // Primitives
-       TOK_STR,
-       TOK_INTEGER,
-       TOK_REAL,
-       TOK_VARIABLE,
-       TOK_IDENT,
-       
-       // Reserved Words
-       // - Definitions
-       TOK_RWD_FUNCTION,
-       TOK_RWD_NAMESPACE,
-       // - Control Flow
-       TOK_RWD_NEW,
-       TOK_RWD_RETURN,
-       TOK_RWD_BREAK,
-       TOK_RWD_CONTINUE,
-       // - Blocks
-       TOK_RWD_IF,
-       TOK_RWD_ELSE,
-       TOK_RWD_DO,
-       TOK_RWD_WHILE,
-       TOK_RWD_FOR,
-       // - Value
-       TOK_RWD_NULL,
-       // - Types
-       TOK_RWD_VOID,
-       TOK_RWD_OBJECT,
-       TOK_RWD_OPAQUE,
-       TOK_RWD_STRING,
-       TOK_RWD_INTEGER,
-       TOK_RWD_REAL,
-       
-       // 
-       TOK_ASSIGN,
-       TOK_SEMICOLON,
-       TOK_COMMA,
-       TOK_SCOPE,
-       TOK_ELEMENT,
-       
-       // Comparisons
-       TOK_EQUALS, TOK_NOTEQUALS,
-       TOK_LT, TOK_LTE,
-       TOK_GT, TOK_GTE,
-       
-       // Operations
-       TOK_BWNOT,      TOK_LOGICNOT,
-       TOK_DIV,        TOK_MUL,
-       TOK_PLUS,       TOK_MINUS,
-       TOK_SHL,        TOK_SHR,
-       TOK_LOGICAND,   TOK_LOGICOR,    TOK_LOGICXOR,
-       TOK_AND,        TOK_OR, TOK_XOR,
-       
-       // Assignment Operations
-       TOK_INCREMENT,          TOK_DECREMENT,
-       TOK_ASSIGN_DIV,         TOK_ASSIGN_MUL,
-       TOK_ASSIGN_PLUS,        TOK_ASSIGN_MINUS,
-       TOK_ASSIGN_SHL,         TOK_ASSIGN_SHR,
-       TOK_ASSIGN_LOGICAND,    TOK_ASSIGN_LOGICOR,     TOK_ASSIGN_LOGXICOR,
-       TOK_ASSIGN_AND,         TOK_ASSIGN_OR,  TOK_ASSIGN_XOR,
-       
-       TOK_PAREN_OPEN,         TOK_PAREN_CLOSE,
-       TOK_BRACE_OPEN,         TOK_BRACE_CLOSE,
-       TOK_SQUARE_OPEN,        TOK_SQUARE_CLOSE,
-       
-       TOK_LAST
-};
-
-#define TOKEN_GROUP_TYPES      TOK_RWD_VOID:\
-       case TOK_RWD_OBJECT:\
-       case TOK_RWD_OPAQUE:\
-       case TOK_RWD_INTEGER:\
-       case TOK_RWD_STRING:\
-       case TOK_RWD_REAL
-#define TOKEN_GROUP_TYPES_STR  "TOK_RWD_VOID, TOK_RWD_OBJECT, TOK_RWD_OPAQUE, TOK_RWD_INTEGER, TOK_RWD_STRING or TOK_RWD_REAL"
-
-#define TOKEN_GET_DATATYPE(_type, _tok) do { switch(_tok) {\
-       case TOK_RWD_VOID:  _type = SS_DATATYPE_UNDEF;  break;\
-       case TOK_RWD_INTEGER:_type = SS_DATATYPE_INTEGER;       break;\
-       case TOK_RWD_OPAQUE: _type = SS_DATATYPE_OPAQUE;        break;\
-       case TOK_RWD_OBJECT: _type = SS_DATATYPE_OBJECT;        break;\
-       case TOK_RWD_REAL:   _type = SS_DATATYPE_REAL;  break;\
-       case TOK_RWD_STRING: _type = SS_DATATYPE_STRING;        break;\
-       default:_type=SS_DATATYPE_UNDEF;fprintf(stderr,\
-       "ERROR: Unexpected %s, expected "TOKEN_GROUP_TYPES_STR"\n",csaTOKEN_NAMES[Parser->Token]);\
-       break;\
-       } } while(0)
-
-# if WANT_TOKEN_STRINGS
-const char * const csaTOKEN_NAMES[] = {
-       "TOK_INVAL",
-       "TOK_EOF",
-       
-       "TOK_STR",
-       "TOK_INTEGER",
-       "TOK_REAL",
-       "TOK_VARIABLE",
-       "TOK_IDENT",
-       
-       "TOK_RWD_FUNCTION",
-       "TOK_RWD_NAMESPACE",
-       
-       "TOK_RWD_NEW",
-       "TOK_RWD_RETURN",
-       "TOK_RWD_BREAK",
-       "TOK_RWD_CONTINUE",
-       
-       "TOK_RWD_IF",
-       "TOK_RWD_ELSE",
-       "TOK_RWD_DO",
-       "TOK_RWD_WHILE",
-       "TOK_RWD_FOR",
-       
-       "TOK_RWD_NULL",
-       "TOK_RWD_VOID",
-       "TOK_RWD_OBJECT",
-       "TOK_RWD_OPAUQE",
-       "TOK_RWD_STRING",
-       "TOK_RWD_INTEGER",
-       "TOK_RWD_REAL",
-       
-       "TOK_ASSIGN",
-       "TOK_SEMICOLON",
-       "TOK_COMMA",
-       "TOK_SCOPE",
-       "TOK_ELEMENT",
-       
-       "TOK_EQUALS",   "TOK_NOTEQUALS",
-       "TOK_LT",       "TOK_LTE",
-       "TOK_GT",       "TOK_GTE",
-       
-       "TOK_BWNOT",    "TOK_LOGICNOT",
-       "TOK_DIV",      "TOK_MUL",
-       "TOK_PLUS",     "TOK_MINUS",
-       "TOK_SHL",      "TOK_SHR",
-       "TOK_LOGICAND", "TOK_LOGICOR",  "TOK_LOGICXOR",
-       "TOK_AND",      "TOK_OR",       "TOK_XOR",
-       
-       "TOK_INCREMENT",        "TOK_DECREMENT",
-       "TOK_ASSIGN_DIV",       "TOK_ASSIGN_MUL",
-       "TOK_ASSIGN_PLUS",      "TOK_ASSIGN_MINUS",
-       "TOK_ASSIGN_SHL",       "TOK_ASSIGN_SHR",
-       "TOK_ASSIGN_LOGICAND",  "TOK_ASSIGN_LOGICOR",   "TOK_ASSIGN_LOGICXOR",
-       "TOK_ASSIGN_AND",       "TOK_ASSIGN_OR",        "TOK_ASSIGN_XOR",
-       
-       "TOK_PAREN_OPEN",       "TOK_PAREN_CLOSE",
-       "TOK_BRACE_OPEN",       "TOK_BRACE_CLOSE",
-       "TOK_SQUARE_OPEN",      "TOK_SQUARE_CLOSE",
-       
-       "TOK_LAST"
-};
-# endif
-
-#endif
diff --git a/Usermode/Libraries/libspiderscript.so_src/values.c b/Usermode/Libraries/libspiderscript.so_src/values.c
deleted file mode 100644 (file)
index 019ff5f..0000000
+++ /dev/null
@@ -1,494 +0,0 @@
-/*
- * SpiderScript Library
- * by John Hodge (thePowersGang)
- * 
- * values.c
- * - Manage tSpiderValue objects
- */
-#include <stdlib.h>
-#include <string.h>
-#include <stdio.h>
-#include "spiderscript.h"
-
-// === IMPORTS ===
-extern void    AST_RuntimeError(void *Node, const char *Format, ...);
-
-// === PROTOTYPES ===
-void   SpiderScript_DereferenceValue(tSpiderValue *Object);
-void   SpiderScript_ReferenceValue(tSpiderValue *Object);
-tSpiderValue   *SpiderScript_CreateInteger(uint64_t Value);
-tSpiderValue   *SpiderScript_CreateReal(double Value);
-tSpiderValue   *SpiderScript_CreateString(int Length, const char *Data);
-tSpiderValue   *SpiderScript_CastValueTo(int Type, tSpiderValue *Source);
- int   SpiderScript_IsValueTrue(tSpiderValue *Value);
-void   SpiderScript_FreeValue(tSpiderValue *Value);
-char   *SpiderScript_DumpValue(tSpiderValue *Value);
-// --- Operations
-tSpiderValue   *SpiderScript_DoOp(tSpiderValue *Left, enum eSpiderValueOps, int bCanCast, tSpiderValue *Right);
-tSpiderValue   *SpiderScript_int_DoOpInt(tSpiderValue *Left, enum eSpiderValueOps, int bCanCast, tSpiderValue *Right);
-tSpiderValue   *SpiderScript_int_DoOpReal(tSpiderValue *Left, enum eSpiderValueOps, int bCanCast, tSpiderValue *Right);
-tSpiderValue   *SpiderScript_int_DoOpString(tSpiderValue *Left, enum eSpiderValueOps, int bCanCast, tSpiderValue *Right);
-
-
-// === CODE ===
-/**
- * \brief Dereference a created object
- */
-void SpiderScript_DereferenceValue(tSpiderValue *Object)
-{
-       if(!Object || Object == ERRPTR) return ;
-       Object->ReferenceCount --;
-       if( Object->ReferenceCount == 0 )
-       {
-                int    i;
-
-               if( Object->Type == SS_DATATYPE_ARRAY || SS_GETARRAYDEPTH(Object->Type) )
-               {
-                       for( i = 0; i < Object->Array.Length; i ++ )
-                       {
-                               if( Object->Array.Items[i] ) {
-                                       SpiderScript_DereferenceValue(Object->Array.Items[i]);
-                               }
-                               Object->Array.Items[i] = NULL;
-                       }
-               }
-               else
-               {               
-                       switch( (enum eSpiderScript_DataTypes) Object->Type )
-                       {
-                       case SS_DATATYPE_OBJECT:
-                               Object->Object->ReferenceCount --;
-                               if(Object->Object->ReferenceCount == 0) {
-                                               Object->Object->Type->Destructor( Object->Object );
-                               }
-                               Object->Object = NULL;
-                               break;
-       
-                       case SS_DATATYPE_OPAQUE:
-                               Object->Opaque.Destroy( Object->Opaque.Data );
-                               break;
-                       default:
-                               break;
-                       }
-               }
-               free(Object);
-       }
-}
-
-/**
- * \brief Reference a value
- */
-void SpiderScript_ReferenceValue(tSpiderValue *Object)
-{
-       if(!Object || Object == ERRPTR) return ;
-       Object->ReferenceCount ++;
-}
-
-/**
- * \brief Allocate and initialise a SpiderScript object
- */
-tSpiderObject *SpiderScript_AllocateObject(tSpiderObjectDef *Class, int ExtraBytes)
-{
-        int    size = sizeof(tSpiderObject) + Class->NAttributes * sizeof(tSpiderValue*) + ExtraBytes;
-       tSpiderObject   *ret = malloc(size);
-       
-       ret->Type = Class;
-       ret->ReferenceCount = 1;
-       ret->OpaqueData = &ret->Attributes[ Class->NAttributes ];
-       memset( ret->Attributes, 0, Class->NAttributes * sizeof(tSpiderValue*) );
-       
-       return ret;
-}
-
-/**
- * \brief Create an integer object
- */
-tSpiderValue *SpiderScript_CreateInteger(uint64_t Value)
-{
-       tSpiderValue    *ret = malloc( sizeof(tSpiderValue) );
-       ret->Type = SS_DATATYPE_INTEGER;
-       ret->ReferenceCount = 1;
-       ret->Integer = Value;
-       return ret;
-}
-
-/**
- * \brief Create an real number object
- */
-tSpiderValue *SpiderScript_CreateReal(double Value)
-{
-       tSpiderValue    *ret = malloc( sizeof(tSpiderValue) );
-       ret->Type = SS_DATATYPE_REAL;
-       ret->ReferenceCount = 1;
-       ret->Real = Value;
-       return ret;
-}
-
-/**
- * \brief Create an string object
- */
-tSpiderValue *SpiderScript_CreateString(int Length, const char *Data)
-{
-       tSpiderValue    *ret = malloc( sizeof(tSpiderValue) + Length + 1 );
-       ret->Type = SS_DATATYPE_STRING;
-       ret->ReferenceCount = 1;
-       ret->String.Length = Length;
-       if( Data )
-               memcpy(ret->String.Data, Data, Length);
-       else
-               memset(ret->String.Data, 0, Length);
-       ret->String.Data[Length] = '\0';
-       return ret;
-}
-
-tSpiderValue *SpiderScript_CreateArray(int InnerType, int ItemCount)
-{
-       tSpiderValue    *ret = malloc( sizeof(tSpiderValue) + ItemCount*sizeof(tSpiderValue*) );
-       ret->Type = SS_MAKEARRAY(InnerType);
-       ret->ReferenceCount = 1;
-       ret->Array.Length = ItemCount;
-       memset(ret->Array.Items, 0, ItemCount*sizeof(tSpiderValue*));
-       return ret;
-}
-
-/**
- * \brief Concatenate two strings
- */
-tSpiderValue *SpiderScript_StringConcat(const tSpiderValue *Str1, const tSpiderValue *Str2)
-{
-        int    newLen = 0;
-       tSpiderValue    *ret;
-       
-       if( Str1 && Str1->Type != SS_DATATYPE_STRING)
-               return NULL;
-       if( Str2 && Str2->Type != SS_DATATYPE_STRING)
-               return NULL;
-       
-       if(Str1)        newLen += Str1->String.Length;
-       if(Str2)        newLen += Str2->String.Length;
-       ret = malloc( sizeof(tSpiderValue) + newLen + 1 );
-       ret->Type = SS_DATATYPE_STRING;
-       ret->ReferenceCount = 1;
-       ret->String.Length = newLen;
-       if(Str1)
-               memcpy(ret->String.Data, Str1->String.Data, Str1->String.Length);
-       if(Str2) {
-               if(Str1)
-                       memcpy(ret->String.Data+Str1->String.Length, Str2->String.Data, Str2->String.Length);
-               else
-                       memcpy(ret->String.Data, Str2->String.Data, Str2->String.Length);
-       }
-       ret->String.Data[ newLen ] = '\0';
-       return ret;
-}
-
-/**
- * \brief Cast one object to another
- * \brief Type Destination type
- * \brief Source       Input data
- */
-tSpiderValue *SpiderScript_CastValueTo(int Type, tSpiderValue *Source)
-{
-       tSpiderValue    *ret = ERRPTR;
-        int    len = 0;
-
-       if( !Source )
-       {
-               switch(Type)
-               {
-               case SS_DATATYPE_INTEGER:       return SpiderScript_CreateInteger(0);
-               case SS_DATATYPE_REAL:  return SpiderScript_CreateReal(0);
-               case SS_DATATYPE_STRING:        return SpiderScript_CreateString(4, "null");
-               }
-               return NULL;
-       }
-       
-       // Check if anything needs to be done
-       if( Source->Type == Type ) {
-               SpiderScript_ReferenceValue(Source);
-               return Source;
-       }
-       
-       // Debug
-       #if 0
-       {
-               printf("Casting %i ", Source->Type);
-               switch(Source->Type)
-               {
-               case SS_DATATYPE_INTEGER:       printf("0x%lx", Source->Integer);       break;
-               case SS_DATATYPE_STRING:        printf("\"%s\"", Source->String.Data);  break;
-               case SS_DATATYPE_REAL:  printf("%f", Source->Real);     break;
-               default:        break;
-               }
-               printf(" to %i\n", Type);
-       }
-       #endif
-       
-       // Object casts
-       #if 0
-       if( Source->Type == SS_DATATYPE_OBJECT )
-       {
-               const char      *name = NULL;
-               switch(Type)
-               {
-               case SS_DATATYPE_INTEGER:       name = "cast Integer";  break;
-               case SS_DATATYPE_REAL:          name = "cast Real";     break;
-               case SS_DATATYPE_STRING:        name = "cast String";   break;
-               case SS_DATATYPE_ARRAY:         name = "cast Array";    break;
-               default:
-                       AST_RuntimeError(NULL, "Invalid cast to %i from Object", Type);
-                       return ERRPTR;
-               }
-               if( fcnname )
-               {
-                       ret = Object_ExecuteMethod(Left->Object, fcnname, Right);
-                       if( ret != ERRPTR )
-                               return ret;
-                       // Fall through and try casting (which will usually fail)
-               }
-       }
-       #endif
-       
-       switch( (enum eSpiderScript_DataTypes)Type )
-       {
-       case SS_DATATYPE_UNDEF:
-       case SS_DATATYPE_ARRAY:
-       case SS_DATATYPE_OPAQUE:
-               AST_RuntimeError(NULL, "Invalid cast to %i", Type);
-               return ERRPTR;
-       case SS_DATATYPE_OBJECT:
-               // TODO: 
-               AST_RuntimeError(NULL, "Invalid cast to %i", Type);
-               return ERRPTR;
-       
-       case SS_DATATYPE_INTEGER:
-               ret = malloc(sizeof(tSpiderValue));
-               ret->Type = SS_DATATYPE_INTEGER;
-               ret->ReferenceCount = 1;
-               switch(Source->Type)
-               {
-               case SS_DATATYPE_INTEGER:       break;  // Handled above
-               case SS_DATATYPE_STRING:        ret->Integer = atoi(Source->String.Data);       break;
-               case SS_DATATYPE_REAL:  ret->Integer = Source->Real;    break;
-               default:
-                       AST_RuntimeError(NULL, "Invalid cast from %i to Integer", Source->Type);
-                       free(ret);
-                       ret = ERRPTR;
-                       break;
-               }
-               break;
-       
-       case SS_DATATYPE_REAL:
-               ret = malloc(sizeof(tSpiderValue));
-               ret->Type = SS_DATATYPE_REAL;
-               ret->ReferenceCount = 1;
-               switch(Source->Type)
-               {
-               case SS_DATATYPE_STRING:        ret->Real = atof(Source->String.Data);  break;
-               case SS_DATATYPE_INTEGER:       ret->Real = Source->Integer;    break;
-               default:
-                       AST_RuntimeError(NULL, "Invalid cast from %i to Real", Source->Type);
-                       free(ret);
-                       ret = ERRPTR;
-                       break;
-               }
-               break;
-       
-       case SS_DATATYPE_STRING:
-               switch(Source->Type)
-               {
-               case SS_DATATYPE_INTEGER:       len = snprintf(NULL, 0, "%li", Source->Integer);        break;
-               case SS_DATATYPE_REAL:  len = snprintf(NULL, 0, "%g", Source->Real);    break;
-               default:        break;
-               }
-               ret = malloc(sizeof(tSpiderValue) + len + 1);
-               ret->Type = SS_DATATYPE_STRING;
-               ret->ReferenceCount = 1;
-               ret->String.Length = len;
-               switch(Source->Type)
-               {
-               case SS_DATATYPE_INTEGER:       sprintf(ret->String.Data, "%li", Source->Integer);      break;
-               case SS_DATATYPE_REAL:
-                       sprintf(ret->String.Data, "%g", Source->Real);  break;
-               default:
-                       AST_RuntimeError(NULL, "Invalid cast from %i to String", Source->Type);
-                       free(ret);
-                       ret = ERRPTR;
-                       break;
-               }
-               break;
-       
-       default:
-               AST_RuntimeError(NULL, "BUG - BUG REPORT: Unimplemented cast target %i", Type);
-               ret = ERRPTR;
-               break;
-       }
-       
-       return ret;
-}
-
-/**
- * \brief Condenses a value down to a boolean
- */
-int SpiderScript_IsValueTrue(tSpiderValue *Value)
-{
-       if( Value == ERRPTR )   return 0;
-       if( Value == NULL )     return 0;
-       
-       switch( (enum eSpiderScript_DataTypes)Value->Type )
-       {
-       case SS_DATATYPE_UNDEF:
-               return 0;
-       
-       case SS_DATATYPE_INTEGER:
-               return !!Value->Integer;
-       
-       case SS_DATATYPE_REAL:
-               return (-.5f < Value->Real && Value->Real < 0.5f);
-       
-       case SS_DATATYPE_STRING:
-               return Value->String.Length > 0;
-       
-       case SS_DATATYPE_OBJECT:
-               return Value->Object != NULL;
-       
-       case SS_DATATYPE_OPAQUE:
-               return Value->Opaque.Data != NULL;
-       
-       case SS_DATATYPE_ARRAY:
-               return Value->Array.Length > 0;
-       default:
-               AST_RuntimeError(NULL, "Unknown type %i in SpiderScript_IsValueTrue", Value->Type);
-               return 0;
-       }
-       return 0;
-}
-
-/**
- * \brief Free a value
- * \note Just calls Object_Dereference
- */
-void SpiderScript_FreeValue(tSpiderValue *Value)
-{
-       SpiderScript_DereferenceValue(Value);
-}
-
-/**
- * \brief Dump a value into a string
- * \return Heap string
- */
-char *SpiderScript_DumpValue(tSpiderValue *Value)
-{
-       char    *ret;
-       if( Value == ERRPTR )
-               return strdup("ERRPTR");
-       if( Value == NULL )
-               return strdup("null");
-       
-       switch( (enum eSpiderScript_DataTypes)Value->Type )
-       {
-       case SS_DATATYPE_UNDEF: return strdup("undefined");
-       
-       case SS_DATATYPE_INTEGER:
-               ret = malloc( sizeof(Value->Integer)*2 + 3 );
-               sprintf(ret, "0x%lx", Value->Integer);
-               return ret;
-       
-       case SS_DATATYPE_REAL:
-               ret = malloc( sprintf(NULL, "%f", Value->Real) + 1 );
-               sprintf(ret, "%f", Value->Real);
-               return ret;
-       
-       case SS_DATATYPE_STRING:
-               ret = malloc( Value->String.Length + 3 );
-               ret[0] = '"';
-               strcpy(ret+1, Value->String.Data);
-               ret[Value->String.Length+1] = '"';
-               ret[Value->String.Length+2] = '\0';
-               return ret;
-       
-       case SS_DATATYPE_OBJECT:
-               ret = malloc( sprintf(NULL, "{%s *%p}", Value->Object->Type->Name, Value->Object) + 1 );
-               sprintf(ret, "{%s *%p}", Value->Object->Type->Name, Value->Object);
-               return ret;
-       
-       case SS_DATATYPE_OPAQUE:
-               ret = malloc( sprintf(NULL, "*%p", Value->Opaque.Data) + 1 );
-               sprintf(ret, "*%p", Value->Opaque.Data);
-               return ret;
-       
-       case SS_DATATYPE_ARRAY:
-               return strdup("Array");
-       
-       default:
-               AST_RuntimeError(NULL, "Unknown type %i in Object_Dump", Value->Type);
-               return NULL;
-       }
-       
-}
-
-// ---
-tSpiderValue *SpiderScript_DoOp(tSpiderValue *Left, enum eSpiderValueOps Operation, int bCanCast, tSpiderValue *Right)
-{
-       switch(Left->Type)
-       {
-       case SS_DATATYPE_INTEGER:
-               return SpiderScript_int_DoOpInt(Left, Operation, bCanCast, Right);
-       default:
-               return NULL;
-       }
-       return NULL;
-}
-
-tSpiderValue *SpiderScript_int_DoOpInt(tSpiderValue *Left, enum eSpiderValueOps Operation, int bCanCast, tSpiderValue *Right)
-{
-       tSpiderValue    *oldright = Right;
-       tSpiderValue    *ret = NULL;
-        int64_t        rv = 0;
-
-       // Casting
-       if(Right && Right->Type != SS_DATATYPE_INTEGER) {
-               if(!bCanCast)   return ERRPTR;
-               Right = SpiderScript_CastValueTo(SS_DATATYPE_INTEGER, Right);
-       }
-
-       // Do the operation
-       switch(Operation)
-       {
-       case SS_VALUEOP_NEGATE:
-               if(Right)       ret = ERRPTR;
-               else    rv = -Left->Integer;
-               break;
-       case SS_VALUEOP_ADD:
-               if(!Right)      ret = ERRPTR;
-               else    rv = Left->Integer + Right->Integer;
-               break;
-       case SS_VALUEOP_SUBTRACT:
-               if(!Right)      ret = ERRPTR;
-               else    rv = Left->Integer - Right->Integer;
-               break;
-       default:
-               ret = ERRPTR;
-               AST_RuntimeError(NULL, "BUG - BUG REPORT: Unimplemented integer operation %i", Operation);
-               break;
-       }
-
-       // Delete temporary value
-       if( Right != oldright )
-               SpiderScript_DereferenceValue(Right);
-
-       // Return error if signaled
-       if(ret == ERRPTR)
-               return ERRPTR;
-
-       // Reuse `Left` if possible, to reduce mallocs  
-       if(Left->ReferenceCount == 1) {
-               SpiderScript_ReferenceValue(Left);
-               Left->Integer = rv;
-               return Left;
-       }
-       else {
-               return SpiderScript_CreateInteger(rv);
-       }
-}
-

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