SpiderScript: String Casts, Escape Codes, Size for Opaque data types
authorJohn Hodge <[email protected]>
Thu, 26 Aug 2010 09:21:10 +0000 (17:21 +0800)
committerJohn Hodge <[email protected]>
Thu, 26 Aug 2010 09:21:10 +0000 (17:21 +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/parse.c
Usermode/include/spiderscript.h

index 8df5469..1a6c3e9 100644 (file)
@@ -173,6 +173,7 @@ tAST_Node *AST_NewCodeBlock(void)
        tAST_Node       *ret = malloc( sizeof(tAST_Node) );
        
        ret->NextSibling = NULL;
+       //ret->Line = giLineNumber;
        ret->Type = NODETYPE_BLOCK;
        ret->Block.FirstChild = NULL;
        ret->Block.LastChild = NULL;
@@ -213,6 +214,7 @@ tAST_Node *AST_NewIf(tAST_Node *Condition, tAST_Node *True, tAST_Node *False)
 {
        tAST_Node       *ret = malloc( sizeof(tAST_Node) );
        ret->NextSibling = NULL;
+       //ret->Line = giLineNumber;
        ret->Type = NODETYPE_IF;
        ret->If.Condition = Condition;
        ret->If.True = True;
@@ -224,6 +226,7 @@ tAST_Node *AST_NewLoop(tAST_Node *Init, int bPostCheck, tAST_Node *Condition, tA
 {
        tAST_Node       *ret = malloc( sizeof(tAST_Node) );
        ret->NextSibling = NULL;
+       //ret->Line = giLineNumber;
        ret->Type = NODETYPE_LOOP;
        ret->For.Init = Init;
        ret->For.bCheckAfter = !!bPostCheck;
@@ -238,6 +241,7 @@ tAST_Node *AST_NewAssign(int Operation, tAST_Node *Dest, tAST_Node *Value)
        tAST_Node       *ret = malloc( sizeof(tAST_Node) );
        
        ret->NextSibling = NULL;
+       //ret->Line = giLineNumber;
        ret->Type = NODETYPE_ASSIGN;
        ret->Assign.Operation = Operation;
        ret->Assign.Dest = Dest;
@@ -246,11 +250,25 @@ tAST_Node *AST_NewAssign(int Operation, tAST_Node *Dest, tAST_Node *Value)
        return ret;
 }
 
+tAST_Node *AST_NewCast(int Target, tAST_Node *Value)
+{
+       tAST_Node       *ret = malloc( sizeof(tAST_Node) );
+       
+       ret->NextSibling = NULL;
+       //ret->Line = giLineNumber;
+       ret->Type = NODETYPE_CAST;
+       ret->Cast.DataType = Target;
+       ret->Cast.Value = Value;
+       
+       return ret;
+}
+
 tAST_Node *AST_NewBinOp(int Operation, tAST_Node *Left, tAST_Node *Right)
 {
        tAST_Node       *ret = malloc( sizeof(tAST_Node) );
        
        ret->NextSibling = NULL;
+       //ret->Line = giLineNumber;
        ret->Type = Operation;
        ret->BinOp.Left = Left;
        ret->BinOp.Right = Right;
@@ -265,6 +283,7 @@ tAST_Node *AST_NewUniOp(int Operation, tAST_Node *Value)
        tAST_Node       *ret = malloc( sizeof(tAST_Node) );
        
        ret->NextSibling = NULL;
+       //ret->Line = giLineNumber;
        ret->Type = Operation;
        ret->UniOp.Value = Value;
        
@@ -279,6 +298,7 @@ tAST_Node *AST_NewString(const char *String, int Length)
        tAST_Node       *ret = malloc( sizeof(tAST_Node) + Length + 1 );
        
        ret->NextSibling = NULL;
+       //ret->Line = giLineNumber;
        ret->Type = NODETYPE_STRING;
        ret->String.Length = Length;
        memcpy(ret->String.Data, String, Length);
@@ -294,6 +314,7 @@ tAST_Node *AST_NewInteger(uint64_t Value)
 {
        tAST_Node       *ret = malloc( sizeof(tAST_Node) );
        ret->NextSibling = NULL;
+       //ret->Line = giLineNumber;
        ret->Type = NODETYPE_INTEGER;
        ret->Integer = Value;
        return ret;
@@ -306,6 +327,7 @@ tAST_Node *AST_NewVariable(const char *Name)
 {
        tAST_Node       *ret = malloc( sizeof(tAST_Node) + strlen(Name) + 1 );
        ret->NextSibling = NULL;
+       //ret->Line = giLineNumber;
        ret->Type = NODETYPE_VARIABLE;
        strcpy(ret->Variable.Name, Name);
        return ret;
@@ -318,6 +340,7 @@ tAST_Node *AST_NewDefineVar(int Type, const char *Name)
 {
        tAST_Node       *ret = malloc( sizeof(tAST_Node) + strlen(Name) + 1 );
        ret->NextSibling = NULL;
+       //ret->Line = giLineNumber;
        ret->Type = NODETYPE_DEFVAR;
        ret->DefVar.DataType = Type;
        ret->DefVar.LevelSizes = NULL;
@@ -332,6 +355,7 @@ tAST_Node *AST_NewConstant(const char *Name)
 {
        tAST_Node       *ret = malloc( sizeof(tAST_Node) + strlen(Name) + 1 );
        ret->NextSibling = NULL;
+       //ret->Line = giLineNumber;
        ret->Type = NODETYPE_CONSTANT;
        strcpy(ret->Variable.Name, Name);
        return ret;
@@ -346,6 +370,7 @@ tAST_Node *AST_NewFunctionCall(const char *Name)
        tAST_Node       *ret = malloc( sizeof(tAST_Node) + strlen(Name) + 1 );
        
        ret->NextSibling = NULL;
+       //ret->Line = giLineNumber;
        ret->Type = NODETYPE_FUNCTIONCALL;
        ret->FunctionCall.FirstArg = NULL;
        ret->FunctionCall.LastArg = NULL;
index 8b9c25b..4c09aef 100644 (file)
@@ -89,6 +89,8 @@ struct sAST_Node
        tAST_Node       *NextSibling;
        tAST_NodeType   Type;
        
+        int    Line;
+       
        union
        {
                struct {
@@ -187,7 +189,6 @@ extern tAST_Script  *AST_NewScript(void);
 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_NewString(const char *String, int Length);
 extern tAST_Node       *AST_NewInteger(uint64_t Value);
 extern tAST_Node       *AST_NewVariable(const char *Name);
@@ -202,6 +203,7 @@ extern void AST_AppendNode(tAST_Node *Parent, tAST_Node *Child);
 extern tAST_Node       *AST_NewIf(tAST_Node *Condition, tAST_Node *True, tAST_Node *False);
 
 extern tAST_Node       *AST_NewAssign(int Operation, tAST_Node *Dest, tAST_Node *Value);
+extern tAST_Node       *AST_NewCast(int Target, tAST_Node *Value);
 extern tAST_Node       *AST_NewBinOp(int Operation, tAST_Node *Left, tAST_Node *Right);
 extern tAST_Node       *AST_NewUniOp(int Operation, tAST_Node *Value);
 
index a912595..fc931f7 100644 (file)
@@ -29,6 +29,7 @@ void  Variable_Destroy(tAST_Variable *Variable);
 void Object_Dereference(tSpiderValue *Object)
 {
        if(!Object)     return ;
+       if(Object == ERRPTR)    return ;
        Object->ReferenceCount --;
        if( Object->ReferenceCount == 0 ) {
                switch( (enum eSpiderScript_DataTypes) Object->Type )
@@ -123,6 +124,8 @@ tSpiderValue *Object_StringConcat(tSpiderValue *Str1, tSpiderValue *Str2)
 tSpiderValue *SpiderScript_CastValueTo(int Type, tSpiderValue *Source)
 {
        tSpiderValue    *ret = ERRPTR;
+        int    len = 0;
+       
        // Check if anything needs to be done
        if( Source->Type == Type ) {
                Object_Reference(Source);
@@ -154,6 +157,30 @@ tSpiderValue *SpiderScript_CastValueTo(int Type, tSpiderValue *Source)
                        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;
+               default:        break;
+               }
+               ret = malloc(sizeof(tSpiderValue) + len + 1);
+               ret->Type = SS_DATATYPE_STRING;
+               ret->ReferenceCount = 1;
+               ret->String.Length = len;
+               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;
+               default:
+                       fprintf(stderr, "SpiderScript_CastValueTo - Invalid cast from %i\n", Source->Type);
+                       free(ret);
+                       ret = ERRPTR;
+                       break;
+               }
+               break;
+       
        default:
                fprintf(stderr, "BUG REPORT: Unimplemented cast target\n");
                break;
@@ -492,7 +519,8 @@ tSpiderValue *AST_ExecuteNode(tAST_BlockState *Block, tAST_Node *Node)
                        }
                        // If statically typed, this should never happen, but catch it anyway
                        else {
-                               fprintf(stderr, "PARSER ERROR: Statically typed implicit cast\n");
+                               fprintf(stderr, "PARSER ERROR: Statically typed implicit cast (line %i)\n",
+                                       Node->Line);
                                ret = ERRPTR;
                                break;
                        }
@@ -582,7 +610,10 @@ tSpiderValue *AST_ExecuteNode(tAST_BlockState *Block, tAST_Node *Node)
                        }
                        // If statically typed, this should never happen, but catch it anyway
                        else {
-                               fprintf(stderr, "PARSER ERROR: Statically typed implicit cast\n");
+                               fprintf(stderr,
+                                       "PARSER ERROR: Statically typed implicit cast (from %i to %i)\n",
+                                       op2->Type, op1->Type
+                                       );
                                ret = ERRPTR;
                                break;
                        }
index b25dd21..720a2fe 100644 (file)
@@ -470,12 +470,23 @@ tAST_Node *Parse_DoParen(tParser *Parser)
        if(LookAhead(Parser) == TOK_PAREN_OPEN)
        {
                tAST_Node       *ret;
+                int    type;
                GetToken(Parser);
                
                // TODO: Handle casts here
-               
-               ret = Parse_DoExpr0(Parser);
-               SyntaxAssert(Parser, GetToken(Parser), TOK_PAREN_CLOSE);
+               switch(LookAhead(Parser))
+               {
+               case TOKEN_GROUP_TYPES:
+                       GetToken(Parser);
+                       TOKEN_GET_DATATYPE(type, Parser->Token);
+                       SyntaxAssert(Parser, GetToken(Parser), TOK_PAREN_CLOSE);
+                       ret = AST_NewCast(type, Parse_DoParen(Parser));
+                       break;
+               default:                
+                       ret = Parse_DoExpr0(Parser);
+                       SyntaxAssert(Parser, GetToken(Parser), TOK_PAREN_CLOSE);
+                       break;
+               }
                return ret;
        }
        else
@@ -513,9 +524,35 @@ tAST_Node *Parse_DoValue(tParser *Parser)
 tAST_Node *Parse_GetString(tParser *Parser)
 {
        tAST_Node       *ret;
+        int    i, j;
        GetToken( Parser );
-       // TODO: Parse Escape Codes
-       ret = AST_NewString( Parser->TokenStr+1, Parser->TokenLen-2 );
+       
+       {
+               char    data[ Parser->TokenLen - 2 ];
+               j = 0;
+               
+               for( i = 1; i < Parser->TokenLen - 1; i++ )
+               {
+                       if( Parser->TokenStr[i] == '\\' ) {
+                               i ++;
+                               switch( Parser->TokenStr[i] )
+                               {
+                               case 'n':       data[j++] = '\n';       break;
+                               case 'r':       data[j++] = '\r';       break;
+                               default:
+                                       // TODO: Octal Codes
+                                       // TODO: Error/Warning?
+                                       break;
+                               }
+                       }
+                       else {
+                               data[j++] = Parser->TokenStr[i];
+                       }
+               }
+               
+               // TODO: Parse Escape Codes
+               ret = AST_NewString( data, j );
+       }
        return ret;
 }
 
index 2a8272a..409cf49 100644 (file)
@@ -84,6 +84,7 @@ struct sSpiderValue
                 */
                struct {
                        void    *Data;  //!< Data (can be anywhere)
+                        int    Size;   //!< Data size (zero means full opaque)
                        void    (*Destroy)(void *Data); //!< Called on GC
                }       Opaque;
                

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