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
package/README.md CHANGED
@@ -1381,19 +1381,28 @@ ba += bytearray([7, 8]) # in-place concatenation
1381
1381
 
1382
1382
  RapydScript provides a `long` builtin backed by JavaScript's native `BigInt`,
1383
1383
  giving you arbitrary-precision integers beyond the safe range of JS `Number`.
1384
+ You can use the `long()` function or Python-style `n` suffix literals:
1384
1385
 
1385
1386
  ```python
1387
+ # Literal syntax (preferred)
1388
+ a = 10n
1389
+ b = 3n
1390
+ c = 0xFFn # hex
1391
+ d = 0b1010n # binary
1392
+ e = 0o77n # octal
1393
+
1394
+ # Function syntax
1386
1395
  a = long(10)
1387
1396
  b = long(3)
1388
1397
 
1389
- a + b # long(13)
1390
- a - b # long(7)
1391
- a * b # long(30)
1392
- a // b # long(3) — floor division (Python semantics, not JS truncation)
1393
- a % b # long(1) — Python-style modulo (result has same sign as divisor)
1394
- a ** b # long(1000)
1395
- long(-7) // long(2) # long(-4) — floors toward −∞ (JS BigInt would give −3)
1396
- long(-7) % long(3) # long(2) — result matches sign of divisor
1398
+ a + b # 13n
1399
+ a - b # 7n
1400
+ a * b # 30n
1401
+ a // b # 3n — floor division (Python semantics, not JS truncation)
1402
+ a % b # 1n — Python-style modulo (result has same sign as divisor)
1403
+ a ** b # 1000n
1404
+ long(-7) // long(2) # -4n — floors toward −∞ (JS BigInt would give −3)
1405
+ long(-7) % long(3) # 2n — result matches sign of divisor
1397
1406
  ```
1398
1407
 
1399
1408
  #### Precision beyond JS Number
@@ -1402,9 +1411,13 @@ The main motivation for `long` is numbers outside the safe integer range of
1402
1411
  JavaScript `Number` (`2^53 − 1 = 9007199254740991`):
1403
1412
 
1404
1413
  ```python
1405
- n = long('9007199254740993') # 2^53 + 1 — cannot be represented as a JS Number
1406
- str(n) # '9007199254740993' (exact)
1407
- str(n + long(1)) # '9007199254740994' (still exact)
1414
+ n = 9007199254740993n # 2^53 + 1 — cannot be represented as a JS Number
1415
+ str(n) # '9007199254740993' (exact)
1416
+ str(n + 1n) # '9007199254740994' (still exact)
1417
+
1418
+ # equivalent using long():
1419
+ n = long('9007199254740993')
1420
+ str(n + long(1))
1408
1421
  ```
1409
1422
 
1410
1423
  #### Operator overloading
@@ -3455,7 +3468,7 @@ One of Python's main strengths is the number of libraries available to the devel
3455
3468
  # fields(), asdict(), astuple(), replace(), is_dataclass(), frozen=True, order=True
3456
3469
  abc # ABC base class, @abstractmethod, Protocol, @runtime_checkable;
3457
3470
  # abstract enforcement at instantiation; ABC.register() virtual subclasses
3458
- collections # namedtuple, deque, Counter, OrderedDict, defaultdict
3471
+ collections # namedtuple, deque, Counter, OrderedDict, defaultdict, ChainMap
3459
3472
  copy # copy (shallow), deepcopy; honours __copy__ / __deepcopy__ hooks
3460
3473
  typing # TYPE_CHECKING, Any, Union, Optional, List, Dict, Set, Tuple, TypeVar,
3461
3474
  # Generic, Protocol, Callable, Literal, Final, TypedDict, NamedTuple,
@@ -3465,6 +3478,8 @@ One of Python's main strengths is the number of libraries available to the devel
3465
3478
  # product, permutations, combinations, combinations_with_replacement
3466
3479
  io # StringIO (in-memory text stream), BytesIO (in-memory binary stream)
3467
3480
  base64 # b64encode/decode, urlsafe_b64encode/decode, b32encode/decode, b16encode/decode, encodebytes/decodebytes
3481
+ statistics # mean, median, mode, variance, stdev, quantiles, correlation,
3482
+ # linear_regression, NormalDist
3468
3483
 
3469
3484
  For the most part, the logic implemented in these libraries functions identically to the Python versions. I'd be happy to include more libraries, if other members of the community want them. However, unlike most other Python-to-JavaScript compilers, RapydScript doesn't need them to be complete since there are already tons of available JavaScript libraries that it can use natively.
3470
3485
 
@@ -4044,6 +4059,7 @@ Python Feature Coverage
4044
4059
  | f-strings, `str.format()`, `format()` builtin, all common `str.*` methods | Fully supported; includes `f'{x=}'` debug format (prints `x=<value>`), format-spec (`f'{x=:.2f}'`), and conversion (`f'{x=!r}'`) |
