Add update operators (+=, -=, *=, /= and //=)

This commit is contained in:
Stephen Dolan committed 2012-09-11 23:55:59 +01:00
1 parent f6c6ba95ad
commit df195b3187
3 files changed
+55 -8

No files matched your search

+6 -1
View File
@@ -22,7 +22,6 @@
"==" { return EQ; }
"as" { return AS; }
"def" { return DEF; }
"|=" { return SETPIPE; }
"if" { return IF; }
"then" { return THEN; }
"else" { return ELSE; }
@@ -32,6 +31,12 @@
"not" { return NOT; }
"end" { return END; }
"//" { return DEFINEDOR; }
"|=" { return SETPIPE; }
"+=" { return SETPLUS; }
"-=" { return SETMINUS; }
"*=" { return SETMULT; }
"/=" { return SETDIV; }
"//=" { return SETDEFINEDOR; }
"."|"="|";"|"["|"]"|","|":"|"("|")"|"{"|"}"|"|"|"+"|"-"|"*"|"/"|"\$" { return yytext[0];}
\"(\\.|[^\\\"])*\" |
+38 -7
View File
@@ -46,7 +46,6 @@
%token DEFINEDOR "//"
%token AS "as"
%token DEF "def"
%token SETPIPE "|="
%token IF "if"
%token THEN "then"
%token ELSE "else"
@@ -55,14 +54,19 @@
%token AND "and"
%token OR "or"
%token NOT "not"
%token SETPIPE "|="
%token SETPLUS "+="
%token SETMINUS "-="
%token SETMULT "*="
%token SETDIV "/="
%token SETDEFINEDOR "//="
/* revolting hack */
%left ';'
%left '|'
%left ','
%right "//"
%nonassoc '=' SETPIPE
%nonassoc '=' SETPIPE SETPLUS SETMINUS SETMULT SETDIV SETDEFINEDOR
%nonassoc EQ
%left OR
%left AND
@@ -138,6 +142,16 @@ static block gen_binop(block a, block b, int op) {
return c;
}
static block gen_update(block a, block op, int optype) {
block assign = a;
block_append(&assign, gen_op_simple(DUP));
if (optype) {
op = gen_binop(gen_noop(), op, optype);
}
block_append(&assign, op);
return gen_assign(assign);
}
%}
%%
@@ -198,11 +212,12 @@ Exp "//" Exp {
$$ = gen_definedor($1, $3);
} |
Exp "//=" Exp {
$$ = gen_update($1, gen_definedor(gen_noop(), $3), 0);
} |
Exp "|=" Exp {
block assign = $1;
block_append(&assign, gen_op_simple(DUP));
block_append(&assign, $3);
$$ = gen_assign(assign);
$$ = gen_update($1, $3, 0);
} |
Exp '|' Exp {
@@ -217,18 +232,34 @@ Exp '+' Exp {
$$ = gen_binop($1, $3, '+');
} |
Exp "+=" Exp {
$$ = gen_update($1, $3, '+');
} |
Exp '-' Exp {
$$ = gen_binop($1, $3, '-');
} |
Exp "-=" Exp {
$$ = gen_update($1, $3, '-');
} |
Exp '*' Exp {
$$ = gen_binop($1, $3, '*');
} |
Exp "*=" Exp {
$$ = gen_update($1, $3, '*');
} |
Exp '/' Exp {
$$ = gen_binop($1, $3, '/');
} |
Exp "/=" Exp {
$$ = gen_update($1, $3, '/');
} |
Exp "==" Exp {
$$ = gen_binop($1, $3, EQ);
} |
+11
View File
@@ -270,6 +270,13 @@ def id(x):x; 2000 as $x | def f(x):1 as $x | id([$x, x, x]); def g(x): 100 as $x
{"foo": 42}
{"foo": 43}
.[] += 2, .[] *= 2, .[] -= 2, .[] /= 2
[1,3,5]
[3,5,7]
[2,6,10]
[-1,1,3]
[0.5, 1.5, 2.5]
.[0].a |= {"old":., "new":(.+1)}
[{"a":1,"b":2}]
[{"a":{"old":1, "new":2},"b":2}]
@@ -305,6 +312,10 @@ def inc(x): x |= .+1; inc(.[].a)
[{"foo":[1,2], "bar": 42}, {"foo":[1], "bar": null}, {"foo":[null,false,3], "bar": 18}, {"foo":[], "bar":42}, {"foo": [null,false,null], "bar": 41}]
[[1,2], [1], [3], [42], [41]]
.[] //= 42
["hello",true,false,[false],null]
["hello",true,42,[false],42]
.[] | [.[0] and .[1], .[0] or .[1]]
[[true,[]], [false,1], [42,null], [null,false]]
[true,true]