X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=Usermode%2FLibraries%2Flibspiderscript.so_src%2Fparse.c;h=c3a682489bda2fd3b413fbd62239719380ba01c4;hb=0f81e4f273cdf1032e9bca55b4185ca9113596cc;hp=3ac6fa8432309da1428f761d813b4b2d5a8576c8;hpb=e89bb46ecd13feaa786f8b156d5195835aaf459e;p=tpg%2Facess2.git diff --git a/Usermode/Libraries/libspiderscript.so_src/parse.c b/Usermode/Libraries/libspiderscript.so_src/parse.c index 3ac6fa84..c3a68248 100644 --- a/Usermode/Libraries/libspiderscript.so_src/parse.c +++ b/Usermode/Libraries/libspiderscript.so_src/parse.c @@ -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 @@ -32,7 +34,7 @@ tAST_Node *Parse_DoValue(tParser *Parser); // Values tAST_Node *Parse_GetString(tParser *Parser); tAST_Node *Parse_GetNumeric(tParser *Parser); tAST_Node *Parse_GetVariable(tParser *Parser); -tAST_Node *Parse_GetIdent(tParser *Parser); +tAST_Node *Parse_GetIdent(tParser *Parser, int bObjectCreate); void SyntaxAssert(tParser *Parser, int Have, int Want); @@ -48,7 +50,7 @@ void SyntaxAssert(tParser *Parser, int Have, int Want); tAST_Script *Parse_Buffer(tSpiderVariant *Variant, char *Buffer) { tParser parser = {0}; - tParser *Parser = &parser; //< Keeps code consitent + tParser *Parser = &parser; //< Keeps code consistent tAST_Script *ret; tAST_Node *mainCode; char *name; @@ -67,7 +69,7 @@ tAST_Script *Parse_Buffer(tSpiderVariant *Variant, char *Buffer) parser.CurPos = Buffer; ret = AST_NewScript(); - mainCode = AST_NewCodeBlock(); + mainCode = AST_NewCodeBlock(&parser); // Give us an error fallback if( setjmp( parser.JmpTarget ) != 0 ) @@ -173,7 +175,7 @@ tAST_Node *Parse_DoCodeBlock(tParser *Parser) return Parse_DoBlockLine(Parser); } - ret = AST_NewCodeBlock(); + ret = AST_NewCodeBlock(Parser); while( LookAhead(Parser) != TOK_BRACE_CLOSE ) { @@ -194,10 +196,13 @@ tAST_Node *Parse_DoBlockLine(tParser *Parser) switch(LookAhead(Parser)) { + // Empty statement + case TOK_SEMICOLON: + GetToken(Parser); + return NULL; // Return from a method case TOK_RWD_RETURN: - //printf("return\n"); GetToken(Parser); ret = AST_NewUniOp(Parser, NODETYPE_RETURN, Parse_DoExpr0(Parser)); break; @@ -215,27 +220,68 @@ 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; + case TOK_RWD_FOR: + { + tAST_Node *init=NULL, *cond=NULL, *inc=NULL, *code; + GetToken(Parser); // Eat 'for' + SyntaxAssert(Parser, GetToken(Parser), TOK_PAREN_OPEN); + + if(LookAhead(Parser) != TOK_SEMICOLON) + init = Parse_DoExpr0(Parser); + + SyntaxAssert(Parser, GetToken(Parser), TOK_SEMICOLON); + + if(LookAhead(Parser) != TOK_SEMICOLON) + cond = Parse_DoExpr0(Parser); + + SyntaxAssert(Parser, GetToken(Parser), TOK_SEMICOLON); + + if(LookAhead(Parser) != TOK_PAREN_CLOSE) + inc = Parse_DoExpr0(Parser); + + SyntaxAssert(Parser, GetToken(Parser), TOK_PAREN_CLOSE); + + code = Parse_DoCodeBlock(Parser); + ret = AST_NewLoop(Parser, init, 0, cond, inc, code); + } + return ret; + case TOK_RWD_DO: - case TOK_RWD_WHILE: - TODO(Parser, "Implement if, for, 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); @@ -293,16 +339,22 @@ tAST_Node *Parse_DoExpr0(tParser *Parser) GetToken(Parser); // Eat Token ret = AST_NewAssign(Parser, NODETYPE_NOP, ret, Parse_DoExpr0(Parser)); break; - #if 0 - case TOK_DIV_EQU: + case TOK_ASSIGN_DIV: GetToken(Parser); // Eat Token ret = AST_NewAssign(Parser, NODETYPE_DIVIDE, ret, Parse_DoExpr0(Parser)); break; - case TOK_MULT_EQU: + case TOK_ASSIGN_MUL: GetToken(Parser); // Eat Token ret = AST_NewAssign(Parser, NODETYPE_MULTIPLY, ret, Parse_DoExpr0(Parser)); break; - #endif + case TOK_ASSIGN_PLUS: + GetToken(Parser); // Eat Token + ret = AST_NewAssign(Parser, NODETYPE_ADD, ret, Parse_DoExpr0(Parser)); + break; + case TOK_ASSIGN_MINUS: + GetToken(Parser); // Eat Token + ret = AST_NewAssign(Parser, NODETYPE_SUBTRACT, ret, Parse_DoExpr0(Parser)); + break; default: #if DEBUG >= 2 printf("Parse_DoExpr0: Parser->Token = %i\n", Parser->Token); @@ -356,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; @@ -440,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)) { @@ -458,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 @@ -506,10 +604,20 @@ tAST_Node *Parse_DoValue(tParser *Parser) switch(tok) { - case TOK_STR: return Parse_GetString(Parser); - case TOK_INTEGER: return Parse_GetNumeric(Parser); - case TOK_IDENT: return Parse_GetIdent(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: + GetToken(Parser); // Omnomnom + return Parse_GetIdent(Parser, 1); default: fprintf(stderr, "Syntax Error: Unexpected %s on line %i, Expected TOK_T_VALUE\n", @@ -563,7 +671,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); @@ -623,30 +731,70 @@ tAST_Node *Parse_GetVariable(tParser *Parser) printf("Parse_GetVariable: name = '%s'\n", name); #endif } - // Handle array references - while( LookAhead(Parser) == TOK_SQUARE_OPEN ) + for(;;) { GetToken(Parser); - ret = AST_NewBinOp(Parser, NODETYPE_INDEX, ret, Parse_DoExpr0(Parser)); - SyntaxAssert(Parser, GetToken(Parser), TOK_SQUARE_CLOSE); + if( Parser->Token == TOK_SQUARE_OPEN ) + { + ret = AST_NewBinOp(Parser, NODETYPE_INDEX, ret, Parse_DoExpr0(Parser)); + SyntaxAssert(Parser, GetToken(Parser), TOK_SQUARE_CLOSE); + continue ; + } + if( Parser->Token == TOK_ELEMENT ) + { + SyntaxAssert(Parser, GetToken(Parser), TOK_IDENT); + // Method Call + if( LookAhead(Parser) == TOK_PAREN_OPEN ) + { + char name[Parser->TokenLen+1]; + memcpy(name, Parser->TokenStr, Parser->TokenLen); + name[Parser->TokenLen] = 0; + ret = AST_NewMethodCall(Parser, ret, name); + GetToken(Parser); // Eat the '(' + // Read arguments + if( GetToken(Parser) != TOK_PAREN_CLOSE ) + { + PutBack(Parser); + do { + AST_AppendFunctionCallArg( ret, Parse_DoExpr0(Parser) ); + } while(GetToken(Parser) == TOK_COMMA); + SyntaxAssert( Parser, Parser->Token, TOK_PAREN_CLOSE ); + } + + } + // Attribute + else + { + char name[Parser->TokenLen]; + memcpy(name, Parser->TokenStr+1, Parser->TokenLen-1); + name[Parser->TokenLen-1] = 0; + ret = AST_NewClassElement(Parser, ret, name); + } + continue ; + } + + break ; } + PutBack(Parser); return ret; } /** - * \brief Get an identifier (constand or function call) + * \brief Get an identifier (constant or function call) */ -tAST_Node *Parse_GetIdent(tParser *Parser) +tAST_Node *Parse_GetIdent(tParser *Parser, int bObjectCreate) { - tAST_Node *ret; + tAST_Node *ret = NULL; char *name; SyntaxAssert(Parser, GetToken(Parser), TOK_IDENT ); name = strndup( Parser->TokenStr, Parser->TokenLen ); - #if 0 - while( GetToken(Parser) == TOK_SCOPE ) + #if USE_SCOPE_CHAR + if( GetToken(Parser) == TOK_SCOPE ) { - ret = AST_New + ret = AST_NewScopeDereference( Parser, Parse_GetIdent(Parser, bObjectCreate), name ); + free(name); + return ret; } PutBack(Parser); #endif @@ -657,7 +805,10 @@ tAST_Node *Parse_GetIdent(tParser *Parser) printf("Parse_GetIdent: Calling '%s'\n", name); #endif // Function Call - ret = AST_NewFunctionCall( Parser, name ); + if( bObjectCreate ) + ret = AST_NewCreateObject( Parser, name ); + else + ret = AST_NewFunctionCall( Parser, name ); // Read arguments if( GetToken(Parser) != TOK_PAREN_CLOSE ) { @@ -674,13 +825,17 @@ tAST_Node *Parse_GetIdent(tParser *Parser) #endif } } - else { - // Runtime Constant + else + { + // Runtime Constant / Variable (When implemented) #if DEBUG >= 2 printf("Parse_GetIdent: Referencing '%s'\n", name); #endif PutBack(Parser); - ret = AST_NewConstant( Parser, name ); + if( bObjectCreate ) // Void constructor (TODO: Should this be an error?) + ret = AST_NewCreateObject( Parser, name ); + else + ret = AST_NewConstant( Parser, name ); } free(name);