From 3887bf8941fe33071d061961f213a7da360af02a Mon Sep 17 00:00:00 2001 From: John Hodge Date: Thu, 26 Aug 2010 17:21:10 +0800 Subject: [PATCH] SpiderScript: String Casts, Escape Codes, Size for Opaque data types --- .../Libraries/libspiderscript.so_src/ast.c | 25 ++++++++++ .../Libraries/libspiderscript.so_src/ast.h | 4 +- .../libspiderscript.so_src/exec_ast.c | 35 +++++++++++++- .../Libraries/libspiderscript.so_src/parse.c | 47 +++++++++++++++++-- Usermode/include/spiderscript.h | 1 + 5 files changed, 104 insertions(+), 8 deletions(-) diff --git a/Usermode/Libraries/libspiderscript.so_src/ast.c b/Usermode/Libraries/libspiderscript.so_src/ast.c index 8df54697..1a6c3e97 100644 --- a/Usermode/Libraries/libspiderscript.so_src/ast.c +++ b/Usermode/Libraries/libspiderscript.so_src/ast.c @@ -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; diff --git a/Usermode/Libraries/libspiderscript.so_src/ast.h b/Usermode/Libraries/libspiderscript.so_src/ast.h index 8b9c25b0..4c09aefc 100644 --- a/Usermode/Libraries/libspiderscript.so_src/ast.h +++ b/Usermode/Libraries/libspiderscript.so_src/ast.h @@ -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); diff --git a/Usermode/Libraries/libspiderscript.so_src/exec_ast.c b/Usermode/Libraries/libspiderscript.so_src/exec_ast.c index a9125955..fc931f72 100644 --- a/Usermode/Libraries/libspiderscript.so_src/exec_ast.c +++ b/Usermode/Libraries/libspiderscript.so_src/exec_ast.c @@ -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; } diff --git a/Usermode/Libraries/libspiderscript.so_src/parse.c b/Usermode/Libraries/libspiderscript.so_src/parse.c index b25dd212..720a2fe2 100644 --- a/Usermode/Libraries/libspiderscript.so_src/parse.c +++ b/Usermode/Libraries/libspiderscript.so_src/parse.c @@ -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; } diff --git a/Usermode/include/spiderscript.h b/Usermode/include/spiderscript.h index 2a8272a1..409cf493 100644 --- a/Usermode/include/spiderscript.h +++ b/Usermode/include/spiderscript.h @@ -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; -- 2.20.1