More work on SpiderScript
authorJohn Hodge <[email protected]>
Wed, 25 Aug 2010 05:11:02 +0000 (13:11 +0800)
committerJohn Hodge <[email protected]>
Wed, 25 Aug 2010 05:11:02 +0000 (13:11 +0800)
- Opaque Data Structures and Objects
- Started on control structures

Also fixing some more Yield() calls

Kernel/arch/x86/vm8086.c
Kernel/time.c
Usermode/Libraries/libspiderscript.so_src/exec_ast.c
Usermode/Libraries/libspiderscript.so_src/lex.c
Usermode/Libraries/libspiderscript.so_src/parse.c
Usermode/Libraries/libspiderscript.so_src/tokens.h
Usermode/include/spiderscript.h

index 469ab43..a1c75e2 100644 (file)
@@ -153,17 +153,14 @@ void VM8086_GPF(tRegs *Regs)
                //Log_Log("VM8086", "gpVM8086_State = %p, gVM8086_CallingThread = %i",
                //      gpVM8086_State, gVM8086_CallingThread);
                if( gpVM8086_State ) {
-                        int    ret;
                        gpVM8086_State->AX = Regs->eax; gpVM8086_State->CX = Regs->ecx;
                        gpVM8086_State->DX = Regs->edx; gpVM8086_State->BX = Regs->ebx;
                        gpVM8086_State->BP = Regs->ebp;
                        gpVM8086_State->SI = Regs->esi; gpVM8086_State->DI = Regs->edi;
                        gpVM8086_State->DS = Regs->ds;  gpVM8086_State->ES = Regs->es;
                        gpVM8086_State = NULL;
-                       // Ensure the caller wakes
-                       while( (ret = Threads_WakeTID(gVM8086_CallingThread)) == -EALREADY) {
-                               Threads_Yield();
-                       }
+                       // Wake the caller
+                       Threads_WakeTID(gVM8086_CallingThread);
                }
                
                //Log_Log("VM8086", "Waiting for something to do");
index 30d11dc..dcc4f79 100644 (file)
@@ -24,7 +24,7 @@ void  Timer_CallTimers(void);
 Uint64 giTicks = 0;
 Sint64 giTimestamp = 0;
 Uint64 giPartMiliseconds = 0;
-tTimer gTimers[NUM_TIMERS];
+tTimer gTimers[NUM_TIMERS];    // TODO: Replace by a ring-list timer
 
 // === CODE ===
 /**
@@ -45,9 +45,7 @@ void Timer_CallTimers()
        void    (*callback)(void *);
        void    *arg;
        
-       for(i = 0;
-               i < NUM_TIMERS;
-               i ++)
+       for(i = 0; i < NUM_TIMERS; i ++)
        {
                if(gTimers[i].Callback == NULL) continue;
                if(giTimestamp < gTimers[i].FiresAfter) continue;
@@ -97,7 +95,7 @@ void Time_RemoveTimer(int ID)
 void Time_Delay(int Delay)
 {
        Sint64  dest = giTimestamp + Delay;
-       while(dest < giTimestamp)       Threads_Yield();
+       while(dest > giTimestamp)       Threads_Yield();
 }
 
 // === EXPORTS ===
index 2bbfd1c..0421686 100644 (file)
@@ -29,7 +29,20 @@ void Object_Dereference(tSpiderValue *Object)
 {
        if(!Object)     return ;
        Object->ReferenceCount --;
-       if( Object->ReferenceCount == 0 )       free(Object);
+       if( Object->ReferenceCount == 0 ) {
+               switch( (enum eSpiderScript_DataTypes) Object->Type )
+               {
+               case SS_DATATYPE_OBJECT:
+                       Object->Object->Type->Destructor( Object->Object );
+                       break;
+               case SS_DATATYPE_OPAQUE:
+                       Object->Opaque.Destroy( Object->Opaque.Data );
+                       break;
+               default:
+                       break;
+               }
+               free(Object);
+       }
 }
 
 void Object_Reference(tSpiderValue *Object)
@@ -103,6 +116,8 @@ tSpiderValue *Object_StringConcat(tSpiderValue *Str1, tSpiderValue *Str2)
 
 /**
  * \brief Cast one object to another
+ * \brief Type Destination type
+ * \brief Source       Input data
  */
 tSpiderValue *Object_CastTo(int Type, tSpiderValue *Source)
 {
@@ -113,11 +128,12 @@ tSpiderValue *Object_CastTo(int Type, tSpiderValue *Source)
                return Source;
        }
        
