subscript 9.1.0 → 10.0.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 (82) hide show
  1. package/README.md +123 -171
  2. package/feature/access.js +67 -7
  3. package/feature/accessor.js +49 -0
  4. package/feature/asi.js +15 -0
  5. package/feature/async.js +45 -0
  6. package/feature/block.js +41 -0
  7. package/feature/class.js +69 -0
  8. package/feature/collection.js +40 -0
  9. package/feature/comment.js +25 -6
  10. package/feature/destruct.js +33 -0
  11. package/feature/function.js +44 -0
  12. package/feature/group.js +41 -12
  13. package/feature/if.js +28 -0
  14. package/feature/literal.js +13 -0
  15. package/feature/loop.js +123 -0
  16. package/feature/module.js +42 -0
  17. package/feature/number.js +45 -10
  18. package/feature/op/arithmetic.js +29 -0
  19. package/feature/op/arrow.js +33 -0
  20. package/feature/op/assign-logical.js +33 -0
  21. package/feature/op/assignment.js +47 -0
  22. package/feature/op/bitwise-unsigned.js +17 -0
  23. package/feature/op/bitwise.js +29 -0
  24. package/feature/op/comparison.js +19 -0
  25. package/feature/op/defer.js +15 -0
  26. package/feature/op/equality.js +16 -0
  27. package/feature/op/identity.js +15 -0
  28. package/feature/op/increment.js +23 -0
  29. package/feature/op/logical.js +21 -0
  30. package/feature/op/membership.js +17 -0
  31. package/feature/op/nullish.js +13 -0
  32. package/feature/op/optional.js +61 -0
  33. package/feature/op/pow.js +19 -0
  34. package/feature/op/range.js +26 -0
  35. package/feature/op/spread.js +15 -0
  36. package/feature/op/ternary.js +15 -0
  37. package/feature/op/type.js +18 -0
  38. package/feature/op/unary.js +41 -0
  39. package/feature/prop.js +34 -0
  40. package/feature/regex.js +31 -0
  41. package/feature/seq.js +21 -0
  42. package/feature/string.js +24 -16
  43. package/feature/switch.js +48 -0
  44. package/feature/template.js +39 -0
  45. package/feature/try.js +57 -0
  46. package/feature/unit.js +35 -0
  47. package/feature/var.js +59 -0
  48. package/jessie.js +31 -0
  49. package/jessie.min.js +8 -0
  50. package/justin.js +39 -48
  51. package/justin.min.js +8 -1
  52. package/package.json +18 -23
  53. package/parse.js +153 -0
  54. package/subscript.d.ts +45 -5
  55. package/subscript.js +62 -22
  56. package/subscript.min.js +5 -1
  57. package/util/bundle.js +507 -0
  58. package/util/stringify.js +172 -0
  59. package/feature/add.js +0 -22
  60. package/feature/array.js +0 -11
  61. package/feature/arrow.js +0 -23
  62. package/feature/assign.js +0 -11
  63. package/feature/bitwise.js +0 -11
  64. package/feature/bool.js +0 -5
  65. package/feature/call.js +0 -15
  66. package/feature/compare.js +0 -11
  67. package/feature/increment.js +0 -11
  68. package/feature/logic.js +0 -11
  69. package/feature/mult.js +0 -25
  70. package/feature/object.js +0 -17
  71. package/feature/optional.js +0 -30
  72. package/feature/pow.js +0 -5
  73. package/feature/shift.js +0 -12
  74. package/feature/spread.js +0 -6
  75. package/feature/ternary.js +0 -10
  76. package/src/compile.d.ts +0 -17
  77. package/src/compile.js +0 -28
  78. package/src/const.js +0 -42
  79. package/src/parse.d.ts +0 -22
  80. package/src/parse.js +0 -114
  81. package/src/stringify.js +0 -31
  82. /package/{LICENSE → license} +0 -0
