@tezos-x/octez.js-michel-codec 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +174 -0
- package/dist/lib/base58.js +255 -0
- package/dist/lib/binary.js +1272 -0
- package/dist/lib/errors.js +90 -0
- package/dist/lib/formatters.js +60 -0
- package/dist/lib/global-constants.js +12 -0
- package/dist/lib/macros.js +548 -0
- package/dist/lib/micheline-emitter.js +132 -0
- package/dist/lib/micheline-parser.js +403 -0
- package/dist/lib/micheline.js +5 -0
- package/dist/lib/michelson-contract.js +93 -0
- package/dist/lib/michelson-typecheck.js +1752 -0
- package/dist/lib/michelson-types.js +83 -0
- package/dist/lib/michelson-validator.js +835 -0
- package/dist/lib/octez.js-michel-codec.js +38 -0
- package/dist/lib/scan.js +128 -0
- package/dist/lib/utils.js +321 -0
- package/dist/lib/version.js +8 -0
- package/dist/octez.js-michel-codec.es6.js +5790 -0
- package/dist/octez.js-michel-codec.es6.js.map +1 -0
- package/dist/octez.js-michel-codec.umd.js +5854 -0
- package/dist/octez.js-michel-codec.umd.js.map +1 -0
- package/dist/types/base58.d.ts +13 -0
- package/dist/types/binary.d.ts +127 -0
- package/dist/types/errors.d.ts +57 -0
- package/dist/types/formatters.d.ts +6 -0
- package/dist/types/global-constants.d.ts +3 -0
- package/dist/types/macros.d.ts +13 -0
- package/dist/types/micheline-emitter.d.ts +17 -0
- package/dist/types/micheline-parser.d.ts +130 -0
- package/dist/types/micheline.d.ts +44 -0
- package/dist/types/michelson-contract.d.ts +24 -0
- package/dist/types/michelson-typecheck.d.ts +38 -0
- package/dist/types/michelson-types.d.ts +147 -0
- package/dist/types/michelson-validator.d.ts +66 -0
- package/dist/types/octez.js-michel-codec.d.ts +16 -0
- package/dist/types/scan.d.ts +26 -0
- package/dist/types/utils.d.ts +77 -0
- package/dist/types/version.d.ts +4 -0
- package/package.json +94 -0
- package/signature.json +315 -0
|
@@ -0,0 +1,548 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.MacroError = void 0;
|
|
4
|
+
exports.expandMacros = expandMacros;
|
|
5
|
+
const octez_js_core_1 = require("@tezos-x/octez.js-core");
|
|
6
|
+
const michelson_types_1 = require("./michelson-types");
|
|
7
|
+
/**
|
|
8
|
+
* @category Error
|
|
9
|
+
* @description Error that indicates macros failed to be expanded
|
|
10
|
+
*/
|
|
11
|
+
class MacroError extends octez_js_core_1.TaquitoError {
|
|
12
|
+
constructor(prim, message) {
|
|
13
|
+
super();
|
|
14
|
+
this.prim = prim;
|
|
15
|
+
this.message = message;
|
|
16
|
+
this.name = 'MacroError';
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
exports.MacroError = MacroError;
|
|
20
|
+
function assertArgs(ex, n) {
|
|
21
|
+
var _a, _b;
|
|
22
|
+
if ((n === 0 && ex.args === undefined) || ((_a = ex.args) === null || _a === void 0 ? void 0 : _a.length) === n) {
|
|
23
|
+
return true;
|
|
24
|
+
}
|
|
25
|
+
throw new MacroError(ex, `macro ${ex.prim} expects ${n} arguments, was given ${(_b = ex.args) === null || _b === void 0 ? void 0 : _b.length}`);
|
|
26
|
+
}
|
|
27
|
+
function assertNoAnnots(ex) {
|
|
28
|
+
if (ex.annots === undefined) {
|
|
29
|
+
return true;
|
|
30
|
+
}
|
|
31
|
+
throw new MacroError(ex, `unexpected annotation on macro ${ex.prim}: ${ex.annots}`);
|
|
32
|
+
}
|
|
33
|
+
function assertIntArg(ex, arg) {
|
|
34
|
+
if ('int' in arg) {
|
|
35
|
+
return true;
|
|
36
|
+
}
|
|
37
|
+
throw new MacroError(ex, `macro ${ex.prim} expects int argument`);
|
|
38
|
+
}
|
|
39
|
+
function parsePairUnpairExpr(p, expr, annotations, agg) {
|
|
40
|
+
let i = 0;
|
|
41
|
+
let ai = 0;
|
|
42
|
+
const ann = [null, null];
|
|
43
|
+
// Left expression
|
|
44
|
+
let lexpr;
|
|
45
|
+
if (i === expr.length) {
|
|
46
|
+
throw new MacroError(p, `unexpected end: ${p.prim}`);
|
|
47
|
+
}
|
|
48
|
+
let c = expr[i++];
|
|
49
|
+
switch (c) {
|
|
50
|
+
case 'P': {
|
|
51
|
+
const { r, n, an } = parsePairUnpairExpr(p, expr.slice(i), annotations.slice(ai), agg);
|
|
52
|
+
lexpr = r;
|
|
53
|
+
i += n;
|
|
54
|
+
ai += an;
|
|
55
|
+
break;
|
|
56
|
+
}
|
|
57
|
+
case 'A':
|
|
58
|
+
if (ai !== annotations.length) {
|
|
59
|
+
ann[0] = annotations[ai++];
|
|
60
|
+
}
|
|
61
|
+
break;
|
|
62
|
+
default:
|
|
63
|
+
throw new MacroError(p, `${p.prim}: unexpected character: ${c}`);
|
|
64
|
+
}
|
|
65
|
+
// Right expression
|
|
66
|
+
let rexpr;
|
|
67
|
+
if (i === expr.length) {
|
|
68
|
+
throw new MacroError(p, `unexpected end: ${p.prim}`);
|
|
69
|
+
}
|
|
70
|
+
c = expr[i++];
|
|
71
|
+
switch (c) {
|
|
72
|
+
case 'P': {
|
|
73
|
+
const { r, n, an } = parsePairUnpairExpr(p, expr.slice(i), annotations.slice(ai), agg);
|
|
74
|
+
rexpr = r.map(([v, a]) => [v + 1, a]);
|
|
75
|
+
i += n;
|
|
76
|
+
ai += an;
|
|
77
|
+
break;
|
|
78
|
+
}
|
|
79
|
+
case 'I':
|
|
80
|
+
if (ai !== annotations.length) {
|
|
81
|
+
ann[1] = annotations[ai++];
|
|
82
|
+
}
|
|
83
|
+
break;
|
|
84
|
+
default:
|
|
85
|
+
throw new MacroError(p, `${p.prim}: unexpected character: ${c}`);
|
|
86
|
+
}
|
|
87
|
+
return { r: agg(lexpr, rexpr, [0, ann]), n: i, an: ai };
|
|
88
|
+
}
|
|
89
|
+
function parseSetMapCadr(p, expr, vann, term) {
|
|
90
|
+
const c = expr[0];
|
|
91
|
+
switch (c) {
|
|
92
|
+
case 'A':
|
|
93
|
+
return expr.length > 1
|
|
94
|
+
? [
|
|
95
|
+
{ prim: 'DUP' },
|
|
96
|
+
{
|
|
97
|
+
prim: 'DIP',
|
|
98
|
+
args: [
|
|
99
|
+
[{ prim: 'CAR', annots: ['@%%'] }, parseSetMapCadr(p, expr.slice(1), [], term)],
|
|
100
|
+
],
|
|
101
|
+
},
|
|
102
|
+
{ prim: 'CDR', annots: ['@%%'] },
|
|
103
|
+
{ prim: 'SWAP' },
|
|
104
|
+
{ prim: 'PAIR', annots: ['%@', '%@', ...vann] },
|
|
105
|
+
]
|
|
106
|
+
: term.a;
|
|
107
|
+
case 'D':
|
|
108
|
+
return expr.length > 1
|
|
109
|
+
? [
|
|
110
|
+
{ prim: 'DUP' },
|
|
111
|
+
{
|
|
112
|
+
prim: 'DIP',
|
|
113
|
+
args: [
|
|
114
|
+
[{ prim: 'CDR', annots: ['@%%'] }, parseSetMapCadr(p, expr.slice(1), [], term)],
|
|
115
|
+
],
|
|
116
|
+
},
|
|
117
|
+
{ prim: 'CAR', annots: ['@%%'] },
|
|
118
|
+
{ prim: 'PAIR', annots: ['%@', '%@', ...vann] },
|
|
119
|
+
]
|
|
120
|
+
: term.d;
|
|
121
|
+
default:
|
|
122
|
+
throw new MacroError(p, `${p.prim}: unexpected character: ${c}`);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
function trimLast(a, v) {
|
|
126
|
+
let l = a.length;
|
|
127
|
+
while (l > 0 && a[l - 1] === v) {
|
|
128
|
+
l--;
|
|
129
|
+
}
|
|
130
|
+
return a.slice(0, l);
|
|
131
|
+
}
|
|
132
|
+
function filterAnnotations(a) {
|
|
133
|
+
const fields = [];
|
|
134
|
+
const rest = [];
|
|
135
|
+
if (a !== undefined) {
|
|
136
|
+
for (const v of a) {
|
|
137
|
+
(v.length !== 0 && v[0] === '%' ? fields : rest).push(v);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
return { fields, rest };
|
|
141
|
+
}
|
|
142
|
+
function mkPrim({ prim, annots, args }) {
|
|
143
|
+
return Object.assign(Object.assign({ prim }, (annots && { annots })), (args && { args }));
|
|
144
|
+
}
|
|
145
|
+
const pairRe = /^P[PAI]{3,}R$/;
|
|
146
|
+
const unpairRe = /^UNP[PAI]{2,}R$/;
|
|
147
|
+
const cadrRe = /^C[AD]{2,}R$/;
|
|
148
|
+
const setCadrRe = /^SET_C[AD]+R$/;
|
|
149
|
+
const mapCadrRe = /^MAP_C[AD]+R$/;
|
|
150
|
+
const diipRe = /^DI{2,}P$/;
|
|
151
|
+
const duupRe = /^DU+P$/;
|
|
152
|
+
function expandMacros(ex, opt) {
|
|
153
|
+
const proto = (opt === null || opt === void 0 ? void 0 : opt.protocol) || michelson_types_1.DefaultProtocol;
|
|
154
|
+
function mayRename(annots) {
|
|
155
|
+
return annots !== undefined ? [{ prim: 'RENAME', annots }] : [];
|
|
156
|
+
}
|
|
157
|
+
switch (ex.prim) {
|
|
158
|
+
// Compare
|
|
159
|
+
case 'CMPEQ':
|
|
160
|
+
case 'CMPNEQ':
|
|
161
|
+
case 'CMPLT':
|
|
162
|
+
case 'CMPGT':
|
|
163
|
+
case 'CMPLE':
|
|
164
|
+
case 'CMPGE':
|
|
165
|
+
if (assertArgs(ex, 0)) {
|
|
166
|
+
return [{ prim: 'COMPARE' }, mkPrim({ prim: ex.prim.slice(3), annots: ex.annots })];
|
|
167
|
+
}
|
|
168
|
+
break;
|
|
169
|
+
case 'IFEQ':
|
|
170
|
+
case 'IFNEQ':
|
|
171
|
+
case 'IFLT':
|
|
172
|
+
case 'IFGT':
|
|
173
|
+
case 'IFLE':
|
|
174
|
+
case 'IFGE':
|
|
175
|
+
if (assertArgs(ex, 2)) {
|
|
176
|
+
return [
|
|
177
|
+
{ prim: ex.prim.slice(2) },
|
|
178
|
+
mkPrim({ prim: 'IF', annots: ex.annots, args: ex.args }),
|
|
179
|
+
];
|
|
180
|
+
}
|
|
181
|
+
break;
|
|
182
|
+
case 'IFCMPEQ':
|
|
183
|
+
case 'IFCMPNEQ':
|
|
184
|
+
case 'IFCMPLT':
|
|
185
|
+
case 'IFCMPGT':
|
|
186
|
+
case 'IFCMPLE':
|
|
187
|
+
case 'IFCMPGE':
|
|
188
|
+
if (assertArgs(ex, 2)) {
|
|
189
|
+
return [
|
|
190
|
+
{ prim: 'COMPARE' },
|
|
191
|
+
{ prim: ex.prim.slice(5) },
|
|
192
|
+
mkPrim({ prim: 'IF', annots: ex.annots, args: ex.args }),
|
|
193
|
+
];
|
|
194
|
+
}
|
|
195
|
+
break;
|
|
196
|
+
// Fail
|
|
197
|
+
case 'FAIL':
|
|
198
|
+
if (assertArgs(ex, 0) && assertNoAnnots(ex)) {
|
|
199
|
+
return [{ prim: 'UNIT' }, { prim: 'FAILWITH' }];
|
|
200
|
+
}
|
|
201
|
+
break;
|
|
202
|
+
// Assertion macros
|
|
203
|
+
case 'ASSERT':
|
|
204
|
+
if (assertArgs(ex, 0) && assertNoAnnots(ex)) {
|
|
205
|
+
return [
|
|
206
|
+
{
|
|
207
|
+
prim: 'IF',
|
|
208
|
+
args: [[], [[{ prim: 'UNIT' }, { prim: 'FAILWITH' }]]],
|
|
209
|
+
},
|
|
210
|
+
];
|
|
211
|
+
}
|
|
212
|
+
break;
|
|
213
|
+
case 'ASSERT_EQ':
|
|
214
|
+
case 'ASSERT_NEQ':
|
|
215
|
+
case 'ASSERT_LT':
|
|
216
|
+
case 'ASSERT_GT':
|
|
217
|
+
case 'ASSERT_LE':
|
|
218
|
+
case 'ASSERT_GE':
|
|
219
|
+
if (assertArgs(ex, 0) && assertNoAnnots(ex)) {
|
|
220
|
+
return [
|
|
221
|
+
{ prim: ex.prim.slice(7) },
|
|
222
|
+
{
|
|
223
|
+
prim: 'IF',
|
|
224
|
+
args: [[], [[{ prim: 'UNIT' }, { prim: 'FAILWITH' }]]],
|
|
225
|
+
},
|
|
226
|
+
];
|
|
227
|
+
}
|
|
228
|
+
break;
|
|
229
|
+
case 'ASSERT_CMPEQ':
|
|
230
|
+
case 'ASSERT_CMPNEQ':
|
|
231
|
+
case 'ASSERT_CMPLT':
|
|
232
|
+
case 'ASSERT_CMPGT':
|
|
233
|
+
case 'ASSERT_CMPLE':
|
|
234
|
+
case 'ASSERT_CMPGE':
|
|
235
|
+
if (assertArgs(ex, 0) && assertNoAnnots(ex)) {
|
|
236
|
+
return [
|
|
237
|
+
[{ prim: 'COMPARE' }, { prim: ex.prim.slice(10) }],
|
|
238
|
+
{
|
|
239
|
+
prim: 'IF',
|
|
240
|
+
args: [[], [[{ prim: 'UNIT' }, { prim: 'FAILWITH' }]]],
|
|
241
|
+
},
|
|
242
|
+
];
|
|
243
|
+
}
|
|
244
|
+
break;
|
|
245
|
+
case 'ASSERT_NONE':
|
|
246
|
+
if (assertArgs(ex, 0) && assertNoAnnots(ex)) {
|
|
247
|
+
return [
|
|
248
|
+
{
|
|
249
|
+
prim: 'IF_NONE',
|
|
250
|
+
args: [[], [[{ prim: 'UNIT' }, { prim: 'FAILWITH' }]]],
|
|
251
|
+
},
|
|
252
|
+
];
|
|
253
|
+
}
|
|
254
|
+
break;
|
|
255
|
+
case 'ASSERT_SOME':
|
|
256
|
+
if (assertArgs(ex, 0)) {
|
|
257
|
+
return [
|
|
258
|
+
{
|
|
259
|
+
prim: 'IF_NONE',
|
|
260
|
+
args: [[[{ prim: 'UNIT' }, { prim: 'FAILWITH' }]], mayRename(ex.annots)],
|
|
261
|
+
},
|
|
262
|
+
];
|
|
263
|
+
}
|
|
264
|
+
break;
|
|
265
|
+
case 'ASSERT_LEFT':
|
|
266
|
+
if (assertArgs(ex, 0)) {
|
|
267
|
+
return [
|
|
268
|
+
{
|
|
269
|
+
prim: 'IF_LEFT',
|
|
270
|
+
args: [mayRename(ex.annots), [[{ prim: 'UNIT' }, { prim: 'FAILWITH' }]]],
|
|
271
|
+
},
|
|
272
|
+
];
|
|
273
|
+
}
|
|
274
|
+
break;
|
|
275
|
+
case 'ASSERT_RIGHT':
|
|
276
|
+
if (assertArgs(ex, 0)) {
|
|
277
|
+
return [
|
|
278
|
+
{
|
|
279
|
+
prim: 'IF_LEFT',
|
|
280
|
+
args: [[[{ prim: 'UNIT' }, { prim: 'FAILWITH' }]], mayRename(ex.annots)],
|
|
281
|
+
},
|
|
282
|
+
];
|
|
283
|
+
}
|
|
284
|
+
break;
|
|
285
|
+
// Syntactic conveniences
|
|
286
|
+
case 'IF_SOME':
|
|
287
|
+
if (assertArgs(ex, 2)) {
|
|
288
|
+
return [mkPrim({ prim: 'IF_NONE', annots: ex.annots, args: [ex.args[1], ex.args[0]] })];
|
|
289
|
+
}
|
|
290
|
+
break;
|
|
291
|
+
case 'IF_RIGHT':
|
|
292
|
+
if (assertArgs(ex, 2)) {
|
|
293
|
+
return [mkPrim({ prim: 'IF_LEFT', annots: ex.annots, args: [ex.args[1], ex.args[0]] })];
|
|
294
|
+
}
|
|
295
|
+
break;
|
|
296
|
+
// CAR/CDR n
|
|
297
|
+
case 'CAR':
|
|
298
|
+
case 'CDR':
|
|
299
|
+
if (ex.args !== undefined) {
|
|
300
|
+
if (assertArgs(ex, 1) && assertIntArg(ex, ex.args[0])) {
|
|
301
|
+
const n = parseInt(ex.args[0].int, 10);
|
|
302
|
+
return mkPrim({
|
|
303
|
+
prim: 'GET',
|
|
304
|
+
args: [{ int: ex.prim === 'CAR' ? String(n * 2 + 1) : String(n * 2) }],
|
|
305
|
+
annots: ex.annots,
|
|
306
|
+
});
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
else {
|
|
310
|
+
return ex;
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
// More syntactic conveniences
|
|
314
|
+
// PAPPAIIR macro
|
|
315
|
+
if (pairRe.test(ex.prim)) {
|
|
316
|
+
if (assertArgs(ex, 0)) {
|
|
317
|
+
const { fields, rest } = filterAnnotations(ex.annots);
|
|
318
|
+
const { r } = parsePairUnpairExpr(ex, ex.prim.slice(1), fields, (l, r, top) => [
|
|
319
|
+
...(l || []),
|
|
320
|
+
...(r || []),
|
|
321
|
+
top,
|
|
322
|
+
]);
|
|
323
|
+
return r.map(([v, a], i) => {
|
|
324
|
+
const ann = [
|
|
325
|
+
...trimLast(a, null).map((v) => (v === null ? '%' : v)),
|
|
326
|
+
...(v === 0 && i === r.length - 1 ? rest : []),
|
|
327
|
+
];
|
|
328
|
+
const leaf = mkPrim({ prim: 'PAIR', annots: ann.length !== 0 ? ann : undefined });
|
|
329
|
+
return v === 0
|
|
330
|
+
? leaf
|
|
331
|
+
: {
|
|
332
|
+
prim: 'DIP',
|
|
333
|
+
args: v === 1 ? [[leaf]] : [{ int: String(v) }, [leaf]],
|
|
334
|
+
};
|
|
335
|
+
});
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
// UNPAPPAIIR macro
|
|
339
|
+
if (unpairRe.test(ex.prim)) {
|
|
340
|
+
if ((0, michelson_types_1.ProtoInferiorTo)(proto, michelson_types_1.Protocol.PtEdo2Zk) && assertArgs(ex, 0)) {
|
|
341
|
+
const { r } = parsePairUnpairExpr(ex, ex.prim.slice(3), ex.annots || [], (l, r, top) => [
|
|
342
|
+
top,
|
|
343
|
+
...(r || []),
|
|
344
|
+
...(l || []),
|
|
345
|
+
]);
|
|
346
|
+
return r.map(([v, a]) => {
|
|
347
|
+
const leaf = [
|
|
348
|
+
{ prim: 'DUP' },
|
|
349
|
+
mkPrim({ prim: 'CAR', annots: a[0] !== null ? [a[0]] : undefined }),
|
|
350
|
+
{
|
|
351
|
+
prim: 'DIP',
|
|
352
|
+
args: [[mkPrim({ prim: 'CDR', annots: a[1] !== null ? [a[1]] : undefined })]],
|
|
353
|
+
},
|
|
354
|
+
];
|
|
355
|
+
return v === 0
|
|
356
|
+
? leaf
|
|
357
|
+
: {
|
|
358
|
+
prim: 'DIP',
|
|
359
|
+
args: v === 1 ? [[leaf]] : [{ int: String(v) }, [leaf]],
|
|
360
|
+
};
|
|
361
|
+
});
|
|
362
|
+
}
|
|
363
|
+
else {
|
|
364
|
+
if (ex.prim === 'UNPAIR') {
|
|
365
|
+
return ex;
|
|
366
|
+
}
|
|
367
|
+
if (assertArgs(ex, 0)) {
|
|
368
|
+
// 008_edo: annotations are deprecated
|
|
369
|
+
const { r } = parsePairUnpairExpr(ex, ex.prim.slice(3), [], (l, r, top) => [
|
|
370
|
+
top,
|
|
371
|
+
...(r || []),
|
|
372
|
+
...(l || []),
|
|
373
|
+
]);
|
|
374
|
+
return r.map(([v]) => {
|
|
375
|
+
const leaf = mkPrim({
|
|
376
|
+
prim: 'UNPAIR',
|
|
377
|
+
});
|
|
378
|
+
return v === 0
|
|
379
|
+
? leaf
|
|
380
|
+
: {
|
|
381
|
+
prim: 'DIP',
|
|
382
|
+
args: v === 1 ? [[leaf]] : [{ int: String(v) }, [leaf]],
|
|
383
|
+
};
|
|
384
|
+
});
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
// C[AD]+R macro
|
|
389
|
+
if (cadrRe.test(ex.prim)) {
|
|
390
|
+
if (assertArgs(ex, 0)) {
|
|
391
|
+
const ch = [...ex.prim.slice(1, ex.prim.length - 1)];
|
|
392
|
+
return ch.map((c, i) => {
|
|
393
|
+
const ann = i === ch.length - 1 ? ex.annots : undefined;
|
|
394
|
+
switch (c) {
|
|
395
|
+
case 'A':
|
|
396
|
+
return mkPrim({ prim: 'CAR', annots: ann });
|
|
397
|
+
case 'D':
|
|
398
|
+
return mkPrim({ prim: 'CDR', annots: ann });
|
|
399
|
+
default:
|
|
400
|
+
throw new MacroError(ex, `unexpected character: ${c}`);
|
|
401
|
+
}
|
|
402
|
+
});
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
// SET_C[AD]+R macro
|
|
406
|
+
if (setCadrRe.test(ex.prim)) {
|
|
407
|
+
if (assertArgs(ex, 0)) {
|
|
408
|
+
const { fields, rest } = filterAnnotations(ex.annots);
|
|
409
|
+
if (fields.length > 1) {
|
|
410
|
+
throw new MacroError(ex, `unexpected annotation on macro ${ex.prim}: ${fields}`);
|
|
411
|
+
}
|
|
412
|
+
const term = fields.length !== 0
|
|
413
|
+
? {
|
|
414
|
+
a: [
|
|
415
|
+
{ prim: 'DUP' },
|
|
416
|
+
{ prim: 'CAR', annots: fields },
|
|
417
|
+
{ prim: 'DROP' },
|
|
418
|
+
{ prim: 'CDR', annots: ['@%%'] },
|
|
419
|
+
{ prim: 'SWAP' },
|
|
420
|
+
{ prim: 'PAIR', annots: [fields[0], '%@'] },
|
|
421
|
+
],
|
|
422
|
+
d: [
|
|
423
|
+
{ prim: 'DUP' },
|
|
424
|
+
{ prim: 'CDR', annots: fields },
|
|
425
|
+
{ prim: 'DROP' },
|
|
426
|
+
{ prim: 'CAR', annots: ['@%%'] },
|
|
427
|
+
{ prim: 'PAIR', annots: ['%@', fields[0]] },
|
|
428
|
+
],
|
|
429
|
+
}
|
|
430
|
+
: {
|
|
431
|
+
a: [
|
|
432
|
+
{ prim: 'CDR', annots: ['@%%'] },
|
|
433
|
+
{ prim: 'SWAP' },
|
|
434
|
+
{ prim: 'PAIR', annots: ['%', '%@'] },
|
|
435
|
+
],
|
|
436
|
+
d: [
|
|
437
|
+
{ prim: 'CAR', annots: ['@%%'] },
|
|
438
|
+
{ prim: 'PAIR', annots: ['%@', '%'] },
|
|
439
|
+
],
|
|
440
|
+
};
|
|
441
|
+
return parseSetMapCadr(ex, ex.prim.slice(5, ex.prim.length - 1), rest, term);
|
|
442
|
+
}
|
|
443
|
+
}
|
|
444
|
+
// MAP_C[AD]+R macro
|
|
445
|
+
if (mapCadrRe.test(ex.prim)) {
|
|
446
|
+
if (assertArgs(ex, 1)) {
|
|
447
|
+
const { fields } = filterAnnotations(ex.annots);
|
|
448
|
+
if (fields.length > 1) {
|
|
449
|
+
throw new MacroError(ex, `unexpected annotation on macro ${ex.prim}: ${fields}`);
|
|
450
|
+
}
|
|
451
|
+
const term = {
|
|
452
|
+
a: [
|
|
453
|
+
{ prim: 'DUP' },
|
|
454
|
+
{ prim: 'CDR', annots: ['@%%'] },
|
|
455
|
+
{
|
|
456
|
+
prim: 'DIP',
|
|
457
|
+
args: [
|
|
458
|
+
[
|
|
459
|
+
mkPrim({
|
|
460
|
+
prim: 'CAR',
|
|
461
|
+
annots: fields.length !== 0 ? ['@' + fields[0].slice(1)] : undefined,
|
|
462
|
+
}),
|
|
463
|
+
ex.args[0],
|
|
464
|
+
],
|
|
465
|
+
],
|
|
466
|
+
},
|
|
467
|
+
{ prim: 'SWAP' },
|
|
468
|
+
{ prim: 'PAIR', annots: [fields.length !== 0 ? fields[0] : '%', '%@'] },
|
|
469
|
+
],
|
|
470
|
+
d: [
|
|
471
|
+
{ prim: 'DUP' },
|
|
472
|
+
mkPrim({
|
|
473
|
+
prim: 'CDR',
|
|
474
|
+
annots: fields.length !== 0 ? ['@' + fields[0].slice(1)] : undefined,
|
|
475
|
+
}),
|
|
476
|
+
ex.args[0],
|
|
477
|
+
{ prim: 'SWAP' },
|
|
478
|
+
{ prim: 'CAR', annots: ['@%%'] },
|
|
479
|
+
{ prim: 'PAIR', annots: ['%@', fields.length !== 0 ? fields[0] : '%'] },
|
|
480
|
+
],
|
|
481
|
+
};
|
|
482
|
+
return parseSetMapCadr(ex, ex.prim.slice(5, ex.prim.length - 1), [], term);
|
|
483
|
+
}
|
|
484
|
+
}
|
|
485
|
+
// Expand deprecated DI...IP to [DIP n]
|
|
486
|
+
if (diipRe.test(ex.prim)) {
|
|
487
|
+
if (assertArgs(ex, 1)) {
|
|
488
|
+
let n = 0;
|
|
489
|
+
while (ex.prim[1 + n] === 'I') {
|
|
490
|
+
n++;
|
|
491
|
+
}
|
|
492
|
+
return mkPrim({ prim: 'DIP', args: [{ int: String(n) }, ex.args[0]] });
|
|
493
|
+
}
|
|
494
|
+
}
|
|
495
|
+
// Expand DU...UP and DUP n
|
|
496
|
+
if (duupRe.test(ex.prim)) {
|
|
497
|
+
let n = 0;
|
|
498
|
+
while (ex.prim[1 + n] === 'U') {
|
|
499
|
+
n++;
|
|
500
|
+
}
|
|
501
|
+
if ((0, michelson_types_1.ProtoInferiorTo)(proto, michelson_types_1.Protocol.PtEdo2Zk)) {
|
|
502
|
+
if (n === 1) {
|
|
503
|
+
if (ex.args === undefined) {
|
|
504
|
+
return ex; // skip
|
|
505
|
+
}
|
|
506
|
+
if (assertArgs(ex, 1) && assertIntArg(ex, ex.args[0])) {
|
|
507
|
+
n = parseInt(ex.args[0].int, 10);
|
|
508
|
+
}
|
|
509
|
+
}
|
|
510
|
+
else {
|
|
511
|
+
assertArgs(ex, 0);
|
|
512
|
+
}
|
|
513
|
+
if (n === 1) {
|
|
514
|
+
return [mkPrim({ prim: 'DUP', annots: ex.annots })];
|
|
515
|
+
}
|
|
516
|
+
else if (n === 2) {
|
|
517
|
+
return [
|
|
518
|
+
{
|
|
519
|
+
prim: 'DIP',
|
|
520
|
+
args: [[mkPrim({ prim: 'DUP', annots: ex.annots })]],
|
|
521
|
+
},
|
|
522
|
+
{ prim: 'SWAP' },
|
|
523
|
+
];
|
|
524
|
+
}
|
|
525
|
+
else {
|
|
526
|
+
return [
|
|
527
|
+
{
|
|
528
|
+
prim: 'DIP',
|
|
529
|
+
args: [{ int: String(n - 1) }, [mkPrim({ prim: 'DUP', annots: ex.annots })]],
|
|
530
|
+
},
|
|
531
|
+
{
|
|
532
|
+
prim: 'DIG',
|
|
533
|
+
args: [{ int: String(n) }],
|
|
534
|
+
},
|
|
535
|
+
];
|
|
536
|
+
}
|
|
537
|
+
}
|
|
538
|
+
else {
|
|
539
|
+
if (n === 1) {
|
|
540
|
+
return ex;
|
|
541
|
+
}
|
|
542
|
+
if (assertArgs(ex, 0)) {
|
|
543
|
+
return mkPrim({ prim: 'DUP', args: [{ int: String(n) }], annots: ex.annots });
|
|
544
|
+
}
|
|
545
|
+
}
|
|
546
|
+
}
|
|
547
|
+
return ex;
|
|
548
|
+
}
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.emitMicheline = emitMicheline;
|
|
4
|
+
const micheline_1 = require("./micheline");
|
|
5
|
+
class Formatter {
|
|
6
|
+
constructor(opt, lev = 0) {
|
|
7
|
+
this.opt = opt;
|
|
8
|
+
this.lev = lev;
|
|
9
|
+
}
|
|
10
|
+
indent(n = 0) {
|
|
11
|
+
var _a;
|
|
12
|
+
let ret = '';
|
|
13
|
+
if (((_a = this.opt) === null || _a === void 0 ? void 0 : _a.indent) !== undefined) {
|
|
14
|
+
for (let i = this.lev + n; i > 0; i--) {
|
|
15
|
+
ret += this.opt.indent;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
return ret;
|
|
19
|
+
}
|
|
20
|
+
get lf() {
|
|
21
|
+
var _a;
|
|
22
|
+
return ((_a = this.opt) === null || _a === void 0 ? void 0 : _a.newline) || '';
|
|
23
|
+
}
|
|
24
|
+
get lfsp() {
|
|
25
|
+
var _a;
|
|
26
|
+
return ((_a = this.opt) === null || _a === void 0 ? void 0 : _a.newline) || ' ';
|
|
27
|
+
}
|
|
28
|
+
down(n) {
|
|
29
|
+
return new Formatter(this.opt, this.lev + n);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
function hasArgs(node) {
|
|
33
|
+
return ('prim' in node &&
|
|
34
|
+
((node.annots !== undefined && node.annots.length !== 0) ||
|
|
35
|
+
(node.args !== undefined && node.args.length !== 0)));
|
|
36
|
+
}
|
|
37
|
+
function isMultiline(node) {
|
|
38
|
+
if (node.args !== undefined) {
|
|
39
|
+
for (const a of node.args) {
|
|
40
|
+
if (Array.isArray(a) || hasArgs(a)) {
|
|
41
|
+
return true;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
return false;
|
|
46
|
+
}
|
|
47
|
+
function emitExpr(node, f, foldMacros) {
|
|
48
|
+
var _a;
|
|
49
|
+
const macro = (_a = node[micheline_1.sourceReference]) === null || _a === void 0 ? void 0 : _a.macro;
|
|
50
|
+
if (foldMacros && macro) {
|
|
51
|
+
return emitExpr(macro, f, foldMacros);
|
|
52
|
+
}
|
|
53
|
+
if (Array.isArray(node)) {
|
|
54
|
+
return emitSeq(node, f, foldMacros);
|
|
55
|
+
}
|
|
56
|
+
else if ('string' in node) {
|
|
57
|
+
return JSON.stringify(node.string);
|
|
58
|
+
}
|
|
59
|
+
else if ('int' in node) {
|
|
60
|
+
return node.int;
|
|
61
|
+
}
|
|
62
|
+
else if ('bytes' in node) {
|
|
63
|
+
return '0x' + node.bytes;
|
|
64
|
+
}
|
|
65
|
+
else {
|
|
66
|
+
if ((node.annots === undefined || node.annots.length === 0) &&
|
|
67
|
+
(node.args === undefined || node.args.length === 0)) {
|
|
68
|
+
return node.prim;
|
|
69
|
+
}
|
|
70
|
+
let ret = '(' + node.prim;
|
|
71
|
+
if (node.annots !== undefined) {
|
|
72
|
+
for (const a of node.annots) {
|
|
73
|
+
ret += ' ' + a;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
if (node.args !== undefined) {
|
|
77
|
+
const multiline = isMultiline(node);
|
|
78
|
+
for (const a of node.args) {
|
|
79
|
+
if (multiline) {
|
|
80
|
+
ret += f.lfsp + f.indent(1) + emitExpr(a, f.down(1), foldMacros);
|
|
81
|
+
}
|
|
82
|
+
else {
|
|
83
|
+
ret += ' ' + emitExpr(a, f, foldMacros);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
return ret + ')';
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
function emitSeq(node, f, foldMacros) {
|
|
91
|
+
let ret = '{' + f.lf;
|
|
92
|
+
let i = node.length;
|
|
93
|
+
for (const el of node) {
|
|
94
|
+
ret += f.indent(1);
|
|
95
|
+
if ('prim' in el) {
|
|
96
|
+
ret += el.prim;
|
|
97
|
+
if (el.annots !== undefined) {
|
|
98
|
+
for (const a of el.annots) {
|
|
99
|
+
ret += ' ' + a;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
if (el.args !== undefined) {
|
|
103
|
+
const multiline = isMultiline(el);
|
|
104
|
+
for (const a of el.args) {
|
|
105
|
+
if (multiline) {
|
|
106
|
+
ret += f.lfsp + f.indent(2) + emitExpr(a, f.down(2), foldMacros);
|
|
107
|
+
}
|
|
108
|
+
else {
|
|
109
|
+
ret += ' ' + emitExpr(a, f, foldMacros);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
else {
|
|
115
|
+
ret += emitExpr(el, f.down(1), foldMacros);
|
|
116
|
+
}
|
|
117
|
+
ret += i > 1 ? ';' + f.lfsp : f.lf;
|
|
118
|
+
i--;
|
|
119
|
+
}
|
|
120
|
+
return ret + f.indent() + '}';
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Formats Micheline expression
|
|
124
|
+
* @param expr An AST node
|
|
125
|
+
* @param opt Options
|
|
126
|
+
*/
|
|
127
|
+
function emitMicheline(expr, opt, foldMacros = false) {
|
|
128
|
+
if (typeof expr !== 'object') {
|
|
129
|
+
throw new TypeError(`object type was expected, got ${typeof expr} instead`);
|
|
130
|
+
}
|
|
131
|
+
return emitExpr(expr, new Formatter(opt), foldMacros);
|
|
132
|
+
}
|