--- parser3/src/main/compile.y 2001/02/23 17:48:00 1.28 +++ parser3/src/main/compile.y 2001/02/24 15:26:03 1.34 @@ -1,5 +1,5 @@ /* - $Id: compile.y,v 1.28 2001/02/23 17:48:00 paf Exp $ + $Id: compile.y,v 1.34 2001/02/24 15:26:03 paf Exp $ */ %{ @@ -45,15 +45,59 @@ all: name_main.APPEND_CONST(MAIN_METHOD_NAME); Array& param_names=*NEW Array(POOL); Array& local_names=*NEW Array(POOL); - Method *method=NEW Method(POOL, name_main, param_names, local_names, *$1); - *PC->methods+=method; + Method& method=*NEW Method(POOL, name_main, param_names, local_names, *$1); + PC->vclass->add_method(name_main, method); } | methods; methods: method | methods method; one_big_piece: maybe_codes; -method: '@' STRING bracketed_maybe_strings maybe_bracketed_strings maybe_comment '\n' +method: control_method | code_method; + +control_method: '@' STRING '\n' + control_strings { + String *name=LA2S($2); + YYSTYPE strings_code=$4; + if(*name==CLASS_NAME) { + if(strings_code->size()==1*2) + PC->vclass->set_name(*LA2S(strings_code)); + else { + strcpy(PC->error, "@"CLASS_NAME" must contain sole name"); + YYERROR; + } + } else { + if(*name==USES_NAME) { + for(int i=0; isize(); i+=2) { + char file[MAX_STRING]; + strcpy(file, LA2S(strings_code, i)->cstr()); + strcat(file, ".p"); + PC->request->use(file, 0); + } + } else if(*name==PARENTS_NAME) { + for(int i=0; isize(); i+=2) { + String *parent_name=LA2S(strings_code, i); + VClass *parent=static_cast( + PC->request->classes().get(*parent_name)); + if(!parent) { + strcpy(PC->error, parent_name->cstr()); + strcat(PC->error, ": undefined class"); + YYERROR; + } + PC->vclass->add_parent(*parent); + } + } else { + strcpy(PC->error, name->cstr()); + strcat(PC->error, ": invalid special name. valid names are " + CLASS_NAME", "USES_NAME" and "PARENTS_NAME); + YYERROR; + } + } +}; +control_strings: control_string | control_strings '\n' control_string { $$=$1; P($$, $3) }; +control_string: STRING; + +code_method: '@' STRING bracketed_maybe_strings maybe_bracketed_strings maybe_comment '\n' maybe_codes { const String *name=LA2S($2); @@ -67,8 +111,8 @@ method: '@' STRING bracketed_maybe_strin for(int i=0; isize(); i+=2) locals_names+=LA2S(locals_names_code, i); - Method *method=NEW Method(POOL, *name, params_names, locals_names, *$7); - *PC->methods+=method; + Method& method=*NEW Method(POOL, *name, params_names, locals_names, *$7); + PC->vclass->add_method(*name, method); }; maybe_bracketed_strings: empty | bracketed_maybe_strings; @@ -125,12 +169,6 @@ name_without_curly_rdive_code: name_adva /* put */ put: '$' name_expr_wdive '(' constructor_value ')' { -/* - TODO: подсмотреть в $3, и если там первым элементом self, - то выкинуть его и делать не WITH_WRITE, а WITH_SELF - если ничего не осталось - $self(xxx) - обругать -*/ $$=$2; /* stack: context,name */ P($$, $4); /* stack: context,name,constructor_value */ OP($$, OP_CONSTRUCT); /* value=pop; name=pop; context=pop; construct(context,name,value) */ @@ -207,18 +245,26 @@ call: '^' name_without_curly_rdive store store_params: store_param | store_params store_param { $$=$1; P($$, $2) }; store_param: store_round_param | store_curly_param; store_round_param: '(' store_param_parts ')' {$$=$2}; -store_param_parts: store_param_part | store_param_parts ';' store_param_part { $$=$1; P($$, $3) }; -store_param_part: constructor_one_param_value { - $$=$1; - OP($$, OP_STORE_PARAM); -} +store_param_parts: + store_param_part +| store_param_parts ';' store_param_part { $$=$1; P($$, $3) } +; store_curly_param: '{' maybe_codes '}' { $$=N(POOL); - OP($$, OP_CODE_ARRAY); - AA($$, $2); - OP($$, OP_CREATE_JUNCTION); + PCA($$, $2); OP($$, OP_STORE_PARAM); }; +store_param_part: + empty /* optimized () case */ +| STRING { /* optimized (STRING) case */ + $$=$1; + OP($$, OP_STORE_PARAM); +} +| complex_constructor_param_value { /* (something complex) */ + $$=$1; + OP($$, OP_STORE_PARAM); +} +; /* name */ @@ -286,13 +332,15 @@ with: '$' name_without_curly_rdive '{' c /* basics */ write_str_literal: STRING { - $$=$1; - OP($$, OP_WRITE); -}; -empty_value: empty { - $$=$1; - PVS($$, NEW VString(POOL)); + if(LA2S($1)->size()) { + $$=$1; + OP($$, OP_WRITE); + } else { + // optimized case of special end of macro. see yylex + $$=N(POOL); + } }; +empty_value: /* empty */ { $$=L(NEW VString(POOL)) }; empty: /* empty */ { $$=N(POOL) }; %% @@ -384,7 +432,7 @@ int yylex(YYSTYPE *lvalp, void *pc) { PC->ls=LS_DEF_PARAMS; goto break2; } - if(c=='\n') { // wrong. bailing out + if(c=='\n') { // special @NAME or wrong result=c; pop_LS(PC); goto break2; @@ -436,7 +484,7 @@ int yylex(YYSTYPE *lvalp, void *pc) { c==' '|| c=='\t' || c=='\n' || c==')' || c=='}') { pop_LS(PC); - PC->source--; PC->col--; + PC->source--; if(--PC->col<0) { PC->line--; PC->col=-1; } result=EON; goto break2; } @@ -604,13 +652,12 @@ int yylex(YYSTYPE *lvalp, void *pc) { goto break2; } pop_LS(PC); - PC->source--; PC->col--; + PC->source--; if(--PC->col<0) { PC->line--; PC->col=-1; } result=EON; goto break2; } if(c==0) { result=-1; -// PC->source--; PC->col--; break; } } @@ -623,8 +670,10 @@ break2: // strip last \n before LS_DEF_NAME or EOF if((c=='@' || c==0) && end[-1]=='\n') end--; - // append last piece - PC->string->APPEND(begin, end-begin, PC->file, begin_line/*, start_col*/); + if(end!=begin) { + // append last piece + PC->string->APPEND(begin, end-begin, PC->file, begin_line/*, start_col*/); + } // create STRING value: array of OP_VALUE+vstring *lvalp=L(NEW VString(PC->string)); // new pieces storage