4045
4060
  | `abs()`, `divmod()`, `any()`, `all()`, `sum()`, `min()`, `max()` | All work |
4046
4061
  | `sorted()`, `reversed()`, `zip()`, `map()`, `filter()` | All work |
4062
+ | `list.sort()` / `sorted()` — `key`, `reverse`, comparators, `__lt__` | `key` and `reverse` keyword arguments both work; a positional **two-argument** function is auto-detected as a comparator (JS-style `.sort((a, b) => …)` / `functools.cmp_to_key` semantics) while a one-argument function is treated as a `key`; custom objects are ordered through their `__lt__` method (with a reflected `__gt__` fallback); the sort is stable, so equal elements keep their original order even under `reverse=True` |
4047
4063
  | `zip(strict=True)` | Raises `ValueError` when iterables have different lengths; equal-length iterables work normally |
4048
4064
  | `set` with full union/intersection/difference API | Fully supported |
4049
4065
  | `isinstance()`, `hasattr()`, `getattr()`, `setattr()`, `dir()` | All work |
@@ -4078,7 +4094,7 @@ Python Feature Coverage
4078
4094
  | `float.is_integer()` | Returns `True` if the float has no fractional part (i.e. is a whole number), `False` otherwise. `float('inf').is_integer()` and `float('nan').is_integer()` both return `False`, matching Python semantics. Added to `Number.prototype` in the baselib so it works on any numeric literal or variable. |
4079
4095
  | `int.bit_length()` | Returns the number of bits needed to represent the integer in binary, excluding the sign and leading zeros. `(0).bit_length()` → `0`; `(255).bit_length()` → `8`; `(256).bit_length()` → `9`; sign is ignored (`(-5).bit_length()` → `3`). Added to `Number.prototype` in the baselib. |
