--- parser3/src/main/compile.y 2005/11/16 14:45:22 1.215 +++ parser3/src/main/compile.y 2005/12/16 14:04:20 1.219 @@ -4,6 +4,8 @@ Copyright (c) 2001-2005 ArtLebedev Group (http://www.artlebedev.com) Author: Alexander Petrosyan (http://design.ru/paf) + + $Id: compile.y,v 1.219 2005/12/16 14:04:20 paf Exp $ */ /** @@ -46,6 +48,10 @@ static int real_yyerror(Parse_control* p static void yyprint(FILE* file, int type, YYSTYPE value); 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 #undef PC #define PC (*(Parse_control *)pc) @@ -91,6 +97,9 @@ static int yylex(YYSTYPE* lvalp, void* p %token DEXISTS "-d" %token IS "is" +%token LITERAL_TRUE "true" +%token LITERAL_FALSE "false" + /* logical */ %left "!||" %left "||" @@ -400,7 +409,7 @@ call_value: '^' { YYSTYPE params_code=$5; if(params_code->count()==4) { // probably [] case. [OP_VALUE+origin+Void+STORE_PARAM] if(Value* value=LA2V(*params_code)) // it is OP_VALUE+origin+value? - if(!value->is_defined()) // value is VVoid? + if(value->is_void()) // value is VVoid? params_code=0; // ^zzz[] case. don't append lone empty param. } /* stack: context, method_junction */ @@ -442,7 +451,7 @@ store_code_param_part: code_param_value store_expr_param_part: expr_value { YYSTYPE expr_code=$1; if(expr_code->count()==3 - && (*expr_code)[0].code==OP_VALUE) { // optimizing (double) case. [OP_VALUE+origin+Double] + && (*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 { @@ -557,10 +566,12 @@ class_constructor_prefix: class_static_p expr_value: expr; expr: double_or_STRING +| true_value +| false_value | get_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; } /* stack: operand // stack: @operand */ | '-' expr %prec NUNARY { $$=$2; O(*$$, OP_NEG) } @@ -620,7 +631,10 @@ write_string: STRING { 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), 0, 0, 0) } +true_value: "true" { $$ = VL(/*we know that we will not change it*/const_cast(&vtrue), 0, 0, 0) } +false_value: "false" { $$ = VL(/*we know that we will not change it*/const_cast(&vfalse), 0, 0, 0) } + empty: /* empty */ { $$=N() }; %% @@ -744,9 +758,9 @@ default: } // #HH ? 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[2]]; + hex_value[(unsigned char)pc.source[2]]); if(c==0) { result=BAD_HEX_LITERAL; goto break2; // wrong hex value[no ^#00 chars allowed]: bail out @@ -1064,6 +1078,22 @@ default: goto break2; } 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': if(end!=begin) { // there were a string after previous operator? result=0; // return that string