Diff for /parser3/src/main/compile.y between versions 1.280 and 1.291

version 1.280, 2016/05/24 16:38:40 version 1.291, 2021/11/08 11:44:19
Line 2 Line 2
 /** @file  /** @file
         Parser: compiler(lexical parser and grammar).          Parser: compiler(lexical parser and grammar).
   
         Copyright (c) 2001-2015 Art. Lebedev Studio (http://www.artlebedev.com)          Copyright (c) 2001-2020 Art. Lebedev Studio (http://www.artlebedev.com)
         Author: Alexander Petrosyan <paf@design.ru> (http://design.ru/paf)          Author: Alexander Petrosyan <paf@design.ru> (http://design.ru/paf)
   
                   
Line 62  static const VString vempty; Line 62  static const VString vempty;
 #define POOL  (*PC.pool)  #define POOL  (*PC.pool)
 #ifndef DOXYGEN  #ifndef DOXYGEN
   
 #define CLASS_ADD if(PC.class_add()){                                   \  #define CLASS_ADD if(PC.class_add()){                           \
         strncpy(PC.error, PC.cclass->type(), MAX_STRING/2);             \          strncpy(PC.error, PC.cclass->type(), MAX_STRING/2);     \
         strcat(PC.error, " - class is already defined");                \          strcat(PC.error, " - class is already defined");        \
         YYERROR;                                                        \          YYERROR;                                                \
   }
   
   #define PC_ERROR(header, value, footer){                        \
           strcpy(PC.error, header);                               \
           strncat(PC.error, value, MAX_STRING/2);                 \
           strcat(PC.error, footer);                               \
 }  }
   
 %}  %}
Line 137  static const VString vempty; Line 143  static const VString vempty;
 %%  %%
 all:  all:
         one_big_piece {          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->is_vars_local());
                 0, 0, /*min, max numbered_params_count*/  
                 0/*param_names*/, 0/*local_names*/,   
                 $1/*parser_code*/, 0/*native_code*/);  
         PC.cclass->set_method(PC.alias_method(main_method_name), method);          PC.cclass->set_method(PC.alias_method(main_method_name), method);
 }  }
 |       methods;  |       methods;