-       switch(Type)
+       switch( (enum eSpiderScript_DataTypes)Type )
        {
        case SS_DATATYPE_UNDEF:
        case SS_DATATYPE_NULL:
        case SS_DATATYPE_ARRAY:
+       case SS_DATATYPE_OPAQUE:
                fprintf(stderr, "Object_CastTo - Invalid cast to %i\n", Type);
                return ERRPTR;
        
@@ -150,7 +166,7 @@ tSpiderValue *Object_CastTo(int Type, tSpiderValue *Source)
  */
 int Object_IsTrue(tSpiderValue *Value)
 {
-       switch(Value->Type)
+       switch( (enum eSpiderScript_DataTypes)Value->Type )
        {
        case SS_DATATYPE_UNDEF:
        case SS_DATATYPE_NULL:
@@ -168,8 +184,14 @@ int Object_IsTrue(tSpiderValue *Value)
        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:
+               fprintf(stderr, "Spiderscript internal error: Unknown type %i in Object_IsTrue\n", Value->Type);
+               return 0;
        }
        return 0;
 }
@@ -180,7 +202,7 @@ int Object_IsTrue(tSpiderValue *Value)
 tSpiderValue *AST_ExecuteNode(tAST_BlockState *Block, tAST_Node *Node)
 {
        tAST_Node       *node;
-       tSpiderValue    *ret, *tmpobj;
+       tSpiderValue    *ret = NULL, *tmpobj;
        tSpiderValue    *op1, *op2;     // Binary operations
         int    cmp;    // Used in comparisons
        
@@ -403,12 +425,20 @@ tSpiderValue *AST_ExecuteNode(tAST_BlockState *Block, tAST_Node *Node)
                                        cmp = -1;
                        }
                        break;
+               default:
+                       fprintf(stderr, "SpiderScript internal error: TODO: Comparison of type %i\n", op1->Type);
+                       ret = ERRPTR;
+                       break;
                }
                
                // Free intermediate objects
                Object_Dereference(op1);
                Object_Dereference(op2);
                
+               // Error check
+               if( ret == ERRPTR )
+                       break;
+               
                // Create return
                switch(Node->Type)
                {
@@ -481,6 +511,7 @@ tSpiderValue *AST_ExecuteNode(tAST_BlockState *Block, tAST_Node *Node)
                                break;
                        }
                        break;
+               // Integer Operations
                case SS_DATATYPE_INTEGER:
                        switch(Node->Type)
                        {
@@ -498,11 +529,27 @@ tSpiderValue *AST_ExecuteNode(tAST_BlockState *Block, tAST_Node *Node)
                                ret = Object_CreateInteger( (op1->Integer << op2->Integer) | (op1->Integer >> (64-op2->Integer)) );
                                break;
                        default:
-                               fprintf(stderr, "SpiderScript internal error: Exec,BinOP,Integer unknown op %i", Node->Type);
+                               fprintf(stderr, "SpiderScript internal error: Exec,BinOP,Integer unknown op %i\n", Node->Type);
                                ret = ERRPTR;
                                break;
                        }
                        break;
+               
+               // Real Numbers
+               case SS_DATATYPE_REAL:
+                       switch(Node->Type)
+                       {
+                       default:
+                               fprintf(stderr, "SpiderScript internal error: Exec,BinOP,Real unknown op %i\n", Node->Type);
+                               ret = ERRPTR;
+                               break;
+                       }
+                       break;
+               
+               default:
+                       fprintf(stderr, "SpiderScript error: Invalid operation (%i) on type (%i)\n", Node->Type, op1->Type);
+                       ret = ERRPTR;
+                       break;
                }
                
                // Free intermediate objects
index 25a7aa7..88437aa 100644 (file)
@@ -25,9 +25,19 @@ const struct {
        const char      *Name;
 } csaReservedWords[] = {
        {TOK_RWD_FUNCTION, "function"},
+       
        {TOK_RWD_RETURN, "return"},
+       {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_VOID, "void"},
        {TOK_RWD_OBJECT, "Object"},
+       {TOK_RWD_OPAQUE, "Opaque"},
        {TOK_RWD_INTEGER, "Integer"},
        {TOK_RWD_REAL, "Real"},
        {TOK_RWD_STRING, "String"}
index 31dabad..5622123 100644 (file)
@@ -190,11 +190,12 @@ tAST_Node *Parse_DoBlockLine(tParser *Parser)
                ret = AST_NewUniOp(NODETYPE_RETURN, Parse_DoExpr0(Parser));
                break;
        
+       // Control Statements
+       //case TOK_RWD_IF:
+       //      break;
+       
        // Define Variables
-       case TOK_RWD_OBJECT:
-       case TOK_RWD_STRING:
-       case TOK_RWD_REAL:
-       case TOK_RWD_INTEGER:
+       case TOKEN_GROUP_TYPES:
                {
                         int    type;
                        
index 9ecb720..6068295 100644 (file)
@@ -45,10 +45,19 @@ enum eTokens
        
        TOK_RWD_FUNCTION,
        TOK_RWD_NAMESPACE,
+       
+       TOK_RWD_NEW,
        TOK_RWD_RETURN,
        
+       TOK_RWD_IF,
+       TOK_RWD_ELSE,
+       TOK_RWD_DO,
+       TOK_RWD_WHILE,
+       TOK_RWD_FOR,
+       
        TOK_RWD_VOID,
        TOK_RWD_OBJECT,
+       TOK_RWD_OPAQUE,
        TOK_RWD_STRING,
        TOK_RWD_INTEGER,
        TOK_RWD_REAL,
@@ -81,14 +90,16 @@ enum eTokens
 
 #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_INTEGER, TOK_RWD_STRING or 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;\
@@ -109,10 +120,19 @@ const char * const csaTOKEN_NAMES[] = {
        
        "TOK_RWD_FUNCTION",
        "TOK_RWD_NAMESPACE",
+       
+       "TOK_RWD_NEW",
        "TOK_RWD_RETURN",
        
+       "TOK_RWD_IF",
+       "TOK_RWD_ELSE",
+       "TOK_RWD_DO",
+       "TOK_RWD_WHILE",
+       "TOK_RWD_FOR",
+       
        "TOK_RWD_VOID",
        "TOK_RWD_OBJECT",
+       "TOK_RWD_OPAUQE",
        "TOK_RWD_STRING",
        "TOK_RWD_INTEGER",
        "TOK_RWD_REAL",
index 9d15d35..c0d6d45 100644 (file)
@@ -13,9 +13,6 @@
  */
 typedef struct sSpiderScript   tSpiderScript;
 
-/**
- * \brief Variant type
- */
 typedef struct sSpiderVariant  tSpiderVariant;
 typedef struct sSpiderFunction tSpiderFunction;
 typedef struct sSpiderValue    tSpiderValue;
@@ -31,7 +28,8 @@ enum eSpiderScript_DataTypes
        SS_DATATYPE_UNDEF,      //!< Undefined
        SS_DATATYPE_NULL,       //!< NULL (Probably will never be used)
        SS_DATATYPE_DYNAMIC,    //!< Dynamically typed variable (will this be used?)
-       SS_DATATYPE_OBJECT,     //!< Opaque object reference
+       SS_DATATYPE_OPAQUE,     //!< Opaque data type
+       SS_DATATYPE_OBJECT,     //!< Object reference
        SS_DATATYPE_ARRAY,      //!< Array
        SS_DATATYPE_INTEGER,    //!< Integer (64-bits)
        SS_DATATYPE_REAL,       //!< Real Number (double)
@@ -46,7 +44,7 @@ struct sSpiderVariant
 {
        const char      *Name;  // Just for debug
        
-        int    bDyamicTyped;
+        int    bDyamicTyped;   //!< Use static typing
        
         int    NFunctions;     //!< Number of functions
        tSpiderFunction *Functions;     //!< Functions
@@ -60,7 +58,7 @@ struct sSpiderVariant
  */
 struct sSpiderValue
 {
-        int    Type;   //!< Variable type
+       enum eSpiderScript_DataTypes    Type;   //!< Variable type
         int    ReferenceCount; //!< Reference count
        
        union {
@@ -81,6 +79,17 @@ struct sSpiderValue
                        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;
        };
 };
@@ -92,6 +101,13 @@ struct sSpiderValue
  */
 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

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