Skip to content

Commit

Permalink
Fixes from testing.
Browse files Browse the repository at this point in the history
- Object comparison with null
- Array bracket notation assignment
- Unreachable code being reached
  • Loading branch information
ndreynolds committed Oct 20, 2012
1 parent d00341a commit 64577cd
Show file tree
Hide file tree
Showing 8 changed files with 112 additions and 17 deletions.
22 changes: 19 additions & 3 deletions src/eval.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ fh_eval(JSValue *ctx, Node *node)
case NODE_REGEXP: return JSREGEXP(node->sval);
case NODE_NUM: return JSNUM(node->val);
case NODE_NULL: return JSNULL();
case NODE_FUNC: return JSFUNC(node);
case NODE_FUNC: return fh_func(ctx, node);
case NODE_OBJ: return fh_obj(ctx, node);
case NODE_ARR: return fh_arr(ctx, node);
case NODE_CALL: return fh_call(ctx, node);
Expand Down Expand Up @@ -117,9 +117,18 @@ fh_stmt_lst(JSValue *ctx, Node *node)


// ----------------------------------------------------------------------------
// Object & Array Literals
// Functions and Object & Array Literals
// ----------------------------------------------------------------------------

JSValue *
fh_func(JSValue *ctx, Node *node)
{
JSValue *func = JSFUNC(node);
// TODO: figure this out
// func->function.closure = ctx;
return func;
}

JSValue *
fh_obj(JSValue *ctx, Node *node)
{
Expand Down Expand Up @@ -202,7 +211,12 @@ fh_assign(JSValue *ctx, Node *node)
ctx = member->e2->type == NODE_MEMBER ?
fh_member(ctx, member->e2) :
fh_get(ctx, fh_str_from_node(ctx, member->e2)->string.ptr);
key = member->e1->sval;
if (IS_ARR(ctx) && member->e1->type == NODE_NUM) {
int val = member->e1->val;
if (val >= ctx->object.length)
fh_arr_set_len(ctx, val + 1);
}
key = fh_str_from_node(ctx, member->e1)->string.ptr;
}

fh_do_assign(ctx, key, val, node->sval);
Expand Down Expand Up @@ -303,6 +317,7 @@ fh_return(JSValue *ctx, Node *node)
JSValue *result = node->e1 ? fh_eval(ctx, node->e1) : JSUNDEF();
if (result->type == T_FUNCTION)
result->function.closure = ctx;
result->signal = S_BREAK;
return result;
}

Expand Down Expand Up @@ -710,6 +725,7 @@ fh_eq(JSValue *a, JSValue *b, bool strict)

// false != null
if (T_XOR(a, b, T_NULL, T_BOOLEAN)) return JSBOOL(0);
if (T_XOR(a, b, T_NULL, T_OBJECT)) return JSBOOL(0);
if (T_XOR(a, b, T_UNDEF, T_NULL)) return JSBOOL(1);
if (T_BOTH(a, b, T_NULL) || T_BOTH(a, b, T_UNDEF)) return JSBOOL(1);
if (T_BOTH(a, b, T_STRING))
Expand Down
1 change: 1 addition & 0 deletions src/eval.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ JSValue * fh_return(JSValue *, Node *);
JSValue * fh_prop_lst(JSValue *, Node *);
JSValue * fh_stmt_lst(JSValue *, Node *);
JSValue * fh_src_lst(JSValue *, Node *);
JSValue * fh_func(JSValue *, Node *);
JSValue * fh_obj(JSValue *, Node *);
JSValue * fh_arr(JSValue *, Node *);
JSValue * fh_call(JSValue *, Node *);
Expand Down
2 changes: 1 addition & 1 deletion src/flathead.c
Original file line number Diff line number Diff line change
Expand Up @@ -366,7 +366,7 @@ JSValue *
fh_has_property(JSValue *obj, char *prop)
{
JSValue *val = fh_get_proto(obj, prop);
return JSBOOL(val->type != T_UNDEF);
return JSBOOL(!IS_UNDEF(val));
}

