[jsbuilt-ins] implementing Boolean object
* renames _type to jstype * mocks up type conversions * adds jslass internal property
This commit is contained in:
parent
9ead39caee
commit
87331205ba
@ -13,7 +13,7 @@ def _to_js(o, name=None):
|
|||||||
elif o is None:
|
elif o is None:
|
||||||
return undefined
|
return undefined
|
||||||
elif isinstance(o, _native_bool):
|
elif isinstance(o, _native_bool):
|
||||||
return JSBoolean.construct(o)
|
return JSBooleanPrototype(o)
|
||||||
elif isinstance(o, _native_string):
|
elif isinstance(o, _native_string):
|
||||||
return JSStringPrototype(o)
|
return JSStringPrototype(o)
|
||||||
elif isinstance(o, _native_number):
|
elif isinstance(o, _native_number):
|
||||||
@ -36,37 +36,60 @@ def js(func):
|
|||||||
return wrapper
|
return wrapper
|
||||||
|
|
||||||
|
|
||||||
def _type(o):
|
def jstype(o):
|
||||||
if o is undefined:
|
if o is undefined:
|
||||||
return _undefined_type
|
return _undefined_type
|
||||||
elif o is None or o is null:
|
elif o is None or o is null:
|
||||||
return _null_type
|
return _null_type
|
||||||
elif isinstance(o, _native_bool) or isinstance(o, JSBooleanPrototype):
|
elif isinstance(o, _native_bool) or o is true or o is false:
|
||||||
return _boolean_type
|
return _boolean_type
|
||||||
elif isinstance(o, _native_string) or isinstance(o, JSStringPrototype):
|
elif isinstance(o, _native_string):
|
||||||
return _string_type
|
return _string_type
|
||||||
elif isinstance(o, _native_number) or isinstance(o, JSNumberPrototype):
|
elif isinstance(o, _native_number):
|
||||||
return _number_type
|
return _number_type
|
||||||
elif isinstance(o, _native_object) or isinstance(o, JSObjectPrototype):
|
elif isinstance(o, _native_object):
|
||||||
return _object_type
|
return _object_type
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
def to_object(o):
|
def to_primitive(o, hint=None):
|
||||||
|
# TODO to_primitive
|
||||||
|
return o
|
||||||
|
|
||||||
|
|
||||||
|
def to_boolean(o):
|
||||||
if o is undefined or o is null:
|
if o is undefined or o is null:
|
||||||
raise Exception('TypeError: Cannot convert undefined or null to object')
|
return false
|
||||||
elif isinstance(o, JSBooleanPrototype):
|
elif isinstance(o, JSBooleanPrototype):
|
||||||
return JSBooleanPrototype(o)
|
return o.value
|
||||||
elif isinstance(o, JSNumberPrototype):
|
elif isinstance(o, JSNumberPrototype):
|
||||||
return JSNumberPrototype(o)
|
return true if o.value and not isnan(o.value) else false
|
||||||
elif isinstance(o, JSStringPrototype):
|
elif isinstance(o, JSStringPrototype):
|
||||||
return JSStringPrototype(o)
|
return true if o.value else false
|
||||||
elif isinstance(o, JSObjectPrototype):
|
elif isinstance(o, JSObjectPrototype):
|
||||||
return o
|
return true
|
||||||
|
else:
|
||||||
|
raise Exception('Failed to convert type %s to boolean (not specified)' % type(o))
|
||||||
|
|
||||||
|
|
||||||
def to_primitive(o, hint):
|
def to_number(o):
|
||||||
return o
|
# TODO to_number
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def to_integer(o):
|
||||||
|
# TODO to_integer
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def to_int32(o):
|
||||||
|
# TODO to_int32
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def to_int16(o):
|
||||||
|
# TODO to_int16
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
def to_string(o):
|
def to_string(o):
|
||||||
@ -122,6 +145,19 @@ def to_string(o):
|
|||||||
return to_string(prim_value)
|
return to_string(prim_value)
|
||||||
|
|
||||||
|
|
||||||
|
def to_object(o):
|
||||||
|
if o is undefined or o is null:
|
||||||
|
raise Exception('TypeError: Cannot convert undefined or null to object')
|
||||||
|
elif isinstance(o, JSBooleanPrototype):
|
||||||
|
return JSBooleanPrototype(o)
|
||||||
|
elif isinstance(o, JSNumberPrototype):
|
||||||
|
return JSNumberPrototype(o)
|
||||||
|
elif isinstance(o, JSStringPrototype):
|
||||||
|
return JSStringPrototype(o)
|
||||||
|
elif isinstance(o, JSObjectPrototype):
|
||||||
|
return o
|
||||||
|
|
||||||
|
|
||||||
class JSBase(object):
|
class JSBase(object):
|
||||||
|
|
||||||
def __init__(self, name):
|
def __init__(self, name):
|
||||||
@ -136,16 +172,13 @@ class JSProtoBase(JSBase):
|
|||||||
def __init__(self):
|
def __init__(self):
|
||||||
super(JSProtoBase, self).__init__('')
|
super(JSProtoBase, self).__init__('')
|
||||||
cls = self.__class__
|
cls = self.__class__
|
||||||
while cls is not JSProtoBase:
|
while cls.__base__ is not JSProtoBase:
|
||||||
cls = cls.__base__
|
cls = cls.__base__
|
||||||
props = cls.own.copy()
|
props = cls.own.copy()
|
||||||
props.update(self.props)
|
props.update(self.props)
|
||||||
self.props = props
|
self.props = props
|
||||||
self.value = {}
|
self.value = {}
|
||||||
|
|
||||||
def __str__(self):
|
|
||||||
return ''
|
|
||||||
|
|
||||||
def get_prop(self, prop):
|
def get_prop(self, prop):
|
||||||
result = self.value.get(prop) if hasattr(self.value, 'get') else None
|
result = self.value.get(prop) if hasattr(self.value, 'get') else None
|
||||||
if result is None:
|
if result is None:
|
||||||
@ -170,6 +203,8 @@ class JSProtoBase(JSBase):
|
|||||||
# interpreter should raise JSTypeError
|
# interpreter should raise JSTypeError
|
||||||
raise Exception('TypeError: %s is not a function' % prop)
|
raise Exception('TypeError: %s is not a function' % prop)
|
||||||
|
|
||||||
|
jsclass = ''
|
||||||
|
|
||||||
|
|
||||||
class JSObjectPrototype(JSProtoBase):
|
class JSObjectPrototype(JSProtoBase):
|
||||||
|
|
||||||
@ -199,6 +234,7 @@ class JSObjectPrototype(JSProtoBase):
|
|||||||
def _is_property_enumerable(self, v):
|
def _is_property_enumerable(self, v):
|
||||||
return 'object is property enumerable'
|
return 'object is property enumerable'
|
||||||
|
|
||||||
|
jsclass = 'Object'
|
||||||
own = {
|
own = {
|
||||||
'constructor': _constructor,
|
'constructor': _constructor,
|
||||||
'toString': _to_string,
|
'toString': _to_string,
|
||||||
@ -272,7 +308,7 @@ class JSObject(JSBase):
|
|||||||
def _keys(self, o):
|
def _keys(self, o):
|
||||||
return 'object keys'
|
return 'object keys'
|
||||||
|
|
||||||
name = 'Object'
|
name = JSObjectPrototype.jsclass
|
||||||
own = {
|
own = {
|
||||||
'length': 1,
|
'length': 1,
|
||||||
'prototype': JSObjectPrototype(),
|
'prototype': JSObjectPrototype(),
|
||||||
@ -349,6 +385,7 @@ class JSFunctionPrototype(JSObjectPrototype):
|
|||||||
def _bind(self, this_arg, *args):
|
def _bind(self, this_arg, *args):
|
||||||
return 'function bind'
|
return 'function bind'
|
||||||
|
|
||||||
|
jsclass = 'Function'
|
||||||
own = {
|
own = {
|
||||||
'length': 0,
|
'length': 0,
|
||||||
'constructor': _constructor,
|
'constructor': _constructor,
|
||||||
@ -375,7 +412,7 @@ class JSFunction(JSObject):
|
|||||||
formal_args = formal_args[:-1]
|
formal_args = formal_args[:-1]
|
||||||
return JSFunctionPrototype('anonymous', body, formal_args)
|
return JSFunctionPrototype('anonymous', body, formal_args)
|
||||||
|
|
||||||
name = 'Function'
|
name = JSFunctionPrototype.jsclass
|
||||||
own = {
|
own = {
|
||||||
'length': 1,
|
'length': 1,
|
||||||
'prototype': JSFunctionPrototype(None, None, None)
|
'prototype': JSFunctionPrototype(None, None, None)
|
||||||
@ -468,6 +505,7 @@ class JSArrayPrototype(JSObjectPrototype):
|
|||||||
def _reduce_right(self, callback, init=None):
|
def _reduce_right(self, callback, init=None):
|
||||||
return 'array reduce right'
|
return 'array reduce right'
|
||||||
|
|
||||||
|
jsclass = 'Array'
|
||||||
own = {
|
own = {
|
||||||
'length': _length,
|
'length': _length,
|
||||||
'constructor': _constructor,
|
'constructor': _constructor,
|
||||||
@ -516,7 +554,7 @@ class JSArray(JSObject):
|
|||||||
def _is_array(self, arg):
|
def _is_array(self, arg):
|
||||||
return 'array is array'
|
return 'array is array'
|
||||||
|
|
||||||
name = 'Array'
|
name = JSArrayPrototype.jsclass
|
||||||
own = {
|
own = {
|
||||||
'length': 1,
|
'length': 1,
|
||||||
'prototype': JSArrayPrototype(),
|
'prototype': JSArrayPrototype(),
|
||||||
@ -597,6 +635,7 @@ class JSStringPrototype(JSObjectPrototype):
|
|||||||
def _trim(self):
|
def _trim(self):
|
||||||
return 'string trim'
|
return 'string trim'
|
||||||
|
|
||||||
|
jsclass = 'String'
|
||||||
own = {
|
own = {
|
||||||
'length': _length,
|
'length': _length,
|
||||||
'constructor': _constructor,
|
'constructor': _constructor,
|
||||||
@ -635,7 +674,7 @@ class JSString(JSObject):
|
|||||||
def _from_char_code(self, *args):
|
def _from_char_code(self, *args):
|
||||||
return 'String from char code'
|
return 'String from char code'
|
||||||
|
|
||||||
name = 'String'
|
name = JSStringPrototype.jsclass
|
||||||
own = {
|
own = {
|
||||||
'length': 1,
|
'length': 1,
|
||||||
'prototype': JSStringPrototype(),
|
'prototype': JSStringPrototype(),
|
||||||
@ -644,13 +683,52 @@ class JSString(JSObject):
|
|||||||
|
|
||||||
|
|
||||||
class JSBooleanPrototype(JSObjectPrototype):
|
class JSBooleanPrototype(JSObjectPrototype):
|
||||||
pass
|
|
||||||
|
def __init__(self, value=None):
|
||||||
|
if value is None:
|
||||||
|
# prototype
|
||||||
|
value = False
|
||||||
|
super(JSBooleanPrototype, self).__init__(value)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _constructor(value=None):
|
||||||
|
return JSBoolean.construct(value)
|
||||||
|
|
||||||
|
def _to_string(self):
|
||||||
|
# TODO find way to test it in other interpreters
|
||||||
|
if jstype(self) is _boolean_type:
|
||||||
|
b = self
|
||||||
|
elif jstype(self) is _object_type and self.jsclass == 'Boolean':
|
||||||
|
b = self.value
|
||||||
|
else:
|
||||||
|
raise Exception('TypeError')
|
||||||
|
return 'true' if b is true else 'false'
|
||||||
|
|
||||||
|
def _value_of(self):
|
||||||
|
return 'boolean value of'
|
||||||
|
|
||||||
|
jsclass = 'Boolean'
|
||||||
|
own = {
|
||||||
|
'constructor': _constructor,
|
||||||
|
'toString': _to_string,
|
||||||
|
'valueOf': _value_of
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
class JSBoolean(JSObject):
|
class JSBoolean(JSObject):
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def call(value=None):
|
||||||
|
return to_boolean(value)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def construct(value=None):
|
def construct(value=None):
|
||||||
pass
|
return JSBooleanPrototype(to_boolean(_to_js(value)))
|
||||||
|
|
||||||
|
name = JSBooleanPrototype.jsclass
|
||||||
|
own = {
|
||||||
|
'prototype': JSBooleanPrototype()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
class JSNumberPrototype(JSObjectPrototype):
|
class JSNumberPrototype(JSObjectPrototype):
|
||||||
@ -661,10 +739,10 @@ class JSNumber(JSObject):
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
undefined = object()
|
undefined = JSBase('undefined')
|
||||||
null = object()
|
null = JSBase('null')
|
||||||
true = JSBoolean.construct(True)
|
true = JSBooleanPrototype(True)
|
||||||
false = JSBoolean.construct(False)
|
false = JSBooleanPrototype(False)
|
||||||
|
|
||||||
_native_bool = bool
|
_native_bool = bool
|
||||||
_native_string = compat_str
|
_native_string = compat_str
|
||||||
|
Loading…
x
Reference in New Issue
Block a user