--- parser3/src/main/compile.y 2001/03/25 10:14:39 1.115 +++ parser3/src/main/compile.y 2001/04/20 14:18:41 1.126 @@ -5,7 +5,7 @@ Author: Alexander Petrosyan (http://design.ru/paf) - $Id: compile.y,v 1.115 2001/03/25 10:14:39 paf Exp $ + $Id: compile.y,v 1.126 2001/04/20 14:18:41 paf Exp $ */ /** @@ -31,6 +31,7 @@ #include "pa_config_includes.h" #include #include +#include #include "compile_tools.h" #include "pa_value.h" @@ -38,13 +39,14 @@ #include "pa_vobject.h" #include "pa_vdouble.h" #include "pa_globals.h" +#include "pa_vunknown.h" #define SELF_ELEMENT_NAME "self" #define USE_CONTROL_METHOD_NAME "USE" -int real_yyerror(parse_control *pc, char *s); +static int real_yyerror(parse_control *pc, char *s); static void yyprint(FILE *file, int type, YYSTYPE value); -int yylex(YYSTYPE *lvalp, void *pc); +static int yylex(YYSTYPE *lvalp, void *pc); // local convinient inplace typecast & var @@ -111,6 +113,7 @@ all: one_big_piece { Method& method=*NEW Method(POOL, *main_method_name, + Method::CT_ANY, 0, 0, /*min, max numbered_params_count*/ 0/*param_names*/, 0/*local_names*/, $1/*parser_code*/, 0/*native_code*/); @@ -125,7 +128,7 @@ method: control_method | code_method; control_method: '@' STRING '\n' control_strings { - const String& command=*SLA2S($2); + const String& command=*LA2S($2); YYSTYPE strings_code=$4; if(strings_code->size()<1*2) { strcpy(PC.error, "@"); @@ -134,7 +137,7 @@ control_method: '@' STRING '\n' YYERROR; } if(command==CLASS_NAME) { - if(PC.cclass!=&PC.request->ROOT) { // already changed from default? + if(PC.cclass) { // already changed from default? strcpy(PC.error, "class already have a name '"); strncat(PC.error, PC.cclass->name().cstr(), 100); strcat(PC.error, "'"); @@ -142,12 +145,10 @@ control_method: '@' STRING '\n' } if(strings_code->size()==1*2) { // new class' name - const String *name=SLA2S(strings_code); + const String *name=LA2S(strings_code); // creating the class PC.cclass=NEW VClass(POOL); PC.cclass->set_name(*name); - // defaulting base. may change with @BASE - PC.cclass->set_base(PC.request->ROOT); // append to request's classes PC.request->classes().put(*name, PC.cclass); } else { @@ -158,16 +159,16 @@ control_method: '@' STRING '\n' if(command==USE_CONTROL_METHOD_NAME) { for(int i=0; isize(); i+=2) PC.request->use_file( - PC.request->absolute(*SLA2S(strings_code, i))); + PC.request->absolute(*LA2S(strings_code, i))); } else if(command==BASE_NAME) { - if(PC.cclass->base()!=&PC.request->ROOT) { // already changed from default? + if(PC.cclass->base()) { // already changed from default? strcpy(PC.error, "class already have a base '"); strncat(PC.error, PC.cclass->base()->name().cstr(), 100); strcat(PC.error, "'"); YYERROR; } if(strings_code->size()==1*2) { - const String& base_name=*SLA2S(strings_code); + const String& base_name=*LA2S(strings_code); VClass *base=static_cast( PC.request->classes().get(base_name)); if(!base) { @@ -200,14 +201,14 @@ maybe_string: empty | STRING; code_method: '@' STRING bracketed_maybe_strings maybe_bracketed_strings maybe_comment '\n' maybe_codes { - const String *name=SLA2S($2); + const String *name=LA2S($2); YYSTYPE params_names_code=$3; Array *params_names=0; if(int size=params_names_code->size()) { params_names=NEW Array(POOL); for(int i=0; isize()) { locals_names=NEW Array(POOL); for(int i=0; isize()==3) // probably [] case. [OP_VALUE + Unknown + STORE_PARAM] + if(Value *value=LA2V(params_code)) // it is OP_VALUE + value? + if(!value->is_defined()) // value is VUnknown? + params_code=0; // ^zzz[] case. don't append lone empty param. + if(params_code) + P($$, params_code); // filling method_frame.store_params + O($$, OP_CALL); // method_frame=pop; ncontext=pop; call(ncontext,method_frame) stack: value }; call_name: name_without_curly_rdive; @@ -370,17 +379,10 @@ store_curly_param_parts: store_curly_param_part | store_curly_param_parts ';' store_curly_param_part { $$=$1; P($$, $3) } ; -store_code_param_part: - empty /* optimized [] case */ -| STRING { /* optimized [STRING] case */ +store_code_param_part: code_param_value { $$=$1; O($$, OP_STORE_PARAM); -} -| constructor_code_value { /* [something complex] */ - $$=$1; - O($$, OP_STORE_PARAM); -} -; +}; store_expr_param_part: write_expr_value { $$=N(POOL); PEA($$, $1); @@ -389,6 +391,11 @@ store_curly_param_part: maybe_codes { $$=N(POOL); PCA($$, $1); }; +code_param_value: + unknown_value /* optimized [;...] case */ +| STRING /* optimized [STRING] case */ +| constructor_code_value /* [something complex] */ +; write_expr_value: expr_value { $$=$1; O($$, OP_WRITE_EXPR_RESULT); @@ -522,7 +529,7 @@ write_string: STRING { change_string_literal_to_write_string_literal($$=$1) }; -empty_string_value: /* empty */ { $$=VL(NEW VString(POOL)) }; +unknown_value: /* empty */ { $$=VL(NEW VUnknown(POOL)) }; empty: /* empty */ { $$=N(POOL) }; %% @@ -570,16 +577,17 @@ static int yylex(YYSTYPE *lvalp, void *p } else PC.col++; - if(c=='^') + if(c=='^' && PC.ls!=LS_COMMENT && PC.ls!=LS_DEF_COMMENT) switch(*PC.source) { - // escaping: ^^ ^$ ^; ^) ^} ^( ^{ ^" + // escaping: ^^ & co case '^': case '$': case ';': + case '(': case ')': case '[': case ']': case '{': case '}': case '"': if(end!=begin) { // append piece till ^ - PC.string->APPEND(begin, end-begin, PC.file, begin_line); + PC.string->APPEND_CLEAN(begin, end-begin, PC.file, begin_line); } // reset piece 'begin' position & line begin=PC.source; // ^ @@ -593,7 +601,7 @@ static int yylex(YYSTYPE *lvalp, void *p case '#': if(end!=begin) { // append piece till ^ - PC.string->APPEND(begin, end-begin, PC.file, begin_line); + PC.string->APPEND_CLEAN(begin, end-begin, PC.file, begin_line); } // #HH ? if(PC.source[0]=='#' && PC.source[1] && PC.source[2]) { @@ -606,7 +614,7 @@ static int yylex(YYSTYPE *lvalp, void *p goto break2; // wrong hex value[no ^#00 chars allowed]: bail out } // append char(hex(HH)) - PC.string->APPEND(hex, 1, PC.file, begin_line); + PC.string->APPEND_CLEAN(hex, 1, PC.file, begin_line); // skip over ^#HH PC.source+=3; PC.col+=3; @@ -621,7 +629,7 @@ static int yylex(YYSTYPE *lvalp, void *p if(c=='#' && PC.col==1) { if(end!=begin) { // append piece till # - PC.string->APPEND(begin, end-begin, PC.file, begin_line); + PC.string->APPEND_CLEAN(begin, end-begin, PC.file, begin_line); } // fall into COMMENT lexical state [wait for \n] push_LS(PC, LS_COMMENT); @@ -785,33 +793,33 @@ static int yylex(YYSTYPE *lvalp, void *p RC; case 'l': case 'g': case 'e': case 'n': if(end==begin) // right after whitespace - switch(*PC.source) { -// case '?': // ok [and bad cases, yacc would bark at them] - case 't': // lt gt [et nt] - result=c=='l'?SLT:c=='g'?SGT:BAD_STRING_COMPARISON_OPERATOR; - skip_analized=1; - goto break2; - case 'e': // le ge ne [ee] - result=c=='l'?SLE:c=='g'?SGE:c=='n'?SNE:BAD_STRING_COMPARISON_OPERATOR; - skip_analized=1; - goto break2; - case 'q': // eq [lq gq nq] - result=c=='e'?SEQ:BAD_STRING_COMPARISON_OPERATOR; - skip_analized=1; - goto break2; + if(isspace(PC.source[1])) { + switch(*PC.source) { + // case '?': // ok [and bad cases, yacc would bark at them] + case 't': // lt gt [et nt] + result=c=='l'?SLT:c=='g'?SGT:BAD_STRING_COMPARISON_OPERATOR; + skip_analized=1; + goto break2; + case 'e': // le ge ne [ee] + result=c=='l'?SLE:c=='g'?SGE:c=='n'?SNE:BAD_STRING_COMPARISON_OPERATOR; + skip_analized=1; + goto break2; + case 'q': // eq [lq gq nq] + result=c=='e'?SEQ:BAD_STRING_COMPARISON_OPERATOR; + skip_analized=1; + goto break2; + } } break; case 'i': if(end==begin) // right after whitespace - switch(PC.source[0]) { - case 'n': - { // in + if(isspace(PC.source[1])) { + switch(PC.source[0]) { + case 'n': // in skip_analized=1; result=IN; goto break2; - } - case 's': - { // is + case 's': // is skip_analized=1; result=IS; goto break2; @@ -857,13 +865,14 @@ static int yylex(YYSTYPE *lvalp, void *p case 0: case ' ': case '\t': case '\n': case ';': - case ']': case '}': case ')': case '"': + case ']': case '}': case ')': + case '"': case '\'': case '<': case '>': // these stand for HTML brackets and expression binary ops case '+': case '*': case '/': case '%': case '&': case '|': case '=': case '!': // common delimiters - case '\'': case ',': + case ',': pop_LS(PC); PC.source--; if(--PC.col<0) { PC.line--; PC.col=-1; } result=EON; @@ -1047,7 +1056,7 @@ break2: } if(end!=begin) { // last piece still alive? // append it - PC.string->APPEND(begin, end-begin, PC.file, begin_line/*, start_col*/); + PC.string->APPEND_CLEAN(begin, end-begin, PC.file, begin_line/*, start_col*/); } } if(PC.string->size()) { // something accumulated? @@ -1071,5 +1080,5 @@ static int real_yyerror(parse_control *p static void yyprint(FILE *file, int type, YYSTYPE value) { if(type==STRING) - fprintf(file, " \"%s\"", SLA2S(value)->cstr()); + fprintf(file, " \"%s\"", LA2S(value)->cstr()); }