JSValue *
Expand Down
5 changes: 0 additions & 5 deletions src/runtime/lib/Array.c
Original file line number Diff line number Diff line change
Expand Up @@ -373,7 +373,6 @@ arr_proto_filter(JSValue *instance, JSArgs *args, State *state)
{
JSValue *callback = ARG(args, 0);
JSValue *ctx = ARG(args, 1);
if (IS_UNDEF(ctx)) ctx = state->ctx;
JSValue *filtered = JSARR();
int len = instance->object.length;

Expand Down Expand Up @@ -401,7 +400,6 @@ arr_proto_for_each(JSValue *instance, JSArgs *args, State *state)
{
JSValue *callback = ARG(args, 0);
JSValue *ctx = ARG(args, 1);
if (IS_UNDEF(ctx)) ctx = state->ctx;
int len = instance->object.length;

JSValue *key, *val;
Expand All @@ -423,7 +421,6 @@ arr_proto_every(JSValue *instance, JSArgs *args, State *state)
{
JSValue *callback = ARG(args, 0);
JSValue *ctx = ARG(args, 1);
if (IS_UNDEF(ctx)) ctx = state->ctx;
int len = instance->object.length;

JSValue *key, *val, *result;
Expand All @@ -447,7 +444,6 @@ arr_proto_map(JSValue *instance, JSArgs *args, State *state)
{
JSValue *callback = ARG(args, 0);
JSValue *ctx = ARG(args, 1);
if (IS_UNDEF(ctx)) ctx = state->ctx;
int len = instance->object.length;
JSValue *map = JSARR();

Expand All @@ -472,7 +468,6 @@ arr_proto_some(JSValue *instance, JSArgs *args, State *state)
{
JSValue *callback = ARG(args, 0);
JSValue *ctx = ARG(args, 1);
if (IS_UNDEF(ctx)) ctx = state->ctx;
int len = instance->object.length;

JSValue *key, *val, *result;
Expand Down
31 changes: 31 additions & 0 deletions test/test_arrays.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,3 +41,34 @@ var getIndex = function() {
var a4 = ['a', 'b', 'c', 'd'];
assertEquals('c', a4[4 - 2]);
assertEquals('b', a4[getIndex()]);


// ----------------------------------------------------------------------------
// Bracket Assignment
// ----------------------------------------------------------------------------

// Easy stuff

var a5 = [];

a5[0] = 10;
a5[1] = 20;
a5[2] = 30;
a5[3] = 40;

assert(a5.length === 4);
assert(a5[0] === 10);
assert(a5[1] === 20);
assert(a5[2] === 30);
assert(a5[3] === 40);

// Indices do not need to be assigned in order (or at all)

var a6 = [];

a6[12] = 42;
a6[10002] = 'hello';

assert(a6.length === 10003);
assert(a6[12] === 42);
assert(a6[10002] === 'hello');
24 changes: 24 additions & 0 deletions test/test_closures.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@

var assert = console.assert;


// Return a function, no accessing outer scope vars. (easy mode)

var f1 = function() {
return function() {
return 42;
Expand All @@ -13,7 +15,9 @@ var f1 = function() {
var f2 = f1();
assert(f2() === 42);


// Return a function, access outer scope vars.

var f3 = function() {
var x = "vuvuzela";
return function() {
Expand All @@ -24,7 +28,9 @@ var f3 = function() {
var f4 = f3();
assert(f4() === "vuvuzela");


// Return a function, modify outer scope vars.

var f5 = function() {
var y = 1;
return function() {
Expand All @@ -37,7 +43,9 @@ assert(f6() === 2);
assert(f6() === 3);
assert(f6() === 4);


// Return an object of functions, assert they ref the same values. (hard mode)

var f7 = function() {
var z = 10;
return {
Expand All @@ -54,3 +62,19 @@ var funcs = f7();
// TODO: Gonna let this pass for now.
//assert(funcs.a() == 9);
//assert(funcs.b() == 9);


// Call with a function, access its outer scope.

var f8 = function(f) {
return f();
};

(function(outerParam) {
var outer = 99;
var result = f8(function() {
return outer + outerParam;
});
assert(result === 100);
})(1);

42 changes: 34 additions & 8 deletions test/test_functions.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,22 +8,39 @@ var assertEquals = function(a, b) {
return assert(a === b);
};


// Function declarations can be used pre-defintion

assertEquals(typeof f0, 'function');
assertEquals(f0(), 42);

function f0() {
return 42;
}


// Syntax allows an empty function body.

var f1 = function() {};

// Statements after a return are not evaluated:

// Statements after a return are not evaluated

(function() {
return 12;
assert();
})();

var returnTest = function() {
if (true) return 42;
return 12;
};

assertEquals(42, returnTest());


// Parameters and return expressions

var add = function(a, b) {
return a + b;
};
Expand All @@ -32,29 +49,38 @@ var square = function(x) {
return x * x;
};

assertEquals(9, square(3));
assertEquals(4, add(2, 2));


// Nested function calls

var incrementSquare = function(x) {
return add(square(x), 1);
};

assertEquals(82, incrementSquare(9));
assertEquals(401, incrementSquare(20));


// Recursive calls

var recursive1 = function(x) {
if (x < 10) {
x = x + 1;
return arguments.callee(x);
return arguments.callee(x); // by reference
}
return x;
};

assertEquals(10, recursive1(1));

var recursive2 = function(x) {
if (x < 10) {
x = x + 1;
return recursive2(x);
return recursive2(x); // by name
}
return x;
};

assertEquals(9, square(3));
assertEquals(4, add(2, 2));
assertEquals(82, incrementSquare(9));
assertEquals(401, incrementSquare(20));
assertEquals(10, recursive1(1));
assertEquals(10, recursive2(1));
2 changes: 2 additions & 0 deletions test/test_operators.js
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,8 @@ assert(null !== undefined);
assert(NaN != NaN && NaN !== NaN);
assert(Infinity == Infinity && Infinity === Infinity);
assert(2 == '2' && 2 !== '2');
assert([] != null);
assert({} != null);

assert('' != '0');
assert(0 == '');
Expand Down

0 comments on commit 64577cd

Please sign in to comment.