SpiderScript - Bugfixes and speed improvements
authorJohn Hodge <[email protected]>
Sat, 2 Apr 2011 09:00:49 +0000 (17:00 +0800)
committerJohn Hodge <[email protected]>
Sat, 2 Apr 2011 09:00:49 +0000 (17:00 +0800)
Usermode/Libraries/libspiderscript.so_src/ast.c
Usermode/Libraries/libspiderscript.so_src/ast.h
Usermode/Libraries/libspiderscript.so_src/exec_ast.c
Usermode/Libraries/libspiderscript.so_src/lex.c
Usermode/Libraries/libspiderscript.so_src/main.c
Usermode/Libraries/libspiderscript.so_src/parse.c
Usermode/Libraries/libspiderscript.so_src/tokens.h

index 36568e6..5aa6e3d 100644 (file)
@@ -117,7 +117,7 @@ void AST_SetFunctionCode(tAST_Function *Function, tAST_Node *Root)
 size_t AST_WriteScript(void *Buffer, tAST_Script *Script)
 {
        tAST_Function   *fcn;
-       size_t  ret = 0, ptr;
+       size_t  ret = 0, ptr = 0;
        
        for( fcn = Script->Functions; fcn; fcn = fcn->Next )
        {
@@ -128,8 +128,11 @@ size_t AST_WriteScript(void *Buffer, tAST_Script *Script)
                ret += AST_WriteNode(Buffer, ret, fcn->Code);
                WRITE_32(Buffer, ptr, ret);     // Actually set next
        }
-       ptr -= 4;
-       WRITE_32(Buffer, ptr, 0);       // Clear next for final
+       if( ptr )
+       {
+               ptr -= 4;
+               WRITE_32(Buffer, ptr, 0);       // Clear next for final
+       }
        
        return ret;
 }
