greybel-interpreter 4.5.13 → 4.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. package/dist/bytecode-generator/context.d.ts +22 -0
  2. package/dist/bytecode-generator/context.js +31 -0
  3. package/dist/bytecode-generator/expression.d.ts +24 -0
  4. package/dist/bytecode-generator/expression.js +640 -0
  5. package/dist/{byte-compiler → bytecode-generator}/instruction.d.ts +17 -19
  6. package/dist/{byte-compiler → bytecode-generator}/instruction.js +13 -12
  7. package/dist/bytecode-generator/line.d.ts +9 -0
  8. package/dist/bytecode-generator/line.js +2 -0
  9. package/dist/bytecode-generator/models.d.ts +42 -0
  10. package/dist/bytecode-generator/models.js +2 -0
  11. package/dist/bytecode-generator/module.d.ts +25 -0
  12. package/dist/bytecode-generator/module.js +72 -0
  13. package/dist/bytecode-generator/statement.d.ts +31 -0
  14. package/dist/bytecode-generator/statement.js +825 -0
  15. package/dist/bytecode-generator/utils.d.ts +5 -0
  16. package/dist/bytecode-generator/utils.js +30 -0
  17. package/dist/bytecode-generator.d.ts +3 -57
  18. package/dist/bytecode-generator.js +31 -1219
  19. package/dist/context.d.ts +5 -2
  20. package/dist/context.js +15 -13
  21. package/dist/index.d.ts +6 -2
  22. package/dist/index.js +10 -2
  23. package/dist/types/function.d.ts +1 -1
  24. package/dist/types/function.js +2 -2
  25. package/dist/types/map.js +10 -10
  26. package/dist/types/string.js +1 -1
  27. package/dist/utils/error.d.ts +1 -1
  28. package/dist/utils/hash.js +8 -14
  29. package/dist/utils/object-value.d.ts +1 -1
  30. package/dist/utils/object-value.js +9 -9
  31. package/dist/utils/stack.d.ts +1 -0
  32. package/dist/utils/stack.js +3 -0
  33. package/dist/utils/uuid.d.ts +2 -1
  34. package/dist/utils/uuid.js +5 -33
  35. package/dist/utils/value-hash.d.ts +2 -0
  36. package/dist/utils/value-hash.js +15 -0
  37. package/dist/vm/call.js +1 -1
  38. package/dist/vm.d.ts +1 -1
  39. package/dist/vm.js +36 -18
  40. package/package.json +4 -4
  41. /package/dist/{byte-compiler → bytecode-generator}/keywords.d.ts +0 -0
  42. /package/dist/{byte-compiler → bytecode-generator}/keywords.js +0 -0
