rapydscript-ns 0.9.3 → 0.9.4

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 (98) hide show
  1. package/.agignore +1 -1
  2. package/.github/workflows/ci.yml +38 -38
  3. package/=template.pyj +5 -5
  4. package/CHANGELOG.md +9 -0
  5. package/HACKING.md +103 -103
  6. package/LICENSE +24 -24
  7. package/PYTHON_GAPS.md +48 -116
  8. package/README.md +35 -15
  9. package/TODO.md +1 -26
  10. package/add-toc-to-readme +2 -2
  11. package/bin/export +75 -75
  12. package/bin/rapydscript +0 -0
  13. package/bin/web-repl-export +102 -102
  14. package/build +2 -2
  15. package/language-service/index.js +9 -7
  16. package/package.json +1 -1
  17. package/publish.py +37 -37
  18. package/session.vim +4 -4
  19. package/setup.cfg +2 -2
  20. package/src/ast.pyj +6 -0
  21. package/src/baselib-containers.pyj +23 -1
  22. package/src/baselib-str.pyj +13 -2
  23. package/src/compiler.pyj +36 -36
  24. package/src/errors.pyj +30 -30
  25. package/src/lib/aes.pyj +646 -646
  26. package/src/lib/collections.pyj +227 -3
  27. package/src/lib/copy.pyj +120 -120
  28. package/src/lib/elementmaker.pyj +83 -83
  29. package/src/lib/encodings.pyj +126 -126
  30. package/src/lib/gettext.pyj +569 -569
  31. package/src/lib/itertools.pyj +580 -580
  32. package/src/lib/math.pyj +193 -193
  33. package/src/lib/operator.pyj +11 -11
  34. package/src/lib/pprint.pyj +455 -0
  35. package/src/lib/random.pyj +118 -118
  36. package/src/lib/react.pyj +74 -74
  37. package/src/lib/statistics.pyj +0 -0
  38. package/src/lib/traceback.pyj +63 -63
  39. package/src/lib/uuid.pyj +77 -77
  40. package/src/monaco-language-service/diagnostics.js +2 -2
  41. package/src/monaco-language-service/dts.js +550 -550
  42. package/src/output/codegen.pyj +4 -1
  43. package/src/output/comments.pyj +45 -45
  44. package/src/output/exceptions.pyj +201 -201
  45. package/src/output/jsx.pyj +164 -164
  46. package/src/output/treeshake.pyj +182 -182
  47. package/src/output/utils.pyj +72 -72
  48. package/src/parse.pyj +28 -7
  49. package/src/string_interpolation.pyj +72 -72
  50. package/src/tokenizer.pyj +18 -2
  51. package/src/unicode_aliases.pyj +576 -576
  52. package/src/utils.pyj +192 -192
  53. package/test/_import_one.pyj +37 -37
  54. package/test/_import_two/__init__.pyj +11 -11
  55. package/test/_import_two/level2/deep.pyj +4 -4
  56. package/test/_import_two/other.pyj +6 -6
  57. package/test/_import_two/sub.pyj +13 -13
  58. package/test/aes_vectors.pyj +421 -421
  59. package/test/annotations.pyj +80 -80
  60. package/test/baselib.pyj +23 -0
  61. package/test/chainmap.pyj +185 -0
  62. package/test/decorators.pyj +77 -77
  63. package/test/docstrings.pyj +39 -39
  64. package/test/elementmaker_test.pyj +45 -45
  65. package/test/functions.pyj +151 -151
  66. package/test/generators.pyj +41 -41
  67. package/test/generic.pyj +370 -370
  68. package/test/internationalization.pyj +73 -73
  69. package/test/lint.pyj +164 -164
  70. package/test/loops.pyj +85 -85
  71. package/test/numpy.pyj +734 -734
  72. package/test/pprint.pyj +232 -0
  73. package/test/repl.pyj +121 -121
  74. package/test/scoped_flags.pyj +76 -76
  75. package/test/statistics.pyj +224 -0
  76. package/test/unit/index.js +80 -0
  77. package/test/unit/language-service-completions.js +2 -0
  78. package/test/unit/language-service-dts.js +543 -543
  79. package/test/unit/language-service-hover.js +455 -455
  80. package/test/unit/language-service.js +63 -2
  81. package/test/unit/web-repl.js +323 -0
  82. package/tools/compiler.d.ts +367 -367
  83. package/tools/completer.js +131 -131
  84. package/tools/export.js +4 -2
  85. package/tools/gettext.js +185 -185
  86. package/tools/ini.js +65 -65
  87. package/tools/msgfmt.js +187 -187
  88. package/tools/repl.js +223 -223
  89. package/tools/test.js +118 -118
  90. package/tools/utils.js +128 -128
  91. package/tools/web_repl.js +95 -95
  92. package/try +41 -41
  93. package/web-repl/env.js +196 -196
  94. package/web-repl/index.html +163 -163
  95. package/web-repl/prism.css +139 -139
  96. package/web-repl/prism.js +113 -113
  97. package/web-repl/rapydscript.js +228 -226
  98. package/web-repl/sha1.js +25 -25
