--- parser3/src/main/compile.y 2024/09/28 14:37:53 1.298 +++ parser3/src/main/compile.y 2026/04/23 18:50:11 1.302 @@ -2,13 +2,13 @@ /** @file Parser: compiler(lexical parser and grammar). - Copyright (c) 2001-2023 Art. Lebedev Studio (http://www.artlebedev.com) + Copyright (c) 2001-2024 Art. Lebedev Studio (http://www.artlebedev.com) Authors: Konstantin Morshnev , Alexandr Petrosian */ -volatile const char * IDENT_COMPILE_Y = "$Id: compile.y,v 1.298 2024/09/28 14:37:53 moko Exp $"; +volatile const char * IDENT_COMPILE_Y = "$Id: compile.y,v 1.302 2026/04/23 18:50:11 moko Exp $"; /** @todo parser4: @@ -653,6 +653,7 @@ name_expr_value: | name_expr_subvar_value /* $subname_is_var_value */ | name_expr_with_subvar_value /* xxx$part_of_subname_is_var_value */ | name_square_code_value /* [codes] */ +| name_round_expr_value /* (expr) */ ; name_expr_subvar_value: '$' subvar_ref_name_rdive { $$=$2; @@ -673,16 +674,17 @@ name_square_code_value: '[' { } codes { PC.explicit_result=*reinterpret_cast(&$2); } ']' { - $$=N(); -#ifdef OPTIMIZE_BYTECODE_GET_ELEMENT__SPECIAL - if(!maybe_append_simple_diving_code(*$$, *$3)) -#endif - { + $$=N(); + if(!maybe_append_simple_diving_code(*$$, *$3)) { OA(*$$, OP::OP_OBJECT_POOL, $3); /* stack: empty write context */ /* some code that writes to that context */ /* context=pop; stack: context.value() */ } }; +name_round_expr_value: '(' expr_value ')' { + $$ = N(); + P(*$$, *$2); +}; subvar_ref_name_rdive: STRING { $$=N(); O(*$$, OP::OP_WITH_READ); @@ -1367,11 +1369,10 @@ default: goto break2; case '[': // $name.<[>code] - if(pc.pos.col>1/*not first column*/ && ( - end[-1]=='$'/*was start of get*/ || - end[-1]==':'/*was class name delim */ || - end[-1]=='.'/*was name delim */ - )) { + if( end[-1]=='$' /* was start of get */ || + end[-1]==':' /* was class name delim */ || + end[-1]=='.' /* was name delim */ + ) { push_LS(pc, LS_NAME_SQUARE_PART); lexical_brackets_nestage=1; RC; @@ -1380,7 +1381,7 @@ default: lexical_brackets_nestage=1; RC; case '{': - if(begin==end) { // ${name}, no need of EON, switching LS + if(end[-1]=='$') { // ${name}, no need of EON, switching LS, not begin==end as $[a]{$b} will fit pc.ls=LS_VAR_NAME_CURLY; } else { pc.ls=LS_VAR_CURLY; @@ -1389,6 +1390,15 @@ default: RC; case '(': + // $name.<(>expr) + if( // end[-1]=='$' /* $() excluded */ || + end[-1]==':' /* was class name delim */ || + end[-1]=='.' /* was name delim */ + ) { + push_LS(pc, LS_VAR_ROUND); + lexical_brackets_nestage=1; + RC; + } pc.ls=LS_VAR_ROUND; lexical_brackets_nestage=1; RC; @@ -1412,6 +1422,11 @@ default: push_LS(pc, LS_NAME_SQUARE_PART); lexical_brackets_nestage=1; RC; + case '(': + // ${name.<(>expr)} + push_LS(pc, LS_VAR_ROUND); + lexical_brackets_nestage=1; + RC; case '}': // ${name} finished, restoring LS pop_LS(pc); RC; @@ -1468,12 +1483,11 @@ default: case LS_METHOD_NAME: switch(c) { case '[': - // ^name.<[>code].xxx - if(pc.pos.col>1/*not first column*/ && ( - end[-1]=='^'/*was start of call*/ || // never, ^[ is literal... - end[-1]==':'/*was class name delim */ || - end[-1]=='.'/*was name delim */ - )) { + // ^name.<[>code] + if( // end[-1]=='^' /* never, ^[ is literal */ || + end[-1]==':' /* was class name delim */ || + end[-1]=='.' /* was name delim */ + ) { push_LS(pc, LS_NAME_SQUARE_PART); lexical_brackets_nestage=1; RC; @@ -1486,6 +1500,15 @@ default: lexical_brackets_nestage=1; RC; case '(': + // ^name.<(>expr) + if( // end[-1]=='^' /* never, ^( is literal */ || + end[-1]==':' /* was class name delim */ || + end[-1]=='.' /* was name delim */ + ) { + push_LS(pc, LS_VAR_ROUND); + lexical_brackets_nestage=1; + RC; + } pc.ls=LS_METHOD_ROUND; lexical_brackets_nestage=1; RC;