--- parser3/src/main/compile.tab.C 2008/06/17 15:52:55 1.118 +++ parser3/src/main/compile.tab.C 2009/06/02 10:24:34 1.137 @@ -129,10 +129,10 @@ /** @file Parser: compiler(lexical parser and grammar). - Copyright (c) 2001-2005 ArtLebedev Group (http://www.artlebedev.com) + Copyright (c) 2001-2009 ArtLebedev Group (http://www.artlebedev.com) Author: Alexander Petrosyan (http://design.ru/paf) - $Id: compile.tab.C,v 1.118 2008/06/17 15:52:55 misha Exp $ + $Id: compile.tab.C,v 1.137 2009/06/02 10:24:34 misha Exp $ */ /** @@ -168,7 +168,10 @@ // defines #define USE_CONTROL_METHOD_NAME "USE" -#define OPTIONS_CONTROL_METHOD_NAME "OPTION" +#define OPTIONS_CONTROL_METHOD_NAME "OPTIONS" +#define OPTION_ALL_VARS_LOCAL_NAME "locals" +#define OPTION_PARTIAL_CLASS "partial" +#define REM_OPERATOR_NAME "rem" // forwards @@ -214,7 +217,7 @@ typedef int YYSTYPE; /* Line 214 of yacc.c. */ -#line 218 "compile.tab.C" +#line 221 "compile.tab.C" #if ! defined (yyoverflow) || YYERROR_VERBOSE @@ -453,24 +456,24 @@ static const short int yyrhs[] = /* YYRLINE[YYN] -- source line where rule number YYN was defined. */ static const unsigned short int yyrline[] = { - 0, 129, 129, 136, 138, 138, 139, 141, 141, 143, - 229, 229, 230, 230, 231, 232, 232, 234, 234, 283, - 283, 284, 285, 285, 286, 286, 288, 288, 292, 292, - 294, 294, 295, 295, 296, 296, 296, 300, 307, 308, - 308, 309, 311, 312, 313, 335, 336, 336, 340, 345, - 346, 347, 348, 365, 370, 373, 374, 375, 377, 380, - 377, 388, 396, 403, 404, 405, 407, 413, 414, 414, - 418, 424, 427, 424, 443, 445, 445, 447, 448, 449, - 451, 454, 451, 457, 458, 460, 461, 464, 465, 468, - 469, 471, 475, 490, 495, 496, 497, 502, 502, 504, - 504, 505, 506, 514, 519, 522, 523, 524, 525, 527, - 531, 540, 543, 540, 551, 556, 556, 557, 563, 564, - 566, 578, 590, 592, 593, 594, 595, 596, 597, 598, - 599, 601, 602, 603, 604, 605, 606, 607, 608, 610, - 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, - 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, - 631, 632, 633, 634, 635, 636, 639, 644, 653, 658, - 659, 660, 662 + 0, 132, 132, 139, 141, 141, 142, 144, 144, 146, + 247, 247, 248, 248, 249, 250, 250, 252, 252, 302, + 302, 303, 304, 304, 305, 305, 307, 307, 311, 311, + 313, 313, 314, 314, 315, 315, 315, 319, 348, 349, + 349, 350, 352, 353, 354, 405, 406, 406, 410, 423, + 424, 425, 426, 443, 448, 451, 452, 453, 455, 458, + 455, 466, 474, 481, 482, 483, 485, 491, 492, 492, + 496, 507, 510, 507, 538, 540, 540, 542, 543, 544, + 546, 549, 546, 552, 553, 555, 556, 559, 560, 563, + 564, 566, 569, 583, 588, 589, 590, 595, 595, 597, + 597, 598, 599, 607, 612, 615, 616, 617, 618, 620, + 624, 633, 636, 633, 644, 649, 649, 650, 656, 657, + 659, 676, 688, 690, 691, 692, 693, 694, 695, 696, + 697, 699, 700, 701, 702, 703, 704, 705, 706, 708, + 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, + 719, 720, 721, 722, 723, 724, 725, 726, 727, 728, + 729, 730, 731, 732, 733, 734, 737, 742, 763, 768, + 769, 770, 772 }; #endif @@ -1425,7 +1428,7 @@ yyreduce: switch (yyn) { case 2: -#line 129 "compile.y" +#line 132 "compile.y" { Method& method=*new Method(Method::CT_ANY, 0, 0, /*min, max numbered_params_count*/ @@ -1436,7 +1439,7 @@ yyreduce: break; case 9: -#line 144 "compile.y" +#line 147 "compile.y" { const String& command=*LA2S(*yyvsp[-2]); YYSTYPE strings_code=yyvsp[0]; @@ -1447,24 +1450,13 @@ yyreduce: YYERROR; } if(command==CLASS_NAME) { - /* - if(PC.cclass->base_class()) { // already changed from default? - strcpy(PC.error, "class already have a name '"); - strncat(PC.error, PC.cclass->name().cstr(), 100); - strcat(PC.error, "'"); - YYERROR; - } - */ if(strings_code->count()==1*OPERATIONS_PER_OPVALUE) { // new class' name const String& name=*LA2S(*strings_code); // creating the class VStateless_class* cclass=new VClass; - PC.cclass=cclass; - PC.cclass->set_name(name); - // append to request's classes - PC.request.classes().put(name, cclass); - *PC.cclasses+=cclass; + PC.cclass_new=cclass; + PC.cclass_new->set_name(name); } else { strcpy(PC.error, "@"CLASS_NAME" must contain only one line with class name (contains more then one)"); YYERROR; @@ -1473,9 +1465,16 @@ yyreduce: for(size_t i=0; icount(); i+=OPERATIONS_PER_OPVALUE) PC.request.use_file(PC.request.main_class, *LA2S(*strings_code, i)); } else if(command==BASE_NAME) { + if(PC.append){ + strcpy(PC.error, "can't set base while appending methods to class '"); + strncat(PC.error, PC.cclass->name().cstr(), MAX_STRING/2); + strcat(PC.error, "'"); + YYERROR; + } + PC.class_add(); if(PC.cclass->base_class()) { // already changed from default? strcpy(PC.error, "class already have a base '"); - strncat(PC.error, PC.cclass->base_class()->name().cstr(), 100); + strncat(PC.error, PC.cclass->base_class()->name().cstr(), MAX_STRING/2); strcat(PC.error, "'"); YYERROR; } @@ -1506,11 +1505,30 @@ yyreduce: } else if(command==OPTIONS_CONTROL_METHOD_NAME) { for(size_t i=0; icount(); i+=OPERATIONS_PER_OPVALUE) { const String& option=*LA2S(*strings_code, i); - if(option==ALL_VARS_LOCAL_NAME){ - PC.cclass->all_vars_local(); + if(option==OPTION_ALL_VARS_LOCAL_NAME){ + PC.set_all_vars_local(); + } else if(option==OPTION_PARTIAL_CLASS){ + if(PC.cclass_new){ + if(VStateless_class* existed=PC.get_existed_class(PC.cclass_new)){ + if(!PC.reuse_existed_class(existed)){ + strcpy(PC.error, "can't append methods to '"); + strncat(PC.error, PC.cclass_new->name().cstr(), MAX_STRING/2); + strcat(PC.error, "' - the class wasn't marked as partial"); + YYERROR; + } + } else { + // mark new class as partial. we can add methods to it later. + PC.cclass_new->set_partial(); + } + } else { + strcpy(PC.error, "'"OPTION_PARTIAL_CLASS"' option should be used straight after @"CLASS_NAME); + YYERROR; + } } else { - strcpy(PC.error, option.cstr()); - strcat(PC.error, ": unknown option in @"OPTIONS_CONTROL_METHOD_NAME" was specified."); + strcpy(PC.error, "'"); + strncat(PC.error, option.cstr(), MAX_STRING/2); + strcat(PC.error, "' invalid option. valid options are " + "'"OPTION_PARTIAL_CLASS"' and '"OPTION_ALL_VARS_LOCAL_NAME"'"); YYERROR; } } @@ -1525,13 +1543,14 @@ yyreduce: break; case 13: -#line 230 "compile.y" +#line 248 "compile.y" { yyval=yyvsp[-1]; P(*yyval, *yyvsp[0]) ;} break; case 17: -#line 234 "compile.y" +#line 252 "compile.y" { + PC.class_add(); PC.explicit_result=false; YYSTYPE params_names_code=yyvsp[-3]; @@ -1551,15 +1570,14 @@ yyreduce: const String* local_name=LA2S(*locals_names_code, i); if(*local_name==RESULT_VAR_NAME) PC.explicit_result=true; - else if(*local_name==ALL_VARS_LOCAL_NAME) + else if(*local_name==OPTION_ALL_VARS_LOCAL_NAME) all_vars_local=true; else *locals_names+=local_name; } } - if(!all_vars_local && PC.cclass && PC.cclass->is_vars_local()){ + if(!all_vars_local && PC.cclass && PC.cclass->is_vars_local()) all_vars_local=true; - } Method* method=new Method( //name, @@ -1575,112 +1593,172 @@ yyreduce: break; case 18: -#line 274 "compile.y" +#line 292 "compile.y" { - Method& method=*reinterpret_cast(yyvsp[-1]); - // fill in the code - method.parser_code=yyvsp[0]; - // register in class - const String& name=*LA2S(*yyvsp[-6]); - PC.cclass->add_method(PC.alias_method(name), method); + Method& method=*reinterpret_cast(yyvsp[-1]); + // fill in the code + method.parser_code=yyvsp[0]; + + // register in class + const String& name=*LA2S(*yyvsp[-6]); + PC.cclass->add_method(PC.alias_method(name), method); ;} break; case 21: -#line 284 "compile.y" +#line 303 "compile.y" {yyval=yyvsp[-1];} break; case 25: -#line 286 "compile.y" +#line 305 "compile.y" { yyval=yyvsp[-2]; P(*yyval, *yyvsp[0]) ;} break; case 31: -#line 294 "compile.y" +#line 313 "compile.y" { yyval=yyvsp[-1]; P(*yyval, *yyvsp[0]) ;} break; case 37: -#line 300 "compile.y" +#line 319 "compile.y" { - yyval=yyvsp[0]; /* stack: resulting value */ - changetail_or_append(*yyval, - OP_GET_ELEMENT, false, /*->*/OP_GET_ELEMENT__WRITE, - /*or */OP_WRITE_VALUE - ); /* value=pop; wcontext.write(value) */ + yyval=N(); + YYSTYPE code=yyvsp[0]; +#ifdef OPTIMIZE_BYTECODE_GET_ELEMENT + if(!maybe_change_first_opcode(*code, OP::OP_VALUE__GET_ELEMENT, /*=>*/OP::OP_VALUE__GET_ELEMENT__WRITE)) +#endif + +#ifdef OPTIMIZE_BYTECODE_GET_OBJECT_ELEMENT + if( + code->count()!=5 + || !maybe_change_first_opcode(*code, OP::OP_GET_OBJECT_ELEMENT, /*=>*/OP::OP_GET_OBJECT_ELEMENT__WRITE) + ) +#endif + +#ifdef OPTIMIZE_BYTECODE_GET_OBJECT_VAR_ELEMENT + if( + code->count()!=5 + || !maybe_change_first_opcode(*code, OP::OP_GET_OBJECT_VAR_ELEMENT, /*=>*/OP::OP_GET_OBJECT_VAR_ELEMENT__WRITE) + ) +#endif + { + changetail_or_append(*code, + OP::OP_GET_ELEMENT, false, /*=>*/OP::OP_GET_ELEMENT__WRITE, + /*or */OP::OP_WRITE_VALUE + ); /* value=pop; wcontext.write(value) */ + } + + P(*yyval, *code); ;} break; case 38: -#line 307 "compile.y" +#line 348 "compile.y" { yyval=yyvsp[0] ;} break; case 41: -#line 309 "compile.y" +#line 350 "compile.y" { yyval=yyvsp[-1] ;} break; case 44: -#line 313 "compile.y" +#line 354 "compile.y" { yyval=N(); - ArrayOperation* diving_code=yyvsp[0]; + YYSTYPE diving_code=yyvsp[0]; const String* first_name=LA2S(*diving_code); - // self.xxx... -> xxx... + size_t count=diving_code->count(); + // self.xxx... => xxx... // OP_VALUE+origin+string+OP_GET_ELEMENT+... -> OP_WITH_SELF+... if(first_name && *first_name==SELF_ELEMENT_NAME) { - O(*yyval, OP_WITH_SELF); /* stack: starting context */ + O(*yyval, OP::OP_WITH_SELF); /* stack: starting context */ P(*yyval, *diving_code, /* skip over... */ - diving_code->count()>=4?4/*OP_VALUE+origin+string+OP_GET_ELEMENTx*/:3/*OP_+origin+string*/); + count>=4?4/*OP_VALUE+origin+string+OP_GET_ELEMENTx*/:3/*OP::OP_+origin+string*/); + } + +#ifdef OPTIMIZE_BYTECODE_GET_OBJECT_ELEMENT + else if(maybe_make_get_object_element(*yyval, *diving_code, count)){ + // optimisation for $object.field + ^object.method[ + } +#endif + +#ifdef OPTIMIZE_BYTECODE_GET_OBJECT_VAR_ELEMENT + else if(maybe_make_get_object_var_element(*yyval, *diving_code, count)){ + // optimisation for $object.$var + } +#endif + +#ifdef OPTIMIZE_BYTECODE_GET_ELEMENT + else if(count==4){ // optimization + O(*yyval, + (PC.in_call_value) + ? OP::OP_VALUE__GET_ELEMENT_OR_OPERATOR // ^object[ : OP_VALUE+origin+string+OP_GET_ELEMENT => OP_VALUE__GET_ELEMENT_OR_OPERATOR+origin+string + : OP::OP_VALUE__GET_ELEMENT // $object : OP_VALUE+origin+string+OP_GET_ELEMENT => OP_VALUE__GET_ELEMENT+origin+string + ); + P(*yyval, *diving_code, 1/*offset*/, 2/*limit*/); // copy origin+value } else { - O(*yyval, OP_WITH_READ); /* stack: starting context */ + O(*yyval, OP::OP_WITH_READ); /* stack: starting context */ + P(*yyval, *diving_code); + } +#else + else { + O(*yyval, OP::OP_WITH_READ); /* stack: starting context */ - // ^if ELEMENT -> ^if ELEMENT_OR_OPERATOR - // OP_VALUE+origin+string+OP_GET_ELEMENT. -> OP_VALUE+origin+string+OP_GET_ELEMENT_OR_OPERATOR. - if(PC.in_call_value && diving_code->count()==4) - diving_code->put(4-1, OP_GET_ELEMENT_OR_OPERATOR); + // ^if OP_ELEMENT => ^if OP_ELEMENT_OR_OPERATOR + // optimized OP_VALUE+origin+string+OP_GET_ELEMENT. => OP_VALUE+origin+string+OP_GET_ELEMENT_OR_OPERATOR. + if(PC.in_call_value && count==4) + diving_code->put(count-1, OP::OP_GET_ELEMENT_OR_OPERATOR); P(*yyval, *diving_code); } +#endif /* diving code; stack: current context */ ;} break; case 45: -#line 335 "compile.y" +#line 405 "compile.y" { yyval=yyvsp[-1]; P(*yyval, *yyvsp[0]) ;} break; case 47: -#line 336 "compile.y" +#line 406 "compile.y" { yyval=yyvsp[-1]; P(*yyval, *yyvsp[0]) ;} break; case 48: -#line 340 "compile.y" +#line 410 "compile.y" { - yyval=yyvsp[-1]; /* stack: context,name */ - P(*yyval, *yyvsp[0]); /* stack: context,name,constructor_value */ + yyval=N(); +#ifdef OPTIMIZE_BYTECODE_CONSTRUCT + if(maybe_optimize_construct(*yyval, *yyvsp[-1], *yyvsp[0])){ + // $a(expr), $.a(expr), $a[value], $.a[value] + } else +#endif + { + P(*yyval, *yyvsp[-1]); /* stack: context,name */ + P(*yyval, *yyvsp[0]); /* stack: context,name,constructor_value */ + } ;} break; case 52: -#line 348 "compile.y" +#line 426 "compile.y" { yyval=N(); - ArrayOperation* diving_code=yyvsp[0]; + YYSTYPE diving_code=yyvsp[0]; const String* first_name=LA2S(*diving_code); - // $self.xxx... -> $xxx... - // OP_VALUE+origin+string+OP_GET_ELEMENT+... -> OP_WITH_SELF+... + // $self.xxx... => $xxx... + // OP_VALUE+origin+string+OP_GET_ELEMENT+... => OP_WITH_SELF+... if(first_name && *first_name==SELF_ELEMENT_NAME) { - O(*yyval, OP_WITH_SELF); /* stack: starting context */ + O(*yyval, OP::OP_WITH_SELF); /* stack: starting context */ P(*yyval, *diving_code, /* skip over... */ - diving_code->count()>=4?4/*OP_VALUE+origin+string+OP_GET_ELEMENTx*/:3/*OP_+origin+string*/); + diving_code->count()>=4?4/*OP::OP_VALUE+origin+string+OP::OP_GET_ELEMENTx*/:3/*OP::OP_+origin+string*/); } else { - O(*yyval, OP_WITH_ROOT); /* stack: starting context */ + O(*yyval, OP::OP_WITH_ROOT); /* stack: starting context */ P(*yyval, *diving_code); } /* diving code; stack: current context */ @@ -1688,21 +1766,21 @@ yyreduce: break; case 53: -#line 365 "compile.y" +#line 443 "compile.y" { yyval=N(); - O(*yyval, OP_WITH_WRITE); /* stack: starting context */ + O(*yyval, OP::OP_WITH_WRITE); /* stack: starting context */ P(*yyval, *yyvsp[0]); /* diving code; stack: context,name */ ;} break; case 54: -#line 370 "compile.y" +#line 448 "compile.y" { yyval=yyvsp[-1]; P(*yyval, *yyvsp[0]) ;} break; case 58: -#line 377 "compile.y" +#line 455 "compile.y" { // allow $result_or_other_variable[ letters here any time ] *reinterpret_cast(&yyval)=PC.explicit_result; PC.explicit_result=false; @@ -1710,103 +1788,120 @@ yyreduce: break; case 59: -#line 380 "compile.y" +#line 458 "compile.y" { PC.explicit_result=*reinterpret_cast(&yyvsp[-1]); ;} break; case 60: -#line 382 "compile.y" +#line 460 "compile.y" { // stack: context, name yyval=yyvsp[-2]; // stack: context, name, value - O(*yyval, OP_CONSTRUCT_VALUE); /* value=pop; name=pop; context=pop; construct(context,name,value) */ + O(*yyval, OP::OP_CONSTRUCT_VALUE); /* value=pop; name=pop; context=pop; construct(context,name,value) */ ;} break; case 61: -#line 388 "compile.y" +#line 466 "compile.y" { yyval=N(); - O(*yyval, OP_PREPARE_TO_EXPRESSION); + O(*yyval, OP::OP_PREPARE_TO_EXPRESSION); // stack: context, name P(*yyval, *yyvsp[-1]); // stack: context, name, value - O(*yyval, OP_CONSTRUCT_EXPR); /* value=pop->as_expr_result; name=pop; context=pop; construct(context,name,value) */ + O(*yyval, OP::OP_CONSTRUCT_EXPR); /* value=pop->as_expr_result; name=pop; context=pop; construct(context,name,value) */ ;} break; case 62: -#line 396 "compile.y" +#line 474 "compile.y" { // stack: context, name yyval=N(); - OA(*yyval, OP_CURLY_CODE__CONSTRUCT, yyvsp[-1]); /* code=pop; name=pop; context=pop; construct(context,name,junction(code)) */ + OA(*yyval, OP::OP_CURLY_CODE__CONSTRUCT, yyvsp[-1]); /* code=pop; name=pop; context=pop; construct(context,name,junction(code)) */ ;} break; case 66: -#line 407 "compile.y" +#line 485 "compile.y" { yyval=N(); - OA(*yyval, OP_OBJECT_POOL, yyvsp[0]); /* stack: empty write context */ + OA(*yyval, OP::OP_OBJECT_POOL, yyvsp[0]); /* stack: empty write context */ /* some code that writes to that context */ /* context=pop; stack: context.value() */ ;} break; case 69: -#line 414 "compile.y" +#line 492 "compile.y" { yyval=yyvsp[-1]; P(*yyval, *yyvsp[0]) ;} break; case 70: -#line 418 "compile.y" +#line 496 "compile.y" { - yyval=yyvsp[0]; /* stack: value */ - changetail_or_append(*yyval, - OP_CALL, true, /*->*/ OP_CALL__WRITE, - /*or */OP_WRITE_VALUE); /* value=pop; wcontext.write(value) */ +#ifdef OPTIMIZE_BYTECODE_CUT_REM_OPERATOR + if((*yyvsp[0]).count()) +#endif + { + yyval=yyvsp[0]; /* stack: value */ + changetail_or_append(*yyval, + OP::OP_CALL, true, /*=>*/ OP::OP_CALL__WRITE, + /*or */OP::OP_WRITE_VALUE); /* value=pop; wcontext.write(value) */ + } ;} break; case 71: -#line 424 "compile.y" +#line 507 "compile.y" { PC.in_call_value=true; ;} break; case 72: -#line 427 "compile.y" +#line 510 "compile.y" { PC.in_call_value=false; ;} break; case 73: -#line 430 "compile.y" +#line 513 "compile.y" { /* ^field.$method{vasya} */ - yyval=yyvsp[-3]; /* with_xxx,diving code; stack: context,method_junction */ +#ifdef OPTIMIZE_BYTECODE_CUT_REM_OPERATOR +#ifdef OPTIMIZE_BYTECODE_GET_ELEMENT + const String* operator_name=LA2S(*yyvsp[-3], 0, OP::OP_VALUE__GET_ELEMENT_OR_OPERATOR); +#else + const String* operator_name=LA2S(*yyvsp[-3], 1); +#endif + if(operator_name && *operator_name == REM_OPERATOR_NAME){ + yyval=N(); + } else +#endif + { + yyval=yyvsp[-3]; /* with_xxx,diving code; stack: context,method_junction */ - YYSTYPE params_code=yyvsp[-1]; - 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_void()) // value is VVoid? - params_code=0; // ^zzz[] case. don't append lone empty param. - } - /* stack: context, method_junction */ - OA(*yyval, OP_CALL, params_code); // method_frame=make frame(pop junction); ncontext=pop; call(ncontext,method_frame) stack: value + YYSTYPE params_code=yyvsp[-1]; + if(params_code->count()==3) { // probably [] case. [OP::OP_VALUE+origin+Void] + if(Value* value=LA2V(*params_code)) // it is OP_VALUE+origin+value? + if(value->is_void()) // value is VVoid? + params_code=0; // ^zzz[] case. don't append lone empty param. + } + /* stack: context, method_junction */ + OA(*yyval, OP::OP_CALL, params_code); // method_frame=make frame(pop junction); ncontext=pop; call(ncontext,method_frame) stack: value + } ;} break; case 76: -#line 445 "compile.y" +#line 540 "compile.y" { yyval=yyvsp[-1]; P(*yyval, *yyvsp[0]) ;} break; case 80: -#line 451 "compile.y" +#line 546 "compile.y" { // allow ^call[ letters here any time ] *reinterpret_cast(&yyval)=PC.explicit_result; PC.explicit_result=false; @@ -1814,131 +1909,129 @@ yyreduce: break; case 81: -#line 454 "compile.y" +#line 549 "compile.y" { PC.explicit_result=*reinterpret_cast(&yyvsp[-1]); ;} break; case 82: -#line 456 "compile.y" +#line 551 "compile.y" {yyval=yyvsp[-2];} break; case 83: -#line 457 "compile.y" +#line 552 "compile.y" {yyval=yyvsp[-1];} break; case 84: -#line 458 "compile.y" +#line 553 "compile.y" {yyval=yyvsp[-1];} break; case 86: -#line 461 "compile.y" +#line 556 "compile.y" { yyval=yyvsp[-2]; P(*yyval, *yyvsp[0]) ;} break; case 88: -#line 465 "compile.y" +#line 560 "compile.y" { yyval=yyvsp[-2]; P(*yyval, *yyvsp[0]) ;} break; case 90: -#line 469 "compile.y" +#line 564 "compile.y" { yyval=yyvsp[-2]; P(*yyval, *yyvsp[0]) ;} break; case 91: -#line 471 "compile.y" +#line 566 "compile.y" { yyval=yyvsp[0]; - O(*yyval, OP_STORE_PARAM); ;} break; case 92: -#line 475 "compile.y" +#line 569 "compile.y" { YYSTYPE expr_code=yyvsp[0]; if(expr_code->count()==3 - && (*expr_code)[0].code==OP_VALUE) { // optimizing (double/bool/incidently 'string' too) case. [OP_VALUE+origin+Double] + && (*expr_code)[0].code==OP::OP_VALUE) { // optimizing (double/bool/incidently 'string' too) case. [OP::OP_VALUE+origin+Double]. no evaluating yyval=expr_code; - O(*yyval, OP_STORE_PARAM); // no evaluating } else { - ArrayOperation* code=N(); - O(*code, OP_PREPARE_TO_EXPRESSION); + YYSTYPE code=N(); + O(*code, OP::OP_PREPARE_TO_EXPRESSION); P(*code, *expr_code); - O(*code, OP_WRITE_EXPR_RESULT); + O(*code, OP::OP_WRITE_EXPR_RESULT); yyval=N(); - OA(*yyval, OP_EXPR_CODE__STORE_PARAM, code); + OA(*yyval, OP::OP_EXPR_CODE__STORE_PARAM, code); } ;} break; case 93: -#line 490 "compile.y" +#line 583 "compile.y" { yyval=N(); - OA(*yyval, OP_CURLY_CODE__STORE_PARAM, yyvsp[0]); + OA(*yyval, OP::OP_CURLY_CODE__STORE_PARAM, yyvsp[0]); ;} break; case 98: -#line 502 "compile.y" +#line 595 "compile.y" { yyval=yyvsp[-1]; P(*yyval, *yyvsp[0]) ;} break; case 100: -#line 504 "compile.y" +#line 597 "compile.y" { yyval=yyvsp[-1]; P(*yyval, *yyvsp[0]) ;} break; case 102: -#line 506 "compile.y" +#line 599 "compile.y" { // we know that name_advance1 not called from ^xxx context // so we'll not check for operator call possibility as we do in name_advance2 /* stack: context */ yyval=yyvsp[0]; /* stack: context,name */ - O(*yyval, OP_GET_ELEMENT); /* name=pop; context=pop; stack: context.get_element(name) */ + O(*yyval, OP::OP_GET_ELEMENT); /* name=pop; context=pop; stack: context.get_element(name) */ ;} break; case 103: -#line 514 "compile.y" +#line 607 "compile.y" { /* stack: context */ yyval=yyvsp[0]; /* stack: context,name */ - O(*yyval, OP_GET_ELEMENT); /* name=pop; context=pop; stack: context.get_element(name) */ + O(*yyval, OP::OP_GET_ELEMENT); /* name=pop; context=pop; stack: context.get_element(name) */ ;} break; case 109: -#line 527 "compile.y" +#line 620 "compile.y" { yyval=yyvsp[0]; - O(*yyval, OP_GET_ELEMENT); + O(*yyval, OP::OP_GET_ELEMENT); ;} break; case 110: -#line 531 "compile.y" +#line 624 "compile.y" { - ArrayOperation* code; + YYSTYPE code; { change_string_literal_to_write_string_literal(*(code=yyvsp[-1])); P(*code, *yyvsp[0]); } yyval=N(); - OA(*yyval, OP_STRING_POOL, code); + OA(*yyval, OP::OP_STRING_POOL, code); ;} break; case 111: -#line 540 "compile.y" +#line 633 "compile.y" { // allow $result_or_other_variable[ letters here any time ] *reinterpret_cast(&yyval)=PC.explicit_result; PC.explicit_result=false; @@ -1946,46 +2039,46 @@ yyreduce: break; case 112: -#line 543 "compile.y" +#line 636 "compile.y" { PC.explicit_result=*reinterpret_cast(&yyvsp[-1]); ;} break; case 113: -#line 545 "compile.y" +#line 638 "compile.y" { yyval=N(); - OA(*yyval, OP_OBJECT_POOL, yyvsp[-2]); /* stack: empty write context */ + OA(*yyval, OP::OP_OBJECT_POOL, yyvsp[-2]); /* stack: empty write context */ /* some code that writes to that context */ /* context=pop; stack: context.value() */ ;} break; case 114: -#line 551 "compile.y" +#line 644 "compile.y" { yyval=N(); - O(*yyval, OP_WITH_READ); + O(*yyval, OP::OP_WITH_READ); P(*yyval, *yyvsp[0]); ;} break; case 116: -#line 556 "compile.y" +#line 649 "compile.y" { yyval=yyvsp[-1]; P(*yyval, *yyvsp[0]) ;} break; case 117: -#line 557 "compile.y" +#line 650 "compile.y" { yyval=yyvsp[0]; - O(*yyval, OP_GET_ELEMENT__WRITE); + O(*yyval, OP::OP_GET_ELEMENT__WRITE); ;} break; case 120: -#line 566 "compile.y" +#line 659 "compile.y" { yyval=yyvsp[-1]; // stack: class name string if(*LA2S(*yyval) == BASE_NAME) { // pseudo BASE class @@ -1996,255 +2089,272 @@ yyreduce: YYERROR; } } - O(*yyval, OP_GET_CLASS); +#ifdef OPTIMIZE_BYTECODE_GET_CLASS + // optimized OP_VALUE+origin+string+OP_GET_CLASS => OP_VALUE__GET_CLASS+origin+string + maybe_change_first_opcode(*yyval, OP::OP_VALUE, OP::OP_VALUE__GET_CLASS, true/*assert if top opcode != OP_VALUE*/) +#else + O(*yyval, OP::OP_GET_CLASS); +#endif ;} break; case 121: -#line 578 "compile.y" +#line 676 "compile.y" { yyval=yyvsp[-1]; if(!PC.in_call_value) { strcpy(PC.error, ":: not allowed here"); YYERROR; } - O(*yyval, OP_PREPARE_TO_CONSTRUCT_OBJECT); + O(*yyval, OP::OP_PREPARE_TO_CONSTRUCT_OBJECT); ;} break; case 128: -#line 597 "compile.y" +#line 695 "compile.y" { yyval = yyvsp[-1] ;} break; case 129: -#line 598 "compile.y" +#line 696 "compile.y" { yyval = yyvsp[-1] ;} break; case 130: -#line 599 "compile.y" +#line 697 "compile.y" { yyval = yyvsp[-1]; ;} break; case 131: -#line 601 "compile.y" - { yyval=yyvsp[0]; O(*yyval, OP_NEG) ;} +#line 699 "compile.y" + { yyval=yyvsp[0]; O(*yyval, OP::OP_NEG) ;} break; case 132: -#line 602 "compile.y" +#line 700 "compile.y" { yyval=yyvsp[0] ;} break; case 133: -#line 603 "compile.y" - { yyval=yyvsp[0]; O(*yyval, OP_INV) ;} +#line 701 "compile.y" + { yyval=yyvsp[0]; O(*yyval, OP::OP_INV) ;} break; case 134: -#line 604 "compile.y" - { yyval=yyvsp[0]; O(*yyval, OP_NOT) ;} +#line 702 "compile.y" + { yyval=yyvsp[0]; O(*yyval, OP::OP_NOT) ;} break; case 135: -#line 605 "compile.y" - { yyval=yyvsp[0]; O(*yyval, OP_DEF) ;} +#line 703 "compile.y" + { yyval=yyvsp[0]; O(*yyval, OP::OP_DEF) ;} break; case 136: -#line 606 "compile.y" - { yyval=yyvsp[0]; O(*yyval, OP_IN) ;} +#line 704 "compile.y" + { yyval=yyvsp[0]; O(*yyval, OP::OP_IN) ;} break; case 137: -#line 607 "compile.y" - { yyval=yyvsp[0]; O(*yyval, OP_FEXISTS) ;} +#line 705 "compile.y" + { yyval=yyvsp[0]; O(*yyval, OP::OP_FEXISTS) ;} break; case 138: -#line 608 "compile.y" - { yyval=yyvsp[0]; O(*yyval, OP_DEXISTS) ;} +#line 706 "compile.y" + { yyval=yyvsp[0]; O(*yyval, OP::OP_DEXISTS) ;} break; case 139: -#line 610 "compile.y" - { yyval=yyvsp[-2]; P(*yyval, *yyvsp[0]); O(*yyval, OP_SUB) ;} +#line 708 "compile.y" + { yyval=yyvsp[-2]; P(*yyval, *yyvsp[0]); O(*yyval, OP::OP_SUB) ;} break; case 140: -#line 611 "compile.y" - { yyval=yyvsp[-2]; P(*yyval, *yyvsp[0]); O(*yyval, OP_ADD) ;} +#line 709 "compile.y" + { yyval=yyvsp[-2]; P(*yyval, *yyvsp[0]); O(*yyval, OP::OP_ADD) ;} break; case 141: -#line 612 "compile.y" - { yyval=yyvsp[-2]; P(*yyval, *yyvsp[0]); O(*yyval, OP_MUL) ;} +#line 710 "compile.y" + { yyval=yyvsp[-2]; P(*yyval, *yyvsp[0]); O(*yyval, OP::OP_MUL) ;} break; case 142: -#line 613 "compile.y" - { yyval=yyvsp[-2]; P(*yyval, *yyvsp[0]); O(*yyval, OP_DIV) ;} +#line 711 "compile.y" + { yyval=yyvsp[-2]; P(*yyval, *yyvsp[0]); O(*yyval, OP::OP_DIV) ;} break; case 143: -#line 614 "compile.y" - { yyval=yyvsp[-2]; P(*yyval, *yyvsp[0]); O(*yyval, OP_MOD) ;} +#line 712 "compile.y" + { yyval=yyvsp[-2]; P(*yyval, *yyvsp[0]); O(*yyval, OP::OP_MOD) ;} break; case 144: -#line 615 "compile.y" - { yyval=yyvsp[-2]; P(*yyval, *yyvsp[0]); O(*yyval, OP_INTDIV) ;} +#line 713 "compile.y" + { yyval=yyvsp[-2]; P(*yyval, *yyvsp[0]); O(*yyval, OP::OP_INTDIV) ;} break; case 145: -#line 616 "compile.y" - { yyval=yyvsp[-2]; P(*yyval, *yyvsp[0]); O(*yyval, OP_BIN_SL) ;} +#line 714 "compile.y" + { yyval=yyvsp[-2]; P(*yyval, *yyvsp[0]); O(*yyval, OP::OP_BIN_SL) ;} break; case 146: -#line 617 "compile.y" - { yyval=yyvsp[-2]; P(*yyval, *yyvsp[0]); O(*yyval, OP_BIN_SR) ;} +#line 715 "compile.y" + { yyval=yyvsp[-2]; P(*yyval, *yyvsp[0]); O(*yyval, OP::OP_BIN_SR) ;} break; case 147: -#line 618 "compile.y" - { yyval=yyvsp[-2]; P(*yyval, *yyvsp[0]); O(*yyval, OP_BIN_AND) ;} +#line 716 "compile.y" + { yyval=yyvsp[-2]; P(*yyval, *yyvsp[0]); O(*yyval, OP::OP_BIN_AND) ;} break; case 148: -#line 619 "compile.y" - { yyval=yyvsp[-2]; P(*yyval, *yyvsp[0]); O(*yyval, OP_BIN_OR) ;} +#line 717 "compile.y" + { yyval=yyvsp[-2]; P(*yyval, *yyvsp[0]); O(*yyval, OP::OP_BIN_OR) ;} break; case 149: -#line 620 "compile.y" - { yyval=yyvsp[-2]; P(*yyval, *yyvsp[0]); O(*yyval, OP_BIN_XOR) ;} +#line 718 "compile.y" + { yyval=yyvsp[-2]; P(*yyval, *yyvsp[0]); O(*yyval, OP::OP_BIN_XOR) ;} break; case 150: -#line 621 "compile.y" - { yyval=yyvsp[-2]; OA(*yyval, OP_NESTED_CODE, yyvsp[0]); O(*yyval, OP_LOG_AND) ;} +#line 719 "compile.y" + { yyval=yyvsp[-2]; OA(*yyval, OP::OP_NESTED_CODE, yyvsp[0]); O(*yyval, OP::OP_LOG_AND) ;} break; case 151: -#line 622 "compile.y" - { yyval=yyvsp[-2]; OA(*yyval, OP_NESTED_CODE, yyvsp[0]); O(*yyval, OP_LOG_OR) ;} +#line 720 "compile.y" + { yyval=yyvsp[-2]; OA(*yyval, OP::OP_NESTED_CODE, yyvsp[0]); O(*yyval, OP::OP_LOG_OR) ;} break; case 152: -#line 623 "compile.y" - { yyval=yyvsp[-2]; P(*yyval, *yyvsp[0]); O(*yyval, OP_LOG_XOR) ;} +#line 721 "compile.y" + { yyval=yyvsp[-2]; P(*yyval, *yyvsp[0]); O(*yyval, OP::OP_LOG_XOR) ;} break; case 153: -#line 624 "compile.y" - { yyval=yyvsp[-2]; P(*yyval, *yyvsp[0]); O(*yyval, OP_NUM_LT) ;} +#line 722 "compile.y" + { yyval=yyvsp[-2]; P(*yyval, *yyvsp[0]); O(*yyval, OP::OP_NUM_LT) ;} break; case 154: -#line 625 "compile.y" - { yyval=yyvsp[-2]; P(*yyval, *yyvsp[0]); O(*yyval, OP_NUM_GT) ;} +#line 723 "compile.y" + { yyval=yyvsp[-2]; P(*yyval, *yyvsp[0]); O(*yyval, OP::OP_NUM_GT) ;} break; case 155: -#line 626 "compile.y" - { yyval=yyvsp[-2]; P(*yyval, *yyvsp[0]); O(*yyval, OP_NUM_LE) ;} +#line 724 "compile.y" + { yyval=yyvsp[-2]; P(*yyval, *yyvsp[0]); O(*yyval, OP::OP_NUM_LE) ;} break; case 156: -#line 627 "compile.y" - { yyval=yyvsp[-2]; P(*yyval, *yyvsp[0]); O(*yyval, OP_NUM_GE) ;} +#line 725 "compile.y" + { yyval=yyvsp[-2]; P(*yyval, *yyvsp[0]); O(*yyval, OP::OP_NUM_GE) ;} break; case 157: -#line 628 "compile.y" - { yyval=yyvsp[-2]; P(*yyval, *yyvsp[0]); O(*yyval, OP_NUM_EQ) ;} +#line 726 "compile.y" + { yyval=yyvsp[-2]; P(*yyval, *yyvsp[0]); O(*yyval, OP::OP_NUM_EQ) ;} break; case 158: -#line 629 "compile.y" - { yyval=yyvsp[-2]; P(*yyval, *yyvsp[0]); O(*yyval, OP_NUM_NE) ;} +#line 727 "compile.y" + { yyval=yyvsp[-2]; P(*yyval, *yyvsp[0]); O(*yyval, OP::OP_NUM_NE) ;} break; case 159: -#line 630 "compile.y" - { yyval=yyvsp[-2]; P(*yyval, *yyvsp[0]); O(*yyval, OP_STR_LT) ;} +#line 728 "compile.y" + { yyval=yyvsp[-2]; P(*yyval, *yyvsp[0]); O(*yyval, OP::OP_STR_LT) ;} break; case 160: -#line 631 "compile.y" - { yyval=yyvsp[-2]; P(*yyval, *yyvsp[0]); O(*yyval, OP_STR_GT) ;} +#line 729 "compile.y" + { yyval=yyvsp[-2]; P(*yyval, *yyvsp[0]); O(*yyval, OP::OP_STR_GT) ;} break; case 161: -#line 632 "compile.y" - { yyval=yyvsp[-2]; P(*yyval, *yyvsp[0]); O(*yyval, OP_STR_LE) ;} +#line 730 "compile.y" + { yyval=yyvsp[-2]; P(*yyval, *yyvsp[0]); O(*yyval, OP::OP_STR_LE) ;} break; case 162: -#line 633 "compile.y" - { yyval=yyvsp[-2]; P(*yyval, *yyvsp[0]); O(*yyval, OP_STR_GE) ;} +#line 731 "compile.y" + { yyval=yyvsp[-2]; P(*yyval, *yyvsp[0]); O(*yyval, OP::OP_STR_GE) ;} break; case 163: -#line 634 "compile.y" - { yyval=yyvsp[-2]; P(*yyval, *yyvsp[0]); O(*yyval, OP_STR_EQ) ;} +#line 732 "compile.y" + { yyval=yyvsp[-2]; P(*yyval, *yyvsp[0]); O(*yyval, OP::OP_STR_EQ) ;} break; case 164: -#line 635 "compile.y" - { yyval=yyvsp[-2]; P(*yyval, *yyvsp[0]); O(*yyval, OP_STR_NE) ;} +#line 733 "compile.y" + { yyval=yyvsp[-2]; P(*yyval, *yyvsp[0]); O(*yyval, OP::OP_STR_NE) ;} break; case 165: -#line 636 "compile.y" - { yyval=yyvsp[-2]; P(*yyval, *yyvsp[0]); O(*yyval, OP_IS) ;} +#line 734 "compile.y" + { yyval=yyvsp[-2]; P(*yyval, *yyvsp[0]); O(*yyval, OP::OP_IS) ;} break; case 166: -#line 639 "compile.y" +#line 737 "compile.y" { - // optimized from OP_STRING->OP_VALUE for doubles + // optimized OP_STRING => OP_VALUE for doubles maybe_change_string_literal_to_double_literal(*(yyval=yyvsp[0])); ;} break; case 167: -#line 644 "compile.y" +#line 742 "compile.y" { +#ifdef OPTIMIZE_BYTECODE_STRING_POOL + // it brakes ^if(" 09 "){...} + YYSTYPE code=yyvsp[0]; + yyval=N(); + if(code->count()==3 && maybe_change_first_opcode(*code, OP::OP_STRING__WRITE, OP::OP_VALUE)){ + // optimized OP_STRING__WRITE+origin+value => OP_VALUE+origin+value without starting OP_STRING_POOL + P(*yyval, *code); + } else { + OA(*yyval, OP::OP_STRING_POOL, code); /* stack: empty write context */ + } +#else yyval=N(); - OA(*yyval, OP_STRING_POOL, yyvsp[0]); /* stack: empty write context */ + OA(*yyval, OP::OP_STRING_POOL, yyvsp[0]); /* stack: empty write context */ +#endif /* some code that writes to that context */ /* context=pop; stack: context.get_string() */ ;} break; case 168: -#line 653 "compile.y" +#line 763 "compile.y" { - // optimized from OP_STRING+OP_WRITE_VALUE to OP_STRING__WRITE + // optimized OP_STRING+OP_WRITE_VALUE => OP_STRING__WRITE change_string_literal_to_write_string_literal(*(yyval=yyvsp[0])) ;} break; case 169: -#line 658 "compile.y" +#line 768 "compile.y" { yyval=VL(/*we know that we will not change it*/const_cast(&vvoid), 0, 0, 0) ;} break; case 170: -#line 659 "compile.y" +#line 769 "compile.y" { yyval = VL(/*we know that we will not change it*/const_cast(&vtrue), 0, 0, 0) ;} break; case 171: -#line 660 "compile.y" +#line 770 "compile.y" { yyval = VL(/*we know that we will not change it*/const_cast(&vfalse), 0, 0, 0) ;} break; case 172: -#line 662 "compile.y" +#line 772 "compile.y" { yyval=N() ;} break; @@ -2252,7 +2362,7 @@ yyreduce: } /* Line 1010 of yacc.c. */ -#line 2256 "compile.tab.C" +#line 2366 "compile.tab.C" yyvsp -= yylen; yyssp -= yylen; @@ -2477,7 +2587,7 @@ yyreturn: } -#line 664 "compile.y" +#line 774 "compile.y" #endif @@ -2570,7 +2680,7 @@ case LS_DEF_COMMENT: default: switch(*pc.source) { // ^escaping some punctuators - case '^': case '$': case ';': + case '^': case '$': case ';': case '@': case '(': case ')': case '[': case ']': case '{': case '}': @@ -2598,7 +2708,7 @@ default: pc.string.append_strdup_know_length(begin, end-begin); } // #HH ? - if(pc.source[0]=='#' && pc.source[1] && pc.source[2]) { + if(pc.source[1] && isxdigit(pc.source[1]) && pc.source[2] && isxdigit(pc.source[2])) { char c=(char)( hex_value[(unsigned char)pc.source[1]]*0x10+ hex_value[(unsigned char)pc.source[2]]); @@ -2617,7 +2727,14 @@ default: // skip analysis = forced literal continue; } - break; + // just escaped char + // reset piece 'begin' position & line + begin=pc.source; + begin_pos=pc.pos; + // skip over _ after ^ + pc.source++; pc.pos.col++; + // skip analysis = forced literal + continue; } break; }