Author: Stephan <[email protected]>
Branch: 
Changeset: r157:394bffae727b
Date: 2011-11-10 00:51 +0100
http://bitbucket.org/pypy/lang-js/changeset/394bffae727b/

Log:    cleaned up primitive types

diff --git a/js/baseop.py b/js/baseop.py
--- a/js/baseop.py
+++ b/js/baseop.py
@@ -18,8 +18,8 @@
         return W_String(sleft + sright)
     # hot path
     if isinstance(nleft, W_IntNumber) and isinstance(nright, W_IntNumber):
-        ileft = nleft.intval
-        iright = nright.intval
+        ileft = nleft.ToInteger()
+        iright = nright.ToInteger()
         try:
             return W_IntNumber(ovfcheck(ileft + iright))
         except OverflowError:
@@ -31,13 +31,13 @@
 
 def increment(ctx, nleft, constval=1):
     if isinstance(nleft, W_IntNumber):
-        return W_IntNumber(nleft.intval + constval)
+        return W_IntNumber(nleft.ToInteger() + constval)
     else:
         return plus(ctx, nleft, W_IntNumber(constval))
 
 def decrement(ctx, nleft, constval=1):
     if isinstance(nleft, W_IntNumber):
-        return W_IntNumber(nleft.intval - constval)
+        return W_IntNumber(nleft.ToInteger() - constval)
     else:
         return sub(ctx, nleft, W_IntNumber(constval))
 
@@ -89,11 +89,11 @@
 
 def compare(ctx, x, y):
     if isinstance(x, W_IntNumber) and isinstance(y, W_IntNumber):
-        return x.intval > y.intval
+        return x.ToInteger() > y.ToInteger()
     if isinstance(x, W_FloatNumber) and isinstance(y, W_FloatNumber):
-        if isnan(x.floatval) or isnan(y.floatval):
+        if isnan(x.ToNumber()) or isnan(y.ToNumber()):
             return -1
-        return x.floatval > y.floatval
+        return x.ToNumber() > y.ToNumber()
     s1 = x.ToPrimitive('Number')
     s2 = y.ToPrimitive('Number')
     if not (isinstance(s1, W_String) and isinstance(s2, W_String)):
@@ -109,11 +109,11 @@
 
 def compare_e(ctx, x, y):
     if isinstance(x, W_IntNumber) and isinstance(y, W_IntNumber):
-        return x.intval >= y.intval
+        return x.ToInteger() >= y.ToInteger()
     if isinstance(x, W_FloatNumber) and isinstance(y, W_FloatNumber):
-        if isnan(x.floatval) or isnan(y.floatval):
+        if isnan(x.ToNumber()) or isnan(y.ToNumber()):
             return -1
-        return x.floatval >= y.floatval
+        return x.ToNumber() >= y.ToNumber()
     s1 = x.ToPrimitive('Number')
     s2 = y.ToPrimitive('Number')
     if not (isinstance(s1, W_String) and isinstance(s2, W_String)):