package/src/parse.js DELETED
@@ -1,114 +0,0 @@
1
- import { SPACE } from "./const.js"
2
-
3
- // current string, index and collected ids
4
- export let idx, cur,
5
-
6
- // no handling tagged literals since easily done on user side with cache, if needed
7
- parse = s => (idx = 0, cur = s, s = expr(), cur[idx] ? err() : s || ''),
8
-
9
- // display error
10
- err = (msg = 'Bad syntax',
11
- lines = cur.slice(0, idx).split('\n'),
12
- last = lines.pop()
13
- ) => {
14
- const before = cur.slice(idx - 108, idx).split('\n').pop()
15
- const after = cur.slice(idx, idx + 108).split('\n').shift()
16
- throw EvalError(`${msg} at ${lines.length}:${last.length} \`${idx >= 108 ? '…' : ''}${before}┃${after}\``, 'font-weight: bold')
17
- },
18
-
19
- // advance until condition meets
20
- next = (is, from = idx, l) => {
21
- while (l = is(cur.charCodeAt(idx))) idx += l
22
- return cur.slice(from, idx)
23
- },
24
-
25
- // consume n characters
26
- skip = (n = 1, from = idx) => (idx += n, cur.slice(from, idx)),
27
-
28
- // a + b - c
29
- expr = (prec = 0, end) => {
30
- let cc, token, newNode, fn
31
-
32
- // chunk/token parser
33
- while (
34
- (cc = space()) && // till not end
35
- // FIXME: extra work is happening here, when lookup bails out due to lower precedence -
36
- // it makes extra `space` call for parent exprs on the same character to check precedence again
37
- (newNode =
38
- ((fn = lookup[cc]) && fn(token, prec)) ?? // if operator with higher precedence isn't found
39
- (!token && next(parse.id)) // parse literal or quit. token seqs are forbidden: `a b`, `a "b"`, `1.32 a`
40
- )
41
- ) token = newNode;
42
-
43
- // check end character
44
- if (end) cc == end ? idx++ : err()
45
-
46
- return token
47
- },
48
-
49
- // skip space chars, return first non-space character
50
- space = cc => { while ((cc = cur.charCodeAt(idx)) <= SPACE) idx++; return cc },
51
-
52
- // parse identifier (configurable)
53
- id = parse.id = c =>
54
- (c >= 48 && c <= 57) || // 0..9
55
- (c >= 65 && c <= 90) || // A...Z
56
- (c >= 97 && c <= 122) || // a...z
57
- c == 36 || c == 95 || // $, _,
58
- (c >= 192 && c != 215 && c != 247), // any non-ASCII
59
-
60
- // operator/token lookup table
61
- // lookup[0] is id parser to let configs redefine it
62
- lookup = [],
63
-
64
-
65
- // create operator checker/mapper (see examples)
66
- token = (
67
- op,
68
- prec = SPACE,
69
- map,
70
- c = op.charCodeAt(0),
71
- l = op.length,
72
- prev = lookup[c],
73
- word = op.toUpperCase() !== op // make sure word boundary comes after word operator
74
- ) => lookup[c] = (a, curPrec, curOp, from = idx) =>
75
- (
76
- (curOp ?
77
- op == curOp :
78
- ((l < 2 || cur.substr(idx, l) == op) && (curOp = op)) // save matched op to avoid mismatches like `|` as part of `||`
79
- ) &&
80
- curPrec < prec && // matches precedence AFTER operator matched
81
- !(word && parse.id(cur.charCodeAt(idx + l))) && // finished word, not part of bigger word
82
- (idx += l, map(a) || (idx = from, !prev && err())) // throw if operator didn't detect usage pattern: (a;^b) etc
83
- ) ||
84
- prev?.(a, curPrec, curOp),
85
-
86
- // right assoc is indicated by negative precedence (meaning go from right to left)
87
- binary = (op, prec, right = false) => token(op, prec, (a, b) => a && (b = expr(prec - (right ? .5 : 0))) && [op, a, b]),
88
-
89
- // post indicates postfix rather than prefix operator
90
- unary = (op, prec, post) => token(op, prec, a => post ? (a && [op, a]) : (!a && (a = expr(prec - .5)) && [op, a])),
91
-
92
- // FIXME: skips means ,,, ;;; are allowed
93
- nary = (op, prec, skips) => {
94
- token(op, prec,
95
- (a, b) => (
96
- b = expr(prec),
97
- (
98
- (a?.[0] !== op) && (a = [op, a || null]), // if beginning of sequence - init node
99
- b?.[0] === op ? a.push(...b.slice(1)) : a.push(b || null), // comments can return same-token expr
100
- a
101
- ))
102
- )
103
- },
104
-
105
- // register (a), [b], {c} etc groups
106
- // FIXME: add "Unclosed paren" error
107
- group = (op, prec) => token(op[0], prec, a => (!a && [op, expr(0, op.charCodeAt(1))])),
108
-
109
- // register a(b), a[b], a<b> etc,
110
- // NOTE: we make sure `null` indicates placeholder
111
- access = (op, prec) => token(op[0], prec, a => (a && [op, a, expr(0, op.charCodeAt(1)) || null]))
112
-
113
-
114
- export default parse
package/src/stringify.js DELETED
@@ -1,31 +0,0 @@
1
- // convert ast to code string (codegen)
2
-
3
- // FIXME: possible enhancements
4
- // * pairs via options
5
- // * custom spacing/newlines (`a.b` vs `a + b` vs `a, b` vs `a; b`)
6
- // * newlines?
7
- // * custom literals?
8
- export function stringify(node) {
9
- if (!node) return ''
10
-
11
- if (Array.isArray(node)) {
12
- const [op, ...args] = node;
13
-
14
- // 1, "x"
15
- if (!op) return JSON.stringify(args[0])
16
-
17
- // (a), a(b)
18
- if (op == '[]' || op == '{}' || op == '()') return (args.length > 1 ? stringify(args.shift()) : '') + op[0] + (stringify(args[0])) + op[1]
19
-
20
- // +a
21
- if (args.length === 1) return op + stringify(args[0])
22
-
23
- // a + b
24
- if (args.length === 2) return stringify(args[0]) + (op === '.' ? op : (' ' + op + ' ')) + stringify(args[1])
25
-
26
- // a; b; c
27
- return args.filter(Boolean).map(a => stringify(a)).join(op + '\n')
28
- }
29
-
30
- return node;
31
- }
File without changes