adjust lineno after continuing script files using mrb_partial_hook; close #1652

parent cff4ac6b
...@@ -3335,13 +3335,9 @@ nextc(parser_state *p) ...@@ -3335,13 +3335,9 @@ nextc(parser_state *p)
eof: eof:
if (!p->cxt) return -1; if (!p->cxt) return -1;
else { else {
mrbc_context *cxt = p->cxt; if (p->cxt->partial_hook(p) < 0)
return -1;
if (cxt->partial_hook(p) < 0) return -1; return -2;
c = '\n';
p->lineno = 1;
p->cxt = cxt;
return c;
} }
} }
...@@ -3560,7 +3556,7 @@ read_escape(parser_state *p) ...@@ -3560,7 +3556,7 @@ read_escape(parser_state *p)
buf[0] = c; buf[0] = c;
for (i=1; i<3; i++) { for (i=1; i<3; i++) {
buf[i] = nextc(p); buf[i] = nextc(p);
if (buf[i] == -1) goto eof; if (buf[i] < 0) goto eof;
if (buf[i] < '0' || '7' < buf[i]) { if (buf[i] < '0' || '7' < buf[i]) {
pushback(p, buf[i]); pushback(p, buf[i]);
break; break;
...@@ -3577,7 +3573,7 @@ read_escape(parser_state *p) ...@@ -3577,7 +3573,7 @@ read_escape(parser_state *p)
for (i=0; i<2; i++) { for (i=0; i<2; i++) {
buf[i] = nextc(p); buf[i] = nextc(p);
if (buf[i] == -1) goto eof; if (buf[i] < 0) goto eof;
if (!ISXDIGIT(buf[i])) { if (!ISXDIGIT(buf[i])) {
pushback(p, buf[i]); pushback(p, buf[i]);
break; break;
...@@ -3606,7 +3602,7 @@ read_escape(parser_state *p) ...@@ -3606,7 +3602,7 @@ read_escape(parser_state *p)
if ((c = nextc(p)) == '\\') { if ((c = nextc(p)) == '\\') {
return read_escape(p) | 0x80; return read_escape(p) | 0x80;
} }
else if (c == -1) goto eof; else if (c < 0) goto eof;
else { else {
return ((c & 0xff) | 0x80); return ((c & 0xff) | 0x80);
} }
...@@ -3623,11 +3619,12 @@ read_escape(parser_state *p) ...@@ -3623,11 +3619,12 @@ read_escape(parser_state *p)
} }
else if (c == '?') else if (c == '?')
return 0177; return 0177;
else if (c == -1) goto eof; else if (c < 0) goto eof;
return c & 0x9f; return c & 0x9f;
eof: eof:
case -1: case -1:
case -2:
yyerror(p, "Invalid escape character syntax"); yyerror(p, "Invalid escape character syntax");
return '\0'; return '\0';
...@@ -3649,7 +3646,7 @@ parse_string(parser_state *p) ...@@ -3649,7 +3646,7 @@ parse_string(parser_state *p)
newtok(p); newtok(p);
while ((c = nextc(p)) != end || nest_level != 0) { while ((c = nextc(p)) != end || nest_level != 0) {
if (hinf && (c == '\n' || c == -1)) { if (hinf && (c == '\n' || c < 0)) {
int line_head; int line_head;
tokadd(p, '\n'); tokadd(p, '\n');
tokfix(p); tokfix(p);
...@@ -3671,7 +3668,7 @@ parse_string(parser_state *p) ...@@ -3671,7 +3668,7 @@ parse_string(parser_state *p)
return tHEREDOC_END; return tHEREDOC_END;
} }
} }
if (c == -1) { if (c < 0) {
char buf[256]; char buf[256];
snprintf(buf, sizeof(buf), "can't find heredoc delimiter \"%s\" anywhere before EOF", hinf->term); snprintf(buf, sizeof(buf), "can't find heredoc delimiter \"%s\" anywhere before EOF", hinf->term);
yyerror(p, buf); yyerror(p, buf);
...@@ -3680,7 +3677,7 @@ parse_string(parser_state *p) ...@@ -3680,7 +3677,7 @@ parse_string(parser_state *p)
yylval.nd = new_str(p, tok(p), toklen(p)); yylval.nd = new_str(p, tok(p), toklen(p));
return tHD_STRING_MID; return tHD_STRING_MID;
} }
if (c == -1) { if (c < 0) {
yyerror(p, "unterminated string meets end of file"); yyerror(p, "unterminated string meets end of file");
return 0; return 0;
} }
...@@ -3706,7 +3703,7 @@ parse_string(parser_state *p) ...@@ -3706,7 +3703,7 @@ parse_string(parser_state *p)
else { else {
if (type & STR_FUNC_REGEXP) { if (type & STR_FUNC_REGEXP) {
tokadd(p, '\\'); tokadd(p, '\\');
if (c != -1) if (c >= 0)
tokadd(p, c); tokadd(p, c);
} else { } else {
pushback(p, c); pushback(p, c);
...@@ -3796,7 +3793,7 @@ parse_string(parser_state *p) ...@@ -3796,7 +3793,7 @@ parse_string(parser_state *p)
char *dup; char *dup;
newtok(p); newtok(p);
while (c = nextc(p), c != -1 && ISALPHA(c)) { while (c = nextc(p), c >= 0 && ISALPHA(c)) {
switch (c) { switch (c) {
case 'i': f |= 1; break; case 'i': f |= 1; break;
case 'x': f |= 2; break; case 'x': f |= 2; break;
...@@ -3855,19 +3852,19 @@ heredoc_identifier(parser_state *p) ...@@ -3855,19 +3852,19 @@ heredoc_identifier(parser_state *p)
if (c == '\'') if (c == '\'')
quote = TRUE; quote = TRUE;
newtok(p); newtok(p);
while ((c = nextc(p)) != -1 && c != term) { while ((c = nextc(p)) >= 0 && c != term) {
if (c == '\n') { if (c == '\n') {
c = -1; c = -1;
break; break;
} }
tokadd(p, c); tokadd(p, c);
} }
if (c == -1) { if (c < 0) {
yyerror(p, "unterminated here document identifier"); yyerror(p, "unterminated here document identifier");
return 0; return 0;
} }
} else { } else {
if (c == -1) { if (c < 0) {
return 0; /* missing here document identifier */ return 0; /* missing here document identifier */
} }
if (! identchar(c)) { if (! identchar(c)) {
...@@ -3878,7 +3875,7 @@ heredoc_identifier(parser_state *p) ...@@ -3878,7 +3875,7 @@ heredoc_identifier(parser_state *p)
newtok(p); newtok(p);
do { do {
tokadd(p, c); tokadd(p, c);
} while ((c = nextc(p)) != -1 && identchar(c)); } while ((c = nextc(p)) >= 0 && identchar(c));
pushback(p, c); pushback(p, c);
} }
tokfix(p); tokfix(p);
...@@ -3948,6 +3945,7 @@ parser_yylex(parser_state *p) ...@@ -3948,6 +3945,7 @@ parser_yylex(parser_state *p)
case '#': /* it's a comment */ case '#': /* it's a comment */
skip(p, '\n'); skip(p, '\n');
/* fall through */ /* fall through */
case -2: /* end of partial script. */
case '\n': case '\n':
maybe_heredoc: maybe_heredoc:
heredoc_treat_nextline(p); heredoc_treat_nextline(p);
...@@ -3982,6 +3980,7 @@ parser_yylex(parser_state *p) ...@@ -3982,6 +3980,7 @@ parser_yylex(parser_state *p)
goto retry; goto retry;
} }
case -1: /* EOF */ case -1: /* EOF */
case -2: /* end of partial script */
goto normal_newline; goto normal_newline;
default: default:
pushback(p, c); pushback(p, c);
...@@ -4165,7 +4164,7 @@ parser_yylex(parser_state *p) ...@@ -4165,7 +4164,7 @@ parser_yylex(parser_state *p)
return '?'; return '?';
} }
c = nextc(p); c = nextc(p);
if (c == -1) { if (c < 0) {
yyerror(p, "incomplete character syntax"); yyerror(p, "incomplete character syntax");
return 0; return 0;
} }
...@@ -4313,7 +4312,7 @@ parser_yylex(parser_state *p) ...@@ -4313,7 +4312,7 @@ parser_yylex(parser_state *p)
if (IS_BEG() || (IS_SPCARG(c) && arg_ambiguous(p))) { if (IS_BEG() || (IS_SPCARG(c) && arg_ambiguous(p))) {
p->lstate = EXPR_BEG; p->lstate = EXPR_BEG;
pushback(p, c); pushback(p, c);
if (c != -1 && ISDIGIT(c)) { if (c >= 0 && ISDIGIT(c)) {
c = '+'; c = '+';
goto start_num; goto start_num;
} }
...@@ -4345,7 +4344,7 @@ parser_yylex(parser_state *p) ...@@ -4345,7 +4344,7 @@ parser_yylex(parser_state *p)
if (IS_BEG() || (IS_SPCARG(c) && arg_ambiguous(p))) { if (IS_BEG() || (IS_SPCARG(c) && arg_ambiguous(p))) {
p->lstate = EXPR_BEG; p->lstate = EXPR_BEG;
pushback(p, c); pushback(p, c);
if (c != -1 && ISDIGIT(c)) { if (c >= 0 && ISDIGIT(c)) {
return tUMINUS_NUM; return tUMINUS_NUM;
} }
return tUMINUS; return tUMINUS;
...@@ -4364,7 +4363,7 @@ parser_yylex(parser_state *p) ...@@ -4364,7 +4363,7 @@ parser_yylex(parser_state *p)
return tDOT2; return tDOT2;
} }
pushback(p, c); pushback(p, c);
if (c != -1 && ISDIGIT(c)) { if (c >= 0 && ISDIGIT(c)) {
yyerror(p, "no .<digit> floating literal anymore; put 0 before dot"); yyerror(p, "no .<digit> floating literal anymore; put 0 before dot");
} }
p->lstate = EXPR_DOT; p->lstate = EXPR_DOT;
...@@ -4390,7 +4389,7 @@ parser_yylex(parser_state *p) ...@@ -4390,7 +4389,7 @@ parser_yylex(parser_state *p)
if (c == 'x' || c == 'X') { if (c == 'x' || c == 'X') {
/* hexadecimal */ /* hexadecimal */
c = nextc(p); c = nextc(p);
if (c != -1 && ISXDIGIT(c)) { if (c >= 0 && ISXDIGIT(c)) {
do { do {
if (c == '_') { if (c == '_') {
if (nondigit) break; if (nondigit) break;
...@@ -4400,7 +4399,7 @@ parser_yylex(parser_state *p) ...@@ -4400,7 +4399,7 @@ parser_yylex(parser_state *p)
if (!ISXDIGIT(c)) break; if (!ISXDIGIT(c)) break;
nondigit = 0; nondigit = 0;
tokadd(p, tolower(c)); tokadd(p, tolower(c));
} while ((c = nextc(p)) != -1); } while ((c = nextc(p)) >= 0);
} }
pushback(p, c); pushback(p, c);
tokfix(p); tokfix(p);
...@@ -4424,7 +4423,7 @@ parser_yylex(parser_state *p) ...@@ -4424,7 +4423,7 @@ parser_yylex(parser_state *p)
if (c != '0' && c != '1') break; if (c != '0' && c != '1') break;
nondigit = 0; nondigit = 0;
tokadd(p, c); tokadd(p, c);
} while ((c = nextc(p)) != -1); } while ((c = nextc(p)) >= 0);
} }
pushback(p, c); pushback(p, c);
tokfix(p); tokfix(p);
...@@ -4438,7 +4437,7 @@ parser_yylex(parser_state *p) ...@@ -4438,7 +4437,7 @@ parser_yylex(parser_state *p)
if (c == 'd' || c == 'D') { if (c == 'd' || c == 'D') {
/* decimal */ /* decimal */
c = nextc(p); c = nextc(p);
if (c != -1 && ISDIGIT(c)) { if (c >= 0 && ISDIGIT(c)) {
do { do {
if (c == '_') { if (c == '_') {
if (nondigit) break; if (nondigit) break;
...@@ -4448,7 +4447,7 @@ parser_yylex(parser_state *p) ...@@ -4448,7 +4447,7 @@ parser_yylex(parser_state *p)
if (!ISDIGIT(c)) break; if (!ISDIGIT(c)) break;
nondigit = 0; nondigit = 0;
tokadd(p, c); tokadd(p, c);
} while ((c = nextc(p)) != -1); } while ((c = nextc(p)) >= 0);
} }
pushback(p, c); pushback(p, c);
tokfix(p); tokfix(p);
...@@ -4466,7 +4465,7 @@ parser_yylex(parser_state *p) ...@@ -4466,7 +4465,7 @@ parser_yylex(parser_state *p)
if (c == 'o' || c == 'O') { if (c == 'o' || c == 'O') {
/* prefixed octal */ /* prefixed octal */
c = nextc(p); c = nextc(p);
if (c == -1 || c == '_' || !ISDIGIT(c)) { if (c < 0 || c == '_' || !ISDIGIT(c)) {
no_digits(); no_digits();
} }
} }
...@@ -4483,7 +4482,7 @@ parser_yylex(parser_state *p) ...@@ -4483,7 +4482,7 @@ parser_yylex(parser_state *p)
if (c > '7') goto invalid_octal; if (c > '7') goto invalid_octal;
nondigit = 0; nondigit = 0;
tokadd(p, c); tokadd(p, c);
} while ((c = nextc(p)) != -1); } while ((c = nextc(p)) >= 0);
if (toklen(p) > start) { if (toklen(p) > start) {
pushback(p, c); pushback(p, c);
...@@ -4526,7 +4525,7 @@ parser_yylex(parser_state *p) ...@@ -4526,7 +4525,7 @@ parser_yylex(parser_state *p)
} }
else { else {
int c0 = nextc(p); int c0 = nextc(p);
if (c0 == -1 || !ISDIGIT(c0)) { if (c0 < 0 || !ISDIGIT(c0)) {
pushback(p, c0); pushback(p, c0);
goto decode_num; goto decode_num;
} }
...@@ -4760,7 +4759,7 @@ parser_yylex(parser_state *p) ...@@ -4760,7 +4759,7 @@ parser_yylex(parser_state *p)
c = nextc(p); c = nextc(p);
quotation: quotation:
if (c == -1 || !ISALNUM(c)) { if (c < 0 || !ISALNUM(c)) {
term = c; term = c;
c = 'Q'; c = 'Q';
} }
...@@ -4771,7 +4770,7 @@ parser_yylex(parser_state *p) ...@@ -4771,7 +4770,7 @@ parser_yylex(parser_state *p)
return 0; return 0;
} }
} }
if (c == -1 || term == -1) { if (c < 0 || term < 0) {
yyerror(p, "unterminated quoted string meets end of file"); yyerror(p, "unterminated quoted string meets end of file");
return 0; return 0;
} }
...@@ -4844,14 +4843,14 @@ parser_yylex(parser_state *p) ...@@ -4844,14 +4843,14 @@ parser_yylex(parser_state *p)
p->lstate = EXPR_END; p->lstate = EXPR_END;
token_column = newtok(p); token_column = newtok(p);
c = nextc(p); c = nextc(p);
if (c == -1) { if (c < 0) {
yyerror(p, "incomplete global variable syntax"); yyerror(p, "incomplete global variable syntax");
return 0; return 0;
} }
switch (c) { switch (c) {
case '_': /* $_: last read line string */ case '_': /* $_: last read line string */
c = nextc(p); c = nextc(p);
if (c != -1 && identchar(c)) { /* if there is more after _ it is a variable */ if (c >= 0 && identchar(c)) { /* if there is more after _ it is a variable */
tokadd(p, '$'); tokadd(p, '$');
tokadd(p, c); tokadd(p, c);
break; break;
...@@ -4909,7 +4908,7 @@ parser_yylex(parser_state *p) ...@@ -4909,7 +4908,7 @@ parser_yylex(parser_state *p)
do { do {
tokadd(p, c); tokadd(p, c);
c = nextc(p); c = nextc(p);
} while (c != -1 && isdigit(c)); } while (c >= 0 && isdigit(c));
pushback(p, c); pushback(p, c);
if (last_state == EXPR_FNAME) goto gvar; if (last_state == EXPR_FNAME) goto gvar;
tokfix(p); tokfix(p);
...@@ -4934,7 +4933,7 @@ parser_yylex(parser_state *p) ...@@ -4934,7 +4933,7 @@ parser_yylex(parser_state *p)
tokadd(p, '@'); tokadd(p, '@');
c = nextc(p); c = nextc(p);
} }
if (c == -1) { if (c < 0) {
if (p->bidx == 1) { if (p->bidx == 1) {
yyerror(p, "incomplete instance variable syntax"); yyerror(p, "incomplete instance variable syntax");
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment