--- parser3/src/main/compile.y 2009/06/07 22:37:31 1.248 +++ parser3/src/main/compile.y 2010/04/28 17:56:22 1.254 @@ -5,7 +5,7 @@ Copyright (c) 2001-2009 ArtLebedev Group (http://www.artlebedev.com) Author: Alexander Petrosyan (http://design.ru/paf) - $Id: compile.y,v 1.248 2009/06/07 22:37:31 misha Exp $ + $Id: compile.y,v 1.254 2010/04/28 17:56:22 pretender Exp $ */ /** @@ -130,11 +130,11 @@ static const VVoid vvoid; %% all: one_big_piece { - Method& method=*new Method(Method::CT_ANY, + Method* method=new Method(Method::CT_ANY, 0, 0, /*min, max numbered_params_count*/ 0/*param_names*/, 0/*local_names*/, $1/*parser_code*/, 0/*native_code*/); - PC.cclass->add_method(PC.alias_method(main_method_name), method); + PC.cclass->set_method(PC.alias_method(main_method_name), method); } | methods; @@ -184,7 +184,7 @@ control_method: '@' STRING '\n' } if(strings_code->count()==1*OPERATIONS_PER_OPVALUE) { const String& base_name=*LA2S(*strings_code); - if(Value* base_class_value=PC.request.classes().get(base_name)) { + if(Value* base_class_value=PC.request.get_class(base_name)) { // @CLASS == @BASE sanity check if(VStateless_class *base_class=base_class_value->get_class()) { if(PC.cclass==base_class) { @@ -290,13 +290,13 @@ code_method: '@' STRING bracketed_maybe_ // todo: check [][;result;] } maybe_codes { - Method& method=*reinterpret_cast($7); + Method* method=reinterpret_cast($7); // fill in the code - method.parser_code=$8; + method->parser_code=$8; // register in class const String& name=*LA2S(*$2); - PC.cclass->add_method(PC.alias_method(name), method); + PC.cclass->set_method(PC.alias_method(name), method); }; maybe_bracketed_strings: empty | bracketed_maybe_strings; @@ -522,9 +522,10 @@ call: call_value { #endif { $$=$1; /* stack: value */ - changetail_or_append(*$$, - OP::OP_CALL, true, /*=>*/ OP::OP_CALL__WRITE, - /*or */OP::OP_WRITE_VALUE); /* value=pop; wcontext.write(value) */ + if(!maybe_change_first_opcode(*$$, OP::OP_CONSTRUCT_OBJECT, /*=>*/OP::OP_CONSTRUCT_OBJECT__WRITE)) + changetail_or_append(*$$, + OP::OP_CALL, true, /*=>*/ OP::OP_CALL__WRITE, + /*or */OP::OP_WRITE_VALUE); /* value=pop; wcontext.write(value) */ } }; call_value: '^' { @@ -540,13 +541,11 @@ call_value: '^' { #else const String* operator_name=LA2S(*$3, 1); #endif - if(operator_name && *operator_name == REM_OPERATOR_NAME){ + if(operator_name && *operator_name==REM_OPERATOR_NAME){ $$=N(); } else #endif { - $$=$3; /* with_xxx,diving code; stack: context,method_junction */ - YYSTYPE params_code=$5; if(params_code->count()==3) { // probably [] case. [OP::OP_VALUE+origin+Void] if(Value* value=LA2V(*params_code)) // it is OP_VALUE+origin+value? @@ -554,7 +553,25 @@ call_value: '^' { params_code=0; // ^zzz[] case. don't append lone empty param. } /* stack: context, method_junction */ - OA(*$$, OP::OP_CALL, params_code); // method_frame=make frame(pop junction); ncontext=pop; call(ncontext,method_frame) stack: value + + YYSTYPE var_code=$3; + if( + var_code->count()==8 + && (*var_code)[0].code==OP::OP_VALUE__GET_CLASS + && (*var_code)[3].code==OP::OP_PREPARE_TO_CONSTRUCT_OBJECT + && (*var_code)[4].code==OP::OP_VALUE + && (*var_code)[7].code==OP::OP_GET_ELEMENT + ){ + yyval=N(); + O(*$$, OP::OP_CONSTRUCT_OBJECT); + P(*$$, *var_code, 1/*offset*/, 2/*limit*/); // class name + P(*$$, *var_code, 5/*offset*/, 2/*limit*/); // constructor name + OA(*$$, params_code); + } else + { + $$=var_code; /* with_xxx,diving code; stack: context,method_junction */ + OA(*$$, OP::OP_CALL, params_code); // method_frame=make frame(pop junction); ncontext=pop; call(ncontext,method_frame) stack: value + } } }; @@ -689,12 +706,8 @@ class_static_prefix: STRING ':' { YYERROR; } } -#ifdef OPTIMIZE_BYTECODE_GET_CLASS // optimized OP_VALUE+origin+string+OP_GET_CLASS => OP_VALUE__GET_CLASS+origin+string maybe_change_first_opcode(*$$, OP::OP_VALUE, OP::OP_VALUE__GET_CLASS) -#else - O(*$$, OP::OP_GET_CLASS); -#endif }; class_constructor_prefix: class_static_prefix ':' { $$=$1; @@ -1333,7 +1346,7 @@ default: case ']': case '}': case ')': case '"': case '\'': case '<': case '>': // these stand for HTML brackets AND expression binary ops - case '+': case '*': case '/': case '%': + case '+': case '*': case '/': case '\\': case '%': case '&': case '|': case '=': case '!': // common delimiters