Skip to content

Commit

Permalink
Fixes to inc/dec ops with member exp operands.
Browse files Browse the repository at this point in the history
  • Loading branch information
ndreynolds committed Nov 21, 2012
1 parent 63a41af commit cb2ca4a
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 18 deletions.
34 changes: 23 additions & 11 deletions src/eval.c
Original file line number Diff line number Diff line change
Expand Up @@ -292,13 +292,8 @@ fh_assign(js_val *ctx, ast_node *node)

if (node->e1->type == NODE_MEMBER) {
js_val *old_ctx = ctx;

ast_node *member = node->e1;
ctx = member->e2->type == NODE_MEMBER ?
fh_member(ctx, member->e2) :
fh_get_rec(ctx, fh_str_from_node(ctx, member->e2)->string.ptr);

key = fh_str_from_node(old_ctx, member->e1)->string.ptr;
ctx = fh_member_parent(old_ctx, node->e1);
key = fh_member_child(old_ctx, node->e1)->string.ptr;

// Set the array length.
if (IS_ARR(ctx)) {
Expand Down Expand Up @@ -629,11 +624,11 @@ fh_postfix_exp(js_val *ctx, ast_node *node)
js_val *old_val = TO_NUM(fh_eval(ctx, node->e1));
char *op = node->sval;
if (STREQ(op, "++")) {
fh_set_rec(ctx, node->e1->sval, fh_add(old_val, JSNUM(1)));
fh_put(ctx, node->e1, fh_add(old_val, JSNUM(1)));
return old_val;
}
if (STREQ(op, "--")) {
fh_set_rec(ctx, node->e1->sval, fh_sub(old_val, JSNUM(1)));
fh_put(ctx, node->e1, fh_sub(old_val, JSNUM(1)));
return old_val;
}
UNREACHABLE();
Expand Down Expand Up @@ -670,14 +665,15 @@ fh_prefix_exp(js_val *ctx, ast_node *node)
js_val *new_val;

// Increment and decrement.
// TODO: these need to throw a syntax error for strict references
if (STREQ(op, "++")) {
new_val = fh_add(old_val, JSNUM(1));
fh_set_rec(ctx, node->e1->sval, new_val);
fh_put(ctx, node->e1, new_val);
return new_val;
}
if (STREQ(op, "--")) {
new_val = fh_sub(old_val, JSNUM(1));
fh_set_rec(ctx, node->e1->sval, new_val);
fh_put(ctx, node->e1, new_val);
return new_val;
}

Expand Down Expand Up @@ -989,6 +985,22 @@ fh_or(js_val *ctx, ast_node *a, ast_node *b)
// Utilities
// ----------------------------------------------------------------------------

void
fh_put(js_val *ctx, ast_node *ref, js_val *val)
{
char *key;
if (ref->type == NODE_MEMBER) {
ctx = fh_member_parent(ctx, ref);
key = fh_member_child(ctx, ref)->string.ptr;
}
else if (ref->sval)
key = ref->sval;
else
return;

fh_set_rec(ctx, key, val);
}

js_val *
fh_str_from_node(js_val *ctx, ast_node *node)
{
Expand Down
1 change: 1 addition & 0 deletions src/eval.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ void fh_forin(js_val *, ast_node *);
void fh_do_assign(js_val *, char *, js_val *, char *);
void fh_func_dec_scan(js_val *, ast_node *);
void fh_var_dec_scan(js_val *, ast_node *);
void fh_put(js_val *, ast_node *, js_val *);

js_args * fh_build_args(js_val *, ast_node *);
js_val * fh_break(void);
Expand Down
2 changes: 1 addition & 1 deletion test/runner.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
//
// e.g. -x node
//
// -a / --args A template in which the string "[test]" will be interploated
// -a / --args A template in which the string "[test]" will be interpolated
// with the path to each test script and given as argument to
// the executable.
//
Expand Down
42 changes: 36 additions & 6 deletions test/test_operators.js
Original file line number Diff line number Diff line change
Expand Up @@ -93,15 +93,21 @@ test('unary prefix operators', function() {
test('unary postfix', function() {

test('increment', function() {
var c = 0;
assert(c++ === 0);
assert(c === 1);
var x = 0;
var obj = {x: 0};
assertEquals(0, x++);
assertEquals(1, x);
assertEquals(0, obj.x++);
assertEquals(1, obj.x);
});

test('decrement', function() {
var d = 2;
assert(d-- === 2);
assert(d === 1);
var x = 2;
var obj = {x: 5};
assertEquals(2, x--);
assertEquals(1, x);
assertEquals(5, obj.x--);
assertEquals(4, obj.x);
});

});
Expand Down Expand Up @@ -248,3 +254,27 @@ test('binary', function() {
});

});


// ------------------------------------------------------------------
// TRICKS
// ------------------------------------------------------------------

test('non alphanumeric js', function() {
assertEquals('10', ++[[]][+[]]+[+[]]);
assertEquals(true, !![]);
assertEquals(false, ![]);
assertEquals(undefined, [][+[]]);
assertEquals('[object Object]', {}+[]);

assertEquals(0, +[]);
assertEquals(1, +!![]);
assertEquals(2, !+[]+!![]);
assertEquals(3, !+[]+!![]+!![]);
assertEquals(4, !+[]+!![]+!![]+!![]);
assertEquals(5, !+[]+!![]+!![]+!![]+!![]);
assertEquals(6, !+[]+!![]+!![]+!![]+!![]+!![]);
assertEquals(7, !+[]+!![]+!![]+!![]+!![]+!![]+!![]);
assertEquals(8, !+[]+!![]+!![]+!![]+!![]+!![]+!![]+!![]);
assertEquals(9, !+[]+!![]+!![]+!![]+!![]+!![]+!![]+!![]+!![]);
});

0 comments on commit cb2ca4a

Please sign in to comment.