case NODETYPE_REAL:
WRITE_REAL(Buffer, Offset, Node->Constant.Real);
break;
+ case NODETYPE_NULL:
+ break;
//default:
// fprintf(stderr, "AST_WriteNode: Unknown node type %i\n", Node->Type);
// Node types with no children
case NODETYPE_NOP: break;
+ case NODETYPE_NULL: break;
case NODETYPE_VARIABLE: break;
case NODETYPE_CONSTANT: break;
case NODETYPE_BREAK:
return ret;
}
+/**
+ * \brief Return a null value
+ */
+tAST_Node *AST_NewNull(tParser *Parser)
+{
+ tAST_Node *ret = AST_int_AllocateNode(Parser, NODETYPE_NULL, 0);
+
+ return ret;
+}
+
/**
* \brief Create a new variable reference node
*/
NODETYPE_STRING, //!< String Constant
NODETYPE_INTEGER, //!< Integer Constant
NODETYPE_REAL, //!< Real Constant
+ NODETYPE_NULL,
- // 7
+ // 8
NODETYPE_DEFVAR, //!< Define a variable (Variable)
NODETYPE_SCOPE, //!< Dereference a Namespace/Class static
NODETYPE_ELEMENT, //!< Reference a class attribute
NODETYPE_CAST, //!< Cast a value to another (Uniop)
- // 11
+ // 12
NODETYPE_RETURN, //!< Return from a function (reserved word)
NODETYPE_BREAK, //!< Break out of a loop
NODETYPE_CONTINUE, //!< Next loop iteration
NODETYPE_METHODCALL, //!< Call a class method
NODETYPE_CREATEOBJECT, //!< Create an object
- // 20
+ // 21
NODETYPE_IF, //!< Conditional
NODETYPE_LOOP, //!< Looping Construct
- // 22
+ // 23
NODETYPE_INDEX, //!< Index into an array
- // 23
+ // 24
NODETYPE_LOGICALNOT, //!< Logical NOT operator
NODETYPE_LOGICALAND, //!< Logical AND operator
NODETYPE_LOGICALOR, //!< Logical OR operator
extern tAST_Node *AST_NewString(tParser *Parser, const char *String, int Length);
extern tAST_Node *AST_NewInteger(tParser *Parser, int64_t Value);
extern tAST_Node *AST_NewReal(tParser *Parser, double Value);
+extern tAST_Node *AST_NewNull(tParser *Parser);
+
extern tAST_Node *AST_NewVariable(tParser *Parser, const char *Name);
extern tAST_Node *AST_NewDefineVar(tParser *Parser, int Type, const char *Name);
extern tAST_Node *AST_NewConstant(tParser *Parser, const char *Name);
int BC_Variable_Define(tAST_BlockInfo *Block, int Type, const char *Name);
int BC_Variable_SetValue(tAST_BlockInfo *Block, tAST_Node *VarNode);
int BC_Variable_GetValue(tAST_BlockInfo *Block, tAST_Node *VarNode);
+void BC_Variable_Clear(tAST_BlockInfo *Block);
// - Errors
void AST_RuntimeMessage(tAST_Node *Node, const char *Type, const char *Format, ...);
void AST_RuntimeError(tAST_Node *Node, const char *Format, ...);
{
tBC_Function *ret;
tAST_BlockInfo bi = {0};
+ int i;
// TODO: Return BCFcn instead?
if(Fcn->BCFcn) return Fcn->BCFcn;
if(!ret) return NULL;
bi.Handle = ret;
+
+ // Parse arguments
+ for( i = 0; i < Fcn->ArgumentCount; i ++ )
+ {
+ BC_Variable_Define(&bi, Fcn->Arguments[i].Type, Fcn->Arguments[i].Name);
+ }
+
if( AST_ConvertNode(&bi, Fcn->ASTFcn, 0) )
{
AST_RuntimeError(Fcn->ASTFcn, "Error in converting function");
Bytecode_DeleteFunction(ret);
+ BC_Variable_Clear(&bi);
return NULL;
}
+ BC_Variable_Clear(&bi);
+
Bytecode_AppendConstInt(ret, 0); // TODO: NULL
Bytecode_AppendReturn(ret);
node;
node = node->NextSibling )
{
- ret = AST_ConvertNode(Block, node, 0);
+ ret = AST_ConvertNode(&blockInfo, node, 0);
if(ret) return ret;
if( blockInfo.StackDepth != 0 ) {
AST_RuntimeError(node, "Stack not reset at end of node");
}
}
+
+ BC_Variable_Clear(&blockInfo);
}
Bytecode_AppendLeaveContext(Block->Handle); // Leave this context
break;
for( i = 0; i < Block->NamespaceDepth; i ++ )
newnamelen += strlen(Block->CurNamespaceStack[i]) + 1;
newnamelen += strlen(Node->FunctionCall.Name) + 1;
+// newnamelen += 1;
+
manglename = alloca(newnamelen);
- manglename[0] = 0;
+ newnamelen = 0;
for( i = 0; i < Block->NamespaceDepth; i ++ ) {
- int pos;
- strcat(manglename, Block->CurNamespaceStack[i]);
- pos = strlen(manglename);
- manglename[pos] = BC_NS_SEPARATOR;
- manglename[pos+1] = '\0';
+ strcpy(manglename+newnamelen, Block->CurNamespaceStack[i]);
+ newnamelen += strlen(Block->CurNamespaceStack[i]) + 1;
+ manglename[ newnamelen - 1 ] = BC_NS_SEPARATOR;
}
- strcat(manglename, Node->FunctionCall.Name);
+ strcpy(manglename + newnamelen, Node->FunctionCall.Name);
+ newnamelen += strlen(Node->FunctionCall.Name) + 1;
+// manglename[ newnamelen ] = '\0'; // Zero length terminator
Block->NamespaceDepth = 0;
// Push arguments to the stack
// Loop
case NODETYPE_LOOP: {
- int loop_start, loop_end;
+ int loop_start, loop_end, code_end;
int saved_break, saved_continue;
const char *saved_tag;
if(ret) return ret;
loop_start = Bytecode_AllocateLabel(Block->Handle);
+ code_end = Bytecode_AllocateLabel(Block->Handle);
loop_end = Bytecode_AllocateLabel(Block->Handle);
saved_break = Block->BreakTarget;
saved_continue = Block->ContinueTarget;
saved_tag = Block->Tag;
Block->BreakTarget = loop_end;
- Block->ContinueTarget = loop_end;
+ Block->ContinueTarget = code_end;
Block->Tag = Node->For.Tag;
Bytecode_SetLabel(Block->Handle, loop_start);
// Code
ret = AST_ConvertNode(Block, Node->For.Code, 0);
if(ret) return ret;
-
+
+ Bytecode_SetLabel(Block->Handle, code_end);
+
// Increment
ret = AST_ConvertNode(Block, Node->For.Increment, 0);
if(ret) return ret;
case NODETYPE_CONTINUE: {
tAST_BlockInfo *bi = Block;
if( Node->Variable.Name[0] ) {
- while(bi && strcmp(bi->Tag, Node->Variable.Name) == 0) bi = bi->Parent;
+ while(bi && (!bi->Tag || strcmp(bi->Tag, Node->Variable.Name) != 0))
+ bi = bi->Parent;
+ }
+ else {
+ while(bi && !bi->Tag)
+ bi = bi->Parent;
}
if( !bi ) return 1;
// TODO: Check if BreakTarget/ContinueTarget are valid
// TODO: Scan namespace for constant name
AST_RuntimeError(Node, "TODO - Runtime Constants");
Block->NamespaceDepth = 0;
- ret = -1;
- break;
+ return -1;
// Constant Values
case NODETYPE_STRING:
if(ret < 0) return -1;
CHECK_IF_NEEDED(1);
break;
-
+ case NODETYPE_NULL:
+ Bytecode_AppendConstNull(Block->Handle);
+ ret = _StackPush(Block, Node, SS_DATATYPE_UNDEF);
+ if(ret < 0) return -1;
+ CHECK_IF_NEEDED(1);
+ break;
+
// --- Operations ---
// Boolean Operations
case NODETYPE_LOGICALNOT: // Logical NOT (!)
}
if(var) break;
}
-
+
if( !var )
{
// if( Block->Script->Variant->bDyamicTyped && CreateType != SS_DATATYPE_UNDEF ) {
return 0;
}
+void BC_Variable_Clear(tAST_BlockInfo *Block)
+{
+ tAST_Variable *var;
+ for( var = Block->FirstVar; var; )
+ {
+ tAST_Variable *tv = var->Next;
+ free( var );
+ var = tv;
+ }
+ Block->FirstVar = NULL;
+}
+
#if 0
void AST_RuntimeMessage(tAST_Node *Node, const char *Type, const char *Format, ...)
{
int Operation;
char bUseInteger; // Used for serialisation
char bUseString; // Used for serialisation
+
+ void *CacheEnt; // Used to runtime cache function calls
+
union {
struct {
int Integer;
op->Content.StringInt.String[Length] = 0;
Bytecode_int_AppendOp(Handle, op);
}
+void Bytecode_AppendConstNull(tBC_Function *Handle)
+ DEF_BC_NONE(BC_OP_LOADNULL)
// --- Indexing / Scoping
void Bytecode_AppendElement(tBC_Function *Handle, const char *Name)
extern void Bytecode_AppendConstInt(tBC_Function *Handle, uint64_t Value);
extern void Bytecode_AppendConstReal(tBC_Function *Handle, double Value);
extern void Bytecode_AppendConstString(tBC_Function *Handle, const void *Data, size_t Length);
+extern void Bytecode_AppendConstNull(tBC_Function *Handle);
// > Scoping
extern void Bytecode_AppendElement(tBC_Function *Handle, const char *Name); // Obj->SubObj
extern void Bytecode_AppendSetElement(tBC_Function *Handle, const char *Name); // Set an object member
BC_OP_LOADINT, // = 10
BC_OP_LOADREAL,
BC_OP_LOADSTR,
+ BC_OP_LOADNULL,
- BC_OP_DUPSTACK, // = 13
+ BC_OP_DUPSTACK, // = 14
BC_OP_DELSTACK, //
BC_OP_CAST, //
- BC_OP_ELEMENT, // = 16
+ BC_OP_ELEMENT, // = 17
BC_OP_SETELEMENT,
BC_OP_INDEX,
BC_OP_SETINDEX,
- BC_OP_ENTERCONTEXT, // = 20
+ BC_OP_ENTERCONTEXT, // = 21
BC_OP_LEAVECONTEXT,
BC_OP_DEFINEVAR,
// Operations
- BC_OP_LOGICNOT, // 23
+ BC_OP_LOGICNOT, // 24
BC_OP_LOGICAND,
BC_OP_LOGICOR,
BC_OP_LOGICXOR,
- BC_OP_BITNOT, // 27
+ BC_OP_BITNOT, // 28
BC_OP_BITAND,
BC_OP_BITOR,
BC_OP_BITXOR,
- BC_OP_BITSHIFTLEFT, // 31
+ BC_OP_BITSHIFTLEFT, // 32
BC_OP_BITSHIFTRIGHT,
BC_OP_BITROTATELEFT,
- BC_OP_NEG, // 34
+ BC_OP_NEG, // 35
BC_OP_ADD,
BC_OP_SUBTRACT,
BC_OP_MULTIPLY,
BC_OP_DIVIDE,
BC_OP_MODULO,
- BC_OP_EQUALS, // 40
+ BC_OP_EQUALS, // 41
BC_OP_NOTEQUALS,
BC_OP_LESSTHAN,
BC_OP_LESSTHANOREQUAL,
#include <string.h>
#include <stdarg.h>
+#define BC_NS_SEPARATOR '@'
+
// === IMPORTS ===
extern tSpiderFunction *gpExports_First;
extern tSpiderValue *AST_ExecuteFunction(tSpiderScript *Script, tScript_Function *Fcn, int NArguments, tSpiderValue **Arguments);
void AST_RuntimeError(tAST_Node *Node, const char *Format, ...);
// === CODE ===
+void *SpiderScript_int_GetNamespace(tSpiderScript *Script, tSpiderNamespace *RootNamespace,
+ const char *BasePath, const char *ItemPath,
+ const char **ItemName
+ )
+{
+ int len;
+ const char *name;
+ const char *end;
+ int bTriedBase;
+
+ tSpiderNamespace *lastns, *ns;
+
+ // Prepend the base namespace
+ if( BasePath ) {
+ name = BasePath;
+ bTriedBase = 0;
+ }
+ else {
+ bTriedBase = 1;
+ name = ItemPath;
+ }
+
+ // Scan
+ lastns = RootNamespace;
+ do {
+ end = strchr(name, BC_NS_SEPARATOR);
+ if(!end) {
+ if( !bTriedBase )
+ len = strlen(name);
+ else
+ break;
+ }
+ else {
+ len = end - name;
+ }
+
+ // Check for this level
+ for( ns = lastns->FirstChild; ns; ns = ns->Next )
+ {
+ if( strncmp(name, ns->Name, len) == 0 && ns->Name[len] == 0 )
+ break ;
+ }
+
+ if(!ns) return NULL;
+
+ if(!end && !bTriedBase) {
+ end = ItemPath - 1; // -1 to counter (name = end + 1)
+ bTriedBase = 1;
+ }
+
+ lastns = ns;
+ name = end + 1;
+ } while( end );
+
+ *ItemName = name;
+
+ return lastns;
+}
+
+tSpiderFunction *SpiderScript_int_GetNativeFunction(tSpiderScript *Script, tSpiderNamespace *RootNamespace,
+ const char *BasePath, const char *FunctionPath)
+{
+ tSpiderNamespace *ns;
+ const char *name;
+ tSpiderFunction *fcn;
+
+ ns = SpiderScript_int_GetNamespace(Script, RootNamespace, BasePath, FunctionPath, &name);
+ if(!ns) return NULL;
+
+ for( fcn = ns->Functions; fcn; fcn = fcn->Next )
+ {
+ if( strcmp(name, fcn->Name) == 0 )
+ return fcn;
+ }
+
+ return NULL;
+}
+
+tSpiderObjectDef *SpiderScript_int_GetNativeClass(tSpiderScript *Script, tSpiderNamespace *RootNamespace,
+ const char *BasePath, const char *ClassPath
+ )
+{
+ tSpiderNamespace *ns;
+ const char *name;
+ tSpiderObjectDef *class;
+
+ ns = SpiderScript_int_GetNamespace(Script, RootNamespace, BasePath, ClassPath, &name);
+ if(!ns) return NULL;
+
+ for( class = ns->Classes; class; class = class->Next )
+ {
+ if( strcmp(name, class->Name) == 0 )
+ return class;
+ }
+
+ return NULL;
+}
+
/**
* \brief Execute a script function
* \param Script Script context to execute in
* \param Arguments Arguments passed
*/
tSpiderValue *SpiderScript_ExecuteFunction(tSpiderScript *Script,
- tSpiderNamespace *Namespace, const char *Function,
- int NArguments, tSpiderValue **Arguments)
+ const char *Function,
+ const char *DefaultNamespaces[],
+ int NArguments, tSpiderValue **Arguments,
+ void **FunctionIdent
+ )
{
- int bFound = 0; // Used to keep nesting levels down
tSpiderValue *ret = ERRPTR;
-
- // First: Find the function in the script
- if( !Namespace )
+ tSpiderFunction *fcn = NULL;
+ int i;
+
+ // Scan list, Last item should always be NULL, so abuse that to check non-prefixed
+ for( i = 0; i == 0 || (DefaultNamespaces && DefaultNamespaces[i-1]); i ++ )
{
- tScript_Function *fcn;
- for( fcn = Script->Functions; fcn; fcn = fcn->Next )
+ const char *ns = DefaultNamespaces ? DefaultNamespaces[i] : NULL;
+ fcn = SpiderScript_int_GetNativeFunction(Script, &Script->Variant->RootNamespace,
+ ns, Function);
+ if( fcn ) break;
+
+ // TODO: Script namespacing
+ }
+
+ // Search the variant's global exports
+ if( !fcn )
+ {
+ for( fcn = Script->Variant->Functions; fcn; fcn = fcn->Next )
{
- if( strcmp(fcn->Name, Function) == 0 )
+ 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;
- return ret;
- }
}
- // Didn't find it in script?
- if(!bFound)
+ // Fourth: Search language exports
+ if( !fcn )
{
- tSpiderFunction *fcn;
- fcn = NULL; // Just to allow the below code to be neat
-
- // Second: Scan current namespace
- if( !fcn && Namespace )
+ for( fcn = gpExports_First; fcn; fcn = fcn->Next )
{
- 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;
- }
+ if( strcmp( fcn->Name, Function ) == 0 )
+ break;
}
-
- // Fourth: Search language exports
- if( !fcn )
+ }
+
+ // Find the function in the script?
+ // TODO: Script namespacing
+ if( !fcn && strchr(Function, BC_NS_SEPARATOR) == NULL )
+ {
+ tScript_Function *sfcn;
+ for( sfcn = Script->Functions; sfcn; sfcn = sfcn->Next )
{
- for( fcn = gpExports_First; fcn; fcn = fcn->Next )
- {
- if( strcmp( fcn->Name, Function ) == 0 )
- break;
- }
+ if( strcmp(sfcn->Name, Function) == 0 )
+ break;
}
-
// Execute!
- if(fcn)
+ if(sfcn)
{
- // TODO: Type Checking
- ret = fcn->Handler( Script, NArguments, Arguments );
- bFound = 1;
+ if( sfcn->BCFcn )
+ ret = Bytecode_ExecuteFunction(Script, sfcn, NArguments, Arguments);
+ else
+ ret = AST_ExecuteFunction(Script, sfcn, NArguments, Arguments);
+
+ if( FunctionIdent ) {
+ *FunctionIdent = sfcn;
+ // Abuses alignment requirements on almost all platforms
+ *(intptr_t*)FunctionIdent |= 1;
+ }
+
+ return ret;
}
}
- // Not found?
- if(!bFound)
+ if(fcn)
{
- fprintf(stderr, "Undefined reference to function '%s' (ns='%s')\n",
- Function, Namespace->Name);
+ // Execute!
+ // TODO: Type Checking
+ ret = fcn->Handler( Script, NArguments, Arguments );
+
+ if( FunctionIdent )
+ *FunctionIdent = fcn;
+
+ return ret;
+ }
+ else
+ {
+ fprintf(stderr, "Undefined reference to function '%s'\n", Function);
return ERRPTR;
}
-
- return ret;
}
/**
* \param Arguments Arguments passed
*/
tSpiderValue *SpiderScript_CreateObject(tSpiderScript *Script,
- tSpiderNamespace *Namespace, const char *ClassName,
+ const char *ClassPath, const char *DefaultNamespaces[],
int NArguments, tSpiderValue **Arguments)
{
- int bFound = 0; // Used to keep nesting levels down
tSpiderValue *ret = ERRPTR;
tSpiderObjectDef *class;
-
+ int i;
+
+ // Scan list, Last item should always be NULL, so abuse that to check non-prefixed
+ for( i = 0; i == 0 || DefaultNamespaces[i-1]; i ++ )
+ {
+ class = SpiderScript_int_GetNativeClass(Script, &Script->Variant->RootNamespace,
+ DefaultNamespaces[i], ClassPath);
+ if( class != NULL ) break;
+
+ // TODO: Language defined classes
+ }
+
// First: Find the function in the script
// TODO: Implement script-defined classes
#if 0
}
#endif
- // Didn't find it in script?
- if(!bFound)
+ // Execute!
+ if(class)
{
- class = NULL; // Just to allow the below code to be neat
-
- //if( !Namespace )
- // Namespace = &Script->Variant->RootNamespace;
+ tSpiderObject *obj;
+ // TODO: Type Checking
- // 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
+ // Call constructor
+ obj = class->Constructor( NArguments, Arguments );
+ if( obj == NULL || obj == ERRPTR )
+ return (void *)obj;
- #if 0
- // Fourth: Search language exports
- if( !class )
- {
- for( class = gpExports_First; class; class = fcn->Next )
- {
- if( strcmp( class->Name, ClassName ) == 0 )
- break;
- }
- }
- #endif
+ // Creatue return object
+ ret = malloc( sizeof(tSpiderValue) );
+ ret->Type = SS_DATATYPE_OBJECT;
+ ret->ReferenceCount = 1;
+ ret->Object = obj;
- // 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;
- }
+ return ret;
}
-
- // Not found?
- if(!bFound)
+ else // Not found?
{
- fprintf(stderr, "Undefined reference to class '%s'\n", ClassName);
+ fprintf(stderr, "Undefined reference to class '%s'\n", ClassPath);
return ERRPTR;
}
-
- return ret;
}
void AST_RuntimeMessage(tAST_Node *Node, const char *Type, const char *Format, ...)
case NODETYPE_CREATEOBJECT:
// Logical block (used to allocate `params`)
{
- tSpiderNamespace *ns = Block->CurNamespace;
+ const char *namespaces[] = {NULL}; // TODO: Default namespaces?
tSpiderValue *params[Node->FunctionCall.NumArgs];
i = 0;
+
+ // Get arguments
for(node = Node->FunctionCall.FirstArg; node; node = node->NextSibling)
{
params[i] = AST_ExecuteNode(Block, node);
}
i ++;
}
-
- if( !ns ) ns = Block->BaseNamespace;
-
+
+ // TODO: Check for cached function reference
+
// Call the function
if( Node->Type == NODETYPE_CREATEOBJECT )
{
ret = SpiderScript_CreateObject(Block->Script,
- ns,
Node->FunctionCall.Name,
+ namespaces,
Node->FunctionCall.NumArgs, params
);
}
else
{
ret = SpiderScript_ExecuteFunction(Block->Script,
- ns, Node->FunctionCall.Name,
- Node->FunctionCall.NumArgs, params
+ Node->FunctionCall.Name,
+ namespaces,
+ Node->FunctionCall.NumArgs, params,
+ NULL
);
}
break;
}
Block->CurNamespace = ns;
-
+
+ // TODO: Check type of child node (Scope, Constant or Function)
+
ret = AST_ExecuteNode(Block, Node->Scope.Element);
}
break;
ret = &Node->Constant;
SpiderScript_ReferenceValue(ret);
break;
+ case NODETYPE_NULL:
+ ret = NULL;
+ break;
// --- Operations ---
// Boolean Operations
return NULL;
}
free(stack);
+
ret = Bytecode_int_GetSpiderValue(&val, &tmpsval);
// Ensure it's a heap value
if(ret == &tmpsval) {
const char *name = OP_STRING(op);
int arg_count = OP_INDX(op);
int i, ret = 0;
- tSpiderNamespace *ns = NULL;
tSpiderValue *args[arg_count];
tSpiderValue *rv;
- tBC_StackEnt val1;
+ tBC_StackEnt val1;
+ const char *namespaces[] = {NULL}; // TODO: Default/imported namespaces
DEBUG_F("CALL (general) %s %i args\n", name, arg_count);
Bytecode_int_DerefStackValue(&val1);
}
- // Resolve namespace into pointer
- if( op->Operation != BC_OP_CALLMETHOD ) {
- const char *name_orig = name;
- 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(DefaultNS, name, &name);
- }
- if( !ns ) {
- AST_RuntimeError(NULL, "Namespace '%s' not found in '%s'", name, name_orig);
- return -1;
- }
- }
-
// Call the function etc.
if( op->Operation == BC_OP_CALLFUNCTION )
{
- rv = SpiderScript_ExecuteFunction(Script, ns, name, arg_count, args);
+ rv = SpiderScript_ExecuteFunction(Script, name, namespaces, arg_count, args, &op->CacheEnt);
}
else if( op->Operation == BC_OP_CREATEOBJ )
{
- rv = SpiderScript_CreateObject(Script, ns, name, arg_count, args);
+ rv = SpiderScript_CreateObject(Script, name, namespaces, arg_count, args);
}
else if( op->Operation == BC_OP_CALLMETHOD )
{
val1.Reference = SpiderScript_CreateString(OP_INDX(op), OP_STRING(op));
PUT_STACKVAL(val1);
break;
+ case BC_OP_LOADNULL:
+ STATE_HDR();
+ DEBUG_F("LOADNULL\n");
+ val1.Type = ET_REFERENCE;
+ val1.Reference = NULL;
+ PUT_STACKVAL(val1);
+ break;
case BC_OP_CAST:
STATE_HDR();
n_rolled ++;
}
PUT_STACKVAL(val1);
- DEBUG_F("Rolled back %i entried\n", n_rolled);
+ DEBUG_F("Rolled back %i entries\n", n_rolled);
}
return Parse_GetVariable(Parser);
case TOK_RWD_NULL:
GetToken(Parser);
- return AST_NewNop(Parser); // NODETYPE_NOP returns NULL
+ return AST_NewNull(Parser); // nODETYPE_NOP returns NULL
case TOK_RWD_NEW:
GetToken(Parser);
return Parse_GetIdent(Parser, 1);
{
if(!Object || Object == ERRPTR) return ;
Object->ReferenceCount --;
- if(Object->Type == SS_DATATYPE_OBJECT) {
- }
+// if(Object->Type == SS_DATATYPE_OBJECT) {
+// }
if( Object->ReferenceCount == 0 )
{
switch( (enum eSpiderScript_DataTypes) Object->Type )
* \return Return value
*/
extern tSpiderValue *SpiderScript_ExecuteFunction(tSpiderScript *Script,
- tSpiderNamespace *Namespace, const char *Function,
- int NArguments, tSpiderValue **Arguments
+ const char *Function, const char *DefaultNamespaces[],
+ int NArguments, tSpiderValue **Arguments,
+ void **FunctionIdent
);
/**
* \brief Execute an object method
* \brief Creates an object instance
*/
extern tSpiderValue *SpiderScript_CreateObject(tSpiderScript *Script,
- tSpiderNamespace *Namespace, const char *ClassName,
+ const char *ClassName, const char *DefaultNamespaces[],
int NArguments, tSpiderValue **Arguments
);