|
|
| version 1.213.10.1, 2005/08/05 13:01:16 | version 1.218, 2005/12/09 07:18:07 |
|---|---|
| Line 2 | Line 2 |
| /** @file | /** @file |
| Parser: compiler(lexical parser and grammar). | Parser: compiler(lexical parser and grammar). |
| Copyright (c) 2001, 2003 ArtLebedev Group (http://www.artlebedev.com) | Copyright (c) 2001-2005 ArtLebedev Group (http://www.artlebedev.com) |
| Author: Alexander Petrosyan <paf@design.ru> (http://design.ru/paf) | Author: Alexander Petrosyan <paf@design.ru> (http://design.ru/paf) |
| $Id$ | $Id$ |
| Line 48 static int real_yyerror(Parse_control* p | Line 48 static int real_yyerror(Parse_control* p |
| static void yyprint(FILE* file, int type, YYSTYPE value); | static void yyprint(FILE* file, int type, YYSTYPE value); |
| static int yylex(YYSTYPE* lvalp, void* pc); | static int yylex(YYSTYPE* lvalp, void* pc); |
| static const VBool vfalse(false); | |
| static const VBool vtrue(true); | |
| static const VVoid vvoid; | |
| // local convinient inplace typecast & var | // local convinient inplace typecast & var |
| #undef PC | #undef PC |
| #define PC (*(Parse_control *)pc) | #define PC (*(Parse_control *)pc) |
| Line 93 static int yylex(YYSTYPE* lvalp, void* p | Line 97 static int yylex(YYSTYPE* lvalp, void* p |
| %token DEXISTS "-d" | %token DEXISTS "-d" |
| %token IS "is" | %token IS "is" |
| %token LITERAL_TRUE "true" | |
| %token LITERAL_FALSE "false" | |
| /* logical */ | /* logical */ |
| %left "!||" | %left "!||" |
| %left "||" | %left "||" |
| Line 441 store_code_param_part: code_param_value | Line 448 store_code_param_part: code_param_value |
| $$=$1; | $$=$1; |
| O(*$$, OP_STORE_PARAM); | O(*$$, OP_STORE_PARAM); |
| }; | }; |
| store_expr_param_part: write_expr_value { | store_expr_param_part: expr_value { |
| $$=N(); | YYSTYPE expr_code=$1; |
| OA(*$$, OP_EXPR_CODE__STORE_PARAM, $1); | if(expr_code->count()==3 |
| && (*expr_code)[0].code==OP_VALUE) { // optimizing (double/bool/incidently 'string' too) case. [OP_VALUE+origin+Double] | |
| $$=expr_code; | |
| O(*$$, OP_STORE_PARAM); // no evaluating | |
| } else { | |
| ArrayOperation* code=N(); | |
| O(*code, OP_PREPARE_TO_EXPRESSION); | |
| P(*code, *expr_code); | |
| O(*code, OP_WRITE_EXPR_RESULT); | |
| $$=N(); | |
| OA(*$$, OP_EXPR_CODE__STORE_PARAM, code); | |
| } | |
| }; | }; |
| store_curly_param_part: maybe_codes { | store_curly_param_part: maybe_codes { |
| $$=N(); | $$=N(); |
| Line 454 code_param_value: | Line 472 code_param_value: |
| | STRING /* optimized [STRING] case */ | | STRING /* optimized [STRING] case */ |
| | constructor_code_value /* [something complex] */ | | constructor_code_value /* [something complex] */ |
| ; | ; |
| write_expr_value: expr_value { | |
| $$=N(); | |
| O(*$$, OP_PREPARE_TO_EXPRESSION); | |
| P(*$$, *$1); | |
| O(*$$, OP_WRITE_EXPR_RESULT); | |
| }; | |
| /* name */ | /* name */ |
| Line 554 class_constructor_prefix: class_static_p | Line 566 class_constructor_prefix: class_static_p |
| expr_value: expr; | expr_value: expr; |
| expr: | expr: |
| double_or_STRING | double_or_STRING |
| | true_value | |
| | false_value | |
| | get_value | | get_value |
| | call_value | | call_value |
| | '"' string_inside_quotes_value '"' { $$ = $2; } | | '"' string_inside_quotes_value '"' { $$ = $2 } |
| | '\'' string_inside_quotes_value '\'' { $$ = $2; } | | '\'' string_inside_quotes_value '\'' { $$ = $2 } |
| | '(' expr ')' { $$ = $2; } | | '(' expr ')' { $$ = $2; } |
| /* stack: operand // stack: @operand */ | /* stack: operand // stack: @operand */ |
| | '-' expr %prec NUNARY { $$=$2; O(*$$, OP_NEG) } | | '-' expr %prec NUNARY { $$=$2; O(*$$, OP_NEG) } |
| Line 617 write_string: STRING { | Line 631 write_string: STRING { |
| change_string_literal_to_write_string_literal(*($$=$1)) | change_string_literal_to_write_string_literal(*($$=$1)) |
| }; | }; |
| void_value: /* empty */ { $$=VL(new VVoid(), 0, 0, 0) }; | void_value: /* empty */ { $$=VL(/*we know that we will not change it*/const_cast<VVoid*>(&vvoid), 0, 0, 0) } |
| true_value: "true" { $$ = VL(/*we know that we will not change it*/const_cast<VBool*>(&vtrue), 0, 0, 0) } | |
| false_value: "false" { $$ = VL(/*we know that we will not change it*/const_cast<VBool*>(&vfalse), 0, 0, 0) } | |
| empty: /* empty */ { $$=N() }; | empty: /* empty */ { $$=N() }; |
| %% | %% |
| Line 741 default: | Line 758 default: |
| } | } |
| // #HH ? | // #HH ? |
| if(pc.source[0]=='#' && pc.source[1] && pc.source[2]) { | if(pc.source[0]=='#' && pc.source[1] && pc.source[2]) { |
| char c= | char c=(char)( |
| hex_value[(unsigned char)pc.source[1]]*0x10+ | hex_value[(unsigned char)pc.source[1]]*0x10+ |
| hex_value[(unsigned char)pc.source[2]]; | hex_value[(unsigned char)pc.source[2]]); |
| if(c==0) { | if(c==0) { |
| result=BAD_HEX_LITERAL; | result=BAD_HEX_LITERAL; |
| goto break2; // wrong hex value[no ^#00 chars allowed]: bail out | goto break2; // wrong hex value[no ^#00 chars allowed]: bail out |
| Line 1061 default: | Line 1078 default: |
| goto break2; | goto break2; |
| } | } |
| break; | break; |
| case 't': | |
| if(end==begin) // right after whitespace | |
| if(pc.source[0]=='r' && pc.source[1]=='u' && pc.source[2]=='e') { // def | |
| skip_analized=3; | |
| result=LITERAL_TRUE; | |
| goto break2; | |
| } | |
| break; | |
| case 'f': | |
| if(end==begin) // right after whitespace | |
| if(pc.source[0]=='a' && pc.source[1]=='l' && pc.source[2]=='s' && pc.source[3]=='e') { // def | |
| skip_analized=4; | |
| result=LITERAL_FALSE; | |
| goto break2; | |
| } | |
| break; | |
| case ' ': case '\t': case '\n': | case ' ': case '\t': case '\n': |
| if(end!=begin) { // there were a string after previous operator? | if(end!=begin) { // there were a string after previous operator? |
| result=0; // return that string | result=0; // return that string |