Add startless range (another part of #5085)

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