Implement relational and equality operators.

This commit is contained in:
Tor Andersson
2014-01-18 18:20:33 +01:00
parent d3d92291f6
commit 05275e2e5d
3 changed files with 77 additions and 39 deletions
+10 -39
View File
@@ -693,48 +693,19 @@ static void jsR_run(js_State *J, js_Function *F)
/* Relational operators */
/* TODO: string comparisons */
case OP_LT:
x = js_tonumber(J, -2);
y = js_tonumber(J, -1);
js_pop(J, 2);
js_pushboolean(J, x < y);
break;
case OP_GT:
x = js_tonumber(J, -2);
y = js_tonumber(J, -1);
js_pop(J, 2);
js_pushboolean(J, x > y);
break;
case OP_LE:
x = js_tonumber(J, -2);
y = js_tonumber(J, -1);
js_pop(J, 2);
js_pushboolean(J, x <= y);
break;
case OP_GE:
x = js_tonumber(J, -2);
y = js_tonumber(J, -1);
js_pop(J, 2);
js_pushboolean(J, x >= y);
break;
case OP_LT: b = jsR_compare(J); js_pushboolean(J, b < 0); break;
case OP_GT: b = jsR_compare(J); js_pushboolean(J, b > 0); break;
case OP_LE: b = jsR_compare(J); js_pushboolean(J, b <= 0); break;
case OP_GE: b = jsR_compare(J); js_pushboolean(J, b >= 0); break;
// OP_INSTANCEOF
/* Equality */
case OP_EQ:
case OP_STRICTEQ:
x = js_tonumber(J, -2);
y = js_tonumber(J, -1);
js_pop(J, 2);
js_pushboolean(J, x == y);
break;
case OP_NE:
case OP_STRICTNE:
x = js_tonumber(J, -2);
y = js_tonumber(J, -1);
js_pop(J, 2);
js_pushboolean(J, x != y);
break;
case OP_EQ: b = jsR_equal(J); js_pushboolean(J, b); break;
case OP_NE: b = jsR_equal(J); js_pushboolean(J, !b); break;
case OP_STRICTEQ: b = jsR_strictequal(J); js_pushboolean(J, b); break;
case OP_STRICTNE: b = jsR_strictequal(J); js_pushboolean(J, !b); break;
/* Binary bitwise operators */
+5
View File
@@ -18,6 +18,11 @@ void jsR_error(js_State *J, const char *fmt, ...);
void js_pushobject(js_State *J, js_Object *v);
js_Object *js_toobject(js_State *J, int idx);
js_Value js_toprimitive(js_State *J, int idx, int hint);
js_Value js_tovalue(js_State *J, int idx);
void jsR_concat(js_State *J);
int jsR_compare(js_State *J);
int jsR_equal(js_State *J);
int jsR_strictequal(js_State *J);
/* public */
+62
View File
@@ -124,5 +124,67 @@ void jsR_concat(js_State *J)
int jsR_compare(js_State *J)
{
js_Value va = js_toprimitive(J, -2, JS_HNUMBER);
js_Value vb = js_toprimitive(J, -1, JS_HNUMBER);
js_pop(J, 2);
if (va.type == JS_TSTRING && vb.type == JS_TSTRING) {
return strcmp(va.u.string, va.u.string);
} else {
double x = jsR_tonumber(J, &va);
double y = jsR_tonumber(J, &vb);
return x < y ? -1 : x > y ? 1 : 0;
}
}
int jsR_equal(js_State *J)
{
js_Value va = js_tovalue(J, -2);
js_Value vb = js_tovalue(J, -1);
js_pop(J, 2);
retry:
if (va.type == vb.type) {
if (va.type == JS_TUNDEFINED) return 1;
if (va.type == JS_TNULL) return 1;
if (va.type == JS_TNUMBER) return va.u.number == vb.u.number;
if (va.type == JS_TBOOLEAN) return va.u.boolean == vb.u.boolean;
if (va.type == JS_TSTRING) return !strcmp(va.u.string, vb.u.string);
if (va.type == JS_TOBJECT) return va.u.object == vb.u.object;
return 0;
}
if (va.type == JS_TNULL && vb.type == JS_TUNDEFINED) return 1;
if (va.type == JS_TUNDEFINED && vb.type == JS_TNULL) return 1;
if (va.type == JS_TNUMBER && (vb.type == JS_TSTRING || vb.type == JS_TBOOLEAN))
return va.u.number == jsR_tonumber(J, &vb);
if ((va.type == JS_TSTRING || va.type == JS_TBOOLEAN) && vb.type == JS_TNUMBER)
return jsR_tonumber(J, &va) == vb.u.number;
if ((va.type == JS_TSTRING || va.type == JS_TNUMBER) && vb.type == JS_TOBJECT) {
vb = jsR_toprimitive(J, &vb, JS_HNONE);
goto retry;
}
if (va.type == JS_TOBJECT && (vb.type == JS_TSTRING || vb.type == JS_TNUMBER)) {
va = jsR_toprimitive(J, &va, JS_HNONE);
goto retry;
}
return 0;
}
int jsR_strictequal(js_State *J)
{
js_Value va = js_tovalue(J, -2);
js_Value vb = js_tovalue(J, -1);
js_pop(J, 2);
if (va.type != vb.type) return 0;
if (va.type == JS_TUNDEFINED) return 1;
if (va.type == JS_TNULL) return 1;
if (va.type == JS_TNUMBER) return va.u.number == vb.u.number;
if (va.type == JS_TBOOLEAN) return va.u.boolean == vb.u.boolean;
if (va.type == JS_TSTRING) return !strcmp(va.u.string, vb.u.string);
if (va.type == JS_TOBJECT) return va.u.object == vb.u.object;
return 0;
}