if(ret) return ret;
if( blockInfo.StackDepth != 0 ) {
AST_RuntimeError(node, "Stack not reset at end of node");
+ blockInfo.StackDepth = 0;
}
}
// > Type check
ret = _StackPop(Block, Node, SS_DATATYPE_UNDEF);
if(ret < 0) return -1;
- if(ret != SS_DATATYPE_ARRAY && (ret >> 16) == 0) {
+ if(ret != SS_DATATYPE_ARRAY && SS_GETARRAYDEPTH(ret) == 0) {
AST_RuntimeError(Node, "Type mismatch, Expected an array, got %i",
ret);
return -2;
// Update the array depth
if( i != SS_DATATYPE_ARRAY ) {
- i -= 0x10000; // Decrease the array level
+ i = SS_DOWNARRAY(i); // Decrease the array level
}
ret = _StackPush(Block, Node, i);
if(ret < 0) return -1;
int BC_SaveValue(tAST_BlockInfo *Block, tAST_Node *DestNode)
{
- int ret;
+ int ret, type;
switch(DestNode->Type)
{
// Variable, simple
case NODETYPE_VARIABLE:
ret = BC_Variable_SetValue( Block, DestNode );
+ if(ret) return ret;
break;
// Array index
case NODETYPE_INDEX:
if(ret) return ret;
ret = _StackPop(Block, DestNode->BinOp.Left, SS_DATATYPE_UNDEF);
if(ret < 0) return -1;
- if(ret != SS_DATATYPE_ARRAY && (ret >> 16) == 0) {
+ if(ret != SS_DATATYPE_ARRAY && SS_GETARRAYDEPTH(ret) == 0) {
AST_RuntimeError(DestNode, "Type mismatch, Expected an array, got %i",
ret);
return -2;
}
+ type = SS_DOWNARRAY(ret);
ret = AST_ConvertNode(Block, DestNode->BinOp.Right, 1); // Offset
if(ret) return ret;
if(ret < 0) return -1;
Bytecode_AppendSetIndex( Block->Handle );
+ _StackPop(Block, DestNode, type);
break;
// Object element
case NODETYPE_ELEMENT:
// === IMPORTS ===
extern tSpiderFunction *gpExports_First;
+extern tSpiderNamespace gExportNamespaceRoot;
extern tSpiderValue *AST_ExecuteFunction(tSpiderScript *Script, tScript_Function *Fcn, int NArguments, tSpiderValue **Arguments);
extern tSpiderValue *Bytecode_ExecuteFunction(tSpiderScript *Script, tScript_Function *Fcn, int NArguments, tSpiderValue **Args);
// Check for this level
for( ns = lastns->FirstChild; ns; ns = ns->Next )
{
+ printf("%p %.*s == %s\n", lastns, len, name, ns->Name);
if( strncmp(name, ns->Name, len) == 0 && ns->Name[len] == 0 )
break ;
}
- if(!ns) return NULL;
+ if(!ns) return NULL;
if(!end && !bTriedBase) {
end = ItemPath - 1; // -1 to counter (name = end + 1)
for( i = 0; i == 0 || (DefaultNamespaces && DefaultNamespaces[i-1]); i ++ )
{
const char *ns = DefaultNamespaces ? DefaultNamespaces[i] : NULL;
- fcn = SpiderScript_int_GetNativeFunction(Script, &Script->Variant->RootNamespace,
- ns, Function);
+ fcn = SpiderScript_int_GetNativeFunction(Script, &Script->Variant->RootNamespace, ns, Function);
if( fcn ) break;
-
+
+ fcn = SpiderScript_int_GetNativeFunction(Script, &gExportNamespaceRoot, ns, Function);
+ if( fcn ) break;
+
// TODO: Script namespacing
}
// 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;
+ const char *ns = DefaultNamespaces[i];
+ class = SpiderScript_int_GetNativeClass(Script, &Script->Variant->RootNamespace, ns, ClassPath);
+ if( class ) break;
+
+ class = SpiderScript_int_GetNativeClass(Script, &gExportNamespaceRoot, ns, ClassPath);
+ if( class ) break;
// TODO: Language defined classes
}
{
switch(Operation)
{
+ // Real = Real OP Real
case BC_OP_ADD: Val1->Real = Val1->Real + Val2->Real; return 0;
case BC_OP_SUBTRACT: Val1->Real = Val1->Real - Val2->Real; return 0;
case BC_OP_MULTIPLY: Val1->Real = Val1->Real * Val2->Real; return 0;
case BC_OP_DIVIDE: Val1->Real = Val1->Real / Val2->Real; return 0;
+ // Bool/Integer = Real OP Real
case BC_OP_EQUALS: Val1->Integer = (Val1->Real == Val2->Real); break;
case BC_OP_NOTEQUALS: Val1->Integer = (Val1->Real != Val2->Real); break;
case BC_OP_LESSTHAN: Val1->Integer = (Val1->Real < Val2->Real); break;
PUT_STACKVAL(val1);
break;
}
- switch(val2.Type * 100 + val1.Type )
- {
- case SS_DATATYPE_INTEGER*100 + SS_DATATYPE_REAL:
+ if( val2.Type == SS_DATATYPE_INTEGER && val1.Type == SS_DATATYPE_REAL ) {
val2.Integer = val1.Real;
- PUT_STACKVAL(val2);
- break;
- case SS_DATATYPE_REAL*100 + SS_DATATYPE_INTEGER:
+ }
+ else if( val2.Type == SS_DATATYPE_REAL && val2.Type == SS_DATATYPE_INTEGER ) {
val2.Real = val1.Integer;
- PUT_STACKVAL(val2);
- break;
- default: {
+ }
+ else {
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;
}
+ PUT_STACKVAL(val2);
break;
case BC_OP_DUPSTACK:
#include <spiderscript.h>
// === PROTOTYPES ===
+tSpiderValue *Exports_sizeof(tSpiderScript *Script, int NArgs, tSpiderValue **Args);
+tSpiderValue *Exports_Lang_Strings_Split(tSpiderScript *Script, int NArgs, tSpiderValue **Args);
tSpiderValue *Exports_Lang_Struct(tSpiderScript *Script, int NArgs, tSpiderValue **Args);
// === GLOBALS ===
-tSpiderFunction gExports_Lang_Struct = {NULL,"Lang.Struct", Exports_Lang_Struct, {SS_DATATYPE_STRING,-1}};
-tSpiderFunction *gpExports_First = &gExports_Lang_Struct;
+tSpiderFunction gExports_Lang_Strings_Split = {
+ .Name = "Split",
+ .Handler = Exports_Lang_Strings_Split,
+ .ReturnType = SS_MAKEARRAY(SS_DATATYPE_STRING),
+ .ArgTypes = {SS_DATATYPE_STRING, SS_DATATYPE_STRING, -1}
+};
+tSpiderNamespace gExports_NS_Lang_Strings = {
+ .Name = "Strings",
+ .Functions = &gExports_Lang_Strings_Split
+ };
+
+tSpiderFunction gExports_Lang_Struct = {
+ .Name = "Struct",
+ .Handler = Exports_Lang_Struct,
+ .ReturnType = SS_DATATYPE_OPAQUE,
+ .ArgTypes = {SS_DATATYPE_STRING, -1}
+};
+// - Lang Namespace
+tSpiderNamespace gExports_NS_Lang = {
+ .Name = "Lang",
+ .Functions = &gExports_Lang_Struct,
+ .FirstChild = &gExports_NS_Lang_Strings
+ };
+tSpiderNamespace gExportNamespaceRoot = {
+ .FirstChild = &gExports_NS_Lang
+};
+
+// -- Global Functions
+tSpiderFunction gExports_sizeof = {
+ .Name = "sizeof",
+ .Handler = Exports_sizeof,
+ .ReturnType = SS_DATATYPE_INTEGER,
+ .ArgTypes = {SS_DATATYPE_UNDEF, -1}
+};
+tSpiderFunction *gpExports_First;
// === CODE ===
+tSpiderValue *Exports_sizeof(tSpiderScript *Script, int NArgs, tSpiderValue **Args)
+{
+ if(NArgs != 1 || !Args[0]) return NULL;
+
+ switch( Args[0]->Type )
+ {
+ case SS_DATATYPE_STRING:
+ return SpiderScript_CreateInteger(Args[0]->String.Length);
+ case SS_DATATYPE_ARRAY:
+ return SpiderScript_CreateInteger(Args[0]->Array.Length);
+ default:
+ return NULL;
+ }
+}
+
+tSpiderValue *Exports_Lang_Strings_Split(tSpiderScript *Script, int NArgs, tSpiderValue **Args)
+{
+ return NULL;
+}
+
tSpiderValue *Exports_Lang_Struct(tSpiderScript *Script, int NArgs, tSpiderValue **Args)
{
int i;
NUM_SS_DATATYPES
};
+#define SS_MAKEARRAY(_type) ((_type) + 0x10000)
+#define SS_DOWNARRAY(_type) ((_type) - 0x10000)
+#define SS_GETARRAYDEPTH(_type) ((_type) >> 16)
+
enum eSpiderValueOps
{
SS_VALUEOP_NOP,
* \brief Function handler
*/
tSpiderValue *(*Handler)(tSpiderScript *Script, int nParams, tSpiderValue **Parameters);
+
+ /**
+ * \brief What type is returned
+ */
+ int ReturnType;
+
/**
* \brief Argument types
*