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.
Files changed (144) hide show
  1. package/.agignore +1 -0
  2. package/.gitattributes +4 -0
  3. package/.github/workflows/ci.yml +38 -0
  4. package/.github/workflows/web-repl-page-deploy.yml +42 -0
  5. package/=template.pyj +5 -0
  6. package/CHANGELOG.md +456 -0
  7. package/CONTRIBUTORS +13 -0
  8. package/HACKING.md +103 -0
  9. package/LICENSE +24 -0
  10. package/README.md +2512 -0
  11. package/TODO.md +327 -0
  12. package/add-toc-to-readme +2 -0
  13. package/bin/export +75 -0
  14. package/bin/rapydscript +70 -0
  15. package/bin/web-repl-export +102 -0
  16. package/build +3 -0
  17. package/package.json +46 -0
  18. package/publish.py +37 -0
  19. package/release/baselib-plain-pretty.js +4370 -0
  20. package/release/baselib-plain-ugly.js +3 -0
  21. package/release/compiler.js +18394 -0
  22. package/release/signatures.json +31 -0
  23. package/session.vim +4 -0
  24. package/setup.cfg +2 -0
  25. package/src/ast.pyj +1356 -0
  26. package/src/baselib-builtins.pyj +279 -0
  27. package/src/baselib-containers.pyj +723 -0
  28. package/src/baselib-errors.pyj +37 -0
  29. package/src/baselib-internal.pyj +421 -0
  30. package/src/baselib-itertools.pyj +97 -0
  31. package/src/baselib-str.pyj +798 -0
  32. package/src/compiler.pyj +36 -0
  33. package/src/errors.pyj +30 -0
  34. package/src/lib/aes.pyj +646 -0
  35. package/src/lib/collections.pyj +695 -0
  36. package/src/lib/elementmaker.pyj +83 -0
  37. package/src/lib/encodings.pyj +126 -0
  38. package/src/lib/functools.pyj +148 -0
  39. package/src/lib/gettext.pyj +569 -0
  40. package/src/lib/itertools.pyj +580 -0
  41. package/src/lib/math.pyj +193 -0
  42. package/src/lib/numpy.pyj +2101 -0
  43. package/src/lib/operator.pyj +11 -0
  44. package/src/lib/pythonize.pyj +20 -0
  45. package/src/lib/random.pyj +118 -0
  46. package/src/lib/re.pyj +470 -0
  47. package/src/lib/traceback.pyj +63 -0
  48. package/src/lib/uuid.pyj +77 -0
  49. package/src/monaco-language-service/analyzer.js +526 -0
  50. package/src/monaco-language-service/builtins.js +543 -0
  51. package/src/monaco-language-service/completions.js +498 -0
  52. package/src/monaco-language-service/diagnostics.js +643 -0
  53. package/src/monaco-language-service/dts.js +550 -0
  54. package/src/monaco-language-service/hover.js +121 -0
  55. package/src/monaco-language-service/index.js +386 -0
  56. package/src/monaco-language-service/scope.js +162 -0
  57. package/src/monaco-language-service/signature.js +144 -0
  58. package/src/output/__init__.pyj +0 -0
  59. package/src/output/classes.pyj +296 -0
  60. package/src/output/codegen.pyj +492 -0
  61. package/src/output/comments.pyj +45 -0
  62. package/src/output/exceptions.pyj +105 -0
  63. package/src/output/functions.pyj +491 -0
  64. package/src/output/literals.pyj +109 -0
  65. package/src/output/loops.pyj +444 -0
  66. package/src/output/modules.pyj +329 -0
  67. package/src/output/operators.pyj +429 -0
  68. package/src/output/statements.pyj +463 -0
  69. package/src/output/stream.pyj +309 -0
  70. package/src/output/treeshake.pyj +182 -0
  71. package/src/output/utils.pyj +72 -0
  72. package/src/parse.pyj +3106 -0
  73. package/src/string_interpolation.pyj +72 -0
  74. package/src/tokenizer.pyj +702 -0
  75. package/src/unicode_aliases.pyj +576 -0
  76. package/src/utils.pyj +192 -0
  77. package/test/_import_one.pyj +37 -0
  78. package/test/_import_two/__init__.pyj +11 -0
  79. package/test/_import_two/level2/__init__.pyj +0 -0
  80. package/test/_import_two/level2/deep.pyj +4 -0
  81. package/test/_import_two/other.pyj +6 -0
  82. package/test/_import_two/sub.pyj +13 -0
  83. package/test/aes_vectors.pyj +421 -0
  84. package/test/annotations.pyj +80 -0
  85. package/test/baselib.pyj +319 -0
  86. package/test/classes.pyj +452 -0
  87. package/test/collections.pyj +152 -0
  88. package/test/decorators.pyj +77 -0
  89. package/test/dict_spread.pyj +76 -0
  90. package/test/docstrings.pyj +39 -0
  91. package/test/elementmaker_test.pyj +45 -0
  92. package/test/ellipsis.pyj +49 -0
  93. package/test/functions.pyj +151 -0
  94. package/test/generators.pyj +41 -0
  95. package/test/generic.pyj +370 -0
  96. package/test/imports.pyj +72 -0
  97. package/test/internationalization.pyj +73 -0
  98. package/test/lint.pyj +164 -0
  99. package/test/loops.pyj +85 -0
  100. package/test/numpy.pyj +734 -0
  101. package/test/omit_function_metadata.pyj +20 -0
  102. package/test/regexp.pyj +55 -0
  103. package/test/repl.pyj +121 -0
  104. package/test/scoped_flags.pyj +76 -0
  105. package/test/starargs.pyj +506 -0
  106. package/test/starred_assign.pyj +104 -0
  107. package/test/str.pyj +198 -0
  108. package/test/subscript_tuple.pyj +53 -0
  109. package/test/unit/fixtures/fibonacci_expected.js +46 -0
  110. package/test/unit/index.js +2989 -0
  111. package/test/unit/language-service-builtins.js +815 -0
  112. package/test/unit/language-service-completions.js +1067 -0
  113. package/test/unit/language-service-dts.js +543 -0
  114. package/test/unit/language-service-hover.js +455 -0
  115. package/test/unit/language-service-scope.js +833 -0
  116. package/test/unit/language-service-signature.js +458 -0
  117. package/test/unit/language-service.js +705 -0
  118. package/test/unit/run-language-service.js +41 -0
  119. package/test/unit/web-repl.js +484 -0
  120. package/tools/build-language-service.js +190 -0
  121. package/tools/cli.js +547 -0
  122. package/tools/compile.js +219 -0
  123. package/tools/compiler.js +108 -0
  124. package/tools/completer.js +131 -0
  125. package/tools/embedded_compiler.js +251 -0
  126. package/tools/export.js +316 -0
  127. package/tools/gettext.js +185 -0
  128. package/tools/ini.js +65 -0
  129. package/tools/lint.js +705 -0
  130. package/tools/msgfmt.js +187 -0
  131. package/tools/repl.js +223 -0
  132. package/tools/self.js +162 -0
  133. package/tools/test.js +118 -0
  134. package/tools/utils.js +128 -0
  135. package/tools/web_repl.js +95 -0
  136. package/try +41 -0
  137. package/web-repl/env.js +74 -0
  138. package/web-repl/index.html +163 -0
  139. package/web-repl/language-service.js +4084 -0
  140. package/web-repl/main.js +254 -0
  141. package/web-repl/prism.css +139 -0
  142. package/web-repl/prism.js +113 -0
  143. package/web-repl/rapydscript.js +435 -0
  144. 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'