--- parser3/src/main/compile.y 2002/09/13 13:41:48 1.193 +++ parser3/src/main/compile.y 2002/10/15 08:31:56 1.199 @@ -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.193 2002/09/13 13:41:48 paf Exp $ + $Id: compile.y,v 1.199 2002/10/15 08:31:56 paf Exp $ */ /** @@ -72,6 +72,8 @@ static int yylex(YYSTYPE *lvalp, void *p %token NGE ">=" %token NEQ "==" %token NNE "!=" +%token NSL "<<" +%token NSR ">>" %token SLT "lt" %token SGT "gt" @@ -100,6 +102,8 @@ static int yylex(YYSTYPE *lvalp, void *p %left '|' %left '&' %left '~' +%left ">>" +%left "<<" /* numerical */ %left '-' '+' @@ -107,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, @@ -155,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 '"); @@ -269,10 +273,14 @@ 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); + // OP_VALUE+string+OP_GET_ELEMENT. -> OP_VALUE+string+...OR_OPERATOR/OR_JUNCTION_EXP. + if(diving_code->size()==3) // ELEMENT without .SUBELEMENT + diving_code->put_int(2, + PC.in_call_value? + OP_GET_ELEMENT_OR_OPERATOR// possibly ^if [search for operator] + :OP_GET_ELEMENT_OR_JUNCTION_EXPAND // possibly $junction [if junction, expand it] + ); + P($$, diving_code); } /* diving code; stack: current context */ @@ -540,6 +548,8 @@ 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) } @@ -645,7 +655,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; @@ -713,7 +723,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) { @@ -752,7 +762,7 @@ default: break; // #COMMENT - case LS_COMMENT: + case LS_USER_COMMENT: if(c=='\n') { // skip comment begin=PC.source; @@ -850,6 +860,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; @@ -878,7 +897,6 @@ default: case '~': case ';': RC; - //case '#': // comment start case '&': case '|': if(*PC.source==c) { // && || result=c=='&'?LAND:LOR; @@ -902,17 +920,36 @@ default: goto break2; } RC; - case '<': case '>': case '=': - if(*PC.source=='=') { // <= >= == - skip_analized=1; - switch(c) { - case '<': result=NLE; break; - case '>': result=NGE; break; - case '=': result=NEQ; break; - } - } else - result=c; + + 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; @@ -975,6 +1012,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: @@ -1238,7 +1293,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*/); }