Today I succeeded to add a new syntax "Pre Incremental Operator"
like C's ++i
into Ruby. The following code can run as you
expect.
There are two possible ways what does ++i
mean.
Call
succ
and assign the resulti = i.succ
Call
+
with 1 and assign the resulti = i.+(1)
I chose the former this time.
Patch
diff --git a/parse.y b/parse.y
index 10ac878..e02a1b1 100644
--- a/parse.y
+++ b/parse.y
@@ -685,6 +685,7 @@ static void token_info_pop(struct parser_params*, const char *token);
%type <val> program reswords then do dot_or_colon
%*/
%token tUPLUS /* unary+ */
+%token tINCR /* ++var */
%token tUMINUS /* unary- */
%token tPOW /* ** */
%token tCMP /* <=> */
@@ -1783,6 +1784,7 @@ op : '|' { ifndef_ripper($$ = '|'); }
'!' { ifndef_ripper($$ = '!'); }
'~' { ifndef_ripper($$ = '~'); }
tUPLUS { ifndef_ripper($$ = tUPLUS); }
+ | tINCR { ifndef_ripper($$ = tINCR); }
tUMINUS { ifndef_ripper($$ = tUMINUS); }
tAREF { ifndef_ripper($$ = tAREF); }
tASET { ifndef_ripper($$ = tASET); }
@@ -4130,6 +4132,15 @@ var_ref : variable
$$ = dispatch1(var_ref, $1);
%*/
}
+ | tINCR variable
+ {
+ /*%%%*/
+ $$ = assignable($2, 0);
+ $$->nd_value = NEW_CALL(gettable($$->nd_vid), rb_intern("succ"), 0);
+ /*%
+ $$ = dispatch2(unary, ripper_intern("++@"), $2);
+ %*/
+ }
;
var_lhs : variable
@@ -6773,6 +6784,9 @@ parser_yylex(struct parser_params *parser)
case '+':
c = nextc();
+ if (c == '+') {
+ return tINCR;
+ }
if (lex_state == EXPR_FNAME || lex_state == EXPR_DOT) {
lex_state = EXPR_ARG;
if (c == '@') {
@@ -8277,6 +8291,7 @@ void_expr_gen(struct parser_params *parser, NODE *node)
case '%':
case tPOW:
case tUPLUS:
+ case tINCR:
case tUMINUS:
case '|':
case '^':
@@ -9111,6 +9126,7 @@ static const struct {
{'-', "-(binary)"},
{tPOW, "**"},
{tUPLUS, "+@"},
+ {tINCR, "++@"},
{tUMINUS, "-@"},
{tCMP, "<=>"},
{tGEQ, ">="},
Post Incremental Operator
I tried to add post incremental operator like C's i++
, but I
found that I couldn't.
There are two possible ways what does i++
mean.
Store the original value, assign the result of
succ
, and return the original valuetmp = i; i = i.succ; tmp
Assign the result of
+
with 1, and return the result of-
with 1(i = i.+(1)) - 1
The latter is easier to implement, because there's no storing a value.
No comments:
Post a Comment