@nyariv/sandboxjs 0.8.23 → 0.8.24
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/.eslintignore +6 -0
- package/.eslintrc.js +22 -0
- package/.prettierrc +4 -0
- package/.vscode/settings.json +4 -0
- package/build/Sandbox.d.ts +11 -79
- package/build/Sandbox.js +21 -216
- package/build/SandboxExec.d.ts +25 -0
- package/build/SandboxExec.js +169 -0
- package/build/eval.d.ts +18 -0
- package/build/eval.js +43 -0
- package/build/executor.d.ts +29 -90
- package/build/executor.js +249 -328
- package/build/parser.d.ts +8 -239
- package/build/parser.js +342 -440
- package/build/unraw.js +13 -16
- package/build/utils.d.ts +242 -0
- package/build/utils.js +276 -0
- package/dist/Sandbox.d.ts +11 -79
- package/dist/Sandbox.js +106 -1
- package/dist/Sandbox.js.map +1 -1
- package/dist/Sandbox.min.js +2 -0
- package/dist/Sandbox.min.js.map +1 -0
- package/dist/SandboxExec.d.ts +25 -0
- package/dist/SandboxExec.js +173 -0
- package/dist/SandboxExec.js.map +1 -0
- package/dist/SandboxExec.min.js +2 -0
- package/dist/SandboxExec.min.js.map +1 -0
- package/dist/eval.d.ts +18 -0
- package/dist/executor.d.ts +29 -90
- package/dist/executor.js +1270 -0
- package/dist/executor.js.map +1 -0
- package/dist/node/Sandbox.d.ts +11 -79
- package/dist/node/Sandbox.js +36 -3150
- package/dist/node/SandboxExec.d.ts +25 -0
- package/dist/node/SandboxExec.js +176 -0
- package/dist/node/eval.d.ts +18 -0
- package/dist/node/executor.d.ts +29 -90
- package/dist/node/executor.js +1289 -0
- package/dist/node/parser.d.ts +8 -239
- package/dist/node/parser.js +1528 -0
- package/dist/node/utils.d.ts +242 -0
- package/dist/node/utils.js +290 -0
- package/dist/parser.d.ts +8 -239
- package/dist/parser.js +1514 -0
- package/dist/parser.js.map +1 -0
- package/dist/utils.d.ts +242 -0
- package/dist/utils.js +279 -0
- package/dist/utils.js.map +1 -0
- package/package.json +11 -3
- package/.github/workflows/npm-publish.yml +0 -34
- package/rollup.config.mjs +0 -33
package/build/parser.js
CHANGED
|
@@ -1,213 +1,158 @@
|
|
|
1
|
-
import unraw from
|
|
1
|
+
import unraw from './unraw.js';
|
|
2
|
+
import { CodeString, isLisp } from './utils.js';
|
|
2
3
|
function createLisp(obj) {
|
|
3
4
|
return [obj.op, obj.a, obj.b];
|
|
4
5
|
}
|
|
5
|
-
|
|
6
|
+
const NullLisp = createLisp({ op: 0 /* LispType.None */, a: 0 /* LispType.None */, b: 0 /* LispType.None */ });
|
|
7
|
+
const lispTypes = new Map();
|
|
6
8
|
export class ParseError extends Error {
|
|
7
9
|
constructor(message, code) {
|
|
8
|
-
super(message +
|
|
10
|
+
super(message + ': ' + code.substring(0, 40));
|
|
9
11
|
this.code = code;
|
|
10
12
|
}
|
|
11
13
|
}
|
|
14
|
+
let lastType;
|
|
15
|
+
let lastPart;
|
|
16
|
+
let lastLastPart;
|
|
17
|
+
let lastLastLastPart;
|
|
18
|
+
let lastLastLastLastPart;
|
|
12
19
|
const inlineIfElse = /^:/;
|
|
13
|
-
const elseIf = /^else(?![\w
|
|
14
|
-
const ifElse = /^if(?![\w
|
|
20
|
+
const elseIf = /^else(?![\w$])/;
|
|
21
|
+
const ifElse = /^if(?![\w$])/;
|
|
15
22
|
const space = /^\s/;
|
|
16
|
-
export
|
|
23
|
+
export const expectTypes = {
|
|
17
24
|
splitter: {
|
|
18
25
|
types: {
|
|
19
|
-
opHigh: /^(\/|\*\*|\*(?!\*)
|
|
20
|
-
op: /^(\+(?!(\+))
|
|
21
|
-
comparitor: /^(<=|>=|<(?!<)|>(?!>)|!==|!=(
|
|
22
|
-
boolOp: /^(&&|\|\||instanceof(?![\w
|
|
23
|
-
bitwise: /^(&(?!&)|\|(?!\|)|\^|<<|>>(?!>)|>>>)(
|
|
26
|
+
opHigh: /^(\/|\*\*|\*(?!\*)|%)(?!=)/,
|
|
27
|
+
op: /^(\+(?!(\+))|-(?!(-)))(?!=)/,
|
|
28
|
+
comparitor: /^(<=|>=|<(?!<)|>(?!>)|!==|!=(?!=)|===|==)/,
|
|
29
|
+
boolOp: /^(&&|\|\||instanceof(?![\w$])|in(?![\w$]))/,
|
|
30
|
+
bitwise: /^(&(?!&)|\|(?!\|)|\^|<<|>>(?!>)|>>>)(?!=)/,
|
|
24
31
|
},
|
|
25
|
-
next: [
|
|
26
|
-
'modifier',
|
|
27
|
-
'value',
|
|
28
|
-
'prop',
|
|
29
|
-
'incrementerBefore',
|
|
30
|
-
]
|
|
32
|
+
next: ['modifier', 'value', 'prop', 'incrementerBefore'],
|
|
31
33
|
},
|
|
32
34
|
inlineIf: {
|
|
33
35
|
types: {
|
|
34
36
|
inlineIf: /^\?(?!\.(?!\d))/,
|
|
35
37
|
},
|
|
36
|
-
next: [
|
|
37
|
-
'expEnd'
|
|
38
|
-
]
|
|
38
|
+
next: ['expEnd'],
|
|
39
39
|
},
|
|
40
40
|
assignment: {
|
|
41
41
|
types: {
|
|
42
|
-
assignModify: /^(
|
|
43
|
-
assign: /^(=)(?!=)
|
|
42
|
+
assignModify: /^(-=|\+=|\/=|\*\*=|\*=|%=|\^=|&=|\|=|>>>=|>>=|<<=)/,
|
|
43
|
+
assign: /^(=)(?!=)/,
|
|
44
44
|
},
|
|
45
|
-
next: [
|
|
46
|
-
'modifier',
|
|
47
|
-
'value',
|
|
48
|
-
'prop',
|
|
49
|
-
'incrementerBefore',
|
|
50
|
-
]
|
|
45
|
+
next: ['modifier', 'value', 'prop', 'incrementerBefore'],
|
|
51
46
|
},
|
|
52
47
|
incrementerBefore: {
|
|
53
|
-
types: { incrementerBefore: /^(
|
|
54
|
-
next: [
|
|
55
|
-
'prop',
|
|
56
|
-
]
|
|
48
|
+
types: { incrementerBefore: /^(\+\+|--)/ },
|
|
49
|
+
next: ['prop'],
|
|
57
50
|
},
|
|
58
51
|
expEdge: {
|
|
59
52
|
types: {
|
|
60
|
-
call: /^(\?\.)?[
|
|
61
|
-
incrementerAfter: /^(
|
|
53
|
+
call: /^(\?\.)?[(]/,
|
|
54
|
+
incrementerAfter: /^(\+\+|--)/,
|
|
62
55
|
},
|
|
63
|
-
next: [
|
|
64
|
-
'splitter',
|
|
65
|
-
'expEdge',
|
|
66
|
-
'dot',
|
|
67
|
-
'inlineIf',
|
|
68
|
-
'expEnd'
|
|
69
|
-
]
|
|
56
|
+
next: ['splitter', 'expEdge', 'dot', 'inlineIf', 'expEnd'],
|
|
70
57
|
},
|
|
71
58
|
modifier: {
|
|
72
59
|
types: {
|
|
73
60
|
not: /^!/,
|
|
74
61
|
inverse: /^~/,
|
|
75
|
-
negative:
|
|
62
|
+
negative: /^-(?!-)/,
|
|
76
63
|
positive: /^\+(?!\+)/,
|
|
77
|
-
typeof: /^typeof(?![\w
|
|
78
|
-
delete: /^delete(?![\w
|
|
64
|
+
typeof: /^typeof(?![\w$])/,
|
|
65
|
+
delete: /^delete(?![\w$])/,
|
|
79
66
|
},
|
|
80
|
-
next: [
|
|
81
|
-
'modifier',
|
|
82
|
-
'value',
|
|
83
|
-
'prop',
|
|
84
|
-
'incrementerBefore',
|
|
85
|
-
]
|
|
67
|
+
next: ['modifier', 'value', 'prop', 'incrementerBefore'],
|
|
86
68
|
},
|
|
87
69
|
dot: {
|
|
88
70
|
types: {
|
|
89
71
|
arrayProp: /^(\?\.)?\[/,
|
|
90
|
-
dot: /^(\?)?\.(?=\s*[a-zA-Z
|
|
72
|
+
dot: /^(\?)?\.(?=\s*[a-zA-Z$_])/,
|
|
91
73
|
},
|
|
92
|
-
next: [
|
|
93
|
-
'splitter',
|
|
94
|
-
'assignment',
|
|
95
|
-
'expEdge',
|
|
96
|
-
'dot',
|
|
97
|
-
'inlineIf',
|
|
98
|
-
'expEnd'
|
|
99
|
-
]
|
|
74
|
+
next: ['splitter', 'assignment', 'expEdge', 'dot', 'inlineIf', 'expEnd'],
|
|
100
75
|
},
|
|
101
76
|
prop: {
|
|
102
77
|
types: {
|
|
103
|
-
prop: /^[a-zA-Z
|
|
78
|
+
prop: /^[a-zA-Z$_][a-zA-Z\d$_]*/,
|
|
104
79
|
},
|
|
105
|
-
next: [
|
|
106
|
-
'splitter',
|
|
107
|
-
'assignment',
|
|
108
|
-
'expEdge',
|
|
109
|
-
'dot',
|
|
110
|
-
'inlineIf',
|
|
111
|
-
'expEnd'
|
|
112
|
-
]
|
|
80
|
+
next: ['splitter', 'assignment', 'expEdge', 'dot', 'inlineIf', 'expEnd'],
|
|
113
81
|
},
|
|
114
82
|
value: {
|
|
115
83
|
types: {
|
|
116
84
|
createObject: /^\{/,
|
|
117
85
|
createArray: /^\[/,
|
|
118
|
-
number: /^(0x[\da-f]+(_[\da-f]+)*|(\d+(_\d+)*(\.\d+(_\d+)*)?|\.\d+(_\d+)*))(e[
|
|
86
|
+
number: /^(0x[\da-f]+(_[\da-f]+)*|(\d+(_\d+)*(\.\d+(_\d+)*)?|\.\d+(_\d+)*))(e[+-]?\d+(_\d+)*)?(n)?(?!\d)/i,
|
|
119
87
|
string: /^"(\d+)"/,
|
|
120
88
|
literal: /^`(\d+)`/,
|
|
121
|
-
regex: /^\/(\d+)\/r(?![\w
|
|
122
|
-
boolean: /^(true|false)(?![\w
|
|
123
|
-
null: /^null(?![\w
|
|
124
|
-
und: /^undefined(?![\w
|
|
125
|
-
arrowFunctionSingle: /^(async\s+)?([a-zA-Z
|
|
126
|
-
arrowFunction: /^(async\s*)?\(\s*((\.\.\.)?\s*[a-zA-Z
|
|
127
|
-
inlineFunction: /^(async\s+)?function(\s*[a-zA-Z
|
|
89
|
+
regex: /^\/(\d+)\/r(?![\w$])/,
|
|
90
|
+
boolean: /^(true|false)(?![\w$])/,
|
|
91
|
+
null: /^null(?![\w$])/,
|
|
92
|
+
und: /^undefined(?![\w$])/,
|
|
93
|
+
arrowFunctionSingle: /^(async\s+)?([a-zA-Z$_][a-zA-Z\d$_]*)\s*=>\s*({)?/,
|
|
94
|
+
arrowFunction: /^(async\s*)?\(\s*((\.\.\.)?\s*[a-zA-Z$_][a-zA-Z\d$_]*(\s*,\s*(\.\.\.)?\s*[a-zA-Z$_][a-zA-Z\d$_]*)*)?\s*\)\s*=>\s*({)?/,
|
|
95
|
+
inlineFunction: /^(async\s+)?function(\s*[a-zA-Z$_][a-zA-Z\d$_]*)?\s*\(\s*((\.\.\.)?\s*[a-zA-Z$_][a-zA-Z\d$_]*(\s*,\s*(\.\.\.)?\s*[a-zA-Z$_][a-zA-Z\d$_]*)*)?\s*\)\s*{/,
|
|
128
96
|
group: /^\(/,
|
|
129
|
-
NaN: /^NaN(?![\w
|
|
130
|
-
Infinity: /^Infinity(?![\w
|
|
131
|
-
void: /^void(?![\w
|
|
132
|
-
await: /^await(?![\w
|
|
133
|
-
new: /^new(?![\w
|
|
97
|
+
NaN: /^NaN(?![\w$])/,
|
|
98
|
+
Infinity: /^Infinity(?![\w$])/,
|
|
99
|
+
void: /^void(?![\w$])\s*/,
|
|
100
|
+
await: /^await(?![\w$])\s*/,
|
|
101
|
+
new: /^new(?![\w$])\s*/,
|
|
134
102
|
},
|
|
135
|
-
next: [
|
|
136
|
-
'splitter',
|
|
137
|
-
'expEdge',
|
|
138
|
-
'dot',
|
|
139
|
-
'inlineIf',
|
|
140
|
-
'expEnd'
|
|
141
|
-
]
|
|
103
|
+
next: ['splitter', 'expEdge', 'dot', 'inlineIf', 'expEnd'],
|
|
142
104
|
},
|
|
143
105
|
initialize: {
|
|
144
106
|
types: {
|
|
145
|
-
initialize: /^(var|let|const)\s+([a-zA-Z
|
|
146
|
-
return: /^return(?![\w
|
|
147
|
-
throw: /^throw(?![\w
|
|
107
|
+
initialize: /^(var|let|const)\s+([a-zA-Z$_][a-zA-Z\d$_]*)\s*(=)?/,
|
|
108
|
+
return: /^return(?![\w$])/,
|
|
109
|
+
throw: /^throw(?![\w$])\s*/,
|
|
148
110
|
},
|
|
149
|
-
next: [
|
|
150
|
-
'modifier',
|
|
151
|
-
'value',
|
|
152
|
-
'prop',
|
|
153
|
-
'incrementerBefore',
|
|
154
|
-
'expEnd'
|
|
155
|
-
]
|
|
111
|
+
next: ['modifier', 'value', 'prop', 'incrementerBefore', 'expEnd'],
|
|
156
112
|
},
|
|
157
113
|
spreadObject: {
|
|
158
114
|
types: {
|
|
159
|
-
spreadObject:
|
|
115
|
+
spreadObject: /^\.\.\./,
|
|
160
116
|
},
|
|
161
|
-
next: [
|
|
162
|
-
'value',
|
|
163
|
-
'prop',
|
|
164
|
-
]
|
|
117
|
+
next: ['value', 'prop'],
|
|
165
118
|
},
|
|
166
119
|
spreadArray: {
|
|
167
120
|
types: {
|
|
168
|
-
spreadArray:
|
|
121
|
+
spreadArray: /^\.\.\./,
|
|
169
122
|
},
|
|
170
|
-
next: [
|
|
171
|
-
'value',
|
|
172
|
-
'prop',
|
|
173
|
-
]
|
|
123
|
+
next: ['value', 'prop'],
|
|
174
124
|
},
|
|
175
125
|
expEnd: { types: {}, next: [] },
|
|
176
126
|
expFunction: {
|
|
177
127
|
types: {
|
|
178
|
-
function: /^(async\s+)?function(\s*[a-zA-Z
|
|
128
|
+
function: /^(async\s+)?function(\s*[a-zA-Z$_][a-zA-Z\d$_]*)\s*\(\s*((\.\.\.)?\s*[a-zA-Z$_][a-zA-Z\d$_]*(\s*,\s*(\.\.\.)?\s*[a-zA-Z$_][a-zA-Z\d$_]*)*)?\s*\)\s*{/,
|
|
179
129
|
},
|
|
180
|
-
next: [
|
|
181
|
-
'expEdge',
|
|
182
|
-
'expEnd'
|
|
183
|
-
]
|
|
130
|
+
next: ['expEdge', 'expEnd'],
|
|
184
131
|
},
|
|
185
132
|
expSingle: {
|
|
186
133
|
types: {
|
|
187
|
-
for: /^(([a-zA-Z
|
|
188
|
-
do: /^(([a-zA-Z
|
|
189
|
-
while: /^(([a-zA-Z
|
|
190
|
-
loopAction: /^(break|continue)(?![\w
|
|
191
|
-
if: /^((([a-zA-Z
|
|
134
|
+
for: /^(([a-zA-Z$_][\w$]*)\s*:)?\s*for\s*\(/,
|
|
135
|
+
do: /^(([a-zA-Z$_][\w$]*)\s*:)?\s*do(?![\w$])\s*(\{)?/,
|
|
136
|
+
while: /^(([a-zA-Z$_][\w$]*)\s*:)?\s*while\s*\(/,
|
|
137
|
+
loopAction: /^(break|continue)(?![\w$])\s*([a-zA-Z$_][\w$]*)?/,
|
|
138
|
+
if: /^((([a-zA-Z$_][\w$]*)\s*:)?\s*)if\s*\(/,
|
|
192
139
|
try: /^try\s*{/,
|
|
193
140
|
block: /^{/,
|
|
194
|
-
switch: /^(([a-zA-Z
|
|
141
|
+
switch: /^(([a-zA-Z$_][\w$]*)\s*:)?\s*switch\s*\(/,
|
|
195
142
|
},
|
|
196
|
-
next: [
|
|
197
|
-
|
|
198
|
-
]
|
|
199
|
-
}
|
|
143
|
+
next: ['expEnd'],
|
|
144
|
+
},
|
|
200
145
|
};
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
146
|
+
const closings = {
|
|
147
|
+
'(': ')',
|
|
148
|
+
'[': ']',
|
|
149
|
+
'{': '}',
|
|
205
150
|
"'": "'",
|
|
206
151
|
'"': '"',
|
|
207
|
-
|
|
152
|
+
'`': '`',
|
|
208
153
|
};
|
|
209
154
|
export function testMultiple(str, tests) {
|
|
210
|
-
let found;
|
|
155
|
+
let found = null;
|
|
211
156
|
for (let i = 0; i < tests.length; i++) {
|
|
212
157
|
const test = tests[i];
|
|
213
158
|
found = test.exec(str);
|
|
@@ -216,97 +161,10 @@ export function testMultiple(str, tests) {
|
|
|
216
161
|
}
|
|
217
162
|
return found;
|
|
218
163
|
}
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
this.ref = { str: "" };
|
|
222
|
-
if (str instanceof CodeString) {
|
|
223
|
-
this.ref = str.ref;
|
|
224
|
-
this.start = str.start;
|
|
225
|
-
this.end = str.end;
|
|
226
|
-
}
|
|
227
|
-
else {
|
|
228
|
-
this.ref.str = str;
|
|
229
|
-
this.start = 0;
|
|
230
|
-
this.end = str.length;
|
|
231
|
-
}
|
|
232
|
-
}
|
|
233
|
-
substring(start, end) {
|
|
234
|
-
if (!this.length)
|
|
235
|
-
return this;
|
|
236
|
-
start = this.start + start;
|
|
237
|
-
if (start < 0) {
|
|
238
|
-
start = 0;
|
|
239
|
-
}
|
|
240
|
-
if (start > this.end) {
|
|
241
|
-
start = this.end;
|
|
242
|
-
}
|
|
243
|
-
end = end === undefined ? this.end : this.start + end;
|
|
244
|
-
if (end < 0) {
|
|
245
|
-
end = 0;
|
|
246
|
-
}
|
|
247
|
-
if (end > this.end) {
|
|
248
|
-
end = this.end;
|
|
249
|
-
}
|
|
250
|
-
const code = new CodeString(this);
|
|
251
|
-
code.start = start;
|
|
252
|
-
code.end = end;
|
|
253
|
-
return code;
|
|
254
|
-
}
|
|
255
|
-
get length() {
|
|
256
|
-
const len = this.end - this.start;
|
|
257
|
-
return len < 0 ? 0 : len;
|
|
258
|
-
}
|
|
259
|
-
char(i) {
|
|
260
|
-
if (this.start === this.end)
|
|
261
|
-
return undefined;
|
|
262
|
-
return this.ref.str[this.start + i];
|
|
263
|
-
}
|
|
264
|
-
toString() {
|
|
265
|
-
return this.ref.str.substring(this.start, this.end);
|
|
266
|
-
}
|
|
267
|
-
trimStart() {
|
|
268
|
-
const found = /^\s+/.exec(this.toString());
|
|
269
|
-
const code = new CodeString(this);
|
|
270
|
-
if (found) {
|
|
271
|
-
code.start += found[0].length;
|
|
272
|
-
}
|
|
273
|
-
return code;
|
|
274
|
-
}
|
|
275
|
-
slice(start, end) {
|
|
276
|
-
if (start < 0) {
|
|
277
|
-
start = this.end - this.start + start;
|
|
278
|
-
}
|
|
279
|
-
if (start < 0) {
|
|
280
|
-
start = 0;
|
|
281
|
-
}
|
|
282
|
-
if (end === undefined) {
|
|
283
|
-
end = this.end - this.start;
|
|
284
|
-
}
|
|
285
|
-
if (end < 0) {
|
|
286
|
-
end = this.end - this.start + end;
|
|
287
|
-
}
|
|
288
|
-
if (end < 0) {
|
|
289
|
-
end = 0;
|
|
290
|
-
}
|
|
291
|
-
return this.substring(start, end);
|
|
292
|
-
}
|
|
293
|
-
trim() {
|
|
294
|
-
const code = this.trimStart();
|
|
295
|
-
const found = /\s+$/.exec(code.toString());
|
|
296
|
-
if (found) {
|
|
297
|
-
code.end -= found[0].length;
|
|
298
|
-
}
|
|
299
|
-
return code;
|
|
300
|
-
}
|
|
301
|
-
valueOf() {
|
|
302
|
-
return this.toString();
|
|
303
|
-
}
|
|
304
|
-
}
|
|
305
|
-
const emptyString = new CodeString("");
|
|
306
|
-
const okFirstChars = /^[\+\-~ !]/;
|
|
307
|
-
const aChar = /^[\w\$]/;
|
|
164
|
+
const emptyString = new CodeString('');
|
|
165
|
+
const okFirstChars = /^[+\-~ !]/;
|
|
308
166
|
const aNumber = expectTypes.value.types.number;
|
|
309
|
-
const wordReg = /^((if|for|else|while|do|function)(?![\w
|
|
167
|
+
const wordReg = /^((if|for|else|while|do|function)(?![\w$])|[\w$]+)/;
|
|
310
168
|
const semiColon = /^;/;
|
|
311
169
|
const insertedSemicolons = new WeakMap();
|
|
312
170
|
const quoteCache = new WeakMap();
|
|
@@ -329,21 +187,21 @@ export function restOfExp(constants, part, tests, quote, firstOpening, closingsT
|
|
|
329
187
|
}
|
|
330
188
|
let escape = false;
|
|
331
189
|
let done = false;
|
|
332
|
-
let lastChar =
|
|
190
|
+
let lastChar = '';
|
|
333
191
|
let isOneLiner = false;
|
|
334
192
|
let i;
|
|
335
193
|
let lastInertedSemi = false;
|
|
336
194
|
for (i = 0; i < part.length && !done; i++) {
|
|
337
195
|
let char = part.char(i);
|
|
338
|
-
if (quote === '"' || quote === "'" || quote ===
|
|
339
|
-
if (quote ===
|
|
340
|
-
|
|
196
|
+
if (quote === '"' || quote === "'" || quote === '`') {
|
|
197
|
+
if (quote === '`' && char === '$' && part.char(i + 1) === '{' && !escape) {
|
|
198
|
+
const skip = restOfExp(constants, part.substring(i + 2), [], '{');
|
|
341
199
|
i += skip.length + 2;
|
|
342
200
|
}
|
|
343
201
|
else if (char === quote && !escape) {
|
|
344
202
|
return part.substring(0, i);
|
|
345
203
|
}
|
|
346
|
-
escape = !escape && char ===
|
|
204
|
+
escape = !escape && char === '\\';
|
|
347
205
|
}
|
|
348
206
|
else if (closings[char]) {
|
|
349
207
|
if (!lastInertedSemi && insertedSemis[i + part.start]) {
|
|
@@ -355,7 +213,7 @@ export function restOfExp(constants, part, tests, quote, firstOpening, closingsT
|
|
|
355
213
|
lastChar = ';';
|
|
356
214
|
continue;
|
|
357
215
|
}
|
|
358
|
-
if (isOneLiner && char ===
|
|
216
|
+
if (isOneLiner && char === '{') {
|
|
359
217
|
isOneLiner = false;
|
|
360
218
|
}
|
|
361
219
|
if (char === firstOpening) {
|
|
@@ -363,14 +221,14 @@ export function restOfExp(constants, part, tests, quote, firstOpening, closingsT
|
|
|
363
221
|
break;
|
|
364
222
|
}
|
|
365
223
|
else {
|
|
366
|
-
|
|
224
|
+
const skip = restOfExp(constants, part.substring(i + 1), [], char);
|
|
367
225
|
cache.set(skip.start - 1, skip.end);
|
|
368
226
|
i += skip.length + 1;
|
|
369
227
|
isStart = false;
|
|
370
228
|
if (closingsTests) {
|
|
371
|
-
|
|
229
|
+
const sub = part.substring(i);
|
|
372
230
|
let found;
|
|
373
|
-
if (found = testMultiple(sub.toString(), closingsTests)) {
|
|
231
|
+
if ((found = testMultiple(sub.toString(), closingsTests))) {
|
|
374
232
|
details.regRes = found;
|
|
375
233
|
done = true;
|
|
376
234
|
}
|
|
@@ -383,22 +241,22 @@ export function restOfExp(constants, part, tests, quote, firstOpening, closingsT
|
|
|
383
241
|
let foundNumber;
|
|
384
242
|
if (closingsTests) {
|
|
385
243
|
let found;
|
|
386
|
-
if (found = testMultiple(sub, closingsTests)) {
|
|
244
|
+
if ((found = testMultiple(sub, closingsTests))) {
|
|
387
245
|
details.regRes = found;
|
|
388
246
|
i++;
|
|
389
247
|
done = true;
|
|
390
248
|
break;
|
|
391
249
|
}
|
|
392
250
|
}
|
|
393
|
-
if (foundNumber = aNumber.exec(sub)) {
|
|
251
|
+
if ((foundNumber = aNumber.exec(sub))) {
|
|
394
252
|
i += foundNumber[0].length - 1;
|
|
395
253
|
sub = part.substring(i).toString();
|
|
396
254
|
}
|
|
397
255
|
else if (lastChar != char) {
|
|
398
|
-
let found;
|
|
256
|
+
let found = null;
|
|
399
257
|
if (char === ';' || (insertedSemis[i + part.start] && !isStart && !lastInertedSemi)) {
|
|
400
258
|
if (hasSemiTest) {
|
|
401
|
-
found = [
|
|
259
|
+
found = [';'];
|
|
402
260
|
}
|
|
403
261
|
else if (insertedSemis[i + part.start]) {
|
|
404
262
|
lastInertedSemi = true;
|
|
@@ -455,45 +313,47 @@ export function restOfExp(constants, part, tests, quote, firstOpening, closingsT
|
|
|
455
313
|
}
|
|
456
314
|
return part.substring(0, i);
|
|
457
315
|
}
|
|
458
|
-
restOfExp.next = [
|
|
459
|
-
|
|
316
|
+
restOfExp.next = ['splitter', 'expEnd', 'inlineIf'];
|
|
317
|
+
const startingExecpted = [
|
|
318
|
+
'initialize',
|
|
319
|
+
'expSingle',
|
|
320
|
+
'expFunction',
|
|
321
|
+
'value',
|
|
322
|
+
'modifier',
|
|
323
|
+
'prop',
|
|
324
|
+
'incrementerBefore',
|
|
460
325
|
'expEnd',
|
|
461
|
-
'inlineIf'
|
|
462
326
|
];
|
|
463
|
-
const startingExecpted = ['initialize', 'expSingle', 'expFunction', 'value', 'modifier', 'prop', 'incrementerBefore', 'expEnd'];
|
|
464
327
|
export const setLispType = (types, fn) => {
|
|
465
328
|
types.forEach((type) => {
|
|
466
329
|
lispTypes.set(type, fn);
|
|
467
330
|
});
|
|
468
331
|
};
|
|
469
332
|
const closingsCreate = {
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
333
|
+
createArray: /^\]/,
|
|
334
|
+
createObject: /^\}/,
|
|
335
|
+
group: /^\)/,
|
|
336
|
+
arrayProp: /^\]/,
|
|
337
|
+
call: /^\)/,
|
|
475
338
|
};
|
|
476
339
|
const typesCreate = {
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
340
|
+
createArray: 12 /* LispType.CreateArray */,
|
|
341
|
+
createObject: 22 /* LispType.CreateObject */,
|
|
342
|
+
group: 23 /* LispType.Group */,
|
|
343
|
+
arrayProp: 19 /* LispType.ArrayProp */,
|
|
344
|
+
call: 5 /* LispType.Call */,
|
|
345
|
+
prop: 1 /* LispType.Prop */,
|
|
483
346
|
'?prop': 20 /* LispType.PropOptional */,
|
|
484
347
|
'?call': 21 /* LispType.CallOptional */,
|
|
485
348
|
};
|
|
486
349
|
setLispType(['createArray', 'createObject', 'group', 'arrayProp', 'call'], (constants, type, part, res, expect, ctx) => {
|
|
487
350
|
let extract = emptyString;
|
|
488
|
-
|
|
351
|
+
const arg = [];
|
|
489
352
|
let end = false;
|
|
490
353
|
let i = res[0].length;
|
|
491
354
|
const start = i;
|
|
492
355
|
while (i < part.length && !end) {
|
|
493
|
-
extract = restOfExp(constants, part.substring(i), [
|
|
494
|
-
closingsCreate[type],
|
|
495
|
-
/^,/
|
|
496
|
-
]);
|
|
356
|
+
extract = restOfExp(constants, part.substring(i), [closingsCreate[type], /^,/]);
|
|
497
357
|
i += extract.length;
|
|
498
358
|
if (extract.trim().length) {
|
|
499
359
|
arg.push(extract);
|
|
@@ -526,10 +386,10 @@ setLispType(['createArray', 'createObject', 'group', 'arrayProp', 'call'], (cons
|
|
|
526
386
|
funcFound = expectTypes.expFunction.types.function.exec('function ' + str);
|
|
527
387
|
if (funcFound) {
|
|
528
388
|
key = funcFound[2].trimStart();
|
|
529
|
-
value = lispify(constants, new CodeString('function ' + str.toString().replace(key,
|
|
389
|
+
value = lispify(constants, new CodeString('function ' + str.toString().replace(key, '')));
|
|
530
390
|
}
|
|
531
391
|
else {
|
|
532
|
-
|
|
392
|
+
const extract = restOfExp(constants, str, [/^:/]);
|
|
533
393
|
key = lispify(constants, extract, [...next, 'spreadObject']);
|
|
534
394
|
if (key[0] === 1 /* LispType.Prop */) {
|
|
535
395
|
key = key[2];
|
|
@@ -539,12 +399,20 @@ setLispType(['createArray', 'createObject', 'group', 'arrayProp', 'call'], (cons
|
|
|
539
399
|
return createLisp({
|
|
540
400
|
op: 6 /* LispType.KeyVal */,
|
|
541
401
|
a: key,
|
|
542
|
-
b: value
|
|
402
|
+
b: value,
|
|
543
403
|
});
|
|
544
404
|
});
|
|
545
405
|
break;
|
|
546
406
|
}
|
|
547
|
-
|
|
407
|
+
const lisptype = (type === 'arrayProp'
|
|
408
|
+
? res[1]
|
|
409
|
+
? 20 /* LispType.PropOptional */
|
|
410
|
+
: 1 /* LispType.Prop */
|
|
411
|
+
: type === 'call'
|
|
412
|
+
? res[1]
|
|
413
|
+
? 21 /* LispType.CallOptional */
|
|
414
|
+
: 5 /* LispType.Call */
|
|
415
|
+
: typesCreate[type]);
|
|
548
416
|
ctx.lispTree = lispify(constants, part.substring(i + 1), expectTypes[expect].next, createLisp({
|
|
549
417
|
op: lisptype,
|
|
550
418
|
a: ctx.lispTree,
|
|
@@ -552,15 +420,15 @@ setLispType(['createArray', 'createObject', 'group', 'arrayProp', 'call'], (cons
|
|
|
552
420
|
}));
|
|
553
421
|
});
|
|
554
422
|
const modifierTypes = {
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
423
|
+
inverse: 64 /* LispType.Inverse */,
|
|
424
|
+
not: 24 /* LispType.Not */,
|
|
425
|
+
positive: 59 /* LispType.Positive */,
|
|
426
|
+
negative: 58 /* LispType.Negative */,
|
|
427
|
+
typeof: 60 /* LispType.Typeof */,
|
|
428
|
+
delete: 61 /* LispType.Delete */,
|
|
561
429
|
};
|
|
562
430
|
setLispType(['inverse', 'not', 'negative', 'positive', 'typeof', 'delete'], (constants, type, part, res, expect, ctx) => {
|
|
563
|
-
|
|
431
|
+
const extract = restOfExp(constants, part.substring(res[0].length), [/^([^\s.?\w$]|\?[^.])/]);
|
|
564
432
|
ctx.lispTree = lispify(constants, part.substring(extract.length + res[0].length), restOfExp.next, createLisp({
|
|
565
433
|
op: modifierTypes[type],
|
|
566
434
|
a: ctx.lispTree,
|
|
@@ -571,28 +439,28 @@ const incrementTypes = {
|
|
|
571
439
|
'++$': 25 /* LispType.IncrementBefore */,
|
|
572
440
|
'--$': 27 /* LispType.DecrementBefore */,
|
|
573
441
|
'$++': 26 /* LispType.IncrementAfter */,
|
|
574
|
-
'$--': 28 /* LispType.DecrementAfter
|
|
442
|
+
'$--': 28 /* LispType.DecrementAfter */,
|
|
575
443
|
};
|
|
576
444
|
setLispType(['incrementerBefore'], (constants, type, part, res, expect, ctx) => {
|
|
577
|
-
|
|
445
|
+
const extract = restOfExp(constants, part.substring(2), [/^[^\s.\w$]/]);
|
|
578
446
|
ctx.lispTree = lispify(constants, part.substring(extract.length + 2), restOfExp.next, createLisp({
|
|
579
|
-
op: incrementTypes[res[0] +
|
|
447
|
+
op: incrementTypes[res[0] + '$'],
|
|
580
448
|
a: lispify(constants, extract, expectTypes[expect].next),
|
|
581
|
-
b: 0 /* LispType.None
|
|
449
|
+
b: 0 /* LispType.None */,
|
|
582
450
|
}));
|
|
583
451
|
});
|
|
584
452
|
setLispType(['incrementerAfter'], (constants, type, part, res, expect, ctx) => {
|
|
585
453
|
ctx.lispTree = lispify(constants, part.substring(res[0].length), expectTypes[expect].next, createLisp({
|
|
586
|
-
op: incrementTypes[
|
|
454
|
+
op: incrementTypes['$' + res[0]],
|
|
587
455
|
a: ctx.lispTree,
|
|
588
|
-
b: 0 /* LispType.None
|
|
456
|
+
b: 0 /* LispType.None */,
|
|
589
457
|
}));
|
|
590
458
|
});
|
|
591
459
|
const adderTypes = {
|
|
592
460
|
'&&': 29 /* LispType.And */,
|
|
593
461
|
'||': 30 /* LispType.Or */,
|
|
594
|
-
|
|
595
|
-
|
|
462
|
+
instanceof: 62 /* LispType.Instanceof */,
|
|
463
|
+
in: 63 /* LispType.In */,
|
|
596
464
|
'=': 9 /* LispType.Assign */,
|
|
597
465
|
'-=': 65 /* LispType.SubractEquals */,
|
|
598
466
|
'+=': 66 /* LispType.AddEquals */,
|
|
@@ -611,7 +479,7 @@ setLispType(['assign', 'assignModify', 'boolOp'], (constants, type, part, res, e
|
|
|
611
479
|
ctx.lispTree = createLisp({
|
|
612
480
|
op: adderTypes[res[0]],
|
|
613
481
|
a: ctx.lispTree,
|
|
614
|
-
b: lispify(constants, part.substring(res[0].length), expectTypes[expect].next)
|
|
482
|
+
b: lispify(constants, part.substring(res[0].length), expectTypes[expect].next),
|
|
615
483
|
});
|
|
616
484
|
});
|
|
617
485
|
const opTypes = {
|
|
@@ -637,10 +505,7 @@ const opTypes = {
|
|
|
637
505
|
'%': 51 /* LispType.Modulus */,
|
|
638
506
|
};
|
|
639
507
|
setLispType(['opHigh', 'op', 'comparitor', 'bitwise'], (constants, type, part, res, expect, ctx) => {
|
|
640
|
-
const next = [
|
|
641
|
-
expectTypes.inlineIf.types.inlineIf,
|
|
642
|
-
inlineIfElse
|
|
643
|
-
];
|
|
508
|
+
const next = [expectTypes.inlineIf.types.inlineIf, inlineIfElse];
|
|
644
509
|
switch (type) {
|
|
645
510
|
case 'opHigh':
|
|
646
511
|
next.push(expectTypes.splitter.types.opHigh);
|
|
@@ -652,7 +517,7 @@ setLispType(['opHigh', 'op', 'comparitor', 'bitwise'], (constants, type, part, r
|
|
|
652
517
|
next.push(expectTypes.splitter.types.bitwise);
|
|
653
518
|
next.push(expectTypes.splitter.types.boolOp);
|
|
654
519
|
}
|
|
655
|
-
|
|
520
|
+
const extract = restOfExp(constants, part.substring(res[0].length), next);
|
|
656
521
|
ctx.lispTree = lispify(constants, part.substring(extract.length + res[0].length), restOfExp.next, createLisp({
|
|
657
522
|
op: opTypes[res[0]],
|
|
658
523
|
a: ctx.lispTree,
|
|
@@ -661,12 +526,12 @@ setLispType(['opHigh', 'op', 'comparitor', 'bitwise'], (constants, type, part, r
|
|
|
661
526
|
});
|
|
662
527
|
setLispType(['inlineIf'], (constants, type, part, res, expect, ctx) => {
|
|
663
528
|
let found = false;
|
|
664
|
-
|
|
529
|
+
const extract = part.substring(0, 0);
|
|
665
530
|
let quoteCount = 1;
|
|
666
531
|
while (!found && extract.length < part.length) {
|
|
667
532
|
extract.end = restOfExp(constants, part.substring(extract.length + 1), [
|
|
668
533
|
expectTypes.inlineIf.types.inlineIf,
|
|
669
|
-
inlineIfElse
|
|
534
|
+
inlineIfElse,
|
|
670
535
|
]).end;
|
|
671
536
|
if (part.char(extract.length) === '?') {
|
|
672
537
|
quoteCount++;
|
|
@@ -685,8 +550,8 @@ setLispType(['inlineIf'], (constants, type, part, res, expect, ctx) => {
|
|
|
685
550
|
b: createLisp({
|
|
686
551
|
op: 16 /* LispType.InlineIfCase */,
|
|
687
552
|
a: lispifyExpr(constants, extract),
|
|
688
|
-
b: lispifyExpr(constants, part.substring(res[0].length + extract.length + 1))
|
|
689
|
-
})
|
|
553
|
+
b: lispifyExpr(constants, part.substring(res[0].length + extract.length + 1)),
|
|
554
|
+
}),
|
|
690
555
|
});
|
|
691
556
|
});
|
|
692
557
|
function extractIfElse(constants, part) {
|
|
@@ -697,10 +562,11 @@ function extractIfElse(constants, part) {
|
|
|
697
562
|
let first = true;
|
|
698
563
|
let elseReg;
|
|
699
564
|
let details = {};
|
|
700
|
-
while ((found = restOfExp(constants, part.substring(found.end - part.start), [elseIf, ifElse, semiColon], undefined, undefined, undefined, details)).length ||
|
|
565
|
+
while ((found = restOfExp(constants, part.substring(found.end - part.start), [elseIf, ifElse, semiColon], undefined, undefined, undefined, details)).length ||
|
|
566
|
+
first) {
|
|
701
567
|
first = false;
|
|
702
568
|
const f = part.substring(found.end - part.start).toString();
|
|
703
|
-
if (f.startsWith(
|
|
569
|
+
if (f.startsWith('if')) {
|
|
704
570
|
found.end++;
|
|
705
571
|
count++;
|
|
706
572
|
}
|
|
@@ -712,7 +578,7 @@ function extractIfElse(constants, part) {
|
|
|
712
578
|
found.end--;
|
|
713
579
|
}
|
|
714
580
|
}
|
|
715
|
-
else if (elseReg = /^;?\s*else(?![\w
|
|
581
|
+
else if ((elseReg = /^;?\s*else(?![\w$])/.exec(f))) {
|
|
716
582
|
foundTrue = part.substring(0, found.end - part.start);
|
|
717
583
|
found.end += elseReg[0].length - 1;
|
|
718
584
|
count--;
|
|
@@ -725,28 +591,31 @@ function extractIfElse(constants, part) {
|
|
|
725
591
|
break;
|
|
726
592
|
}
|
|
727
593
|
if (!count) {
|
|
728
|
-
|
|
594
|
+
const ie = extractIfElse(constants, part.substring(found.end - part.start + (/^;?\s*else(?![\w$])/.exec(f)?.[0].length || 0)));
|
|
729
595
|
foundElse = ie.all;
|
|
730
596
|
break;
|
|
731
597
|
}
|
|
732
598
|
details = {};
|
|
733
599
|
}
|
|
734
600
|
foundTrue = foundTrue || part.substring(0, found.end - part.start);
|
|
735
|
-
return {
|
|
601
|
+
return {
|
|
602
|
+
all: part.substring(0, Math.max(foundTrue.end, foundElse.end) - part.start),
|
|
603
|
+
true: foundTrue,
|
|
604
|
+
false: foundElse,
|
|
605
|
+
};
|
|
736
606
|
}
|
|
737
607
|
setLispType(['if'], (constants, type, part, res, expect, ctx) => {
|
|
738
|
-
let condition = restOfExp(constants, part.substring(res[0].length), [],
|
|
608
|
+
let condition = restOfExp(constants, part.substring(res[0].length), [], '(');
|
|
739
609
|
const ie = extractIfElse(constants, part.substring(res[1].length));
|
|
740
|
-
const isBlock = /^\s*\{/.exec(part.substring(res[0].length + condition.length + 1).toString());
|
|
741
610
|
const startTrue = res[0].length - res[1].length + condition.length + 1;
|
|
742
611
|
let trueBlock = ie.true.substring(startTrue);
|
|
743
612
|
let elseBlock = ie.false;
|
|
744
613
|
condition = condition.trim();
|
|
745
614
|
trueBlock = trueBlock.trim();
|
|
746
615
|
elseBlock = elseBlock.trim();
|
|
747
|
-
if (trueBlock.char(0) ===
|
|
616
|
+
if (trueBlock.char(0) === '{')
|
|
748
617
|
trueBlock = trueBlock.slice(1, -1);
|
|
749
|
-
if (elseBlock.char(0) ===
|
|
618
|
+
if (elseBlock.char(0) === '{')
|
|
750
619
|
elseBlock = elseBlock.slice(1, -1);
|
|
751
620
|
ctx.lispTree = createLisp({
|
|
752
621
|
op: 13 /* LispType.If */,
|
|
@@ -754,39 +623,39 @@ setLispType(['if'], (constants, type, part, res, expect, ctx) => {
|
|
|
754
623
|
b: createLisp({
|
|
755
624
|
op: 14 /* LispType.IfCase */,
|
|
756
625
|
a: lispifyBlock(trueBlock, constants),
|
|
757
|
-
b: lispifyBlock(elseBlock, constants)
|
|
758
|
-
})
|
|
626
|
+
b: lispifyBlock(elseBlock, constants),
|
|
627
|
+
}),
|
|
759
628
|
});
|
|
760
629
|
});
|
|
761
630
|
setLispType(['switch'], (constants, type, part, res, expect, ctx) => {
|
|
762
|
-
const test = restOfExp(constants, part.substring(res[0].length), [],
|
|
763
|
-
let start = part.toString().indexOf(
|
|
631
|
+
const test = restOfExp(constants, part.substring(res[0].length), [], '(');
|
|
632
|
+
let start = part.toString().indexOf('{', res[0].length + test.length + 1);
|
|
764
633
|
if (start === -1)
|
|
765
|
-
throw new SyntaxError(
|
|
766
|
-
let statement = insertSemicolons(constants, restOfExp(constants, part.substring(start + 1), [],
|
|
634
|
+
throw new SyntaxError('Invalid switch');
|
|
635
|
+
let statement = insertSemicolons(constants, restOfExp(constants, part.substring(start + 1), [], '{'));
|
|
767
636
|
let caseFound;
|
|
768
637
|
const caseTest = /^\s*(case\s|default)\s*/;
|
|
769
|
-
|
|
638
|
+
const cases = [];
|
|
770
639
|
let defaultFound = false;
|
|
771
|
-
while (caseFound = caseTest.exec(statement.toString())) {
|
|
640
|
+
while ((caseFound = caseTest.exec(statement.toString()))) {
|
|
772
641
|
if (caseFound[1] === 'default') {
|
|
773
642
|
if (defaultFound)
|
|
774
|
-
throw new SyntaxError(
|
|
643
|
+
throw new SyntaxError('Only one default switch case allowed');
|
|
775
644
|
defaultFound = true;
|
|
776
645
|
}
|
|
777
|
-
|
|
646
|
+
const cond = restOfExp(constants, statement.substring(caseFound[0].length), [/^:/]);
|
|
778
647
|
let found = emptyString;
|
|
779
|
-
let i = start = caseFound[0].length + cond.length + 1;
|
|
780
|
-
|
|
648
|
+
let i = (start = caseFound[0].length + cond.length + 1);
|
|
649
|
+
const bracketFound = /^\s*\{/.exec(statement.substring(i).toString());
|
|
781
650
|
let exprs = [];
|
|
782
651
|
if (bracketFound) {
|
|
783
652
|
i += bracketFound[0].length;
|
|
784
|
-
found = restOfExp(constants, statement.substring(i), [],
|
|
653
|
+
found = restOfExp(constants, statement.substring(i), [], '{');
|
|
785
654
|
i += found.length + 1;
|
|
786
655
|
exprs = lispifyBlock(found, constants);
|
|
787
656
|
}
|
|
788
657
|
else {
|
|
789
|
-
|
|
658
|
+
const notEmpty = restOfExp(constants, statement.substring(i), [caseTest]);
|
|
790
659
|
if (!notEmpty.trim().length) {
|
|
791
660
|
exprs = [];
|
|
792
661
|
i += notEmpty.length;
|
|
@@ -804,14 +673,14 @@ setLispType(['switch'], (constants, type, part, res, expect, ctx) => {
|
|
|
804
673
|
statement = statement.substring(i);
|
|
805
674
|
cases.push(createLisp({
|
|
806
675
|
op: 41 /* LispType.SwitchCase */,
|
|
807
|
-
a: caseFound[1] ===
|
|
808
|
-
b: exprs
|
|
676
|
+
a: caseFound[1] === 'default' ? 0 /* LispType.None */ : lispifyExpr(constants, cond),
|
|
677
|
+
b: exprs,
|
|
809
678
|
}));
|
|
810
679
|
}
|
|
811
680
|
ctx.lispTree = createLisp({
|
|
812
681
|
op: 40 /* LispType.Switch */,
|
|
813
682
|
a: lispifyExpr(constants, test),
|
|
814
|
-
b: cases
|
|
683
|
+
b: cases,
|
|
815
684
|
});
|
|
816
685
|
});
|
|
817
686
|
setLispType(['dot', 'prop'], (constants, type, part, res, expect, ctx) => {
|
|
@@ -822,7 +691,7 @@ setLispType(['dot', 'prop'], (constants, type, part, res, expect, ctx) => {
|
|
|
822
691
|
if (res[1]) {
|
|
823
692
|
op = '?prop';
|
|
824
693
|
}
|
|
825
|
-
|
|
694
|
+
const matches = part.substring(res[0].length).toString().match(expectTypes.prop.types.prop);
|
|
826
695
|
if (matches && matches.length) {
|
|
827
696
|
prop = matches[0];
|
|
828
697
|
index = prop.length + res[0].length;
|
|
@@ -834,33 +703,37 @@ setLispType(['dot', 'prop'], (constants, type, part, res, expect, ctx) => {
|
|
|
834
703
|
ctx.lispTree = lispify(constants, part.substring(index), expectTypes[expect].next, createLisp({
|
|
835
704
|
op: typesCreate[op],
|
|
836
705
|
a: ctx.lispTree,
|
|
837
|
-
b: prop
|
|
706
|
+
b: prop,
|
|
838
707
|
}));
|
|
839
708
|
});
|
|
840
709
|
setLispType(['spreadArray', 'spreadObject'], (constants, type, part, res, expect, ctx) => {
|
|
841
710
|
ctx.lispTree = createLisp({
|
|
842
711
|
op: type === 'spreadArray' ? 18 /* LispType.SpreadArray */ : 17 /* LispType.SpreadObject */,
|
|
843
712
|
a: 0 /* LispType.None */,
|
|
844
|
-
b: lispify(constants, part.substring(res[0].length), expectTypes[expect].next)
|
|
713
|
+
b: lispify(constants, part.substring(res[0].length), expectTypes[expect].next),
|
|
845
714
|
});
|
|
846
715
|
});
|
|
847
716
|
setLispType(['return', 'throw'], (constants, type, part, res, expect, ctx) => {
|
|
848
717
|
ctx.lispTree = createLisp({
|
|
849
718
|
op: type === 'return' ? 8 /* LispType.Return */ : 46 /* LispType.Throw */,
|
|
850
719
|
a: 0 /* LispType.None */,
|
|
851
|
-
b: lispifyExpr(constants, part.substring(res[0].length))
|
|
720
|
+
b: lispifyExpr(constants, part.substring(res[0].length)),
|
|
852
721
|
});
|
|
853
722
|
});
|
|
854
723
|
setLispType(['number', 'boolean', 'null', 'und', 'NaN', 'Infinity'], (constants, type, part, res, expect, ctx) => {
|
|
855
724
|
ctx.lispTree = lispify(constants, part.substring(res[0].length), expectTypes[expect].next, createLisp({
|
|
856
|
-
op: type ===
|
|
725
|
+
op: type === 'number' ? (res[10] ? 83 /* LispType.BigInt */ : 7 /* LispType.Number */) : 35 /* LispType.GlobalSymbol */,
|
|
857
726
|
a: 0 /* LispType.None */,
|
|
858
|
-
b: res[10] ? res[1] : res[0]
|
|
727
|
+
b: res[10] ? res[1] : res[0],
|
|
859
728
|
}));
|
|
860
729
|
});
|
|
861
730
|
setLispType(['string', 'literal', 'regex'], (constants, type, part, res, expect, ctx) => {
|
|
862
731
|
ctx.lispTree = lispify(constants, part.substring(res[0].length), expectTypes[expect].next, createLisp({
|
|
863
|
-
op: type === 'string'
|
|
732
|
+
op: type === 'string'
|
|
733
|
+
? 2 /* LispType.StringIndex */
|
|
734
|
+
: type === 'literal'
|
|
735
|
+
? 84 /* LispType.LiteralIndex */
|
|
736
|
+
: 85 /* LispType.RegexIndex */,
|
|
864
737
|
a: 0 /* LispType.None */,
|
|
865
738
|
b: res[1],
|
|
866
739
|
}));
|
|
@@ -871,14 +744,14 @@ setLispType(['initialize'], (constants, type, part, res, expect, ctx) => {
|
|
|
871
744
|
ctx.lispTree = lispify(constants, part.substring(res[0].length), expectTypes[expect].next, createLisp({
|
|
872
745
|
op: lt,
|
|
873
746
|
a: res[2],
|
|
874
|
-
b: 0 /* LispType.None
|
|
747
|
+
b: 0 /* LispType.None */,
|
|
875
748
|
}));
|
|
876
749
|
}
|
|
877
750
|
else {
|
|
878
751
|
ctx.lispTree = createLisp({
|
|
879
752
|
op: lt,
|
|
880
753
|
a: res[2],
|
|
881
|
-
b: lispify(constants, part.substring(res[0].length), expectTypes[expect].next)
|
|
754
|
+
b: lispify(constants, part.substring(res[0].length), expectTypes[expect].next),
|
|
882
755
|
});
|
|
883
756
|
}
|
|
884
757
|
});
|
|
@@ -887,9 +760,9 @@ setLispType(['function', 'inlineFunction', 'arrowFunction', 'arrowFunctionSingle
|
|
|
887
760
|
const isReturn = isArrow && !res[res.length - 1];
|
|
888
761
|
const argPos = isArrow ? 2 : 3;
|
|
889
762
|
const isAsync = res[1] ? 88 /* LispType.True */ : 0 /* LispType.None */;
|
|
890
|
-
const args = res[argPos] ? res[argPos].replace(/\s+/g,
|
|
763
|
+
const args = res[argPos] ? res[argPos].replace(/\s+/g, '').split(/,/g) : [];
|
|
891
764
|
if (!isArrow) {
|
|
892
|
-
args.unshift((res[2] ||
|
|
765
|
+
args.unshift((res[2] || '').trimStart());
|
|
893
766
|
}
|
|
894
767
|
let ended = false;
|
|
895
768
|
args.forEach((arg) => {
|
|
@@ -898,64 +771,62 @@ setLispType(['function', 'inlineFunction', 'arrowFunction', 'arrowFunctionSingle
|
|
|
898
771
|
if (arg.startsWith('...'))
|
|
899
772
|
ended = true;
|
|
900
773
|
});
|
|
901
|
-
|
|
902
|
-
const
|
|
903
|
-
const func = (isReturn ? 'return ' + f : f.toString());
|
|
774
|
+
const f = restOfExp(constants, part.substring(res[0].length), !isReturn ? [/^}/] : [/^[,)}\]]/, semiColon]);
|
|
775
|
+
const func = isReturn ? 'return ' + f : f.toString();
|
|
904
776
|
ctx.lispTree = lispify(constants, part.substring(res[0].length + func.length + 1), expectTypes[expect].next, createLisp({
|
|
905
|
-
op: isArrow
|
|
906
|
-
|
|
907
|
-
|
|
777
|
+
op: isArrow
|
|
778
|
+
? 11 /* LispType.ArrowFunction */
|
|
779
|
+
: type === 'function'
|
|
780
|
+
? 37 /* LispType.Function */
|
|
781
|
+
: 10 /* LispType.InlineFunction */,
|
|
782
|
+
a: [isAsync, ...args],
|
|
783
|
+
b: constants.eager ? lispifyFunction(new CodeString(func), constants) : func,
|
|
908
784
|
}));
|
|
909
785
|
});
|
|
910
|
-
const iteratorRegex = /^((let|var|const)\s+)?\s*([a-zA-Z
|
|
786
|
+
const iteratorRegex = /^((let|var|const)\s+)?\s*([a-zA-Z$_][a-zA-Z\d$_]*)\s+(in|of)(?![\w$])/;
|
|
911
787
|
setLispType(['for', 'do', 'while'], (constants, type, part, res, expect, ctx) => {
|
|
912
788
|
let i = 0;
|
|
913
789
|
let startStep = 88 /* LispType.True */;
|
|
914
790
|
let startInternal = [];
|
|
915
|
-
let getIterator
|
|
791
|
+
let getIterator = 0 /* LispType.None */;
|
|
916
792
|
let beforeStep = 0 /* LispType.None */;
|
|
917
793
|
let checkFirst = 88 /* LispType.True */;
|
|
918
794
|
let condition;
|
|
919
795
|
let step = 88 /* LispType.True */;
|
|
920
796
|
let body;
|
|
921
797
|
switch (type) {
|
|
922
|
-
case 'while':
|
|
923
|
-
i = part.toString().indexOf(
|
|
924
|
-
|
|
798
|
+
case 'while': {
|
|
799
|
+
i = part.toString().indexOf('(') + 1;
|
|
800
|
+
const extract = restOfExp(constants, part.substring(i), [], '(');
|
|
925
801
|
condition = lispifyReturnExpr(constants, extract);
|
|
926
802
|
body = restOfExp(constants, part.substring(i + extract.length + 1)).trim();
|
|
927
|
-
if (body
|
|
803
|
+
if (body.char(0) === '{')
|
|
928
804
|
body = body.slice(1, -1);
|
|
929
805
|
break;
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
806
|
+
}
|
|
807
|
+
case 'for': {
|
|
808
|
+
i = part.toString().indexOf('(') + 1;
|
|
809
|
+
const args = [];
|
|
933
810
|
let extract2 = emptyString;
|
|
934
811
|
for (let k = 0; k < 3; k++) {
|
|
935
|
-
extract2 = restOfExp(constants, part.substring(i), [/^[
|
|
812
|
+
extract2 = restOfExp(constants, part.substring(i), [/^[;)]/]);
|
|
936
813
|
args.push(extract2.trim());
|
|
937
814
|
i += extract2.length + 1;
|
|
938
|
-
if (part.char(i - 1) ===
|
|
815
|
+
if (part.char(i - 1) === ')')
|
|
939
816
|
break;
|
|
940
817
|
}
|
|
941
818
|
let iterator;
|
|
942
819
|
if (args.length === 1 && (iterator = iteratorRegex.exec(args[0].toString()))) {
|
|
943
820
|
if (iterator[4] === 'of') {
|
|
944
|
-
getIterator = lispifyReturnExpr(constants, args[0].substring(iterator[0].length)),
|
|
945
|
-
startInternal = [
|
|
946
|
-
ofStart2,
|
|
947
|
-
ofStart3
|
|
948
|
-
];
|
|
821
|
+
(getIterator = lispifyReturnExpr(constants, args[0].substring(iterator[0].length))),
|
|
822
|
+
(startInternal = [ofStart2, ofStart3]);
|
|
949
823
|
condition = ofCondition;
|
|
950
824
|
step = ofStep;
|
|
951
825
|
beforeStep = lispify(constants, new CodeString((iterator[1] || 'let ') + iterator[3] + ' = $$next.value'), ['initialize']);
|
|
952
826
|
}
|
|
953
827
|
else {
|
|
954
|
-
getIterator = lispifyReturnExpr(constants, args[0].substring(iterator[0].length)),
|
|
955
|
-
startInternal = [
|
|
956
|
-
inStart2,
|
|
957
|
-
inStart3
|
|
958
|
-
];
|
|
828
|
+
(getIterator = lispifyReturnExpr(constants, args[0].substring(iterator[0].length))),
|
|
829
|
+
(startInternal = [inStart2, inStart3]);
|
|
959
830
|
step = inStep;
|
|
960
831
|
condition = inCondition;
|
|
961
832
|
beforeStep = lispify(constants, new CodeString((iterator[1] || 'let ') + iterator[3] + ' = $$keys[$$keyIndex]'), ['initialize']);
|
|
@@ -967,59 +838,70 @@ setLispType(['for', 'do', 'while'], (constants, type, part, res, expect, ctx) =>
|
|
|
967
838
|
step = lispifyExpr(constants, args.shift());
|
|
968
839
|
}
|
|
969
840
|
else {
|
|
970
|
-
throw new SyntaxError(
|
|
841
|
+
throw new SyntaxError('Invalid for loop definition');
|
|
971
842
|
}
|
|
972
843
|
body = restOfExp(constants, part.substring(i)).trim();
|
|
973
|
-
if (body
|
|
844
|
+
if (body.char(0) === '{')
|
|
974
845
|
body = body.slice(1, -1);
|
|
975
846
|
break;
|
|
976
|
-
|
|
847
|
+
}
|
|
848
|
+
case 'do': {
|
|
977
849
|
checkFirst = 0 /* LispType.None */;
|
|
978
850
|
const isBlock = !!res[3];
|
|
979
851
|
body = restOfExp(constants, part.substring(res[0].length), isBlock ? [/^\}/] : [semiColon]);
|
|
980
|
-
condition = lispifyReturnExpr(constants, restOfExp(constants, part.substring(part.toString().indexOf(
|
|
852
|
+
condition = lispifyReturnExpr(constants, restOfExp(constants, part.substring(part.toString().indexOf('(', res[0].length + body.length) + 1), [], '('));
|
|
981
853
|
break;
|
|
854
|
+
}
|
|
982
855
|
}
|
|
983
|
-
const a = [
|
|
856
|
+
const a = [
|
|
857
|
+
checkFirst,
|
|
858
|
+
startInternal,
|
|
859
|
+
getIterator,
|
|
860
|
+
startStep,
|
|
861
|
+
step,
|
|
862
|
+
condition,
|
|
863
|
+
beforeStep,
|
|
864
|
+
];
|
|
984
865
|
ctx.lispTree = createLisp({
|
|
985
866
|
op: 38 /* LispType.Loop */,
|
|
986
867
|
a,
|
|
987
|
-
b: lispifyBlock(body, constants)
|
|
868
|
+
b: lispifyBlock(body, constants),
|
|
988
869
|
});
|
|
989
870
|
});
|
|
990
871
|
setLispType(['block'], (constants, type, part, res, expect, ctx) => {
|
|
991
872
|
ctx.lispTree = createLisp({
|
|
992
873
|
op: 42 /* LispType.Block */,
|
|
993
|
-
a: lispifyBlock(restOfExp(constants, part.substring(1), [],
|
|
994
|
-
b: 0 /* LispType.None
|
|
874
|
+
a: lispifyBlock(restOfExp(constants, part.substring(1), [], '{'), constants),
|
|
875
|
+
b: 0 /* LispType.None */,
|
|
995
876
|
});
|
|
996
877
|
});
|
|
997
878
|
setLispType(['loopAction'], (constants, type, part, res, expect, ctx) => {
|
|
998
879
|
ctx.lispTree = createLisp({
|
|
999
880
|
op: 86 /* LispType.LoopAction */,
|
|
1000
881
|
a: res[1],
|
|
1001
|
-
b: 0 /* LispType.None
|
|
882
|
+
b: 0 /* LispType.None */,
|
|
1002
883
|
});
|
|
1003
884
|
});
|
|
1004
|
-
const catchReg = /^\s*(catch\s*(\(\s*([a-zA-Z
|
|
885
|
+
const catchReg = /^\s*(catch\s*(\(\s*([a-zA-Z$_][a-zA-Z\d$_]*)\s*\))?|finally)\s*\{/;
|
|
1005
886
|
setLispType(['try'], (constants, type, part, res, expect, ctx) => {
|
|
1006
|
-
const body = restOfExp(constants, part.substring(res[0].length), [],
|
|
887
|
+
const body = restOfExp(constants, part.substring(res[0].length), [], '{');
|
|
1007
888
|
let catchRes = catchReg.exec(part.substring(res[0].length + body.length + 1).toString());
|
|
1008
889
|
let finallyBody;
|
|
1009
|
-
let exception =
|
|
890
|
+
let exception = '';
|
|
1010
891
|
let catchBody;
|
|
1011
892
|
let offset = 0;
|
|
1012
893
|
if (catchRes[1].startsWith('catch')) {
|
|
1013
894
|
catchRes = catchReg.exec(part.substring(res[0].length + body.length + 1).toString());
|
|
1014
895
|
exception = catchRes[2];
|
|
1015
|
-
catchBody = restOfExp(constants, part.substring(res[0].length + body.length + 1 + catchRes[0].length), [],
|
|
896
|
+
catchBody = restOfExp(constants, part.substring(res[0].length + body.length + 1 + catchRes[0].length), [], '{');
|
|
1016
897
|
offset = res[0].length + body.length + 1 + catchRes[0].length + catchBody.length + 1;
|
|
1017
|
-
if ((catchRes = catchReg.exec(part.substring(offset).toString())) &&
|
|
1018
|
-
|
|
898
|
+
if ((catchRes = catchReg.exec(part.substring(offset).toString())) &&
|
|
899
|
+
catchRes[1].startsWith('finally')) {
|
|
900
|
+
finallyBody = restOfExp(constants, part.substring(offset + catchRes[0].length), [], '{');
|
|
1019
901
|
}
|
|
1020
902
|
}
|
|
1021
903
|
else {
|
|
1022
|
-
finallyBody = restOfExp(constants, part.substring(res[0].length + body.length + 1 + catchRes[0].length), [],
|
|
904
|
+
finallyBody = restOfExp(constants, part.substring(res[0].length + body.length + 1 + catchRes[0].length), [], '{');
|
|
1023
905
|
}
|
|
1024
906
|
const b = [
|
|
1025
907
|
exception,
|
|
@@ -1029,24 +911,24 @@ setLispType(['try'], (constants, type, part, res, expect, ctx) => {
|
|
|
1029
911
|
ctx.lispTree = createLisp({
|
|
1030
912
|
op: 39 /* LispType.Try */,
|
|
1031
913
|
a: lispifyBlock(insertSemicolons(constants, body), constants),
|
|
1032
|
-
b
|
|
914
|
+
b,
|
|
1033
915
|
});
|
|
1034
916
|
});
|
|
1035
917
|
setLispType(['void', 'await'], (constants, type, part, res, expect, ctx) => {
|
|
1036
|
-
const extract = restOfExp(constants, part.substring(res[0].length), [/^([^\s
|
|
918
|
+
const extract = restOfExp(constants, part.substring(res[0].length), [/^([^\s.?\w$]|\?[^.])/]);
|
|
1037
919
|
ctx.lispTree = lispify(constants, part.substring(res[0].length + extract.length), expectTypes[expect].next, createLisp({
|
|
1038
920
|
op: type === 'void' ? 87 /* LispType.Void */ : 44 /* LispType.Await */,
|
|
1039
921
|
a: lispify(constants, extract),
|
|
1040
|
-
b: 0 /* LispType.None
|
|
922
|
+
b: 0 /* LispType.None */,
|
|
1041
923
|
}));
|
|
1042
924
|
});
|
|
1043
925
|
setLispType(['new'], (constants, type, part, res, expect, ctx) => {
|
|
1044
926
|
let i = res[0].length;
|
|
1045
|
-
const obj = restOfExp(constants, part.substring(i), [], undefined,
|
|
927
|
+
const obj = restOfExp(constants, part.substring(i), [], undefined, '(');
|
|
1046
928
|
i += obj.length + 1;
|
|
1047
929
|
const args = [];
|
|
1048
|
-
if (part.char(i - 1) ===
|
|
1049
|
-
const argsString = restOfExp(constants, part.substring(i), [],
|
|
930
|
+
if (part.char(i - 1) === '(') {
|
|
931
|
+
const argsString = restOfExp(constants, part.substring(i), [], '(');
|
|
1050
932
|
i += argsString.length + 1;
|
|
1051
933
|
let found;
|
|
1052
934
|
let j = 0;
|
|
@@ -1062,48 +944,51 @@ setLispType(['new'], (constants, type, part, res, expect, ctx) => {
|
|
|
1062
944
|
}));
|
|
1063
945
|
});
|
|
1064
946
|
const ofStart2 = lispify(undefined, new CodeString('let $$iterator = $$obj[Symbol.iterator]()'), ['initialize']);
|
|
1065
|
-
const ofStart3 = lispify(undefined, new CodeString('let $$next = $$iterator.next()'), [
|
|
1066
|
-
|
|
947
|
+
const ofStart3 = lispify(undefined, new CodeString('let $$next = $$iterator.next()'), [
|
|
948
|
+
'initialize',
|
|
949
|
+
]);
|
|
950
|
+
const ofCondition = lispify(undefined, new CodeString('return !$$next.done'), [
|
|
951
|
+
'initialize',
|
|
952
|
+
]);
|
|
1067
953
|
const ofStep = lispify(undefined, new CodeString('$$next = $$iterator.next()'));
|
|
1068
|
-
const inStart2 = lispify(undefined, new CodeString('let $$keys = Object.keys($$obj)'), [
|
|
954
|
+
const inStart2 = lispify(undefined, new CodeString('let $$keys = Object.keys($$obj)'), [
|
|
955
|
+
'initialize',
|
|
956
|
+
]);
|
|
1069
957
|
const inStart3 = lispify(undefined, new CodeString('let $$keyIndex = 0'), ['initialize']);
|
|
1070
958
|
const inStep = lispify(undefined, new CodeString('$$keyIndex++'));
|
|
1071
|
-
const inCondition = lispify(undefined, new CodeString('return $$keyIndex < $$keys.length'), [
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
var lastLastPart;
|
|
1075
|
-
var lastLastLastPart;
|
|
1076
|
-
var lastLastLastLastPart;
|
|
959
|
+
const inCondition = lispify(undefined, new CodeString('return $$keyIndex < $$keys.length'), [
|
|
960
|
+
'initialize',
|
|
961
|
+
]);
|
|
1077
962
|
function lispify(constants, part, expected, lispTree, topLevel = false) {
|
|
1078
|
-
lispTree = lispTree ||
|
|
963
|
+
lispTree = lispTree || NullLisp;
|
|
1079
964
|
expected = expected || expectTypes.initialize.next;
|
|
1080
965
|
if (part === undefined)
|
|
1081
966
|
return lispTree;
|
|
1082
967
|
part = part.trimStart();
|
|
1083
968
|
const str = part.toString();
|
|
1084
969
|
if (!part.length && !expected.includes('expEnd')) {
|
|
1085
|
-
throw new SyntaxError(
|
|
970
|
+
throw new SyntaxError('Unexpected end of expression');
|
|
1086
971
|
}
|
|
1087
972
|
if (!part.length)
|
|
1088
973
|
return lispTree;
|
|
1089
|
-
|
|
974
|
+
const ctx = { lispTree: lispTree };
|
|
1090
975
|
let res;
|
|
1091
|
-
for (
|
|
976
|
+
for (const expect of expected) {
|
|
1092
977
|
if (expect === 'expEnd') {
|
|
1093
978
|
continue;
|
|
1094
979
|
}
|
|
1095
|
-
for (
|
|
980
|
+
for (const type in expectTypes[expect].types) {
|
|
1096
981
|
if (type === 'expEnd') {
|
|
1097
982
|
continue;
|
|
1098
983
|
}
|
|
1099
|
-
if (res = expectTypes[expect].types[type].exec(str)) {
|
|
984
|
+
if ((res = expectTypes[expect].types[type].exec(str))) {
|
|
1100
985
|
lastType = type;
|
|
1101
986
|
lastLastLastLastPart = lastLastLastPart;
|
|
1102
987
|
lastLastLastPart = lastLastPart;
|
|
1103
988
|
lastLastPart = lastPart;
|
|
1104
989
|
lastPart = part;
|
|
1105
990
|
try {
|
|
1106
|
-
lispTypes.get(type)(constants, type, part, res, expect, ctx);
|
|
991
|
+
lispTypes.get(type)?.(constants, type, part, res, expect, ctx);
|
|
1107
992
|
}
|
|
1108
993
|
catch (e) {
|
|
1109
994
|
if (topLevel && e instanceof SyntaxError) {
|
|
@@ -1118,7 +1003,6 @@ function lispify(constants, part, expected, lispTree, topLevel = false) {
|
|
|
1118
1003
|
break;
|
|
1119
1004
|
}
|
|
1120
1005
|
if (!res && part.length) {
|
|
1121
|
-
let msg = `Unexpected token after ${lastType}: ${part.char(0)}`;
|
|
1122
1006
|
if (topLevel) {
|
|
1123
1007
|
throw new ParseError(`Unexpected token after ${lastType}: ${part.char(0)}`, str);
|
|
1124
1008
|
}
|
|
@@ -1129,8 +1013,8 @@ function lispify(constants, part, expected, lispTree, topLevel = false) {
|
|
|
1129
1013
|
const startingExpectedWithoutSingle = startingExecpted.filter((r) => r !== 'expSingle');
|
|
1130
1014
|
function lispifyExpr(constants, str, expected) {
|
|
1131
1015
|
if (!str.trimStart().length)
|
|
1132
|
-
return
|
|
1133
|
-
|
|
1016
|
+
return NullLisp;
|
|
1017
|
+
const subExpressions = [];
|
|
1134
1018
|
let sub;
|
|
1135
1019
|
let pos = 0;
|
|
1136
1020
|
expected = expected || expectTypes.initialize.next;
|
|
@@ -1149,29 +1033,33 @@ function lispifyExpr(constants, str, expected) {
|
|
|
1149
1033
|
return lispify(constants, str, expected, undefined, true);
|
|
1150
1034
|
}
|
|
1151
1035
|
if (expected.includes('initialize')) {
|
|
1152
|
-
|
|
1036
|
+
const defined = expectTypes.initialize.types.initialize.exec(subExpressions[0].toString());
|
|
1153
1037
|
if (defined) {
|
|
1154
1038
|
return createLisp({
|
|
1155
1039
|
op: 42 /* LispType.Block */,
|
|
1156
1040
|
a: subExpressions.map((str, i) => lispify(constants, i ? new CodeString(defined[1] + ' ' + str) : str, ['initialize'], undefined, true)),
|
|
1157
|
-
b: 0 /* LispType.None
|
|
1041
|
+
b: 0 /* LispType.None */,
|
|
1158
1042
|
});
|
|
1159
1043
|
}
|
|
1160
1044
|
else if (expectTypes.initialize.types.return.exec(subExpressions[0].toString())) {
|
|
1161
1045
|
return lispify(constants, str, expected, undefined, true);
|
|
1162
1046
|
}
|
|
1163
1047
|
}
|
|
1164
|
-
const exprs = subExpressions.map((str
|
|
1048
|
+
const exprs = subExpressions.map((str) => lispify(constants, str, expected, undefined, true));
|
|
1165
1049
|
return createLisp({ op: 43 /* LispType.Expression */, a: exprs, b: 0 /* LispType.None */ });
|
|
1166
1050
|
}
|
|
1167
1051
|
export function lispifyReturnExpr(constants, str) {
|
|
1168
|
-
return createLisp({
|
|
1052
|
+
return createLisp({
|
|
1053
|
+
op: 8 /* LispType.Return */,
|
|
1054
|
+
a: 0 /* LispType.None */,
|
|
1055
|
+
b: lispifyExpr(constants, str),
|
|
1056
|
+
});
|
|
1169
1057
|
}
|
|
1170
1058
|
export function lispifyBlock(str, constants, expression = false) {
|
|
1171
1059
|
str = insertSemicolons(constants, str);
|
|
1172
1060
|
if (!str.trim().length)
|
|
1173
1061
|
return [];
|
|
1174
|
-
|
|
1062
|
+
const parts = [];
|
|
1175
1063
|
let part;
|
|
1176
1064
|
let pos = 0;
|
|
1177
1065
|
let start = 0;
|
|
@@ -1179,12 +1067,13 @@ export function lispifyBlock(str, constants, expression = false) {
|
|
|
1179
1067
|
let skipped = false;
|
|
1180
1068
|
let isInserted = false;
|
|
1181
1069
|
while ((part = restOfExp(constants, str.substring(pos), [semiColon], undefined, undefined, undefined, details)).length) {
|
|
1182
|
-
isInserted = str.char(pos + part.length) && str.char(pos + part.length) !== ';';
|
|
1070
|
+
isInserted = !!(str.char(pos + part.length) && str.char(pos + part.length) !== ';');
|
|
1183
1071
|
pos += part.length + (isInserted ? 0 : 1);
|
|
1184
|
-
if (/^\s*else(?![\w
|
|
1072
|
+
if (/^\s*else(?![\w$])/.test(str.substring(pos).toString())) {
|
|
1185
1073
|
skipped = true;
|
|
1186
1074
|
}
|
|
1187
|
-
else if (details
|
|
1075
|
+
else if (details['words']?.includes('do') &&
|
|
1076
|
+
/^\s*while(?![\w$])/.test(str.substring(pos).toString())) {
|
|
1188
1077
|
skipped = true;
|
|
1189
1078
|
}
|
|
1190
1079
|
else {
|
|
@@ -1199,7 +1088,10 @@ export function lispifyBlock(str, constants, expression = false) {
|
|
|
1199
1088
|
if (skipped) {
|
|
1200
1089
|
parts.push(str.substring(start, pos - (isInserted ? 0 : 1)));
|
|
1201
1090
|
}
|
|
1202
|
-
return parts
|
|
1091
|
+
return parts
|
|
1092
|
+
.map((str) => str.trimStart())
|
|
1093
|
+
.filter((str) => str.length)
|
|
1094
|
+
.map((str) => {
|
|
1203
1095
|
return lispifyExpr(constants, str.trimStart(), startingExecpted);
|
|
1204
1096
|
});
|
|
1205
1097
|
}
|
|
@@ -1207,17 +1099,19 @@ export function lispifyFunction(str, constants, expression = false) {
|
|
|
1207
1099
|
if (!str.trim().length)
|
|
1208
1100
|
return [];
|
|
1209
1101
|
const tree = lispifyBlock(str, constants, expression);
|
|
1210
|
-
|
|
1102
|
+
const hoisted = [];
|
|
1211
1103
|
hoist(tree, hoisted);
|
|
1212
1104
|
return hoisted.concat(tree);
|
|
1213
1105
|
}
|
|
1214
|
-
export function isLisp(item) {
|
|
1215
|
-
return Array.isArray(item) && typeof item[0] === 'number' && item[0] !== 0 /* LispType.None */ && item[0] !== 88 /* LispType.True */;
|
|
1216
|
-
}
|
|
1217
1106
|
function hoist(item, res) {
|
|
1218
1107
|
if (isLisp(item)) {
|
|
1108
|
+
if (!isLisp(item))
|
|
1109
|
+
return false;
|
|
1219
1110
|
const [op, a, b] = item;
|
|
1220
|
-
if (op === 39 /* LispType.Try */ ||
|
|
1111
|
+
if (op === 39 /* LispType.Try */ ||
|
|
1112
|
+
op === 13 /* LispType.If */ ||
|
|
1113
|
+
op === 38 /* LispType.Loop */ ||
|
|
1114
|
+
op === 40 /* LispType.Switch */) {
|
|
1221
1115
|
hoist(a, res);
|
|
1222
1116
|
hoist(b, res);
|
|
1223
1117
|
}
|
|
@@ -1231,7 +1125,7 @@ function hoist(item, res) {
|
|
|
1231
1125
|
}
|
|
1232
1126
|
else if (Array.isArray(item)) {
|
|
1233
1127
|
const rep = [];
|
|
1234
|
-
for (
|
|
1128
|
+
for (const it of item) {
|
|
1235
1129
|
if (!hoist(it, res)) {
|
|
1236
1130
|
rep.push(it);
|
|
1237
1131
|
}
|
|
@@ -1243,9 +1137,9 @@ function hoist(item, res) {
|
|
|
1243
1137
|
}
|
|
1244
1138
|
return false;
|
|
1245
1139
|
}
|
|
1246
|
-
const closingsNoInsertion = /^(\})\s*(catch|finally|else|while|instanceof)(?![\w
|
|
1247
|
-
// \w|)|] \n \w = 2 // \} \w|\{ = 5
|
|
1248
|
-
const colonsRegex = /^((([\w
|
|
1140
|
+
const closingsNoInsertion = /^(\})\s*(catch|finally|else|while|instanceof)(?![\w$])/;
|
|
1141
|
+
// \w|)|] \n \w = 2 // \} \w|\{ = 5
|
|
1142
|
+
const colonsRegex = /^((([\w$\])"'`]|\+\+|--)\s*\r?\n\s*([\w$+\-!~]))|(\}\s*[\w$!~+\-{("'`]))/;
|
|
1249
1143
|
// if () \w \n; \w == \w \n \w | last === if a
|
|
1250
1144
|
// if () { }; \w == \} ^else | last === if b
|
|
1251
1145
|
// if () \w \n; else \n \w \n; == \w \n \w | last === else a
|
|
@@ -1271,10 +1165,10 @@ export function insertSemicolons(constants, str) {
|
|
|
1271
1165
|
if (details.regRes) {
|
|
1272
1166
|
valid = true;
|
|
1273
1167
|
const [, , a, , , b] = details.regRes;
|
|
1274
|
-
edge = details.regRes[3] ===
|
|
1168
|
+
edge = details.regRes[3] === '++' || details.regRes[3] === '--' ? sub.length + 1 : sub.length;
|
|
1275
1169
|
part = rest.substring(0, edge);
|
|
1276
1170
|
if (b) {
|
|
1277
|
-
|
|
1171
|
+
const res = closingsNoInsertion.exec(rest.substring(sub.length - 1).toString());
|
|
1278
1172
|
if (res) {
|
|
1279
1173
|
if (res[2] === 'while') {
|
|
1280
1174
|
valid = details.lastWord !== 'do';
|
|
@@ -1283,12 +1177,17 @@ export function insertSemicolons(constants, str) {
|
|
|
1283
1177
|
valid = false;
|
|
1284
1178
|
}
|
|
1285
1179
|
}
|
|
1286
|
-
else if (details.lastWord === 'function' &&
|
|
1180
|
+
else if (details.lastWord === 'function' &&
|
|
1181
|
+
details.regRes[5][0] === '}' &&
|
|
1182
|
+
details.regRes[5].slice(-1) === '(') {
|
|
1287
1183
|
valid = false;
|
|
1288
1184
|
}
|
|
1289
1185
|
}
|
|
1290
1186
|
else if (a) {
|
|
1291
|
-
if (details.lastWord === 'if' ||
|
|
1187
|
+
if (details.lastWord === 'if' ||
|
|
1188
|
+
details.lastWord === 'while' ||
|
|
1189
|
+
details.lastWord === 'for' ||
|
|
1190
|
+
details.lastWord === 'else') {
|
|
1292
1191
|
valid = false;
|
|
1293
1192
|
}
|
|
1294
1193
|
}
|
|
@@ -1308,49 +1207,50 @@ export function checkRegex(str) {
|
|
|
1308
1207
|
let done = false;
|
|
1309
1208
|
let cancel = false;
|
|
1310
1209
|
while (i < str.length && !done && !cancel) {
|
|
1311
|
-
done =
|
|
1210
|
+
done = str[i] === '/' && !escape;
|
|
1312
1211
|
escape = str[i] === '\\' && !escape;
|
|
1313
1212
|
cancel = str[i] === '\n';
|
|
1314
1213
|
i++;
|
|
1315
1214
|
}
|
|
1316
|
-
|
|
1317
|
-
cancel =
|
|
1215
|
+
const after = str.substring(i);
|
|
1216
|
+
cancel = cancel || !done || /^\s*\d/.test(after);
|
|
1318
1217
|
if (cancel)
|
|
1319
1218
|
return null;
|
|
1320
|
-
|
|
1321
|
-
if (/^\s+[\w
|
|
1219
|
+
const flags = /^[a-z]*/.exec(after);
|
|
1220
|
+
if (/^\s+[\w$]/.test(str.substring(i + flags[0].length))) {
|
|
1322
1221
|
return null;
|
|
1323
1222
|
}
|
|
1324
1223
|
return {
|
|
1325
1224
|
regex: str.substring(1, i - 1),
|
|
1326
|
-
flags: (flags && flags[0]) ||
|
|
1327
|
-
length: i + ((flags && flags[0].length) || 0)
|
|
1225
|
+
flags: (flags && flags[0]) || '',
|
|
1226
|
+
length: i + ((flags && flags[0].length) || 0),
|
|
1328
1227
|
};
|
|
1329
1228
|
}
|
|
1330
1229
|
const notDivide = /(typeof|delete|instanceof|return|in|of|throw|new|void|do|if)$/;
|
|
1331
|
-
const possibleDivide = /^([\w
|
|
1332
|
-
export function extractConstants(constants, str, currentEnclosure =
|
|
1230
|
+
const possibleDivide = /^([\w$\])]|\+\+|--)[\s/]/;
|
|
1231
|
+
export function extractConstants(constants, str, currentEnclosure = '') {
|
|
1333
1232
|
let quote;
|
|
1334
1233
|
let extract = [];
|
|
1335
1234
|
let escape = false;
|
|
1336
1235
|
let regexFound;
|
|
1337
|
-
let comment =
|
|
1236
|
+
let comment = '';
|
|
1338
1237
|
let commentStart = -1;
|
|
1339
1238
|
let currJs = [];
|
|
1340
|
-
let char =
|
|
1239
|
+
let char = '';
|
|
1341
1240
|
const strRes = [];
|
|
1342
1241
|
const enclosures = [];
|
|
1343
|
-
let isPossibleDivide;
|
|
1344
|
-
|
|
1242
|
+
let isPossibleDivide = null;
|
|
1243
|
+
let i = 0;
|
|
1244
|
+
for (i = 0; i < str.length; i++) {
|
|
1345
1245
|
char = str[i];
|
|
1346
1246
|
if (comment) {
|
|
1347
1247
|
if (char === comment) {
|
|
1348
|
-
if (comment ===
|
|
1349
|
-
comment =
|
|
1248
|
+
if (comment === '*' && str[i + 1] === '/') {
|
|
1249
|
+
comment = '';
|
|
1350
1250
|
i++;
|
|
1351
1251
|
}
|
|
1352
|
-
else if (comment ===
|
|
1353
|
-
comment =
|
|
1252
|
+
else if (comment === '\n') {
|
|
1253
|
+
comment = '';
|
|
1354
1254
|
}
|
|
1355
1255
|
}
|
|
1356
1256
|
}
|
|
@@ -1361,8 +1261,8 @@ export function extractConstants(constants, str, currentEnclosure = "") {
|
|
|
1361
1261
|
continue;
|
|
1362
1262
|
}
|
|
1363
1263
|
if (quote) {
|
|
1364
|
-
if (quote ===
|
|
1365
|
-
|
|
1264
|
+
if (quote === '`' && char === '$' && str[i + 1] === '{') {
|
|
1265
|
+
const skip = extractConstants(constants, str.substring(i + 2), '{');
|
|
1366
1266
|
currJs.push(skip.str);
|
|
1367
1267
|
extract.push('${', currJs.length - 1, `}`);
|
|
1368
1268
|
i += skip.length + 2;
|
|
@@ -1371,7 +1271,7 @@ export function extractConstants(constants, str, currentEnclosure = "") {
|
|
|
1371
1271
|
if (quote === '`') {
|
|
1372
1272
|
const li = createLisp({
|
|
1373
1273
|
op: 36 /* LispType.Literal */,
|
|
1374
|
-
a: unraw(extract.join(
|
|
1274
|
+
a: unraw(extract.join('')),
|
|
1375
1275
|
b: [],
|
|
1376
1276
|
});
|
|
1377
1277
|
li.tempJsStrings = currJs;
|
|
@@ -1379,7 +1279,7 @@ export function extractConstants(constants, str, currentEnclosure = "") {
|
|
|
1379
1279
|
strRes.push(`\``, constants.literals.length - 1, `\``);
|
|
1380
1280
|
}
|
|
1381
1281
|
else {
|
|
1382
|
-
constants.strings.push(unraw(extract.join(
|
|
1282
|
+
constants.strings.push(unraw(extract.join('')));
|
|
1383
1283
|
strRes.push(`"`, constants.strings.length - 1, `"`);
|
|
1384
1284
|
}
|
|
1385
1285
|
quote = null;
|
|
@@ -1390,12 +1290,12 @@ export function extractConstants(constants, str, currentEnclosure = "") {
|
|
|
1390
1290
|
}
|
|
1391
1291
|
}
|
|
1392
1292
|
else {
|
|
1393
|
-
if (
|
|
1293
|
+
if (char === "'" || char === '"' || char === '`') {
|
|
1394
1294
|
currJs = [];
|
|
1395
1295
|
quote = char;
|
|
1396
1296
|
}
|
|
1397
1297
|
else if (closings[currentEnclosure] === char && !enclosures.length) {
|
|
1398
|
-
return { str: strRes.join(
|
|
1298
|
+
return { str: strRes.join(''), length: i };
|
|
1399
1299
|
}
|
|
1400
1300
|
else if (closings[char]) {
|
|
1401
1301
|
enclosures.push(char);
|
|
@@ -1405,11 +1305,13 @@ export function extractConstants(constants, str, currentEnclosure = "") {
|
|
|
1405
1305
|
enclosures.pop();
|
|
1406
1306
|
strRes.push(char);
|
|
1407
1307
|
}
|
|
1408
|
-
else if (char ===
|
|
1409
|
-
comment = str[i + 1] ===
|
|
1308
|
+
else if (char === '/' && (str[i + 1] === '*' || str[i + 1] === '/')) {
|
|
1309
|
+
comment = str[i + 1] === '*' ? '*' : '\n';
|
|
1410
1310
|
commentStart = i;
|
|
1411
1311
|
}
|
|
1412
|
-
else if (char === '/' &&
|
|
1312
|
+
else if (char === '/' &&
|
|
1313
|
+
!isPossibleDivide &&
|
|
1314
|
+
(regexFound = checkRegex(str.substring(i)))) {
|
|
1413
1315
|
constants.regexes.push(regexFound);
|
|
1414
1316
|
strRes.push(`/`, constants.regexes.length - 1, `/r`);
|
|
1415
1317
|
i += regexFound.length - 1;
|
|
@@ -1418,30 +1320,30 @@ export function extractConstants(constants, str, currentEnclosure = "") {
|
|
|
1418
1320
|
strRes.push(char);
|
|
1419
1321
|
}
|
|
1420
1322
|
if (!isPossibleDivide || !space.test(char)) {
|
|
1421
|
-
if (isPossibleDivide = possibleDivide.exec(str.substring(i))) {
|
|
1323
|
+
if ((isPossibleDivide = possibleDivide.exec(str.substring(i)))) {
|
|
1422
1324
|
if (notDivide.test(str.substring(0, i + isPossibleDivide[1].length))) {
|
|
1423
1325
|
isPossibleDivide = null;
|
|
1424
1326
|
}
|
|
1425
1327
|
}
|
|
1426
1328
|
}
|
|
1427
1329
|
}
|
|
1428
|
-
escape = quote && char ===
|
|
1330
|
+
escape = !!(quote && char === '\\');
|
|
1429
1331
|
}
|
|
1430
1332
|
}
|
|
1431
1333
|
if (comment) {
|
|
1432
|
-
if (comment ===
|
|
1334
|
+
if (comment === '*') {
|
|
1433
1335
|
throw new SyntaxError(`Unclosed comment '/*': ${str.substring(commentStart)}`);
|
|
1434
1336
|
}
|
|
1435
1337
|
}
|
|
1436
|
-
return { str: strRes.join(
|
|
1338
|
+
return { str: strRes.join(''), length: i };
|
|
1437
1339
|
}
|
|
1438
|
-
export function parse(code, eager = false, expression = false) {
|
|
1340
|
+
export default function parse(code, eager = false, expression = false) {
|
|
1439
1341
|
if (typeof code !== 'string')
|
|
1440
1342
|
throw new ParseError(`Cannot parse ${code}`, code);
|
|
1441
1343
|
let str = ' ' + code;
|
|
1442
1344
|
const constants = { strings: [], literals: [], regexes: [], eager };
|
|
1443
1345
|
str = extractConstants(constants, str).str;
|
|
1444
|
-
for (
|
|
1346
|
+
for (const l of constants.literals) {
|
|
1445
1347
|
l[2] = l.tempJsStrings.map((js) => lispifyExpr(constants, new CodeString(js)));
|
|
1446
1348
|
delete l.tempJsStrings;
|
|
1447
1349
|
}
|