--- parser3/src/main/compile.y 2004/04/06 07:53:57 1.208 +++ parser3/src/main/compile.y 2005/08/08 13:30:45 1.214 @@ -5,7 +5,7 @@ Copyright (c) 2001, 2003 ArtLebedev Group (http://www.artlebedev.com) Author: Alexander Petrosyan (http://design.ru/paf) - $Id: compile.y,v 1.208 2004/04/06 07:53:57 paf Exp $ + $Id: compile.y,v 1.214 2005/08/08 13:30:45 paf Exp $ */ /** @@ -47,7 +47,6 @@ static int real_yyerror(Parse_control* pc, char* s); static void yyprint(FILE* file, int type, YYSTYPE value); static int yylex(YYSTYPE* lvalp, void* pc); -static int is_not_whitespace(char c, int); // local convinient inplace typecast & var #undef PC @@ -67,7 +66,7 @@ static int is_not_whitespace(char c, int %token BAD_HEX_LITERAL %token BAD_METHOD_DECL_START %token BAD_METHOD_PARAMETER_NAME_CHARACTER -%token BAD_MATH_OPERATOR_CHARACTER +%token BAD_NONWHITESPACE_CHARACTER_IN_EXPLICIT_RESULT_MODE %token LAND "&&" %token LOR "||" @@ -263,14 +262,7 @@ maybe_codes: empty | codes; codes: code | codes code { $$=$1; P(*$$, *$2) }; code: write_string | action; -action: { - *reinterpret_cast(&$$)=PC.explicit_result; - PC.explicit_result=false; -} real_action { - PC.explicit_result=reinterpret_cast($1); - $$=$2; -}; -real_action: get | put | call; +action: get | put | call; /* get */ @@ -351,9 +343,14 @@ construct: | construct_round | construct_curly ; -construct_square: '[' any_constructor_code_value ']' { +construct_square: '[' { + // allow $result_or_other_variable[ letters here any time ] + *reinterpret_cast(&$$)=PC.explicit_result; PC.explicit_result=false; +} any_constructor_code_value { + PC.explicit_result=*reinterpret_cast(&$2); +} ']' { // stack: context, name - $$=$2; // stack: context, name, value + $$=$3; // stack: context, name, value O(*$$, OP_CONSTRUCT_VALUE); /* value=pop; name=pop; context=pop; construct(context,name,value) */ } ; @@ -420,7 +417,12 @@ store_param: | store_round_param | store_curly_param ; -store_square_param: '[' store_code_param_parts ']' {$$=$2}; +store_square_param: '[' { + // allow ^call[ letters here any time ] + *reinterpret_cast(&$$)=PC.explicit_result; PC.explicit_result=false; +} store_code_param_parts { + PC.explicit_result=*reinterpret_cast(&$2); +} ']' {$$=$3}; store_round_param: '(' store_expr_param_parts ')' {$$=$2}; store_curly_param: '{' store_curly_param_parts '}' {$$=$2}; store_code_param_parts: @@ -439,9 +441,19 @@ store_code_param_part: code_param_value $$=$1; O(*$$, OP_STORE_PARAM); }; -store_expr_param_part: write_expr_value { - $$=N(); - OA(*$$, OP_EXPR_CODE__STORE_PARAM, $1); +store_expr_param_part: expr_value { + YYSTYPE expr_code=$1; + if(expr_code->count()==3) { // optimizing (double) 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 { $$=N(); @@ -452,12 +464,6 @@ code_param_value: | STRING /* optimized [STRING] case */ | constructor_code_value /* [something complex] */ ; -write_expr_value: expr_value { - $$=N(); - O(*$$, OP_PREPARE_TO_EXPRESSION); - P(*$$, *$1); - O(*$$, OP_WRITE_EXPR_RESULT); -}; /* name */ @@ -499,9 +505,14 @@ name_expr_with_subvar_value: STRING subv $$=N(); OA(*$$, OP_STRING_POOL, code); }; -name_square_code_value: '[' codes ']' { +name_square_code_value: '[' { + // allow $result_or_other_variable[ letters here any time ] + *reinterpret_cast(&$$)=PC.explicit_result; PC.explicit_result=false; +} codes { + PC.explicit_result=*reinterpret_cast(&$2); +} ']' { $$=N(); - OA(*$$, OP_OBJECT_POOL, $2); /* stack: empty write context */ + OA(*$$, OP_OBJECT_POOL, $3); /* stack: empty write context */ /* some code that writes to that context */ /* context=pop; stack: context.value() */ }; @@ -544,13 +555,9 @@ class_constructor_prefix: class_static_p /* expr */ -expr_value: expr { - // see OP_PREPARE_TO_EXPRESSION!! - if(($$=$1)->count()==2) // only one string literal in there? - change_string_literal_to_double_literal(*$$); // make that string literal Double -}; +expr_value: expr; expr: - STRING + double_or_STRING | get_value | call_value | '"' string_inside_quotes_value '"' { $$ = $2; } @@ -595,6 +602,11 @@ expr: | expr "is" expr { $$=$1; P(*$$, *$3); O(*$$, OP_IS) } ; +double_or_STRING: STRING { + // optimized from OP_STRING->OP_VALUE for doubles + maybe_change_string_literal_to_double_literal(*($$=$1)); +}; + string_inside_quotes_value: maybe_codes { $$=N(); OA(*$$, OP_STRING_POOL, $1); /* stack: empty write context */ @@ -605,18 +617,8 @@ string_inside_quotes_value: maybe_codes /* basics */ write_string: STRING { - // $1=OP_STRING+origin+OP_WRITE_VALUE - if(PC.explicit_result) { // only allow decoration whitespaces, no byte code actually produced - String::Body body=static_cast($1->get(2).value)->string(); - if(body.for_each/*first_that, actually*/(is_not_whitespace, 0)) { - strcpy(PC.error, "only whitespaces are allowed here (explicit result mode), look before this point"); - YYERROR; - } - $$=N(); - } else { - // optimized from OP_STRING+origin+OP_WRITE_VALUE to OP_STRING__WRITE - change_string_literal_to_write_string_literal(*($$=$1)); - } + // optimized from OP_STRING+OP_WRITE_VALUE to OP_STRING__WRITE + change_string_literal_to_write_string_literal(*($$=$1)) }; void_value: /* empty */ { $$=VL(new VVoid(), 0, 0, 0) }; @@ -691,7 +693,8 @@ static int yylex(YYSTYPE *lvalp, void *a } else // @ in first column inside some code [when could that be?] result=BAD_METHOD_DECL_START; goto break2; - } else if(c=='^') { + } + if(c=='^') { if(pc.ls==LS_METHOD_AFTER) { // handle after-method situation pop_LS(pc); @@ -810,6 +813,16 @@ default: lexical_brackets_nestage++; break; } + if(pc.explicit_result && c) + switch(c) { + case '\n': case ' ': case '\t': + begin=pc.source; + begin_pos=pc.pos; + continue; // skip it + default: + result=BAD_NONWHITESPACE_CHARACTER_IN_EXPLICIT_RESULT_MODE; + goto break2; + } break; // #COMMENT @@ -1310,6 +1323,16 @@ default: lexical_brackets_nestage++; break; } + if(pc.explicit_result && c) + switch(c) { + case '\n': case ' ': case '\t': + begin=pc.source; + begin_pos=pc.pos; + continue; // skip it + default: + result=BAD_NONWHITESPACE_CHARACTER_IN_EXPLICIT_RESULT_MODE; + goto break2; + } break; case LS_METHOD_AFTER: @@ -1380,7 +1403,3 @@ static void yyprint(FILE *file, int type if(type==STRING) fprintf(file, " \"%s\"", LA2S(*value)->cstr()); } - -static int is_not_whitespace(char c, int) { - return !isspace(c); -}