Author: Stephan <step...@stzal.com> Branch: Changeset: r377:fb52d8a52d9e Date: 2013-05-13 09:11 +0200 http://bitbucket.org/pypy/lang-js/changeset/fb52d8a52d9e/
Log: cleaned up comparsion code diff --git a/js/baseop.py b/js/baseop.py --- a/js/baseop.py +++ b/js/baseop.py @@ -3,10 +3,12 @@ """ from js.jsobj import W_String, W_IntNumber, W_FloatNumber -from js.object_space import _w, isint +from js.object_space import _w, isint, isstr, isfloat from rpython.rlib.rarithmetic import ovfcheck from rpython.rlib.rfloat import isnan, isinf +from rpython.rlib.objectmodel import specialize + from js.builtins.number import w_NAN, w_POSITIVE_INFINITY, w_NEGATIVE_INFINITY import math @@ -141,50 +143,56 @@ return W_FloatNumber(val) -def compare(ctx, x, y): +@specialize.argtype(0, 1) +def _compare_gt(x, y): + return x > y + + +@specialize.argtype(0, 1) +def _compare_ge(x, y): + return x >= y + + +def _base_compare(x, y, _compare): if isint(x) and isint(y): - return x.ToInteger() > y.ToInteger() - if isinstance(x, W_FloatNumber) and isinstance(y, W_FloatNumber): - if isnan(x.ToNumber()) or isnan(y.ToNumber()): - return -1 - return x.ToNumber() > y.ToNumber() - s1 = x.ToPrimitive('Number') - s2 = y.ToPrimitive('Number') - if not (isinstance(s1, W_String) and isinstance(s2, W_String)): - s4 = s1.ToNumber() - s5 = s2.ToNumber() - if isnan(s4) or isnan(s5): - return False - return s4 > s5 + return _compare(x.ToInteger(), y.ToInteger()) + + if isfloat(x) and isfloat(y): + n1 = x.ToNumber() + n2 = x.ToNumber() + return _compare(n1, n2) + + p1 = x.ToPrimitive('Number') + p2 = y.ToPrimitive('Number') + + if not (isstr(p1) and isstr(p2)): + n1 = p1.ToNumber() + n2 = p2.ToNumber() + return _compare(n1, n2) else: - s4 = s1.to_string() - s5 = s2.to_string() - return s4 > s5 + s1 = p1.to_string() + s2 = p2.to_string() + return _compare(s1, s2) -def compare_e(ctx, x, y): - if isint(x) and isint(y): - return x.ToInteger() >= y.ToInteger() - if isinstance(x, W_FloatNumber) and isinstance(y, W_FloatNumber): - if isnan(x.ToNumber()) or isnan(y.ToNumber()): - return -1 - return x.ToNumber() >= y.ToNumber() - s1 = x.ToPrimitive('Number') - s2 = y.ToPrimitive('Number') - if not (isinstance(s1, W_String) and isinstance(s2, W_String)): - s4 = s1.ToNumber() - s5 = s2.ToNumber() - if isnan(s4) or isnan(s5): - return False - return s4 >= s5 - else: - s4 = s1.to_string() - s5 = s2.to_string() - return s4 >= s5 +def compare_gt(x, y): + return _base_compare(x, y, _compare_gt) + + +def compare_ge(x, y): + return _base_compare(x, y, _compare_ge) + + +def compare_lt(x, y): + return _base_compare(y, x, _compare_gt) + + +def compare_le(x, y): + return _base_compare(y, x, _compare_ge) # 11.9.3 -def AbstractEC(ctx, x, y): +def AbstractEC(x, y): """ Implements the Abstract Equality Comparison x == y trying to be fully to the spec @@ -220,19 +228,19 @@ (type1 == "null" and type2 == "undefined"): return True if type1 == "number" and type2 == "string": - return AbstractEC(ctx, x, W_FloatNumber(y.ToNumber())) + return AbstractEC(x, W_FloatNumber(y.ToNumber())) if type1 == "string" and type2 == "number": - return AbstractEC(ctx, W_FloatNumber(x.ToNumber()), y) + return AbstractEC(W_FloatNumber(x.ToNumber()), y) if type1 == "boolean": - return AbstractEC(ctx, W_FloatNumber(x.ToNumber()), y) + return AbstractEC(W_FloatNumber(x.ToNumber()), y) if type2 == "boolean": - return AbstractEC(ctx, x, W_FloatNumber(y.ToNumber())) + return AbstractEC(x, W_FloatNumber(y.ToNumber())) if (type1 == "string" or type1 == "number") and \ type2 == "object": - return AbstractEC(ctx, x, y.ToPrimitive()) + return AbstractEC(x, y.ToPrimitive()) if (type2 == "string" or type2 == "number") and \ type1 == "object": - return AbstractEC(ctx, x.ToPrimitive(), y) + return AbstractEC(x.ToPrimitive(), y) return False objtype = x.GetValue().type() diff --git a/js/object_space.py b/js/object_space.py --- a/js/object_space.py +++ b/js/object_space.py @@ -7,6 +7,16 @@ return isinstance(w, W_IntNumber) +def isstr(w): + from js.jsobj import W_String + return isinstance(w, W_String) + + +def isfloat(w): + from js.jsobj import W_FloatNumber + return isinstance(w, W_FloatNumber) + + @enforceargs(int) def newint(i): from js.jsobj import W_IntNumber @@ -79,7 +89,7 @@ @enforceargs(bool) def newbool(val): - if val is True: + if val: return w_True return w_False diff --git a/js/opcodes.py b/js/opcodes.py --- a/js/opcodes.py +++ b/js/opcodes.py @@ -3,8 +3,7 @@ from js.object_space import _w, isint from js.exception import JsTypeError -from js.baseop import plus, sub, compare, AbstractEC, StrictEC,\ - compare_e, increment, decrement, mult, division, uminus, mod +from js.baseop import plus, sub, AbstractEC, StrictEC, increment, decrement, mult, division, uminus, mod from js.jsobj import put_property @@ -35,12 +34,10 @@ from js.object_space import newbool s4 = ctx.stack_pop() s2 = ctx.stack_pop() - res = self.decision(ctx, s2, s4) - # XXX mimik behaviour of old newbool - res_true = res is True - ctx.stack_append(newbool(res_true)) + res = self.decision(s2, s4) + ctx.stack_append(newbool(res)) - def decision(self, ctx, op1, op2): + def decision(self, op1, op2): raise NotImplementedError @@ -369,16 +366,17 @@ rnum = rval.ToUInt32() lnum = lval.ToUInt32() - from rpython.rlib.rarithmetic import ovfcheck_float_to_int + #from rpython.rlib.rarithmetic import ovfcheck_float_to_int shift_count = rnum & 0x1F res = lnum >> shift_count + w_res = _w(res) - try: - ovfcheck_float_to_int(res) - w_res = _w(res) - except OverflowError: - w_res = _w(float(res)) + #try: + #ovfcheck_float_to_int(res) + #w_res = _w(res) + #except OverflowError: + #w_res = _w(float(res)) ctx.stack_append(w_res) @@ -476,42 +474,50 @@ class GT(BaseBinaryComparison): - def decision(self, ctx, op1, op2): - return compare(ctx, op1, op2) + def decision(self, op1, op2): + from js.baseop import compare_gt + res = compare_gt(op1, op2) + return res class GE(BaseBinaryComparison): - def decision(self, ctx, op1, op2): - return compare_e(ctx, op1, op2) + def decision(self, op1, op2): + from js.baseop import compare_ge + res = compare_ge(op1, op2) + return res class LT(BaseBinaryComparison): - def decision(self, ctx, op1, op2): - return compare(ctx, op2, op1) + def decision(self, op1, op2): + from js.baseop import compare_lt + res = compare_lt(op1, op2) + return res class LE(BaseBinaryComparison): - def decision(self, ctx, op1, op2): - return compare_e(ctx, op2, op1) + def decision(self, op1, op2): + from js.baseop import compare_le + res = compare_le(op1, op2) + return res class EQ(BaseBinaryComparison): - def decision(self, ctx, op1, op2): - return AbstractEC(ctx, op1, op2) + def decision(self, op1, op2): + return AbstractEC(op1, op2) class NE(BaseBinaryComparison): - def decision(self, ctx, op1, op2): - return not AbstractEC(ctx, op1, op2) + def decision(self, op1, op2): + return not AbstractEC(op1, op2) class IS(BaseBinaryComparison): - def decision(self, ctx, op1, op2): + def decision(self, op1, op2): return StrictEC(op1, op2) class ISNOT(BaseBinaryComparison): - def decision(self, ctx, op1, op2): + def decision(self, op1, op2): return not StrictEC(op1, op2) _______________________________________________ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit