--- parser3/src/main/compile.y 2002/09/13 11:35:13 1.192 +++ parser3/src/main/compile.y 2002/10/14 15:22:42 1.198 @@ -5,7 +5,7 @@ Copyright (c) 2001 ArtLebedev Group (http://www.artlebedev.com) Author: Alexander Petrosyan (http://design.ru/paf) - $Id: compile.y,v 1.192 2002/09/13 11:35:13 paf Exp $ + $Id: compile.y,v 1.198 2002/10/14 15:22:42 paf Exp $ */ /** @@ -60,15 +60,20 @@ static int yylex(YYSTYPE *lvalp, void *p %token BAD_STRING_COMPARISON_OPERATOR %token BAD_HEX_LITERAL %token BAD_METHOD_DECL_START +%token BAD_METHOD_PARAMETER_NAME_CHARACTER +%token BAD_MATH_OPERATOR_CHARACTER %token LAND "&&" %token LOR "||" -%token LXOR "##" +%token LXOR "!||" +%token NXOR "!|" %token NLE "<=" %token NGE ">=" %token NEQ "==" %token NNE "!=" +%token NSL "<<" +%token NSR ">>" %token SLT "lt" %token SGT "gt" @@ -84,7 +89,7 @@ static int yylex(YYSTYPE *lvalp, void *p %token IS "is" /* logical */ -%left "##" +%left "!||" %left "||" %left "&&" %left '<' '>' "<=" ">=" "lt" "gt" "le" "ge" @@ -93,10 +98,12 @@ static int yylex(YYSTYPE *lvalp, void *p %left '!' /* bitwise */ -%left '#' +%left "!|" %left '|' %left '&' %left '~' +%left ">>" +%left "<<" /* numerical */ %left '-' '+' @@ -104,7 +111,7 @@ static int yylex(YYSTYPE *lvalp, void *p %left NEG /* negation: unary - */ %% -all: +all: one_big_piece { Method& method=*NEW Method(POOL, PC.request->main_method_name, @@ -152,7 +159,7 @@ control_method: '@' STRING '\n' } } else if(command==USE_CONTROL_METHOD_NAME) { for(int i=0; isize(); i+=2) - PC.request->use_file(*LA2S(strings_code, i)); + PC.request->use_file(PC.request->main_class, *LA2S(strings_code, i)); } else if(command==BASE_NAME) { if(PC.cclass->base_class()) { // already changed from default? strcpy(PC.error, "class already have a base '"); @@ -266,10 +273,25 @@ name_without_curly_rdive_read: name_with } else { O($$, OP_WITH_READ); /* stack: starting context */ - // ^if ELEMENT -> ^if ELEMENT_OR_OPERATOR - // OP_VALUE+string+OP_GET_ELEMENT. -> OP_VALUE+string+OP_GET_ELEMENT_OR_OPERATOR. - if(PC.in_call_value && diving_code->size()==3) - diving_code->put_int(2, OP_GET_ELEMENT_OR_OPERATOR); + bool noDot=diving_code->size()==3; + // OP_VALUE+string+OP_GET_ELEMENT. -> OP_VALUE+string+...OR_OPERATOR/OR_JUNCTION_EXP. + if(PC.in_call_value) { + // ^if << possibly operator + // but ^code.xxxx << expand junction !!! + + diving_code->put_int(2, + noDot? // ELEMENT without .SUBELEMENT + OP_GET_ELEMENT_OR_OPERATOR // possibly ^if [search for operator] + : OP_GET_ELEMENT_OR_JUNCTION_EXPAND); // possibly ^junction.xxx [if junction, expand it] + } else { + // $code << expand junction + // $code.value << do not expand junction + // $code.value[xxx] << do not expand junction + + if(noDot) + diving_code->put_int(2, OP_GET_ELEMENT_OR_JUNCTION_EXPAND); // possibly $junction [if junction, expand it] + } + P($$, diving_code); } /* diving code; stack: current context */ @@ -537,12 +559,14 @@ expr: | expr '/' expr { $$=$1; P($$, $3); O($$, OP_DIV) } | expr '%' expr { $$=$1; P($$, $3); O($$, OP_MOD) } | expr '\\' expr { $$=$1; P($$, $3); O($$, OP_INTDIV) } +| expr "<<" expr { $$=$1; P($$, $3); O($$, OP_BIN_SL) } +| expr ">>" expr { $$=$1; P($$, $3); O($$, OP_BIN_SR) } | expr '&' expr { $$=$1; P($$, $3); O($$, OP_BIN_AND) } | expr '|' expr { $$=$1; P($$, $3); O($$, OP_BIN_OR) } -| expr '#' expr { $$=$1; P($$, $3); O($$, OP_BIN_XOR) } +| expr "!|" expr { $$=$1; P($$, $3); O($$, OP_BIN_XOR) } | expr "&&" expr { $$=$1; OA($$, OP_NESTED_CODE, $3); O($$, OP_LOG_AND) } | expr "||" expr { $$=$1; OA($$, OP_NESTED_CODE, $3); O($$, OP_LOG_OR) } -| expr "##" expr { $$=$1; P($$, $3); O($$, OP_LOG_XOR) } +| expr "!||" expr { $$=$1; P($$, $3); O($$, OP_LOG_XOR) } | expr '<' expr { $$=$1; P($$, $3); O($$, OP_NUM_LT) } | expr '>' expr { $$=$1; P($$, $3); O($$, OP_NUM_GT) } | expr "<=" expr { $$=$1; P($$, $3); O($$, OP_NUM_LE) } @@ -642,7 +666,7 @@ case LS_VAR_NAME_SIMPLE_WITH_COLON: case LS_VAR_NAME_SIMPLE_WITHOUT_COLON: case LS_VAR_NAME_CURLY: case LS_METHOD_NAME: -case LS_COMMENT: +case LS_USER_COMMENT: case LS_DEF_COMMENT: // no literals in names, please break; @@ -710,7 +734,7 @@ default: PC.string->APPEND_CLEAN(begin, end-begin, PC.file, begin_line); } // fall into COMMENT lexical state [wait for \n] - push_LS(PC, LS_COMMENT); + push_LS(PC, LS_USER_COMMENT); continue; } switch(PC.ls) { @@ -749,7 +773,7 @@ default: break; // #COMMENT - case LS_COMMENT: + case LS_USER_COMMENT: if(c=='\n') { // skip comment begin=PC.source; @@ -797,7 +821,8 @@ default: case LS_DEF_PARAMS: switch(c) { case '$': // common error - RC; + result=BAD_METHOD_PARAMETER_NAME_CHARACTER; + goto break2; case ';': RC; case ']': @@ -846,6 +871,15 @@ default: else // PC.ls==LS_VAR_ROUND // variable constructor ended pop_LS(PC); // return to normal life RC; + case '#': // comment start skipping + if(end!=begin) { + // append piece till # + PC.string->APPEND_CLEAN(begin, end-begin, PC.file, begin_line); + } + // fall into COMMENT lexical state [wait for \n] + push_LS(PC, LS_EXPRESSION_COMMENT); + lexical_brackets_nestage=1; + continue; case '$': push_LS(PC, LS_EXPRESSION_VAR_NAME_WITH_COLON); RC; @@ -874,25 +908,59 @@ default: case '~': case ';': RC; - case '&': case '|': case '#': + case '&': case '|': if(*PC.source==c) { // && || - result=c=='#'?LXOR:c=='&'?LAND:LOR; + result=c=='&'?LAND:LOR; skip_analized=1; } else result=c; goto break2; - case '<': case '>': case '=': case '!': - if(*PC.source=='=') { // <= >= == != + case '!': + switch(PC.source[0]) { + case '|': // !| !|| skip_analized=1; - switch(c) { - case '<': result=NLE; break; - case '>': result=NGE; break; - case '=': result=NEQ; break; - case '!': result=NNE; break; - } - } else - result=c; + if(PC.source[1]=='|') { + skip_analized++; + result=LXOR; + } else + result=NXOR; + goto break2; + case '=': // != + skip_analized=1; + result=NNE; + goto break2; + } + RC; + + case '<': // <<, <=, < + switch(*PC.source) { + case '<': // <[<] + skip_analized=1; result=NSL; break; + case '=': // <[=] + skip_analized=1; result=NLE; break; + default: // <[] + result=c; break; + } + goto break2; + case '>': // >>, >=, > + switch(*PC.source) { + case '>': // >[>] + skip_analized=1; result=NSR; break; + case '=': // >[=] + skip_analized=1; result=NGE; break; + default: // >[] + result=c; break; + } + goto break2; + case '=': // == + switch(*PC.source) { + case '=': // =[=] + skip_analized=1; result=NEQ; break; + default: // =[] + result=c; break; // not used now + } goto break2; + case '"': push_LS(PC, LS_EXPRESSION_STRING_QUOTED); RC; @@ -955,6 +1023,24 @@ default: continue; } break; + case LS_EXPRESSION_COMMENT: + if(c=='(') + lexical_brackets_nestage++; + + switch(*PC.source) { + case '\n': case ')': + if(*PC.source==')') + if(--lexical_brackets_nestage!=0) + continue; + + // skip comment + begin=PC.source; + begin_line=PC.line; + + pop_LS(PC); + continue; + } + break; // VARIABLE GET/PUT/WITH case LS_VAR_NAME_SIMPLE_WITH_COLON: @@ -1218,7 +1304,7 @@ break2: if(end!=begin && end[-1]=='\n') // allow one empty line before LS_DEF_NAME end--; } - if(end!=begin && PC.ls!=LS_COMMENT) { // last piece still alive and not comment? + if(end!=begin && PC.ls!=LS_USER_COMMENT) { // last piece still alive and not comment? // append it PC.string->APPEND_CLEAN(begin, end-begin, PC.file, begin_line/*, start_col*/); }