mirror of
https://github.com/ccxvii/mujs.git
synced 2026-09-22 07:03:36 +08:00
Implement relational and equality operators.
This commit is contained in:
@@ -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 */
|
||||
|
||||
|
||||
@@ -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 */
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user