@@ -0,0 +1,455 @@
1
+ ###########################################################
2
+ # RapydScript Standard Library
3
+ # License: Apache License 2.0
4
+ # This library is covered under Apache license, so that
5
+ # you can distribute it with your RapydScript applications.
6
+ ###########################################################
7
+
8
+
9
+ # Implementation of Python's 'pprint' module.
10
+ #
11
+ # Pretty-prints arbitrary RapydScript / Python data structures.
12
+ #
13
+ # A value's repr() is used when it fits within `width`; otherwise containers
14
+ # are broken across multiple lines with Python-style indentation.
15
+ #
16
+ # Public API:
17
+ # pformat(object, ...) -> str
18
+ # pprint(object, ...)
19
+ # pp(object, ...) same as pprint but defaults sort_dicts=False
20
+ # saferepr(object) repr() with recursive references marked
21
+ # isreadable(object) whether pformat output can be parsed back
22
+ # isrecursive(object) whether the object has recursive references
23
+ # class PrettyPrinter
24
+
25
+
26
+ # ── private helpers ─────────────────────────────────────────────────────────
27
+
28
+ v"""
29
+ function _pp_is_plain_dict_like(obj) {
30
+ if (obj === null || obj === undefined) return false;
31
+ if (typeof obj !== 'object') return false;
32
+ if (Array.isArray(obj)) return false;
33
+ if (obj.jsmap && typeof obj.jsmap.forEach === 'function') return false;
34
+ if (obj.jsset && typeof obj.jsset.values === 'function') return false;
35
+ var proto = Object.getPrototypeOf(obj);
36
+ return proto === null || proto === Object.prototype;
37
+ }
38
+ var _pp_id_counter = 0;
39
+ function _pp_id(obj) {
40
+ if (obj === null || obj === undefined) return 0;
41
+ if (typeof obj !== 'object') return 0;
42
+ if (!obj.__pp_id__) {
43
+ Object.defineProperty(obj, '__pp_id__',
44
+ { value: ++_pp_id_counter, configurable: true, writable: true });
45
+ }
46
+ return obj.__pp_id__;
47
+ }
48
+ """
49
+
50
+
51
+ def _try_repr(x):
52
+ try:
53
+ return repr(x)
54
+ except:
55
+ return str(x)
56
+
57
+
58
+ def _cmp_pair(a, b):
59
+ try:
60
+ if a[0] < b[0]:
61
+ return -1
62
+ if a[0] > b[0]:
63
+ return 1
64
+ return 0
65
+ except:
66
+ return 0
67
+
68
+
69
+ def _cmp_value(a, b):
70
+ try:
71
+ if a < b:
72
+ return -1
73
+ if a > b:
74
+ return 1
75
+ return 0
76
+ except:
77
+ return 0
78
+
79
+
80
+ def _is_dict(obj):
81
+ if isinstance(obj, dict):
82
+ return True
83
+ return v'_pp_is_plain_dict_like(obj)'
84
+
85
+
86
+ def _get_dict_pairs(obj, sort_dicts):
87
+ pairs = v'[]'
88
+ if isinstance(obj, dict):
89
+ iterator = obj.items()
90
+ r = iterator.next()
91
+ while not r.done:
92
+ pairs.push(v'[r.value[0], r.value[1]]')
93
+ r = iterator.next()
94
+ else:
95
+ v"""
96
+ var _keys = Object.keys(obj);
97
+ for (var _i = 0; _i < _keys.length; _i++) {
98
+ pairs.push([_keys[_i], obj[_keys[_i]]]);
99
+ }
100
+ """
101
+ if sort_dicts:
102
+ pairs.sort(_cmp_pair)
103
+ return pairs
104
+
105
+
106
+ def _get_set_items(obj):
107
+ items = v'[]'
108
+ iterator = obj.jsset.values()
109
+ r = iterator.next()
110
+ while not r.done:
111
+ items.push(r.value)
112
+ r = iterator.next()
113
+ items.sort(_cmp_value)
114
+ return items
115
+
116
+
117
+ def _recursion_marker(obj):
118
+ name = 'object'
119
+ try:
120
+ if obj.constructor and obj.constructor.name:
121
+ name = obj.constructor.name
122
+ elif isinstance(obj, dict):
123
+ name = 'dict'
124
+ elif isinstance(obj, set):
125
+ name = 'set'
126
+ elif Array.isArray(obj):
127
+ name = 'list'
128
+ except:
129
+ pass
130
+ return '<Recursion on ' + name + ' with id=' + str(v'_pp_id(obj)') + '>'
131
+
132
+
133
+ def _safe_repr(obj, context, maxlevels, level, sort_dicts):
134
+ """Return [repr_string, readable, recursive].
135
+
136
+ readable -- True if the output is parseable back by eval
137
+ recursive -- True if obj (or any sub-object) recursively contains itself
138
+ """
139
+ if obj is None:
140
+ return v'["None", true, false]'
141
+ if obj is True:
142
+ return v'["True", true, false]'
143
+ if obj is False:
144
+ return v'["False", true, false]'
145
+ t = jstype(obj)
146
+ if t is 'number' or t is 'string' or t is 'bigint':
147
+ return v'[_try_repr(obj), true, false]'
148
+
149
+ obj_id = v'_pp_id(obj)'
150
+
151
+ if Array.isArray(obj):
152
+ if obj.length is 0:
153
+ return v'["[]", true, false]'
154
+ if maxlevels is not None and level >= maxlevels:
155
+ return v'["[...]", false, false]'
156
+ if context.has(obj):
157
+ return v'[_recursion_marker(obj), false, true]'
158
+ context.set(obj, 1)
159
+ components = v'[]'
160
+ readable = True
161
+ recursive = False
162
+ for v'var i = 0; i < obj.length; i++':
163
+ r = _safe_repr(obj[i], context, maxlevels, level + 1, sort_dicts)
164
+ components.push(r[0])
165
+ if not r[1]:
166
+ readable = False
167
+ if r[2]:
168
+ recursive = True
169
+ context.delete(obj)
170
+ return v'["[" + components.join(", ") + "]", readable, recursive]'
171
+
172
+ if isinstance(obj, set):
173
+ if obj.size is 0:
174
+ return v'["set()", false, false]'
175
+ if maxlevels is not None and level >= maxlevels:
176
+ return v'["{...}", false, false]'
177
+ if context.has(obj):
178
+ return v'[_recursion_marker(obj), false, true]'
179
+ context.set(obj, 1)
180
+ items = _get_set_items(obj)
181
+ components = v'[]'
182
+ readable = True
183
+ recursive = False
184
+ for v'var j = 0; j < items.length; j++':
185
+ r = _safe_repr(items[j], context, maxlevels, level + 1, sort_dicts)
186
+ components.push(r[0])
187
+ if not r[1]:
188
+ readable = False
189
+ if r[2]:
190
+ recursive = True
191
+ context.delete(obj)
192
+ return v'["{" + components.join(", ") + "}", readable, recursive]'
193
+
194
+ if isinstance(obj, frozenset):
195
+ if obj.size is 0:
196
+ return v'["frozenset()", true, false]'
197
+ if maxlevels is not None and level >= maxlevels:
198
+ return v'["frozenset({...})", false, false]'
199
+ items = _get_set_items(obj)
200
+ components = v'[]'
201
+ readable = True
202
+ recursive = False
203
+ for v'var k = 0; k < items.length; k++':
204
+ r = _safe_repr(items[k], context, maxlevels, level + 1, sort_dicts)
205
+ components.push(r[0])
206
+ if not r[1]:
207
+ readable = False
208
+ if r[2]:
209
+ recursive = True
210
+ return v'["frozenset({" + components.join(", ") + "})", readable, recursive]'
211
+
212
+ if _is_dict(obj):
213
+ pairs = _get_dict_pairs(obj, sort_dicts)
214
+ if pairs.length is 0:
215
+ return v'["{}", true, false]'
216
+ if maxlevels is not None and level >= maxlevels:
217
+ return v'["{...}", false, false]'
218
+ if context.has(obj):
219
+ return v'[_recursion_marker(obj), false, true]'
220
+ context.set(obj, 1)
221
+ components = v'[]'
222
+ readable = True
223
+ recursive = False
224
+ for v'var m = 0; m < pairs.length; m++':
225
+ kr = _safe_repr(pairs[m][0], context, maxlevels, level + 1, sort_dicts)
226
+ vr = _safe_repr(pairs[m][1], context, maxlevels, level + 1, sort_dicts)
227
+ components.push(kr[0] + ': ' + vr[0])
228
+ if not kr[1] or not vr[1]:
229
+ readable = False
230
+ if kr[2] or vr[2]:
231
+ recursive = True
232
+ context.delete(obj)
233
+ return v'["{" + components.join(", ") + "}", readable, recursive]'
234
+
235
+ # Class instance, function, etc. — fall back to repr().
236
+ rep = _try_repr(obj)
237
+ return v'[rep, false, false]'
238
+
239
+
240
+ # ── stream buffer used when no stream is given ──────────────────────────────
241
+
242
+ class _StreamBuffer:
243
+ def __init__(self):
244
+ self.parts = v'[]'
245
+
246
+ def write(self, s):
247
+ self.parts.push(s)
248
+
249
+ def getvalue(self):
250
+ return self.parts.join('')
251
+
252
+
253
+ # ── PrettyPrinter ───────────────────────────────────────────────────────────
254
+
255
+ class PrettyPrinter:
256
+ """Handle pretty-printing operations onto a stream."""
257
+
258
+ def __init__(self, indent=1, width=80, depth=None, stream=None,
259
+ compact=False, sort_dicts=True, underscore_numbers=False):
260
+ if jstype(indent) is not 'number' or indent < 0:
261
+ raise ValueError('indent must be a non-negative integer')
262
+ if jstype(width) is not 'number' or width < 0:
263
+ raise ValueError('width must be a non-negative integer')
264
+ if depth is not None:
265
+ if jstype(depth) is not 'number' or depth <= 0:
266
+ raise ValueError('depth must be > 0')
267
+ self._depth = depth
268
+ self._indent_per_level = indent
269
+ self._width = width
270
+ self._compact = bool(compact)
271
+ self._sort_dicts = bool(sort_dicts)
272
+ self._underscore_numbers = bool(underscore_numbers)
273
+ self._stream = stream
274
+
275
+ def pprint(self, object):
276
+ if self._stream is not None:
277
+ self._format(object, self._stream, 0, 0, v'new Map()', 0)
278
+ self._stream.write('\n')
279
+ else:
280
+ print(self.pformat(object))
281
+
282
+ def pformat(self, object):
283
+ buf = _StreamBuffer()
284
+ self._format(object, buf, 0, 0, v'new Map()', 0)
285
+ return buf.getvalue()
286
+
287
+ def isreadable(self, object):
288
+ r = _safe_repr(object, v'new Map()', self._depth, 0, self._sort_dicts)
289
+ return r[1] and not r[2]
290
+
291
+ def isrecursive(self, object):
292
+ r = _safe_repr(object, v'new Map()', self._depth, 0, self._sort_dicts)
293
+ return r[2]
294
+
295
+ def _format(self, obj, stream, indent, allowance, context, level):
296
+ if obj is not None and jstype(obj) is 'object' and context.has(obj):
297
+ stream.write(_recursion_marker(obj))
298
+ return
299
+
300
+ rep = self._repr(obj, context, level)
301
+ max_width = self._width - indent - allowance
302
+
303
+ if rep.length <= max_width:
304
+ stream.write(rep)
305
+ return
306
+
307
+ # too wide -- try to expand the container across multiple lines
308
+ if Array.isArray(obj) and obj.length > 0:
309
+ if self._depth is not None and level >= self._depth:
310
+ stream.write(rep)
311
+ return
312
+ context.set(obj, 1)
313
+ stream.write('[')
314
+ self._format_items(obj, stream, indent, allowance + 1, context, level + 1)
315
+ stream.write(']')
316
+ context.delete(obj)
317
+ return
318
+
319
+ if isinstance(obj, set) and obj.size > 0:
320
+ if self._depth is not None and level >= self._depth:
321
+ stream.write(rep)
322
+ return
323
+ context.set(obj, 1)
324
+ items = _get_set_items(obj)
325
+ stream.write('{')
326
+ self._format_items(items, stream, indent, allowance + 1, context, level + 1)
327
+ stream.write('}')
328
+ context.delete(obj)
329
+ return
330
+
331
+ if isinstance(obj, frozenset) and obj.size > 0:
332
+ if self._depth is not None and level >= self._depth:
333
+ stream.write(rep)
334
+ return
335
+ items = _get_set_items(obj)
336
+ stream.write('frozenset({')
337
+ self._format_items(items, stream, indent + 10, allowance + 2, context, level + 1)
338
+ stream.write('})')
339
+ return
340
+
341
+ if _is_dict(obj):
342
+ pairs = _get_dict_pairs(obj, self._sort_dicts)
343
+ if pairs.length > 0:
344
+ if self._depth is not None and level >= self._depth:
345
+ stream.write(rep)
346
+ return
347
+ context.set(obj, 1)
348
+ stream.write('{')
349
+ if self._indent_per_level > 1:
350
+ stream.write(' '.repeat(self._indent_per_level - 1))
351
+ self._format_dict_items(pairs, stream, indent, allowance + 1, context, level + 1)
352
+ stream.write('}')
353
+ context.delete(obj)
354
+ return
355
+
356
+ stream.write(rep)
357
+
358
+ def _format_items(self, items, stream, indent, allowance, context, level):
359
+ indent = indent + self._indent_per_level
360
+ if self._indent_per_level > 1:
361
+ stream.write(' '.repeat(self._indent_per_level - 1))
362
+ delimnl = ',\n' + ' '.repeat(indent)
363
+ delim = ''
364
+ width = self._width - indent + 1
365
+ max_width = width
366
+ last_index = items.length - 1
367
+ for v'var i = 0; i < items.length; i++':
368
+ last = i is last_index
369
+ ent = items[i]
370
+ if self._compact:
371
+ rep = self._repr(ent, context, level)
372
+ w = rep.length + 2
373
+ if width < w:
374
+ width = max_width
375
+ if delim:
376
+ delim = delimnl
377
+ if width >= w:
378
+ width -= w
379
+ stream.write(delim)
380
+ delim = ', '
381
+ stream.write(rep)
382
+ continue
383
+ stream.write(delim)
384
+ delim = delimnl
385
+ self._format(ent, stream, indent,
386
+ allowance if last else 1,
387
+ context, level)
388
+
389
+ def _format_dict_items(self, items, stream, indent, allowance, context, level):
390
+ indent = indent + self._indent_per_level
391
+ delimnl = ',\n' + ' '.repeat(indent)
392
+ last_index = items.length - 1
393
+ for v'var i = 0; i < items.length; i++':
394
+ last = i is last_index
395
+ key = items[i][0]
396
+ ent = items[i][1]
397
+ rep = self._repr(key, context, level)
398
+ stream.write(rep)
399
+ stream.write(': ')
400
+ self._format(ent, stream, indent + rep.length + 2,
401
+ allowance if last else 1, context, level)
402
+ if not last:
403
+ stream.write(delimnl)
404
+
405
+ def _repr(self, obj, context, level):
406
+ r = _safe_repr(obj, context, self._depth, level, self._sort_dicts)
407
+ return r[0]
408
+
409
+ def format(self, object, context, maxlevels, level):
410
+ """Hook for subclasses; returns (string, readable, recursive)."""
411
+ return _safe_repr(object, context, maxlevels, level, self._sort_dicts)
412
+
413
+
414
+ # ── module-level convenience functions ──────────────────────────────────────
415
+
416
+ def pformat(object, indent=1, width=80, depth=None, compact=False,
417
+ sort_dicts=True, underscore_numbers=False):
418
+ """Pretty-print a value as a string."""
419
+ return PrettyPrinter(indent=indent, width=width, depth=depth,
420
+ compact=compact, sort_dicts=sort_dicts,
421
+ underscore_numbers=underscore_numbers).pformat(object)
422
+
423
+
424
+ def pprint(object, stream=None, indent=1, width=80, depth=None,
425
+ compact=False, sort_dicts=True, underscore_numbers=False):
426
+ """Pretty-print a value to a stream, or to stdout if stream is None."""
427
+ PrettyPrinter(indent=indent, width=width, depth=depth, stream=stream,
428
+ compact=compact, sort_dicts=sort_dicts,
429
+ underscore_numbers=underscore_numbers).pprint(object)
430
+
431
+
432
+ def pp(object, stream=None, indent=1, width=80, depth=None,
433
+ compact=False, sort_dicts=False, underscore_numbers=False):
434
+ """Pretty-print with sort_dicts=False by default."""
435
+ pprint(object, stream=stream, indent=indent, width=width, depth=depth,
436
+ compact=compact, sort_dicts=sort_dicts,
437
+ underscore_numbers=underscore_numbers)
438
+
439
+
440
+ def saferepr(object):
441
+ """Like repr() but recursive references are marked as <Recursion ...>."""
442
+ r = _safe_repr(object, v'new Map()', None, 0, True)
443
+ return r[0]
444
+
445
+
446
+ def isreadable(object):
447
+ """True if pformat(object) is readable by eval()."""
448
+ r = _safe_repr(object, v'new Map()', None, 0, True)
449
+ return r[1] and not r[2]
450
+
451
+
452
+ def isrecursive(object):
453
+ """True if object contains any recursive references."""
454
+ r = _safe_repr(object, v'new Map()', None, 0, True)
455
+ return r[2]
@@ -1,118 +1,118 @@
1
- ###########################################################
2
- # RapydScript Standard Library
3
- # Author: Alexander Tsepkov
4
- # Copyright 2013 Pyjeon Software LLC
5
- # License: Apache License 2.0
6
- # This library is covered under Apache license, so that
7
- # you can distribute it with your RapydScript applications.
8
- ###########################################################
9
-
10
-
11
- # basic implementation of Python's 'random' library
12
-
13
- # JavaScript's Math.random() does not allow seeding its random generator, to bypass that, this module implements its own
14
- # version that can be seeded. I decided on RC4 algorithm for this.
15
-
16
- # please don't mess with this from the outside
17
-
18
- ρσ_seed_state = {
19
- 'key': [],
20
- 'key_i': 0,
21
- 'key_j': 0
22
- }
23
-
24
- ρσ_get_random_byte = def():
25
- ρσ_seed_state.key_i = (ρσ_seed_state.key_i + 1) % 256
26
- ρσ_seed_state.key_j = (ρσ_seed_state.key_j + ρσ_seed_state.key[ρσ_seed_state.key_i]) % 256
27
- ρσ_seed_state.key[ρσ_seed_state.key_i], ρσ_seed_state.key[ρσ_seed_state.key_j] = \
28
- ρσ_seed_state.key[ρσ_seed_state.key_j], ρσ_seed_state.key[ρσ_seed_state.key_i]
29
- return ρσ_seed_state.key[(ρσ_seed_state.key[ρσ_seed_state.key_i] + \
30
- ρσ_seed_state.key[ρσ_seed_state.key_j]) % 256]
31
-
32
- def seed(x=Date().getTime()):
33
- ρσ_seed_state.key_i = ρσ_seed_state.key_j = 0
34
- if jstype(x) is 'number':
35
- x = x.toString()
36
- elif jstype(x) is not 'string':
37
- raise TypeError("unhashable type: '" + jstype(x) + "'")
38
- for i in range(256):
39
- ρσ_seed_state.key[i] = i
40
- j = 0
41
- for i in range(256):
42
- j = (j + ρσ_seed_state.key[i] + x.charCodeAt(i % x.length)) % 256
43
- ρσ_seed_state.key[i], ρσ_seed_state.key[j] = ρσ_seed_state.key[j], ρσ_seed_state.key[i]
44
- seed()
45
-
46
- def random():
47
- n = 0
48
- m = 1
49
- for i in range(8):
50
- n += ρσ_get_random_byte() * m
51
- m *= 256
52
- return v'n / 0x10000000000000000'
53
-
54
- def randrange():
55
- if arguments.length is 1:
56
- return randbelow(int(arguments[0]))
57
- start = int(arguments[0])
58
- stop = int(arguments[1])
59
- if arguments.length < 3:
60
- step = 1
61
- else:
62
- step = int(arguments[2])
63
- width = stop - start
64
- if step is 1:
65
- if width > 0:
66
- return start + randbelow(width)
67
- raise ValueError("empty range for randrange()")
68
- if step > 0:
69
- n = (width + step - 1) // step
70
- elif step < 0:
71
- n = (width + step + 1) // step
72
- else:
73
- raise ValueError("zero step for randrange()")
74
- if n <= 0:
75
- raise ValueError(f"empty range in randrange({start}, {stop}, {step})")
76
- return start + step * randbelow(n)
77
-
78
-
79
- def randint(a, b):
80
- return int(random()*(b-a+1) + a)
81
-
82
- def uniform(a, b):
83
- return random()*(b-a) + a
84
-
85
- def randbelow(n):
86
- return Math.floor(random()*n)
87
-
88
- def choice(seq):
89
- if seq.length > 0:
90
- return seq[randbelow(seq.length)]
91
- else:
92
- raise IndexError()
93
-
94
- # uses Fisher-Yates algorithm to shuffle an array
95
- def shuffle(x, random_f=random):
96
- for i in range(x.length):
97
- j = Math.floor(random_f() * (i+1))
98
- x[i], x[j] = x[j], x[i]
99
- return x
100
-
101
- # similar to shuffle, but only shuffles a subset and creates a copy
102
- def sample(population, k):
103
- x = population.slice()
104
- for i in range(population.length-1, population.length-k-1, -1):
105
- j = Math.floor(random() * (i+1))
106
- x[i], x[j] = x[j], x[i]
107
- return x.slice(population.length-k)
108
-
109
-
110
- #import stdlib
111
- #a = range(50)
112
- #random.seed(5)
113
- #print(random.choice(a))
114
- #print(random.shuffle(a))
115
- #print(random.randrange(10))
116
- #print(random.randint(1,5))
117
- #print(random.uniform(1,5))
118
- #print(random.sample(range(20),5))
1
+ ###########################################################
2
+ # RapydScript Standard Library
3
+ # Author: Alexander Tsepkov
4
+ # Copyright 2013 Pyjeon Software LLC
5
+ # License: Apache License 2.0
6
+ # This library is covered under Apache license, so that
7
+ # you can distribute it with your RapydScript applications.
8
+ ###########################################################
9
+
10
+
11
+ # basic implementation of Python's 'random' library
12
+
13
+ # JavaScript's Math.random() does not allow seeding its random generator, to bypass that, this module implements its own
14
+ # version that can be seeded. I decided on RC4 algorithm for this.
15
+
16
+ # please don't mess with this from the outside
17
+
18
+ ρσ_seed_state = {
19
+ 'key': [],
20
+ 'key_i': 0,
21
+ 'key_j': 0
22
+ }
23
+
24
+ ρσ_get_random_byte = def():
25
+ ρσ_seed_state.key_i = (ρσ_seed_state.key_i + 1) % 256
26
+ ρσ_seed_state.key_j = (ρσ_seed_state.key_j + ρσ_seed_state.key[ρσ_seed_state.key_i]) % 256
27
+ ρσ_seed_state.key[ρσ_seed_state.key_i], ρσ_seed_state.key[ρσ_seed_state.key_j] = \
28
+ ρσ_seed_state.key[ρσ_seed_state.key_j], ρσ_seed_state.key[ρσ_seed_state.key_i]
29
+ return ρσ_seed_state.key[(ρσ_seed_state.key[ρσ_seed_state.key_i] + \
30
+ ρσ_seed_state.key[ρσ_seed_state.key_j]) % 256]
31
+
32
+ def seed(x=Date().getTime()):
33
+ ρσ_seed_state.key_i = ρσ_seed_state.key_j = 0
34
+ if jstype(x) is 'number':
35
+ x = x.toString()
36
+ elif jstype(x) is not 'string':
37
+ raise TypeError("unhashable type: '" + jstype(x) + "'")
38
+ for i in range(256):
39
+ ρσ_seed_state.key[i] = i
40
+ j = 0
41
+ for i in range(256):
42
+ j = (j + ρσ_seed_state.key[i] + x.charCodeAt(i % x.length)) % 256
43
+ ρσ_seed_state.key[i], ρσ_seed_state.key[j] = ρσ_seed_state.key[j], ρσ_seed_state.key[i]
44
+ seed()
45
+
46
+ def random():
47
+ n = 0
48
+ m = 1
49
+ for i in range(8):
50
+ n += ρσ_get_random_byte() * m
51
+ m *= 256
52
+ return v'n / 0x10000000000000000'
53
+
54
+ def randrange():
55
+ if arguments.length is 1:
56
+ return randbelow(int(arguments[0]))
57
+ start = int(arguments[0])
58
+ stop = int(arguments[1])
59
+ if arguments.length < 3:
60
+ step = 1
61
+ else:
62
+ step = int(arguments[2])
63
+ width = stop - start
64
+ if step is 1:
65
+ if width > 0:
66
+ return start + randbelow(width)
67
+ raise ValueError("empty range for randrange()")
68
+ if step > 0:
69
+ n = (width + step - 1) // step
70
+ elif step < 0:
71
+ n = (width + step + 1) // step
72
+ else:
73
+ raise ValueError("zero step for randrange()")
74
+ if n <= 0:
75
+ raise ValueError(f"empty range in randrange({start}, {stop}, {step})")
76
+ return start + step * randbelow(n)
77
+
78
+
79
+ def randint(a, b):
80
+ return int(random()*(b-a+1) + a)
81
+
82
+ def uniform(a, b):
83
+ return random()*(b-a) + a
84
+
85
+ def randbelow(n):
86
+ return Math.floor(random()*n)
87
+
88
+ def choice(seq):
89
+ if seq.length > 0:
90
+ return seq[randbelow(seq.length)]
91
+ else:
92
+ raise IndexError()
93
+
94
+ # uses Fisher-Yates algorithm to shuffle an array
95
+ def shuffle(x, random_f=random):
96
+ for i in range(x.length):
97
+ j = Math.floor(random_f() * (i+1))
98
+ x[i], x[j] = x[j], x[i]
99
+ return x
100
+
101
+ # similar to shuffle, but only shuffles a subset and creates a copy
102
+ def sample(population, k):
103
+ x = population.slice()
104
+ for i in range(population.length-1, population.length-k-1, -1):
105
+ j = Math.floor(random() * (i+1))
106
+ x[i], x[j] = x[j], x[i]
107
+ return x.slice(population.length-k)
108
+
109
+
110
+ #import stdlib
111
+ #a = range(50)
112
+ #random.seed(5)
113
+ #print(random.choice(a))
114
+ #print(random.shuffle(a))
115
+ #print(random.randrange(10))
116
+ #print(random.randint(1,5))
117
+ #print(random.uniform(1,5))
118
+ #print(random.sample(range(20),5))