Merge branch 'master' of git.mutabah.net:acess2
authorJohn Hodge <[email protected]>
Tue, 24 Apr 2012 07:06:23 +0000 (15:06 +0800)
committerJohn Hodge <[email protected]>
Tue, 24 Apr 2012 07:06:23 +0000 (15:06 +0800)
38 files changed:
BuildConf/x86/default.mk
KernelLand/Kernel/arch/armv7/proc.S
KernelLand/Kernel/arch/x86/irq.c
KernelLand/Kernel/arch/x86/vm8086.c
KernelLand/Kernel/debug.c
KernelLand/Kernel/drv/vterm.c
KernelLand/Kernel/drv/vterm_output.c
KernelLand/Kernel/drvutil.c
KernelLand/Modules/Display/VESA/common.h
KernelLand/Modules/Display/VESA/main.c
KernelLand/Modules/Display/VIAVideo/Makefile [new file with mode: 0644]
KernelLand/Modules/Display/VIAVideo/common.h [new file with mode: 0644]
KernelLand/Modules/Display/VIAVideo/main.c [new file with mode: 0644]
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/tokens.h [deleted file]
Usermode/Libraries/libspiderscript.so_src/values.c [deleted file]
Usermode/include/spiderscript.h [deleted file]

index 592d702..a4ce894 100644 (file)
@@ -3,7 +3,7 @@ MODULES += Storage/ATA
 MODULES += Storage/FDDv2
 MODULES += Network/NE2000 Network/RTL8139
 MODULES += Display/VESA
-MODULES += Display/BochsGA
+MODULES += Display/BochsGA Display/VIAVideo
 MODULES += Input/PS2KbMouse
 MODULES += x86/ISADMA x86/VGAText
 
index 8711dee..1979058 100644 (file)
@@ -49,9 +49,8 @@ SwitchTask:
 #      mov r1, #1
        mcrne p15, 0, r1, c8, c7, 0     @ TLBIALL - Invalid user space
 
-       @ Restore SP
+       @ Restore state
        mov sp, r0
-
        bx r2
 
 .return:
@@ -102,3 +101,5 @@ csProc_CloneInt_NewTaskMessage:
        .asciz "New task PC=%p, R4=%p, sp=%p"
 csProc_CloneInt_OldTaskMessage:
        .asciz "Parent task PC=%p, R4=%p, SP=%p"
+
+@ vim: ft=armv7
index e2dcf0e..3d23636 100644 (file)
@@ -26,6 +26,7 @@ void  *gaIRQ_DataPointers[16][MAX_CALLBACKS_PER_IRQ];
 void IRQ_Handler(tRegs *Regs)
 {
         int    i, irq = Regs->int_num - 0xF0;
+        int    bHandled = 0;
 
        //Log("IRQ_Handler: (Regs={int_num:%i})", Regs->int_num);
 
@@ -37,8 +38,13 @@ void IRQ_Handler(tRegs *Regs)
                        if( irq != 8 )
                                Log("IRQ %i: Call %p", Regs->int_num, gIRQ_Handlers[Regs->int_num][i]);
                        #endif
+                       bHandled = 1;
                }
        }
+       
+       if( !bHandled ) {
+               Log_Debug("IRQ", "Unhandled IRQ %i", irq);
+       }
 
        //Log(" IRQ_Handler: Resetting");
        if(irq >= 8)
index d93bdf1..44c60df 100644 (file)
@@ -10,6 +10,8 @@
 #include <semaphore.h>
 
 // === CONSTANTS ===
+#define TRACE_EMU      0
+
 #define VM8086_MAGIC_CS        0xFFFF
 #define VM8086_MAGIC_IP        0x0010
 #define VM8086_STACK_SEG       0x9F00
@@ -54,6 +56,7 @@ tPID  gVM8086_WorkerPID;
 tTID   gVM8086_CallingThread;
 tVM8086        volatile * volatile gpVM8086_State = (void*)-1; // Set to -1 to avoid race conditions
 Uint32 gaVM8086_MemBitmap[VM8086_BLOCKCOUNT/32];
+ int   gbVM8086_ShadowIF = 0;
 
 // === FUNCTIONS ===
 int VM8086_Install(char **Arguments)
@@ -91,11 +94,11 @@ int VM8086_Install(char **Arguments)
                MM_Map( 0, 0 ); // IVT / BDA
                // Map (but allow allocation) of 0x1000 - 0x9F000
                // - So much hack, it isn't funny
+               // TODO: Remove this and replce with something less hacky
                for(i=1;i<0x9F;i++) {
                        MM_Map( i * 0x1000, i * 0x1000 );
-                       MM_DerefPhys( i * 0x1000 );     // Above
                        while(MM_GetRefCount(i*0x1000))
-                               MM_DerefPhys( i * 0x1000 );     // Phys setup
+                               MM_DerefPhys( i * 0x1000 );
                }
                MM_Map( 0x9F000, 0x9F000 );     // Stack / EBDA
                // System Stack / Stub
@@ -165,9 +168,12 @@ int VM8086_Install(char **Arguments)
 void VM8086_GPF(tRegs *Regs)
 {
        Uint8   opcode;
+       Uint16  newcs, newip;
        
 //     Log_Log("VM8086", "GPF - %04x:%04x", Regs->cs, Regs->eip);
-       
+
+       LOG("VM8086 GPF at %04x:%04x", Regs->cs, Regs->eip);
+
        if(Regs->eip == VM8086_MAGIC_IP && Regs->cs == VM8086_MAGIC_CS
        && Threads_GetPID() == gVM8086_WorkerPID)
        {
@@ -219,17 +225,24 @@ void VM8086_GPF(tRegs *Regs)
        case VM8086_OP_PUSHF:   //PUSHF
                Regs->esp -= 2;
                *(Uint16*)( Regs->ss*16 + (Regs->esp&0xFFFF) ) = Regs->eflags & 0xFFFF;
+               if( gbVM8086_ShadowIF )
+                       *(Uint16*)( Regs->ss*16 + (Regs->esp&0xFFFF) ) |= 0x200;
+               else
+                       *(Uint16*)( Regs->ss*16 + (Regs->esp&0xFFFF) ) &= ~0x200;
                #if TRACE_EMU
-               Log_Debug("VM8086", "Emulated PUSHF");
+               Log_Debug("VM8086", "%04x:%04x Emulated PUSHF (value 0x%x)",
+                       Regs->cs, Regs->eip-1, Regs->eflags & 0xFFFF);
                #endif
                break;
        case VM8086_OP_POPF:    //POPF
                // Changing IF is not allowed
                Regs->eflags &= 0xFFFF0202;
                Regs->eflags |= *(Uint16*)( Regs->ss*16 + (Regs->esp&0xFFFF) );
+               gbVM8086_ShadowIF = !!(*(Uint16*)( Regs->ss*16 + (Regs->esp&0xFFFF) ) & 0x200);
                Regs->esp += 2;
                #if TRACE_EMU
-               Log_Debug("VM8086", "Emulated POPF");
+               Log_Debug("VM8086", "%04x:%04x Emulated POPF (new value 0x%x)",
+                       Regs->cs, Regs->eip-1, Regs->eflags & 0xFFFF);
                #endif
                break;
        
@@ -242,20 +255,26 @@ void VM8086_GPF(tRegs *Regs)
                Regs->esp -= 2; *(Uint16*)( Regs->ss*16 + (Regs->esp&0xFFFF) ) = Regs->cs;
                Regs->esp -= 2; *(Uint16*)( Regs->ss*16 + (Regs->esp&0xFFFF) ) = Regs->eip;
                
-               Regs->cs = *(Uint16*)(4*id + 2);
-               Regs->eip = *(Uint16*)(4*id);
+               newcs = *(Uint16*)(4*id + 2);
+               newip = *(Uint16*)(4*id);
                #if TRACE_EMU
-               Log_Debug("VM8086", "Emulated INT 0x%x", id);
+               Log_Debug("VM8086", "%04x:%04x Emulated INT 0x%x (%04x:%04x) - AX=%04x,BX=%04x",
+                       Regs->cs, Regs->eip-2, id, newcs, newip, Regs->eax, Regs->ebx);
                #endif
+               Regs->cs = newcs;
+               Regs->eip = newip;
                }
                break;
        
        case VM8086_OP_IRET:    //IRET
-               Regs->eip = *(Uint16*)( Regs->ss*16 + (Regs->esp&0xFFFF) );     Regs->esp += 2;
-               Regs->cs  = *(Uint16*)( Regs->ss*16 + (Regs->esp&0xFFFF) );     Regs->esp += 2;
+               newip = *(Uint16*)( Regs->ss*16 + (Regs->esp&0xFFFF) ); Regs->esp += 2;
+               newcs = *(Uint16*)( Regs->ss*16 + (Regs->esp&0xFFFF) ); Regs->esp += 2;
                #if TRACE_EMU
-               Log_Debug("VM8086", "IRET to %04x:%04x", Regs->cs, Regs->eip);
+               Log_Debug("VM8086", "%04x:%04x IRET to %04x:%04x",
+                       Regs->cs, Regs->eip-1, newcs, newip);
                #endif
+               Regs->cs = newcs;
+               Regs->eip = newip;
                break;
        
        
@@ -263,55 +282,72 @@ void VM8086_GPF(tRegs *Regs)
                Regs->eax &= 0xFFFFFF00;
                Regs->eax |= inb(Regs->edx&0xFFFF);
                #if TRACE_EMU
-               Log_Debug("VM8086", "Emulated IN AL, DX (Port 0x%x)\n", Regs->edx&0xFFFF);
+               Log_Debug("VM8086", "%04x:%04x Emulated IN AL, DX (Port 0x%x [Val 0x%02x])",
+                       Regs->cs, Regs->eip-1, Regs->edx&0xFFFF, Regs->eax&0xFF);
                #endif
                break;
        case VM8086_OP_IN_ADX:  //IN AX, DX
                Regs->eax &= 0xFFFF0000;
                Regs->eax |= inw(Regs->edx&0xFFFF);
                #if TRACE_EMU
-               Log_Debug("VM8086", "Emulated IN AX, DX (Port 0x%x)\n", Regs->edx&0xFFFF);
+               Log_Debug("VM8086", "%04x:%04x Emulated IN AX, DX (Port 0x%x [Val 0x%04x])",
+                       Regs->cs, Regs->eip-1, Regs->edx&0xFFFF, Regs->eax&0xFFFF);
                #endif
                break;
                
        case VM8086_OP_OUT_AD:  //OUT DX, AL
                outb(Regs->edx&0xFFFF, Regs->eax&0xFF);
                #if TRACE_EMU
-               Log_Debug("VM8086", "Emulated OUT DX, AL (*0x%04x = 0x%02x)\n", Regs->edx&0xFFFF, Regs->eax&0xFF);
+               Log_Debug("VM8086", "%04x:%04x Emulated OUT DX, AL (*0x%04x = 0x%02x)",
+                       Regs->cs, Regs->eip-1, Regs->edx&0xFFFF, Regs->eax&0xFF);
                #endif
                break;
        case VM8086_OP_OUT_ADX: //OUT DX, AX
                outw(Regs->edx&0xFFFF, Regs->eax&0xFFFF);
                #if TRACE_EMU
-               Log_Debug("VM8086", "Emulated OUT DX, AX (*0x%04x = 0x%04x)\n", Regs->edx&0xFFFF, Regs->eax&0xFFFF);
+               Log_Debug("VM8086", "%04x:%04x Emulated OUT DX, AX (*0x%04x = 0x%04x)",
+                       Regs->cs, Regs->eip-1, Regs->edx&0xFFFF, Regs->eax&0xFFFF);
                #endif
                break;
                
        // TODO: Decide on allowing VM8086 Apps to enable/disable interrupts
        case 0xFA:      //CLI
+               #if TRACE_EMU
+               Log_Debug("VM8086", "%04x:%04x Ignored CLI",
+                       Regs->cs, Regs->eip);
+               #endif
+               gbVM8086_ShadowIF = 0;
                break;
        case 0xFB:      //STI
+               #if TRACE_EMU
+               Log_Debug("VM8086", "%04x:%04x Ignored STI",
+                       Regs->cs, Regs->eip);
+               #endif
+               gbVM8086_ShadowIF = 1;
                break;
        
        case 0x66:
                opcode = *(Uint8*)( (Regs->cs*16) + (Regs->eip&0xFFFF));
+               Regs->eip ++;
                switch( opcode )
                {
                case VM8086_OP_IN_ADX:  //IN AX, DX
                        Regs->eax = ind(Regs->edx&0xFFFF);
                        #if TRACE_EMU
-                       Log_Debug("VM8086", "Emulated IN EAX, DX (Port 0x%x)\n", Regs->edx&0xFFFF);
+                       Log_Debug("VM8086", "%04x:%04x Emulated IN EAX, DX (Port 0x%x [Val 0x%08x])",
+                               Regs->cs, Regs->eip-1, Regs->edx&0xFFFF, Regs->eax);
                        #endif
                        break;
                case VM8086_OP_OUT_ADX: //OUT DX, AX
                        outd(Regs->edx&0xFFFF, Regs->eax);
                        #if TRACE_EMU
-                       Log_Debug("VM8086", "Emulated OUT DX, EAX (*0x%04x = 0x%08x)\n", Regs->edx&0xFFFF, Regs->eax);
+                       Log_Debug("VM8086", "%04x:%04x Emulated OUT DX, EAX (*0x%04x = 0x%08x)",
+                               Regs->cs, Regs->eip-1, Regs->edx&0xFFFF, Regs->eax);
                        #endif
                        break;
                default:
                        Log_Error("VM8086", "Error - Unknown opcode 66 %02x caused a GPF at %04x:%04x",
-                               Regs->cs, Regs->eip,
+                               Regs->cs, Regs->eip-2,
                                opcode
                                );
                        // Force an end to the call
@@ -332,7 +368,7 @@ void VM8086_GPF(tRegs *Regs)
 
        default:
                Log_Error("VM8086", "Error - Unknown opcode %02x caused a GPF at %04x:%04x",
-                       opcode, Regs->cs, Regs->eip);
+                       opcode, Regs->cs, Regs->eip-1);
                // Force an end to the call
                Regs->cs = VM8086_MAGIC_CS;
                Regs->eip = VM8086_MAGIC_IP;
index 9edf126..6a50ca2 100644 (file)
@@ -1,17 +1,13 @@
 /*
  * AcessOS Microkernel Version
  * debug.c
- * 
- * TODO: Move the Debug_putchar methods out to the arch/ tree
  */
 #include <acess.h>
 #include <stdarg.h>
 
 #define        DEBUG_MAX_LINE_LEN      256
-
-#define        LOCK_DEBUG_OUTPUT       1
-
-#define TRACE_TO_KTERM 1
+#define        LOCK_DEBUG_OUTPUT       1       // Avoid interleaving of output lines?
+#define TRACE_TO_KTERM 0       // Send ENTER/DEBUG/LEAVE to debug?
 
 // === IMPORTS ===
 extern void    Threads_Dump(void);
index 5f4a25c..1cc60be 100644 (file)
@@ -758,6 +758,8 @@ void VT_SetTerminal(int ID)
        giVT_CurrentTerminal = ID;
        gpVT_CurTerm = &gVT_Terminals[ID];
        
+       LOG("Attempting VT_SetMode");
+       
        if( gpVT_CurTerm->Mode == TERM_MODE_TEXT )
        {
                VT_SetMode( VIDEO_BUFFMT_TEXT );
@@ -769,7 +771,9 @@ void VT_SetTerminal(int ID)
                        VFS_IOCtl(giVT_OutputDevHandle, VIDEO_IOCTL_SETCURSORBITMAP, gpVT_CurTerm->VideoCursor);
                VT_SetMode( VIDEO_BUFFMT_FRAMEBUFFER );
        }
-       
+
+       LOG("Mode set");        
+
        if(gpVT_CurTerm->Buffer)
        {
                // TODO: Handle non equal sized
@@ -779,9 +783,11 @@ void VT_SetTerminal(int ID)
                        gpVT_CurTerm->Width*gpVT_CurTerm->Height*sizeof(Uint32),
                        gpVT_CurTerm->Buffer
                        );
+               LOG("Updated screen contents");
        }
        
        VT_int_UpdateCursor(gpVT_CurTerm, 1);
        // Update the screen
        VT_int_UpdateScreen(gpVT_CurTerm, 1);