4080
4096
  | Arithmetic type coercion — `TypeError` on incompatible operands | `1 + '1'` raises `TypeError: unsupported operand type(s) for +: 'int' and 'str'`; all arithmetic operators (`+`, `-`, `*`, `/`, `//`, `%`, `**`) enforce compatible types in their `ρσ_op_*` helpers. `bool` is treated as numeric (like Python's `int` subclass). Activated by `overload_operators` (on by default). String `+` string and numeric `+` numeric are allowed; mixed types raise `TypeError` with a Python-style message. |
4081
- | `long(val[, base])` — arbitrary-precision integers | Backed by JS `BigInt`. `long(42)`, `long('ff', 16)`, `long('1010', 2)`, `long(True)`. Arithmetic: `+`, `-`, `*`, `//`, `%`, `**` — `//` and `%` follow Python floor-division semantics (floor toward −∞), not JS BigInt truncation. `/` raises `TypeError` (use `//`). Bitwise: `&`, `\|`, `^`, `<<`, `>>`. Comparisons: `<`, `<=`, `>`, `>=`, `==`, `!=`. `isinstance(x, long)` works. Mixing `long` with `int` or `float` raises `TypeError`. Requires `BigInt` (Chrome 67+, Firefox 68+, Safari 14+, Node 10.3+). |
4097
+ | `long(val[, base])` and `42n` literal — arbitrary-precision integers | Backed by JS `BigInt`. Literal syntax: `42n`, `0xFFn`, `0b1010n`, `0o77n`. Function syntax: `long(42)`, `long('ff', 16)`, `long('1010', 2)`, `long(True)`. Arithmetic: `+`, `-`, `*`, `//`, `%`, `**` — `//` and `%` follow Python floor-division semantics (floor toward −∞), not JS BigInt truncation. `/` raises `TypeError` (use `//`). Bitwise: `&`, `\|`, `^`, `<<`, `>>`. Comparisons: `<`, `<=`, `>`, `>=`, `==`, `!=`. `isinstance(x, long)` works. Mixing `long` with `int` or `float` raises `TypeError`. Requires `BigInt` (Chrome 67+, Firefox 68+, Safari 14+, Node 10.3+). |
4082
4098
  | `complex(real=0, imag=0)` and complex literals `3+4j` | Full complex number type via `ρσ_complex` class. `complex(real, imag)`, `complex(string)` (parses `'3+4j'`), and `j`/`J` imaginary literal suffix (e.g. `4j`, `3.5J`). Attributes: `.real`, `.imag`. Methods: `conjugate()`, `__abs__()`, `__bool__()`, `__repr__()`, `__str__()`. Arithmetic: `+`, `-`, `*`, `/`, `**` via dunder methods (or operator overloading with `overload_operators`). `abs(z)` dispatches `__abs__`. `isinstance(z, complex)` works. String representation matches Python: `(3+4j)`, `4j`, `(3-0j)`. |
4083
4099
  | `eval(expr[, globals[, locals]])` | String literals are compiled as **RapydScript source** at compile time (the compiler parses and transpiles the string, just like Python's `eval` takes Python source). `eval(expr)` maps to native JS direct `eval` for scope access. `eval(expr, globals)` / `eval(expr, globals, locals)` use `Function` constructor with explicit bindings; `locals` override `globals`. Runtime `ρσ_` helpers referenced in the compiled string are automatically injected into the Function scope. Only string *literals* are transformed at compile time; dynamic strings are passed through unchanged. |
4084
4100
  | `exec(code[, globals[, locals]])` | String literals are compiled as **RapydScript source** at compile time. Executes the compiled code string; always returns `None`. Without `globals`/`locals` uses native `eval` (scope access). With `globals`/`locals` uses `Function` constructor — mutable objects (lists, dicts) passed in `globals` are accessible by reference, so side-effects are visible after the call. `ρσ_dict` instances (created when `dict_literals` flag is active) are correctly unwrapped via their `jsmap` backing store. |
@@ -4163,7 +4179,7 @@ Modules with a `src/lib/` implementation available are marked ✅. All others ar
4163
4179
  | `random` | ✅ | RC4-seeded PRNG in `src/lib/random.pyj` |
4164
4180
  | `re` | ✅ | Regex wrapper in `src/lib/re.pyj`; uses the JS engine — full PCRE-level support on modern runtimes: positive/negative lookbehind (ES2018+, including variable-width), unicode via automatic `u` flag (ES2015+), `re.fullmatch()`, `re.S`/`re.NOFLAG` aliases. `MatchObject.start()`/`.end()` return exact positions on runtimes with the ES2022 `d` flag (Node 18+); heuristic fallback on older runtimes. Conditional groups `(?(id)yes\|no)` are not supported (JS limitation) and raise `re.error`. |
4165
4181
  | `encodings` | ✅ | UTF-8 encode/decode helpers and low-level base64 utilities; for the standard Python API use the `base64` module instead |
4166
- | `collections` | ✅ | `defaultdict`, `Counter`, `OrderedDict`, `deque` |
4182
+ | `collections` | ✅ | `defaultdict`, `Counter`, `OrderedDict`, `deque`, `namedtuple`, `ChainMap` |
4167
4183
  | `functools` | ✅ | `reduce`, `partial`, `wraps`, `lru_cache` |
4168
4184
  | `itertools` | ✅ | Common iteration tools |
4169
4185
  | `numpy` | ✅ | Full numpy-like library in `src/lib/numpy.pyj`; `numpy.random` and `numpy.linalg` sub-modules |
@@ -4187,11 +4203,15 @@ Modules with a `src/lib/` implementation available are marked ✅. All others ar
4187
4203
  | `textwrap` | ✅ | `wrap(text[, width=70[, ...]])`, `fill(text[, width=70[, ...]])`, `shorten(text, width[, ...])`, `dedent(text)`, `indent(text, prefix[, predicate])`, `TextWrapper` class in `src/lib/textwrap.pyj`; `TextWrapper` supports all standard options: `width`, `initial_indent`, `subsequent_indent`, `expand_tabs`, `tabsize`, `replace_whitespace`, `fix_sentence_endings`, `break_long_words`, `break_on_hyphens`, `drop_whitespace`, `max_lines`, `placeholder`; module-level `wrap`/`fill`/`shorten` accept the same options as explicit keyword parameters; `shorten()` normalises internal whitespace before truncating; `break_on_hyphens=True` (default) splits on em-dashes (2+ hyphens) between word characters, matching Python 3 behaviour |
4188
4204
  | `logging` | ✅ | `getLogger(name)`, `basicConfig(**kwargs)`, `debug/info/warning/error/critical/exception/log()` module-level shortcuts, `disable(level)`, `addLevelName(level, name)`, `getLevelName(level)`, `captureWarnings(capture)`, `makeLogRecord(dict)`, `setLogRecordFactory(factory)`, `getLogRecordFactory()` in `src/lib/logging.pyj`; `Logger` class with `setLevel`, `isEnabledFor`, `getEffectiveLevel`, `addHandler`, `removeHandler`, `hasHandlers`, `addFilter`, `removeFilter`, `debug/info/warning/error/critical/exception/log` methods; `Handler` base class; `StreamHandler(stream=None)` (writes to `console.debug/info/warn/error` when no stream given, or to any object with `.write(s)`); `NullHandler`; `Formatter(fmt, datefmt, style)` with full `%(attr)s/d/f` record formatting and `formatTime(record, datefmt)` (supports `%Y %m %d %H %M %S %f` strftime codes); `Filter(name)` and `Filterer` mixin; `LogRecord` with `getMessage()` supporting `%s/%d/%f/%e/%g/%x/%o/%%` %-formatting; level constants `NOTSET=0`, `DEBUG=10`, `INFO=20`, `WARNING=30`, `ERROR=40`, `CRITICAL=50`; full logger hierarchy (dotted names, `propagate`, `parent`); `lastResort` handler; note: `FileHandler` raises `NotImplementedError` (no file I/O in JS); `exception()` logs at ERROR without automatic exc_info capture |
4189
4205
  | `heapq` | ✅ | `heappush(heap, item)`, `heappop(heap)`, `heapify(x)`, `heapreplace(heap, item)`, `heappushpop(heap, item)`, `nsmallest(n, iterable[, key])`, `nlargest(n, iterable[, key])` in `src/lib/heapq.pyj`; min-heap operations on plain lists; heap invariant maintained by sift-up/sift-down (ported from CPython); `nsmallest`/`nlargest` support an optional `key` function; `heappop` and `heapreplace` raise `IndexError` on an empty heap; original iterable is not mutated by `nsmallest`/`nlargest` |
4206
+ | `pprint` | ✅ | `pformat(object, ...)` → str, `pprint(object[, stream], ...)`, `pp(object, ...)` (same as `pprint` but `sort_dicts=False` by default), `saferepr(object)`, `isreadable(object)`, `isrecursive(object)`, `PrettyPrinter` class in `src/lib/pprint.pyj`; keyword options `indent` (default 1), `width` (default 80), `depth`, `compact`, `sort_dicts` (default True), `underscore_numbers` (accepted, currently a no-op); a value's `repr()` is used when it fits within `width`, otherwise lists/tuples/dicts/sets/frozensets are broken across multiple lines with Python-style indentation; recursive references are detected and rendered as `<Recursion on … with id=…>`; pretty-prints RapydScript `dict`/`set`/`frozenset`, plain JS objects, and arrays; `pprint`/`pp` write to a `stream` object's `.write()` (defaulting to stdout via `print()`) |
4207
+ | `statistics` | ✅ | `mean`, `fmean`, `geometric_mean`, `harmonic_mean`, `median`, `median_low`, `median_high`, `median_grouped`, `mode`, `multimode`, `variance`, `pvariance`, `stdev`, `pstdev`, `quantiles`, `covariance`, `correlation`, `linear_regression` in `src/lib/statistics.pyj`; `NormalDist` class (`.mean`/`.median`/`.mode`/`.stdev`/`.variance` properties, `pdf()`, `cdf()`, `inv_cdf()`, `quantiles()`, `zscore()`, `overlap()`, `samples(n[, seed])`, `from_samples()`, plus arithmetic with scalars and other `NormalDist` instances); `StatisticsError` (a `ValueError` subclass); every data argument may be a list, a JS array, a string, or any iterable; `correlation()` supports `method='ranked'` (Spearman); `quantiles()` supports `method='inclusive'`/`'exclusive'`; `linear_regression()` returns an object with `.slope`/`.intercept`; all computation is IEEE-754 double precision (no `Fraction`/`Decimal` preservation), and `cdf()`/`overlap()` use a rational error-function approximation accurate to ~1e-7 |
4208
+ | `decimal` | ❌ | Fixed-precision decimal arithmetic not available; JS `Number` is IEEE-754 only |
4209
+ | `fractions` | ❌ | Rational arithmetic (`Fraction(num, den)`) not available |
4210
+ | `difflib` | ❌ | `unified_diff`, `SequenceMatcher`, `get_close_matches` not available |
4190
4211
  | `inspect` | ❌ | `signature`, `getmembers`, `isfunction` etc. not available |
4191
4212
  | `struct` | ❌ | Binary packing/unpacking not available |
4192
4213
  | `hashlib` | ❌ | MD5, SHA-256 etc. not available; use Web Crypto API via verbatim JS |
4193
4214
  | `hmac` | ❌ | Keyed hashing not available |
4194
- | `pprint` | ❌ | Pretty-printing not available |
4195
4215
  | `unittest` | ❌ | Not available; RapydScript uses a custom test runner (`node bin/rapydscript test`) |
4196
4216
 
4197
4217
  ---
package/TODO.md CHANGED
@@ -1,34 +1,9 @@
1
1
 
2
- ### libraries
3
-
4
- - The 7n literal isn't supported by the parser — use BigInt()
5
2
 
6
3
  - remove repl_mode and make repl make a new context for each "run" press
7
4
 
8
5
  - vscode plugin based on language service?
9
6
 
10
7
 
11
- I would like you to add support for [python async def functions with yield (async generators)] to rapydscript. It should have the same syntax as the Python implementation, and be transpiled into equivalent javascript. Ensure with unit tests that it transpiles and the output JS runs correctly, and that the language service correctly handles it in parsed code. Make sure it works in the web-repl. Update the README if it has any outdated info about this, and the PYTHON_FEATURE_COVERAGE report. Add a simple example to the bottom of the TODO document using this feature (make no other changes to that file). Remove the suggestion from PYTHON_GAPS if it is there.
12
-
13
- ### Async generator example
14
-
15
- ```py
16
- # `async def` + `yield` makes an async generator. The function returns an
17
- # async iterator immediately; values are pulled with `await it.next()` or
18
- # consumed with `async for`.
19
-
20
- from asyncio import sleep
21
-
22
- async def countdown(n):
23
- while n > 0:
24
- await sleep(0) # cooperative yield to the event loop
25
- yield n
26
- n -= 1
27
-
28
- async def main():
29
- async for x in countdown(3):
30
- print(x) # prints 3, then 2, then 1
31
-
32
- main()
33
- ```
8
+ I would like you to add support for [python 7n style literal] to rapydscript. It should have the same syntax as the Python implementation, and be transpiled into equivalent javascript. Ensure with unit tests that it transpiles and the output JS runs correctly, and that the language service correctly handles it in parsed code. Make sure it works in the web-repl. Update the README if it has any outdated info about this, and the PYTHON_FEATURE_COVERAGE report. Add a simple example to the bottom of the TODO document using this feature (make no other changes to that file). Remove the suggestion from PYTHON_GAPS if it is there.
34
9
 
package/add-toc-to-readme CHANGED
@@ -1,2 +1,2 @@
1
- #!/bin/sh
2
- exec node_modules/doctoc/doctoc.js --title '**Contents**' README.md
1
+ #!/bin/sh
2
+ exec node_modules/doctoc/doctoc.js --title '**Contents**' README.md
package/bin/export CHANGED
@@ -1,75 +1,75 @@
1
- #!/usr/bin/env node
2
- // vim:ft=javascript:ts=4:et
3
-
4
- "use strict";
5
-
6
- var fs = require('fs');
7
- var path = require('path');
8
- var crypto = require('crypto');
9
-
10
- var base = path.join(path.dirname(__dirname));
11
- var meta = JSON.parse(fs.readFileSync(path.join(base, 'package.json'), {'encoding':'utf-8'}));
12
- var compiler_dir = path.join(base, 'dev');
13
- if (!path_exists(path.join(compiler_dir, 'compiler.js'))) compiler_dir = path.join(base, 'release');
14
-
15
- var manifest = {}, total = 0;
16
- ['compiler.js', 'baselib-plain-pretty.js', 'baselib-plain-ugly.js'].forEach(function(x) {
17
- manifest[x] = fs.readFileSync(path.join(compiler_dir, x), {'encoding':'utf-8'});
18
- total += manifest[x].length;
19
- });
20
-
21
- ['web_repl.js', 'repl.js', 'completer.js', 'utils.js', 'gettext.js', 'msgfmt.js'].forEach(function(x) {
22
- x = 'tools/' + x;
23
- manifest[x] = fs.readFileSync(path.join(base, x), {'encoding':'utf-8'});
24
- total += manifest[x].length;
25
- });
26
-
27
-
28
- var dedup = {};
29
-
30
- function path_exists(path) {
31
- try {
32
- fs.statSync(path);
33
- return true;
34
- } catch(e) {
35
- if (e.code != 'ENOENT') throw e;
36
- }
37
- }
38
-
39
- function sha1sum(data) {
40
- var h = crypto.createHash('sha1');
41
- h.update(data);
42
- return h.digest('hex');
43
- }
44
-
45
- function process_dir(name) {
46
- var dpath = path.join(base, name);
47
- var items = fs.readdirSync(dpath);
48
- items.forEach(function (x) {
49
- var iname = name + '/' + x;
50
- var ipath = path.join(dpath, x);
51
- var s = fs.statSync(ipath);
52
- if (s.isDirectory()) return process_dir(iname);
53
- var raw = fs.readFileSync(ipath, {'encoding':'utf-8'});
54
- var sig = sha1sum(raw);
55
- if (dedup.hasOwnProperty(sig)) {
56
- manifest[iname] = [dedup[sig]];
57
- } else {
58
- manifest[iname] = raw;
59
- dedup[sig] = iname;
60
- total += s.size;
61
- }
62
- });
63
- }
64
-
65
- Object.keys(meta.dependencies).forEach(function (x) {
66
- process_dir('node_modules/' + x);
67
- });
68
- console.log('// vim:fileencoding=utf-8');
69
- console.log('(function() {');
70
- console.log('var rs_version = ' + JSON.stringify(meta.version) + ';');
71
- console.log('var data = ' + JSON.stringify(manifest) + ';');
72
- console.log();
73
- console.log(fs.readFileSync(path.join(base, 'tools', 'export.js'), {'encoding':'utf-8'}));
74
- console.log('})()');
75
- console.error('RapydScript compiler (uncompressed) size: ' + (total/(1024 * 1024)).toFixed(1) + ' MB');
1
+ #!/usr/bin/env node
2
+ // vim:ft=javascript:ts=4:et
3
+
4
+ "use strict";
5
+
6
+ var fs = require('fs');
7
+ var path = require('path');
8
+ var crypto = require('crypto');
9
+
10
+ var base = path.join(path.dirname(__dirname));
11
+ var meta = JSON.parse(fs.readFileSync(path.join(base, 'package.json'), {'encoding':'utf-8'}));
12
+ var compiler_dir = path.join(base, 'dev');
13
+ if (!path_exists(path.join(compiler_dir, 'compiler.js'))) compiler_dir = path.join(base, 'release');
14
+
15
+ var manifest = {}, total = 0;
16
+ ['compiler.js', 'baselib-plain-pretty.js', 'baselib-plain-ugly.js'].forEach(function(x) {
17
+ manifest[x] = fs.readFileSync(path.join(compiler_dir, x), {'encoding':'utf-8'});
18
+ total += manifest[x].length;
19
+ });
20
+
21
+ ['web_repl.js', 'repl.js', 'completer.js', 'utils.js', 'gettext.js', 'msgfmt.js'].forEach(function(x) {
22
+ x = 'tools/' + x;
23
+ manifest[x] = fs.readFileSync(path.join(base, x), {'encoding':'utf-8'});
24
+ total += manifest[x].length;
25
+ });
26
+
27
+
28
+ var dedup = {};
29
+
30
+ function path_exists(path) {
31
+ try {
32
+ fs.statSync(path);
33
+ return true;
34
+ } catch(e) {
35
+ if (e.code != 'ENOENT') throw e;
36
+ }
37
+ }
38
+
39
+ function sha1sum(data) {
40
+ var h = crypto.createHash('sha1');
41
+ h.update(data);
42
+ return h.digest('hex');
43
+ }
44
+
45
+ function process_dir(name) {
46
+ var dpath = path.join(base, name);
47
+ var items = fs.readdirSync(dpath);
48
+ items.forEach(function (x) {
49
+ var iname = name + '/' + x;
50
+ var ipath = path.join(dpath, x);
51
+ var s = fs.statSync(ipath);
52
+ if (s.isDirectory()) return process_dir(iname);
53
+ var raw = fs.readFileSync(ipath, {'encoding':'utf-8'});
54
+ var sig = sha1sum(raw);
55
+ if (dedup.hasOwnProperty(sig)) {
56
+ manifest[iname] = [dedup[sig]];
57
+ } else {
58
+ manifest[iname] = raw;
59
+ dedup[sig] = iname;
60
+ total += s.size;
61
+ }
62
+ });
63
+ }
64
+
65
+ Object.keys(meta.dependencies).forEach(function (x) {
66
+ process_dir('node_modules/' + x);
67
+ });
68
+ console.log('// vim:fileencoding=utf-8');
69
+ console.log('(function() {');
70
+ console.log('var rs_version = ' + JSON.stringify(meta.version) + ';');
71
+ console.log('var data = ' + JSON.stringify(manifest) + ';');
72
+ console.log();
73
+ console.log(fs.readFileSync(path.join(base, 'tools', 'export.js'), {'encoding':'utf-8'}));
74
+ console.log('})()');
75
+ console.error('RapydScript compiler (uncompressed) size: ' + (total/(1024 * 1024)).toFixed(1) + ' MB');
package/bin/rapydscript CHANGED
File without changes
@@ -1,102 +1,102 @@
1
- #!/usr/bin/env node
2
- // vim:ft=javascript:ts=4:et
3
-
4
- "use strict";
5
-
6
- var fs = require('fs');
7
- var path = require('path');
8
-
9
- var base = path.normalize(path.resolve(path.join(path.dirname(__dirname))));
10
- var meta = JSON.parse(fs.readFileSync(path.join(base, 'package.json'), {'encoding':'utf-8'}));
11
- var commit_sha = fs.readFileSync(path.join(base, '.git', 'refs', 'heads', 'master'), {'encoding':'utf-8'}).trim();
12
- var compiler_dir = path.join(base, 'dev');
13
- if (!path_exists(path.join(compiler_dir, 'compiler.js'))) compiler_dir = path.join(base, 'release');
14
-
15
- var manifest = {}, total = 0;
16
- ['compiler.js', 'baselib-plain-pretty.js'].forEach(function(x) {
17
- manifest[x] = fs.readFileSync(path.join(compiler_dir, x), {'encoding':'utf-8'});
18
- total += manifest[x].length;
19
- });
20
-
21
- ['web_repl.js', 'embedded_compiler.js', 'utils.js', 'completer.js', 'msgfmt.js', 'gettext.js'].forEach(function(x) {
22
- x = 'tools/' + x;
23
- manifest[x] = fs.readFileSync(path.join(base, x), {'encoding':'utf-8'});
24
- total += manifest[x].length;
25
- });
26
-
27
- var stdlib = path.join(base, 'src', 'lib');
28
-
29
- function path_exists(path) {
30
- try {
31
- fs.statSync(path);
32
- return true;
33
- } catch(e) {
34
- if (e.code != 'ENOENT') throw e;
35
- }
36
- }
37
-
38
- function process_dir(relpath) {
39
- var fullpath = (relpath) ? path.join(stdlib, relpath) : stdlib;
40
- fs.readdirSync(fullpath).forEach(function (x) {
41
- var q = path.join(fullpath, x);
42
- var s = fs.statSync(q);
43
- if (s.isDirectory()) return process_dir(relpath + '/' + x);
44
- if (!x.endsWith('.pyj')) return;
45
- var iname = ('__stdlib__' + '/' + relpath + '/' + x).replace(/\\/g, '/').replace(/\/+/g, '/');
46
- var raw = fs.readFileSync(q, {'encoding':'utf-8'});
47
- manifest[iname] = raw;
48
- total += s.size;
49
- });
50
- }
51
- process_dir('');
52
-
53
-
54
- var rs = '// vim:fileencoding=utf-8\n';
55
- rs += '(function(external_namespace) {\n';
56
- rs += '"use strict;"\n';
57
- rs += 'var rs_version = ' + JSON.stringify(meta.version) + ';\n';
58
- rs += 'var rs_commit_sha = ' + JSON.stringify(commit_sha) + ';\n';
59
- rs += '\n// Embedded modules {{{\n';
60
- rs += 'var data = ' + JSON.stringify(manifest) + ';\n\n';
61
- rs += '// End embedded modules }}}\n\n';
62
- rs += fs.readFileSync(path.join(base, 'web-repl', 'env.js'));
63
- rs += '\n// Embedded sha1 implementation {{{\n';
64
- rs += '(function() {\n';
65
- rs += fs.readFileSync(path.join(base, 'web-repl', 'sha1.js'));
66
- rs += '}).call(jsSHA);\n';
67
- rs += '// End embedded sha1 implementation }}}\n\n';
68
- rs += 'var exports = namespace;\n';
69
- rs += fs.readFileSync(path.join(base, 'tools', 'export.js'), {'encoding':'utf-8'});
70
- rs += 'external_namespace.RapydScript = namespace;\n';
71
- rs += '})(this);\n';
72
-
73
-
74
- var base_dir = process.argv.slice(-1)[0];
75
- if (process.argv.length !== 3) {
76
- console.error('Usage: web-repl-export /path/to/export/directory');
77
- process.exit(1);
78
- }
79
-
80
- base_dir = path.normalize(path.resolve(base_dir));
81
-
82
- try {
83
- fs.mkdirSync(base_dir);
84
- } catch(e) {
85
- if (e.code !== 'EEXIST') throw e;
86
- }
87
-
88
- try {
89
- process.chdir(base_dir);
90
- } catch(e) {
91
- if (e.code === 'ENOTDIR') { console.error(base_dir + ' is not a directory'); process.exit(1); }
92
- throw e;
93
- }
94
- fs.writeFileSync('rapydscript.js', rs, {'encoding':'utf-8'});
95
- var web_repl = path.join(base, 'web-repl');
96
- fs.readdirSync(web_repl).forEach(function(x) {
97
- if (['sha1.js', 'env.js'].indexOf(x) !== -1) return;
98
- var data = fs.readFileSync(path.join(web_repl, x), {'encoding':'utf-8'});
99
- fs.writeFileSync(x, data, {'encoding':'utf-8'});
100
- });
101
- console.log('RapydScript compiler (uncompressed) size: ' + (total/(1024)).toFixed(1) + ' KB');
102
- console.log('web-repl exported to: ' + base_dir);
1
+ #!/usr/bin/env node
2
+ // vim:ft=javascript:ts=4:et
3
+
4
+ "use strict";
5
+
6
+ var fs = require('fs');
7
+ var path = require('path');
8
+
9
+ var base = path.normalize(path.resolve(path.join(path.dirname(__dirname))));
10
+ var meta = JSON.parse(fs.readFileSync(path.join(base, 'package.json'), {'encoding':'utf-8'}));
11
+ var commit_sha = fs.readFileSync(path.join(base, '.git', 'refs', 'heads', 'master'), {'encoding':'utf-8'}).trim();
12
+ var compiler_dir = path.join(base, 'dev');
13
+ if (!path_exists(path.join(compiler_dir, 'compiler.js'))) compiler_dir = path.join(base, 'release');
14
+
15
+ var manifest = {}, total = 0;
16
+ ['compiler.js', 'baselib-plain-pretty.js'].forEach(function(x) {
17
+ manifest[x] = fs.readFileSync(path.join(compiler_dir, x), {'encoding':'utf-8'});
18
+ total += manifest[x].length;
19
+ });
20
+
21
+ ['web_repl.js', 'embedded_compiler.js', 'utils.js', 'completer.js', 'msgfmt.js', 'gettext.js'].forEach(function(x) {
22
+ x = 'tools/' + x;
23
+ manifest[x] = fs.readFileSync(path.join(base, x), {'encoding':'utf-8'});
24
+ total += manifest[x].length;
25
+ });
26
+
27
+ var stdlib = path.join(base, 'src', 'lib');
28
+
29
+ function path_exists(path) {
30
+ try {
31
+ fs.statSync(path);
32
+ return true;
33
+ } catch(e) {
34
+ if (e.code != 'ENOENT') throw e;
35
+ }
36
+ }
37
+
38
+ function process_dir(relpath) {
39
+ var fullpath = (relpath) ? path.join(stdlib, relpath) : stdlib;
40
+ fs.readdirSync(fullpath).forEach(function (x) {
41
+ var q = path.join(fullpath, x);
42
+ var s = fs.statSync(q);
43
+ if (s.isDirectory()) return process_dir(relpath + '/' + x);
44
+ if (!x.endsWith('.pyj')) return;
45
+ var iname = ('__stdlib__' + '/' + relpath + '/' + x).replace(/\\/g, '/').replace(/\/+/g, '/');
46
+ var raw = fs.readFileSync(q, {'encoding':'utf-8'});
47
+ manifest[iname] = raw;
48
+ total += s.size;
49
+ });
50
+ }
51
+ process_dir('');
52
+
53
+
54
+ var rs = '// vim:fileencoding=utf-8\n';
55
+ rs += '(function(external_namespace) {\n';
56
+ rs += '"use strict;"\n';
57
+ rs += 'var rs_version = ' + JSON.stringify(meta.version) + ';\n';
58
+ rs += 'var rs_commit_sha = ' + JSON.stringify(commit_sha) + ';\n';
59
+ rs += '\n// Embedded modules {{{\n';
60
+ rs += 'var data = ' + JSON.stringify(manifest) + ';\n\n';
61
+ rs += '// End embedded modules }}}\n\n';
62
+ rs += fs.readFileSync(path.join(base, 'web-repl', 'env.js'));
63
+ rs += '\n// Embedded sha1 implementation {{{\n';
64
+ rs += '(function() {\n';
65
+ rs += fs.readFileSync(path.join(base, 'web-repl', 'sha1.js'));
66
+ rs += '}).call(jsSHA);\n';
67
+ rs += '// End embedded sha1 implementation }}}\n\n';
68
+ rs += 'var exports = namespace;\n';
69
+ rs += fs.readFileSync(path.join(base, 'tools', 'export.js'), {'encoding':'utf-8'});
70
+ rs += 'external_namespace.RapydScript = namespace;\n';
71
+ rs += '})(this);\n';
72
+
73
+
74
+ var base_dir = process.argv.slice(-1)[0];
75
+ if (process.argv.length !== 3) {
76
+ console.error('Usage: web-repl-export /path/to/export/directory');
77
+ process.exit(1);
78
+ }
79
+
80
+ base_dir = path.normalize(path.resolve(base_dir));
81
+
82
+ try {
83
+ fs.mkdirSync(base_dir);
84
+ } catch(e) {
85
+ if (e.code !== 'EEXIST') throw e;
86
+ }
87
+
88
+ try {
89
+ process.chdir(base_dir);
90
+ } catch(e) {
91
+ if (e.code === 'ENOTDIR') { console.error(base_dir + ' is not a directory'); process.exit(1); }
92
+ throw e;
93
+ }
94
+ fs.writeFileSync('rapydscript.js', rs, {'encoding':'utf-8'});
95
+ var web_repl = path.join(base, 'web-repl');
96
+ fs.readdirSync(web_repl).forEach(function(x) {
97
+ if (['sha1.js', 'env.js'].indexOf(x) !== -1) return;
98
+ var data = fs.readFileSync(path.join(web_repl, x), {'encoding':'utf-8'});
99
+ fs.writeFileSync(x, data, {'encoding':'utf-8'});
100
+ });
101
+ console.log('RapydScript compiler (uncompressed) size: ' + (total/(1024)).toFixed(1) + ' KB');
102
+ console.log('web-repl exported to: ' + base_dir);
package/build CHANGED
@@ -1,3 +1,3 @@
1
- #!/bin/sh
2
- exec bin/rapydscript self --complete --test
1
+ #!/bin/sh
2
+ exec bin/rapydscript self --complete --test
3
3
  exec bin/web-repl-export web-repl