- // 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:
- // Get operands
- op1 = AST_ExecuteNode(Script, Node->BinOp.Left);
- op2 = AST_ExecuteNode(Script, Node->BinOp.Right);
-
- // Convert types
- if( op1->Type != op2->Type ) {
- // If dynamically typed, convert op2 to op1's type
- if(Script->Variant->bDyamicTyped)
+ // 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 )