+       LOG("done");
 }
index 4d1c352..357132c 100644 (file)
@@ -7,7 +7,7 @@
  */
 #include "vterm.h"
 #include <api_drv_video.h>
-#define DEBUG  1
+#define DEBUG  0
 
 // === CODE ===
 /**
index d9bd92d..d2c86bf 100644 (file)
@@ -136,7 +136,7 @@ int DrvUtil_Video_WriteLFB(tDrvUtil_Video_BufInfo *FBInfo, size_t Offset, size_t
         int    x, y;
         int    bytes_per_px = (FBInfo->Depth + 7) / 8;
        ENTER("pFBInfo xOffset xLength pBuffer",
-               Mode, FBInfo, Offset, Length, Buffer);
+               FBInfo, Offset, Length, Buffer);
 
        csr_x = FBInfo->CursorX;
        csr_y = FBInfo->CursorY;
@@ -287,9 +287,12 @@ int DrvUtil_Video_SetCursor(tDrvUtil_Video_BufInfo *Buf, tVideo_IOCtl_Bitmap *Bi
         int    csrX = Buf->CursorX, csrY = Buf->CursorY;
        size_t  size;
 
+       ENTER("pBuf pBitmap", Buf, Bitmap);
+
        // Clear old bitmap
        if( Buf->CursorBitmap )
        {
+               LOG("Clearing old cursor");
                DrvUtil_Video_RemoveCursor(Buf);
                if( !Bitmap || Bitmap->W != Buf->CursorBitmap->W || Bitmap->H != Buf->CursorBitmap->H )
                {
@@ -306,24 +309,29 @@ int DrvUtil_Video_SetCursor(tDrvUtil_Video_BufInfo *Buf, tVideo_IOCtl_Bitmap *Bi
        {
                Buf->CursorX = -1;
                Buf->CursorY = -1;
+               LEAVE('i', 0);
                return 0;
        }
 
        // Sanity check the bitmap
+       LOG("Sanity checking plox");
        if( !CheckMem(Bitmap, sizeof(*Bitmap)) || !CheckMem(Bitmap->Data, Bitmap->W*Bitmap->H*sizeof(Uint32)) )
        {
                Log_Warning("DrvUtil", "DrvUtil_Video_SetCursor: Bitmap (%p) is in invalid memory", Bitmap);
                errno = -EINVAL;
+               LEAVE('i', -1);
                return -1;
        }
 
        // Don't take a copy of the DrvUtil provided cursor
        if( Bitmap == &gDrvUtil_TextModeCursor )
        {
+               LOG("No copy (provided cursor)");
                Buf->CursorBitmap = Bitmap;
        }
        else
        {
+               LOG("Make copy");
                size = sizeof(tVideo_IOCtl_Bitmap) + Bitmap->W*Bitmap->H*4;
                
                // Take a copy
@@ -332,7 +340,9 @@ int DrvUtil_Video_SetCursor(tDrvUtil_Video_BufInfo *Buf, tVideo_IOCtl_Bitmap *Bi
        }
        
        // Restore cursor position
+       LOG("Drawing");
        DrvUtil_Video_DrawCursor(Buf, csrX, csrY);
+       LEAVE('i', 0);
        return 0;
 }
 
@@ -340,24 +350,30 @@ void DrvUtil_Video_DrawCursor(tDrvUtil_Video_BufInfo *Buf, int X, int Y)
 {
         int    render_ox=0, render_oy=0, render_w, render_h;
 
+       ENTER("pBuf iX iY", Buf, X, Y);
        DrvUtil_Video_RemoveCursor(Buf);
 
        // X < 0 disables the cursor
        if( X < 0 ) {
                Buf->CursorX = -1;
+               LEAVE('-');
                return ;
        }
 
        // Sanity checking
-       if( X < 0 || Y < 0 )    return;
-       if( X >= Buf->Width || Y >= Buf->Height )       return;
+       if( X < 0 || Y < 0 || X >= Buf->Width || Y >= Buf->Height ) {
+               LEAVE('-');
+               return ;
+       }
 
        // Ensure the cursor is enabled
-       if( !Buf->CursorBitmap )        return ;
+       if( !Buf->CursorBitmap ) {
+               LEAVE('-');
+               return ;
+       }
        
        // Save cursor position (for changing the bitmap)
        Buf->CursorX = X;       Buf->CursorY = Y;
-
        // Apply cursor's center offset
        X -= Buf->CursorBitmap->XOfs;
        Y -= Buf->CursorBitmap->YOfs;
@@ -375,8 +391,12 @@ void DrvUtil_Video_DrawCursor(tDrvUtil_Video_BufInfo *Buf, int X, int Y)
        Buf->CursorDestX   = X;         Buf->CursorDestY = Y;
        Buf->CursorReadX   = render_ox; Buf->CursorReadY = render_oy;
 
+       LOG("%ix%i at %i,%i offset %i,%i",
+               render_w, render_h, X, Y, render_ox, render_oy);
+
        // Call render routine
        DrvUtil_Video_RenderCursor(Buf);
+       LEAVE('-');
 }
 
 void DrvUtil_Video_RenderCursor(tDrvUtil_Video_BufInfo *Buf)
@@ -393,10 +413,13 @@ void DrvUtil_Video_RenderCursor(tDrvUtil_Video_BufInfo *Buf)
        dest = (Uint8*)Buf->Framebuffer + dest_y*Buf->Pitch + dest_x*bytes_per_px;
        src = Buf->CursorBitmap->Data + src_y * Buf->CursorBitmap->W + src_x;
        
+       LOG("dest = %p, src = %p", dest, src);
+
        // Allocate save buffer if not already
        if( !Buf->CursorSaveBuf )
                Buf->CursorSaveBuf = malloc( Buf->CursorBitmap->W*Buf->CursorBitmap->H*bytes_per_px );
 
+       LOG("Saving back");
        // Save behind the cursor
        for( y = 0; y < render_h; y ++ )
                memcpy(
@@ -413,6 +436,7 @@ void DrvUtil_Video_RenderCursor(tDrvUtil_Video_BufInfo *Buf)
                Log_Warning("DrvUtil", "TODO: Support 15/16 bpp modes in cursor draw");
                break;
        case 24:
+               LOG("24-bit render");
                for( y = 0; y < render_h; y ++ )
                {
                        Uint8   *px;
@@ -435,6 +459,7 @@ void DrvUtil_Video_RenderCursor(tDrvUtil_Video_BufInfo *Buf)
                }
                break;
        case 32:
+               LOG("32-bit render");
                for( y = 0; y < render_h; y ++ )
                {
                        Uint32  *px;
@@ -448,6 +473,7 @@ void DrvUtil_Video_RenderCursor(tDrvUtil_Video_BufInfo *Buf)
                                else
                                        ;       // NOP, completely transparent
                        }
+                       LOG("row %i/%i (%p-%P) done", y+1, render_h, dest, MM_GetPhysAddr(dest));
                        src += Buf->CursorBitmap->W;
                        dest = (Uint8*)dest + Buf->Pitch;
                }
index eeaddd5..c81fe1a 100644 (file)
@@ -22,7 +22,24 @@ typedef struct sVesa_Mode
 
 typedef struct sVesa_CallModeInfo
 {
+       /**
+        * 0 : Mode is supported
+        * 1 : Optional information avaliable (Xres onwards)
+        * 2 : BIOS Output Supported
+        * 3 : Colour Mode?
+        * 4 : Graphics mode?
+        * -- VBE v2.0+
+        * 5 : Mode is not VGA compatible
+        * 6 : Bank switched mode supported
+        * 7 : Linear framebuffer mode supported
+        * 8 : Double-scan mode avaliable
+        */
        Uint16  attributes;