@@ -133,11 +133,11 @@
     trying to be fully to the spec
     """
     if isinstance(x, W_IntNumber) and isinstance(y, W_IntNumber):
-        return x.intval == y.intval
+        return x.ToInteger() == y.ToInteger()
     if isinstance(x, W_FloatNumber) and isinstance(y, W_FloatNumber):
-        if isnan(x.floatval) or isnan(y.floatval):
+        if isnan(x.ToNumber()) or isnan(y.ToNumber()):
             return False
-        return x.floatval == y.floatval
+        return x.ToNumber() == y.ToNumber()
     type1 = x.type()
     type2 = y.type()
     if type1 == type2:
@@ -217,7 +217,8 @@
 
 
 def commonnew(ctx, obj, args):
-    if not isinstance(obj, W_PrimitiveObject):
+    from js.jsobj import W_BasicObject
+    if not (isinstance(obj, W_PrimitiveObject) or isinstance(obj, 
W_BasicObject)):
         raise ThrowException(W_String('it is not a constructor'))
     try:
         res = obj.Construct(args=args)
@@ -227,5 +228,5 @@
 
 def uminus(obj, ctx):
     if isinstance(obj, W_IntNumber):
-        return W_IntNumber(-obj.intval)
+        return W_IntNumber(-obj.ToInteger())
     return W_FloatNumber(-obj.ToNumber())
diff --git a/js/builtins.py b/js/builtins.py
--- a/js/builtins.py
+++ b/js/builtins.py
@@ -6,7 +6,7 @@
 from js.jsobj import W_Object,\
      w_Undefined, W_NewBuiltin, W_IntNumber, w_Null, create_object, W_Boolean,\
      W_FloatNumber, W_String, W_Builtin, W_Array, w_Null, newbool,\
-     isnull_or_undefined, W_PrimitiveObject, W_ListObject, W_BaseNumber,\
+     isnull_or_undefined, W_PrimitiveObject, W_ListObject, W_Number,\
      DONT_DELETE, DONT_ENUM, READ_ONLY, INTERNAL
 from js.execution import ThrowException, JsTypeError
 
@@ -59,7 +59,7 @@
         if len(args) >= 1:
             arg0 = args[0]
             if  isinstance(arg0, W_String):
-                src = arg0.strval
+                src = arg0.ToString()
             else:
                 return arg0
         else:
@@ -508,8 +508,8 @@
         t = 'W_FloatNumber'
     elif isinstance(o, W_IntNumber):
         t = 'W_IntNumber'
-    elif isinstance(o, W_BaseNumber):
-        t = 'W_Base_Number'
+    elif isinstance(o, W_Number):
+        t = 'W_Number'
     return W_String(t)
 
 def put_values(ctx, obj, dictvalues):
@@ -580,9 +580,9 @@
 def absjs(args, this):
     val = args[0]
     if isinstance(val, W_IntNumber):
-        if val.intval > 0:
+        if val.ToInteger() > 0:
             return val # fast path
-        return W_IntNumber(-val.intval)
+        return W_IntNumber(-val.ToInteger())
     return W_FloatNumber(abs(args[0].ToNumber()))
 
 def floorjs(args, this):
@@ -636,7 +636,7 @@
     if not isinstance(w_string, W_String):
         raise JsTypeError(W_String("Expected string"))
     assert isinstance(w_string, W_String)
-    strval = w_string.strval
+    strval = w_string.ToString()
     lgt = len(strval)
     i = 0
     while i < lgt:
@@ -736,7 +736,7 @@
         W_NativeObject.__init__(self, Class, Prototype, None )
 
     def Call(self, args=[], this=None):
-        if len(args) == 1 and isinstance(args[0], W_BaseNumber):
+        if len(args) == 1 and isinstance(args[0], W_Number):
             array = create_array()
             array.Put('length', args[0])
         else:
diff --git a/js/jsobj.py b/js/jsobj.py
--- a/js/jsobj.py
+++ b/js/jsobj.py
@@ -20,7 +20,45 @@
 class SeePage(NotImplementedError):
     pass
 
-class W_Root(object):
+class W___Root(object):
+    pass
+
+class W__Root(W___Root):
+    _settled_ = True
+    _attrs_ = []
+    _type_ = ''
+
+    def __str__(self):
+        return self.ToString()
+
+    def type(self):
+        return self._type_
+
+    def ToBoolean(self):
+        return False
+
+    def ToPrimitive(self, hint=""):
+        return self
+
+    def ToString(self):
+        return ''
+
+    def ToObject(self):
+        raise JsTypeError
+
+    def ToNumber(self):
+        return 0.0
+
+    def ToInteger(self):
+        return int(self.ToNumber())
+
+    def ToInt32(self):
+        return r_int32(self.ToInteger())
+
+    def ToUInt32(self):
+        return r_uint32(self.ToInteger())
+
+class W_Root(W___Root):
     _settled_ = True
     _attrs_ = []
     def __init__(self):
@@ -84,43 +122,28 @@
     def Delete(self, name):
         return False
 
-class W_Undefined(W_Root):
-    def __str__(self):
-        return "w_undefined"
+class W__Primitive(W__Root):
+    pass
 
+class W_Undefined(W__Primitive):
+    _type_ = 'undefined'
     def ToInteger(self):
         return 0
 
     def ToNumber(self):
         return NAN
 
-    def ToBoolean(self):
-        return False
+    def ToString(self):
+        return self._type_
 
-    def ToString(self):
-        return "undefined"
-
-    def type(self):
-        return 'undefined'
-
-    def tolist(self):
-        return []
-
-class W_Null(W_Root):
-    def __str__(self):
-        return "null"
+class W_Null(W__Primitive):
+    _type_ = 'null'
 
     def ToBoolean(self):
         return False
 
     def ToString(self):
-        return "null"
-
-    def type(self):
-        return 'null'
-
-    def tolist(self):
-        return []
+        return self._type_
 
 w_Undefined = W_Undefined()
 w_Null = W_Null()
@@ -279,12 +302,12 @@
         t1 = self.Get(tryone)
         if isinstance(t1, W_PrimitiveObject):
             val = t1.Call(this=self)
-            if isinstance(val, W_Primitive):
+            if isinstance(val, W__Primitive):
                 return val
         t2 = self.Get(trytwo)
         if isinstance(t2, W_PrimitiveObject):
             val = t2.Call(this=self)
-            if isinstance(val, W_Primitive):
+            if isinstance(val, W__Primitive):
                 return val
         raise JsTypeError
 
@@ -350,11 +373,6 @@
     def type(self):
         return 'function'
 
-class W_Primitive(W_Root):
-    """unifying parent for primitives"""
-    def ToPrimitive(self, hint=""):
-        return self
-
 class W_NewBuiltin(W_PrimitiveObject):
     length = -1
     def __init__(self, Prototype=None, Class='function', Value=w_Undefined):
@@ -464,120 +482,111 @@
                 raise RangeError()
             self.set_length(arrayindex+1)
 
-class W_Boolean(W_Primitive):
-    _immutable_fields_ = ['boolval']
+class W_Boolean(W__Primitive):
+    _immutable_fields_ = ['_boolval_']
+    _type_ = 'boolean'
+
     def __init__(self, boolval):
-        self.boolval = bool(boolval)
+        W__Primitive.__init__(self)
+        self._boolval_ = bool(boolval)
+
+    def __repr__(self):
+        return 'W_Bool(%s)' % (str(self._boolval_), )
 
     def ToObject(self):
+        # TODO
         return create_object('Boolean', Value=self)
 
     def ToString(self):
-        if self.boolval == True:
+        if self._boolval_ == True:
             return "true"
         return "false"
 
     def ToNumber(self):
-        if self.boolval:
+        if self._boolval_ == True:
             return 1.0
         return 0.0
 
     def ToBoolean(self):
-        return self.boolval
+        return self._boolval_
 
-    def type(self):
-        return 'boolean'
+class W_String(W__Primitive):
+    _immutable_fields_ = ['_strval_']
+    _type_ = 'string'
+
+    def __init__(self, strval):
+        W__Primitive.__init__(self)
+        self._strval_ = strval
 
     def __repr__(self):
-        return "<W_Bool "+str(self.boolval)+" >"
-
-class W_String(W_Primitive):
-    _immutable_fields_ = ['strval']
-    def __init__(self, strval):
-        W_Primitive.__init__(self)
-        self.strval = strval
-
-    def __repr__(self):
-        return 'W_String(%s)' % (self.strval,)
+        return 'W_String(%s)' % (repr(self._strval_),)
 
     def ToObject(self):
+        # TODO
         o = create_object('String', Value=self)
-        o.Put('length', W_IntNumber(len(self.strval)), flags = READ_ONLY | 
DONT_DELETE | DONT_ENUM)
+        o.Put('length', W_IntNumber(len(self._strval_)), flags = READ_ONLY | 
DONT_DELETE | DONT_ENUM)
         return o
 
     def ToString(self):
-        return self.strval
+        return self._strval_
 
     def ToBoolean(self):
-        if len(self.strval) == 0:
+        if len(self._strval_) == 0:
             return False
         else:
             return True
 
-    def type(self):
-        return 'string'
-
-    def GetPropertyName(self):
-        return self.ToString()
-
     def ToNumber(self):
-        if not self.strval:
+        if not self._strval_:
             return 0.0
         try:
-            return float(self.strval)
+            return float(self._strval_)
         except ValueError:
             try:
-                return float(int(self.strval, 16))
+                return float(int(self._strval_, 16))
             except ValueError:
                 try:
-                    return float(int(self.strval, 8))
+                    return float(int(self._strval_, 8))
                 except ValueError:
                     return NAN
 
-
-class W_BaseNumber(W_Primitive):
+class W_Number(W__Primitive):
     """ Base class for numbers, both known to be floats
     and those known to be integers
     """
+    _type_ = 'number'
+
     def ToObject(self):
+        # TODO
         return create_object('Number', Value=self)
 
-    def Get(self, P):
-        return w_Undefined
+    def ToBoolean(self):
+        num = self.ToNumber()
+        if isnan(num):
+            return False
+        return bool(num)
 
-    def type(self):
-        return 'number'
-
-class W_IntNumber(W_BaseNumber):
-    _immutable_fields_ = ['intval']
+class W_IntNumber(W_Number):
+    _immutable_fields_ = ['_intval_']
     """ Number known to be an integer
     """
     def __init__(self, intval):
-        W_BaseNumber.__init__(self)
-        self.intval = intmask(intval)
+        W_Number.__init__(self)
+        self._intval_ = intmask(intval)
+
+    def __repr__(self):
+        return 'W_IntNumber(%s)' % (self._intval_,)
+
+    def ToInteger(self):
+        return self._intval_
+
+    def ToNumber(self):
+        # XXX
+        return float(self._intval_)
 
     def ToString(self):
         # XXX incomplete, this doesn't follow the 9.8.1 recommendation
-        return str(self.intval)
-
-    def ToBoolean(self):
-        return bool(self.intval)
-
-    def ToNumber(self):
-        # XXX
-        return float(self.intval)
-
-    def ToInt32(self):
-        return r_int32(self.intval)
-
-    def ToUInt32(self):
-        return r_uint32(self.intval)
-
-    def GetPropertyName(self):
-        return self.ToString()
-
-    def __repr__(self):
-        return 'W_IntNumber(%s)' % (self.intval,)
+        return str(self.ToInteger())
 
 def r_int32(n):
     return intmask(rffi.cast(rffi.INT, n))
@@ -585,26 +594,29 @@
 def r_uint32(n):
     return intmask(rffi.cast(rffi.UINT, n))
 
-class W_FloatNumber(W_BaseNumber):
-    _immutable_fields_ = ['floatval']
+class W_FloatNumber(W_Number):
+    _immutable_fields_ = ['_floatval_']
     """ Number known to be a float
     """
     def __init__(self, floatval):
-        W_BaseNumber.__init__(self)
-        self.floatval = float(floatval)
+        W_Number.__init__(self)
+        self._floatval_ = float(floatval)
+
+    def __repr__(self):
+        return 'W_FloatNumber(%s)' % (self._floatval_,)
 
     def ToString(self):
         # XXX incomplete, this doesn't follow the 9.8.1 recommendation
-        if isnan(self.floatval):
+        if isnan(self._floatval_):
             return 'NaN'
-        if isinf(self.floatval):
-            if self.floatval > 0:
+        if isinf(self._floatval_):
+            if self._floatval_ > 0:
                 return 'Infinity'
             else:
                 return '-Infinity'
         res = ''
         try:
-            res = formatd(self.floatval, 'g', 10)
+            res = formatd(self._floatval_, 'g', 10)
         except OverflowError:
             raise
 
@@ -614,35 +626,17 @@
             res = res[:cut] + res[-1]
         return res
 
-    def ToBoolean(self):
-        if isnan(self.floatval):
-            return False
-        return bool(self.floatval)
-
     def ToNumber(self):
-        return self.floatval
+        return self._floatval_
 
     def ToInteger(self):
-        if isnan(self.floatval):
+        if isnan(self._floatval_):
             return 0
 
-        if self.floatval == 0 or isinf(self.floatval):
-            return self.floatval
+        if self._floatval_ == 0 or isinf(self._floatval_):
+            return self._floatval_
 
-        return intmask(int(self.floatval))
-
-    def ToInt32(self):
-        if isnan(self.floatval) or isinf(self.floatval):
-            return 0
-        return r_int32(int(self.floatval))
-
-    def ToUInt32(self):
-        if isnan(self.floatval) or isinf(self.floatval):
-            return r_uint(0)
-        return r_uint32(int(self.floatval))
-
-    def __repr__(self):
-        return 'W_FloatNumber(%s)' % (self.floatval,)
+        return intmask(int(self._floatval_))
 
 class W_List(W_Root):
     def __init__(self, list_w):
diff --git a/js/opcodes.py b/js/opcodes.py
--- a/js/opcodes.py
+++ b/js/opcodes.py
@@ -68,7 +68,7 @@
         ctx.append(self.w_intvalue)
 
     def __repr__(self):
-        return 'LOAD_INTCONSTANT %s' % (self.w_intvalue.intval,)
+        return 'LOAD_INTCONSTANT %s' % (self.w_intvalue.ToInteger(),)
 
 class LOAD_BOOLCONSTANT(Opcode):
     def __init__(self, value):
@@ -85,7 +85,7 @@
         ctx.append(self.w_floatvalue)
 
     def __repr__(self):
-        return 'LOAD_FLOATCONSTANT %s' % (self.w_floatvalue.floatval,)
+        return 'LOAD_FLOATCONSTANT %s' % (self.w_floatvalue.ToNumber(),)
 
 class LOAD_STRINGCONSTANT(Opcode):
     _immutable_fields_ = ['w_stringvalue']
@@ -96,7 +96,7 @@
         ctx.append(self.w_stringvalue)
 
     def __repr__(self):
-        return 'LOAD_STRINGCONSTANT "%s"' % (self.w_stringvalue.strval,)
+        return 'LOAD_STRINGCONSTANT "%s"' % (self.w_stringvalue.ToString(),)
 
 class LOAD_UNDEFINED(Opcode):
     def eval(self, ctx):
diff --git a/js/operations.py b/js/operations.py
--- a/js/operations.py
+++ b/js/operations.py
@@ -7,7 +7,7 @@
 from js.jsobj import W_IntNumber, W_FloatNumber, W_Object,\
      w_Undefined, W_NewBuiltin, W_String, create_object, W_List,\
      W_PrimitiveObject, ActivationObject, W_Array, W_Boolean,\
-     w_Null, W_BaseNumber, isnull_or_undefined
+     w_Null, isnull_or_undefined
 from pypy.rlib.parsing.ebnfparse import Symbol, Nonterminal
 from js.execution import JsTypeError, ThrowException
 from js.jscode import JsCode
diff --git a/js/test/test_interp.py b/js/test/test_interp.py
--- a/js/test/test_interp.py
+++ b/js/test/test_interp.py
@@ -1,7 +1,7 @@
 import py
 from js import interpreter
 from js.operations import IntNumber, FloatNumber, Position, Plus
-from js.jsobj import W_Object, W_Root, w_Null
+from js.jsobj import W_Object, W_Root, w_Null, W___Root
 from js.execution import ThrowException
 from js.jscode import JsCode, POP
 from js.baseop import AbstractEC
@@ -44,7 +44,7 @@
     except ThrowException, excpt:
         code_val = excpt.exception
     print code_val, value
-    if isinstance(value, W_Root):
+    if isinstance(value, W___Root):
         assert AbstractEC(jsint.global_context, code_val, value) == True
     elif isinstance(value, bool):
         assert code_val.ToBoolean() == value
diff --git a/js/test/test_jsobj.py b/js/test/test_jsobj.py
--- a/js/test/test_jsobj.py
+++ b/js/test/test_jsobj.py
@@ -1,5 +1,5 @@
-import pytest
-from js.jsobj import W_IntNumber, W_FloatNumber, W_Null
+import py
+from js.jsobj import W_IntNumber, W_FloatNumber, w_Null, w_Undefined, w_True, 
w_False, NAN, W_String, W__Object as W_Object, W_BasicObject, W_BooleanObject
 
 def test_intnumber():
     n = W_IntNumber(0x80000000)
@@ -11,5 +11,116 @@
     assert n.ToInt32() == -0x80000000
     assert n.ToUInt32() == 0x80000000
 
-def test_type_null():
-    assert W_Null().type() == 'null'
+class TestType():
+    def test_undefined(self):
+        assert w_Undefined.type() == 'undefined'
+
+    def test_null(self):
+        assert w_Null.type() == 'null'
+
+    def test_boolean(self):
+        assert w_True.type() == 'boolean'
+        assert w_False.type() == 'boolean'
+
+    def test_number(self):
+        assert W_IntNumber(0).type() == 'number'
+        assert W_FloatNumber(0.0).type() == 'number'
+        assert W_FloatNumber(NAN).type() == 'number'
+
+    def test_string(self):
+        assert W_String('').type() == 'string'
+
+    def test_object(self):
+        assert W_Object().type() == 'object'
+
+class TestToBoolean():
+    def test_undefined(self):
+        assert w_Undefined.ToBoolean() == False
+
+    def test_null(self):
+        assert w_Null.ToBoolean() == False
+
+    def test_boolean(self):
+        assert w_True.ToBoolean() == True
+        assert w_False.ToBoolean() == False
+
+    def test_number(self):
+        assert W_IntNumber(0).ToBoolean() == False
+        assert W_IntNumber(1).ToBoolean() == True
+        assert W_FloatNumber(0.0).ToBoolean() == False
+        assert W_FloatNumber(1.0).ToBoolean() == True
+        assert W_FloatNumber(NAN).ToBoolean() == False
+
+    def test_string(self):
+        assert W_String('').ToBoolean() == False
+        assert W_String('a').ToBoolean() == True
+
+    def test_object(self):
+        assert W_Object().ToBoolean() == True
+
+class TestToNumber():
+    def test_undefined(self):
+        assert w_Undefined.ToNumber() is NAN
+
+    def test_null(self):
+        assert w_Null.ToNumber() == 0
+
+    def test_boolean(self):
+        assert w_True.ToNumber() == 1
+        assert w_False.ToNumber() == 0
+
+    def test_number(self):
+        assert W_IntNumber(0).ToNumber() == 0
+        assert W_IntNumber(1).ToNumber() == 1
+        assert W_FloatNumber(0.0).ToNumber() == 0
+        assert W_FloatNumber(1.0).ToNumber() == 1.0
+        assert W_FloatNumber(NAN).ToNumber() is NAN
+
+    def test_string(self):
+        assert W_String('').ToNumber() == 0
+        assert W_String('x').ToNumber() is NAN
+        assert W_String('1').ToNumber() == 1
+
+    def test_object(self):
+        py.test.skip()
+        W_Object().ToNumber()
+
+class TestToString():
+    def test_undefined(self):
+        assert w_Undefined.ToString() == 'undefined'
+
+    def test_null(self):
+        assert w_Null.ToString() == 'null'
+
+    def test_boolean(self):
+        assert w_True.ToString() == 'true'
+        assert w_False.ToString() == 'false'
+
+    def test_number(self):
+        assert W_IntNumber(0).ToString() == '0'
+        assert W_IntNumber(1).ToString() == '1'
+        assert W_FloatNumber(0.0).ToString() == '0'
+        assert W_FloatNumber(1.0).ToString() == '1'
+        assert W_FloatNumber(NAN).ToString() == 'NaN'
+
+    def test_string(self):
+        assert W_String('').ToString() == ''
+        assert W_String('x').ToString() == 'x'
+        assert W_String('1').ToString() == '1'
+
+    def test_object(self):
+        py.test.skip()
+        W_Object().ToString()
+
+class TestW_BasicObject():
+    def test_Prototype(self):
+        assert W_BasicObject().Prototype() is None
+
+    def test_Class(self):
+        assert W_BasicObject().Class() == 'Object'
+
+class Test_WBooleanObject():
+    def test_toPrimitive(self):
+        py.test.skip()
+        b = W_BooleanObject(w_True)
+        assert b.ToPrimitive() == w_True
diff --git a/js/utils.py b/js/utils.py
--- a/js/utils.py
+++ b/js/utils.py
@@ -26,8 +26,8 @@
         return self.stack[i]
 
     def append(self, element):
-        from js.jsobj import W_Root
-        assert isinstance(element, W_Root)
+        from js.jsobj import W___Root
+        assert isinstance(element, W___Root)
         i = self.stack_pointer
         assert i >= 0
         self.stack[i] = element
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to