//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");
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 ===
/**
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;
void Time_Delay(int Delay)
{
Sint64 dest = giTimestamp + Delay;
- while(dest < giTimestamp) Threads_Yield();
+ while(dest > giTimestamp) Threads_Yield();
}
// === EXPORTS ===
{
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)
/**
* \brief Cast one object to another
+ * \brief Type Destination type
+ * \brief Source Input data
*/
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;
*/
int Object_IsTrue(tSpiderValue *Value)
{
- switch(Value->Type)
+ switch( (enum eSpiderScript_DataTypes)Value->Type )
{
case SS_DATATYPE_UNDEF:
case SS_DATATYPE_NULL:
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;
}
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
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)
{
break;
}
break;
+ // Integer Operations
case SS_DATATYPE_INTEGER:
switch(Node->Type)
{
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
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"}
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;
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,
#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;\
"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",
*/
typedef struct sSpiderScript tSpiderScript;
-/**
- * \brief Variant type
- */
typedef struct sSpiderVariant tSpiderVariant;
typedef struct sSpiderFunction tSpiderFunction;
typedef struct sSpiderValue tSpiderValue;
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)
{
const char *Name; // Just for debug
- int bDyamicTyped;
+ int bDyamicTyped; //!< Use static typing
int NFunctions; //!< Number of functions
tSpiderFunction *Functions; //!< Functions
*/
struct sSpiderValue
{
- int Type; //!< Variable type
+ enum eSpiderScript_DataTypes Type; //!< Variable type
int ReferenceCount; //!< Reference count
union {
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;
};
};
*/
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