@@ -0,0 +1,825 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.BytecodeStatementGenerator = void 0;
13
+ const greybel_core_1 = require("greybel-core");
14
+ const miniscript_core_1 = require("miniscript-core");
15
+ const default_1 = require("../types/default");
16
+ const number_1 = require("../types/number");
17
+ const string_1 = require("../types/string");
18
+ const error_1 = require("../utils/error");
19
+ const expression_1 = require("./expression");
20
+ const instruction_1 = require("./instruction");
21
+ const keywords_1 = require("./keywords");
22
+ const module_1 = require("./module");
23
+ const utils_1 = require("./utils");
24
+ class BytecodeStatementGenerator {
25
+ constructor(context, parseCodeFunction) {
26
+ this.context = context;
27
+ this.exprGenerator = new expression_1.BytecodeExpressionGenerator(this.context, parseCodeFunction, this);
28
+ this.parseCode = parseCodeFunction;
29
+ }
30
+ process(node) {
31
+ return __awaiter(this, void 0, void 0, function* () {
32
+ const mod = this.context.module.peek();
33
+ if (this.context.isDebugMode()) {
34
+ mod.pushCode({
35
+ op: instruction_1.OpCode.BREAKPOINT,
36
+ source: mod.getSourceLocation(node)
37
+ });
38
+ }
39
+ switch (node.type) {
40
+ case miniscript_core_1.ASTType.MemberExpression:
41
+ yield this.processMemberExpression(node);
42
+ return;
43
+ case miniscript_core_1.ASTType.IndexExpression:
44
+ yield this.processIndexExpression(node);
45
+ return;
46
+ case miniscript_core_1.ASTType.SliceExpression:
47
+ return;
48
+ case miniscript_core_1.ASTType.Identifier:
49
+ yield this.processIdentifier(node);
50
+ return;
51
+ case miniscript_core_1.ASTType.AssignmentStatement:
52
+ yield this.processAssignmentStatement(node);
53
+ return;
54
+ case miniscript_core_1.ASTType.Chunk: {
55
+ const chunk = node;
56
+ for (const item of chunk.body) {
57
+ yield this.process(item);
58
+ }
59
+ return;
60
+ }
61
+ case miniscript_core_1.ASTType.BooleanLiteral:
62
+ case miniscript_core_1.ASTType.StringLiteral:
63
+ case miniscript_core_1.ASTType.NumericLiteral:
64
+ case miniscript_core_1.ASTType.NilLiteral:
65
+ return;
66
+ case miniscript_core_1.ASTType.IsaExpression:
67
+ case miniscript_core_1.ASTType.BinaryExpression:
68
+ case miniscript_core_1.ASTType.LogicalExpression:
69
+ yield this.processEvaluationExpression(node);
70
+ return;
71
+ case miniscript_core_1.ASTType.ReturnStatement:
72
+ yield this.processReturn(node);
73
+ return;
74
+ case miniscript_core_1.ASTType.BreakStatement:
75
+ yield this.processBreak(node);
76
+ return;
77
+ case miniscript_core_1.ASTType.ContinueStatement:
78
+ yield this.processContinue(node);
79
+ return;
80
+ case miniscript_core_1.ASTType.MapConstructorExpression:
81
+ yield this.processMapConstructorExpression(node);
82
+ return;
83
+ case miniscript_core_1.ASTType.ListConstructorExpression:
84
+ yield this.processListConstructorExpression(node);
85
+ return;
86
+ case miniscript_core_1.ASTType.FunctionDeclaration:
87
+ return;
88
+ case miniscript_core_1.ASTType.WhileStatement:
89
+ yield this.processWhileStatement(node);
90
+ return;
91
+ case miniscript_core_1.ASTType.ParenthesisExpression:
92
+ yield this.process(node.expression);
93
+ return;
94
+ case miniscript_core_1.ASTType.BinaryNegatedExpression:
95
+ case miniscript_core_1.ASTType.UnaryExpression:
96
+ case miniscript_core_1.ASTType.NegationExpression:
97
+ yield this.processUnaryExpression(node);
98
+ return;
99
+ case miniscript_core_1.ASTType.CallStatement:
100
+ yield this.process(node.expression);
101
+ return;
102
+ case miniscript_core_1.ASTType.CallExpression:
103
+ yield this.processCallExpression(node);
104
+ return;
105
+ case miniscript_core_1.ASTType.IfStatement:
106
+ case miniscript_core_1.ASTType.IfShortcutStatement:
107
+ yield this.processIfStatement(node);
108
+ return;
109
+ case miniscript_core_1.ASTType.ForGenericStatement:
110
+ yield this.processForGenericStatement(node);
111
+ return;
112
+ case miniscript_core_1.ASTType.EmptyExpression:
113
+ case miniscript_core_1.ASTType.Comment:
114
+ return;
115
+ case greybel_core_1.ASTType.FeatureEnvarExpression:
116
+ return;
117
+ case greybel_core_1.ASTType.FeatureImportExpression:
118
+ yield this.processImportExpression(node);
119
+ return;
120
+ case greybel_core_1.ASTType.FeatureIncludeExpression:
121
+ yield this.processIncludeExpression(node);
122
+ return;
123
+ case greybel_core_1.ASTType.FeatureDebuggerExpression:
124
+ yield this.processDebuggerExpression(node);
125
+ return;
126
+ default: {
127
+ const range = new miniscript_core_1.ASTRange(node.start, node.end);
128
+ throw new error_1.PrepareError(`Unexpected AST type ${node.type}`, {
129
+ target: this.context.target.peek(),
130
+ range
131
+ });
132
+ }
133
+ }
134
+ });
135
+ }
136
+ processMemberExpression(node, context) {
137
+ return __awaiter(this, void 0, void 0, function* () {
138
+ const mod = this.context.module.peek();
139
+ const base = (0, utils_1.unwrap)(node.base);
140
+ if (base instanceof miniscript_core_1.ASTIdentifier && base.name === keywords_1.RuntimeKeyword.Super) {
141
+ mod.pushCode({
142
+ op: instruction_1.OpCode.PUSH,
143
+ source: mod.getSourceLocation(node.identifier),
144
+ value: new string_1.CustomString(node.identifier.name)
145
+ });
146
+ mod.pushCode({
147
+ op: instruction_1.OpCode.GET_SUPER_PROPERTY,
148
+ source: mod.getSourceLocation(node.identifier),
149
+ invoke: !(context === null || context === void 0 ? void 0 : context.isReference),
150
+ command: true
151
+ });
152
+ }
153
+ else {
154
+ yield this.exprGenerator.process(base);
155
+ yield this.processIdentifier(node.identifier, {
156
+ isDescending: true,
157
+ isReference: !!(context === null || context === void 0 ? void 0 : context.isReference)
158
+ });
159
+ }
160
+ });
161
+ }
162
+ processIndexExpression(node, context) {
163
+ return __awaiter(this, void 0, void 0, function* () {
164
+ const mod = this.context.module.peek();
165
+ const base = (0, utils_1.unwrap)(node.base);
166
+ if (base instanceof miniscript_core_1.ASTIdentifier && base.name === keywords_1.RuntimeKeyword.Super) {
167
+ yield this.exprGenerator.process(node.index);
168
+ mod.pushCode({
169
+ op: instruction_1.OpCode.GET_SUPER_PROPERTY,
170
+ source: mod.getSourceLocation(node.index, node.type),
171
+ invoke: !(context === null || context === void 0 ? void 0 : context.isReference),
172
+ command: true
173
+ });
174
+ }
175
+ else {
176
+ yield this.exprGenerator.process(base);
177
+ yield this.exprGenerator.process(node.index);
178
+ mod.pushCode({
179
+ op: instruction_1.OpCode.GET_PROPERTY,
180
+ source: mod.getSourceLocation(node.index, node.type),
181
+ invoke: !(context === null || context === void 0 ? void 0 : context.isReference),
182
+ command: true
183
+ });
184
+ }
185
+ });
186
+ }
187
+ processIdentifier(node, context) {
188
+ return __awaiter(this, void 0, void 0, function* () {
189
+ const mod = this.context.module.peek();
190
+ if (!(context === null || context === void 0 ? void 0 : context.isDescending)) {
191
+ switch (node.name) {
192
+ case keywords_1.RuntimeKeyword.Self:
193
+ case keywords_1.RuntimeKeyword.Super:
194
+ case keywords_1.RuntimeKeyword.Outer:
195
+ case keywords_1.RuntimeKeyword.Locals:
196
+ case keywords_1.RuntimeKeyword.Globals: {
197
+ return;
198
+ }
199
+ default: {
200
+ mod.pushCode({
201
+ op: instruction_1.OpCode.GET_VARIABLE,
202
+ source: mod.getSourceLocation(node),
203
+ property: new string_1.CustomString(node.name),
204
+ invoke: !(context === null || context === void 0 ? void 0 : context.isReference),
205
+ command: true
206
+ });
207
+ }
208
+ }
209
+ }
210
+ else {
211
+ mod.pushCode({
212
+ op: instruction_1.OpCode.PUSH,
213
+ source: mod.getSourceLocation(node),
214
+ value: new string_1.CustomString(node.name)
215
+ });
216
+ mod.pushCode({
217
+ op: instruction_1.OpCode.GET_PROPERTY,
218
+ source: mod.getSourceLocation(node),
219
+ invoke: !(context === null || context === void 0 ? void 0 : context.isReference),
220
+ command: true
221
+ });
222
+ }
223
+ });
224
+ }
225
+ processAssignmentStatement(node) {
226
+ return __awaiter(this, void 0, void 0, function* () {
227
+ const mod = this.context.module.peek();
228
+ let variable = (0, utils_1.unwrap)(node.variable);
229
+ if (variable instanceof miniscript_core_1.ASTUnaryExpression) {
230
+ variable = (0, utils_1.unwrap)(variable.argument);
231
+ }
232
+ if (variable instanceof miniscript_core_1.ASTMemberExpression) {
233
+ yield this.exprGenerator.process(variable.base);
234
+ mod.pushCode({
235
+ op: instruction_1.OpCode.PUSH,
236
+ source: mod.getSourceLocation(variable.identifier),
237
+ value: new string_1.CustomString(variable.identifier.name)
238
+ });
239
+ }
240
+ else if (variable instanceof miniscript_core_1.ASTIndexExpression) {
241
+ yield this.exprGenerator.process(variable.base);
242
+ yield this.exprGenerator.process(variable.index);
243
+ }
244
+ else if (variable instanceof miniscript_core_1.ASTIdentifier) {
245
+ mod.pushCode({
246
+ op: instruction_1.OpCode.GET_LOCALS,
247
+ source: mod.getSourceLocation(variable)
248
+ });
249
+ mod.pushCode({
250
+ op: instruction_1.OpCode.PUSH,
251
+ source: mod.getSourceLocation(variable),
252
+ value: new string_1.CustomString(variable.name)
253
+ });
254
+ }
255
+ else {
256
+ yield this.exprGenerator.process(variable);
257
+ mod.pushCode({
258
+ op: instruction_1.OpCode.PUSH,
259
+ source: mod.getSourceLocation(variable),
260
+ value: default_1.DefaultType.Void
261
+ });
262
+ }
263
+ yield this.exprGenerator.process(node.init, { includeOuter: true });
264
+ mod.pushCode({
265
+ op: instruction_1.OpCode.ASSIGN,
266
+ source: mod.getSourceLocation(node)
267
+ });
268
+ });
269
+ }
270
+ processEvaluationExpression(node) {
271
+ return __awaiter(this, void 0, void 0, function* () {
272
+ const mod = this.context.module.peek();
273
+ const skip = {
274
+ op: instruction_1.OpCode.NOOP,
275
+ source: mod.getSourceLocation(node)
276
+ };
277
+ yield this.exprGenerator.process(node.left);
278
+ if (node.operator === miniscript_core_1.Operator.And) {
279
+ mod.pushCode({
280
+ op: instruction_1.OpCode.GOTO_A_IF_FALSE,
281
+ source: mod.getSourceLocation(node),
282
+ goto: skip
283
+ });
284
+ }
285
+ else if (node.operator === miniscript_core_1.Operator.Or) {
286
+ mod.pushCode({
287
+ op: instruction_1.OpCode.GOTO_A_IF_TRUE,
288
+ source: mod.getSourceLocation(node),
289
+ goto: skip
290
+ });
291
+ }
292
+ yield this.process(node.right);
293
+ switch (node.operator) {
294
+ case miniscript_core_1.Operator.And:
295
+ case miniscript_core_1.Operator.Or: {
296
+ mod.pushCode(skip);
297
+ break;
298
+ }
299
+ case miniscript_core_1.Operator.Isa:
300
+ case miniscript_core_1.Operator.Equal:
301
+ case miniscript_core_1.Operator.NotEqual:
302
+ case miniscript_core_1.Operator.LessThan:
303
+ case miniscript_core_1.Operator.LessThanOrEqual:
304
+ case miniscript_core_1.Operator.GreaterThan:
305
+ case miniscript_core_1.Operator.GreaterThanOrEqual:
306
+ case miniscript_core_1.Operator.Plus:
307
+ case miniscript_core_1.Operator.Minus:
308
+ case miniscript_core_1.Operator.Asterik:
309
+ case miniscript_core_1.Operator.Slash:
310
+ case miniscript_core_1.Operator.Modulo:
311
+ case miniscript_core_1.Operator.Power:
312
+ case greybel_core_1.Operator.BitwiseAnd:
313
+ case greybel_core_1.Operator.BitwiseOr:
314
+ case greybel_core_1.Operator.LeftShift:
315
+ case greybel_core_1.Operator.RightShift:
316
+ case greybel_core_1.Operator.UnsignedRightShift: {
317
+ break;
318
+ }
319
+ default:
320
+ throw new Error(`Unexpected evaluation expression operator. ("${node.operator}")`);
321
+ }
322
+ });
323
+ }
324
+ processReturn(node) {
325
+ return __awaiter(this, void 0, void 0, function* () {
326
+ const mod = this.context.module.peek();
327
+ if (mod.isGlobalScope()) {
328
+ if (node.argument) {
329
+ yield this.process(node.argument);
330
+ }
331
+ return;
332
+ }
333
+ if (node.argument) {
334
+ yield this.exprGenerator.process(node.argument);
335
+ }
336
+ else {
337
+ mod.pushCode({
338
+ op: instruction_1.OpCode.PUSH,
339
+ source: mod.getSourceLocation(node),
340
+ value: default_1.DefaultType.Void
341
+ });
342
+ }
343
+ mod.pushCode({
344
+ op: instruction_1.OpCode.RETURN,
345
+ source: mod.getSourceLocation(node)
346
+ });
347
+ });
348
+ }
349
+ processBreak(node) {
350
+ return __awaiter(this, void 0, void 0, function* () {
351
+ const mod = this.context.module.peek();
352
+ const jumpPoint = mod.getJumpPoint();
353
+ if (jumpPoint === null)
354
+ return;
355
+ const end = jumpPoint[1];
356
+ mod.pushCode({
357
+ op: instruction_1.OpCode.GOTO_A,
358
+ source: mod.getSourceLocation(node),
359
+ goto: end
360
+ });
361
+ });
362
+ }
363
+ processContinue(node) {
364
+ return __awaiter(this, void 0, void 0, function* () {
365
+ const mod = this.context.module.peek();
366
+ const jumpPoint = mod.getJumpPoint();
367
+ if (jumpPoint === null)
368
+ return;
369
+ const start = jumpPoint[0];
370
+ mod.pushCode({
371
+ op: instruction_1.OpCode.GOTO_A,
372
+ source: mod.getSourceLocation(node),
373
+ goto: start
374
+ });
375
+ });
376
+ }
377
+ processMapConstructorExpression(node) {
378
+ return __awaiter(this, void 0, void 0, function* () {
379
+ const mod = this.context.module.peek();
380
+ for (const field of node.fields) {
381
+ yield this.exprGenerator.process(field.key);
382
+ yield this.exprGenerator.process(field.value);
383
+ }
384
+ mod.pushCode({
385
+ op: instruction_1.OpCode.CONSTRUCT_MAP,
386
+ source: mod.getSourceLocation(node),
387
+ length: node.fields.length,
388
+ command: true
389
+ });
390
+ });
391
+ }
392
+ processListConstructorExpression(node) {
393
+ return __awaiter(this, void 0, void 0, function* () {
394
+ const mod = this.context.module.peek();
395
+ for (const field of node.fields) {
396
+ yield this.exprGenerator.process(field.value);
397
+ }
398
+ mod.pushCode({
399
+ op: instruction_1.OpCode.CONSTRUCT_LIST,
400
+ source: mod.getSourceLocation(node),
401
+ length: node.fields.length,
402
+ command: true
403
+ });
404
+ });
405
+ }
406
+ processWhileStatement(node) {
407
+ return __awaiter(this, void 0, void 0, function* () {
408
+ const mod = this.context.module.peek();
409
+ const start = {
410
+ op: instruction_1.OpCode.NOOP,
411
+ source: mod.getSourceLocation(node.condition)
412
+ };
413
+ const end = {
414
+ op: instruction_1.OpCode.NOOP,
415
+ source: mod.getSourceLocation(node)
416
+ };
417
+ mod.pushCode(start);
418
+ yield this.exprGenerator.process(node.condition);
419
+ mod.pushCode({
420
+ op: instruction_1.OpCode.GOTO_A_IF_FALSE,
421
+ source: mod.getSourceLocation(node.condition),
422
+ goto: end
423
+ });
424
+ mod.pushJumppoint(start, end);
425
+ for (const item of node.body) {
426
+ yield this.process(item);
427
+ }
428
+ mod.popJumppoint();
429
+ mod.pushCode({
430
+ op: instruction_1.OpCode.GOTO_A,
431
+ source: mod.getSourceLocation(node.condition),
432
+ goto: start
433
+ });
434
+ mod.pushCode(end);
435
+ });
436
+ }
437
+ processUnaryExpression(node) {
438
+ return __awaiter(this, void 0, void 0, function* () {
439
+ const mod = this.context.module.peek();
440
+ const arg = (0, utils_1.unwrap)(node.argument);
441
+ switch (node.operator) {
442
+ case miniscript_core_1.Operator.Reference:
443
+ if (arg instanceof miniscript_core_1.ASTMemberExpression) {
444
+ yield this.processMemberExpression(arg, { isReference: true });
445
+ }
446
+ else if (arg instanceof miniscript_core_1.ASTIndexExpression) {
447
+ yield this.processIndexExpression(arg, { isReference: true });
448
+ }
449
+ else if (arg instanceof miniscript_core_1.ASTIdentifier) {
450
+ yield this.processIdentifier(arg, {
451
+ isDescending: false,
452
+ isReference: true
453
+ });
454
+ }
455
+ else {
456
+ yield this.process(arg);
457
+ }
458
+ return;
459
+ case miniscript_core_1.Operator.Not: {
460
+ yield this.exprGenerator.process(arg);
461
+ mod.pushCode({
462
+ op: instruction_1.OpCode.FALSIFY,
463
+ source: mod.getSourceLocation(node),
464
+ command: true
465
+ });
466
+ return;
467
+ }
468
+ case miniscript_core_1.Operator.Minus: {
469
+ yield this.exprGenerator.process(arg);
470
+ mod.pushCode({
471
+ op: instruction_1.OpCode.NEGATE,
472
+ source: mod.getSourceLocation(node),
473
+ command: true
474
+ });
475
+ return;
476
+ }
477
+ case miniscript_core_1.Operator.New: {
478
+ yield this.exprGenerator.process(arg);
479
+ mod.pushCode({
480
+ op: instruction_1.OpCode.NEW,
481
+ source: mod.getSourceLocation(node),
482
+ command: true
483
+ });
484
+ }
485
+ }
486
+ });
487
+ }
488
+ processCallExpression(node) {
489
+ return __awaiter(this, void 0, void 0, function* () {
490
+ const mod = this.context.module.peek();
491
+ const pushArgs = () => __awaiter(this, void 0, void 0, function* () {
492
+ for (const arg of node.arguments) {
493
+ yield this.exprGenerator.process(arg);
494
+ }
495
+ });
496
+ const left = (0, utils_1.unwrap)(node.base);
497
+ if (left instanceof miniscript_core_1.ASTMemberExpression) {
498
+ const base = (0, utils_1.unwrap)(left.base);
499
+ if (base instanceof miniscript_core_1.ASTIdentifier && base.name === keywords_1.RuntimeKeyword.Super) {
500
+ mod.pushCode({
501
+ op: instruction_1.OpCode.PUSH,
502
+ source: mod.getSourceLocation(left.identifier),
503
+ value: new string_1.CustomString(left.identifier.name)
504
+ });
505
+ yield pushArgs();
506
+ mod.pushCode({
507
+ op: instruction_1.OpCode.CALL_SUPER_PROPERTY,
508
+ source: mod.getSourceLocation(node.base, node.type),
509
+ length: node.arguments.length,
510
+ command: true
511
+ });
512
+ }
513
+ else {
514
+ yield this.exprGenerator.process(base);
515
+ mod.pushCode({
516
+ op: instruction_1.OpCode.PUSH,
517
+ source: mod.getSourceLocation(left.identifier),
518
+ value: new string_1.CustomString(left.identifier.name)
519
+ });
520
+ yield pushArgs();
521
+ mod.pushCode({
522
+ op: instruction_1.OpCode.CALL_WITH_CONTEXT,
523
+ source: mod.getSourceLocation(left.identifier, node.type),
524
+ length: node.arguments.length,
525
+ command: true
526
+ });
527
+ }
528
+ }
529
+ else if (left instanceof miniscript_core_1.ASTIndexExpression) {
530
+ const base = (0, utils_1.unwrap)(left.base);
531
+ if (base instanceof miniscript_core_1.ASTIdentifier && base.name === keywords_1.RuntimeKeyword.Super) {
532
+ yield this.exprGenerator.process(left.index);
533
+ yield pushArgs();
534
+ mod.pushCode({
535
+ op: instruction_1.OpCode.CALL_SUPER_PROPERTY,
536
+ source: mod.getSourceLocation(left.index, node.type),
537
+ length: node.arguments.length,
538
+ command: true
539
+ });
540
+ }
541
+ else {
542
+ yield this.exprGenerator.process(base);
543
+ yield this.exprGenerator.process(left.index);
544
+ yield pushArgs();
545
+ mod.pushCode({
546
+ op: instruction_1.OpCode.CALL_WITH_CONTEXT,
547
+ source: mod.getSourceLocation(left.index, node.type),
548
+ length: node.arguments.length,
549
+ command: true
550
+ });
551
+ }
552
+ }
553
+ else if (left instanceof miniscript_core_1.ASTIdentifier) {
554
+ yield this.exprGenerator.processIdentifier(left, {
555
+ isDescending: false,
556
+ isReference: true
557
+ });
558
+ yield pushArgs();
559
+ mod.pushCode({
560
+ op: instruction_1.OpCode.CALL,
561
+ source: mod.getSourceLocation(left, node.type),
562
+ length: node.arguments.length,
563
+ command: true
564
+ });
565
+ }
566
+ else {
567
+ yield this.exprGenerator.process(left);
568
+ yield pushArgs();
569
+ mod.pushCode({
570
+ op: instruction_1.OpCode.CALL,
571
+ source: mod.getSourceLocation(left, node.type),
572
+ length: node.arguments.length,
573
+ command: true
574
+ });
575
+ }
576
+ });
577
+ }
578
+ processIfStatement(node) {
579
+ return __awaiter(this, void 0, void 0, function* () {
580
+ const mod = this.context.module.peek();
581
+ const end = {
582
+ op: instruction_1.OpCode.NOOP,
583
+ source: mod.getSourceLocation(node)
584
+ };
585
+ for (const clause of node.clauses) {
586
+ if (clause instanceof miniscript_core_1.ASTIfClause) {
587
+ const next = {
588
+ op: instruction_1.OpCode.NOOP,
589
+ source: mod.getSourceLocation(clause)
590
+ };
591
+ yield this.exprGenerator.process(clause.condition);
592
+ mod.pushCode({
593
+ op: instruction_1.OpCode.GOTO_A_IF_FALSE,
594
+ source: mod.getSourceLocation(node),
595
+ goto: next
596
+ });
597
+ for (const item of clause.body) {
598
+ yield this.process(item);
599
+ }
600
+ mod.pushCode({
601
+ op: instruction_1.OpCode.GOTO_A,
602
+ source: mod.getSourceLocation(node),
603
+ goto: end
604
+ });
605
+ mod.pushCode(next);
606
+ }
607
+ else if (clause instanceof miniscript_core_1.ASTElseClause) {
608
+ for (const item of clause.body) {
609
+ yield this.process(item);
610
+ }
611
+ }
612
+ }
613
+ mod.pushCode(end);
614
+ });
615
+ }
616
+ processForGenericStatement(node) {
617
+ return __awaiter(this, void 0, void 0, function* () {
618
+ const mod = this.context.module.peek();
619
+ const variable = node.variable;
620
+ const idxVariable = new string_1.CustomString(`__${variable.name}_idx`);
621
+ const start = {
622
+ op: instruction_1.OpCode.NEXT,
623
+ source: mod.getSourceLocation(node.iterator),
624
+ idxVariable,
625
+ variable: new string_1.CustomString(variable.name)
626
+ };
627
+ const end = {
628
+ op: instruction_1.OpCode.POP_ITERATOR,
629
+ source: mod.getSourceLocation(node.iterator)
630
+ };
631
+ mod.pushJumppoint(start, end);
632
+ mod.pushCode({
633
+ op: instruction_1.OpCode.GET_LOCALS,
634
+ source: mod.getSourceLocation(node)
635
+ });
636
+ mod.pushCode({
637
+ op: instruction_1.OpCode.PUSH,
638
+ source: mod.getSourceLocation(node),
639
+ value: idxVariable
640
+ });
641
+ mod.pushCode({
642
+ op: instruction_1.OpCode.PUSH,
643
+ source: mod.getSourceLocation(node),
644
+ value: new number_1.CustomNumber(-1)
645
+ });
646
+ mod.pushCode({
647
+ op: instruction_1.OpCode.ASSIGN,
648
+ source: mod.getSourceLocation(node)
649
+ });
650
+ yield this.exprGenerator.process(node.iterator);
651
+ mod.pushCode({
652
+ op: instruction_1.OpCode.PUSH_ITERATOR,
653
+ source: mod.getSourceLocation(node.iterator)
654
+ });
655
+ mod.pushCode(start);
656
+ mod.pushCode({
657
+ op: instruction_1.OpCode.GOTO_A_IF_FALSE,
658
+ source: mod.getSourceLocation(node.iterator),
659
+ goto: end
660
+ });
661
+ for (const item of node.body) {
662
+ yield this.process(item);
663
+ }
664
+ mod.pushCode({
665
+ op: instruction_1.OpCode.GOTO_A,
666
+ source: mod.getSourceLocation(node.iterator),
667
+ goto: start
668
+ });
669
+ mod.pushCode(end);
670
+ mod.popJumppoint();
671
+ });
672
+ }
673
+ createImport(node, path, code) {
674
+ return __awaiter(this, void 0, void 0, function* () {
675
+ try {
676
+ const mod = new module_1.Module(path);
677
+ this.context.target.push(path);
678
+ this.context.module.push(mod);
679
+ const childNodes = this.parseCode(code);
680
+ mod.pushCode({
681
+ op: instruction_1.OpCode.GET_LOCALS,
682
+ source: mod.getInternalLocation()
683
+ });
684
+ mod.pushCode({
685
+ op: instruction_1.OpCode.PUSH,
686
+ source: mod.getInternalLocation(),
687
+ value: new string_1.CustomString('module')
688
+ });
689
+ mod.pushCode({
690
+ op: instruction_1.OpCode.PUSH,
691
+ source: mod.getInternalLocation(),
692
+ value: new string_1.CustomString('exports')
693
+ });
694
+ mod.pushCode({
695
+ op: instruction_1.OpCode.CONSTRUCT_MAP,
696
+ source: mod.getInternalLocation(),
697
+ length: 0
698
+ });
699
+ mod.pushCode({
700
+ op: instruction_1.OpCode.CONSTRUCT_MAP,
701
+ source: mod.getInternalLocation(),
702
+ length: 1
703
+ });
704
+ mod.pushCode({
705
+ op: instruction_1.OpCode.ASSIGN,
706
+ source: mod.getInternalLocation()
707
+ });
708
+ yield this.process(childNodes);
709
+ mod.pushCode({
710
+ op: instruction_1.OpCode.GET_VARIABLE,
711
+ source: mod.getInternalLocation(),
712
+ property: new string_1.CustomString('module')
713
+ });
714
+ mod.pushCode({
715
+ op: instruction_1.OpCode.PUSH,
716
+ source: mod.getInternalLocation(),
717
+ value: new string_1.CustomString('exports')
718
+ });
719
+ mod.pushCode({
720
+ op: instruction_1.OpCode.GET_PROPERTY,
721
+ source: mod.getInternalLocation()
722
+ });
723
+ this.context.module.pop();
724
+ this.context.target.pop();
725
+ this.context.imports.set(path, mod.getCode());
726
+ }
727
+ catch (err) {
728
+ if (err instanceof error_1.PrepareError) {
729
+ throw err;
730
+ }
731
+ throw new error_1.PrepareError(err.message, {
732
+ target: path,
733
+ range: new miniscript_core_1.ASTRange(node.start, node.end)
734
+ }, err);
735
+ }
736
+ });
737
+ }
738
+ processImportExpression(node) {
739
+ return __awaiter(this, void 0, void 0, function* () {
740
+ const mod = this.context.module.peek();
741
+ const currentTarget = this.context.target.peek();
742
+ const importTarget = yield this.context.handler.resourceHandler.getTargetRelativeTo(currentTarget, node.path);
743
+ if (this.context.target.includes(importTarget)) {
744
+ console.warn(`Found circular dependency between "${currentTarget}" and "${importTarget}" at line ${node.start.line}. Using noop instead to prevent overflow.`);
745
+ return;
746
+ }
747
+ if (!this.context.imports.has(importTarget)) {
748
+ const code = yield this.context.handler.resourceHandler.get(importTarget);
749
+ if (code == null) {
750
+ const range = new miniscript_core_1.ASTRange(node.start, node.end);
751
+ throw new error_1.PrepareError(`Cannot find import "${currentTarget}"`, {
752
+ target: currentTarget,
753
+ range
754
+ });
755
+ }
756
+ yield this.createImport(node, importTarget, code);
757
+ }
758
+ mod.pushCode({
759
+ op: instruction_1.OpCode.GET_LOCALS,
760
+ source: mod.getSourceLocation(node)
761
+ });
762
+ mod.pushCode({
763
+ op: instruction_1.OpCode.PUSH,
764
+ source: mod.getSourceLocation(node),
765
+ value: new string_1.CustomString(node.name.name)
766
+ });
767
+ mod.pushCode({
768
+ op: instruction_1.OpCode.IMPORT,
769
+ source: mod.getSourceLocation(node),
770
+ path: importTarget
771
+ });
772
+ mod.pushCode({
773
+ op: instruction_1.OpCode.ASSIGN,
774
+ source: mod.getSourceLocation(node)
775
+ });
776
+ });
777
+ }
778
+ processIncludeExpression(node) {
779
+ return __awaiter(this, void 0, void 0, function* () {
780
+ const currentTarget = this.context.target.peek();
781
+ const importTarget = yield this.context.handler.resourceHandler.getTargetRelativeTo(currentTarget, node.path);
782
+ if (this.context.target.includes(importTarget)) {
783
+ console.warn(`Found circular dependency between "${currentTarget}" and "${importTarget}" at line ${node.start.line}. Using noop instead to prevent overflow.`);
784
+ return;
785
+ }
786
+ const code = yield this.context.handler.resourceHandler.get(importTarget);
787
+ if (code == null) {
788
+ const range = new miniscript_core_1.ASTRange(node.start, node.end);
789
+ throw new error_1.PrepareError(`Cannot find import "${currentTarget}"`, {
790
+ target: currentTarget,
791
+ range
792
+ });
793
+ }
794
+ try {
795
+ this.context.target.push(importTarget);
796
+ const childNodes = this.parseCode(code);
797
+ yield this.process(childNodes);
798
+ this.context.target.pop();
799
+ }
800
+ catch (err) {
801
+ if (err instanceof error_1.PrepareError) {
802
+ throw err;
803
+ }
804
+ throw new error_1.PrepareError(err.message, {
805
+ target: importTarget,
806
+ range: new miniscript_core_1.ASTRange(node.start, node.end)
807
+ }, err);
808
+ }
809
+ });
810
+ }
811
+ processDebuggerExpression(node) {
812
+ return __awaiter(this, void 0, void 0, function* () {
813
+ const mod = this.context.module.peek();
814
+ mod.pushCode({
815
+ op: instruction_1.OpCode.BREAKPOINT_ENABLE,
816
+ source: mod.getSourceLocation(node)
817
+ });
818
+ mod.pushCode({
819
+ op: instruction_1.OpCode.BREAKPOINT,
820
+ source: mod.getSourceLocation(node)
821
+ });
822
+ });
823
+ }
824
+ }
825
+ exports.BytecodeStatementGenerator = BytecodeStatementGenerator;