Refactored rb_strterm_heredoc_t
This commit is contained in:
parent
1432471a75
commit
c7f780c155
103
parse.y
103
parse.y
@ -604,15 +604,24 @@ typedef struct rb_strterm_literal_struct {
|
|||||||
} u3;
|
} u3;
|
||||||
} rb_strterm_literal_t;
|
} rb_strterm_literal_t;
|
||||||
|
|
||||||
|
#define HERETERM_LENGTH_BITS ((SIZEOF_VALUE - 1) * CHAR_BIT - 1)
|
||||||
|
|
||||||
struct rb_strterm_heredoc_struct {
|
struct rb_strterm_heredoc_struct {
|
||||||
SIGNED_VALUE sourceline; /* lineno of the line that contains `<<"END"` */
|
|
||||||
VALUE term; /* `"END"` of `<<"END"` */
|
|
||||||
VALUE lastline; /* the string of line that contains `<<"END"` */
|
VALUE lastline; /* the string of line that contains `<<"END"` */
|
||||||
union {
|
long offset; /* the column of END in `<<"END"` */
|
||||||
VALUE dummy;
|
int sourceline; /* lineno of the line that contains `<<"END"` */
|
||||||
long lastidx; /* the column of `<<"END"` */
|
unsigned length /* the length of END in `<<"END"` */
|
||||||
} u3;
|
#if HERETERM_LENGTH_BITS < SIZEOF_INT * CHAR_BIT
|
||||||
|
: HERETERM_LENGTH_BITS
|
||||||
|
#else
|
||||||
|
# undef HERETERM_LENGTH_BITS
|
||||||
|
# define HERETERM_LENGTH_BITS (SIZEOF_INT * CHAR_BIT)
|
||||||
|
#endif
|
||||||
|
;
|
||||||
|
unsigned quote: 1;
|
||||||
|
uint8_t func;
|
||||||
};
|
};
|
||||||
|
STATIC_ASSERT(rb_strterm_heredoc_t, sizeof(rb_strterm_heredoc_t) <= 4 * SIZEOF_VALUE);
|
||||||
|
|
||||||
#define STRTERM_HEREDOC IMEMO_FL_USER0
|
#define STRTERM_HEREDOC IMEMO_FL_USER0
|
||||||
|
|
||||||
@ -631,7 +640,6 @@ rb_strterm_mark(VALUE obj)
|
|||||||
rb_strterm_t *strterm = (rb_strterm_t*)obj;
|
rb_strterm_t *strterm = (rb_strterm_t*)obj;
|
||||||
if (RBASIC(obj)->flags & STRTERM_HEREDOC) {
|
if (RBASIC(obj)->flags & STRTERM_HEREDOC) {
|
||||||
rb_strterm_heredoc_t *heredoc = &strterm->u.heredoc;
|
rb_strterm_heredoc_t *heredoc = &strterm->u.heredoc;
|
||||||
rb_gc_mark(heredoc->term);
|
|
||||||
rb_gc_mark(heredoc->lastline);
|
rb_gc_mark(heredoc->lastline);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -6785,48 +6793,41 @@ heredoc_identifier(struct parser_params *p)
|
|||||||
* term_len is length of `<<"END"` except `END`,
|
* term_len is length of `<<"END"` except `END`,
|
||||||
* in this case term_len is 4 (<, <, " and ").
|
* in this case term_len is 4 (<, <, " and ").
|
||||||
*/
|
*/
|
||||||
int c = nextc(p), term, func = 0, term_len = 2;
|
long len, offset = p->lex.pcur - p->lex.pbeg;
|
||||||
|
int c = nextc(p), term, func = 0, quote = 0;
|
||||||
enum yytokentype token = tSTRING_BEG;
|
enum yytokentype token = tSTRING_BEG;
|
||||||
long len;
|
|
||||||
int indent = 0;
|
int indent = 0;
|
||||||
|
|
||||||
if (c == '-') {
|
if (c == '-') {
|
||||||
c = nextc(p);
|
c = nextc(p);
|
||||||
term_len++;
|
|
||||||
func = STR_FUNC_INDENT;
|
func = STR_FUNC_INDENT;
|
||||||
|
offset++;
|
||||||
}
|
}
|
||||||
else if (c == '~') {
|
else if (c == '~') {
|
||||||
c = nextc(p);
|
c = nextc(p);
|
||||||
term_len++;
|
|
||||||
func = STR_FUNC_INDENT;
|
func = STR_FUNC_INDENT;
|
||||||
|
offset++;
|
||||||
indent = INT_MAX;
|
indent = INT_MAX;
|
||||||
}
|
}
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case '\'':
|
case '\'':
|
||||||
term_len++;
|
|
||||||
func |= str_squote; goto quoted;
|
func |= str_squote; goto quoted;
|
||||||
case '"':
|
case '"':
|
||||||
term_len++;
|
|
||||||
func |= str_dquote; goto quoted;
|
func |= str_dquote; goto quoted;
|
||||||
case '`':
|
case '`':
|
||||||
term_len++;
|
|
||||||
token = tXSTRING_BEG;
|
token = tXSTRING_BEG;
|
||||||
func |= str_xquote; goto quoted;
|
func |= str_xquote; goto quoted;
|
||||||
|
|
||||||
quoted:
|
quoted:
|
||||||
term_len++;
|
quote++;
|
||||||
newtok(p);
|
offset++;
|
||||||
tokadd(p, term_len);
|
|
||||||
tokadd(p, func);
|
|
||||||
term = c;
|
term = c;
|
||||||
while ((c = nextc(p)) != -1 && c != term) {
|
len = 0;
|
||||||
if (c == '\r' || c == '\n') goto unterminated;
|
while ((c = nextc(p)) != term) {
|
||||||
if (tokadd_mbchar(p, c) == -1) return 0;
|
if (c == -1 || c == '\r' || c == '\n') {
|
||||||
}
|
yyerror(NULL, p, "unterminated here document identifier");
|
||||||
if (c == -1) {
|
return -1;
|
||||||
unterminated:
|
}
|
||||||
yyerror(NULL, p, "unterminated here document identifier");
|
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -6838,26 +6839,30 @@ heredoc_identifier(struct parser_params *p)
|
|||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
newtok(p);
|
func |= str_dquote;
|
||||||
tokadd(p, term_len);
|
|
||||||
tokadd(p, func |= str_dquote);
|
|
||||||
do {
|
do {
|
||||||
if (tokadd_mbchar(p, c) == -1) return 0;
|
int n = parser_precise_mbclen(p, p->lex.pcur-1);
|
||||||
|
if (n < 0) return 0;
|
||||||
|
p->lex.pcur += --n;
|
||||||
} while ((c = nextc(p)) != -1 && parser_is_identchar(p));
|
} while ((c = nextc(p)) != -1 && parser_is_identchar(p));
|
||||||
pushback(p, c);
|
pushback(p, c);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
tokfix(p);
|
len = p->lex.pcur - (p->lex.pbeg + offset) - quote;
|
||||||
|
if ((unsigned long)len >= 1LU << HERETERM_LENGTH_BITS)
|
||||||
|
yyerror(NULL, p, "too long here document identifier");
|
||||||
dispatch_scan_event(p, tHEREDOC_BEG);
|
dispatch_scan_event(p, tHEREDOC_BEG);
|
||||||
len = p->lex.pcur - p->lex.pbeg;
|
|
||||||
lex_goto_eol(p);
|
lex_goto_eol(p);
|
||||||
|
|
||||||
p->lex.strterm = new_strterm(STR_NEW(tok(p), toklen(p)), /* term */
|
p->lex.strterm = new_strterm(0, 0, 0, p->lex.lastline);
|
||||||
p->lex.lastline, /* lastline */
|
|
||||||
len, /* lastidx */
|
|
||||||
p->ruby_sourceline);
|
|
||||||
p->lex.strterm->flags |= STRTERM_HEREDOC;
|
p->lex.strterm->flags |= STRTERM_HEREDOC;
|
||||||
|
rb_strterm_heredoc_t *here = &p->lex.strterm->u.heredoc;
|
||||||
|
here->offset = offset;
|
||||||
|
here->sourceline = p->ruby_sourceline;
|
||||||
|
here->length = (int)len;
|
||||||
|
here->quote = quote;
|
||||||
|
here->func = func;
|
||||||
|
|
||||||
token_flush(p);
|
token_flush(p);
|
||||||
p->heredoc_indent = indent;
|
p->heredoc_indent = indent;
|
||||||
@ -6875,7 +6880,7 @@ heredoc_restore(struct parser_params *p, rb_strterm_heredoc_t *here)
|
|||||||
p->lex.lastline = line;
|
p->lex.lastline = line;
|
||||||
p->lex.pbeg = RSTRING_PTR(line);
|
p->lex.pbeg = RSTRING_PTR(line);
|
||||||
p->lex.pend = p->lex.pbeg + RSTRING_LEN(line);
|
p->lex.pend = p->lex.pbeg + RSTRING_LEN(line);
|
||||||
p->lex.pcur = p->lex.pbeg + here->u3.lastidx;
|
p->lex.pcur = p->lex.pbeg + here->offset + here->length + here->quote;
|
||||||
p->heredoc_end = p->ruby_sourceline;
|
p->heredoc_end = p->ruby_sourceline;
|
||||||
p->ruby_sourceline = (int)here->sourceline;
|
p->ruby_sourceline = (int)here->sourceline;
|
||||||
token_flush(p);
|
token_flush(p);
|
||||||
@ -7108,14 +7113,14 @@ here_document(struct parser_params *p, rb_strterm_heredoc_t *here)
|
|||||||
rb_encoding *enc = p->enc;
|
rb_encoding *enc = p->enc;
|
||||||
int bol;
|
int bol;
|
||||||
|
|
||||||
eos = RSTRING_PTR(here->term);
|
eos = RSTRING_PTR(here->lastline) + here->offset;
|
||||||
len = RSTRING_LEN(here->term) - 2; /* here->term includes term_len and func */
|
len = here->length;
|
||||||
eos++; /* skip term_len */
|
indent = (func = here->func) & STR_FUNC_INDENT;
|
||||||
indent = (func = *eos++) & STR_FUNC_INDENT;
|
|
||||||
|
|
||||||
if ((c = nextc(p)) == -1) {
|
if ((c = nextc(p)) == -1) {
|
||||||
error:
|
error:
|
||||||
compile_error(p, "can't find string \"%s\" anywhere before EOF", eos);
|
compile_error(p, "can't find string \"%.*s\" anywhere before EOF",
|
||||||
|
(int)len, eos);
|
||||||
#ifdef RIPPER
|
#ifdef RIPPER
|
||||||
if (!has_delayed_token(p)) {
|
if (!has_delayed_token(p)) {
|
||||||
dispatch_scan_event(p, tSTRING_CONTENT);
|
dispatch_scan_event(p, tSTRING_CONTENT);
|
||||||
@ -9931,13 +9936,15 @@ rb_parser_fatal(struct parser_params *p, const char *fmt, ...)
|
|||||||
YYLTYPE *
|
YYLTYPE *
|
||||||
rb_parser_set_location_from_strterm_heredoc(struct parser_params *p, rb_strterm_heredoc_t *here, YYLTYPE *yylloc)
|
rb_parser_set_location_from_strterm_heredoc(struct parser_params *p, rb_strterm_heredoc_t *here, YYLTYPE *yylloc)
|
||||||
{
|
{
|
||||||
const char *eos = RSTRING_PTR(here->term);
|
int sourceline = here->sourceline;
|
||||||
long term_len = RSTRING_LEN(here->term) - 2 + (unsigned char)eos[0];
|
int beg_pos = (int)here->offset - here->quote
|
||||||
|
- (rb_strlen_lit("<<-") - !(here->func & STR_FUNC_INDENT));
|
||||||
|
int end_pos = (int)here->offset + here->length + here->quote;
|
||||||
|
|
||||||
yylloc->beg_pos.lineno = (int)here->sourceline;
|
yylloc->beg_pos.lineno = sourceline;
|
||||||
yylloc->beg_pos.column = (int)(here->u3.lastidx - term_len);
|
yylloc->beg_pos.column = beg_pos;
|
||||||
yylloc->end_pos.lineno = (int)here->sourceline;
|
yylloc->end_pos.lineno = sourceline;
|
||||||
yylloc->end_pos.column = (int)(here->u3.lastidx);
|
yylloc->end_pos.column = end_pos;
|
||||||
return yylloc;
|
return yylloc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user