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.
- package/README.md +123 -171
- package/feature/access.js +67 -7
- package/feature/accessor.js +49 -0
- package/feature/asi.js +15 -0
- package/feature/async.js +45 -0
- package/feature/block.js +41 -0
- package/feature/class.js +69 -0
- package/feature/collection.js +40 -0
- package/feature/comment.js +25 -6
- package/feature/destruct.js +33 -0
- package/feature/function.js +44 -0
- package/feature/group.js +41 -12
- package/feature/if.js +28 -0
- package/feature/literal.js +13 -0
- package/feature/loop.js +123 -0
- package/feature/module.js +42 -0
- package/feature/number.js +45 -10
- package/feature/op/arithmetic.js +29 -0
- package/feature/op/arrow.js +33 -0
- package/feature/op/assign-logical.js +33 -0
- package/feature/op/assignment.js +47 -0
- package/feature/op/bitwise-unsigned.js +17 -0
- package/feature/op/bitwise.js +29 -0
- package/feature/op/comparison.js +19 -0
- package/feature/op/defer.js +15 -0
- package/feature/op/equality.js +16 -0
- package/feature/op/identity.js +15 -0
- package/feature/op/increment.js +23 -0
- package/feature/op/logical.js +21 -0
- package/feature/op/membership.js +17 -0
- package/feature/op/nullish.js +13 -0
- package/feature/op/optional.js +61 -0
- package/feature/op/pow.js +19 -0
- package/feature/op/range.js +26 -0
- package/feature/op/spread.js +15 -0
- package/feature/op/ternary.js +15 -0
- package/feature/op/type.js +18 -0
- package/feature/op/unary.js +41 -0
- package/feature/prop.js +34 -0
- package/feature/regex.js +31 -0
- package/feature/seq.js +21 -0
- package/feature/string.js +24 -16
- package/feature/switch.js +48 -0
- package/feature/template.js +39 -0
- package/feature/try.js +57 -0
- package/feature/unit.js +35 -0
- package/feature/var.js +59 -0
- package/jessie.js +31 -0
- package/jessie.min.js +8 -0
- package/justin.js +39 -48
- package/justin.min.js +8 -1
- package/package.json +18 -23
- package/parse.js +153 -0
- package/subscript.d.ts +45 -5
- package/subscript.js +62 -22
- package/subscript.min.js +5 -1
- package/util/bundle.js +507 -0
- package/util/stringify.js +172 -0
- package/feature/add.js +0 -22
- package/feature/array.js +0 -11
- package/feature/arrow.js +0 -23
- package/feature/assign.js +0 -11
- package/feature/bitwise.js +0 -11
- package/feature/bool.js +0 -5
- package/feature/call.js +0 -15
- package/feature/compare.js +0 -11
- package/feature/increment.js +0 -11
- package/feature/logic.js +0 -11
- package/feature/mult.js +0 -25
- package/feature/object.js +0 -17
- package/feature/optional.js +0 -30
- package/feature/pow.js +0 -5
- package/feature/shift.js +0 -12
- package/feature/spread.js +0 -6
- package/feature/ternary.js +0 -10
- package/src/compile.d.ts +0 -17
- package/src/compile.js +0 -28
- package/src/const.js +0 -42
- package/src/parse.d.ts +0 -22
- package/src/parse.js +0 -114
- package/src/stringify.js +0 -31
- /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
|
-
}
|
/package/{LICENSE → license}
RENAMED
|
File without changes
|