Line 155  control_method: '@' STRING '\n' Line 158  control_method: '@' STRING '\n'
         const String& command=LA2S(*$2)->trim(String::TRIM_END);          const String& command=LA2S(*$2)->trim(String::TRIM_END);
         YYSTYPE strings_code=$4;          YYSTYPE strings_code=$4;
         if(strings_code->count()<1*OPERATIONS_PER_OPVALUE) {          if(strings_code->count()<1*OPERATIONS_PER_OPVALUE) {
                 strcpy(PC.error, "@");                  PC_ERROR("@", command.cstr(), " is empty");
                 strcat(PC.error, command.cstr());  
                 strcat(PC.error, " is empty");  
                 YYERROR;                  YYERROR;
         }          }
         if(command==CLASS_NAME) {          if(command==CLASS_NAME) {
Line 166  control_method: '@' STRING '\n' Line 167  control_method: '@' STRING '\n'
                         // new class' name                          // new class' name
                         const String& name=LA2S(*strings_code)->trim(String::TRIM_END);                          const String& name=LA2S(*strings_code)->trim(String::TRIM_END);
                         // creating the class                          // creating the class
                         VStateless_class* cclass=new VClass;                          VStateless_class* cclass=new VClass(name.cstr(), PC.request.get_used_filespec(PC.file_no));
                         PC.cclass_new=cclass;                          PC.cclass_new=cclass;
                         PC.cclass_new->set_type(name.cstr());  
                         PC.append=false;                          PC.append=false;
                 } else {                  } else {
                         strcpy(PC.error, "@" CLASS_NAME " must contain only one line with class name (contains more then one)");                          strcpy(PC.error, "@" CLASS_NAME " must contain only one line with class name (contains more then one)");
Line 177  control_method: '@' STRING '\n' Line 177  control_method: '@' STRING '\n'
         } else if(command==USE_CONTROL_METHOD_NAME) {          } else if(command==USE_CONTROL_METHOD_NAME) {
                 CLASS_ADD;                  CLASS_ADD;
                 for(size_t i=0; i<strings_code->count(); i+=OPERATIONS_PER_OPVALUE){                  for(size_t i=0; i<strings_code->count(); i+=OPERATIONS_PER_OPVALUE){
                         PC.request.use_file(PC.request.main_class, LA2S(*strings_code, i)->trim(String::TRIM_END),                          PC.request.use_file(LA2S(*strings_code, i)->trim(String::TRIM_END), PC.request.get_used_filespec(PC.file_no), strings_code->get(i+1).origin);
                                 PC.request.get_used_filename(PC.file_no), strings_code->get(i+1).origin);  
                 }                  }
         } else if(command==BASE_NAME) {          } else if(command==BASE_NAME) {
                 if(PC.append){                  if(PC.append){
                         strcpy(PC.error, "can't set base while appending methods to class '");                          PC_ERROR("can't set base while appending methods to class '", PC.cclass->type(), "'");
                         strncat(PC.error, PC.cclass->type(), MAX_STRING/2);  
                         strcat(PC.error, "'");  
                         YYERROR;                          YYERROR;
                 }                  }
                 CLASS_ADD;                  CLASS_ADD;
                 if(PC.cclass->base_class()) { // already changed from default?                  if(PC.cclass->base_class()) { // already changed from default?
                         strcpy(PC.error, "class already have a base '");                          PC_ERROR("class already have a base '", PC.cclass->base_class()->type(), "'");
                         strncat(PC.error, PC.cclass->base_class()->type(), MAX_STRING/2);  
                         strcat(PC.error, "'");  
                         YYERROR;                          YYERROR;
                 }                  }
                 if(strings_code->count()==1*OPERATIONS_PER_OPVALUE) {                  if(strings_code->count()==1*OPERATIONS_PER_OPVALUE) {
                         const String& base_name=LA2S(*strings_code)->trim(String::TRIM_END);                          const String& base_name=LA2S(*strings_code)->trim(String::TRIM_END);
                         if(Value* base_class_value=PC.request.get_class(base_name)) {                          if(VStateless_class *base_class=PC.request.get_class(base_name)) {
                                 // @CLASS == @BASE sanity check                                  // @CLASS == @BASE sanity check
                                 if(VStateless_class *base_class=base_class_value->get_class()) {                                  if(PC.cclass==base_class) {
                                         if(PC.cclass==base_class) {                                          strcpy(PC.error, "@" CLASS_NAME " equals @" BASE_NAME);
                                                 strcpy(PC.error, "@" CLASS_NAME " equals @" BASE_NAME);  
                                                 YYERROR;  
                                         }  
                                         PC.cclass->get_class()->set_base(base_class);  
                                 } else { // they asked to derive from a class without methods ['env' & co]  
                                         strcpy(PC.error, base_name.cstr());  
                                         strcat(PC.error, ": you can not derive from this class in @" BASE_NAME);  
                                         YYERROR;                                          YYERROR;
                                 }                                  }
                                   PC.cclass->get_class()->set_base(base_class);
                         } else {                          } else {
                                 strcpy(PC.error, base_name.cstr());                                  PC_ERROR("'", base_name.cstr(), "': undefined class in @" BASE_NAME);
                                 strcat(PC.error, ": undefined class in @" BASE_NAME);  
                                 YYERROR;                                  YYERROR;
                         }                          }
                 } else {                  } else {
Line 227  control_method: '@' STRING '\n' Line 215  control_method: '@' STRING '\n'
                                 if(PC.cclass_new){                                  if(PC.cclass_new){
                                         if(VStateless_class* existed=PC.get_existed_class(PC.cclass_new)){                                          if(VStateless_class* existed=PC.get_existed_class(PC.cclass_new)){
                                                 if(!PC.reuse_existed_class(existed)){                                                  if(!PC.reuse_existed_class(existed)){
                                                         strcpy(PC.error, "can't append methods to '");                                                          PC_ERROR("can't append methods to '", PC.cclass_new->type(), "' - the class wasn't marked as partial");
                                                         strncat(PC.error, PC.cclass_new->type(), MAX_STRING/2);  
                                                         strcat(PC.error, "' - the class wasn't marked as partial");  
                                                         YYERROR;                                                          YYERROR;
                                                 }                                                  }
                                         } else {                                          } else {
Line 245  control_method: '@' STRING '\n' Line 231  control_method: '@' STRING '\n'
                         } else if(option==Symbols::DYNAMIC_SYMBOL){                          } else if(option==Symbols::DYNAMIC_SYMBOL){
                                 PC.set_methods_call_type(Method::CT_DYNAMIC);                                  PC.set_methods_call_type(Method::CT_DYNAMIC);
                         } else {                          } else {
                                 strcpy(PC.error, "'");                                  PC_ERROR("'", option.cstr(), "' invalid option. valid options are 'partial', 'locals', 'static' and 'dynamic'");
                                 strncat(PC.error, option.cstr(), MAX_STRING/2);  
                                 strcat(PC.error, "' invalid option. valid options are 'partial', 'locals', 'static' and 'dynamic'");  
                                 YYERROR;                                  YYERROR;
                         }                          }
                 }                  }
         } else {          } else {
                 strcpy(PC.error, "'");                  PC_ERROR("'", command.cstr(), "' invalid special name. valid names are '" CLASS_NAME "', '" USE_CONTROL_METHOD_NAME "', '" BASE_NAME "' and '" OPTIONS_CONTROL_METHOD_NAME "'.");
                 strncat(PC.error, command.cstr(), MAX_STRING/2);  
                 strcat(PC.error, "' invalid special name. valid names are "  
                         "'" CLASS_NAME "', '" USE_CONTROL_METHOD_NAME "', '" BASE_NAME "' and '" OPTIONS_CONTROL_METHOD_NAME "'.");  
                 YYERROR;                  YYERROR;
         }          }
 };  };