@@ -139,7 +142,6 @@ size_t AST_WriteScript(void *Buffer, tAST_Script *Script)
  */
 size_t AST_WriteNode(void *Buffer, size_t Offset, tAST_Node *Node)
 {
-       size_t  ptr;
        size_t  baseOfs = Offset;
        
        if(!Node) {
@@ -219,7 +221,11 @@ size_t AST_WriteNode(void *Buffer, size_t Offset, tAST_Node *Node)
        
        // Unary Operations
        case NODETYPE_RETURN:
-               ptr = Offset;
+       case NODETYPE_BWNOT:
+       case NODETYPE_LOGICALNOT:
+       case NODETYPE_NEGATE:
+       case NODETYPE_POSTINC:
+       case NODETYPE_POSTDEC:
                Offset += AST_WriteNode(Buffer, Offset, Node->UniOp.Value);
                break;
        
@@ -237,8 +243,8 @@ size_t AST_WriteNode(void *Buffer, size_t Offset, tAST_Node *Node)
        case NODETYPE_BWOR:     case NODETYPE_LOGICALOR:
        case NODETYPE_BWXOR:    case NODETYPE_LOGICALXOR:
        case NODETYPE_EQUALS:
-       case NODETYPE_LESSTHAN:
-       case NODETYPE_GREATERTHAN:
+       case NODETYPE_LESSTHAN: case NODETYPE_LESSTHANEQUAL:
+       case NODETYPE_GREATERTHAN:      case NODETYPE_GREATERTHANEQUAL:
                Offset += AST_WriteNode(Buffer, Offset, Node->BinOp.Left);
                Offset += AST_WriteNode(Buffer, Offset, Node->BinOp.Right);
                break;
@@ -347,6 +353,11 @@ void AST_FreeNode(tAST_Node *Node)
        
        // Unary Operations
        case NODETYPE_RETURN:
+       case NODETYPE_BWNOT:
+       case NODETYPE_LOGICALNOT:
+       case NODETYPE_NEGATE:
+       case NODETYPE_POSTINC:
+       case NODETYPE_POSTDEC:
                AST_FreeNode(Node->UniOp.Value);
                break;
        
@@ -364,8 +375,8 @@ void AST_FreeNode(tAST_Node *Node)
        case NODETYPE_BWOR:     case NODETYPE_LOGICALOR:
        case NODETYPE_BWXOR:    case NODETYPE_LOGICALXOR:
        case NODETYPE_EQUALS:
-       case NODETYPE_LESSTHAN:
-       case NODETYPE_GREATERTHAN:
+       case NODETYPE_LESSTHAN: case NODETYPE_LESSTHANEQUAL:
+       case NODETYPE_GREATERTHAN:      case NODETYPE_GREATERTHANEQUAL:
                AST_FreeNode( Node->BinOp.Left );
                AST_FreeNode( Node->BinOp.Right );
                break;
@@ -386,6 +397,7 @@ tAST_Node *AST_NewCodeBlock(tParser *Parser)
        tAST_Node       *ret = malloc( sizeof(tAST_Node) );
        
        ret->NextSibling = NULL;
+       ret->File = NULL;
        ret->Line = Parser->CurLine;
        ret->Type = NODETYPE_BLOCK;
        ret->Block.FirstChild = NULL;
@@ -427,6 +439,7 @@ tAST_Node *AST_NewIf(tParser *Parser, tAST_Node *Condition, tAST_Node *True, tAS
 {
        tAST_Node       *ret = malloc( sizeof(tAST_Node) );
        ret->NextSibling = NULL;
+       ret->File = NULL;
        ret->Line = Parser->CurLine;
        ret->Type = NODETYPE_IF;
        ret->If.Condition = Condition;
@@ -439,6 +452,7 @@ tAST_Node *AST_NewLoop(tParser *Parser, tAST_Node *Init, int bPostCheck, tAST_No
 {
        tAST_Node       *ret = malloc( sizeof(tAST_Node) );
        ret->NextSibling = NULL;
+       ret->File = NULL;
        ret->Line = Parser->CurLine;
        ret->Type = NODETYPE_LOOP;
        ret->For.Init = Init;
@@ -454,6 +468,7 @@ tAST_Node *AST_NewAssign(tParser *Parser, int Operation, tAST_Node *Dest, tAST_N
        tAST_Node       *ret = malloc( sizeof(tAST_Node) );
        
        ret->NextSibling = NULL;
+       ret->File = NULL;
        ret->Line = Parser->CurLine;
        ret->Type = NODETYPE_ASSIGN;
        ret->Assign.Operation = Operation;
@@ -468,6 +483,7 @@ tAST_Node *AST_NewCast(tParser *Parser, int Target, tAST_Node *Value)
        tAST_Node       *ret = malloc( sizeof(tAST_Node) );
        
        ret->NextSibling = NULL;
+       ret->File = NULL;
        ret->Line = Parser->CurLine;
        ret->Type = NODETYPE_CAST;
        ret->Cast.DataType = Target;
@@ -481,6 +497,7 @@ tAST_Node *AST_NewBinOp(tParser *Parser, int Operation, tAST_Node *Left, tAST_No
        tAST_Node       *ret = malloc( sizeof(tAST_Node) );
        
        ret->NextSibling = NULL;
+       ret->File = NULL;
        ret->Line = Parser->CurLine;
        ret->Type = Operation;
        ret->BinOp.Left = Left;
@@ -496,6 +513,7 @@ tAST_Node *AST_NewUniOp(tParser *Parser, int Operation, tAST_Node *Value)
        tAST_Node       *ret = malloc( sizeof(tAST_Node) );
        
        ret->NextSibling = NULL;
+       ret->File = NULL;
        ret->Line = Parser->CurLine;
        ret->Type = Operation;
        ret->UniOp.Value = Value;
@@ -503,6 +521,18 @@ tAST_Node *AST_NewUniOp(tParser *Parser, int Operation, tAST_Node *Value)
        return ret;
 }
 
+tAST_Node *AST_NewNop(tParser *Parser)
+{
+       tAST_Node       *ret = malloc( sizeof(tAST_Node) );
+       
+       ret->NextSibling = NULL;
+       ret->File = NULL;
+       ret->Line = Parser->CurLine;
+       ret->Type = NODETYPE_NOP;
+       
+       return ret;
+}
+
 /**
  * \brief Create a new string node
  */
@@ -511,6 +541,7 @@ tAST_Node *AST_NewString(tParser *Parser, const char *String, int Length)
        tAST_Node       *ret = malloc( sizeof(tAST_Node) + Length + 1 );
        
        ret->NextSibling = NULL;
+       ret->File = NULL;
        ret->Line = Parser->CurLine;
        ret->Type = NODETYPE_STRING;
        ret->String.Length = Length;
@@ -523,16 +554,31 @@ tAST_Node *AST_NewString(tParser *Parser, const char *String, int Length)
 /**
  * \brief Create a new integer node
  */
-tAST_Node *AST_NewInteger(tParser *Parser, uint64_t Value)
+tAST_Node *AST_NewInteger(tParser *Parser, int64_t Value)
 {
        tAST_Node       *ret = malloc( sizeof(tAST_Node) );
        ret->NextSibling = NULL;
+       ret->File = NULL;
        ret->Line = Parser->CurLine;
        ret->Type = NODETYPE_INTEGER;
        ret->Integer = Value;
        return ret;
 }
 
+/**
+ * \brief Create a new real number node
+ */
+tAST_Node *AST_NewReal(tParser *Parser, double Value)
+{
+       tAST_Node       *ret = malloc( sizeof(tAST_Node) );
+       ret->NextSibling = NULL;
+       ret->File = NULL;
+       ret->Line = Parser->CurLine;
+       ret->Type = NODETYPE_REAL;
+       ret->Real = Value;
+       return ret;
+}
+
 /**
  * \brief Create a new variable reference node
  */
@@ -540,6 +586,7 @@ tAST_Node *AST_NewVariable(tParser *Parser, const char *Name)
 {
        tAST_Node       *ret = malloc( sizeof(tAST_Node) + strlen(Name) + 1 );
        ret->NextSibling = NULL;
+       ret->File = NULL;
        ret->Line = Parser->CurLine;
        ret->Type = NODETYPE_VARIABLE;
        strcpy(ret->Variable.Name, Name);
@@ -553,6 +600,7 @@ tAST_Node *AST_NewDefineVar(tParser *Parser, int Type, const char *Name)
 {
        tAST_Node       *ret = malloc( sizeof(tAST_Node) + strlen(Name) + 1 );
        ret->NextSibling = NULL;
+       ret->File = NULL;
        ret->Line = Parser->CurLine;
        ret->Type = NODETYPE_DEFVAR;
        ret->DefVar.DataType = Type;
@@ -568,6 +616,7 @@ tAST_Node *AST_NewConstant(tParser *Parser, const char *Name)
 {
        tAST_Node       *ret = malloc( sizeof(tAST_Node) + strlen(Name) + 1 );
        ret->NextSibling = NULL;
+       ret->File = NULL;
        ret->Line = Parser->CurLine;
        ret->Type = NODETYPE_CONSTANT;
        strcpy(ret->Variable.Name, Name);
@@ -583,11 +632,13 @@ tAST_Node *AST_NewFunctionCall(tParser *Parser, const char *Name)
        tAST_Node       *ret = malloc( sizeof(tAST_Node) + strlen(Name) + 1 );
        
        ret->NextSibling = NULL;
+       ret->File = NULL;
        ret->Line = Parser->CurLine;
        ret->Type = NODETYPE_FUNCTIONCALL;
        ret->FunctionCall.Object = NULL;
        ret->FunctionCall.FirstArg = NULL;
        ret->FunctionCall.LastArg = NULL;
+       ret->FunctionCall.NumArgs = 0;
        strcpy(ret->FunctionCall.Name, Name);
        return ret;
 }
@@ -596,11 +647,13 @@ tAST_Node *AST_NewMethodCall(tParser *Parser, tAST_Node *Object, const char *Nam
        tAST_Node       *ret = malloc( sizeof(tAST_Node) + strlen(Name) + 1 );
        
        ret->NextSibling = NULL;
+       ret->File = NULL;
        ret->Line = Parser->CurLine;
        ret->Type = NODETYPE_METHODCALL;
        ret->FunctionCall.Object = Object;
        ret->FunctionCall.FirstArg = NULL;
        ret->FunctionCall.LastArg = NULL;
+       ret->FunctionCall.NumArgs = 0;
        strcpy(ret->FunctionCall.Name, Name);
        return ret;
 }
@@ -610,11 +663,13 @@ tAST_Node *AST_NewCreateObject(tParser *Parser, const char *Name)
        tAST_Node       *ret = malloc( sizeof(tAST_Node) + strlen(Name) + 1 );
        
        ret->NextSibling = NULL;
+       ret->File = NULL;
        ret->Line = Parser->CurLine;
        ret->Type = NODETYPE_CREATEOBJECT;
        ret->FunctionCall.Object = NULL;
        ret->FunctionCall.FirstArg = NULL;
        ret->FunctionCall.LastArg = NULL;
+       ret->FunctionCall.NumArgs = 0;
        strcpy(ret->FunctionCall.Name, Name);
        return ret;
 }
@@ -640,6 +695,7 @@ void AST_AppendFunctionCallArg(tAST_Node *Node, tAST_Node *Arg)
                Node->FunctionCall.FirstArg = Arg;
                Node->FunctionCall.LastArg = Arg;
        }
+       Node->FunctionCall.NumArgs ++;
 }
 
 /**
@@ -650,6 +706,7 @@ tAST_Node *AST_NewScopeDereference(tParser *Parser, const char *Name, tAST_Node
        tAST_Node       *ret = malloc( sizeof(tAST_Node) + strlen(Name) + 1 );
        
        ret->NextSibling = NULL;
+       ret->File = NULL;
        ret->Line = Parser->CurLine;
        ret->Type = NODETYPE_SCOPE;
        ret->Scope.Element = Child;
@@ -665,6 +722,7 @@ tAST_Node *AST_NewClassElement(tParser *Parser, tAST_Node *Object, const char *N
        tAST_Node       *ret = malloc( sizeof(tAST_Node) + strlen(Name) + 1 );
        
        ret->NextSibling = NULL;
+       ret->File = NULL;
        ret->Line = Parser->CurLine;
        ret->Type = NODETYPE_ELEMENT;
        ret->Scope.Element = Object;
index c6593ac..a9cf1db 100644 (file)
@@ -35,6 +35,8 @@ enum eAST_NodeTypes
        
        NODETYPE_RETURN,        //!< Return from a function (reserved word)
        NODETYPE_ASSIGN,        //!< Variable assignment operator
+       NODETYPE_POSTINC,       //!< Post-increment (i++) - Uniop
+       NODETYPE_POSTDEC,       //!< Post-decrement (i--) - Uniop
        NODETYPE_FUNCTIONCALL,  //!< Call a function
        NODETYPE_METHODCALL,    //!< Call a class method
        NODETYPE_CREATEOBJECT,  //!< Create an object
@@ -44,14 +46,18 @@ enum eAST_NodeTypes
        
        NODETYPE_INDEX, //!< Index into an array
        
+       NODETYPE_LOGICALNOT,    //!< Logical NOT operator
        NODETYPE_LOGICALAND,    //!< Logical AND operator
        NODETYPE_LOGICALOR,     //!< Logical OR operator
        NODETYPE_LOGICALXOR,    //!< Logical XOR operator
        
        NODETYPE_EQUALS,        //!< Comparison Equals
        NODETYPE_LESSTHAN,      //!< Comparison Less Than
+       NODETYPE_LESSTHANEQUAL, //!< Comparison Less Than or Equal
        NODETYPE_GREATERTHAN,   //!< Comparison Greater Than
+       NODETYPE_GREATERTHANEQUAL,      //!< Comparison Greater Than or Equal
        
+       NODETYPE_BWNOT, //!< Bitwise NOT
        NODETYPE_BWAND, //!< Bitwise AND
        NODETYPE_BWOR,  //!< Bitwise OR
        NODETYPE_BWXOR, //!< Bitwise XOR
@@ -60,6 +66,7 @@ enum eAST_NodeTypes
        NODETYPE_BITSHIFTRIGHT, //!< Bitwise Shift Right (Shrink)
        NODETYPE_BITROTATELEFT, //!< Bitwise Rotate Left (Grow)
        
+       NODETYPE_NEGATE,        //!< Negagte
        NODETYPE_ADD,   //!< Add
        NODETYPE_SUBTRACT,      //!< Subtract
        NODETYPE_MULTIPLY,      //!< Multiply
@@ -124,6 +131,7 @@ struct sAST_Node
                        tAST_Node       *Object;
                        tAST_Node       *FirstArg;
                        tAST_Node       *LastArg;
+                        int    NumArgs;
                        char    Name[];
                }       FunctionCall;
                
@@ -207,8 +215,11 @@ extern tAST_Function       *AST_AppendFunction(tAST_Script *Script, const char *Name);
 extern void    AST_AppendFunctionArg(tAST_Function *Function, tAST_Node *Arg);
 extern void    AST_SetFunctionCode(tAST_Function *Function, tAST_Node *Root);
 
+extern tAST_Node       *AST_NewNop(tParser *Parser);
+
 extern tAST_Node       *AST_NewString(tParser *Parser, const char *String, int Length);
-extern tAST_Node       *AST_NewInteger(tParser *Parser, uint64_t Value);
+extern tAST_Node       *AST_NewInteger(tParser *Parser, int64_t Value);
+extern tAST_Node       *AST_NewReal(tParser *Parser, double Value);
 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);
index e0de9ff..74d6383 100644 (file)
@@ -22,6 +22,7 @@ char  *SpiderScript_DumpValue(tSpiderValue *Value);
 
 tSpiderValue   *AST_ExecuteNode(tAST_BlockState *Block, tAST_Node *Node);
 tSpiderValue   *AST_ExecuteNode_BinOp(tAST_BlockState *Block, int Operation, tSpiderValue *Left, tSpiderValue *Right);
+tSpiderValue   *AST_ExecuteNode_UniOp(tAST_BlockState *Block, int Operation, tSpiderValue *Value);
 
 tAST_Variable *Variable_Define(tAST_BlockState *Block, int Type, const char *Name);
  int   Variable_SetValue(tAST_BlockState *Block, const char *Name, tSpiderValue *Value);
@@ -155,7 +156,16 @@ tSpiderValue *SpiderScript_CastValueTo(int Type, tSpiderValue *Source)
        tSpiderValue    *ret = ERRPTR;
         int    len = 0;
 
-       if( !Source )   return NULL;
+       if( !Source )
+       {
+               switch(Type)
+               {
+               case SS_DATATYPE_INTEGER:       return SpiderScript_CreateInteger(0);
+               case SS_DATATYPE_REAL:  return SpiderScript_CreateReal(0);
+               case SS_DATATYPE_STRING:        return SpiderScript_CreateString(4, "null");
+               }
+               return NULL;
+       }
        
        // Check if anything needs to be done
        if( Source->Type == Type ) {
@@ -163,6 +173,20 @@ tSpiderValue *SpiderScript_CastValueTo(int Type, tSpiderValue *Source)
                return Source;
        }
        
+       #if 0
+       {
+               printf("Casting %i ", Source->Type);
+               switch(Source->Type)
+               {
+               case SS_DATATYPE_INTEGER:       printf("0x%lx", Source->Integer);       break;
+               case SS_DATATYPE_STRING:        printf("\"%s\"", Source->String.Data);  break;
+               case SS_DATATYPE_REAL:  printf("%f", Source->Real);     break;
+               default:        break;
+               }
+               printf(" to %i\n", Type);
+       }
+       #endif
+       
        #if 0
        if( Source->Type == SS_DATATYPE_OBJECT )
        {
@@ -213,11 +237,27 @@ tSpiderValue *SpiderScript_CastValueTo(int Type, tSpiderValue *Source)
                }
                break;
        
+       case SS_DATATYPE_REAL:
+               ret = malloc(sizeof(tSpiderValue));
+               ret->Type = SS_DATATYPE_REAL;
+               ret->ReferenceCount = 1;
+               switch(Source->Type)
+               {
+               case SS_DATATYPE_STRING:        ret->Real = atof(Source->String.Data);  break;
+               case SS_DATATYPE_INTEGER:       ret->Real = Source->Integer;    break;
+               default:
+                       AST_RuntimeError(NULL, "Invalid cast from %i to Real", Source->Type);
+                       free(ret);
+                       ret = ERRPTR;
+                       break;
+               }
+               break;
+       
        case SS_DATATYPE_STRING:
                switch(Source->Type)
                {
                case SS_DATATYPE_INTEGER:       len = snprintf(NULL, 0, "%li", Source->Integer);        break;
-               case SS_DATATYPE_REAL:  snprintf(NULL, 0, "%f", Source->Real);  break;
+               case SS_DATATYPE_REAL:  len = snprintf(NULL, 0, "%g", Source->Real);    break;
                default:        break;
                }
                ret = malloc(sizeof(tSpiderValue) + len + 1);
@@ -227,7 +267,8 @@ tSpiderValue *SpiderScript_CastValueTo(int Type, tSpiderValue *Source)
                switch(Source->Type)
                {
                case SS_DATATYPE_INTEGER:       sprintf(ret->String.Data, "%li", Source->Integer);      break;
-               case SS_DATATYPE_REAL:  sprintf(ret->String.Data, "%f", Source->Real);  break;
+               case SS_DATATYPE_REAL:
+                       sprintf(ret->String.Data, "%g", Source->Real);  break;
                default:
                        AST_RuntimeError(NULL, "Invalid cast from %i to String", Source->Type);
                        free(ret);
@@ -237,7 +278,8 @@ tSpiderValue *SpiderScript_CastValueTo(int Type, tSpiderValue *Source)
                break;
        
        default:
-               AST_RuntimeError(NULL, "BUG - BUG REPORT: Unimplemented cast target");
+               AST_RuntimeError(NULL, "BUG - BUG REPORT: Unimplemented cast target %i", Type);
+               ret = ERRPTR;
                break;
        }
        
@@ -383,7 +425,7 @@ tSpiderValue *SpiderScript_ExecuteFunction(tSpiderScript *Script,
                        bs.CurNamespace = NULL;
                        bs.Script = Script;
                        
-                       
+                       // Parse arguments
                        for( arg = astFcn->Arguments; arg; arg = arg->NextSibling, i++ )
                        {
                                // TODO: Type checks
@@ -657,7 +699,7 @@ tSpiderValue *AST_ExecuteNode(tAST_BlockState *Block, tAST_Node *Node)
        tSpiderValue    *ret = NULL, *tmpobj;
        tSpiderValue    *op1, *op2;     // Binary operations
         int    cmp;    // Used in comparisons
-        int    i=0;
+        int    i;
        
        switch(Node->Type)
        {
@@ -668,20 +710,20 @@ tSpiderValue *AST_ExecuteNode(tAST_BlockState *Block, tAST_Node *Node)
        case NODETYPE_BLOCK:
                {
                        tAST_BlockState blockInfo;
-                       memcpy(&blockInfo, Block, sizeof(tAST_BlockState));
+                       blockInfo.Parent = Block;
+                       blockInfo.Script = Block->Script;
                        blockInfo.FirstVar = NULL;
                        blockInfo.RetVal = NULL;
-                       blockInfo.Parent = Block;
+                       blockInfo.BaseNamespace = Block->BaseNamespace;
+                       blockInfo.CurNamespace = NULL;
                        ret = NULL;
                        for(node = Node->Block.FirstChild; node && !blockInfo.RetVal; node = node->NextSibling )
                        {
-                               tmpobj = AST_ExecuteNode(&blockInfo, node);
-                               if(tmpobj == ERRPTR) {  // Error check
-                                       ret = ERRPTR;
+                               ret = AST_ExecuteNode(&blockInfo, node);
+                               if(ret == ERRPTR) {     // Error check
                                        break ;
                                }
-                               if(tmpobj)      Object_Dereference(tmpobj);     // Free unused value
-                               tmpobj = NULL;
+                               if(ret) Object_Dereference(ret);        // Free unused value
                        }
                        // Clean up variables
                        while(blockInfo.FirstVar)
@@ -690,7 +732,8 @@ tSpiderValue *AST_ExecuteNode(tAST_BlockState *Block, tAST_Node *Node)
                                Variable_Destroy( blockInfo.FirstVar );
                                blockInfo.FirstVar = nextVar;
                        }
-                       
+                       if(ret != ERRPTR)
+                               ret = NULL;
                        if( blockInfo.RetVal )
                                Block->RetVal = blockInfo.RetVal;
                }
@@ -715,7 +758,7 @@ tSpiderValue *AST_ExecuteNode(tAST_BlockState *Block, tAST_Node *Node)
                        if( value == ERRPTR )
                                return ERRPTR;
                        if(ret) Object_Dereference(ret);
-                       Object_Dereference(varVal);
+                       if(varVal)      Object_Dereference(varVal);
                        ret = value;
                }
                
@@ -725,72 +768,96 @@ tSpiderValue *AST_ExecuteNode(tAST_BlockState *Block, tAST_Node *Node)
                }
                break;
        
+       case NODETYPE_POSTINC:
+       case NODETYPE_POSTDEC:
+               {
+                       tSpiderValue    *varVal, *value, *one;
+                       if( Node->UniOp.Value->Type != NODETYPE_VARIABLE ) {
+                               AST_RuntimeError(Node, "LVALUE of assignment is not a variable");
+                               return ERRPTR;
+                       }
+               
+                       varVal = Variable_GetValue(Block, Node->Assign.Dest->Variable.Name);
+                       one = SpiderScript_CreateInteger(1);
+                       
+                       if( Node->Type == NODETYPE_POSTDEC )
+                               value = AST_ExecuteNode_BinOp(Block, NODETYPE_SUBTRACT, varVal, one);
+                       else
+                               value = AST_ExecuteNode_BinOp(Block, NODETYPE_ADD, varVal, one);
+                       if( value == ERRPTR )
+                               return ERRPTR;
+                       Object_Dereference(one);        // Free constant one
+                       
+                       ret = varVal;
+               
+                       if( Variable_SetValue( Block, Node->Assign.Dest->Variable.Name, value ) ) {
+                               Object_Dereference( ret );
+                               return ERRPTR;
+                       }
+                       Object_Dereference( value );
+               }
+               break;
+       
        // Function Call
        case NODETYPE_METHODCALL:
        case NODETYPE_FUNCTIONCALL:
        case NODETYPE_CREATEOBJECT:
+               // Logical block (used to allocate `params`)
                {
-                        int    nParams = 0;
-                       for(node = Node->FunctionCall.FirstArg; node; node = node->NextSibling) {
-                               nParams ++;
-                       }
-                       // Logical block (used to allocate `params`)
+                       tSpiderValue    *params[Node->FunctionCall.NumArgs];
+                       i = 0;
+                       for(node = Node->FunctionCall.FirstArg; node; node = node->NextSibling)
                        {
-                               tSpiderValue    *params[nParams];
-                               i = 0;
-                               for(node = Node->FunctionCall.FirstArg; node; node = node->NextSibling)
-                               {
-                                       params[i] = AST_ExecuteNode(Block, node);
-                                       if( params[i] == ERRPTR ) {
-                                               while(i--)      Object_Dereference(params[i]);
-                                               ret = ERRPTR;
-                                               goto _return;
-                                       }
-                                       i ++;
-                               }
-                               
-                               if( !Block->CurNamespace )
-                                       Block->CurNamespace = Block->BaseNamespace;
-                               
-                               // Call the function
-                               if( Node->Type == NODETYPE_CREATEOBJECT )
-                               {
-                                       ret = SpiderScript_CreateObject(Block->Script,
-                                               Block->CurNamespace,
-                                               Node->FunctionCall.Name,
-                                               nParams, params
-                                               );
-                               }
-                               else if( Node->Type == NODETYPE_METHODCALL )
-                               {
-                                       tSpiderValue *obj = AST_ExecuteNode(Block, Node->FunctionCall.Object);
-                                       if( !obj || obj->Type != SS_DATATYPE_OBJECT ) {
-                                               AST_RuntimeError(Node->FunctionCall.Object,
-                                                       "Type Mismatch - Required SS_DATATYPE_OBJECT for method call");
-                                               while(i--)      Object_Dereference(params[i]);
-                                               ret = ERRPTR;
-                                               break;
-                                       }
-                                       ret = SpiderScript_ExecuteMethod(Block->Script,
-                                               obj->Object, Node->FunctionCall.Name,
-                                               nParams, params
-                                               );
-                                       Object_Dereference(obj);
+                               params[i] = AST_ExecuteNode(Block, node);
+                               if( params[i] == ERRPTR ) {
+                                       while(i--)      Object_Dereference(params[i]);
+                                       ret = ERRPTR;
+                                       goto _return;
                                }
-                               else
-                               {
-                                       ret = SpiderScript_ExecuteFunction(Block->Script,
-                                               Block->CurNamespace, Node->FunctionCall.Name,
-                                               nParams, params
-                                               );
+                               i ++;
+                       }
+                       
+                       if( !Block->CurNamespace )
+                               Block->CurNamespace = Block->BaseNamespace;
+                       
+                       // Call the function
+                       if( Node->Type == NODETYPE_CREATEOBJECT )
+                       {
+                               ret = SpiderScript_CreateObject(Block->Script,
+                                       Block->CurNamespace,
+                                       Node->FunctionCall.Name,
+                                       Node->FunctionCall.NumArgs, params
+                                       );
+                       }
+                       else if( Node->Type == NODETYPE_METHODCALL )
+                       {
+                               tSpiderValue *obj = AST_ExecuteNode(Block, Node->FunctionCall.Object);
+                               if( !obj || obj->Type != SS_DATATYPE_OBJECT ) {
+                                       AST_RuntimeError(Node->FunctionCall.Object,
+                                               "Type Mismatch - Required SS_DATATYPE_OBJECT for method call");
+                                       while(i--)      Object_Dereference(params[i]);
+                                       ret = ERRPTR;
+                                       break;
                                }
-
-                               
-                               // Dereference parameters
-                               while(i--)      Object_Dereference(params[i]);
-                               
-                               // falls out
+                               ret = SpiderScript_ExecuteMethod(Block->Script,
+                                       obj->Object, Node->FunctionCall.Name,
+                                       Node->FunctionCall.NumArgs, params
+                                       );
+                               Object_Dereference(obj);
+                       }
+                       else
+                       {
+                               ret = SpiderScript_ExecuteFunction(Block->Script,
+                                       Block->CurNamespace, Node->FunctionCall.Name,
+                                       Node->FunctionCall.NumArgs, params
+                                       );
                        }
+
+                       
+                       // Dereference parameters
+                       while(i--)      Object_Dereference(params[i]);
+                       
+                       // falls out
                }
                break;
        
@@ -981,6 +1048,12 @@ tSpiderValue *AST_ExecuteNode(tAST_BlockState *Block, tAST_Node *Node)
        
        // --- Operations ---
        // Boolean Operations
+       case NODETYPE_LOGICALNOT:       // Logical NOT (!)
+               op1 = AST_ExecuteNode(Block, Node->UniOp.Value);
+               if(op1 == ERRPTR)       return ERRPTR;
+               ret = SpiderScript_CreateInteger( !SpiderScript_IsValueTrue(op1) );
+               Object_Dereference(op1);
+               break;
        case NODETYPE_LOGICALAND:       // Logical AND (&&)
        case NODETYPE_LOGICALOR:        // Logical OR (||)
        case NODETYPE_LOGICALXOR:       // Logical XOR (^^)
@@ -1015,12 +1088,23 @@ tSpiderValue *AST_ExecuteNode(tAST_BlockState *Block, tAST_Node *Node)
        case NODETYPE_EQUALS:
        case NODETYPE_LESSTHAN:
        case NODETYPE_GREATERTHAN:
+       case NODETYPE_LESSTHANEQUAL:
+       case NODETYPE_GREATERTHANEQUAL:
                op1 = AST_ExecuteNode(Block, Node->BinOp.Left);
                if(op1 == ERRPTR)       return ERRPTR;
                op2 = AST_ExecuteNode(Block, Node->BinOp.Right);
                if(op2 == ERRPTR) {
                        Object_Dereference(op1);
-                       return ERRPTR;
+                       ret = ERRPTR;
+                       break;
+               }
+               
+               if( !op1 || !op2 ) {
+                       AST_RuntimeError(Node, "NULL Comparison (%p and %p)\n", op1, op2);
+                       if(op1) Object_Dereference(op1);
+                       if(op2) Object_Dereference(op2);
+                       ret = SpiderScript_CreateInteger( !op1 && !op2 );
+                       break;
                }
                
                // Convert types
@@ -1073,6 +1157,10 @@ tSpiderValue *AST_ExecuteNode(tAST_BlockState *Block, tAST_Node *Node)
                        else
                                cmp = 1;
                        break;
+               // - Real Number Comparisons
+               case SS_DATATYPE_REAL:
+                       cmp = (op1->Real - op2->Real) / op2->Real * 10000;      // < 0.1% difference is equality
+                       break;
                default:
                        AST_RuntimeError(Node, "TODO - Comparison of type %i", op1->Type);
                        ret = ERRPTR;
@@ -1093,6 +1181,8 @@ tSpiderValue *AST_ExecuteNode(tAST_BlockState *Block, tAST_Node *Node)
                case NODETYPE_EQUALS:   ret = SpiderScript_CreateInteger(cmp == 0);     break;
                case NODETYPE_LESSTHAN: ret = SpiderScript_CreateInteger(cmp < 0);      break;
                case NODETYPE_GREATERTHAN:      ret = SpiderScript_CreateInteger(cmp > 0);      break;
+               case NODETYPE_LESSTHANEQUAL:    ret = SpiderScript_CreateInteger(cmp <= 0);     break;
+               case NODETYPE_GREATERTHANEQUAL: ret = SpiderScript_CreateInteger(cmp >= 0);     break;
                default:
                        AST_RuntimeError(Node, "Exec,CmpOp unknown op %i", Node->Type);
                        ret = ERRPTR;
@@ -1100,6 +1190,15 @@ tSpiderValue *AST_ExecuteNode(tAST_BlockState *Block, tAST_Node *Node)
                }
                break;
        
+       // General Unary Operations
+       case NODETYPE_BWNOT:    // Bitwise NOT (~)
+       case NODETYPE_NEGATE:   // Negation (-)
+               op1 = AST_ExecuteNode(Block, Node->UniOp.Value);
+               if(op1 == ERRPTR)       return ERRPTR;
+               ret = AST_ExecuteNode_UniOp(Block, Node->Type, op1);
+               Object_Dereference(op1);
+               break;
+       
        // General Binary Operations
        case NODETYPE_ADD:
        case NODETYPE_SUBTRACT:
@@ -1137,6 +1236,64 @@ _return:
        return ret;
 }
 
+tSpiderValue *AST_ExecuteNode_UniOp(tAST_BlockState *Block, int Operation, tSpiderValue *Value)
+{
+       tSpiderValue    *ret;
+       #if 0
+       if( Value->Type == SS_DATATYPE_OBJECT )
+       {
+               const char      *fcnname;
+               switch(Operation)
+               {
+               case NODETYPE_NEGATE:   fcnname = "-ve";        break;
+               case NODETYPE_BWNOT:    fcnname = "~";  break;
+               default:        fcnname = NULL; break;
+               }
+               
+               if( fcnname )
+               {
+                       ret = Object_ExecuteMethod(Value->Object, fcnname, );
+                       if( ret != ERRPTR )
+                               return ret;
+                       // Fall through and try casting (which will usually fail)
+               }
+       }
+       #endif
+       switch(Value->Type)
+       {
+       // Integer Operations
+       case SS_DATATYPE_INTEGER:
+               switch(Operation)
+               {
+               case NODETYPE_NEGATE:   ret = SpiderScript_CreateInteger( -Value->Integer );    break;
+               case NODETYPE_BWNOT:    ret = SpiderScript_CreateInteger( ~Value->Integer );    break;
+               default:
+                       AST_RuntimeError(NULL, "SpiderScript internal error: Exec,UniOP,Integer unknown op %i", Operation);
+                       ret = ERRPTR;
+                       break;
+               }
+               break;
+       // Real number Operations
+       case SS_DATATYPE_REAL:
+               switch(Operation)
+               {
+               case NODETYPE_NEGATE:   ret = SpiderScript_CreateInteger( -Value->Real );       break;
+               default:
+                       AST_RuntimeError(NULL, "SpiderScript internal error: Exec,UniOP,Real unknown op %i", Operation);
+                       ret = ERRPTR;
+                       break;
+               }
+               break;
+       
+       default:
+               AST_RuntimeError(NULL, "Invalid operation (%i) on type (%i)", Operation, Value->Type);
+               ret = ERRPTR;
+               break;
+       }
+       
+       return ret;
+}
+
 tSpiderValue *AST_ExecuteNode_BinOp(tAST_BlockState *Block, int Operation, tSpiderValue *Left, tSpiderValue *Right)
 {
        tSpiderValue    *preCastValue = Right;
@@ -1241,6 +1398,10 @@ tSpiderValue *AST_ExecuteNode_BinOp(tAST_BlockState *Block, int Operation, tSpid
        case SS_DATATYPE_REAL:
                switch(Operation)
                {
+               case NODETYPE_ADD:      ret = SpiderScript_CreateReal( Left->Real + Right->Real );      break;
+               case NODETYPE_SUBTRACT: ret = SpiderScript_CreateReal( Left->Real - Right->Real );      break;
+               case NODETYPE_MULTIPLY: ret = SpiderScript_CreateReal( Left->Real * Right->Real );      break;
+               case NODETYPE_DIVIDE:   ret = SpiderScript_CreateReal( Left->Real / Right->Real );      break;
                default:
                        AST_RuntimeError(NULL, "SpiderScript internal error: Exec,BinOP,Real unknown op %i", Operation);
                        ret = ERRPTR;
index bd1712b..be3a15b 100644 (file)
@@ -163,8 +163,22 @@ int GetToken(tParser *File)
                ret = TOK_AND;
                break;
        
-       case '/':       ret = TOK_DIV;  break;
-       case '*':       ret = TOK_MUL;  break;
+       case '/':
+               if( *File->CurPos == '=' ) {
+                       File->CurPos ++;
+                       ret = TOK_ASSIGN_DIV;
+                       break;
+               }
+               ret = TOK_DIV;
+               break;
+       case '*':
+               if( *File->CurPos == '=' ) {
+                       File->CurPos ++;
+                       ret = TOK_ASSIGN_MUL;
+                       break;
+               }
+               ret = TOK_MUL;
+               break;
        case '+':
                if( *File->CurPos == '+' ) {
                        File->CurPos ++;
@@ -201,8 +215,13 @@ int GetToken(tParser *File)
        case '"':
                while( *File->CurPos && !(*File->CurPos == '"' && *File->CurPos != '\\') )
                        File->CurPos ++;
-               File->CurPos ++;
-               ret = TOK_STR;
+               if( *File->CurPos )
+               {
+                       File->CurPos ++;
+                       ret = TOK_STR;
+               }
+               else
+                       ret = TOK_EOF;
                break;
        
        // Brackets
@@ -254,6 +273,15 @@ int GetToken(tParser *File)
                ret = TOK_GT;
                break;
        
+       // Logical NOT
+       case '!':
+               ret = TOK_LOGICNOT;
+               break;
+       // Bitwise NOT
+       case '~':
+               ret = TOK_BWNOT;
+               break;
+       
        // Variables
        // \$[0-9]+ or \$[_a-zA-Z][_a-zA-Z0-9]*
        case '$':
@@ -277,6 +305,7 @@ int GetToken(tParser *File)
                // Numbers
                if( isdigit(*File->CurPos) )
                {
+                       ret = TOK_INTEGER;
                        if( *File->CurPos == '0' && File->CurPos[1] == 'x' ) {
                                File->CurPos += 2;
                                while(('0' <= *File->CurPos && *File->CurPos <= '9')
@@ -289,21 +318,40 @@ int GetToken(tParser *File)
                        else {
                                while( isdigit(*File->CurPos) )
                                        File->CurPos ++;
+                               
+                               // Decimal
+                               if( *File->CurPos == '.' )
+                               {
+                                       ret = TOK_REAL;
+                                       File->CurPos ++;
+                                       while( isdigit(*File->CurPos) )
+                                               File->CurPos ++;
+                               }
+                               // Exponent
+                               if( *File->CurPos == 'e' || *File->CurPos == 'E' )
+                               {
+                                       ret = TOK_REAL;
+                                       File->CurPos ++;
+                                       if(*File->CurPos == '-' || *File->CurPos == '+')
+                                               File->CurPos ++;
+                                       while( isdigit(*File->CurPos) )
+                                               File->CurPos ++;
+                               }
                        }
-                       ret = TOK_INTEGER;
                        break;
                }
        
                // Identifier
                if( is_ident(*File->CurPos) )
                {
+                       ret = TOK_IDENT;
+                       
                        // Identifier
                        while( is_ident(*File->CurPos) || isdigit(*File->CurPos) )
                                File->CurPos ++;
                        
                        // This is set later too, but we use it below
                        File->TokenLen = File->CurPos - File->TokenStr;
-                       ret = TOK_IDENT;
                        
                        // Check if it's a reserved word
                        {
index 20554f5..919a6f2 100644 (file)
@@ -42,10 +42,6 @@ tSpiderScript *SpiderScript_ParseFile(tSpiderVariant *Variant, const char *Filen
                return NULL;
        }
        
-       // Create the script
-       ret = malloc(sizeof(tSpiderScript));
-       ret->Variant = Variant;
-       
        fseek(fp, 0, SEEK_END);
        fLen = ftell(fp);
        fseek(fp, 0, SEEK_SET);
@@ -53,11 +49,19 @@ tSpiderScript *SpiderScript_ParseFile(tSpiderVariant *Variant, const char *Filen
        // Allocate and read data
        data = malloc(fLen + 1);
        if(!data)       return NULL;
-       fread(data, fLen, 1, fp);
+       fLen = fread(data, 1, fLen, fp);
+       if( fLen < 0 ) {
+               free(data);
+               return NULL;
+       }
        data[fLen] = '\0';
        
        fclose(fp);
        
+       // Create the script
+       ret = malloc(sizeof(tSpiderScript));
+       ret->Variant = Variant;
+       
        ret->CurNamespace = NULL;
        ret->Script = Parse_Buffer(Variant, data);
        if( ret->Script == NULL ) {
index 907c729..e04bc25 100644 (file)
@@ -25,6 +25,8 @@ tAST_Node     *Parse_DoExpr3(tParser *Parser);        // Bitwise Operators
 tAST_Node      *Parse_DoExpr4(tParser *Parser);        // Bit Shifts
 tAST_Node      *Parse_DoExpr5(tParser *Parser);        // Arithmatic
 tAST_Node      *Parse_DoExpr6(tParser *Parser);        // Mult & Div
+tAST_Node      *Parse_DoExpr7(tParser *Parser);        // Right Unary Operations
+tAST_Node      *Parse_DoExpr8(tParser *Parser);        // Left Unary Operations
 
 tAST_Node      *Parse_DoParen(tParser *Parser);        // Parenthesis (Always Last)
 tAST_Node      *Parse_DoValue(tParser *Parser);        // Values
@@ -218,6 +220,8 @@ tAST_Node *Parse_DoBlockLine(tParser *Parser)
                        GetToken(Parser);
                        false = Parse_DoCodeBlock(Parser);
                }
+               else
+                       false = AST_NewNop(Parser);
                ret = AST_NewIf(Parser, cond, true, false);
                }
                return ret;
@@ -249,22 +253,35 @@ tAST_Node *Parse_DoBlockLine(tParser *Parser)
                return ret;
        
        case TOK_RWD_DO:
-       case TOK_RWD_WHILE:
-               TODO(Parser, "Implement do and while\n");
+               {
+               tAST_Node       *code, *cond;
+               GetToken(Parser);       // Eat 'do'
+               code = Parse_DoCodeBlock(Parser);
+               SyntaxAssert( Parser, GetToken(Parser), TOK_RWD_WHILE );
+               SyntaxAssert( Parser, GetToken(Parser), TOK_PAREN_OPEN );
+               cond = Parse_DoExpr0(Parser);
+               SyntaxAssert( Parser, GetToken(Parser), TOK_PAREN_CLOSE );
+               ret = AST_NewLoop(Parser, AST_NewNop(Parser), 1, cond, AST_NewNop(Parser), code);
+               }
                break;
+       case TOK_RWD_WHILE:
+               {
+               tAST_Node       *code, *cond;
+               GetToken(Parser);       // Eat 'while'
+               SyntaxAssert( Parser, GetToken(Parser), TOK_PAREN_OPEN );
+               cond = Parse_DoExpr0(Parser);
+               SyntaxAssert( Parser, GetToken(Parser), TOK_PAREN_CLOSE );
+               code = Parse_DoCodeBlock(Parser);
+               ret = AST_NewLoop(Parser, AST_NewNop(Parser), 0, cond, AST_NewNop(Parser), code);
+               }
+               return ret;
        
        // Define Variables
        case TOKEN_GROUP_TYPES:
                {
                         int    type;
-                       
-                       switch(GetToken(Parser))
-                       {
-                       case TOK_RWD_INTEGER:   type = SS_DATATYPE_INTEGER;     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;
-                       }
+                       GetToken(Parser);
+                       TOKEN_GET_DATATYPE(type, Parser->Token);
                        
                        SyntaxAssert(Parser, GetToken(Parser), TOK_VARIABLE);
                        
@@ -391,6 +408,12 @@ tAST_Node *Parse_DoExpr2(tParser *Parser)
        case TOK_GT:
                ret = AST_NewBinOp(Parser, NODETYPE_GREATERTHAN, ret, Parse_DoExpr2(Parser));
                break;
+       case TOK_LTE:
+               ret = AST_NewBinOp(Parser, NODETYPE_LESSTHANEQUAL, ret, Parse_DoExpr2(Parser));
+               break;
+       case TOK_GTE:
+               ret = AST_NewBinOp(Parser, NODETYPE_GREATERTHANEQUAL, ret, Parse_DoExpr2(Parser));
+               break;
        default:
                PutBack(Parser);
                break;
@@ -475,7 +498,7 @@ tAST_Node *Parse_DoExpr5(tParser *Parser)
 // --------------------
 tAST_Node *Parse_DoExpr6(tParser *Parser)
 {
-       tAST_Node *ret = Parse_DoParen(Parser);
+       tAST_Node *ret = Parse_DoExpr7(Parser);
 
        switch(GetToken(Parser))
        {
@@ -493,6 +516,46 @@ tAST_Node *Parse_DoExpr6(tParser *Parser)
        return ret;
 }
 
+// Right Unary Operations
+tAST_Node *Parse_DoExpr7(tParser *Parser)
+{
+       tAST_Node *ret = Parse_DoExpr8(Parser);
+       
+       switch(GetToken(Parser))
+       {
+       case TOK_INCREMENT:
+               ret = AST_NewUniOp(Parser, NODETYPE_POSTINC, ret);
+               break;
+       case TOK_DECREMENT:
+               ret = AST_NewUniOp(Parser, NODETYPE_POSTDEC, ret);
+               break;
+       default:
+               PutBack(Parser);
+               break;
+       }
+       return ret;
+}
+
+// Left Unary Operations
+tAST_Node *Parse_DoExpr8(tParser *Parser)
+{
+       switch(GetToken(Parser))
+       {
+       case TOK_INCREMENT:
+               return AST_NewAssign(Parser, NODETYPE_ADD, Parse_DoExpr8(Parser), AST_NewInteger(Parser, 1));
+       case TOK_DECREMENT:
+               return AST_NewAssign(Parser, NODETYPE_SUBTRACT, Parse_DoExpr8(Parser), AST_NewInteger(Parser, 1));
+       case TOK_MINUS:
+               return AST_NewUniOp(Parser, NODETYPE_NEGATE, Parse_DoExpr8(Parser));
+       case TOK_LOGICNOT:
+               return AST_NewUniOp(Parser, NODETYPE_LOGICALNOT, Parse_DoExpr8(Parser));
+       case TOK_BWNOT:
+               return AST_NewUniOp(Parser, NODETYPE_BWNOT, Parse_DoExpr8(Parser));
+       default:
+               PutBack(Parser);
+               return Parse_DoParen(Parser);
+       }
+}
 
 // --------------------
 // 2nd Last Expression - Parens
@@ -543,6 +606,10 @@ tAST_Node *Parse_DoValue(tParser *Parser)
        {
        case TOK_STR:   return Parse_GetString(Parser);
        case TOK_INTEGER:       return Parse_GetNumeric(Parser);
+       case TOK_REAL:
+               GetToken(Parser);
+               return AST_NewReal( Parser, atof(Parser->TokenStr) );
+       
        case TOK_IDENT: return Parse_GetIdent(Parser, 0);
        case TOK_VARIABLE:      return Parse_GetVariable(Parser);
        case TOK_RWD_NEW:
@@ -601,7 +668,7 @@ tAST_Node *Parse_GetNumeric(tParser *Parser)
 {
        uint64_t        value = 0;
        char    *pos;
-       GetToken( Parser );
+       SyntaxAssert( Parser, GetToken( Parser ), TOK_INTEGER );
        pos = Parser->TokenStr;
        //printf("pos = %p, *pos = %c\n", pos, *pos);
                
index 5a529f7..33128cf 100644 (file)
@@ -41,6 +41,7 @@ enum eTokens
        // Primitives
        TOK_STR,
        TOK_INTEGER,
+       TOK_REAL,
        TOK_VARIABLE,
        TOK_IDENT,
        
@@ -80,6 +81,7 @@ enum eTokens
        TOK_GT, TOK_GTE,
        
        // Operations
+       TOK_BWNOT,      TOK_LOGICNOT,
        TOK_DIV,        TOK_MUL,
        TOK_PLUS,       TOK_MINUS,
        TOK_SHL,        TOK_SHR,
@@ -116,7 +118,7 @@ enum eTokens
        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;\
-       default:fprintf(stderr,\
+       default:_type=SS_DATATYPE_UNDEF;fprintf(stderr,\
        "ERROR: Unexpected %s, expected "TOKEN_GROUP_TYPES_STR"\n",csaTOKEN_NAMES[Parser->Token]);\
        break;\
        } } while(0)
@@ -128,6 +130,7 @@ const char * const csaTOKEN_NAMES[] = {
        
        "TOK_STR",
        "TOK_INTEGER",
+       "TOK_REAL",
        "TOK_VARIABLE",
        "TOK_IDENT",
        
@@ -162,6 +165,7 @@ const char * const csaTOKEN_NAMES[] = {
        "TOK_LT",       "TOK_LTE",
        "TOK_GT",       "TOK_GTE",
        
+       "TOK_BWNOT",    "TOK_LOGICNOT",
        "TOK_DIV",      "TOK_MUL",
        "TOK_PLUS",     "TOK_MINUS",
        "TOK_SHL",      "TOK_SHR",

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