+       /**
+        * 0 : Window exists
+        * 1 : Window is readable
+        * 2 : Window is writable
+        */
        Uint8   winA,winB;
        Uint16  granularity;
        Uint16  winsize;
@@ -35,25 +52,32 @@ typedef struct sVesa_CallModeInfo
        Uint8   memory_model, bank_size, image_pages;
        Uint8   reserved0;
 
+       // -- VBE v1.2+
        Uint8   red_mask, red_position;
        Uint8   green_mask, green_position;
        Uint8   blue_mask, blue_position;
        Uint8   rsv_mask, rsv_position;
        Uint8   directcolor_attributes;
 
-       Uint32  physbase;  // Your LFB address ;)
-       Uint32  reserved1;
-       Sint16  reserved2;
+       // -- VBE v2.0+
+       Uint32  physbase;
+       Uint32  offscreen_ptr;  // Start of offscreen memory
+       Uint16  offscreen_size_kb;      // Size of offscreen memory
+       
+       // -- VBE v3.0
+       Uint16  lfb_pitch;
+       Uint8   image_count_banked;
+       Uint8   image_count_lfb;
 }      tVesa_CallModeInfo;
 
 typedef struct sVesa_CallInfo
 {
-   char                signature[4];           // == "VESA"
-   Uint16      Version;        // == 0x0300 for Vesa 3.0
-   tFarPtr     OEMString;      // isa vbeFarPtr
-   Uint8       Capabilities[4];        
-   tFarPtr     VideoModes;     // isa vbeParPtr
-   Uint16      TotalMemory;    // as # of 64KB blocks
+       char            signature[4];           // == "VESA"
+       Uint16  Version;        // == 0x0300 for Vesa 3.0
+       tFarPtr OEMString;      // isa vbeFarPtr
+       Uint8   Capabilities[4];        
+       tFarPtr VideoModes;     // isa vbeParPtr
+       Uint16  TotalMemory;    // as # of 64KB blocks
 }      tVesa_CallInfo;
 
 #endif
index 2dbc98c..ddf0671 100644 (file)
@@ -16,6 +16,8 @@
 \r
 // === CONSTANTS ===\r
 #define        FLAG_LFB        0x1\r
+#define FLAG_POPULATED 0x2\r
+#define FLAG_VALID     0x4\r
 #define VESA_DEFAULT_FRAMEBUFFER       (KERNEL_BASE|0xA0000)\r
 #define BLINKING_CURSOR        1\r
 #if BLINKING_CURSOR\r
@@ -24,6 +26,7 @@
 \r
 // === PROTOTYPES ===\r
  int   Vesa_Install(char **Arguments);\r
+ int   VBE_int_GetModeList(void);\r
 size_t Vesa_Write(tVFS_Node *Node, off_t Offset, size_t Length, const void *Buffer);\r
  int   Vesa_IOCtl(tVFS_Node *Node, int ID, void *Data);\r
  int   Vesa_Int_SetMode(int Mode);\r
@@ -67,6 +70,27 @@ tDrvUtil_Video_BufInfo       gVesa_BufInfo;
 \r
 // === CODE ===\r
 int Vesa_Install(char **Arguments)\r
+{\r
+        int    rv;\r
+       \r
+       gpVesa_BiosState = VM8086_Init();\r
+       \r
+       if( (rv = VBE_int_GetModeList()) )\r
+               return rv;\r
+               \r
+       #if BLINKING_CURSOR\r
+       // Create blink timer\r
+       gpVesaCursorTimer = Time_AllocateTimer( Vesa_FlipCursor, NULL );\r
+       #endif\r
+\r
+       // Install Device\r
+       giVesaDriverId = DevFS_AddDevice( &gVesa_DriverStruct );\r
+       if(giVesaDriverId == -1)        return MODULE_ERR_MISC;\r
+\r
+       return MODULE_ERR_OK;\r
+}\r
+\r
+int VBE_int_GetModeList(void)\r
 {\r
        tVesa_CallInfo  *info;\r
        tFarPtr infoPtr;\r
@@ -74,7 +98,6 @@ int Vesa_Install(char **Arguments)
        int     i;\r
        \r
        // Allocate Info Block\r
-       gpVesa_BiosState = VM8086_Init();\r
        info = VM8086_Allocate(gpVesa_BiosState, 512, &infoPtr.seg, &infoPtr.ofs);\r
        // Set Requested Version\r
        memcpy(info->signature, "VBE2", 4);\r
@@ -88,15 +111,16 @@ int Vesa_Install(char **Arguments)
                return MODULE_ERR_NOTNEEDED;\r
        }\r
        \r
-       //Log_Debug("VESA", "info->VideoModes = %04x:%04x", info->VideoModes.seg, info->VideoModes.ofs);\r
        modes = (Uint16 *) VM8086_GetPointer(gpVesa_BiosState, info->VideoModes.seg, info->VideoModes.ofs);\r
+//     VM8086_Deallocate( gpVesa_BiosState, info );\r
        \r
-       // Read Modes\r
+       // Count Modes\r
        for( giVesaModeCount = 0; modes[giVesaModeCount] != 0xFFFF; giVesaModeCount++ );\r
+       giVesaModeCount ++;     // First text mode\r
        gVesa_Modes = (tVesa_Mode *)malloc( giVesaModeCount * sizeof(tVesa_Mode) );\r
        \r
-       Log_Debug("VESA", "%i Modes", giVesaModeCount);\r
-       \r
+       Log_Debug("VBE", "%i Modes", giVesaModeCount);\r
+\r
        // Insert Text Mode\r
        gVesa_Modes[0].width = 80;\r
        gVesa_Modes[0].height = 25;\r
@@ -108,22 +132,103 @@ int Vesa_Install(char **Arguments)
        \r
        for( i = 1; i < giVesaModeCount; i++ )\r
        {\r
-               gVesa_Modes[i].code = modes[i];\r
+               gVesa_Modes[i].code = modes[i-1];\r
        }\r
-\r
-//     VM8086_Deallocate( info );\r
        \r
-       #if BLINKING_CURSOR\r
-       // Create blink timer\r
-       gpVesaCursorTimer = Time_AllocateTimer( Vesa_FlipCursor, NULL );\r
+       return 0;\r
+}\r
+\r
+void VBE_int_FillMode_Int(int Index, tVesa_CallModeInfo *vbeinfo, tFarPtr *BufPtr)\r
+{\r
+       tVesa_Mode      *mode = &gVesa_Modes[Index];\r
+\r
+       // Get Mode info\r
+       gpVesa_BiosState->AX = 0x4F01;\r
+       gpVesa_BiosState->CX = mode->code;\r
+       gpVesa_BiosState->ES = BufPtr->seg;\r
+       gpVesa_BiosState->DI = BufPtr->ofs;\r
+       VM8086_Int(gpVesa_BiosState, 0x10);\r
+\r
+       if( gpVesa_BiosState->AX != 0x004F ) {\r
+               Log_Error("VESA", "Getting info on mode 0x%x failed (AX=0x%x)",\r
+                       mode->code, gpVesa_BiosState->AX);\r
+               return ;\r
+       }\r
+\r
+       #define S_LOG(s, fld, fmt)      LOG(" ."#fld" = "fmt, (s).fld)\r
+       LOG("vbeinfo[0x%x] = {", mode->code);\r
+       S_LOG(*vbeinfo, attributes, "0x%02x");\r
+       S_LOG(*vbeinfo, winA, "0x%02x");\r
+       S_LOG(*vbeinfo, winB, "0x%02x");\r
+       S_LOG(*vbeinfo, granularity, "0x%04x");\r
+       S_LOG(*vbeinfo, winsize, "0x%04x");\r
+       S_LOG(*vbeinfo, segmentA, "0x%04x");\r
+       S_LOG(*vbeinfo, segmentB, "0x%04x");\r
+       LOG(" .realFctPtr = %04x:%04x", vbeinfo->realFctPtr.seg, vbeinfo->realFctPtr.ofs);\r
+       S_LOG(*vbeinfo, pitch, "0x%04x");\r
+       // -- Extended\r
+       S_LOG(*vbeinfo, Xres, "%i");\r
+       S_LOG(*vbeinfo, Yres, "%i");\r
+       S_LOG(*vbeinfo, Wchar, "%i");\r
+       S_LOG(*vbeinfo, Ychar, "%i");\r
+       S_LOG(*vbeinfo, planes, "%i");\r
+       S_LOG(*vbeinfo, bpp, "%i");\r
+       S_LOG(*vbeinfo, banks, "%i");\r
+       S_LOG(*vbeinfo, memory_model, "%i");\r
+       S_LOG(*vbeinfo, bank_size, "%i");\r
+       S_LOG(*vbeinfo, image_pages, "%i");\r
+       // -- VBE 1.2+\r
+       LOG(" Red   = %i bits at %i", vbeinfo->red_mask,   vbeinfo->red_position  );\r
+       LOG(" Green = %i bits at %i", vbeinfo->green_mask, vbeinfo->green_position);\r
+       LOG(" Blue  = %i bits at %i", vbeinfo->blue_mask,  vbeinfo->blue_position );\r
+       #if 0\r
+       Uint8   rsv_mask, rsv_position;\r
+       Uint8   directcolor_attributes;\r
        #endif\r
+       // --- VBE 2.0+\r
+       S_LOG(*vbeinfo, physbase, "0x%08x");\r
+       S_LOG(*vbeinfo, offscreen_ptr, "0x%08x");\r
+       S_LOG(*vbeinfo, offscreen_size_kb, "0x%04x");\r
+       // --- VBE 3.0+\r
+       S_LOG(*vbeinfo, lfb_pitch, "0x%04x");\r
+       S_LOG(*vbeinfo, image_count_banked, "%i");\r
+       S_LOG(*vbeinfo, image_count_lfb, "%i");\r
+       LOG("}");\r
 \r
-       // Install Device\r
-       giVesaDriverId = DevFS_AddDevice( &gVesa_DriverStruct );\r
-       if(giVesaDriverId == -1)        return MODULE_ERR_MISC;\r
+       mode->flags = FLAG_POPULATED;\r
+       if( !(vbeinfo->attributes & 1) ) {\r
+               #if DEBUG\r
+               Log_Log("VESA", "0x%x - not supported", mode->code);\r
+               #endif\r
+               mode->width = 0;\r
+               mode->height = 0;\r
+               mode->bpp = 0;\r
+               return ;\r
+       }\r
 \r
-       return MODULE_ERR_OK;\r
-}\r
+       // Parse Info\r
+       mode->flags |= FLAG_VALID;\r
+       if ( (vbeinfo->attributes & 0x90) == 0x90 )\r
+       {\r
+               mode->flags |= FLAG_LFB;\r
+               mode->framebuffer = vbeinfo->physbase;\r
+               mode->fbSize = vbeinfo->Yres*vbeinfo->pitch;\r
+       } else {\r
+               mode->framebuffer = 0;\r
+               mode->fbSize = 0;\r
+       }\r
+       \r
+       mode->pitch = vbeinfo->pitch;\r
+       mode->width = vbeinfo->Xres;\r
+       mode->height = vbeinfo->Yres;\r
+       mode->bpp = vbeinfo->bpp;\r
+       \r
+       #if DEBUG\r
+       Log_Log("VESA", "#%i 0x%x - %ix%ix%i (%x)",\r
+               Index, mode->code, mode->width, mode->height, mode->bpp, mode->flags);\r
+       #endif\r
+\r
+} \r
 \r
 void Vesa_int_FillModeList(void)\r
 {\r
@@ -133,40 +238,12 @@ void Vesa_int_FillModeList(void)
                tVesa_CallModeInfo      *modeinfo;\r
                tFarPtr modeinfoPtr;\r
                \r
-               modeinfo = VM8086_Allocate(gpVesa_BiosState, 512, &modeinfoPtr.seg, &modeinfoPtr.ofs);\r
+               modeinfo = VM8086_Allocate(gpVesa_BiosState, 256, &modeinfoPtr.seg, &modeinfoPtr.ofs);\r
                for( i = 1; i < giVesaModeCount; i ++ )\r
                {\r
-                       // Get Mode info\r
-                       gpVesa_BiosState->AX = 0x4F01;\r
-                       gpVesa_BiosState->CX = gVesa_Modes[i].code;\r
-                       gpVesa_BiosState->ES = modeinfoPtr.seg;\r
-                       gpVesa_BiosState->DI = modeinfoPtr.ofs;\r
-                       VM8086_Int(gpVesa_BiosState, 0x10);\r
-                       \r
-                       // Parse Info\r
-                       gVesa_Modes[i].flags = 0;\r
-                       if ( (modeinfo->attributes & 0x90) == 0x90 )\r
-                       {\r
-                               gVesa_Modes[i].flags |= FLAG_LFB;\r
-                               gVesa_Modes[i].framebuffer = modeinfo->physbase;\r
-                               gVesa_Modes[i].fbSize = modeinfo->Yres*modeinfo->pitch;\r
-                       } else {\r
-                               gVesa_Modes[i].framebuffer = 0;\r
-                               gVesa_Modes[i].fbSize = 0;\r
-                       }\r
-                       \r
-                       gVesa_Modes[i].pitch = modeinfo->pitch;\r
-                       gVesa_Modes[i].width = modeinfo->Xres;\r
-                       gVesa_Modes[i].height = modeinfo->Yres;\r
-                       gVesa_Modes[i].bpp = modeinfo->bpp;\r
-                       \r
-                       #if DEBUG\r
-                       Log_Log("VESA", "0x%x - %ix%ix%i",\r
-                               gVesa_Modes[i].code, gVesa_Modes[i].width, gVesa_Modes[i].height, gVesa_Modes[i].bpp);\r
-                       #endif\r
-               }\r
-       \r
-//             VM8086_Deallocate( modeinfo );\r
+                       VBE_int_FillMode_Int(i, modeinfo, &modeinfoPtr);\r
+               }       \r
+//             VM8086_Deallocate( gpVesa_BiosState, modeinfo );\r
                \r
                gbVesaModesChecked = 1;\r
        }\r