Line 278  code_method: '@' STRING bracketed_maybe_ Line 259  code_method: '@' STRING bracketed_maybe_
   
         YYSTYPE locals_names_code=$4;          YYSTYPE locals_names_code=$4;
         ArrayString* locals_names=0;          ArrayString* locals_names=0;
         bool all_vars_local=false;          bool all_vars_local=PC.cclass->is_vars_local();
   
         if(int size=locals_names_code->count()) {          if(int size=locals_names_code->count()) {
                 locals_names=new ArrayString;                  locals_names=new ArrayString;
                 for(int i=0; i<size; i+=OPERATIONS_PER_OPVALUE) {                  for(int i=0; i<size; i+=OPERATIONS_PER_OPVALUE) {
Line 291  code_method: '@' STRING bracketed_maybe_ Line 273  code_method: '@' STRING bracketed_maybe_
                                 *locals_names+=local_name;                                  *locals_names+=local_name;
                 }                  }
         }          }
         if(!all_vars_local && PC.cclass && PC.cclass->is_vars_local())  
                 all_vars_local=true;  
   
         Method* method=new Method(          Method* method=new Method(
                 //name,                   //name, 
Line 335  get: get_value { Line 315  get: get_value {
         size_t count=code->count();          size_t count=code->count();
   
 #ifdef OPTIMIZE_BYTECODE_GET_ELEMENT  #ifdef OPTIMIZE_BYTECODE_GET_ELEMENT
         if(          if(count!=3 || !change_first(*code, OP::OP_VALUE__GET_ELEMENT, /*=>*/OP::OP_VALUE__GET_ELEMENT__WRITE) )
                 count!=3  
                 || !change_first(*code, OP::OP_VALUE__GET_ELEMENT, /*=>*/OP::OP_VALUE__GET_ELEMENT__WRITE)  
         )  
 #endif  #endif
   
 #ifdef OPTIMIZE_BYTECODE_GET_SELF_ELEMENT  #ifdef OPTIMIZE_BYTECODE_GET_SELF_ELEMENT
         if(          if(count!=3 || !change_first(*code, OP::OP_WITH_SELF__VALUE__GET_ELEMENT, /*=>*/OP::OP_WITH_SELF__VALUE__GET_ELEMENT__WRITE) )
                 count!=3  
                 || !change_first(*code, OP::OP_WITH_SELF__VALUE__GET_ELEMENT, /*=>*/OP::OP_WITH_SELF__VALUE__GET_ELEMENT__WRITE)  
         )  
 #endif  #endif
   
 #ifdef OPTIMIZE_BYTECODE_GET_OBJECT_ELEMENT  #ifdef OPTIMIZE_BYTECODE_GET_OBJECT_ELEMENT
         if(          if(count!=5 || !change_first(*code, OP::OP_GET_OBJECT_ELEMENT, /*=>*/OP::OP_GET_OBJECT_ELEMENT__WRITE) )
                 count!=5  
                 || !change_first(*code, OP::OP_GET_OBJECT_ELEMENT, /*=>*/OP::OP_GET_OBJECT_ELEMENT__WRITE)  
         )  
 #endif  #endif
   
 #ifdef OPTIMIZE_BYTECODE_GET_OBJECT_VAR_ELEMENT  #ifdef OPTIMIZE_BYTECODE_GET_OBJECT_VAR_ELEMENT
         if(          if(count!=5 || !change_first(*code, OP::OP_GET_OBJECT_VAR_ELEMENT, /*=>*/OP::OP_GET_OBJECT_VAR_ELEMENT__WRITE) )
                 count!=5  
                 || !change_first(*code, OP::OP_GET_OBJECT_VAR_ELEMENT, /*=>*/OP::OP_GET_OBJECT_VAR_ELEMENT__WRITE)  
         )  
 #endif  #endif
   
 #ifdef OPTIMIZE_BYTECODE_GET_ELEMENT__SPECIAL  #ifdef OPTIMIZE_BYTECODE_GET_ELEMENT__SPECIAL
         if(          if(!change(*code, count-1/* last */, OP::OP_GET_ELEMENT__SPECIAL, /*=>*/OP::OP_GET_ELEMENT__SPECIAL__WRITE) )
                 !change(*code, count-1/* last */, OP::OP_GET_ELEMENT__SPECIAL, /*=>*/OP::OP_GET_ELEMENT__SPECIAL__WRITE)  
         )  
 #endif  #endif
   
         {          {
                 change_or_append(*code, count-1 /* last */,                  change_or_append(*code, count-1 /* last */, OP::OP_GET_ELEMENT, /*=>*/OP::OP_GET_ELEMENT__WRITE, /*or */OP::OP_WRITE_VALUE ); /* value=pop; wcontext.write(value) */
                         OP::OP_GET_ELEMENT, /*=>*/OP::OP_GET_ELEMENT__WRITE,  
                         /*or */OP::OP_WRITE_VALUE  
                         ); /* value=pop; wcontext.write(value) */  
         }          }
   
         P(*$$, *code);          P(*$$, *code);
Line 405  name_without_curly_rdive_read: name_with Line 368  name_without_curly_rdive_read: name_with
 #endif  #endif
   
 #ifdef OPTIMIZE_BYTECODE_GET_ELEMENT  #ifdef OPTIMIZE_BYTECODE_GET_ELEMENT
         if(          if(count>=4 && (*diving_code)[0].code==OP::OP_VALUE && (*diving_code)[3].code==OP::OP_GET_ELEMENT ){
                 count>=4  
                 && (*diving_code)[0].code==OP::OP_VALUE  
                 && (*diving_code)[3].code==OP::OP_GET_ELEMENT  
         ){  
                  // optimization                   // optimization
                 O(*$$,                  O(*$$,
                         (PC.in_call_value && count==4)                          (PC.in_call_value && count==4)
Line 466  name_expr_wdive_root: name_expr_dive_cod Line 425  name_expr_wdive_root: name_expr_dive_cod
                 // $self.                  // $self.
         } else          } else
 #ifdef OPTIMIZE_BYTECODE_GET_ELEMENT  #ifdef OPTIMIZE_BYTECODE_GET_ELEMENT
         if(          if(count>=4 && (*diving_code)[0].code==OP::OP_VALUE && (*diving_code)[3].code==OP::OP_GET_ELEMENT ){
                 count>=4  
                 && (*diving_code)[0].code==OP::OP_VALUE  
                 && (*diving_code)[3].code==OP::OP_GET_ELEMENT  
         ){  
                 O(*$$, OP::OP_WITH_ROOT__VALUE__GET_ELEMENT);                  O(*$$, OP::OP_WITH_ROOT__VALUE__GET_ELEMENT);
                 P(*$$, *diving_code, 1/*offset*/, 2/*limit*/); // copy origin+value                  P(*$$, *diving_code, 1/*offset*/, 2/*limit*/); // copy origin+value
                 if(count>4)                  if(count>4)
Line 508  construct_square: '[' { Line 463  construct_square: '[' {
 ;  ;
 construct_round: '(' expr_value ')' {   construct_round: '(' expr_value ')' { 
         $$=N();           $$=N(); 
         O(*$$, OP::OP_PREPARE_TO_EXPRESSION);  
         // stack: context, name          // stack: context, name
         P(*$$, *$2); // stack: context, name, value          P(*$$, *$2); // stack: context, name, value
         O(*$$, OP::OP_CONSTRUCT_EXPR); /* value=pop->as_expr_result; name=pop; context=pop; construct(context,name,value) */          O(*$$, OP::OP_CONSTRUCT_EXPR); /* value=pop->as_expr_result; name=pop; context=pop; construct(context,name,value) */
Line 543  call: call_value { Line 497  call: call_value {
 #endif  #endif
         {          {
                 $$=$1; /* stack: value */                  $$=$1; /* stack: value */
                 if(!change_first(*$$, OP::OP_CONSTRUCT_OBJECT, /*=>*/OP::OP_CONSTRUCT_OBJECT__WRITE))                  if(!change_first(*$$, OP::OP_CONSTRUCT_OBJECT, /*=>*/ OP::OP_CONSTRUCT_OBJECT__WRITE))
                         change_or_append(*$$, count-2 /* second last */,                          change_or_append(*$$, count-2 /* second last */, OP::OP_CALL, /*=>*/ OP::OP_CALL__WRITE, /*or */ OP::OP_WRITE_VALUE); /* value=pop; wcontext.write(value) */
                                 OP::OP_CALL, /*=>*/ OP::OP_CALL__WRITE,  
                                 /*or */OP::OP_WRITE_VALUE); /* value=pop; wcontext.write(value) */  
         }          }
 };  };
 call_value: '^' {   call_value: '^' { 
                                         PC.in_call_value=true;           PC.in_call_value=true; 
                         }  }
                         call_name {  call_name {
                                 PC.in_call_value=false;          PC.in_call_value=false;
                         }   } 
                         store_params EON { /* ^field.$method{vasya} */  store_params EON { /* ^field.$method{vasya} */
 #ifdef OPTIMIZE_BYTECODE_CUT_REM_OPERATOR  #ifdef OPTIMIZE_BYTECODE_CUT_REM_OPERATOR
 #ifdef OPTIMIZE_BYTECODE_GET_ELEMENT  #ifdef OPTIMIZE_BYTECODE_GET_ELEMENT
         const String* operator_name=LA2S(*$3, 0, OP::OP_VALUE__GET_ELEMENT_OR_OPERATOR);          const String* operator_name=LA2S(*$3, 0, OP::OP_VALUE__GET_ELEMENT_OR_OPERATOR);
Line 579  call_value: '^' { Line 531  call_value: '^' {
                         YYSTYPE var_code=$3;                          YYSTYPE var_code=$3;
                         if(                          if(
                                 var_code->count()==8                                  var_code->count()==8
                                 && (*var_code)[0].code==OP::OP_VALUE__GET_CLASS                                  && ( (*var_code)[0].code==OP::OP_VALUE__GET_CLASS || (*var_code)[0].code==OP::OP_VALUE__GET_BASE_CLASS )
                                 && (*var_code)[3].code==OP::OP_PREPARE_TO_CONSTRUCT_OBJECT                                  && (*var_code)[3].code==OP::OP_PREPARE_TO_CONSTRUCT_OBJECT
                                 && (*var_code)[4].code==OP::OP_VALUE                                  && (*var_code)[4].code==OP::OP_VALUE
 #ifdef FEATURE_GET_ELEMENT4CALL  #ifdef FEATURE_GET_ELEMENT4CALL
Line 653  store_expr_param_part: expr_value { Line 605  store_expr_param_part: expr_value {
                 $$=expr_code;                   $$=expr_code; 
         } else {          } else {
                 YYSTYPE code=N();                  YYSTYPE code=N();
                 O(*code, OP::OP_PREPARE_TO_EXPRESSION);  
                 P(*code, *expr_code);                  P(*code, *expr_code);
                 O(*code, OP::OP_WRITE_EXPR_RESULT);                  O(*code, OP::OP_WRITE_EXPR_RESULT);
                 $$=N();                   $$=N(); 
Line 729  name_square_code_value: '[' { Line 680  name_square_code_value: '[' {
         if(!maybe_append_simple_diving_code(*$$, *$3))          if(!maybe_append_simple_diving_code(*$$, *$3))
 #endif  #endif
         {          {
         OA(*$$, OP::OP_OBJECT_POOL, $3); /* stack: empty write context */                  OA(*$$, OP::OP_OBJECT_POOL, $3); /* stack: empty write context */
         /* some code that writes to that context */                  /* some code that writes to that context */
         /* context=pop; stack: context.value() */                  /* context=pop; stack: context.value() */
         }          }
 };  };
 subvar_ref_name_rdive: STRING {  subvar_ref_name_rdive: STRING {
Line 751  class_prefix: Line 702  class_prefix:
 ;  ;
 class_static_prefix: STRING ':' {  class_static_prefix: STRING ':' {
         $$=$1; // stack: class name string          $$=$1; // stack: class name string
           OP::OPCODE code = OP::OP_VALUE__GET_CLASS;
         if(*LA2S(*$$) == BASE_NAME) { // pseudo BASE class          if(*LA2S(*$$) == BASE_NAME) { // pseudo BASE class
                 if(VStateless_class* base=PC.cclass->base_class()) {                  if(VStateless_class* base=PC.cclass->base_class()) {
                         change_string_literal_value(*$$, *new String(base->type()));                          change_string_literal_value(*$$, *new String(base->type()));
Line 758  class_static_prefix: STRING ':' { Line 710  class_static_prefix: STRING ':' {
                         strcpy(PC.error, "no base class declared");                          strcpy(PC.error, "no base class declared");
                         YYERROR;                          YYERROR;
                 }                  }
                   code = OP::OP_VALUE__GET_BASE_CLASS;
           } else {
                   // can't use get_class because it will call @autouse[] if the class wasn't loaded
                   VStateless_class* base=PC.request.classes().get(*LA2S(*$$));
                   if(base && PC.cclass->derived_from(*base))
                           code = OP::OP_VALUE__GET_BASE_CLASS;
         }          }
         // optimized OP_VALUE+origin+string+OP_GET_CLASS => OP_VALUE__GET_CLASS+origin+string          // optimized OP_VALUE+origin+string+OP_GET_CLASS => OP_VALUE__GET_CLASS+origin+string
         change_first(*$$, OP::OP_VALUE, OP::OP_VALUE__GET_CLASS);          change_first(*$$, OP::OP_VALUE, code);
 };  };
 class_constructor_prefix: class_static_prefix ':' {  class_constructor_prefix: class_static_prefix ':' {
         $$=$1;          $$=$1;
Line 1604  default: Line 1562  default:
                                 pc.ls=LS_METHOD_SQUARE;                                  pc.ls=LS_METHOD_SQUARE;
                                 lexical_brackets_nestage=1;                                  lexical_brackets_nestage=1;
                                 RC;                                  RC;
                         }                                                                    }
                         if(c=='{') {/* ]{ }{ ){ */                          if(c=='{') {/* ]{ }{ ){ */
                                 pc.ls=LS_METHOD_CURLY;                                  pc.ls=LS_METHOD_CURLY;
                                 lexical_brackets_nestage=1;                                  lexical_brackets_nestage=1;
                                 RC;                                  RC;
                         }                                                                    }
                         if(c=='(') {/* ]( }( )( */                          if(c=='(') {/* ]( }( )( */
                                 pc.ls=LS_METHOD_ROUND;                                  pc.ls=LS_METHOD_ROUND;
                                 lexical_brackets_nestage=1;                                  lexical_brackets_nestage=1;
                                 RC;                                  RC;
                         }                                                                    }
                         pop_LS(pc);                          pop_LS(pc);
                         pc.ungetc();                          pc.ungetc();
                         result=EON;                          result=EON;
Line 1645  break2: Line 1603  break2:
 #else  #else
                 Value *lookup=0;                  Value *lookup=0;
 #endif  #endif
                 *lvalp=VL(                  *lvalp=VL(lookup ? lookup : new VString(*new String(pc.string, String::L_CLEAN)), pc.file_no, pc.string_start.line, pc.string_start.col);
                         lookup ? lookup : new VString(*new String(pc.string, String::L_CLEAN)), pc.file_no, pc.string_start.line, pc.string_start.col);  
                 // new pieces storage                  // new pieces storage
                 pc.string.clear();                  pc.string.clear();
                 pc.string_start.clear();                  pc.string_start.clear();
Line 1660  break2: Line 1617  break2:
 }  }
   
 static int real_yyerror(Parse_control *pc, const char *s) {  // Called by yyparse on error  static int real_yyerror(Parse_control *pc, const char *s) {  // Called by yyparse on error
            strncpy(PC.error, s, MAX_STRING);          pa_strncpy(PC.error, s, MAX_STRING);
            return 1;          return 1;
 }  }
   
 static void yyprint(FILE *file, int type, YYSTYPE value) {  static void yyprint(FILE *file, int type, YYSTYPE value) {

Removed from v.1.280  
changed lines
  Added in v.1.291


E-mail: