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,798 @@
|
|
|
1
|
+
# vim:fileencoding=utf-8
|
|
2
|
+
# License: BSD
|
|
3
|
+
# Copyright: 2015, Kovid Goyal <kovid at kovidgoyal.net>
|
|
4
|
+
|
|
5
|
+
# globals: ρσ_kwargs_symbol, ρσ_list_decorate, ρσ_iterator_symbol, HTMLElement
|
|
6
|
+
|
|
7
|
+
# Locale can’t be changed in-flight, so we just retrieve this once.
|
|
8
|
+
# Sadly older node versions (< 8) don’t support formatToParts
|
|
9
|
+
# decimal_sep = Intl.NumberFormat() \
|
|
10
|
+
# .formatToParts(1.1) \
|
|
11
|
+
# .find(def(part): return part.type == 'decimal';) \
|
|
12
|
+
# .value
|
|
13
|
+
decimal_sep = (1.1).toLocaleString()[1]
|
|
14
|
+
|
|
15
|
+
def ρσ_repr_js_builtin(x, as_array):
|
|
16
|
+
ans = v'[]'
|
|
17
|
+
b = '{}'
|
|
18
|
+
if as_array:
|
|
19
|
+
b = '[]'
|
|
20
|
+
for v'var i = 0; i < x.length; i++':
|
|
21
|
+
ans.push(ρσ_repr(x[i]))
|
|
22
|
+
else:
|
|
23
|
+
keys = Object.keys(x)
|
|
24
|
+
for v'var k = 0; k < keys.length; k++':
|
|
25
|
+
key = keys[k]
|
|
26
|
+
ans.push(JSON.stringify(key) + ':' + ρσ_repr(x[key]))
|
|
27
|
+
return b[0] + ans.join(', ') + b[1]
|
|
28
|
+
|
|
29
|
+
def ρσ_html_element_to_string(elem):
|
|
30
|
+
attrs = v'[]'
|
|
31
|
+
for attr in elem.attributes:
|
|
32
|
+
if attr.specified:
|
|
33
|
+
val = attr.value
|
|
34
|
+
if val.length > 10:
|
|
35
|
+
val = val[:15] + '...'
|
|
36
|
+
val = JSON.stringify(val)
|
|
37
|
+
attrs.push(f'{attr.name}={val}')
|
|
38
|
+
attrs = (' ' + attrs.join(' ')) if attrs.length else ''
|
|
39
|
+
ans = f'<{elem.tagName}{attrs}>'
|
|
40
|
+
return ans
|
|
41
|
+
|
|
42
|
+
def ρσ_repr(x):
|
|
43
|
+
if x is None:
|
|
44
|
+
return 'None'
|
|
45
|
+
if x is undefined:
|
|
46
|
+
return 'undefined'
|
|
47
|
+
ans = x
|
|
48
|
+
if v'typeof x.__repr__ === "function"':
|
|
49
|
+
ans = x.__repr__()
|
|
50
|
+
elif x is True or x is False:
|
|
51
|
+
ans = 'True' if x else 'False'
|
|
52
|
+
elif Array.isArray(x):
|
|
53
|
+
ans = ρσ_repr_js_builtin(x, True)
|
|
54
|
+
elif jstype(x) is 'function':
|
|
55
|
+
ans = x.toString()
|
|
56
|
+
elif jstype(x) is 'object' and not x.toString:
|
|
57
|
+
# Assume this is a dictionary
|
|
58
|
+
ans = ρσ_repr_js_builtin(x)
|
|
59
|
+
else:
|
|
60
|
+
name = Object.prototype.toString.call(x).slice(8, -1)
|
|
61
|
+
if "Int8Array Uint8Array Uint8ClampedArray Int16Array Uint16Array Int32Array Uint32Array Float32Array Float64Array".indexOf(name) != -1:
|
|
62
|
+
return name + '([' + x.map(def(i): return str.format('0x{:02x}', i);).join(', ') + '])'
|
|
63
|
+
if jstype(HTMLElement) is not 'undefined' and v'x instanceof HTMLElement':
|
|
64
|
+
ans = ρσ_html_element_to_string(x)
|
|
65
|
+
else:
|
|
66
|
+
ans = x.toString() if v'typeof x.toString === "function"' else x
|
|
67
|
+
if ans is '[object Object]':
|
|
68
|
+
# Assume this is a dictionary
|
|
69
|
+
return ρσ_repr_js_builtin(x)
|
|
70
|
+
try:
|
|
71
|
+
ans = JSON.stringify(x)
|
|
72
|
+
except:
|
|
73
|
+
pass
|
|
74
|
+
return ans + '' # Ensures we return an object of type string (i.e. primitive value) rather than a String object
|
|
75
|
+
|
|
76
|
+
def ρσ_str(x):
|
|
77
|
+
if x is None:
|
|
78
|
+
return 'None'
|
|
79
|
+
if x is undefined:
|
|
80
|
+
return 'undefined'
|
|
81
|
+
ans = x
|
|
82
|
+
if v'typeof x.__str__ === "function"':
|
|
83
|
+
ans = x.__str__()
|
|
84
|
+
elif v'typeof x.__repr__ === "function"':
|
|
85
|
+
ans = x.__repr__()
|
|
86
|
+
elif x is True or x is False:
|
|
87
|
+
ans = 'True' if x else 'False'
|
|
88
|
+
elif Array.isArray(x):
|
|
89
|
+
ans = ρσ_repr_js_builtin(x, True)
|
|
90
|
+
elif v'typeof x.toString === "function"':
|
|
91
|
+
name = Object.prototype.toString.call(x).slice(8, -1)
|
|
92
|
+
if "Int8Array Uint8Array Uint8ClampedArray Int16Array Uint16Array Int32Array Uint32Array Float32Array Float64Array".indexOf(name) != -1:
|
|
93
|
+
return name + '([' + x.map(def(i): return str.format('0x{:02x}', i);).join(', ') + '])'
|
|
94
|
+
if jstype(HTMLElement) is not 'undefined' and v'x instanceof HTMLElement':
|
|
95
|
+
ans = ρσ_html_element_to_string(x)
|
|
96
|
+
else:
|
|
97
|
+
ans = x.toString()
|
|
98
|
+
if ans is '[object Object]':
|
|
99
|
+
# Assume this is a dictionary
|
|
100
|
+
ans = ρσ_repr_js_builtin(x)
|
|
101
|
+
elif jstype(x) is 'object' and not x.toString:
|
|
102
|
+
# Assume this is a dictionary
|
|
103
|
+
ans = ρσ_repr_js_builtin(x)
|
|
104
|
+
return ans + '' # Ensures we return an object of type string (i.e. primitive value) rather than a String object
|
|
105
|
+
|
|
106
|
+
define_str_func = def(name, func):
|
|
107
|
+
ρσ_str.prototype[name] = func
|
|
108
|
+
ρσ_str[name] = f = func.call.bind(func)
|
|
109
|
+
if func.__argnames__:
|
|
110
|
+
Object.defineProperty(f, '__argnames__', {'value':v"['string']".concat(func.__argnames__)})
|
|
111
|
+
|
|
112
|
+
ρσ_orig_split, ρσ_orig_replace = String.prototype.split.call.bind(String.prototype.split), String.prototype.replace.call.bind(String.prototype.replace)
|
|
113
|
+
|
|
114
|
+
# format() {{{
|
|
115
|
+
define_str_func('format', def ():
|
|
116
|
+
template = this
|
|
117
|
+
if template is undefined:
|
|
118
|
+
raise TypeError("Template is required")
|
|
119
|
+
args = Array.prototype.slice.call(arguments)
|
|
120
|
+
kwargs = {}
|
|
121
|
+
if args[-1] and args[-1][ρσ_kwargs_symbol] is not undefined:
|
|
122
|
+
kwargs = args[-1]
|
|
123
|
+
args = args[:-1]
|
|
124
|
+
|
|
125
|
+
explicit = implicit = False
|
|
126
|
+
idx = 0
|
|
127
|
+
split = ρσ_orig_split
|
|
128
|
+
|
|
129
|
+
if ρσ_str.format._template_resolve_pat is undefined:
|
|
130
|
+
ρσ_str.format._template_resolve_pat = /[.\[]/
|
|
131
|
+
|
|
132
|
+
def resolve(arg, object):
|
|
133
|
+
if not arg:
|
|
134
|
+
return object
|
|
135
|
+
first, arg = arg[0], arg[1:]
|
|
136
|
+
key = split(arg, ρσ_str.format._template_resolve_pat, 1)[0]
|
|
137
|
+
rest = arg[key.length:]
|
|
138
|
+
ans = object[key[:-1]] if first is '[' else getattr(object, key)
|
|
139
|
+
if ans is undefined:
|
|
140
|
+
raise KeyError(key[:-1] if first is '[' else key)
|
|
141
|
+
return resolve(rest, ans)
|
|
142
|
+
|
|
143
|
+
def resolve_format_spec(format_spec):
|
|
144
|
+
if ρσ_str.format._template_resolve_fs_pat is undefined:
|
|
145
|
+
ρσ_str.format._template_resolve_fs_pat = /[{]([a-zA-Z0-9_]+)[}]/g
|
|
146
|
+
return format_spec.replace(ρσ_str.format._template_resolve_fs_pat, def (match, key):
|
|
147
|
+
if not Object.prototype.hasOwnProperty.call(kwargs, key):
|
|
148
|
+
return ''
|
|
149
|
+
return '' + kwargs[key]
|
|
150
|
+
)
|
|
151
|
+
|
|
152
|
+
def set_comma(ans, comma):
|
|
153
|
+
if comma is not ',':
|
|
154
|
+
sep = 1234
|
|
155
|
+
sep = sep.toLocaleString(undefined, v'{useGrouping: true}')[1]
|
|
156
|
+
ans = str.replace(ans, sep, comma)
|
|
157
|
+
return ans
|
|
158
|
+
|
|
159
|
+
def safe_comma(value, comma):
|
|
160
|
+
try:
|
|
161
|
+
return set_comma(value.toLocaleString(undefined, v'{useGrouping: true}'), comma)
|
|
162
|
+
except:
|
|
163
|
+
return value.toString(10)
|
|
164
|
+
|
|
165
|
+
|
|
166
|
+
def safe_fixed(value, precision, comma):
|
|
167
|
+
if not comma:
|
|
168
|
+
return value.toFixed(precision)
|
|
169
|
+
try:
|
|
170
|
+
return set_comma(value.toLocaleString(undefined, v'{useGrouping: true, minimumFractionDigits: precision, maximumFractionDigits: precision}'), comma)
|
|
171
|
+
except:
|
|
172
|
+
return value.toFixed(precision)
|
|
173
|
+
|
|
174
|
+
|
|
175
|
+
def apply_formatting(value, format_spec):
|
|
176
|
+
if format_spec.indexOf('{') is not -1:
|
|
177
|
+
format_spec = resolve_format_spec(format_spec)
|
|
178
|
+
if ρσ_str.format._template_format_pat is undefined:
|
|
179
|
+
ρσ_str.format._template_format_pat = ///
|
|
180
|
+
([^{}](?=[<>=^]))?([<>=^])? # fill & align
|
|
181
|
+
([-+\x20])? # sign
|
|
182
|
+
(\#)? # integer base specifier
|
|
183
|
+
(0)? # zero-padding
|
|
184
|
+
(\d+)? # width
|
|
185
|
+
([,_])? # use a grouping (thousands) seperator
|
|
186
|
+
(?:\.(\d+))? # precision
|
|
187
|
+
([bcdeEfFgGnosxX%])? # type
|
|
188
|
+
///
|
|
189
|
+
|
|
190
|
+
try:
|
|
191
|
+
fill, align, sign, fhash, zeropad, width, comma, precision, ftype = format_spec.match(ρσ_str.format._template_format_pat)[1:]
|
|
192
|
+
except TypeError:
|
|
193
|
+
return value
|
|
194
|
+
if zeropad:
|
|
195
|
+
fill = fill or '0'
|
|
196
|
+
align = align or '='
|
|
197
|
+
else:
|
|
198
|
+
fill = fill or ' '
|
|
199
|
+
align = align or '>'
|
|
200
|
+
is_numeric = v'Number(value) === value'
|
|
201
|
+
is_int = is_numeric and v'value % 1 === 0'
|
|
202
|
+
precision = parseInt(precision, 10)
|
|
203
|
+
lftype = (ftype or '').toLowerCase()
|
|
204
|
+
|
|
205
|
+
if ftype is 'n':
|
|
206
|
+
is_numeric = True
|
|
207
|
+
if is_int:
|
|
208
|
+
if comma:
|
|
209
|
+
raise ValueError("Cannot specify ',' with 'n'")
|
|
210
|
+
value = parseInt(value, 10).toLocaleString()
|
|
211
|
+
else:
|
|
212
|
+
value = parseFloat(value).toLocaleString()
|
|
213
|
+
|
|
214
|
+
elif v"['b', 'c', 'd', 'o', 'x']".indexOf(lftype) is not -1:
|
|
215
|
+
value = parseInt(value, 10)
|
|
216
|
+
is_numeric = True
|
|
217
|
+
if not isNaN(value):
|
|
218
|
+
if ftype is 'b':
|
|
219
|
+
value = v'(value >>> 0).toString(2)'
|
|
220
|
+
if fhash:
|
|
221
|
+
value = '0b' + value
|
|
222
|
+
elif ftype is 'c':
|
|
223
|
+
if value > 0xFFFF:
|
|
224
|
+
code = value - 0x10000
|
|
225
|
+
value = String.fromCharCode(0xD800+(code>>10), 0xDC00+(code&0x3FF))
|
|
226
|
+
else:
|
|
227
|
+
value = String.fromCharCode(value)
|
|
228
|
+
elif ftype is 'd':
|
|
229
|
+
if comma:
|
|
230
|
+
value = safe_comma(value, comma)
|
|
231
|
+
else:
|
|
232
|
+
value = value.toString(10)
|
|
233
|
+
elif ftype is 'o':
|
|
234
|
+
value = value.toString(8)
|
|
235
|
+
if fhash:
|
|
236
|
+
value = '0o' + value
|
|
237
|
+
elif lftype is 'x':
|
|
238
|
+
value = value.toString(16)
|
|
239
|
+
value = value.toLowerCase() if ftype is 'x' else value.toUpperCase()
|
|
240
|
+
if fhash:
|
|
241
|
+
value = '0x' + value
|
|
242
|
+
|
|
243
|
+
elif v"['e','f','g','%']".indexOf(lftype) is not -1:
|
|
244
|
+
is_numeric = True
|
|
245
|
+
value = parseFloat(value)
|
|
246
|
+
prec = 6 if isNaN(precision) else precision
|
|
247
|
+
if lftype is 'e':
|
|
248
|
+
value = value.toExponential(prec)
|
|
249
|
+
value = value.toUpperCase() if ftype is 'E' else value.toLowerCase()
|
|
250
|
+
elif lftype is 'f':
|
|
251
|
+
value = safe_fixed(value, prec, comma)
|
|
252
|
+
value = value.toUpperCase() if ftype is 'F' else value.toLowerCase()
|
|
253
|
+
elif lftype is '%':
|
|
254
|
+
value *= 100
|
|
255
|
+
value = safe_fixed(value, prec, comma) + '%'
|
|
256
|
+
elif lftype is 'g':
|
|
257
|
+
prec = max(1, prec)
|
|
258
|
+
exp = parseInt(split(value.toExponential(prec - 1).toLowerCase(), 'e')[1], 10)
|
|
259
|
+
if -4 <= exp < prec:
|
|
260
|
+
value = safe_fixed(value, prec - 1 - exp, comma)
|
|
261
|
+
else:
|
|
262
|
+
value = value.toExponential(prec - 1)
|
|
263
|
+
value = value.replace(/0+$/g, '')
|
|
264
|
+
if value[-1] is decimal_sep:
|
|
265
|
+
value = value[:-1]
|
|
266
|
+
if ftype is 'G':
|
|
267
|
+
value = value.toUpperCase()
|
|
268
|
+
|
|
269
|
+
else:
|
|
270
|
+
if comma:
|
|
271
|
+
value = parseInt(value, 10)
|
|
272
|
+
if isNaN(value):
|
|
273
|
+
raise ValueError('Must use numbers with , or _')
|
|
274
|
+
value = safe_comma(value, comma)
|
|
275
|
+
value += '' # Ensure we have a string
|
|
276
|
+
if not isNaN(precision):
|
|
277
|
+
value = value[:precision]
|
|
278
|
+
|
|
279
|
+
value += '' # Ensure we have a string
|
|
280
|
+
|
|
281
|
+
if is_numeric and sign:
|
|
282
|
+
nval = v'Number(value)'
|
|
283
|
+
is_positive = not isNaN(nval) and nval >= 0
|
|
284
|
+
if is_positive and (sign is ' ' or sign is '+'):
|
|
285
|
+
value = sign + value
|
|
286
|
+
|
|
287
|
+
def repeat(char, num):
|
|
288
|
+
return v'(new Array(num+1)).join(char)'
|
|
289
|
+
|
|
290
|
+
if is_numeric and width and width[0] is '0':
|
|
291
|
+
width = width[1:]
|
|
292
|
+
fill, align = '0', '='
|
|
293
|
+
|
|
294
|
+
width = parseInt(width or '-1', 10)
|
|
295
|
+
if isNaN(width):
|
|
296
|
+
raise ValueError('Invalid width specification: ' + width)
|
|
297
|
+
|
|
298
|
+
if fill and value.length < width:
|
|
299
|
+
if align is '<':
|
|
300
|
+
value = value + repeat(fill, width - value.length)
|
|
301
|
+
elif align is '>':
|
|
302
|
+
value = repeat(fill, width - value.length) + value
|
|
303
|
+
elif align is '^':
|
|
304
|
+
left = (width - value.length) // 2
|
|
305
|
+
right = width - left - value.length
|
|
306
|
+
value = repeat(fill, left) + value + repeat(fill, right)
|
|
307
|
+
elif align is '=':
|
|
308
|
+
if value[0] in "+- ":
|
|
309
|
+
value = value[0] + repeat(fill, width - value.length) + value[1:]
|
|
310
|
+
else:
|
|
311
|
+
value = repeat(fill, width - value.length) + value
|
|
312
|
+
else:
|
|
313
|
+
raise ValueError('Unrecognized alignment: ' + align)
|
|
314
|
+
|
|
315
|
+
return value
|
|
316
|
+
|
|
317
|
+
def parse_markup(markup):
|
|
318
|
+
key = transformer = format_spec = ''
|
|
319
|
+
pos = 0
|
|
320
|
+
state = 0
|
|
321
|
+
while pos < markup.length:
|
|
322
|
+
ch = markup[pos]
|
|
323
|
+
if state is 0:
|
|
324
|
+
if ch is '!':
|
|
325
|
+
state = 1
|
|
326
|
+
elif ch is ':':
|
|
327
|
+
state = 2
|
|
328
|
+
else:
|
|
329
|
+
key += ch
|
|
330
|
+
elif state is 1:
|
|
331
|
+
if ch is ':':
|
|
332
|
+
state = 2
|
|
333
|
+
else:
|
|
334
|
+
transformer += ch
|
|
335
|
+
else:
|
|
336
|
+
format_spec += ch
|
|
337
|
+
pos += 1
|
|
338
|
+
return key, transformer, format_spec
|
|
339
|
+
|
|
340
|
+
def render_markup(markup):
|
|
341
|
+
nonlocal explicit, implicit, idx
|
|
342
|
+
key, transformer, format_spec = parse_markup(markup)
|
|
343
|
+
if transformer and v"['a', 'r', 's']".indexOf(transformer) is -1:
|
|
344
|
+
raise ValueError('Unknown conversion specifier: ' + transformer)
|
|
345
|
+
ends_with_equal = key.endsWith('=')
|
|
346
|
+
if ends_with_equal:
|
|
347
|
+
key = key[:-1]
|
|
348
|
+
lkey = key.length and split(key, /[.\[]/, 1)[0]
|
|
349
|
+
if lkey:
|
|
350
|
+
explicit = True
|
|
351
|
+
if implicit:
|
|
352
|
+
raise ValueError('cannot switch from automatic field numbering to manual field specification')
|
|
353
|
+
nvalue = parseInt(lkey)
|
|
354
|
+
object = kwargs[lkey] if isNaN(nvalue) else args[nvalue]
|
|
355
|
+
if object is undefined:
|
|
356
|
+
if isNaN(nvalue):
|
|
357
|
+
raise KeyError(lkey)
|
|
358
|
+
raise IndexError(lkey)
|
|
359
|
+
object = resolve(key[lkey.length:], object)
|
|
360
|
+
else:
|
|
361
|
+
implicit = True
|
|
362
|
+
if explicit:
|
|
363
|
+
raise ValueError('cannot switch from manual field specification to automatic field numbering')
|
|
364
|
+
if idx >= args.length:
|
|
365
|
+
raise IndexError('Not enough arguments to match template: ' + template)
|
|
366
|
+
object = args[idx]
|
|
367
|
+
idx += 1
|
|
368
|
+
if jstype(object) is 'function':
|
|
369
|
+
object = object()
|
|
370
|
+
ans = '' + object
|
|
371
|
+
if format_spec:
|
|
372
|
+
ans = apply_formatting(ans, format_spec)
|
|
373
|
+
if ends_with_equal:
|
|
374
|
+
ans = f'{key}={ans}'
|
|
375
|
+
return ans
|
|
376
|
+
|
|
377
|
+
|
|
378
|
+
ans = ''
|
|
379
|
+
pos = 0
|
|
380
|
+
in_brace = 0
|
|
381
|
+
markup = ''
|
|
382
|
+
while pos < template.length:
|
|
383
|
+
ch = template[pos]
|
|
384
|
+
if in_brace:
|
|
385
|
+
if ch is '{':
|
|
386
|
+
in_brace += 1
|
|
387
|
+
markup += '{'
|
|
388
|
+
elif ch is '}':
|
|
389
|
+
in_brace -= 1
|
|
390
|
+
if in_brace > 0:
|
|
391
|
+
markup += '}'
|
|
392
|
+
else:
|
|
393
|
+
ans += render_markup(markup)
|
|
394
|
+
else:
|
|
395
|
+
markup += ch
|
|
396
|
+
else:
|
|
397
|
+
if ch is '{':
|
|
398
|
+
if template[pos+1] is '{':
|
|
399
|
+
pos += 1
|
|
400
|
+
ans += '{'
|
|
401
|
+
else:
|
|
402
|
+
in_brace = 1
|
|
403
|
+
markup = ''
|
|
404
|
+
else:
|
|
405
|
+
ans += ch
|
|
406
|
+
if ch is '}' and template[pos+1] is '}':
|
|
407
|
+
pos += 1
|
|
408
|
+
|
|
409
|
+
pos += 1
|
|
410
|
+
|
|
411
|
+
if in_brace:
|
|
412
|
+
raise ValueError("expected '}' before end of string")
|
|
413
|
+
|
|
414
|
+
return ans
|
|
415
|
+
)
|
|
416
|
+
# }}}
|
|
417
|
+
|
|
418
|
+
define_str_func('capitalize', def ():
|
|
419
|
+
string = this
|
|
420
|
+
if string:
|
|
421
|
+
string = string[0].toUpperCase() + string[1:].toLowerCase()
|
|
422
|
+
return string
|
|
423
|
+
)
|
|
424
|
+
|
|
425
|
+
define_str_func('center', def(width, fill):
|
|
426
|
+
left = (width - this.length) // 2
|
|
427
|
+
right = width - left - this.length # noqa:unused-local
|
|
428
|
+
fill = fill or ' '
|
|
429
|
+
return v'new Array(left+1).join(fill)' + this + v'new Array(right+1).join(fill)'
|
|
430
|
+
)
|
|
431
|
+
|
|
432
|
+
define_str_func('count', def(needle, start, end):
|
|
433
|
+
string = this
|
|
434
|
+
start = start or 0
|
|
435
|
+
end = end or string.length
|
|
436
|
+
if start < 0 or end < 0:
|
|
437
|
+
string = string[start:end]
|
|
438
|
+
start, end = 0, string.length
|
|
439
|
+
pos = start
|
|
440
|
+
step = needle.length
|
|
441
|
+
if not step:
|
|
442
|
+
return 0
|
|
443
|
+
ans = 0
|
|
444
|
+
while pos is not -1:
|
|
445
|
+
pos = string.indexOf(needle, pos)
|
|
446
|
+
if pos is not -1:
|
|
447
|
+
ans += 1
|
|
448
|
+
pos += step
|
|
449
|
+
return ans
|
|
450
|
+
)
|
|
451
|
+
|
|
452
|
+
define_str_func('endswith', def(suffixes, start, end):
|
|
453
|
+
string = this
|
|
454
|
+
start = start or 0
|
|
455
|
+
if jstype(suffixes) is 'string':
|
|
456
|
+
suffixes = v'[suffixes]'
|
|
457
|
+
if end is not undefined:
|
|
458
|
+
string = string[:end]
|
|
459
|
+
for v'var i = 0; i < suffixes.length; i++':
|
|
460
|
+
q = suffixes[i] # noqa:undef
|
|
461
|
+
if string.indexOf(q, Math.max(start, string.length - q.length)) is not -1:
|
|
462
|
+
return True
|
|
463
|
+
return False
|
|
464
|
+
)
|
|
465
|
+
|
|
466
|
+
define_str_func('startswith', def(prefixes, start, end):
|
|
467
|
+
start = start or 0
|
|
468
|
+
if jstype(prefixes) is 'string':
|
|
469
|
+
prefixes = v'[prefixes]'
|
|
470
|
+
for v'var i = 0; i < prefixes.length; i++':
|
|
471
|
+
prefix = prefixes[i] # noqa:undef
|
|
472
|
+
end = this.length if end is undefined else end
|
|
473
|
+
if end - start >= prefix.length and prefix is this[start:start + prefix.length]:
|
|
474
|
+
return True
|
|
475
|
+
return False
|
|
476
|
+
)
|
|
477
|
+
|
|
478
|
+
define_str_func('find', def(needle, start, end):
|
|
479
|
+
while start < 0:
|
|
480
|
+
start += this.length
|
|
481
|
+
ans = this.indexOf(needle, start)
|
|
482
|
+
if end is not undefined and ans is not -1:
|
|
483
|
+
while end < 0:
|
|
484
|
+
end += this.length
|
|
485
|
+
if ans >= end - needle.length:
|
|
486
|
+
return -1
|
|
487
|
+
return ans
|
|
488
|
+
)
|
|
489
|
+
|
|
490
|
+
define_str_func('rfind', def(needle, start, end):
|
|
491
|
+
while end < 0:
|
|
492
|
+
end += this.length
|
|
493
|
+
ans = this.lastIndexOf(needle, end - 1)
|
|
494
|
+
if start is not undefined and ans is not -1:
|
|
495
|
+
while start < 0:
|
|
496
|
+
start += this.length
|
|
497
|
+
if ans < start:
|
|
498
|
+
return -1
|
|
499
|
+
return ans
|
|
500
|
+
)
|
|
501
|
+
|
|
502
|
+
define_str_func('index', def(needle, start, end):
|
|
503
|
+
ans = ρσ_str.prototype.find.apply(this, arguments)
|
|
504
|
+
if ans is -1:
|
|
505
|
+
raise ValueError('substring not found')
|
|
506
|
+
return ans
|
|
507
|
+
)
|
|
508
|
+
|
|
509
|
+
define_str_func('rindex', def(needle, start, end):
|
|
510
|
+
ans = ρσ_str.prototype.rfind.apply(this, arguments)
|
|
511
|
+
if ans is -1:
|
|
512
|
+
raise ValueError('substring not found')
|
|
513
|
+
return ans
|
|
514
|
+
)
|
|
515
|
+
|
|
516
|
+
define_str_func('islower', def():
|
|
517
|
+
return this.length > 0 and this.toLowerCase() is this.toString()
|
|
518
|
+
)
|
|
519
|
+
|
|
520
|
+
define_str_func('isupper', def():
|
|
521
|
+
return this.length > 0 and this.toUpperCase() is this.toString()
|
|
522
|
+
)
|
|
523
|
+
|
|
524
|
+
define_str_func('isspace', def():
|
|
525
|
+
return this.length > 0 and /^\s+$/.test(this)
|
|
526
|
+
)
|
|
527
|
+
|
|
528
|
+
define_str_func('join', def(iterable):
|
|
529
|
+
if Array.isArray(iterable):
|
|
530
|
+
return iterable.join(this)
|
|
531
|
+
ans = ''
|
|
532
|
+
r = iterable.next()
|
|
533
|
+
while not r.done:
|
|
534
|
+
if ans:
|
|
535
|
+
ans += this
|
|
536
|
+
ans += r.value
|
|
537
|
+
r = iterable.next()
|
|
538
|
+
return ans
|
|
539
|
+
)
|
|
540
|
+
|
|
541
|
+
define_str_func('ljust', def(width, fill):
|
|
542
|
+
string = this
|
|
543
|
+
if width > string.length:
|
|
544
|
+
fill = fill or ' '
|
|
545
|
+
string += v'new Array(width - string.length + 1).join(fill)'
|
|
546
|
+
return string
|
|
547
|
+
)
|
|
548
|
+
|
|
549
|
+
define_str_func('rjust', def(width, fill):
|
|
550
|
+
string = this
|
|
551
|
+
if width > string.length:
|
|
552
|
+
fill = fill or ' '
|
|
553
|
+
string = v'new Array(width - string.length + 1).join(fill)' + string
|
|
554
|
+
return string
|
|
555
|
+
)
|
|
556
|
+
|
|
557
|
+
define_str_func('lower', def():
|
|
558
|
+
return this.toLowerCase()
|
|
559
|
+
)
|
|
560
|
+
|
|
561
|
+
define_str_func('upper', def():
|
|
562
|
+
return this.toUpperCase()
|
|
563
|
+
)
|
|
564
|
+
|
|
565
|
+
define_str_func('title', def():
|
|
566
|
+
# Split the string into words based on spaces
|
|
567
|
+
words = this.split(' ')
|
|
568
|
+
|
|
569
|
+
# Capitalize the first letter of each word
|
|
570
|
+
title_cased_words = [word[0].upper() + word[1:].lower() if word else '' for word in words]
|
|
571
|
+
|
|
572
|
+
# Join the words back into a single string
|
|
573
|
+
return ' '.join(title_cased_words)
|
|
574
|
+
)
|
|
575
|
+
|
|
576
|
+
define_str_func('lstrip', def(chars):
|
|
577
|
+
string = this
|
|
578
|
+
pos = 0
|
|
579
|
+
chars = chars or ρσ_str.whitespace
|
|
580
|
+
while chars.indexOf(string[pos]) is not -1:
|
|
581
|
+
pos += 1
|
|
582
|
+
if pos:
|
|
583
|
+
string = string[pos:]
|
|
584
|
+
return string
|
|
585
|
+
)
|
|
586
|
+
|
|
587
|
+
define_str_func('rstrip', def(chars):
|
|
588
|
+
string = this
|
|
589
|
+
pos = string.length - 1
|
|
590
|
+
chars = chars or ρσ_str.whitespace
|
|
591
|
+
while chars.indexOf(string[pos]) is not -1:
|
|
592
|
+
pos -= 1
|
|
593
|
+
if pos < string.length - 1:
|
|
594
|
+
string = string[:pos + 1]
|
|
595
|
+
return string
|
|
596
|
+
)
|
|
597
|
+
|
|
598
|
+
define_str_func('strip', def(chars):
|
|
599
|
+
return ρσ_str.prototype.lstrip.call(ρσ_str.prototype.rstrip.call(this, chars), chars)
|
|
600
|
+
)
|
|
601
|
+
|
|
602
|
+
define_str_func('partition', def(sep):
|
|
603
|
+
idx = this.indexOf(sep)
|
|
604
|
+
if idx is -1:
|
|
605
|
+
return this, '', ''
|
|
606
|
+
return this[:idx], sep, this[idx + sep.length:]
|
|
607
|
+
)
|
|
608
|
+
|
|
609
|
+
define_str_func('rpartition', def(sep):
|
|
610
|
+
idx = this.lastIndexOf(sep)
|
|
611
|
+
if idx is -1:
|
|
612
|
+
return '', '', this
|
|
613
|
+
return this[:idx], sep, this[idx + sep.length:]
|
|
614
|
+
)
|
|
615
|
+
|
|
616
|
+
define_str_func('replace', def(old, repl, count):
|
|
617
|
+
string = this
|
|
618
|
+
if count is 1:
|
|
619
|
+
return ρσ_orig_replace(string, old, repl)
|
|
620
|
+
if count < 1:
|
|
621
|
+
return string
|
|
622
|
+
count = count or Number.MAX_VALUE
|
|
623
|
+
pos = 0
|
|
624
|
+
while count > 0:
|
|
625
|
+
count -= 1
|
|
626
|
+
idx = string.indexOf(old, pos)
|
|
627
|
+
if idx is -1:
|
|
628
|
+
break
|
|
629
|
+
pos = idx + repl.length
|
|
630
|
+
string = string[:idx] + repl + string[idx + old.length:]
|
|
631
|
+
return string
|
|
632
|
+
)
|
|
633
|
+
|
|
634
|
+
define_str_func('split', def(sep, maxsplit):
|
|
635
|
+
if maxsplit is 0:
|
|
636
|
+
return [this]
|
|
637
|
+
split = ρσ_orig_split
|
|
638
|
+
if sep is undefined or sep is None:
|
|
639
|
+
if maxsplit > 0:
|
|
640
|
+
ans = split(this, /(\s+)/)
|
|
641
|
+
extra = ''
|
|
642
|
+
parts = v'[]'
|
|
643
|
+
for v'var i = 0; i < ans.length; i++':
|
|
644
|
+
if parts.length >= maxsplit + 1:
|
|
645
|
+
extra += ans[i]
|
|
646
|
+
elif i % 2 is 0:
|
|
647
|
+
parts.push(ans[i]) # noqa:undef
|
|
648
|
+
parts[-1] += extra
|
|
649
|
+
ans = parts
|
|
650
|
+
else:
|
|
651
|
+
ans = split(this, /\s+/)
|
|
652
|
+
else:
|
|
653
|
+
if sep is '':
|
|
654
|
+
raise ValueError('empty separator')
|
|
655
|
+
ans = split(this, sep)
|
|
656
|
+
if maxsplit > 0 and ans.length > maxsplit:
|
|
657
|
+
extra = ans[maxsplit:].join(sep)
|
|
658
|
+
ans = ans[:maxsplit]
|
|
659
|
+
ans.push(extra)
|
|
660
|
+
return ρσ_list_decorate(ans)
|
|
661
|
+
)
|
|
662
|
+
|
|
663
|
+
define_str_func('rsplit', def(sep, maxsplit):
|
|
664
|
+
if not maxsplit:
|
|
665
|
+
return ρσ_str.prototype.split.call(this, sep)
|
|
666
|
+
split = ρσ_orig_split
|
|
667
|
+
if sep is undefined or sep is None:
|
|
668
|
+
if maxsplit > 0:
|
|
669
|
+
ans = v'[]'
|
|
670
|
+
is_space = /\s/
|
|
671
|
+
pos = this.length - 1
|
|
672
|
+
current = ''
|
|
673
|
+
while pos > -1 and maxsplit > 0:
|
|
674
|
+
spc = False
|
|
675
|
+
ch = this[pos]
|
|
676
|
+
while pos > -1 and is_space.test(ch):
|
|
677
|
+
spc = True
|
|
678
|
+
ch = v'this[--pos]'
|
|
679
|
+
if spc:
|
|
680
|
+
if current:
|
|
681
|
+
ans.push(current)
|
|
682
|
+
maxsplit -= 1
|
|
683
|
+
current = ch
|
|
684
|
+
else:
|
|
685
|
+
current += ch
|
|
686
|
+
pos -= 1
|
|
687
|
+
ans.push(this[:pos + 1] + current)
|
|
688
|
+
ans.reverse()
|
|
689
|
+
else:
|
|
690
|
+
ans = split(this, /\s+/)
|
|
691
|
+
else:
|
|
692
|
+
if sep is '':
|
|
693
|
+
raise ValueError('empty separator')
|
|
694
|
+
ans = v'[]'
|
|
695
|
+
pos = end = this.length
|
|
696
|
+
while pos > -1 and maxsplit > 0:
|
|
697
|
+
maxsplit -= 1
|
|
698
|
+
idx = this.lastIndexOf(sep, pos)
|
|
699
|
+
if idx is -1:
|
|
700
|
+
break
|
|
701
|
+
ans.push(this[idx + sep.length:end])
|
|
702
|
+
pos = idx - 1
|
|
703
|
+
end = idx
|
|
704
|
+
ans.push(this[:end])
|
|
705
|
+
ans.reverse()
|
|
706
|
+
return ρσ_list_decorate(ans)
|
|
707
|
+
)
|
|
708
|
+
|
|
709
|
+
define_str_func('splitlines', def(keepends):
|
|
710
|
+
split = ρσ_orig_split
|
|
711
|
+
if keepends:
|
|
712
|
+
parts = split(this, /((?:\r?\n)|\r)/)
|
|
713
|
+
ans = v'[]'
|
|
714
|
+
for v'var i = 0; i < parts.length; i++':
|
|
715
|
+
if i % 2 is 0:
|
|
716
|
+
ans.push(parts[i])
|
|
717
|
+
else:
|
|
718
|
+
ans[-1] += parts[i] # noqa:undef
|
|
719
|
+
else:
|
|
720
|
+
ans = split(this, /(?:\r?\n)|\r/)
|
|
721
|
+
return ρσ_list_decorate(ans)
|
|
722
|
+
)
|
|
723
|
+
|
|
724
|
+
define_str_func('swapcase', def():
|
|
725
|
+
ans = v'new Array(this.length)'
|
|
726
|
+
for v'var i = 0; i < ans.length; i++':
|
|
727
|
+
a = this[i]
|
|
728
|
+
# We dont care about non-BMP chars as they are not cased anyway
|
|
729
|
+
b = a.toLowerCase()
|
|
730
|
+
if a is b:
|
|
731
|
+
b = a.toUpperCase()
|
|
732
|
+
ans[i] = b # noqa:undef
|
|
733
|
+
return ans.join('')
|
|
734
|
+
)
|
|
735
|
+
|
|
736
|
+
define_str_func('zfill', def(width):
|
|
737
|
+
string = this
|
|
738
|
+
if width > string.length:
|
|
739
|
+
string = v'new Array(width - string.length + 1).join("0")' + string
|
|
740
|
+
return string
|
|
741
|
+
)
|
|
742
|
+
|
|
743
|
+
ρσ_str.uchrs = def(string, with_positions):
|
|
744
|
+
# Return iterator over unicode chars in string. Will yield the unicode
|
|
745
|
+
# replacement char U+FFFD for broken surrogate pairs
|
|
746
|
+
return {
|
|
747
|
+
'_string': string,
|
|
748
|
+
'_pos': 0,
|
|
749
|
+
ρσ_iterator_symbol: def(): return this;,
|
|
750
|
+
'next' : def():
|
|
751
|
+
length = this._string.length
|
|
752
|
+
if this._pos >= length:
|
|
753
|
+
return {'done': True}
|
|
754
|
+
pos = this._pos
|
|
755
|
+
value = v'this._string.charCodeAt(this._pos++)'
|
|
756
|
+
ans = '\ufffd'
|
|
757
|
+
if 0xD800 <= value <= 0xDBFF:
|
|
758
|
+
if this._pos < length:
|
|
759
|
+
# high surrogate, and there is a next character
|
|
760
|
+
extra = v'this._string.charCodeAt(this._pos++)'
|
|
761
|
+
if (extra & 0xDC00) is 0xDC00: # low surrogate
|
|
762
|
+
ans = String.fromCharCode(value, extra)
|
|
763
|
+
elif (value & 0xDC00) is not 0xDC00: # not a low surrogate
|
|
764
|
+
ans = String.fromCharCode(value)
|
|
765
|
+
if with_positions:
|
|
766
|
+
return {'done':False, 'value':[pos, ans]}
|
|
767
|
+
else:
|
|
768
|
+
return {'done':False, 'value':ans}
|
|
769
|
+
}
|
|
770
|
+
|
|
771
|
+
ρσ_str.uslice = def(string, start, end):
|
|
772
|
+
items = v'[]'
|
|
773
|
+
iterator = ρσ_str.uchrs(string)
|
|
774
|
+
r = iterator.next()
|
|
775
|
+
while not r.done:
|
|
776
|
+
items.push(r.value)
|
|
777
|
+
r = iterator.next()
|
|
778
|
+
return items[start or 0:items.length if end is undefined else end].join('')
|
|
779
|
+
|
|
780
|
+
ρσ_str.ulen = def(string):
|
|
781
|
+
iterator = ρσ_str.uchrs(string)
|
|
782
|
+
r = iterator.next()
|
|
783
|
+
ans = 0
|
|
784
|
+
while not r.done:
|
|
785
|
+
r = iterator.next()
|
|
786
|
+
ans += 1
|
|
787
|
+
return ans
|
|
788
|
+
|
|
789
|
+
ρσ_str.ascii_lowercase = 'abcdefghijklmnopqrstuvwxyz'
|
|
790
|
+
ρσ_str.ascii_uppercase = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
|
|
791
|
+
ρσ_str.ascii_letters = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
|
|
792
|
+
ρσ_str.digits = '0123456789'
|
|
793
|
+
ρσ_str.punctuation = '!"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~'
|
|
794
|
+
ρσ_str.printable = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~ \t\n\r\x0b\x0c'
|
|
795
|
+
ρσ_str.whitespace = ' \t\n\r\x0b\x0c'
|
|
796
|
+
|
|
797
|
+
v'define_str_func = undefined'
|
|
798
|
+
v'var str = ρσ_str, repr = ρσ_repr'
|