@nyariv/sandboxjs 0.8.23 → 0.8.25
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/README.md +1 -1
- 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 +345 -444
- 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 +1527 -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 +1513 -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/jest.config.js +200 -0
- package/package.json +16 -5
- package/tsconfig.jest.json +16 -0
- 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,18 @@ 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
|
-
|
|
1211
|
-
|
|
1212
|
-
return hoisted.concat(tree);
|
|
1102
|
+
hoist(tree);
|
|
1103
|
+
return tree;
|
|
1213
1104
|
}
|
|
1214
|
-
|
|
1215
|
-
return Array.isArray(item) && typeof item[0] === 'number' && item[0] !== 0 /* LispType.None */ && item[0] !== 88 /* LispType.True */;
|
|
1216
|
-
}
|
|
1217
|
-
function hoist(item, res) {
|
|
1105
|
+
function hoist(item, res = []) {
|
|
1218
1106
|
if (isLisp(item)) {
|
|
1107
|
+
if (!isLisp(item))
|
|
1108
|
+
return false;
|
|
1219
1109
|
const [op, a, b] = item;
|
|
1220
|
-
if (op === 39 /* LispType.Try */ ||
|
|
1110
|
+
if (op === 39 /* LispType.Try */ ||
|
|
1111
|
+
op === 13 /* LispType.If */ ||
|
|
1112
|
+
op === 38 /* LispType.Loop */ ||
|
|
1113
|
+
op === 40 /* LispType.Switch */) {
|
|
1221
1114
|
hoist(a, res);
|
|
1222
1115
|
hoist(b, res);
|
|
1223
1116
|
}
|
|
@@ -1231,21 +1124,21 @@ function hoist(item, res) {
|
|
|
1231
1124
|
}
|
|
1232
1125
|
else if (Array.isArray(item)) {
|
|
1233
1126
|
const rep = [];
|
|
1234
|
-
for (
|
|
1127
|
+
for (const it of item) {
|
|
1235
1128
|
if (!hoist(it, res)) {
|
|
1236
1129
|
rep.push(it);
|
|
1237
1130
|
}
|
|
1238
1131
|
}
|
|
1239
1132
|
if (rep.length !== item.length) {
|
|
1240
1133
|
item.length = 0;
|
|
1241
|
-
item.push(...rep);
|
|
1134
|
+
item.push(...res, ...rep);
|
|
1242
1135
|
}
|
|
1243
1136
|
}
|
|
1244
1137
|
return false;
|
|
1245
1138
|
}
|
|
1246
|
-
const closingsNoInsertion = /^(\})\s*(catch|finally|else|while|instanceof)(?![\w
|
|
1247
|
-
// \w|)|] \n \w = 2 // \} \w|\{ = 5
|
|
1248
|
-
const colonsRegex = /^((([\w
|
|
1139
|
+
const closingsNoInsertion = /^(\})\s*(catch|finally|else|while|instanceof)(?![\w$])/;
|
|
1140
|
+
// \w|)|] \n \w = 2 // \} \w|\{ = 5
|
|
1141
|
+
const colonsRegex = /^((([\w$\])"'`]|\+\+|--)\s*\r?\n\s*([\w$+\-!~]))|(\}\s*[\w$!~+\-{("'`]))/;
|
|
1249
1142
|
// if () \w \n; \w == \w \n \w | last === if a
|
|
1250
1143
|
// if () { }; \w == \} ^else | last === if b
|
|
1251
1144
|
// if () \w \n; else \n \w \n; == \w \n \w | last === else a
|
|
@@ -1271,10 +1164,10 @@ export function insertSemicolons(constants, str) {
|
|
|
1271
1164
|
if (details.regRes) {
|
|
1272
1165
|
valid = true;
|
|
1273
1166
|
const [, , a, , , b] = details.regRes;
|
|
1274
|
-
edge = details.regRes[3] ===
|
|
1167
|
+
edge = details.regRes[3] === '++' || details.regRes[3] === '--' ? sub.length + 1 : sub.length;
|
|
1275
1168
|
part = rest.substring(0, edge);
|
|
1276
1169
|
if (b) {
|
|
1277
|
-
|
|
1170
|
+
const res = closingsNoInsertion.exec(rest.substring(sub.length - 1).toString());
|
|
1278
1171
|
if (res) {
|
|
1279
1172
|
if (res[2] === 'while') {
|
|
1280
1173
|
valid = details.lastWord !== 'do';
|
|
@@ -1283,12 +1176,17 @@ export function insertSemicolons(constants, str) {
|
|
|
1283
1176
|
valid = false;
|
|
1284
1177
|
}
|
|
1285
1178
|
}
|
|
1286
|
-
else if (details.lastWord === 'function' &&
|
|
1179
|
+
else if (details.lastWord === 'function' &&
|
|
1180
|
+
details.regRes[5][0] === '}' &&
|
|
1181
|
+
details.regRes[5].slice(-1) === '(') {
|
|
1287
1182
|
valid = false;
|
|
1288
1183
|
}
|
|
1289
1184
|
}
|
|
1290
1185
|
else if (a) {
|
|
1291
|
-
if (details.lastWord === 'if' ||
|
|
1186
|
+
if (details.lastWord === 'if' ||
|
|
1187
|
+
details.lastWord === 'while' ||
|
|
1188
|
+
details.lastWord === 'for' ||
|
|
1189
|
+
details.lastWord === 'else') {
|
|
1292
1190
|
valid = false;
|
|
1293
1191
|
}
|
|
1294
1192
|
}
|
|
@@ -1308,49 +1206,50 @@ export function checkRegex(str) {
|
|
|
1308
1206
|
let done = false;
|
|
1309
1207
|
let cancel = false;
|
|
1310
1208
|
while (i < str.length && !done && !cancel) {
|
|
1311
|
-
done =
|
|
1209
|
+
done = str[i] === '/' && !escape;
|
|
1312
1210
|
escape = str[i] === '\\' && !escape;
|
|
1313
1211
|
cancel = str[i] === '\n';
|
|
1314
1212
|
i++;
|
|
1315
1213
|
}
|
|
1316
|
-
|
|
1317
|
-
cancel =
|
|
1214
|
+
const after = str.substring(i);
|
|
1215
|
+
cancel = cancel || !done || /^\s*\d/.test(after);
|
|
1318
1216
|
if (cancel)
|
|
1319
1217
|
return null;
|
|
1320
|
-
|
|
1321
|
-
if (/^\s+[\w
|
|
1218
|
+
const flags = /^[a-z]*/.exec(after);
|
|
1219
|
+
if (/^\s+[\w$]/.test(str.substring(i + flags[0].length))) {
|
|
1322
1220
|
return null;
|
|
1323
1221
|
}
|
|
1324
1222
|
return {
|
|
1325
1223
|
regex: str.substring(1, i - 1),
|
|
1326
|
-
flags: (flags && flags[0]) ||
|
|
1327
|
-
length: i + ((flags && flags[0].length) || 0)
|
|
1224
|
+
flags: (flags && flags[0]) || '',
|
|
1225
|
+
length: i + ((flags && flags[0].length) || 0),
|
|
1328
1226
|
};
|
|
1329
1227
|
}
|
|
1330
1228
|
const notDivide = /(typeof|delete|instanceof|return|in|of|throw|new|void|do|if)$/;
|
|
1331
|
-
const possibleDivide = /^([\w
|
|
1332
|
-
export function extractConstants(constants, str, currentEnclosure =
|
|
1229
|
+
const possibleDivide = /^([\w$\])]|\+\+|--)[\s/]/;
|
|
1230
|
+
export function extractConstants(constants, str, currentEnclosure = '') {
|
|
1333
1231
|
let quote;
|
|
1334
1232
|
let extract = [];
|
|
1335
1233
|
let escape = false;
|
|
1336
1234
|
let regexFound;
|
|
1337
|
-
let comment =
|
|
1235
|
+
let comment = '';
|
|
1338
1236
|
let commentStart = -1;
|
|
1339
1237
|
let currJs = [];
|
|
1340
|
-
let char =
|
|
1238
|
+
let char = '';
|
|
1341
1239
|
const strRes = [];
|
|
1342
1240
|
const enclosures = [];
|
|
1343
|
-
let isPossibleDivide;
|
|
1344
|
-
|
|
1241
|
+
let isPossibleDivide = null;
|
|
1242
|
+
let i = 0;
|
|
1243
|
+
for (i = 0; i < str.length; i++) {
|
|
1345
1244
|
char = str[i];
|
|
1346
1245
|
if (comment) {
|
|
1347
1246
|
if (char === comment) {
|
|
1348
|
-
if (comment ===
|
|
1349
|
-
comment =
|
|
1247
|
+
if (comment === '*' && str[i + 1] === '/') {
|
|
1248
|
+
comment = '';
|
|
1350
1249
|
i++;
|
|
1351
1250
|
}
|
|
1352
|
-
else if (comment ===
|
|
1353
|
-
comment =
|
|
1251
|
+
else if (comment === '\n') {
|
|
1252
|
+
comment = '';
|
|
1354
1253
|
}
|
|
1355
1254
|
}
|
|
1356
1255
|
}
|
|
@@ -1361,8 +1260,8 @@ export function extractConstants(constants, str, currentEnclosure = "") {
|
|
|
1361
1260
|
continue;
|
|
1362
1261
|
}
|
|
1363
1262
|
if (quote) {
|
|
1364
|
-
if (quote ===
|
|
1365
|
-
|
|
1263
|
+
if (quote === '`' && char === '$' && str[i + 1] === '{') {
|
|
1264
|
+
const skip = extractConstants(constants, str.substring(i + 2), '{');
|
|
1366
1265
|
currJs.push(skip.str);
|
|
1367
1266
|
extract.push('${', currJs.length - 1, `}`);
|
|
1368
1267
|
i += skip.length + 2;
|
|
@@ -1371,7 +1270,7 @@ export function extractConstants(constants, str, currentEnclosure = "") {
|
|
|
1371
1270
|
if (quote === '`') {
|
|
1372
1271
|
const li = createLisp({
|
|
1373
1272
|
op: 36 /* LispType.Literal */,
|
|
1374
|
-
a: unraw(extract.join(
|
|
1273
|
+
a: unraw(extract.join('')),
|
|
1375
1274
|
b: [],
|
|
1376
1275
|
});
|
|
1377
1276
|
li.tempJsStrings = currJs;
|
|
@@ -1379,7 +1278,7 @@ export function extractConstants(constants, str, currentEnclosure = "") {
|
|
|
1379
1278
|
strRes.push(`\``, constants.literals.length - 1, `\``);
|
|
1380
1279
|
}
|
|
1381
1280
|
else {
|
|
1382
|
-
constants.strings.push(unraw(extract.join(
|
|
1281
|
+
constants.strings.push(unraw(extract.join('')));
|
|
1383
1282
|
strRes.push(`"`, constants.strings.length - 1, `"`);
|
|
1384
1283
|
}
|
|
1385
1284
|
quote = null;
|
|
@@ -1390,12 +1289,12 @@ export function extractConstants(constants, str, currentEnclosure = "") {
|
|
|
1390
1289
|
}
|
|
1391
1290
|
}
|
|
1392
1291
|
else {
|
|
1393
|
-
if (
|
|
1292
|
+
if (char === "'" || char === '"' || char === '`') {
|
|
1394
1293
|
currJs = [];
|
|
1395
1294
|
quote = char;
|
|
1396
1295
|
}
|
|
1397
1296
|
else if (closings[currentEnclosure] === char && !enclosures.length) {
|
|
1398
|
-
return { str: strRes.join(
|
|
1297
|
+
return { str: strRes.join(''), length: i };
|
|
1399
1298
|
}
|
|
1400
1299
|
else if (closings[char]) {
|
|
1401
1300
|
enclosures.push(char);
|
|
@@ -1405,11 +1304,13 @@ export function extractConstants(constants, str, currentEnclosure = "") {
|
|
|
1405
1304
|
enclosures.pop();
|
|
1406
1305
|
strRes.push(char);
|
|
1407
1306
|
}
|
|
1408
|
-
else if (char ===
|
|
1409
|
-
comment = str[i + 1] ===
|
|
1307
|
+
else if (char === '/' && (str[i + 1] === '*' || str[i + 1] === '/')) {
|
|
1308
|
+
comment = str[i + 1] === '*' ? '*' : '\n';
|
|
1410
1309
|
commentStart = i;
|
|
1411
1310
|
}
|
|
1412
|
-
else if (char === '/' &&
|
|
1311
|
+
else if (char === '/' &&
|
|
1312
|
+
!isPossibleDivide &&
|
|
1313
|
+
(regexFound = checkRegex(str.substring(i)))) {
|
|
1413
1314
|
constants.regexes.push(regexFound);
|
|
1414
1315
|
strRes.push(`/`, constants.regexes.length - 1, `/r`);
|
|
1415
1316
|
i += regexFound.length - 1;
|
|
@@ -1418,30 +1319,30 @@ export function extractConstants(constants, str, currentEnclosure = "") {
|
|
|
1418
1319
|
strRes.push(char);
|
|
1419
1320
|
}
|
|
1420
1321
|
if (!isPossibleDivide || !space.test(char)) {
|
|
1421
|
-
if (isPossibleDivide = possibleDivide.exec(str.substring(i))) {
|
|
1322
|
+
if ((isPossibleDivide = possibleDivide.exec(str.substring(i)))) {
|
|
1422
1323
|
if (notDivide.test(str.substring(0, i + isPossibleDivide[1].length))) {
|
|
1423
1324
|
isPossibleDivide = null;
|
|
1424
1325
|
}
|
|
1425
1326
|
}
|
|
1426
1327
|
}
|
|
1427
1328
|
}
|
|
1428
|
-
escape = quote && char ===
|
|
1329
|
+
escape = !!(quote && char === '\\');
|
|
1429
1330
|
}
|
|
1430
1331
|
}
|
|
1431
1332
|
if (comment) {
|
|
1432
|
-
if (comment ===
|
|
1333
|
+
if (comment === '*') {
|
|
1433
1334
|
throw new SyntaxError(`Unclosed comment '/*': ${str.substring(commentStart)}`);
|
|
1434
1335
|
}
|
|
1435
1336
|
}
|
|
1436
|
-
return { str: strRes.join(
|
|
1337
|
+
return { str: strRes.join(''), length: i };
|
|
1437
1338
|
}
|
|
1438
|
-
export function parse(code, eager = false, expression = false) {
|
|
1339
|
+
export default function parse(code, eager = false, expression = false) {
|
|
1439
1340
|
if (typeof code !== 'string')
|
|
1440
1341
|
throw new ParseError(`Cannot parse ${code}`, code);
|
|
1441
1342
|
let str = ' ' + code;
|
|
1442
1343
|
const constants = { strings: [], literals: [], regexes: [], eager };
|
|
1443
1344
|
str = extractConstants(constants, str).str;
|
|
1444
|
-
for (
|
|
1345
|
+
for (const l of constants.literals) {
|
|
1445
1346
|
l[2] = l.tempJsStrings.map((js) => lispifyExpr(constants, new CodeString(js)));
|
|
1446
1347
|
delete l.tempJsStrings;
|
|
1447
1348
|
}
|