rapydscript-ns 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.agignore +1 -0
- package/.gitattributes +4 -0
- package/.github/workflows/ci.yml +38 -0
- package/.github/workflows/web-repl-page-deploy.yml +42 -0
- package/=template.pyj +5 -0
- package/CHANGELOG.md +456 -0
- package/CONTRIBUTORS +13 -0
- package/HACKING.md +103 -0
- package/LICENSE +24 -0
- package/README.md +2512 -0
- package/TODO.md +327 -0
- package/add-toc-to-readme +2 -0
- package/bin/export +75 -0
- package/bin/rapydscript +70 -0
- package/bin/web-repl-export +102 -0
- package/build +3 -0
- package/package.json +46 -0
- package/publish.py +37 -0
- package/release/baselib-plain-pretty.js +4370 -0
- package/release/baselib-plain-ugly.js +3 -0
- package/release/compiler.js +18394 -0
- package/release/signatures.json +31 -0
- package/session.vim +4 -0
- package/setup.cfg +2 -0
- package/src/ast.pyj +1356 -0
- package/src/baselib-builtins.pyj +279 -0
- package/src/baselib-containers.pyj +723 -0
- package/src/baselib-errors.pyj +37 -0
- package/src/baselib-internal.pyj +421 -0
- package/src/baselib-itertools.pyj +97 -0
- package/src/baselib-str.pyj +798 -0
- package/src/compiler.pyj +36 -0
- package/src/errors.pyj +30 -0
- package/src/lib/aes.pyj +646 -0
- package/src/lib/collections.pyj +695 -0
- package/src/lib/elementmaker.pyj +83 -0
- package/src/lib/encodings.pyj +126 -0
- package/src/lib/functools.pyj +148 -0
- package/src/lib/gettext.pyj +569 -0
- package/src/lib/itertools.pyj +580 -0
- package/src/lib/math.pyj +193 -0
- package/src/lib/numpy.pyj +2101 -0
- package/src/lib/operator.pyj +11 -0
- package/src/lib/pythonize.pyj +20 -0
- package/src/lib/random.pyj +118 -0
- package/src/lib/re.pyj +470 -0
- package/src/lib/traceback.pyj +63 -0
- package/src/lib/uuid.pyj +77 -0
- package/src/monaco-language-service/analyzer.js +526 -0
- package/src/monaco-language-service/builtins.js +543 -0
- package/src/monaco-language-service/completions.js +498 -0
- package/src/monaco-language-service/diagnostics.js +643 -0
- package/src/monaco-language-service/dts.js +550 -0
- package/src/monaco-language-service/hover.js +121 -0
- package/src/monaco-language-service/index.js +386 -0
- package/src/monaco-language-service/scope.js +162 -0
- package/src/monaco-language-service/signature.js +144 -0
- package/src/output/__init__.pyj +0 -0
- package/src/output/classes.pyj +296 -0
- package/src/output/codegen.pyj +492 -0
- package/src/output/comments.pyj +45 -0
- package/src/output/exceptions.pyj +105 -0
- package/src/output/functions.pyj +491 -0
- package/src/output/literals.pyj +109 -0
- package/src/output/loops.pyj +444 -0
- package/src/output/modules.pyj +329 -0
- package/src/output/operators.pyj +429 -0
- package/src/output/statements.pyj +463 -0
- package/src/output/stream.pyj +309 -0
- package/src/output/treeshake.pyj +182 -0
- package/src/output/utils.pyj +72 -0
- package/src/parse.pyj +3106 -0
- package/src/string_interpolation.pyj +72 -0
- package/src/tokenizer.pyj +702 -0
- package/src/unicode_aliases.pyj +576 -0
- package/src/utils.pyj +192 -0
- package/test/_import_one.pyj +37 -0
- package/test/_import_two/__init__.pyj +11 -0
- package/test/_import_two/level2/__init__.pyj +0 -0
- package/test/_import_two/level2/deep.pyj +4 -0
- package/test/_import_two/other.pyj +6 -0
- package/test/_import_two/sub.pyj +13 -0
- package/test/aes_vectors.pyj +421 -0
- package/test/annotations.pyj +80 -0
- package/test/baselib.pyj +319 -0
- package/test/classes.pyj +452 -0
- package/test/collections.pyj +152 -0
- package/test/decorators.pyj +77 -0
- package/test/dict_spread.pyj +76 -0
- package/test/docstrings.pyj +39 -0
- package/test/elementmaker_test.pyj +45 -0
- package/test/ellipsis.pyj +49 -0
- package/test/functions.pyj +151 -0
- package/test/generators.pyj +41 -0
- package/test/generic.pyj +370 -0
- package/test/imports.pyj +72 -0
- package/test/internationalization.pyj +73 -0
- package/test/lint.pyj +164 -0
- package/test/loops.pyj +85 -0
- package/test/numpy.pyj +734 -0
- package/test/omit_function_metadata.pyj +20 -0
- package/test/regexp.pyj +55 -0
- package/test/repl.pyj +121 -0
- package/test/scoped_flags.pyj +76 -0
- package/test/starargs.pyj +506 -0
- package/test/starred_assign.pyj +104 -0
- package/test/str.pyj +198 -0
- package/test/subscript_tuple.pyj +53 -0
- package/test/unit/fixtures/fibonacci_expected.js +46 -0
- package/test/unit/index.js +2989 -0
- package/test/unit/language-service-builtins.js +815 -0
- package/test/unit/language-service-completions.js +1067 -0
- package/test/unit/language-service-dts.js +543 -0
- package/test/unit/language-service-hover.js +455 -0
- package/test/unit/language-service-scope.js +833 -0
- package/test/unit/language-service-signature.js +458 -0
- package/test/unit/language-service.js +705 -0
- package/test/unit/run-language-service.js +41 -0
- package/test/unit/web-repl.js +484 -0
- package/tools/build-language-service.js +190 -0
- package/tools/cli.js +547 -0
- package/tools/compile.js +219 -0
- package/tools/compiler.js +108 -0
- package/tools/completer.js +131 -0
- package/tools/embedded_compiler.js +251 -0
- package/tools/export.js +316 -0
- package/tools/gettext.js +185 -0
- package/tools/ini.js +65 -0
- package/tools/lint.js +705 -0
- package/tools/msgfmt.js +187 -0
- package/tools/repl.js +223 -0
- package/tools/self.js +162 -0
- package/tools/test.js +118 -0
- package/tools/utils.js +128 -0
- package/tools/web_repl.js +95 -0
- package/try +41 -0
- package/web-repl/env.js +74 -0
- package/web-repl/index.html +163 -0
- package/web-repl/language-service.js +4084 -0
- package/web-repl/main.js +254 -0
- package/web-repl/prism.css +139 -0
- package/web-repl/prism.js +113 -0
- package/web-repl/rapydscript.js +435 -0
- package/web-repl/sha1.js +25 -0
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
# vim:fileencoding=utf-8
|
|
2
|
+
# License: GPL v3 Copyright: 2015, Kovid Goyal <kovid at kovidgoyal.net>
|
|
3
|
+
|
|
4
|
+
html_elements = {
|
|
5
|
+
'a', 'abbr', 'acronym', 'address', 'area',
|
|
6
|
+
'article', 'aside', 'audio', 'b', 'base', 'big', 'body', 'blockquote', 'br', 'button',
|
|
7
|
+
'canvas', 'caption', 'center', 'cite', 'code', 'col', 'colgroup',
|
|
8
|
+
'command', 'datagrid', 'datalist', 'dd', 'del', 'details', 'dfn',
|
|
9
|
+
'dialog', 'dir', 'div', 'dl', 'dt', 'em', 'event-source', 'fieldset',
|
|
10
|
+
'figcaption', 'figure', 'footer', 'font', 'form', 'header', 'h1',
|
|
11
|
+
'h2', 'h3', 'h4', 'h5', 'h6', 'hr', 'head', 'i', 'iframe', 'img', 'input', 'ins',
|
|
12
|
+
'keygen', 'kbd', 'label', 'legend', 'li', 'm', 'map', 'menu', 'meter',
|
|
13
|
+
'multicol', 'nav', 'nextid', 'ol', 'output', 'optgroup', 'option',
|
|
14
|
+
'p', 'pre', 'progress', 'q', 's', 'samp', 'script', 'section', 'select',
|
|
15
|
+
'small', 'sound', 'source', 'spacer', 'span', 'strike', 'strong', 'style',
|
|
16
|
+
'sub', 'sup', 'table', 'tbody', 'td', 'textarea', 'time', 'tfoot',
|
|
17
|
+
'th', 'thead', 'tr', 'tt', 'u', 'ul', 'var', 'video'
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
mathml_elements = {
|
|
21
|
+
'maction', 'math', 'merror', 'mfrac', 'mi',
|
|
22
|
+
'mmultiscripts', 'mn', 'mo', 'mover', 'mpadded', 'mphantom',
|
|
23
|
+
'mprescripts', 'mroot', 'mrow', 'mspace', 'msqrt', 'mstyle', 'msub',
|
|
24
|
+
'msubsup', 'msup', 'mtable', 'mtd', 'mtext', 'mtr', 'munder',
|
|
25
|
+
'munderover', 'none'
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
svg_elements = {
|
|
29
|
+
'a', 'animate', 'animateColor', 'animateMotion',
|
|
30
|
+
'animateTransform', 'clipPath', 'circle', 'defs', 'desc', 'ellipse',
|
|
31
|
+
'font-face', 'font-face-name', 'font-face-src', 'g', 'glyph', 'hkern',
|
|
32
|
+
'linearGradient', 'line', 'marker', 'metadata', 'missing-glyph',
|
|
33
|
+
'mpath', 'path', 'polygon', 'polyline', 'radialGradient', 'rect',
|
|
34
|
+
'set', 'stop', 'svg', 'switch', 'text', 'title', 'tspan', 'use'
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
html5_tags = html_elements.union(mathml_elements).union(svg_elements)
|
|
38
|
+
|
|
39
|
+
def _makeelement(tag, *args, **kwargs):
|
|
40
|
+
ans = this.createElement(tag)
|
|
41
|
+
|
|
42
|
+
for attr in kwargs:
|
|
43
|
+
vattr = str.replace(str.rstrip(attr, '_'), '_', '-')
|
|
44
|
+
val = kwargs[attr]
|
|
45
|
+
if callable(val):
|
|
46
|
+
if str.startswith(attr, 'on'):
|
|
47
|
+
attr = attr[2:]
|
|
48
|
+
ans.addEventListener(attr, val)
|
|
49
|
+
elif val is True:
|
|
50
|
+
ans.setAttribute(vattr, vattr)
|
|
51
|
+
elif jstype(val) is 'string':
|
|
52
|
+
ans.setAttribute(vattr, val)
|
|
53
|
+
|
|
54
|
+
for arg in args:
|
|
55
|
+
if jstype(arg) is 'string':
|
|
56
|
+
arg = this.createTextNode(arg)
|
|
57
|
+
ans.appendChild(arg)
|
|
58
|
+
return ans
|
|
59
|
+
|
|
60
|
+
def maker_for_document(document):
|
|
61
|
+
# Create an elementmaker to be used with the specified document
|
|
62
|
+
E = _makeelement.bind(document)
|
|
63
|
+
Object.defineProperties(E, {
|
|
64
|
+
tag: {
|
|
65
|
+
'value':_makeelement.bind(document, tag)
|
|
66
|
+
} for tag in html5_tags
|
|
67
|
+
})
|
|
68
|
+
return E
|
|
69
|
+
|
|
70
|
+
if jstype(document) is 'undefined':
|
|
71
|
+
E = maker_for_document({
|
|
72
|
+
'createTextNode': def(value): return value;,
|
|
73
|
+
'createElement': def(name):
|
|
74
|
+
return {
|
|
75
|
+
'name':name,
|
|
76
|
+
'children':[],
|
|
77
|
+
'attributes':{},
|
|
78
|
+
'setAttribute': def(name, val): this.attributes[name] = val;,
|
|
79
|
+
'appendChild': def(child): this.children.push(child);,
|
|
80
|
+
}
|
|
81
|
+
})
|
|
82
|
+
else:
|
|
83
|
+
E = maker_for_document(document)
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
# vim:fileencoding=utf-8
|
|
2
|
+
# License: BSD Copyright: 2016, Kovid Goyal <kovid at kovidgoyal.net>
|
|
3
|
+
|
|
4
|
+
def base64encode(bytes, altchars, pad_char):
|
|
5
|
+
# Convert an array of bytes into a base-64 encoded string
|
|
6
|
+
l = bytes.length
|
|
7
|
+
remainder = l % 3
|
|
8
|
+
main_length = l - remainder
|
|
9
|
+
encodings = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789' + (altchars or '+/')
|
|
10
|
+
pad_char = '=' if pad_char is undefined else pad_char
|
|
11
|
+
ans = v'[]'
|
|
12
|
+
for v'var i = 0; i < main_length; i += 3':
|
|
13
|
+
chunk = (bytes[i] << 16) | (bytes[i + 1] << 8) | bytes[i + 2]
|
|
14
|
+
ans.push(encodings[(chunk & 16515072) >> 18], encodings[(chunk & 258048) >> 12], encodings[(chunk & 4032) >> 6], encodings[chunk & 63])
|
|
15
|
+
if remainder is 1:
|
|
16
|
+
chunk = bytes[main_length]
|
|
17
|
+
ans.push(encodings[(chunk & 252) >> 2], encodings[(chunk & 3) << 4], pad_char, pad_char)
|
|
18
|
+
elif remainder is 2:
|
|
19
|
+
chunk = (bytes[main_length] << 8) | bytes[main_length + 1]
|
|
20
|
+
ans.push(encodings[(chunk & 64512) >> 10], encodings[(chunk & 1008) >> 4], encodings[(chunk & 15) << 2], pad_char)
|
|
21
|
+
return ans.join('')
|
|
22
|
+
|
|
23
|
+
def base64decode(string):
|
|
24
|
+
# convert the output of base64encode back into an array of bytes
|
|
25
|
+
# (Uint8Array) only works with the standard altchars and pad_char
|
|
26
|
+
if jstype(window) is not 'undefined':
|
|
27
|
+
chars = window.atob(string)
|
|
28
|
+
else:
|
|
29
|
+
chars = new Buffer(string, 'base64').toString('binary') # noqa: undef
|
|
30
|
+
ans = Uint8Array(chars.length)
|
|
31
|
+
for i in range(ans.length):
|
|
32
|
+
ans[i] = chars.charCodeAt(i)
|
|
33
|
+
return ans
|
|
34
|
+
|
|
35
|
+
def urlsafe_b64encode(bytes, pad_char):
|
|
36
|
+
return base64encode(bytes, '-_', pad_char)
|
|
37
|
+
|
|
38
|
+
def urlsafe_b64decode(string):
|
|
39
|
+
string = String.prototype.replace.call(string, /[_-]/g, def(m): return '+' if m is '-' else '/';)
|
|
40
|
+
return base64decode(string)
|
|
41
|
+
|
|
42
|
+
def hexlify(bytes):
|
|
43
|
+
ans = v'[]'
|
|
44
|
+
for v'var i = 0; i < bytes.length; i++':
|
|
45
|
+
x = bytes[i].toString(16)
|
|
46
|
+
if x.length is 1:
|
|
47
|
+
x = '0' + x
|
|
48
|
+
ans.push(x)
|
|
49
|
+
return ans.join('')
|
|
50
|
+
|
|
51
|
+
def unhexlify(string):
|
|
52
|
+
num = string.length // 2
|
|
53
|
+
if num * 2 is not string.length:
|
|
54
|
+
raise ValueError('string length is not a multiple of two')
|
|
55
|
+
ans = Uint8Array(num)
|
|
56
|
+
for v'var i = 0; i < num; i++':
|
|
57
|
+
x = parseInt(string[i*2:i*2+2], 16)
|
|
58
|
+
if isNaN(x):
|
|
59
|
+
raise ValueError('string is not hex-encoded')
|
|
60
|
+
ans[i] = x
|
|
61
|
+
return ans
|
|
62
|
+
|
|
63
|
+
utf8_decoder_table = v'''[
|
|
64
|
+
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 00..1f
|
|
65
|
+
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 20..3f
|
|
66
|
+
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 40..5f
|
|
67
|
+
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 60..7f
|
|
68
|
+
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, // 80..9f
|
|
69
|
+
7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, // a0..bf
|
|
70
|
+
8,8,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, // c0..df
|
|
71
|
+
0xa,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x4,0x3,0x3, // e0..ef
|
|
72
|
+
0xb,0x6,0x6,0x6,0x5,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8, // f0..ff
|
|
73
|
+
0x0,0x1,0x2,0x3,0x5,0x8,0x7,0x1,0x1,0x1,0x4,0x6,0x1,0x1,0x1,0x1, // s0..s0
|
|
74
|
+
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,0,1,0,1,1,1,1,1,1, // s1..s2
|
|
75
|
+
1,2,1,1,1,1,1,2,1,2,1,1,1,1,1,1,1,1,1,1,1,1,1,2,1,1,1,1,1,1,1,1, // s3..s4
|
|
76
|
+
1,2,1,1,1,1,1,1,1,2,1,1,1,1,1,1,1,1,1,1,1,1,1,3,1,3,1,1,1,1,1,1, // s5..s6
|
|
77
|
+
1,3,1,1,1,1,1,3,1,3,1,1,1,1,1,1,1,3,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // s7..s8
|
|
78
|
+
]'''
|
|
79
|
+
|
|
80
|
+
def _from_code_point(x):
|
|
81
|
+
if x <= 0xFFFF:
|
|
82
|
+
return String.fromCharCode(x)
|
|
83
|
+
x -= 0x10000
|
|
84
|
+
return String.fromCharCode((x >> 10) + 0xD800, (x % 0x400) + 0xDC00)
|
|
85
|
+
|
|
86
|
+
def utf8_decode(bytes, errors, replacement):
|
|
87
|
+
# Convert an array of UTF-8 encoded bytes into a string
|
|
88
|
+
state = 0
|
|
89
|
+
ans = v'[]'
|
|
90
|
+
|
|
91
|
+
for v'var i = 0, l = bytes.length; i < l; i++': # noqa
|
|
92
|
+
byte = bytes[i]
|
|
93
|
+
typ = utf8_decoder_table[byte]
|
|
94
|
+
codep = (byte & 0x3f) | (codep << 6) if state is not 0 else (0xff >> typ) & (byte)
|
|
95
|
+
state = utf8_decoder_table[256 + state*16 + typ]
|
|
96
|
+
if state is 0:
|
|
97
|
+
ans.push(_from_code_point(codep))
|
|
98
|
+
elif state is 1:
|
|
99
|
+
if not errors or errors is 'strict':
|
|
100
|
+
raise UnicodeDecodeError(str.format('The byte 0x{:02x} at position {} is not valid UTF-8', byte, i))
|
|
101
|
+
elif errors is 'replace':
|
|
102
|
+
ans.push(replacement or '?')
|
|
103
|
+
return ans.join('')
|
|
104
|
+
|
|
105
|
+
def utf8_encode_js(string):
|
|
106
|
+
# Encode a string as an array of UTF-8 bytes
|
|
107
|
+
escstr = encodeURIComponent(string)
|
|
108
|
+
ans = v'[]'
|
|
109
|
+
for v'var i = 0; i < escstr.length; i++':
|
|
110
|
+
ch = escstr[i]
|
|
111
|
+
if ch is '%':
|
|
112
|
+
ans.push(parseInt(escstr[i+1:i+3], 16))
|
|
113
|
+
i += 2
|
|
114
|
+
else:
|
|
115
|
+
ans.push(ch.charCodeAt(0))
|
|
116
|
+
return Uint8Array(ans)
|
|
117
|
+
|
|
118
|
+
if jstype(TextEncoder) is 'function':
|
|
119
|
+
_u8enc = TextEncoder('utf-8')
|
|
120
|
+
utf8_encode = _u8enc.encode.bind(_u8enc)
|
|
121
|
+
_u8enc = undefined
|
|
122
|
+
else:
|
|
123
|
+
utf8_encode = utf8_encode_js
|
|
124
|
+
|
|
125
|
+
def utf8_encode_native(string):
|
|
126
|
+
return _u8enc.encode(string)
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
# vim:fileencoding=utf-8
|
|
2
|
+
# License: BSD
|
|
3
|
+
# RapydScript implementation of Python's functools standard library.
|
|
4
|
+
#
|
|
5
|
+
# Supported: reduce, partial, wraps, lru_cache, cache, total_ordering, cmp_to_key
|
|
6
|
+
|
|
7
|
+
def reduce(func, iterable, *rest):
|
|
8
|
+
"""Apply func cumulatively to items of iterable, from left to right."""
|
|
9
|
+
it = iter(iterable)
|
|
10
|
+
r = it.next()
|
|
11
|
+
if len(rest) == 0:
|
|
12
|
+
if r.done:
|
|
13
|
+
raise TypeError('reduce() of empty sequence with no initial value')
|
|
14
|
+
value = r.value
|
|
15
|
+
r = it.next()
|
|
16
|
+
else:
|
|
17
|
+
value = rest[0]
|
|
18
|
+
while not r.done:
|
|
19
|
+
value = func(value, r.value)
|
|
20
|
+
r = it.next()
|
|
21
|
+
return value
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def partial(func, *args, **kwargs):
|
|
25
|
+
"""Return a new function with partial application of args and kwargs."""
|
|
26
|
+
stored_args = args
|
|
27
|
+
stored_kwargs = kwargs
|
|
28
|
+
def wrapper(*more_args, **more_kwargs):
|
|
29
|
+
return func(*stored_args.concat(more_args), **stored_kwargs, **more_kwargs)
|
|
30
|
+
wrapper.func = func
|
|
31
|
+
wrapper.args = stored_args
|
|
32
|
+
wrapper.keywords = stored_kwargs
|
|
33
|
+
return wrapper
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def wraps(wrapped):
|
|
37
|
+
"""Decorator factory: copy metadata from wrapped onto the wrapper function."""
|
|
38
|
+
def decorator(wrapper):
|
|
39
|
+
wrapper.__name__ = wrapped.name or wrapped.__name__
|
|
40
|
+
wrapper.__doc__ = wrapped.__doc__
|
|
41
|
+
wrapper.__wrapped__ = wrapped
|
|
42
|
+
return wrapper
|
|
43
|
+
return decorator
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
def _make_lru_cached(func, maxsize):
|
|
47
|
+
state = v"{'cache': new Map(), 'order': [], 'hits': 0, 'misses': 0}"
|
|
48
|
+
def wrapper(*args):
|
|
49
|
+
key = JSON.stringify(args)
|
|
50
|
+
if state.cache.has(key):
|
|
51
|
+
state.hits += 1
|
|
52
|
+
return state.cache.get(key)
|
|
53
|
+
state.misses += 1
|
|
54
|
+
result = func(*args)
|
|
55
|
+
if maxsize is None or state.order.length < maxsize:
|
|
56
|
+
state.cache.set(key, result)
|
|
57
|
+
state.order.push(key)
|
|
58
|
+
elif maxsize > 0:
|
|
59
|
+
old = state.order.shift()
|
|
60
|
+
state.cache.delete(old)
|
|
61
|
+
state.cache.set(key, result)
|
|
62
|
+
state.order.push(key)
|
|
63
|
+
return result
|
|
64
|
+
def cache_clear():
|
|
65
|
+
v'state.cache.clear(); state.order.length = 0;'
|
|
66
|
+
state.hits = 0
|
|
67
|
+
state.misses = 0
|
|
68
|
+
wrapper.cache_clear = cache_clear
|
|
69
|
+
wrapper.cache_info = def():
|
|
70
|
+
return {'hits': state.hits, 'misses': state.misses,
|
|
71
|
+
'maxsize': maxsize, 'currsize': state.cache.size}
|
|
72
|
+
wrapper.__wrapped__ = func
|
|
73
|
+
return wrapper
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
def lru_cache(maxsize=128):
|
|
77
|
+
"""Memoizing decorator. Use as @lru_cache or @lru_cache(maxsize=N)."""
|
|
78
|
+
if callable(maxsize):
|
|
79
|
+
return _make_lru_cached(maxsize, 128)
|
|
80
|
+
def decorator(func):
|
|
81
|
+
return _make_lru_cached(func, maxsize)
|
|
82
|
+
return decorator
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
def cache(func):
|
|
86
|
+
"""Simple unbounded memoizing decorator (equivalent to lru_cache(maxsize=None))."""
|
|
87
|
+
return _make_lru_cached(func, None)
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
def total_ordering(cls):
|
|
91
|
+
"""Class decorator that fills in missing ordering methods from one root method."""
|
|
92
|
+
p = cls.prototype
|
|
93
|
+
has_eq = jstype(p.__eq__) is 'function'
|
|
94
|
+
if jstype(p.__lt__) is 'function':
|
|
95
|
+
if jstype(p.__gt__) is not 'function':
|
|
96
|
+
p.__gt__ = v'function(other) { return other.__lt__(this); }'
|
|
97
|
+
if jstype(p.__le__) is not 'function':
|
|
98
|
+
if has_eq:
|
|
99
|
+
p.__le__ = v'function(other) { return this.__lt__(other) || this.__eq__(other); }'
|
|
100
|
+
else:
|
|
101
|
+
p.__le__ = v'function(other) { return this.__lt__(other) || this === other; }'
|
|
102
|
+
if jstype(p.__ge__) is not 'function':
|
|
103
|
+
p.__ge__ = v'function(other) { return !this.__lt__(other); }'
|
|
104
|
+
elif jstype(p.__gt__) is 'function':
|
|
105
|
+
if jstype(p.__lt__) is not 'function':
|
|
106
|
+
p.__lt__ = v'function(other) { return other.__gt__(this); }'
|
|
107
|
+
if jstype(p.__ge__) is not 'function':
|
|
108
|
+
if has_eq:
|
|
109
|
+
p.__ge__ = v'function(other) { return this.__gt__(other) || this.__eq__(other); }'
|
|
110
|
+
else:
|
|
111
|
+
p.__ge__ = v'function(other) { return this.__gt__(other) || this === other; }'
|
|
112
|
+
if jstype(p.__le__) is not 'function':
|
|
113
|
+
p.__le__ = v'function(other) { return !this.__gt__(other); }'
|
|
114
|
+
elif jstype(p.__le__) is 'function':
|
|
115
|
+
if jstype(p.__ge__) is not 'function':
|
|
116
|
+
p.__ge__ = v'function(other) { return other.__le__(this); }'
|
|
117
|
+
if jstype(p.__lt__) is not 'function':
|
|
118
|
+
if has_eq:
|
|
119
|
+
p.__lt__ = v'function(other) { return this.__le__(other) && !this.__eq__(other); }'
|
|
120
|
+
else:
|
|
121
|
+
p.__lt__ = v'function(other) { return this.__le__(other) && this !== other; }'
|
|
122
|
+
if jstype(p.__gt__) is not 'function':
|
|
123
|
+
p.__gt__ = v'function(other) { return !this.__le__(other); }'
|
|
124
|
+
elif jstype(p.__ge__) is 'function':
|
|
125
|
+
if jstype(p.__le__) is not 'function':
|
|
126
|
+
p.__le__ = v'function(other) { return other.__ge__(this); }'
|
|
127
|
+
if jstype(p.__gt__) is not 'function':
|
|
128
|
+
if has_eq:
|
|
129
|
+
p.__gt__ = v'function(other) { return this.__ge__(other) && !this.__eq__(other); }'
|
|
130
|
+
else:
|
|
131
|
+
p.__gt__ = v'function(other) { return this.__ge__(other) && this !== other; }'
|
|
132
|
+
if jstype(p.__lt__) is not 'function':
|
|
133
|
+
p.__lt__ = v'function(other) { return !this.__ge__(other); }'
|
|
134
|
+
return cls
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
def cmp_to_key(mycmp):
|
|
138
|
+
"""Convert a comparison function (returning negative/zero/positive) to a key class."""
|
|
139
|
+
v"""var K = function K(obj) {
|
|
140
|
+
if (!(this instanceof K)) return new K(obj);
|
|
141
|
+
this.obj = obj;
|
|
142
|
+
};
|
|
143
|
+
K.prototype.__lt__ = function(other) { return mycmp(this.obj, other.obj) < 0; };
|
|
144
|
+
K.prototype.__gt__ = function(other) { return mycmp(this.obj, other.obj) > 0; };
|
|
145
|
+
K.prototype.__eq__ = function(other) { return mycmp(this.obj, other.obj) === 0; };
|
|
146
|
+
K.prototype.__le__ = function(other) { return mycmp(this.obj, other.obj) <= 0; };
|
|
147
|
+
K.prototype.__ge__ = function(other) { return mycmp(this.obj, other.obj) >= 0; };"""
|
|
148
|
+
return K
|