Add startless range (another part of #5085)

Ref #5093; close #5085
parent 8d36393a
...@@ -1478,6 +1478,7 @@ heredoc_end(parser_state *p) ...@@ -1478,6 +1478,7 @@ heredoc_end(parser_state *p)
%token tANDOP tOROP /* && and || */ %token tANDOP tOROP /* && and || */
%token tMATCH tNMATCH /* =~ and !~ */ %token tMATCH tNMATCH /* =~ and !~ */
%token tDOT2 tDOT3 /* .. and ... */ %token tDOT2 tDOT3 /* .. and ... */
%token tBDOT2 tBDOT3 /* (.. and (... */
%token tAREF tASET /* [] and []= */ %token tAREF tASET /* [] and []= */
%token tLSHFT tRSHFT /* << and >> */ %token tLSHFT tRSHFT /* << and >> */
%token tCOLON2 /* :: */ %token tCOLON2 /* :: */
...@@ -1514,7 +1515,7 @@ heredoc_end(parser_state *p) ...@@ -1514,7 +1515,7 @@ heredoc_end(parser_state *p)
%right '=' tOP_ASGN %right '=' tOP_ASGN
%left modifier_rescue %left modifier_rescue
%right '?' ':' tLABEL_TAG %right '?' ':' tLABEL_TAG
%nonassoc tDOT2 tDOT3 %nonassoc tDOT2 tDOT3 tBDOT2 tBDOT3
%left tOROP %left tOROP
%left tANDOP %left tANDOP
%nonassoc tCMP tEQ tEQQ tNEQ tMATCH tNMATCH %nonassoc tCMP tEQ tEQQ tNEQ tMATCH tNMATCH
...@@ -2194,6 +2195,10 @@ arg : lhs '=' arg_rhs ...@@ -2194,6 +2195,10 @@ arg : lhs '=' arg_rhs
{ {
$$ = new_dot2(p, $1, new_nil(p)); $$ = new_dot2(p, $1, new_nil(p));
} }
| tBDOT2 arg
{
$$ = new_dot2(p, new_nil(p), $2);
}
| arg tDOT3 arg | arg tDOT3 arg
{ {
$$ = new_dot3(p, $1, $3); $$ = new_dot3(p, $1, $3);
...@@ -2202,6 +2207,10 @@ arg : lhs '=' arg_rhs ...@@ -2202,6 +2207,10 @@ arg : lhs '=' arg_rhs
{ {
$$ = new_dot3(p, $1, new_nil(p)); $$ = new_dot3(p, $1, new_nil(p));
} }
| tBDOT3 arg
{
$$ = new_dot3(p, new_nil(p), $2);
}
| arg '+' arg | arg '+' arg
{ {
$$ = call_bin_op(p, $1, "+", $3); $$ = call_bin_op(p, $1, "+", $3);
...@@ -5440,13 +5449,15 @@ parser_yylex(parser_state *p) ...@@ -5440,13 +5449,15 @@ parser_yylex(parser_state *p)
return '-'; return '-';
case '.': case '.':
{
int is_beg = IS_BEG();
p->lstate = EXPR_BEG; p->lstate = EXPR_BEG;
if ((c = nextc(p)) == '.') { if ((c = nextc(p)) == '.') {
if ((c = nextc(p)) == '.') { if ((c = nextc(p)) == '.') {
return tDOT3; return is_beg ? tBDOT3 : tDOT3;
} }
pushback(p, c); pushback(p, c);
return tDOT2; return is_beg ? tBDOT2 : tDOT2;
} }
pushback(p, c); pushback(p, c);
if (c >= 0 && ISDIGIT(c)) { if (c >= 0 && ISDIGIT(c)) {
...@@ -5454,6 +5465,7 @@ parser_yylex(parser_state *p) ...@@ -5454,6 +5465,7 @@ parser_yylex(parser_state *p)
} }
p->lstate = EXPR_DOT; p->lstate = EXPR_DOT;
return '.'; return '.';
}
start_num: start_num:
case '0': case '1': case '2': case '3': case '4': case '0': case '1': case '2': case '3': case '4':
......
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -32,7 +32,7 @@ r_check(mrb_state *mrb, mrb_value a, mrb_value b) ...@@ -32,7 +32,7 @@ r_check(mrb_state *mrb, mrb_value a, mrb_value b)
return; return;
} }
if (mrb_nil_p(b)) return; if (mrb_nil_p(a) || mrb_nil_p(b)) return;
n = mrb_cmp(mrb, a, b); n = mrb_cmp(mrb, a, b);
if (n == -2) { /* can not be compared */ if (n == -2) { /* can not be compared */
...@@ -217,7 +217,13 @@ range_include(mrb_state *mrb, mrb_value range) ...@@ -217,7 +217,13 @@ range_include(mrb_state *mrb, mrb_value range)
beg = RANGE_BEG(r); beg = RANGE_BEG(r);
end = RANGE_END(r); end = RANGE_END(r);
if (r_le(mrb, beg, val)) { /* beg <= val */ if (mrb_nil_p(beg)) {
if (RANGE_EXCL(r) ? r_gt(mrb, end, val) /* end > val */
: r_ge(mrb, end, val)) { /* end >= val */
return mrb_true_value();
}
}
else if (r_le(mrb, beg, val)) { /* beg <= val */
if (mrb_nil_p(end)) { if (mrb_nil_p(end)) {
return mrb_true_value(); return mrb_true_value();
} }
...@@ -266,9 +272,14 @@ range_inspect(mrb_state *mrb, mrb_value range) ...@@ -266,9 +272,14 @@ range_inspect(mrb_state *mrb, mrb_value range)
mrb_value str; mrb_value str;
struct RRange *r = mrb_range_ptr(mrb, range); struct RRange *r = mrb_range_ptr(mrb, range);
if (!mrb_nil_p(RANGE_BEG(r))) {
str = mrb_inspect(mrb, RANGE_BEG(r)); str = mrb_inspect(mrb, RANGE_BEG(r));
str = mrb_str_dup(mrb, str); str = mrb_str_dup(mrb, str);
mrb_str_cat(mrb, str, "...", RANGE_EXCL(r) ? 3 : 2); mrb_str_cat(mrb, str, "...", RANGE_EXCL(r) ? 3 : 2);
}
else {
str = mrb_str_new(mrb, "...", RANGE_EXCL(r) ? 3 : 2);
}
if (!mrb_nil_p(RANGE_END(r))) { if (!mrb_nil_p(RANGE_END(r))) {
mrb_value str2 = mrb_inspect(mrb, RANGE_END(r)); mrb_value str2 = mrb_inspect(mrb, RANGE_END(r));
mrb_str_cat_str(mrb, str, str2); mrb_str_cat_str(mrb, str, str2);
......
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