Path: blob/main/python/pylang/src/baselib/builtins.py
1398 views
# globals: exports, console, ρσ_iterator_symbol, ρσ_kwargs_symbol, ρσ_arraylike, ρσ_list_contains12def abs(a):3return r"%js (typeof a === 'object' && a.__abs__ !== undefined) ? a.__abs__() : Math.abs(a)"45def ρσ_operator_add(a, b):6return r"""%js (7typeof a !== 'object' ? a + b :8((a.__add__ !== undefined ? a.__add__(b) :9a.concat !== undefined ? a.concat(b) :10a + b)11)12)13"""1415def ρσ_operator_neg(a):16return v"(typeof a === 'object' && a.__neg__ !== undefined) ? a.__neg__() : (-a)"1718def ρσ_operator_sub(a, b):19return v"(typeof a === 'object' && a.__sub__ !== undefined) ? a.__sub__(b) : a - b"2021def ρσ_operator_mul(a, b):22return v"(typeof a === 'object' && a.__mul__ !== undefined) ? a.__mul__(b) : a * b"2324def ρσ_operator_div(a, b):25return v"(typeof a === 'object' && a.__div__ !== undefined) ? a.__div__(b) : a / b"2627def ρσ_operator_pow(a, b):28return v"(typeof a === 'object' && a.__pow__ !== undefined) ? a.__pow__(b) : a ** b"293031def ρσ_operator_iadd(a, b):32return v"(typeof a === 'object' && a.__iadd__ !== undefined) ? a.__iadd__(b) : ρσ_operator_add(a,b)"3334def ρσ_operator_isub(a, b):35return v"(typeof a === 'object' && a.__isub__ !== undefined) ? a.__isub__(b) : ρσ_operator_sub(a,b)"3637def ρσ_operator_imul(a, b):38return v"(typeof a === 'object' && a.__imul__ !== undefined) ? a.__imul__(b) : ρσ_operator_mul(a,b)"3940def ρσ_operator_idiv(a, b):41return v"(typeof a === 'object' && a.__idiv__ !== undefined) ? a.__idiv__(b) : ρσ_operator_div(a,b)"4243def ρσ_operator_ipow(a, b):44return v"(typeof a === 'object' && a.__ipow__ !== undefined) ? a.__ipow__(b) : ρσ_operator_pow(a,b)"454647def ρσ_operator_truediv(a, b):48return v"(typeof a === 'object' && a.__truediv__ !== undefined) ? a.__truediv__(b) : a / b"4950def ρσ_operator_floordiv(a, b):51return v"(typeof a === 'object' && a.__floordiv__ !== undefined) ? a.__floordiv__(b) : Math.floor(a / b)"5253def ρσ_bool(val):54return v'!!val'5556def ρσ_round(val):57# no attempt at Python semantics yet58return v"Math.round(val)"5960def ρσ_print():61if v'typeof console' is 'object':62parts = v'[]'63for v'var i = 0; i < arguments.length; i++':64parts.push(ρσ_str(arguments[i])) # noqa: undef65console.log(parts.join(' '))6667def ρσ_int(val, base):68if jstype(val) is "number":69ans = val | 070else:71ans = parseInt(val, base or 10)72if isNaN(ans):73raise ValueError('Invalid literal for int with base ' + (base or 10) + ': ' + val)74return ans7576def ρσ_float(val):77if jstype(val) is "number":78ans = val79else:80ans = parseFloat(val)81if isNaN(ans):82raise ValueError('Could not convert string to float: ' + arguments[0])83return ans8485def ρσ_arraylike_creator():86names = 'Int8Array Uint8Array Uint8ClampedArray Int16Array Uint16Array Int32Array Uint32Array Float32Array Float64Array'.split(' ')87if jstype(HTMLCollection) is 'function':88names = names.concat('HTMLCollection NodeList NamedNodeMap TouchList'.split(' '))89return def(x):90if Array.isArray(x) or v'typeof x' is 'string' or names.indexOf(Object.prototype.toString.call(x).slice(8, -1)) > -1:91return True92return False9394def options_object(f):95return def():96if v'typeof arguments[arguments.length - 1] === "object"':97arguments[arguments.length - 1][ρσ_kwargs_symbol] = True98return f.apply(this, arguments)99100def ρσ_id(x):101return x.ρσ_object_id102103def ρσ_dir(item):104# TODO: this isn't really representative of real Python's dir(), nor is it105# an intuitive replacement for "for ... in" loop, need to update this logic106# and introduce a different way of achieving "for ... in"107arr = []108for v'var i in item': arr.push(i) # noqa:undef109return arr110111def ρσ_ord(x):112ans = x.charCodeAt(0)113if 0xD800 <= ans <= 0xDBFF:114second = x.charCodeAt(1)115if 0xDC00 <= second <= 0xDFFF:116return (ans - 0xD800) * 0x400 + second - 0xDC00 + 0x10000117raise TypeError('string is missing the low surrogate char')118return ans119120def ρσ_chr(code):121if code <= 0xFFFF:122return String.fromCharCode(code)123code -= 0x10000124return String.fromCharCode(0xD800+(code>>10), 0xDC00+(code&0x3FF))125126def ρσ_callable(x):127return v'typeof x === "function"'128129def ρσ_bin(x):130if jstype(x) is not 'number' or x % 1 is not 0:131raise TypeError('integer required')132ans = x.toString(2)133if ans[0] is '-':134ans = '-' + '0b' + ans[1:]135else:136ans = '0b' + ans137return ans138139def ρσ_hex(x):140if jstype(x) is not 'number' or x % 1 is not 0:141raise TypeError('integer required')142ans = x.toString(16)143if ans[0] is '-':144ans = '-' + '0x' + ans[1:]145else:146ans = '0x' + ans147return ans148149def ρσ_enumerate(iterable):150ans = v'{"_i":-1}'151ans[ρσ_iterator_symbol] = def():152return this153if ρσ_arraylike(iterable):154ans['next'] = def():155this._i += 1156if this._i < iterable.length:157return v"{'done':false, 'value':[this._i, iterable[this._i]]}"158return v"{'done':true}"159return ans160if jstype(iterable[ρσ_iterator_symbol]) is 'function':161iterator = iterable.keys() if jstype(Map) is 'function' and v'iterable instanceof Map' else iterable[ρσ_iterator_symbol]()162ans['_iterator'] = iterator163ans['next'] = def():164r = this._iterator.next()165if r.done:166return v"{'done':true}"167this._i += 1168return v"{'done':false, 'value':[this._i, r.value]}"169return ans170return ρσ_enumerate(Object.keys(iterable))171172def ρσ_reversed(iterable):173if ρσ_arraylike(iterable):174ans = v'{"_i": iterable.length}'175ans['next'] = def():176this._i -= 1177if this._i > -1:178return v"{'done':false, 'value':iterable[this._i]}"179return v"{'done':true}"180ans[ρσ_iterator_symbol] = def():181return this182return ans183raise TypeError('reversed() can only be called on arrays or strings')184185def ρσ_iter(iterable):186# Generate a JavaScript iterator object from iterable187if jstype(iterable[ρσ_iterator_symbol]) is 'function':188return iterable.keys() if jstype(Map) is 'function' and v'iterable instanceof Map' else iterable[ρσ_iterator_symbol]()189if ρσ_arraylike(iterable):190ans = v'{"_i":-1}'191ans[ρσ_iterator_symbol] = def():192return this193ans['next'] = def():194this._i += 1195if this._i < iterable.length:196return v"{'done':false, 'value':iterable[this._i]}"197return v"{'done':true}"198return ans199return ρσ_iter(Object.keys(iterable))200201def ρσ_range_next(step, length):202this._i += step203this._idx += 1204if this._idx >= length:205this._i, this._idx = this.__i, -1206return v"{'done':true}"207return v"{'done':false, 'value':this._i}"208209def ρσ_range(start, stop, step):210if arguments.length <= 1:211stop = start or 0212start = 0213step = arguments[2] or 1214length = Math.max(Math.ceil((stop - start) / step), 0)215ans = v'{start:start, step:step, stop:stop}'216ans[ρσ_iterator_symbol] = def():217it = v'{"_i": start - step, "_idx": -1}'218it.next = ρσ_range_next.bind(it, step, length)219it[ρσ_iterator_symbol] = def():220return this221return it222ans.count = def(val):223if not this._cached:224this._cached = list(this)225return this._cached.count(val)226ans.index = def(val):227if not this._cached:228this._cached = list(this)229return this._cached.index(val)230231def slice(new_start=undefined, new_stop=undefined):232if step < 0:233if new_start is undefined and new_stop is undefined:234return ans235# I'm too lazy to do this directly, so just fallback for now.236return list(ans)[new_start:new_stop]237238if new_start is undefined:239if new_stop is undefined:240return ans241else:242if new_stop < 0:243new_stop = (length + new_stop);244return ρσ_range(start, Math.max(start, Math.min(new_stop*step+start, stop)), step)245if new_stop is undefined:246if new_start < 0:247new_start = (length + new_start);248return ρσ_range(Math.min(stop, Math.max(new_start*step+start, start)), stop, step)249else:250if new_stop < 0:251new_stop = (length + new_stop);252if new_start < 0:253new_start = (length + new_start);254return ρσ_range(Math.min(new_stop*step, Math.max(new_start*step+start, start)), Math.max(new_start*step+start, Math.min(new_stop*step+start, stop)), step)255ans.slice = slice;256257# ans.__getitem__258259ans.__len__ = def():260return length261ans.__repr__ = def():262if step == 1:263return f'range({start}, {stop})'264else:265return f'range({start}, {stop}, {step})'266ans.__str__ = ans.toString = ans.__repr__267if jstype(Proxy) is 'function':268ans = new Proxy(ans, {269'get': def(obj, prop):270if jstype(prop) is 'string':271iprop = parseInt(prop)272if not isNaN(iprop):273prop = iprop274if jstype(prop) is 'number':275if not obj._cached:276obj._cached = list(obj)277return obj._cached[prop]278return obj[prop]279})280return ans281282def ρσ_getattr(obj, name, defval):283try:284ret = obj[name]285except TypeError:286if defval is undefined:287raise AttributeError('The attribute ' + name + ' is not present')288return defval289if ret is undefined and not v'(name in obj)':290if defval is undefined:291raise AttributeError('The attribute ' + name + ' is not present')292ret = defval293return ret294295def ρσ_setattr(obj, name, value):296obj[name] = value297298def ρσ_hasattr(obj, name):299return v'name in obj'300301ρσ_len = (def ():302303def len(obj):304if ρσ_arraylike(obj): return obj.length305if jstype(obj.__len__) is 'function': return obj.__len__()306if v'obj instanceof Set' or v'obj instanceof Map': return obj.size307return Object.keys(obj).length308309def len5(obj):310if ρσ_arraylike(obj): return obj.length311if jstype(obj.__len__) is 'function': return obj.__len__()312return Object.keys(obj).length313314return len if v'typeof Set' is 'function' and v'typeof Map' is 'function' else len5315)()316317def ρσ_get_module(name):318return ρσ_modules[name]319320def ρσ_pow(x, y, z):321ans = Math.pow(x, y)322if z is not undefined:323ans %= z324return ans325326def ρσ_type(x):327return x.constructor328329330def ρσ_divmod(x, y):331if y is 0:332raise ZeroDivisionError('integer division or modulo by zero')333d = Math.floor(x / y)334return d, x - d * y335336337def ρσ_max(*args, **kwargs):338if args.length is 0:339if kwargs.defval is not undefined:340return kwargs.defval341raise TypeError('expected at least one argument')342if args.length is 1:343args = args[0]344if kwargs.key:345args = [kwargs.key(x) for x in args]346if not Array.isArray(args):347args = list(args)348if args.length:349return this.apply(None, args)350if kwargs.defval is not undefined:351return kwargs.defval352raise TypeError('expected at least one argument')353354v'var round = ρσ_round; var max = ρσ_max.bind(Math.max), min = ρσ_max.bind(Math.min), bool = ρσ_bool, type = ρσ_type'355v'var float = ρσ_float, int = ρσ_int, arraylike = ρσ_arraylike_creator(), ρσ_arraylike = arraylike'356v'var print = ρσ_print, id = ρσ_id, get_module = ρσ_get_module, pow = ρσ_pow, divmod = ρσ_divmod'357v'var dir = ρσ_dir, ord = ρσ_ord, chr = ρσ_chr, bin = ρσ_bin, hex = ρσ_hex, callable = ρσ_callable'358v'var enumerate = ρσ_enumerate, iter = ρσ_iter, reversed = ρσ_reversed, len = ρσ_len'359v'var range = ρσ_range, getattr = ρσ_getattr, setattr = ρσ_setattr, hasattr = ρσ_hasattr'360361362