@@ -192,7 +269,6 @@ const char *csaVESA_IOCtls[] = {DRV_IOCTLNAMES, DRV_VIDEO_IOCTLNAMES, NULL};
 int Vesa_IOCtl(tVFS_Node *Node, int ID, void *Data)\r
 {\r
         int    ret;\r
-       //Log_Debug("VESA", "Vesa_Ioctl: (Node=%p, ID=%i, Data=%p)", Node, ID, Data);\r
        switch(ID)\r
        {\r
        BASE_IOCTLS(DRV_TYPE_VIDEO, "VESA", VERSION, csaVESA_IOCtls);\r
@@ -249,11 +325,15 @@ int Vesa_Int_SetMode(int mode)
        gpVesa_BiosState->AX = 0x4F02;\r
        gpVesa_BiosState->BX = gVesa_Modes[mode].code;\r
        if(gVesa_Modes[mode].flags & FLAG_LFB) {\r
-               gpVesa_BiosState->BX |= 0x4000; // Bit 14 - Use LFB\r
+               gpVesa_BiosState->BX |= 1 << 14;        // Use LFB\r
        }\r
+       LOG("In : AX=%04x/BX=%04x",\r
+               gpVesa_BiosState->AX, gpVesa_BiosState->BX);\r
        \r
        // Set Mode\r
        VM8086_Int(gpVesa_BiosState, 0x10);\r
+\r
+       LOG("Out: AX = %04x", gpVesa_BiosState->AX);\r
        \r
        // Map Framebuffer\r
        if( (tVAddr)gpVesa_Framebuffer != VESA_DEFAULT_FRAMEBUFFER )\r
@@ -261,8 +341,8 @@ int Vesa_Int_SetMode(int mode)
        giVesaPageCount = (gVesa_Modes[mode].fbSize + 0xFFF) >> 12;\r
        gpVesa_Framebuffer = (void*)MM_MapHWPages(gVesa_Modes[mode].framebuffer, giVesaPageCount);\r
        \r
-       Log_Log("VESA", "Setting mode to %i (%ix%i %ibpp) %p[0x%x] maps %P",\r
-               mode,\r
+       Log_Log("VESA", "Setting mode to %i 0x%x (%ix%i %ibpp) %p[0x%x] maps %P",\r
+               mode, gVesa_Modes[mode].code,\r
                gVesa_Modes[mode].width, gVesa_Modes[mode].height,\r
                gVesa_Modes[mode].bpp,\r
                gpVesa_Framebuffer, giVesaPageCount << 12, gVesa_Modes[mode].framebuffer\r
diff --git a/KernelLand/Modules/Display/VIAVideo/Makefile b/KernelLand/Modules/Display/VIAVideo/Makefile
new file mode 100644 (file)
index 0000000..c30e486
--- /dev/null
@@ -0,0 +1,7 @@
+#
+#
+
+OBJ = main.o
+NAME = VIAVideo
+
+-include ../Makefile.tpl
diff --git a/KernelLand/Modules/Display/VIAVideo/common.h b/KernelLand/Modules/Display/VIAVideo/common.h
new file mode 100644 (file)
index 0000000..d6b5ba1
--- /dev/null
@@ -0,0 +1,22 @@
+/*
+ */
+#ifndef _VIAVIDEO__COMMON_H_
+#define _VIAVIDEO__COMMON_H_
+
+typedef struct sVIAVideo_Dev   tVIAVideo_Dev;
+
+struct sVIAVideo_Dev
+{
+       tPAddr  FramebufferPhys;
+       tPAddr  MMIOPhys;
+       
+       void    *Framebuffer;
+       Uint8   *MMIO;
+
+       tDrvUtil_Video_BufInfo  BufInfo;
+
+       size_t  FBSize;
+};
+
+#endif
+
diff --git a/KernelLand/Modules/Display/VIAVideo/main.c b/KernelLand/Modules/Display/VIAVideo/main.c
new file mode 100644 (file)
index 0000000..2d5ef58
--- /dev/null
@@ -0,0 +1,280 @@
+/*
+ * Acess2 VIA Video Driver
+ * - By John Hodge
+ * 
+ * main.c
+ * - Driver core
+ *
+ * NOTE: Based off the UniChrome driver for X, http://unichrome.sourceforge.net/
+ */
+#define DEBUG  0
+#include <acess.h>
+#include <fs_devfs.h>
+#include <drv_pci.h>
+#include <modules.h>
+#include <api_drv_video.h>
+#include "common.h"
+
+#define VERSION        VER2(0,1)
+
+// === CONSTANTS ===
+const struct sVGA_Timings
+{
+        int    HFP, HSync, HDisplay, HBP;
+        int    VFP, VSync, VDisplay, VBP;
+} csaTimings[] = {
+       {40, 128, 800, 88,    1, 4, 600, 23},   // SVGA @ 60Hz
+       {24, 136, 1024, 160,  3, 6, 768, 29},   // XGA @ 60Hz
+       {38, 112, 1280, 248,  1, 3, 1024, 38}   // 1280x1024 @ 60Hz
+};
+
+// === PROTOTYPES ===
+ int   VIAVideo_Initialise(char **Arguments);
+void   VIAVideo_Cleanup(void);
+
+size_t VIAVideo_Write(tVFS_Node *Node, off_t Offset, size_t Length, const void *Buffer);
+ int   VIAVideo_IOCtl(tVFS_Node *Node, int ID, void *Data);
+
+void   VIAVideo_int_SetMode(const struct sVGA_Timings *Timings, int Depth);
+void   VIAVideo_int_ResetCRTC(int Index, BOOL Reset);
+
+static void    _SRMask(int Reg, Uint8 Byte, Uint8 Mask);
+static void    _CRMask(int Reg, Uint8 Byte, Uint8 Mask);
+
+// === GLOBALS ===
+MODULE_DEFINE(0, VERSION, VIAVideo, VIAVideo_Initialise, VIAVideo_Cleanup, NULL);
+tVFS_NodeType  gVIAVideo_NodeType = {
+       .Write = VIAVideo_Write,
+       .IOCtl = VIAVideo_IOCtl
+       };
+tDevFS_Driver  gVIAVideo_DriverStruct = {
+       NULL, "VIAVideo",
+       {.Type = &gVIAVideo_NodeType}
+       };
+ int   giVIAVideo_DriverID;
+tVIAVideo_Dev  gVIAVideo_Info;
+
+// === CODE ===
+int VIAVideo_Initialise(char **Arguments)
+{
+        int    count = 0;
+       
+       count += PCI_CountDevices(0x1106, 0x3108);
+       if(count == 0)  return MODULE_ERR_NOTNEEDED;
+       
+
+       for( int i = 0; (i = PCI_GetDevice(0x1106, 0x3108, i)) != -1; i ++ )
+       {
+               // TODO: Support MMIO
+               Log_Log("VIAVideo", "BAR0 = 0x%x", PCI_GetBAR(i, 0));
+               Log_Log("VIAVideo", "BAR1 = 0x%x", PCI_GetBAR(i, 1));
+               Log_Log("VIAVideo", "BAR2 = 0x%x", PCI_GetBAR(i, 2));
+               Log_Log("VIAVideo", "BAR3 = 0x%x", PCI_GetBAR(i, 3));
+               Log_Log("VIAVideo", "BAR4 = 0x%x", PCI_GetBAR(i, 4));
+               Log_Log("VIAVideo", "BAR5 = 0x%x", PCI_GetBAR(i, 5));
+               
+               if( gVIAVideo_Info.FramebufferPhys )    continue ;
+               
+               gVIAVideo_Info.FramebufferPhys = PCI_GetBAR(i, 0);
+               gVIAVideo_Info.MMIOPhys = PCI_GetBAR(i, 1);
+               
+               gVIAVideo_Info.Framebuffer = (void*)MM_MapHWPages(gVIAVideo_Info.FramebufferPhys, (1024*768*4)/PAGE_SIZE);
+               // TODO: Map MMIO
+
+               memset(gVIAVideo_Info.Framebuffer, 128, 1024*4*200);
+
+               gVIAVideo_Info.BufInfo.Framebuffer = gVIAVideo_Info.Framebuffer;
+               gVIAVideo_Info.BufInfo.Pitch = 1024*4;
+               gVIAVideo_Info.BufInfo.Width = 1024;
+               gVIAVideo_Info.BufInfo.Height = 768;
+               gVIAVideo_Info.BufInfo.Depth = 32;      
+
+       }
+
+       VIAVideo_int_SetMode( &csaTimings[1], 32 );
+
+       // Install Device
+       giVIAVideo_DriverID = DevFS_AddDevice( &gVIAVideo_DriverStruct );
+       if(giVIAVideo_DriverID == -1)   return MODULE_ERR_MISC;
+
+       return MODULE_ERR_OK;
+}
+
+void VIAVideo_Cleanup(void)
+{
+       return ;
+}
+
+size_t VIAVideo_Write(tVFS_Node *Node, off_t Offset, size_t Length, const void *Buffer)
+{
+       #if 0
+       return DrvUtil_Video_WriteLFB(&gVIAVideo_Info.BufInfo, Offset, Length, Buffer);
+       #endif
+       return 0;
+       #if 0
+       if( Offset >= gVIAVideo_Info.FBSize )
+               return 0;
+       if( Length > gVIAVideo_Info.FBSize )
+               Length = gVIAVideo_Info.FBSize;
+       if( Offset + Length > gVIAVideo_Info.FBSize )
+               Length = gVIAVideo_Info.FBSize - Offset;
+       
+       memcpy( (Uint8*)gVIAVideo_Info.Framebuffer + Offset, Buffer, Length );
+       
+       return Length;
+       #endif
+}
+
+int VIAVideo_IOCtl(tVFS_Node *Node, int ID, void *Data)
+{
+       return 0;
+}
+
+// --- Modeset!
+void VIAVideo_int_SetMode(const struct sVGA_Timings *Timings, int Depth)
+{
+        int    temp;
+       
+       // ??? Some Magic (Unichrome - VGACRMask(pVia, 0x17, 0x00, 0x80);)      
+
+       // Reset CRTC1
+       VIAVideo_int_ResetCRTC(0, TRUE);
+       
+       // -- Set framebuffer --
+       // Set colour depth bits
+       // VGASRMask(Crtc, 0x15, {0x00,0x14,0x0C}[Depth=8,16,24/32], 0x1C)
+       switch(Depth) {
+       case 8:  _SRMask(0x15, 0x00, 0x1C);     break;
+       case 16: _SRMask(0x15, 0x14, 0x1C);     break;
+       case 24: _SRMask(0x15, 0x0C, 0x1C);     break;
+       case 32: _SRMask(0x15, 0x0C, 0x1C);     break;
+       default:        return ;
+       }
+       // Set line length
+       {
+                int    pitch = Timings->HDisplay * (Depth/8) / 8;
+               // (Pitch/8) -> CR13 + CR35&0xE0
+               _CRMask(0x13, pitch, 0xFF);
+               _CRMask(0x35, (pitch>>8)<<5, 0xE0);
+       }
+       // - Set frame origin? (->FrameSet(Crtc, X, Y))
+       // DWORD Offset in memory
+       // Stored in CR0D + CR0C + CR34 + CR48&0x03
+
+       // -- Set CRTC Mode --
+       // NOTES:
+       // - VGA Represents the signal cycle as Display, Blank with Sync anywhere in that
+       // - Hence, I program the blanking as HBP, Sync, HFP (with the sync in the blanking area)
+
+       // Set mode
+       // VGAMiscMask(Crtc, (HSyncEnabled ? 0x40 : 0x00), 0x40);
+       // VGAMiscMask(Crtc, (VSyncEnabled ? 0x80 : 0x00), 0x80);
+       // HTotal:   CR00 + CR36&0x08 = /8-5
+       temp = (Timings->HFP + Timings->HSync + Timings->HDisplay + Timings->HBP) / 8 - 5;
+       _CRMask(0x00, temp, 0xFF);
+       _CRMask(0x36, (temp>>8)<<3, 0x08);
+       // HDisplay: CR01 = /8-1
+       temp = Timings->HDisplay / 8 - 1;
+       _CRMask(0x01, temp, 0xFF);
+       // HBlank Start: CR02 = /8-1
+       temp = (Timings->HDisplay) / 8 - 1;
+       _CRMask(0x02, temp, 0xFF);
+       // HBlank End:   CR03&0x1F + CR05&0x80 + CR33&0x20 = /8-1
+       temp = (Timings->HBP + Timings->HSync + Timings->HFP) / 8 - 1;
+       if( temp >> 7 ) Log_Error("VIA", "HBlank End doesn't fit (%i not 7 bits)", temp);
+       _CRMask(0x03, temp, 0x1F);
+       _CRMask(0x05, (temp>>5)<<7, 0x80);
+       _CRMask(0x33, (temp>>6)<<5, 0x20);
+       // HSync Start: CR04 + CR33&0x10 = /8
+       temp = (Timings->HDisplay + Timings->HBP) / 8;
+       _CRMask(0x04, temp, 0xFF);
+       _CRMask(0x33, (temp>>8)<<4, 0x10);
+       // HSync End:   CR05&0x1F = /8
+       temp = (Timings->HSync) / 8;
+       _CRMask(0x05, temp, 0x1F);
+       // VTotal:   CR06 + CR07&0x01 + CR07&0x20 + CR35&0x01 = -2
+       temp = (Timings->VFP + Timings->VBP + Timings->VSync + Timings->VDisplay) - 2;
+       _CRMask(0x06, temp, 0xFF);
+       _CRMask(0x07, (temp>>8)<<0, 0x01);
+       _CRMask(0x07, (temp>>9)<<5, 0x20);
+       _CRMask(0x35, (temp>>10)<<0, 0x01);
+       // VDisplay: CR12 + CR07&0x02 + CR07&0x40 + CR35&0x04 = -1
+       temp = (Timings->VDisplay) - 1;
+       _CRMask(0x12, temp, 0xFF);
+       _CRMask(0x07, (temp>>8)<<1, 0x02);
+       _CRMask(0x07, (temp>>9)<<6, 0x40);
+       _CRMask(0x07, (temp>>10)<<2, 0x04);
+       // 0:  CR0C + CR0D + CD34 + CR48&0x03 ("Primary starting address")
+       temp = 0;
+       _CRMask(0x0C, temp, 0xFF);
+       _CRMask(0x0D, (temp>>8), 0xFF);
+       _CRMask(0x34, (temp>>16), 0xFF);
+       _CRMask(0x48, (temp>>24), 0x03);
+       // VSyncStart: CR10 + CR07&0x04 + CR07&0x80 + CR35&0x02
+       temp = (Timings->VDisplay + Timings->HBP);
+       _CRMask(0x10, temp, 0xFF);
+       _CRMask(0x07, (temp>>8)<<2, 0x04);
+       _CRMask(0x07, (temp>>9)<<7, 0x80);
+       _CRMask(0x35, (temp>>10)<<1, 0x02);
+       // VSyncEnd:   CR11&0x0F
+       temp = (Timings->VSync);
+       _CRMask(0x11, temp, 0x0F);
+       // 0x3FFF: CR18 + CR07&0x10 + CR09&0x40 + CR33&0x06 + CR35&0x10 ("line compare")
+       temp = 0x3FFF;
+       _CRMask(0x18, temp, 0xFF);
+       _CRMask(0x07, (temp>>8)<<4, 0x10);
+       _CRMask(0x09, (temp>>9)<<6, 0x40);
+       _CRMask(0x33, (temp>>10)<<1, 0x06);
+       _CRMask(0x35, (temp>>12)<<4, 0x10);
+       // 0:  CR09&0x1F ("Maximum scanline")
+       temp = 0;
+       _CRMask(0x09, temp, 0x1F);
+       // 0: Cursor location
+       temp = 0;
+       _CRMask(0x14, temp, 0xFF);
+       // VBlankStart: CR15 + CR07&0x08 + CR09&0x20 + CR35&0x08 = -1
+       temp = (Timings->VDisplay) - 1;
+       _CRMask(0x15, temp, 0xFF);
+       _CRMask(0x07, (temp>>8)<<3, 0x08);
+       _CRMask(0x09, (temp>>9)<<5, 0x20);
+       _CRMask(0x35, (temp>>10)<<3, 0x08);
+       // VBlankEnd:   CR16 = -1
+       temp = (Timings->VBP + Timings->VSync + Timings->VFP) - 1;
+       _CRMask(0x16, temp, 0xFF);
+       // 0:  CR08 (Preset Row Scan Register)
+       _CRMask(0x08, 0, 0xFF);
+       // 0:  CR32 (???)
+       _CRMask(0x32, 0, 0xFF);
+       // 0:  CR33&0xC8
+       _CRMask(0x33, 0, 0xC8);
+
+       // Set scaling?
+
+       // Disable CRTC reset
+       VIAVideo_int_ResetCRTC(0, FALSE);
+}
+
+void VIAVideo_int_ResetCRTC(int Index, BOOL Reset)
+{
+       // VGASRMask(Crtc, 0x00, (Reset ? 0x00 : 0x02), 0x02);
+       _SRMask(0x00, (Reset ? 0x00 : 0x02), 0x02);
+}
+
+void _SRMask(int Reg, Uint8 Byte, Uint8 Mask)
+{
+       Uint8   cv = 0;
+       outb(0x3C4, Reg);
+       if(Mask != 0xFF)        cv = inb(0x3C5) & ~Mask;
+       cv |= Byte & Mask;
+       outb(0x3C5, cv);
+}
+
+void _CRMask(int Reg, Uint8 Byte, Uint8 Mask)
+{
+       Uint8   cv = 0;
+       outb(0x3D4, Reg);
+       if(Mask != 0xFF)        cv = inb(0x3D5) & ~Mask;
+       cv |= Byte & Mask;
+       outb(0x3D5, cv);
+}
+
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 28382ca..0000000
+++ /dev/null
@@ -1,13 +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 exec_ast.o exports.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 12f9f77..0000000
+++ /dev/null
@@ -1,744 +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_8(Buffer, Offset, Node->DefVar.DataType);
-               // TODO: Duplicate compress the strings
-               WRITE_STR(Buffer, Offset, Node->DefVar.Name);
-               
-               WRITE_NODELIST(Buffer, Offset, Node->DefVar.LevelSizes);
-               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_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;
-       
-       //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:
-               for( node = Node->DefVar.LevelSizes; node; )
-               {
-                       tAST_Node       *savedNext = node->NextSibling;
-                       AST_FreeNode(node);
-                       node = savedNext;
-               }
-               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_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_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;
-       case NODETYPE_DEFVAR:
-               if(Parent->DefVar.LevelSizes == NULL) {
-                       Parent->DefVar.LevelSizes = Parent->DefVar.LevelSizes_Last = Child;
-               }
-               else {
-                       Parent->DefVar.LevelSizes_Last->NextSibling = Child;
-                       Parent->DefVar.LevelSizes_Last = 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 ) {
-               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 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.LevelSizes = NULL;
-       ret->DefVar.LevelSizes_Last = NULL;
-       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 8ee56d7..0000000
+++ /dev/null
@@ -1,235 +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
-       
-       NODETYPE_VARIABLE,      //!< Variable
-       NODETYPE_CONSTANT,      //!< Runtime Constant
-       NODETYPE_STRING,        //!< String Constant
-       NODETYPE_INTEGER,       //!< Integer Constant
-       NODETYPE_REAL,  //!< Real Constant
-       
-       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)
-       
-       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
-       
-       NODETYPE_IF,    //!< Conditional
-       NODETYPE_LOOP,  //!< Looping Construct
-       
-       NODETYPE_INDEX, //!< Index into an array
-       
-       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_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       *LevelSizes;
-                       tAST_Node       *LevelSizes_Last;
-                       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_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);
-
-#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 58cc5f8..0000000
+++ /dev/null
@@ -1,679 +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_NODE_RETURNS     0
-#define MAX_NAMESPACE_DEPTH    10
-
-// === IMPORTS ===
-extern tSpiderFunction *gpExports_First;
-
-// === TYPES ===
-typedef struct sAST_BlockInfo
-{
-       struct sAST_BlockInfo   *Parent;
-       void    *Handle;
-       const char      *Tag;
-
-        int    BreakTarget;
-        int    ContinueTarget;
-       
-       const char      *CurNamespaceStack[MAX_NAMESPACE_DEPTH];
-} tAST_BlockInfo;
-
-// === PROTOTYPES ===
-// Node Traversal
- int   AST_ConvertNode(tAST_BlockInfo *Block, tAST_Node *Node, int bKeepValue);
-// 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);
-// - 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 ===
-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};
-
-       // TODO: Return BCFcn instead?
-       if(Fcn->BCFcn)  return Fcn->BCFcn;
-       
-       ret = Bytecode_CreateFunction(Fcn);
-       if(!ret)        return NULL;
-       
-       bi.Handle = ret;
-       if( AST_ConvertNode(&bi, Fcn->ASTFcn, 0) )
-       {
-               Bytecode_DeleteFunction(ret);
-               return NULL;
-       }
-
-       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);\
-} } 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 )
-                       {
-                               AST_ConvertNode(Block, node, 0);
-                       }
-               }
-               Bytecode_AppendLeaveContext(Block->Handle);     // Leave this context
-               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 -1;
-               }
-               
-               // Perform assignment operation
-               if( Node->Assign.Operation != NODETYPE_NOP )
-               {
-                       
-                       ret = BC_Variable_GetValue(Block, Node->Assign.Dest);
-                       if(ret) return ret;
-                       ret = AST_ConvertNode(Block, Node->Assign.Value, 1);
-                       if(ret) return ret;
-                       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);
-                       Bytecode_AppendBinOp(Block->Handle, op);
-               }
-               else
-               {
-                       ret = AST_ConvertNode(Block, Node->Assign.Value, 1);
-                       if(ret) return ret;
-               }
-               
-               if( bKeepValue )
-                       Bytecode_AppendDuplicate(Block->Handle);
-               // Set the variable value
-               ret = BC_Variable_SetValue( Block, Node->Assign.Dest );
-               break;
-       
-       // Post increment/decrement
-       case NODETYPE_POSTINC:
-       case NODETYPE_POSTDEC:
-               // TODO: Support assigning to object attributes
-               if( Node->UniOp.Value->Type != NODETYPE_VARIABLE ) {
-                       AST_RuntimeError(Node, "LVALUE of assignment is not a variable");
-                       return -1;
-               }
-
-               // 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 = BC_Variable_GetValue(Block, Node->UniOp.Value);
-               if(ret) return ret;
-
-               if( Node->Type == NODETYPE_POSTDEC )
-                       Bytecode_AppendBinOp(Block->Handle, BC_OP_SUBTRACT);
-               else
-                       Bytecode_AppendBinOp(Block->Handle, BC_OP_ADD);
-               if(ret) return ret;
-
-
-               ret = BC_Variable_SetValue(Block, Node->UniOp.Value);
-               if(ret) return ret;
-               // Doesn't push unless needed
-               break;
-       
-       // Function Call
-       case NODETYPE_METHODCALL:
-       case NODETYPE_FUNCTIONCALL:
-       case NODETYPE_CREATEOBJECT: {
-                int    nargs = 0;
-
-               // Put the object earlier on the stack to the arguments (for exec)
-               if( Node->Type == NODETYPE_METHODCALL ) {
-                       ret = AST_ConvertNode(Block, Node->FunctionCall.Object, 1);
-                       if(ret) return ret;
-               }               
-
-               for(node = Node->FunctionCall.FirstArg; node; node = node->NextSibling)
-               {
-                       ret = AST_ConvertNode(Block, node, 1);
-                       if(ret) return ret;
-                       nargs ++;
-               }
-               
-               // Call the function
-               if( Node->Type == NODETYPE_METHODCALL )
-               {
-                       // TODO: Sanity check stack top
-                       Bytecode_AppendMethodCall(Block->Handle, Node->FunctionCall.Name, nargs);
-               }
-               else
-               {
-                        int    newnamelen = 0;
-                       char    *manglename;
-                       for( i = 0; i < MAX_NAMESPACE_DEPTH && Block->CurNamespaceStack[i]; i ++ )
-                               newnamelen = strlen(Block->CurNamespaceStack[i]) + 1;
-                       newnamelen += strlen(Node->FunctionCall.Name) + 1;
-                       manglename = alloca(newnamelen);
-                       manglename[0] = 0;
-                       for( i = 0; i < MAX_NAMESPACE_DEPTH && Block->CurNamespaceStack[i]; i ++ ) {
-                                int    pos;
-                               strcat(manglename, Block->CurNamespaceStack[i]);
-                               pos = strlen(manglename);
-                               manglename[pos] = BC_NS_SEPARATOR;
-                               manglename[pos+1] = '\0';
-                       }
-                       strcat(manglename, Node->FunctionCall.Name);
-                               
-                       if( Node->Type == NODETYPE_CREATEOBJECT )
-                       {
-                               // TODO: Sanity check stack top
-                               Bytecode_AppendCreateObj(Block->Handle, manglename, nargs);
-                       }
-                       else
-                       {
-                               Bytecode_AppendFunctionCall(Block->Handle, manglename, nargs);
-                       }
-               }
-               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;
-               
-               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;
-                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);
-               loop_end = Bytecode_AllocateLabel(Block->Handle);
-
-               saved_break = Block->BreakTarget;
-               saved_continue = Block->ContinueTarget;
-               saved_tag = Block->Tag;
-               Block->BreakTarget = loop_end;
-               Block->ContinueTarget = loop_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);
-                       Bytecode_AppendCondJump(Block->Handle, loop_end);
-               }
-       
-               // Code
-               ret = AST_ConvertNode(Block, Node->For.Code, 0);
-               if(ret) return ret;
-               
-               // Increment
-               ret = AST_ConvertNode(Block, Node->For.Increment, 0);
-               if(ret) return ret;
-
-               // Tail check
-               if( Node->For.bCheckAfter )
-               {
-                       ret = AST_ConvertNode(Block, Node->For.Condition, 1);
-                       if(ret) 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);
-               break;
-       
-       case NODETYPE_BREAK:
-       case NODETYPE_CONTINUE: {
-               tAST_BlockInfo  *bi = Block;
-               if( Node->Variable.Name[0] ) {
-                       while(bi && strcmp(bi->Tag, Node->Variable.Name) == 0)  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;
-                       Bytecode_AppendSaveVar(Block->Handle, Node->DefVar.Name);
-               }
-               break;
-       
-       // Scope
-       case NODETYPE_SCOPE:
-               for( i = 0; i < MAX_NAMESPACE_DEPTH && Block->CurNamespaceStack[i]; i ++ );
-               if( i == MAX_NAMESPACE_DEPTH ) {
-                       AST_RuntimeError(Node, "Exceeded max explicit namespace depth (%i)", i);
-                       return 2;
-               }
-               Block->CurNamespaceStack[i] = Node->Scope.Name;
-               ret = AST_ConvertNode(Block, Node->Scope.Element, 2);
-               Block->CurNamespaceStack[i] = NULL;
-               CHECK_IF_NEEDED(0);     // No warning?
-               // TODO: Will this collide with _CALLFUNCTION etc?
-               break;
-       
-       // Variable
-       case NODETYPE_VARIABLE:
-               ret = BC_Variable_GetValue( Block, Node );
-               CHECK_IF_NEEDED(1);
-               break;
-       
-       // Element of an Object
-       case NODETYPE_ELEMENT:
-               ret = AST_ConvertNode( Block, Node->Scope.Element, 1 );
-               if(ret) return ret;
-
-               Bytecode_AppendElement(Block->Handle, Node->Scope.Name);
-               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;
-               Bytecode_AppendCast(Block->Handle, Node->Cast.DataType);
-               CHECK_IF_NEEDED(1);
-               break;
-
-       // Index into an array
-       case NODETYPE_INDEX:
-               ret = AST_ConvertNode(Block, Node->BinOp.Left, 1);      // Array
-               if(ret) return ret;
-               ret = AST_ConvertNode(Block, Node->BinOp.Right, 1);     // Offset
-               if(ret) return ret;
-               
-               Bytecode_AppendIndex(Block->Handle);
-               CHECK_IF_NEEDED(1);
-               break;
-
-       // TODO: Implement runtime constants
-       case NODETYPE_CONSTANT:
-               // TODO: Scan namespace for constant name
-               AST_RuntimeError(Node, "TODO - Runtime Constants");
-               ret = -1;
-               break;
-       
-       // Constant Values
-       case NODETYPE_STRING:
-               Bytecode_AppendConstString(Block->Handle, Node->Constant.String.Data, Node->Constant.String.Length);
-               CHECK_IF_NEEDED(1);
-               break;
-       case NODETYPE_INTEGER:
-               Bytecode_AppendConstInt(Block->Handle, Node->Constant.Integer);
-               CHECK_IF_NEEDED(1);
-               break;
-       case NODETYPE_REAL:
-               Bytecode_AppendConstReal(Block->Handle, Node->Constant.Real);
-               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;
-               Bytecode_AppendUniOp(Block->Handle, op);
-               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_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 = AST_ConvertNode(Block, Node->BinOp.Right, 1);
-               if(ret) return ret;
-       
-               Bytecode_AppendBinOp(Block->Handle, op);
-               CHECK_IF_NEEDED(1);
-               break;
-       
-       default:
-               ret = -1;
-               AST_RuntimeError(Node, "BUG - SpiderScript AST_ConvertNode Unimplemented %i", Node->Type);
-               break;
-       }
-
-       #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;
-}
-
-/**
- * \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)
-{
-       #if 0
-       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;
-       strcpy(var->Name, Name);
-       
-       if(prev)        prev->Next = var;
-       else    Block->FirstVar = var;
-       
-       return var;
-       #else
-       Bytecode_AppendDefineVar(Block->Handle, Name, Type);
-       return 0;
-       #endif
-}
-
-tAST_Variable *BC_Variable_Lookup(tAST_BlockInfo *Block, tAST_Node *VarNode, int CreateType)
-{
-       #if 0
-       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_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", "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;
-       #else
-       return (void*)1;
-       #endif
-}
-
-/**
- * \brief Set the value of a variable
- * \return Boolean Failure
- */
-int BC_Variable_SetValue(tAST_BlockInfo *Block, tAST_Node *VarNode)
-{
-       tAST_Variable   *var;
-       
-       var = BC_Variable_Lookup(Block, VarNode, SS_DATATYPE_UNDEF);
-       if(!var)        return -1;
-
-       // TODO: Check types
-
-       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;
-       
-       Bytecode_AppendLoadVar(Block->Handle, VarNode->Variable.Name);
-       return 0;
-}
-
-#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
diff --git a/Usermode/Libraries/libspiderscript.so_src/bytecode.h b/Usermode/Libraries/libspiderscript.so_src/bytecode.h
deleted file mode 100644 (file)
index bc3c91c..0000000
+++ /dev/null
@@ -1,50 +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
-       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 b089b9a..0000000
+++ /dev/null
@@ -1,444 +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);
-
-       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_qword(uint64_t value)
-       {
-               _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_dword(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_dword( 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_dword(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);
-       
-       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);
-}
-
-// --- Indexing / Scoping
-void Bytecode_AppendElement(tBC_Function *Handle, const char *Name)
-       DEF_BC_STR(BC_OP_ELEMENT, Name)
-void Bytecode_AppendIndex(tBC_Function *Handle)
-       DEF_BC_NONE(BC_OP_INDEX)
-
-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 0d901eb..0000000
+++ /dev/null
@@ -1,79 +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);
-//  > Scoping
-extern void    Bytecode_AppendElement(tBC_Function *Handle, const char *Name); // Obj->SubObj
-extern void    Bytecode_AppendIndex(tBC_Function *Handle);     // Index into an array
-//  > 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 5affbef..0000000
+++ /dev/null
@@ -1,133 +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);
-               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);
-                       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 59c58be..0000000
+++ /dev/null
@@ -1,67 +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_DUPSTACK, // = 13
-       BC_OP_DELSTACK, // 
-       BC_OP_CAST,     //
-       
-       BC_OP_ELEMENT,  // = 16
-       BC_OP_INDEX,
-
-       BC_OP_ENTERCONTEXT,     // = 18
-       BC_OP_LEAVECONTEXT,
-       BC_OP_DEFINEVAR,
-
-       // Operations
-       BC_OP_LOGICNOT, // 21
-       BC_OP_LOGICAND,
-       BC_OP_LOGICOR,
-       BC_OP_LOGICXOR,
-
-       BC_OP_BITNOT,   // 25
-       BC_OP_BITAND,
-       BC_OP_BITOR,
-       BC_OP_BITXOR,
-
-       BC_OP_BITSHIFTLEFT,     // 29
-       BC_OP_BITSHIFTRIGHT,
-       BC_OP_BITROTATELEFT,
-
-       BC_OP_NEG,      // 32
-       BC_OP_ADD,
-       BC_OP_SUBTRACT,
-       BC_OP_MULTIPLY,
-       BC_OP_DIVIDE,
-       BC_OP_MODULO,
-
-       BC_OP_EQUALS,   // 38
-       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 b073cbf..0000000
+++ /dev/null
@@ -1,342 +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>
-
-// === IMPORTS ===
-extern tSpiderFunction *gpExports_First;
-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 ===
-/**
- * \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,
-       tSpiderNamespace *Namespace, const char *Function,
-       int NArguments, tSpiderValue **Arguments)
-{
-        int    bFound = 0;     // Used to keep nesting levels down
-       tSpiderValue    *ret = ERRPTR;
-       
-       // First: Find the function in the script
-       {
-               tScript_Function        *fcn;
-               for( fcn = Script->Functions; fcn; fcn = fcn->Next )
-               {
-                       if( strcmp(fcn->Name, Function) == 0 )
-                               break;
-               }
-               // Execute!
-               if(fcn)
-               {
-                       if( fcn->BCFcn )
-                               ret = Bytecode_ExecuteFunction(Script, fcn, NArguments, Arguments);
-                       else
-                               ret = AST_ExecuteFunction(Script, fcn, NArguments, Arguments);
-                       bFound = 1;
-               }
-       }
-       
-       // Didn't find it in script?
-       if(!bFound)
-       {
-               tSpiderFunction *fcn;
-               fcn = NULL;     // Just to allow the below code to be neat
-               
-               // Second: Scan current namespace
-               if( !fcn && Namespace )
-               {
-                       for( fcn = Namespace->Functions; fcn; fcn = fcn->Next )
-                       {
-                               if( strcmp( fcn->Name, Function ) == 0 )
-                                       break;
-                       }
-               }
-               
-               // Third: 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;
-                       }
-               }
-               
-               // Execute!
-               if(fcn)
-               {
-                       // TODO: Type Checking
-                       ret = fcn->Handler( Script, NArguments, Arguments );
-                       bFound = 1;
-               }
-       }
-       
-       // Not found?
-       if(!bFound)
-       {
-               fprintf(stderr, "Undefined reference to function '%s' (ns='%s')\n",
-                       Function, Namespace->Name);
-               return ERRPTR;
-       }
-       
-       return ret;
-}
-
-/**
- * \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,
-       tSpiderNamespace *Namespace, const char *ClassName,
-       int NArguments, tSpiderValue **Arguments)
-{
-        int    bFound = 0;     // Used to keep nesting levels down
-       tSpiderValue    *ret = ERRPTR;
-       tSpiderObjectDef        *class;
-       
-       // 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
-       
-       // Didn't find it in script?
-       if(!bFound)
-       {
-               class = NULL;   // Just to allow the below code to be neat
-               
-               //if( !Namespace )
-               //      Namespace = &Script->Variant->RootNamespace;
-               
-               // Second: Scan current namespace
-               if( !class && Namespace )
-               {
-                       for( class = Namespace->Classes; class; class = class->Next )
-                       {
-                               if( strcmp( class->Name, ClassName ) == 0 )
-                                       break;
-                       }
-               }
-               
-               #if 0
-               // Third: Search the variant's global exports
-               if( !class )
-               {
-                       for( class = Script->Variant->Classes; class; class = fcn->Next )
-                       {
-                               if( strcmp( class->Name, Function ) == 0 )
-                                       break;
-                       }
-               }
-               #endif
-               
-               #if 0
-               // Fourth: Search language exports
-               if( !class )
-               {
-                       for( class = gpExports_First; class; class = fcn->Next )
-                       {
-                               if( strcmp( class->Name, ClassName ) == 0 )
-                                       break;
-                       }
-               }
-               #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;
-                       bFound = 1;
-               }
-       }
-       
-       // Not found?
-       if(!bFound)
-       {
-               fprintf(stderr, "Undefined reference to class '%s'\n", ClassName);
-               return ERRPTR;
-       }
-       
-       return ret;
-}
-
-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 7a94dc4..0000000
+++ /dev/null
@@ -1,1062 +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 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);
-// - 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 ===
-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`)
-               {
-                       tSpiderNamespace        *ns = Block->CurNamespace;
-                       tSpiderValue    *params[Node->FunctionCall.NumArgs];
-                       i = 0;
-                       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 ++;
-                       }
-                       
-                       if( !ns )       ns = Block->BaseNamespace;
-                       
-                       // Call the function
-                       if( Node->Type == NODETYPE_CREATEOBJECT )
-                       {
-                               ret = SpiderScript_CreateObject(Block->Script,
-                                       ns,
-                                       Node->FunctionCall.Name,
-                                       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,
-                                       ns, Node->FunctionCall.Name,
-                                       Node->FunctionCall.NumArgs, params
-                                       );
-                       }
-
-                       
-                       // 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;
-               
-               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;
-               if( !tmpobj || tmpobj->Type != SS_DATATYPE_OBJECT )
-               {
-                       AST_RuntimeError(Node->Scope.Element, "Unable to dereference a non-object");
-                       ret = ERRPTR;
-                       break ;
-               }
-               
-               for( i = 0; i < tmpobj->Object->Type->NAttributes; i ++ )
-               {
-                       if( strcmp(Node->Scope.Name, tmpobj->Object->Type->AttributeDefs[i].Name) == 0 )
-                       {
-                               ret = tmpobj->Object->Attributes[i];
-                               SpiderScript_ReferenceValue(ret);
-                               break;
-                       }
-               }
-               if( i == tmpobj->Object->Type->NAttributes )
-               {
-                       AST_RuntimeError(Node->Scope.Element, "Unknown attribute '%s' of class '%s'",
-                               Node->Scope.Name, tmpobj->Object->Type->Name);
-                       ret = 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( !op1 || op1->Type != SS_DATATYPE_ARRAY )
-               {
-                       // TODO: Implement "operator []" on objects
-                       AST_RuntimeError(Node, "Indexing non-array");
-                       ret = ERRPTR;
-                       break;
-               }
-               
-               if( (!op2 || op2->Type != SS_DATATYPE_INTEGER) && !Block->Script->Variant->bImplicitCasts ) {
-                       AST_RuntimeError(Node, "Array index is not an integer");
-                       ret = ERRPTR;
-                       break;
-               }
-               
-               if( !op2 || op2->Type != SS_DATATYPE_INTEGER )
-               {
-                       tmpobj = SpiderScript_CastValueTo(SS_DATATYPE_INTEGER, op2);
-                       SpiderScript_DereferenceValue(op2);
-                       op2 = tmpobj;
-               }
-               
-               if( op2->Integer >= op1->Array.Length ) {
-                       AST_RuntimeError(Node, "Array index out of bounds %i >= %i",
-                               op2->Integer, op1->Array.Length);
-                       ret = ERRPTR;
-                       break;
-               }
-               
-               ret = op1->Array.Items[ op2->Integer ];
-               SpiderScript_ReferenceValue(ret);
-               
-               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;
-       
-       // --- 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_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;
-}
-
-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_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_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;
-}
-
-/**
- * \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);
-}
-
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 4673bd2..0000000
+++ /dev/null
@@ -1,806 +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 {
-                       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:
-               printf("*%p", Ent->Reference);
-               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));
-       }
-
-       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;
-}
-
-#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);
-       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();
-                       // NOTE: Evil, all jumps are off by -1, so fix that
-                       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;
-                       }
-                       DEBUG_F("[Deref "); PRINT_STACKVAL(local_vars[slot]); DEBUG_F("] ");
-                       Bytecode_int_DerefStackValue( &local_vars[slot] );
-                       GET_STACKVAL(local_vars[slot]);
-                       PRINT_STACKVAL(local_vars[slot]);
-                       DEBUG_F("\n");
-                       } 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_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;
-                       }
-                       switch(val2.Type * 100 + val1.Type )
-                       {
-                       case SS_DATATYPE_INTEGER*100 + SS_DATATYPE_REAL:
-                               val2.Integer = val1.Real;
-                               PUT_STACKVAL(val2);
-                               break;
-                       case SS_DATATYPE_REAL*100 + SS_DATATYPE_INTEGER:
-                               val2.Real = val1.Integer;
-                               PUT_STACKVAL(val2);
-                               break;
-                       default: {
-                               pval1 = Bytecode_int_GetSpiderValue(&val1, &tmpVal1);
-                               pval2 = SpiderScript_CastValueTo(val2.Type, pval1);
-                               if(pval1 != &tmpVal1)   SpiderScript_DereferenceValue(pval1);
-                               Bytecode_int_SetSpiderValue(&val2, pval2);
-                               SpiderScript_DereferenceValue(pval2);
-                               PUT_STACKVAL(val2);
-                               } break;
-                       }
-                       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;
-
-                       STATE_HDR();
-                       DEBUG_F("UNIOP %i\n", ast_op);
-
-                       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_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
-
-                       #define PERFORM_NUM_OP(_type, _field) if(val1.Type == _type && val1.Type == val2.Type) { \
-                               switch(op->Operation) { \
-                               case BC_OP_ADD: val1._field = val1._field + val2._field;        break; \
-                               case BC_OP_SUBTRACT:    val1._field = val1._field - val2._field;        break; \
-                               case BC_OP_MULTIPLY:    val1._field = val1._field * val2._field;        break; \
-                               case BC_OP_DIVIDE:      val1._field = val1._field / val2._field;        break; \
-                               case BC_OP_EQUALS:      val1._field = val1._field == val2._field;       break; \
-                               case BC_OP_LESSTHAN:    val1._field = val1._field < val2._field;        break; \
-                               case BC_OP_LESSTHANOREQUAL:     val1._field = val1._field <= val2._field;       break; \
-                               case BC_OP_GREATERTHAN: val1._field = val1._field > val2._field;        break; \
-                               case BC_OP_GREATERTHANOREQUAL:  val1._field = val1._field >= val2._field;       break; \
-                               \
-                               case BC_OP_BITAND:      val1._field = (int64_t)val1._field & (int64_t)val2._field;      break; \
-                               case BC_OP_BITOR:       val1._field = (int64_t)val1._field | (int64_t)val2._field;      break; \
-                               case BC_OP_BITXOR:      val1._field = (int64_t)val1._field ^ (int64_t)val2._field;      break; \
-                               case BC_OP_MODULO:      val1._field = (int64_t)val1._field % (int64_t)val2._field;      break; \
-                               default:        AST_RuntimeError(NULL, "Invalid operation on datatype %i", _type); nextop = NULL; break;\
-                               }\
-                               PUT_STACKVAL(val1);\
-                               break;\
-                       }
-
-                       PERFORM_NUM_OP(SS_DATATYPE_INTEGER, Integer);
-                       PERFORM_NUM_OP(SS_DATATYPE_REAL, Real);
-               
-                       pval1 = Bytecode_int_GetSpiderValue(&val1, &tmpVal1);
-                       pval2 = Bytecode_int_GetSpiderValue(&val2, &tmpVal2);
-                       Bytecode_int_DerefStackValue(&val1);
-                       Bytecode_int_DerefStackValue(&val2);
-
-                       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: {
-                       tScript_Function        *fcn = NULL;
-                       const char      *name = OP_STRING(op);
-                        int    arg_count = OP_INDX(op);
-                       
-                       STATE_HDR();
-                       DEBUG_F("CALL FUNCTION %s %i args\n", name, arg_count);
-
-                       if( op->Operation == BC_OP_CALLFUNCTION )
-                       {
-                               // 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
-                       {
-                               tSpiderNamespace        *ns = NULL;
-                               tSpiderValue    *args[arg_count];
-                               tSpiderValue    *rv;
-                               // Read arguments
-                               for( i = arg_count; i --; )
-                               {
-                                       GET_STACKVAL(val1);
-                                       args[i] = Bytecode_int_GetSpiderValue(&val1, NULL);
-                                       Bytecode_int_DerefStackValue(&val1);
-                               }
-                               
-                               // Resolve namespace into pointer
-                               if( op->Operation != BC_OP_CALLMETHOD ) {
-                                       if( name[0] == BC_NS_SEPARATOR ) {
-                                               name ++;
-                                               ns = Bytecode_int_ResolveNamespace(&Script->Variant->RootNamespace, name, &name);
-                                       }
-                                       else {
-                                               // TODO: Support multiple default namespaces
-                                               ns = Bytecode_int_ResolveNamespace(default_namespace, name, &name);
-                                       }
-                               }
-                               
-                               // Call the function etc.
-                               if( op->Operation == BC_OP_CALLFUNCTION )
-                               {
-                                       rv = SpiderScript_ExecuteFunction(Script, ns, name, arg_count, args);
-                               }
-                               else if( op->Operation == BC_OP_CREATEOBJ )
-                               {
-                                       rv = SpiderScript_CreateObject(Script, ns, name, 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->Type == SS_DATATYPE_OBJECT)
-                                               obj = val1.Reference->Object;
-                                       else {
-                                               // Error
-                                               AST_RuntimeError(NULL, "OP_CALLMETHOD on non object");
-                                               nextop = NULL;
-                                               break;
-                                       }
-                                       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");
-                                       nextop = NULL;
-                                       break;
-                               }
-                               // 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);
-                       }
-                       } 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 )
-               {
-                       Bytecode_int_DerefStackValue(&local_vars[i]);
-               }
-       }
-       
-       // - Restore stack
-//     printf("TODO: Roll back stack\n");
-       if( Stack->Entries[Stack->EntryCount - 1].Type == ET_FUNCTION_START )
-               Stack->EntryCount --;
-       else
-       {
-               GET_STACKVAL(val1);
-               while( Stack->EntryCount && Stack->Entries[ --Stack->EntryCount ].Type != ET_FUNCTION_START )
-               {
-                       Bytecode_int_DerefStackValue( &Stack->Entries[Stack->EntryCount] );
-               }
-               PUT_STACKVAL(val1);
-       }
-       
-
-       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 4c73eb9..0000000
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Acess2 - SpiderScript
- * - Script Exports (Lang. Namespace)
- */
-#include <string.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <spiderscript.h>
-
-// === PROTOTYPES ===
-tSpiderValue   *Exports_Lang_Struct(tSpiderScript *Script, int NArgs, tSpiderValue **Args);
-
-// === GLOBALS ===
-tSpiderFunction        gExports_Lang_Struct = {NULL,"Lang.Struct", Exports_Lang_Struct, {SS_DATATYPE_STRING,-1}};
-tSpiderFunction        *gpExports_First = &gExports_Lang_Struct;
-
-// === CODE ===
-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 2d16bcf..0000000
+++ /dev/null
@@ -1,468 +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 '!':
-               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 bd29280..0000000
+++ /dev/null
@@ -1,145 +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;
-       printf("Total Size: ");
-       fflush(stdout);
-       size = AST_WriteScript(NULL, Script);
-       printf("0x%x bytes\n", (unsigned)size);
-       
-       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 e6d9694..0000000
+++ /dev/null
@@ -1,1082 +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      *Parse_DoBlockLine(tParser *Parser);
-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, ...);
-
-#define SyntaxAssert(_parser, _have, _want) 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 NULL; \
-       } \
-}while(0)
-
-#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;
-       
-       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(GetToken(Parser))
-                       {
-                       // Define a function (pass on to the other function definition code)
-                       case TOK_IDENT:
-                               PutBack(Parser);
-                               if( Parse_FunctionDefinition(Script, Parser, type) == NULL )
-                                       longjmp(Parser->JmpTarget, -1);
-                               break ;
-                       // Define a variable
-                       case TOK_VARIABLE:
-                               node = Parse_GetVarDef(Parser, type);
-                               if(!node)       longjmp(Parser->JmpTarget, -1);
-                               
-                               AST_AppendNode( mainCode, node );
-                               // Can't use SyntaxAssert because that returns
-                               if(GetToken(Parser) != TOK_SEMICOLON) {
-                                       SyntaxError(Parser, 1, "Unexpected %s, expected TOK_SEMICOLON",
-                                               csaTOKEN_NAMES[Parser->Token]);
-                                       longjmp(Parser->JmpTarget, -1);
-                               }
-                               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);
-                       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);
-
-       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       *ret;
-       
-       // Check if we are being called for a one-liner
-       if( GetToken(Parser) != TOK_BRACE_OPEN ) {
-               PutBack(Parser);
-               return Parse_DoBlockLine(Parser);
-       }
-       
-       ret = AST_NewCodeBlock(Parser);
-       
-       while( LookAhead(Parser) != TOK_BRACE_CLOSE )
-       {
-               tAST_Node       *node = Parse_DoBlockLine(Parser);
-               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       *ret;
-       
-       //printf("Parse_DoBlockLine: Line %i\n", Parser->CurLine);
-       
-       switch(LookAhead(Parser))
-       {
-       // New block
-       case TOK_BRACE_OPEN:
-               return Parse_DoCodeBlock(Parser);
-       
-       // 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);
-               if( LookAhead(Parser) == TOK_RWD_ELSE ) {
-                       GetToken(Parser);
-                       false = Parse_DoCodeBlock(Parser);
-               }
-               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);
-               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);
-               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);
-               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);
-                       
-                       SyntaxAssert(Parser, GetToken(Parser), TOK_VARIABLE);
-                       
-                       ret = Parse_GetVarDef(Parser, type);
-               }
-               break;
-       
-       // Default
-       default:
-               //printf("exp0\n");
-               ret = Parse_DoExpr0(Parser);
-               break;
-       }
-       
-       SyntaxAssert(Parser, GetToken(Parser), TOK_SEMICOLON );
-       return ret;
-}
-
-/**
- * \brief Get a variable definition
- */
-tAST_Node *Parse_GetVarDef(tParser *Parser, int Type)
-{
-       char    name[Parser->TokenLen];
-       tAST_Node       *ret;
-       
-       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
-       while( LookAhead(Parser) == TOK_SQUARE_OPEN )
-       {
-               tAST_Node *node;
-               GetToken(Parser);
-               node = Parse_DoExpr0(Parser);
-               if(!node) {
-                       AST_FreeNode(ret);
-                       return NULL;
-               }
-               AST_AppendNode(ret, node);
-               SyntaxAssert(Parser, GetToken(Parser), TOK_SQUARE_CLOSE);
-       }
-       
-       if( LookAhead(Parser) == TOK_ASSIGN )
-       {
-               GetToken(Parser);
-               ret->DefVar.InitialValue = Parse_DoExpr0(Parser);
-               if(!ret->DefVar.InitialValue) {
-                       AST_FreeNode(ret);
-                       return NULL;
-               }
-       }
-       
-       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_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_NewNop(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;
-       }
-}
-
diff --git a/Usermode/Libraries/libspiderscript.so_src/tokens.h b/Usermode/Libraries/libspiderscript.so_src/tokens.h
deleted file mode 100644 (file)
index 44176b0..0000000
+++ /dev/null
@@ -1,200 +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;
-}      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_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_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 f72e290..0000000
+++ /dev/null
@@ -1,461 +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, int Operation, int bCanCast, tSpiderValue *Right);
-tSpiderValue   *SpiderScript_int_DoOpInt(tSpiderValue *Left, int Operation, int bCanCast, tSpiderValue *Right);
-tSpiderValue   *SpiderScript_int_DoOpReal(tSpiderValue *Left, int Operation, int bCanCast, tSpiderValue *Right);
-tSpiderValue   *SpiderScript_int_DoOpString(tSpiderValue *Left, int Operation, int bCanCast, tSpiderValue *Right);
-
-
-// === CODE ===
-/**
- * \brief Dereference a created object
- */
-void SpiderScript_DereferenceValue(tSpiderValue *Object)
-{
-       if(!Object || Object == ERRPTR) return ;
-       Object->ReferenceCount --;
-       if(Object->Type == SS_DATATYPE_OBJECT) {
-       }
-       if( Object->ReferenceCount == 0 )
-       {
-               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;
-}
-
-/**
- * \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, int Operation, int bCanCast, tSpiderValue *Right)
-{
-       switch(Left->Type)
-       {
-       case SS_DATATYPE_INTEGER:
-               return SpiderScript_int_DoOpInt(Left, Operation, bCanCast, Right);
-       }
-       return NULL;
-}
-
-tSpiderValue *SpiderScript_int_DoOpInt(tSpiderValue *Left, int Operation, int bCanCast, tSpiderValue *Right)
-{
-       tSpiderValue    *oldright = Right;
-       tSpiderValue    *ret = NULL;
-        int64_t        rv;
-
-       // Casting
-       if(Right && Right->Type != SS_DATATYPE_INTEGER) {
-               if(!bCanCast)   return ERRPTR;
-               Right = SpiderScript_CastValueTo(Right, SS_DATATYPE_INTEGER);
-       }
-
-       // 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;
-       }
-
-       // 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);
-       }
-}
-
diff --git a/Usermode/include/spiderscript.h b/Usermode/include/spiderscript.h
deleted file mode 100644 (file)
index e1dc507..0000000
+++ /dev/null
@@ -1,321 +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
-        */
-       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
-};
-
-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);
-       
-       tSpiderFunction *Methods;       //!< Method Definitions (linked list)
-       
-        int    NAttributes;    //!< Number of attributes
-       
-       //! Attribute definitions
-       struct {
-               const char      *Name;  //!< Attribute Name
-                int    bReadOnly;      //!< Allow writes to the attribute?
-       }       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 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,
-       tSpiderNamespace *Namespace, const char *Function,
-       int NArguments, tSpiderValue **Arguments
-       );
-/**
- * \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,
-       tSpiderNamespace *Namespace, const char *ClassName,
-       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_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

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