@harmoniclabs/pebble 0.1.0-dev7 → 0.1.0-dev8
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/dist/IR/IRNodes/IRConst.js +1 -1
- package/dist/IR/IRNodes/IRNative/IRNativeTag.d.ts +4 -3
- package/dist/IR/IRNodes/IRNative/IRNativeTag.js +8 -4
- package/dist/IR/IRNodes/IRNative/index.d.ts +4 -2
- package/dist/IR/IRNodes/IRNative/index.js +5 -2
- package/dist/IR/toUPLC/CompilerOptions.d.ts +1 -1
- package/dist/IR/toUPLC/CompilerOptions.js +2 -1
- package/dist/IR/toUPLC/compileIRToUPLC.js +33 -34
- package/dist/IR/toUPLC/subRoutines/handleLetted/index.js +69 -3
- package/dist/IR/toUPLC/subRoutines/replaceNatives/nativeToIR.d.ts +1 -1
- package/dist/IR/toUPLC/subRoutines/replaceNatives/nativeToIR.js +19 -9
- package/dist/IR/toUPLC/subRoutines/rewriteNativesAppliedToConstantsAndReturnRoot.js +292 -17
- package/dist/IR/utils/positiveIntAsBytes.js +1 -1
- package/dist/compiler/AstCompiler/AstCompiler.d.ts +2 -0
- package/dist/compiler/AstCompiler/AstCompiler.js +27 -1
- package/dist/compiler/AstCompiler/internal/exprs/_compileFuncExpr.js +6 -0
- package/dist/compiler/Compiler.d.ts +8 -1
- package/dist/compiler/Compiler.js +34 -1
- package/dist/compiler/TirCompiler/expressify/ExpressifyCtx.js +1 -1
- package/dist/compiler/TirCompiler/expressify/expressify.js +2 -0
- package/dist/compiler/TirCompiler/expressify/expressifyVars.js +36 -12
- package/dist/compiler/tir/expressions/TirNativeFunc.d.ts +2 -2
- package/dist/compiler/tir/expressions/TirNativeFunc.js +27 -14
- package/dist/utils/BitUtils/index.d.ts +1 -1
- package/dist/utils/BitUtils/index.js +1 -1
- package/dist/utils/IsSingleKey.d.ts +1 -1
- package/dist/utils/UPLCFlatUtils/index.d.ts +1 -1
- package/dist/utils/UPLCFlatUtils/index.js +2 -2
- package/package.json +6 -6
|
@@ -2,7 +2,6 @@ import { Pair } from "@harmoniclabs/pair";
|
|
|
2
2
|
import { isData, dataToCbor } from "@harmoniclabs/plutus-data";
|
|
3
3
|
import { fromUtf8, toHex } from "@harmoniclabs/uint8array-utils";
|
|
4
4
|
import { BasePlutsError } from "../../utils/BasePlutsError.js";
|
|
5
|
-
import UPLCFlatUtils from "../../utils/UPLCFlatUtils/index.js";
|
|
6
5
|
import { concatUint8Arr } from "../utils/concatUint8Arr.js";
|
|
7
6
|
import { positiveBigIntAsBytes } from "../utils/positiveIntAsBytes.js";
|
|
8
7
|
import { isIRParentTerm } from "../utils/isIRParentTerm.js";
|
|
@@ -27,6 +26,7 @@ import { TirStringT } from "../../compiler/tir/types/TirNativeType/native/string
|
|
|
27
26
|
import { TirVoidT } from "../../compiler/tir/types/TirNativeType/native/void.js";
|
|
28
27
|
import { hashIrData, isIRHash } from "../IRHash.js";
|
|
29
28
|
import { ByteString } from "@harmoniclabs/bytestring";
|
|
29
|
+
import { UPLCFlatUtils } from "../../utils/UPLCFlatUtils/index.js";
|
|
30
30
|
export function isIRConstPair(value) {
|
|
31
31
|
return (value instanceof Pair &&
|
|
32
32
|
isIRConstValue(value.fst) &&
|
|
@@ -96,11 +96,10 @@ export declare enum IRNativeTag {
|
|
|
96
96
|
_dropList = -4,
|
|
97
97
|
_foldr = -6,
|
|
98
98
|
_foldl = -7,
|
|
99
|
-
_mkFindDataOptional = -8,
|
|
100
99
|
_length = -9,
|
|
101
100
|
_some = -10,
|
|
102
101
|
_every = -11,
|
|
103
|
-
|
|
102
|
+
_filter = -12,
|
|
104
103
|
_id = -15,
|
|
105
104
|
_not = -16,
|
|
106
105
|
_strictAnd = -17,
|
|
@@ -133,6 +132,8 @@ export declare enum IRNativeTag {
|
|
|
133
132
|
_isZero = -42,
|
|
134
133
|
_sortedValueLovelaces = -43,
|
|
135
134
|
_getCredentialsHash = -44,
|
|
136
|
-
_findSopOptional = -45
|
|
135
|
+
_findSopOptional = -45,
|
|
136
|
+
_increment = -46,
|
|
137
|
+
_decrement = -47
|
|
137
138
|
}
|
|
138
139
|
export declare function nativeTagToString(nativeTag: IRNativeTag): string;
|
|
@@ -116,11 +116,11 @@ export var IRNativeTag;
|
|
|
116
116
|
IRNativeTag[IRNativeTag["_dropList"] = -4] = "_dropList";
|
|
117
117
|
IRNativeTag[IRNativeTag["_foldr"] = -6] = "_foldr";
|
|
118
118
|
IRNativeTag[IRNativeTag["_foldl"] = -7] = "_foldl";
|
|
119
|
-
|
|
119
|
+
// _mkFindDataOptional = -8,
|
|
120
120
|
IRNativeTag[IRNativeTag["_length"] = -9] = "_length";
|
|
121
121
|
IRNativeTag[IRNativeTag["_some"] = -10] = "_some";
|
|
122
122
|
IRNativeTag[IRNativeTag["_every"] = -11] = "_every";
|
|
123
|
-
IRNativeTag[IRNativeTag["
|
|
123
|
+
IRNativeTag[IRNativeTag["_filter"] = -12] = "_filter";
|
|
124
124
|
// _fstPair = -13,
|
|
125
125
|
// _sndPair = -14,
|
|
126
126
|
IRNativeTag[IRNativeTag["_id"] = -15] = "_id";
|
|
@@ -156,6 +156,8 @@ export var IRNativeTag;
|
|
|
156
156
|
IRNativeTag[IRNativeTag["_sortedValueLovelaces"] = -43] = "_sortedValueLovelaces";
|
|
157
157
|
IRNativeTag[IRNativeTag["_getCredentialsHash"] = -44] = "_getCredentialsHash";
|
|
158
158
|
IRNativeTag[IRNativeTag["_findSopOptional"] = -45] = "_findSopOptional";
|
|
159
|
+
IRNativeTag[IRNativeTag["_increment"] = -46] = "_increment";
|
|
160
|
+
IRNativeTag[IRNativeTag["_decrement"] = -47] = "_decrement";
|
|
159
161
|
})(IRNativeTag || (IRNativeTag = {}));
|
|
160
162
|
Object.freeze(IRNativeTag);
|
|
161
163
|
export function nativeTagToString(nativeTag) {
|
|
@@ -165,12 +167,12 @@ export function nativeTagToString(nativeTag) {
|
|
|
165
167
|
case IRNativeTag._dropList: return "dropList";
|
|
166
168
|
case IRNativeTag._foldr: return "foldr";
|
|
167
169
|
case IRNativeTag._foldl: return "foldl";
|
|
168
|
-
case IRNativeTag._mkFindDataOptional: return "mkFind";
|
|
170
|
+
// case IRNativeTag._mkFindDataOptional : return "mkFind";
|
|
169
171
|
case IRNativeTag._findSopOptional: return "findSopOptional";
|
|
170
172
|
case IRNativeTag._length: return "length";
|
|
171
173
|
case IRNativeTag._some: return "some";
|
|
172
174
|
case IRNativeTag._every: return "every";
|
|
173
|
-
case IRNativeTag.
|
|
175
|
+
case IRNativeTag._filter: return "mkFilter";
|
|
174
176
|
// case IRNativeTag._fstPair : return "fstPair";
|
|
175
177
|
// case IRNativeTag._sndPair : return "sndPair";
|
|
176
178
|
case IRNativeTag._id: return "id";
|
|
@@ -199,6 +201,8 @@ export function nativeTagToString(nativeTag) {
|
|
|
199
201
|
case IRNativeTag._isZero: return "isZero";
|
|
200
202
|
case IRNativeTag._sortedValueLovelaces: return "sortedValueLovelaces";
|
|
201
203
|
case IRNativeTag._getCredentialsHash: return "getCredentialHash";
|
|
204
|
+
case IRNativeTag._increment: return "increment";
|
|
205
|
+
case IRNativeTag._decrement: return "decrement";
|
|
202
206
|
default: return "";
|
|
203
207
|
}
|
|
204
208
|
}
|
|
@@ -131,11 +131,10 @@ export declare class IRNative implements IIRTerm, Cloneable<IRNative>, IIRParent
|
|
|
131
131
|
static get _dropList(): IRNative;
|
|
132
132
|
static get _foldr(): IRNative;
|
|
133
133
|
static get _foldl(): IRNative;
|
|
134
|
-
static get _mkFindDataOptional(): IRNative;
|
|
135
134
|
static get _length(): IRNative;
|
|
136
135
|
static get _some(): IRNative;
|
|
137
136
|
static get _every(): IRNative;
|
|
138
|
-
static get
|
|
137
|
+
static get _filter(): IRNative;
|
|
139
138
|
static get _id(): IRNative;
|
|
140
139
|
static get _not(): IRNative;
|
|
141
140
|
static get _strictAnd(): IRNative;
|
|
@@ -162,6 +161,9 @@ export declare class IRNative implements IIRTerm, Cloneable<IRNative>, IIRParent
|
|
|
162
161
|
static get _amountOfValue(): IRNative;
|
|
163
162
|
static get _sortedValueLovelaces(): IRNative;
|
|
164
163
|
static get _getCredentialsHash(): IRNative;
|
|
164
|
+
static get _increment(): IRNative;
|
|
165
|
+
static get _decrement(): IRNative;
|
|
166
|
+
static get _isZero(): IRNative;
|
|
165
167
|
static equals(type: TirType): IRTerm;
|
|
166
168
|
static equalListOf(type: TirType): IRHoisted;
|
|
167
169
|
}
|
|
@@ -184,11 +184,11 @@ export class IRNative {
|
|
|
184
184
|
static get _dropList() { return new IRNative(IRNativeTag._dropList); }
|
|
185
185
|
static get _foldr() { return new IRNative(IRNativeTag._foldr); }
|
|
186
186
|
static get _foldl() { return new IRNative(IRNativeTag._foldl); }
|
|
187
|
-
static get _mkFindDataOptional() { return new IRNative(IRNativeTag._mkFindDataOptional); }
|
|
187
|
+
// static get _mkFindDataOptional() { return new IRNative( IRNativeTag._mkFindDataOptional ); }
|
|
188
188
|
static get _length() { return new IRNative(IRNativeTag._length); }
|
|
189
189
|
static get _some() { return new IRNative(IRNativeTag._some); }
|
|
190
190
|
static get _every() { return new IRNative(IRNativeTag._every); }
|
|
191
|
-
static get
|
|
191
|
+
static get _filter() { return new IRNative(IRNativeTag._filter); }
|
|
192
192
|
// static get _fstPair() { return new IRNative( IRNativeTag._fstPair ); }
|
|
193
193
|
// static get _sndPair() { return new IRNative( IRNativeTag._sndPair ); }
|
|
194
194
|
static get _id() { return new IRNative(IRNativeTag._id); }
|
|
@@ -217,6 +217,9 @@ export class IRNative {
|
|
|
217
217
|
static get _amountOfValue() { return new IRNative(IRNativeTag._amountOfValue); }
|
|
218
218
|
static get _sortedValueLovelaces() { return new IRNative(IRNativeTag._sortedValueLovelaces); }
|
|
219
219
|
static get _getCredentialsHash() { return new IRNative(IRNativeTag._getCredentialsHash); }
|
|
220
|
+
static get _increment() { return new IRNative(IRNativeTag._increment); }
|
|
221
|
+
static get _decrement() { return new IRNative(IRNativeTag._decrement); }
|
|
222
|
+
static get _isZero() { return new IRNative(IRNativeTag._isZero); }
|
|
220
223
|
static equals(type) {
|
|
221
224
|
type = getUnaliased(type);
|
|
222
225
|
if (type instanceof TirAliasType)
|
|
@@ -69,7 +69,8 @@ export const defaultOptions = Object.freeze({
|
|
|
69
69
|
...productionOptions,
|
|
70
70
|
});
|
|
71
71
|
export const testOptions = Object.freeze({
|
|
72
|
-
...debugOptions,
|
|
72
|
+
// ...debugOptions,
|
|
73
|
+
...productionOptions,
|
|
73
74
|
silent: true
|
|
74
75
|
});
|
|
75
76
|
export const defulatCompilerOptions = defaultOptions;
|
|
@@ -31,7 +31,7 @@ export function compileIRToUPLC(term, paritalOptions = defaultOptions) {
|
|
|
31
31
|
// ------------------------------------------------------------------------- //
|
|
32
32
|
///////////////////////////////////////////////////////////////////////////////
|
|
33
33
|
const options = completeCompilerOptions(paritalOptions);
|
|
34
|
-
const debugAsserts = options.debugAsserts ?? false;
|
|
34
|
+
// const debugAsserts = (options as any).debugAsserts ?? false;
|
|
35
35
|
// unwrap top level letted and hoisted;
|
|
36
36
|
while (term instanceof IRLetted || term instanceof IRHoisted) {
|
|
37
37
|
// replace with value
|
|
@@ -39,33 +39,24 @@ export function compileIRToUPLC(term, paritalOptions = defaultOptions) {
|
|
|
39
39
|
// forget the parent; this is the new root
|
|
40
40
|
term.parent = undefined;
|
|
41
41
|
}
|
|
42
|
-
debugAsserts && _debug_assertions(term);
|
|
42
|
+
// debugAsserts && _debug_assertions( term );
|
|
43
|
+
///////////////////////////////////////////////////////////////////////////////
|
|
44
|
+
// ------------------------------------------------------------------------- //
|
|
45
|
+
// ----------------------------- optimizations ----------------------------- //
|
|
46
|
+
// ------------------------------------------------------------------------- //
|
|
47
|
+
///////////////////////////////////////////////////////////////////////////////
|
|
43
48
|
// term = preEvaluateDefinedTermsAndReturnRoot( term );
|
|
44
49
|
term = rewriteNativesAppliedToConstantsAndReturnRoot(term);
|
|
45
|
-
debugAsserts && _debug_assertions(term);
|
|
50
|
+
// debugAsserts && _debug_assertions( term );
|
|
46
51
|
// removing unused variables BEFORE going into the rest of the compilation
|
|
47
52
|
// helps letted terms to find a better spot (and possibly be inlined instead of hoisted)
|
|
48
53
|
term = removeUnusedVarsAndReturnRoot(term);
|
|
49
|
-
debugAsserts && _debug_assertions(term);
|
|
54
|
+
// debugAsserts && _debug_assertions( term );
|
|
50
55
|
_makeAllNegativeNativesHoisted(term);
|
|
51
|
-
///////////////////////////////////////////////////////////////////////////////
|
|
52
|
-
// ------------------------------------------------------------------------- //
|
|
53
|
-
// ----------------------------- optimizations ----------------------------- //
|
|
54
|
-
// ------------------------------------------------------------------------- //
|
|
55
|
-
///////////////////////////////////////////////////////////////////////////////
|
|
56
|
-
// --------------------- optimize recursive functions --------------------- //
|
|
57
|
-
// avoid passing whole structs
|
|
58
|
-
// take letted terms outside
|
|
59
|
-
// ----------------------- optimize normal functions ----------------------- //
|
|
60
|
-
// avoid passing whole structs
|
|
61
|
-
// reorganize function arguments to take advantage of partial applicaiton
|
|
62
|
-
///////////////////////////////////////////////////////////////////////////////
|
|
63
|
-
// ------------------------------------------------------------------------- //
|
|
64
|
-
// ------------------------------ final steps ------------------------------ //
|
|
65
|
-
// ------------------------------------------------------------------------- //
|
|
66
|
-
///////////////////////////////////////////////////////////////////////////////
|
|
67
56
|
term = replaceNativesAndReturnRoot(term);
|
|
68
|
-
|
|
57
|
+
// re-call rewrite to optimize introduced hoisted
|
|
58
|
+
term = rewriteNativesAppliedToConstantsAndReturnRoot(term);
|
|
59
|
+
// debugAsserts && _debug_assertions( term );
|
|
69
60
|
// unwrap top level letted and hoisted;
|
|
70
61
|
// some natives may be converted to hoisted;
|
|
71
62
|
// this is really just an edge case
|
|
@@ -79,31 +70,39 @@ export function compileIRToUPLC(term, paritalOptions = defaultOptions) {
|
|
|
79
70
|
term instanceof IRConst // while we are at it
|
|
80
71
|
)
|
|
81
72
|
return term.toUPLC();
|
|
73
|
+
///////////////////////////////////////////////////////////////////////////////
|
|
74
|
+
// ------------------------------------------------------------------------- //
|
|
75
|
+
// ------------------------------- hoisting -------------------------------- //
|
|
76
|
+
// ------------------------------------------------------------------------- //
|
|
77
|
+
///////////////////////////////////////////////////////////////////////////////
|
|
78
|
+
// hoist `(force (builtin ifThenElse))` or `(force (force (builtin fstPair)))` etc
|
|
82
79
|
replaceForcedNativesWithHoisted(term);
|
|
83
|
-
debugAsserts && _debug_assertions(term);
|
|
80
|
+
// debugAsserts && _debug_assertions( term );
|
|
84
81
|
if (options.delayHoists)
|
|
85
82
|
replaceHoistedWithLetted(term);
|
|
86
83
|
else
|
|
87
84
|
replaceClosedLettedWithHoisted(term);
|
|
88
|
-
debugAsserts && _debug_assertions(term);
|
|
89
|
-
if
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
85
|
+
// debugAsserts && _debug_assertions( term );
|
|
86
|
+
// if(
|
|
87
|
+
// // debugAsserts
|
|
88
|
+
// && options.delayHoists
|
|
89
|
+
// && includesNode( term, node => node instanceof IRHoisted )
|
|
90
|
+
// ) {
|
|
91
|
+
// throw new Error("debug assertion failed: hoisted nodes found while delayHoists is true");
|
|
92
|
+
// }
|
|
94
93
|
// handle letted before hoisted because the tree is smaller
|
|
95
94
|
// and we also have less letted dependecies to handle
|
|
96
95
|
term = handleLettedAndReturnRoot(term);
|
|
97
|
-
debugAsserts && _debug_assertions(term);
|
|
96
|
+
// debugAsserts && _debug_assertions( term );
|
|
98
97
|
term = handleHoistedAndReturnRoot(term);
|
|
99
|
-
debugAsserts && _debug_assertions(term);
|
|
98
|
+
// debugAsserts && _debug_assertions( term );
|
|
100
99
|
// replaced hoisted terms might include new letted terms
|
|
101
100
|
while (includesNode(term, node => node instanceof IRLetted
|
|
102
101
|
|| node instanceof IRHoisted)) {
|
|
103
102
|
term = handleLettedAndReturnRoot(term);
|
|
104
103
|
term = handleHoistedAndReturnRoot(term);
|
|
105
104
|
}
|
|
106
|
-
debugAsserts && _debug_assertions(term);
|
|
105
|
+
// debugAsserts && _debug_assertions( term );
|
|
107
106
|
///////////////////////////////////////////////////////////////////////////////
|
|
108
107
|
// ------------------------------------------------------------------------- //
|
|
109
108
|
// --------------------------- translate to UPLC --------------------------- //
|
|
@@ -117,13 +116,13 @@ export function compileIRToUPLC(term, paritalOptions = defaultOptions) {
|
|
|
117
116
|
// if( options.delayHoists ) replaceHoistedWithLetted( term );
|
|
118
117
|
// handle new hoisted terms
|
|
119
118
|
term = handleHoistedAndReturnRoot(term);
|
|
120
|
-
debugAsserts && _debug_assertions(term);
|
|
119
|
+
// debugAsserts && _debug_assertions( term );
|
|
121
120
|
// strictly necessary to check the options
|
|
122
121
|
// otherwise forced natives where already hoisted
|
|
123
122
|
// will be re-hosited; causeing uselsess evaluations
|
|
124
123
|
if (!options.delayHoists)
|
|
125
124
|
term = hoistForcedNatives(term);
|
|
126
|
-
debugAsserts && _debug_assertions(term);
|
|
125
|
+
// debugAsserts && _debug_assertions( term );
|
|
127
126
|
// at this point we expect the IR to be translable 1:1 to UPLC
|
|
128
127
|
// The loop is needed because after inlining some params,
|
|
129
128
|
// new params in outer (or sibling) functions can become
|
|
@@ -161,7 +160,7 @@ export function compileIRToUPLC(term, paritalOptions = defaultOptions) {
|
|
|
161
160
|
// irJson.text,
|
|
162
161
|
// JSON.stringify( onlyHoistedAndLetted( irJson ) )
|
|
163
162
|
// );
|
|
164
|
-
debugAsserts && _debug_assertions(term);
|
|
163
|
+
// debugAsserts && _debug_assertions( term );
|
|
165
164
|
// const srcmap = {};
|
|
166
165
|
const uplc = term.toUPLC(ToUplcCtx.root());
|
|
167
166
|
if (!isClosedTerm(uplc)) {
|
|
@@ -4,7 +4,7 @@ import { getSortedLettedSet, getLettedTerms, IRLetted } from "../../../IRNodes/I
|
|
|
4
4
|
import { IRVar } from "../../../IRNodes/IRVar.js";
|
|
5
5
|
import { _modifyChildFromTo } from "../../_internal/_modifyChildFromTo.js";
|
|
6
6
|
import { findAllNoHoisted } from "../../_internal/findAll.js";
|
|
7
|
-
import { getMaxScope } from "./groupByScope.js";
|
|
7
|
+
import { getMaxScope, getUnboundedVars } from "./groupByScope.js";
|
|
8
8
|
import { IRDelayed } from "../../../IRNodes/IRDelayed.js";
|
|
9
9
|
import { lowestCommonAncestor } from "../../_internal/lowestCommonAncestor.js";
|
|
10
10
|
import { isIRTerm } from "../../../utils/isIRTerm.js";
|
|
@@ -47,9 +47,22 @@ export function handleLettedAndReturnRoot(term) {
|
|
|
47
47
|
//
|
|
48
48
|
// hence why `pop` (and not `shift`)
|
|
49
49
|
const { letted, nReferences } = sortedLettedSet.pop();
|
|
50
|
+
// const shouldLog = (
|
|
51
|
+
// letted.value instanceof IRApp
|
|
52
|
+
// && letted.value.fn instanceof IRNative
|
|
53
|
+
// && letted.value.fn.tag === IRNativeTag.addInteger
|
|
54
|
+
// && letted.value.arg instanceof IRConst
|
|
55
|
+
// && letted.value.arg.value === -1n
|
|
56
|
+
// )
|
|
50
57
|
// shouldLog && // console.log("nReferences", nReferences);
|
|
51
58
|
// console.log(` ------------------ working with ${lettedToStr(letted)} ------------------ `);
|
|
52
|
-
|
|
59
|
+
// console.log(` ------------------ working with ${lettedToStr(letted)} ------------------ `);
|
|
60
|
+
// if( shouldLog ) {
|
|
61
|
+
// console.log( prettyIRInline( letted ) );
|
|
62
|
+
// }
|
|
63
|
+
const wasSingleReferenceButRecursive = nReferences <= 1;
|
|
64
|
+
if (wasSingleReferenceButRecursive // nReferences <= 1
|
|
65
|
+
&& !someParentIsRecursive(letted)) {
|
|
53
66
|
// console.log("inlining letted (single reference) with value", prettyIRText( letted.value ) )
|
|
54
67
|
_modifyChildFromTo(letted.parent, letted, letted.value);
|
|
55
68
|
continue;
|
|
@@ -81,7 +94,9 @@ export function handleLettedAndReturnRoot(term) {
|
|
|
81
94
|
continue;
|
|
82
95
|
}
|
|
83
96
|
// just in case
|
|
84
|
-
if (sameLettedRefs.length === 1
|
|
97
|
+
if (sameLettedRefs.length === 1
|
|
98
|
+
&& !minScope
|
|
99
|
+
&& !wasSingleReferenceButRecursive) {
|
|
85
100
|
// console.log("inlining letted (single reference pedantic) with value", prettyIRText( letted.value ) )
|
|
86
101
|
_modifyChildFromTo(letted.parent, letted, letted.value);
|
|
87
102
|
continue;
|
|
@@ -108,6 +123,47 @@ export function handleLettedAndReturnRoot(term) {
|
|
|
108
123
|
}
|
|
109
124
|
;
|
|
110
125
|
}
|
|
126
|
+
if (wasSingleReferenceButRecursive) {
|
|
127
|
+
// OPTIMIZATION:
|
|
128
|
+
// TODO:
|
|
129
|
+
// see the general case below
|
|
130
|
+
const unbounded = getUnboundedVars(letted.value);
|
|
131
|
+
if (unbounded.size === 0) {
|
|
132
|
+
// if closed
|
|
133
|
+
// handle as hoisted
|
|
134
|
+
for (const ref of sameLettedRefs) {
|
|
135
|
+
_modifyChildFromTo(ref.parent, ref, new IRVar(ref.name));
|
|
136
|
+
}
|
|
137
|
+
term = new IRApp(new IRFunc([letted.name], term), letted.value);
|
|
138
|
+
continue;
|
|
139
|
+
}
|
|
140
|
+
// else find highest common ancestor where all unbounded vars are defined
|
|
141
|
+
// OPTIMIZATION:
|
|
142
|
+
// TODO:
|
|
143
|
+
// only hoist outside the highest, but fully defined, IRRecursive
|
|
144
|
+
// and NOT the highest overall
|
|
145
|
+
// otherwise we risk paying for introducing stuff we don't use
|
|
146
|
+
let tmp = lca;
|
|
147
|
+
// let lowestOutsideRecursive: IRTerm = lca;
|
|
148
|
+
while (tmp = tmp.parent) {
|
|
149
|
+
if (tmp instanceof IRDelayed) {
|
|
150
|
+
lca = tmp;
|
|
151
|
+
// lowestOutsideRecursive = tmp;
|
|
152
|
+
continue;
|
|
153
|
+
}
|
|
154
|
+
if (tmp instanceof IRFunc || tmp instanceof IRRecursive) {
|
|
155
|
+
if (tmp.params.some(p => unbounded.has(p))) {
|
|
156
|
+
// some parameter is defined here
|
|
157
|
+
// so we stop
|
|
158
|
+
break;
|
|
159
|
+
}
|
|
160
|
+
else
|
|
161
|
+
lca = tmp;
|
|
162
|
+
// else lowestOutsideRecursive = tmp;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
// lca = lowestOutsideRecursive;
|
|
166
|
+
}
|
|
111
167
|
if (!isIRTerm(lca)) {
|
|
112
168
|
throw new Error("letting nodes with hash " + irHashToHex(lettedHash) + " from different trees");
|
|
113
169
|
}
|
|
@@ -176,3 +232,13 @@ function handleLettedAsHoistedAndReturnRoot(letted, lca, sameLettedRefs, current
|
|
|
176
232
|
}
|
|
177
233
|
return currentRoot;
|
|
178
234
|
}
|
|
235
|
+
function someParentIsRecursive(term) {
|
|
236
|
+
let parent;
|
|
237
|
+
;
|
|
238
|
+
while (parent = term.parent) {
|
|
239
|
+
if (parent instanceof IRRecursive)
|
|
240
|
+
return true;
|
|
241
|
+
term = parent;
|
|
242
|
+
}
|
|
243
|
+
return false;
|
|
244
|
+
}
|
|
@@ -28,7 +28,7 @@ export declare const hoisted_strictAnd: IRHoisted;
|
|
|
28
28
|
export declare const hoisted_strictOr: IRHoisted;
|
|
29
29
|
export declare const hoisted_some: IRHoisted;
|
|
30
30
|
export declare const hoisted_every: IRHoisted;
|
|
31
|
-
export declare const
|
|
31
|
+
export declare const hoisted_filter: IRHoisted;
|
|
32
32
|
export declare const hoisted_gtBS: IRHoisted;
|
|
33
33
|
export declare const hoisted_gtEqBS: IRHoisted;
|
|
34
34
|
export declare const hoisted_gtInt: IRHoisted;
|
|
@@ -12,7 +12,7 @@ import { IRRecursive } from "../../../IRNodes/IRRecursive.js";
|
|
|
12
12
|
import { IRSelfCall } from "../../../IRNodes/IRSelfCall.js";
|
|
13
13
|
import { IRError } from "../../../IRNodes/IRError.js";
|
|
14
14
|
import { _ir_apps } from "../../../IRNodes/IRApp.js";
|
|
15
|
-
import { _ir_let } from "../../../tree_utils/_ir_let.js";
|
|
15
|
+
import { _ir_let, _ir_let_sym } from "../../../tree_utils/_ir_let.js";
|
|
16
16
|
import { _ir_lazyChooseList } from "../../../tree_utils/_ir_lazyChooseList.js";
|
|
17
17
|
import { _ir_lazyIfThenElse } from "../../../tree_utils/_ir_lazyIfThenElse.js";
|
|
18
18
|
import { hoisted_drop4, hoisted_drop2, hoisted_drop3 } from "../_comptimeDropN.js";
|
|
@@ -156,13 +156,21 @@ const every_head = Symbol("head");
|
|
|
156
156
|
const every_tail = Symbol("tail");
|
|
157
157
|
export const hoisted_every = new IRHoisted(new IRFunc([every_pred], _ir_apps(hoisted_recursiveList.clone(), new IRFunc([every_dummy], new IRDelayed(IRConst.bool(true))), new IRFunc([every_self, every_head, every_tail], new IRForced(_ir_apps(hoisted_strictAnd.clone(), new IRDelayed(new IRApp(new IRVar(every_pred), new IRVar(every_head))), new IRDelayed(new IRApp(new IRVar(every_self), new IRVar(every_tail)))))))));
|
|
158
158
|
hoisted_every.hash;
|
|
159
|
-
// hoisted
|
|
160
|
-
const filt_pnil = Symbol("pnilOfType");
|
|
159
|
+
// hoisted _filter
|
|
161
160
|
const filt_pred = Symbol("predicate");
|
|
161
|
+
const filt_self = Symbol("filter_self");
|
|
162
|
+
const filt_list = Symbol("list");
|
|
162
163
|
const filt_elem = Symbol("elem");
|
|
163
|
-
const
|
|
164
|
-
|
|
165
|
-
|
|
164
|
+
export const hoisted_filter = new IRHoisted(new IRFunc([filt_pred], new IRRecursive(filt_self, new IRFunc([filt_list], _ir_lazyChooseList(new IRVar(filt_list),
|
|
165
|
+
// case nil
|
|
166
|
+
new IRVar(filt_list), // nil
|
|
167
|
+
// case cons
|
|
168
|
+
_ir_let_sym(filt_elem, _ir_apps(IRNative.headList, new IRVar(filt_list)), _ir_lazyIfThenElse(_ir_apps(new IRVar(filt_pred), new IRVar(filt_elem)),
|
|
169
|
+
// then => cons(elem, self(tail))
|
|
170
|
+
_ir_apps(IRNative.mkCons, new IRVar(filt_elem), _ir_apps(new IRSelfCall(filt_self), _ir_apps(IRNative.tailList, new IRVar(filt_list)))),
|
|
171
|
+
// else => self(tail)
|
|
172
|
+
_ir_apps(new IRSelfCall(filt_self), _ir_apps(IRNative.tailList, new IRVar(filt_list))))))))));
|
|
173
|
+
hoisted_filter.hash;
|
|
166
174
|
// comparison & conversion hoisted (previously inline)
|
|
167
175
|
const gtbs_a = Symbol("a"), gtbs_b = Symbol("b");
|
|
168
176
|
export const hoisted_gtBS = new IRHoisted(new IRFunc([gtbs_a, gtbs_b], _ir_apps(IRNative.lessThanByteString, new IRVar(gtbs_b), new IRVar(gtbs_a))));
|
|
@@ -211,12 +219,12 @@ export function nativeToIR(native) {
|
|
|
211
219
|
switch (native.tag) {
|
|
212
220
|
case IRNativeTag._foldr: return hoisted_foldr.clone();
|
|
213
221
|
case IRNativeTag._foldl: return hoiseted_foldl.clone();
|
|
214
|
-
case IRNativeTag._mkFindDataOptional: return hoisted_mkFindDataOptional.clone();
|
|
222
|
+
// case IRNativeTag._mkFindDataOptional: return hoisted_mkFindDataOptional.clone();
|
|
215
223
|
case IRNativeTag._findSopOptional: return hoisted_findSopOptional.clone();
|
|
216
224
|
case IRNativeTag._length: return hoisted_length.clone();
|
|
217
225
|
case IRNativeTag._some: return hoisted_some.clone();
|
|
218
226
|
case IRNativeTag._every: return hoisted_every.clone();
|
|
219
|
-
case IRNativeTag.
|
|
227
|
+
case IRNativeTag._filter: return hoisted_filter.clone();
|
|
220
228
|
case IRNativeTag._id: return hoisted_id.clone();
|
|
221
229
|
case IRNativeTag._not: return hoisted_not.clone();
|
|
222
230
|
case IRNativeTag._strictAnd: return hoisted_strictAnd.clone();
|
|
@@ -239,6 +247,8 @@ export function nativeToIR(native) {
|
|
|
239
247
|
case IRNativeTag._getCredentialsHash: return hoisted_getCredentialsHash.clone();
|
|
240
248
|
case IRNativeTag._dropList: return hoisted_dropList.clone();
|
|
241
249
|
case IRNativeTag._mkMapList: return hoisted_mkMapList.clone();
|
|
250
|
+
case IRNativeTag._increment: return hoisted_addOne.clone();
|
|
251
|
+
case IRNativeTag._decrement: return hoisted_subOne.clone();
|
|
242
252
|
// case IRNativeTag._mkEqualsList: return hoisted_mkEqualsList.clone();
|
|
243
253
|
default:
|
|
244
254
|
throw new Error("unknown (negative) native calling 'nativeToIR'; " +
|
|
@@ -260,7 +270,7 @@ IRConst.bool(false),
|
|
|
260
270
|
// both lists are cons
|
|
261
271
|
_ir_strictAnd(_ir_apps(new IRVar(eqList_eqFunc), new IRApp(IRNative.headList, new IRVar(eqList_listA)), new IRApp(IRNative.headList, new IRVar(eqList_listB))), _ir_apps(new IRSelfCall(eqList_self), new IRApp(IRNative.tailList, new IRVar(eqList_listA)), new IRApp(IRNative.tailList, new IRVar(eqList_listB))))))))));
|
|
262
272
|
hoisted_mkEqualsList.hash;
|
|
263
|
-
// (nil of type) => ( a => b ) => [a] => [b]
|
|
273
|
+
// (nil of type) [b] => ( a => b ) => [a] => [b]
|
|
264
274
|
const mkMap_nil = Symbol("nilOfType");
|
|
265
275
|
const mkMap_mapFunc = Symbol("mapFunc");
|
|
266
276
|
const mkMap_map = Symbol("map_self");
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { TirBoolT, TirIntT } from "../../../compiler/tir/types/TirNativeType/index.js";
|
|
2
|
+
import { equalIrHash } from "../../IRHash.js";
|
|
1
3
|
import { _ir_apps } from "../../IRNodes/IRApp.js";
|
|
2
4
|
import { IRConst } from "../../IRNodes/IRConst.js";
|
|
3
5
|
import { IRFunc } from "../../IRNodes/IRFunc.js";
|
|
@@ -9,13 +11,25 @@ import { IRVar } from "../../IRNodes/IRVar.js";
|
|
|
9
11
|
import { _modifyChildFromTo } from "../_internal/_modifyChildFromTo.js";
|
|
10
12
|
import { getApplicationTerms } from "../utils/getApplicationTerms.js";
|
|
11
13
|
import { _compTimeDropN } from "./_comptimeDropN.js";
|
|
14
|
+
import { hoisted_isZero, hoisted_length, hoisted_not } from "./replaceNatives/nativeToIR.js";
|
|
12
15
|
export function rewriteNativesAppliedToConstantsAndReturnRoot(term) {
|
|
13
16
|
// traverse the tree, find applications of natives to constants
|
|
14
17
|
// and replace them with the optimized equivalent
|
|
15
18
|
const stack = [term];
|
|
19
|
+
function modifyTermAndPushToReprocess(current, newTerm) {
|
|
20
|
+
const parent = current.parent;
|
|
21
|
+
if (parent) {
|
|
22
|
+
_modifyChildFromTo(parent, current, newTerm);
|
|
23
|
+
}
|
|
24
|
+
else {
|
|
25
|
+
term = newTerm;
|
|
26
|
+
term.parent = undefined;
|
|
27
|
+
}
|
|
28
|
+
stack.unshift(newTerm); // reprocess new term for further optimizations (if any)
|
|
29
|
+
}
|
|
16
30
|
while (stack.length > 0) {
|
|
17
31
|
const current = stack.pop();
|
|
18
|
-
const parent = current.parent;
|
|
32
|
+
// const parent = current.parent;
|
|
19
33
|
const appTerms = getApplicationTerms(current);
|
|
20
34
|
if (!appTerms) {
|
|
21
35
|
stack.unshift(...current.children());
|
|
@@ -25,16 +39,196 @@ export function rewriteNativesAppliedToConstantsAndReturnRoot(term) {
|
|
|
25
39
|
const [fstArg, ...restArgs] = args;
|
|
26
40
|
if (isId(func)
|
|
27
41
|
&& restArgs.length === 0) {
|
|
28
|
-
|
|
29
|
-
_modifyChildFromTo(parent, current, fstArg);
|
|
30
|
-
}
|
|
31
|
-
else {
|
|
32
|
-
term = fstArg;
|
|
33
|
-
term.parent = undefined;
|
|
34
|
-
}
|
|
35
|
-
stack.unshift(fstArg);
|
|
42
|
+
modifyTermAndPushToReprocess(current, fstArg);
|
|
36
43
|
continue;
|
|
37
44
|
}
|
|
45
|
+
if (func instanceof IRNative) {
|
|
46
|
+
const tag = func.tag;
|
|
47
|
+
if (tag === IRNativeTag.strictIfThenElse
|
|
48
|
+
&& restArgs.length === 2) {
|
|
49
|
+
const conditionArg = fstArg;
|
|
50
|
+
const condtionAppTerms = getApplicationTerms(conditionArg);
|
|
51
|
+
if (!condtionAppTerms) {
|
|
52
|
+
const boolValue = getConstBool(conditionArg);
|
|
53
|
+
if (typeof boolValue === "boolean") {
|
|
54
|
+
const newTerm = boolValue ? restArgs[0] : restArgs[1];
|
|
55
|
+
modifyTermAndPushToReprocess(current, newTerm);
|
|
56
|
+
continue;
|
|
57
|
+
}
|
|
58
|
+
stack.unshift(...current.children()); // normal processing
|
|
59
|
+
continue;
|
|
60
|
+
}
|
|
61
|
+
const { func: condFunc, args: condArgs } = condtionAppTerms;
|
|
62
|
+
const thenArg = restArgs[0];
|
|
63
|
+
const elseArg = restArgs[1];
|
|
64
|
+
if (isNot(condFunc)
|
|
65
|
+
&& condArgs.length === 1) {
|
|
66
|
+
// replace with swapped branches
|
|
67
|
+
const newTerm = _ir_apps(IRNative.strictIfThenElse, condArgs[0], elseArg, thenArg);
|
|
68
|
+
modifyTermAndPushToReprocess(current, newTerm);
|
|
69
|
+
continue;
|
|
70
|
+
}
|
|
71
|
+
else if (isLessThanOrEqualInteger(condFunc)
|
|
72
|
+
&& condArgs.length === 2) {
|
|
73
|
+
const [lhs, rhs] = condArgs;
|
|
74
|
+
const lhsInt = getConstInt(lhs);
|
|
75
|
+
const rhsInt = getConstInt(rhs);
|
|
76
|
+
if (typeof lhsInt === "bigint" && typeof rhsInt === "bigint") {
|
|
77
|
+
// replace with constant
|
|
78
|
+
const newTerm = (lhsInt <= rhsInt) ? thenArg : elseArg;
|
|
79
|
+
modifyTermAndPushToReprocess(current, newTerm);
|
|
80
|
+
continue;
|
|
81
|
+
}
|
|
82
|
+
else if (typeof lhsInt === "bigint") {
|
|
83
|
+
const newTerm = _ir_apps(IRNative.strictIfThenElse, _ir_apps(new IRHoisted(_ir_apps(IRNative.lessThanEqualInteger, lhs)), rhs), thenArg, elseArg);
|
|
84
|
+
modifyTermAndPushToReprocess(current, newTerm);
|
|
85
|
+
continue;
|
|
86
|
+
}
|
|
87
|
+
else if (typeof rhsInt === "bigint") {
|
|
88
|
+
const newTerm = _ir_apps(IRNative.strictIfThenElse, _ir_apps(new IRHoisted(_ir_apps(IRNative.lessThanInteger, rhs)), lhs), elseArg, thenArg);
|
|
89
|
+
modifyTermAndPushToReprocess(current, newTerm);
|
|
90
|
+
continue;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
else if (isLessThanInteger(condFunc)
|
|
94
|
+
&& condArgs.length === 2) {
|
|
95
|
+
const [lhs, rhs] = condArgs;
|
|
96
|
+
const lhsInt = getConstInt(lhs);
|
|
97
|
+
const rhsInt = getConstInt(rhs);
|
|
98
|
+
if (typeof lhsInt === "bigint" && typeof rhsInt === "bigint") {
|
|
99
|
+
// replace with constant
|
|
100
|
+
const newTerm = (lhsInt < rhsInt) ? thenArg : elseArg;
|
|
101
|
+
modifyTermAndPushToReprocess(current, newTerm);
|
|
102
|
+
continue;
|
|
103
|
+
}
|
|
104
|
+
else if (typeof lhsInt === "bigint") {
|
|
105
|
+
const newTerm = _ir_apps(IRNative.strictIfThenElse, _ir_apps(new IRHoisted(_ir_apps(IRNative.lessThanInteger, lhs)), rhs), thenArg, elseArg);
|
|
106
|
+
modifyTermAndPushToReprocess(current, newTerm);
|
|
107
|
+
continue;
|
|
108
|
+
}
|
|
109
|
+
else if (typeof rhsInt === "bigint") {
|
|
110
|
+
const newTerm = _ir_apps(IRNative.strictIfThenElse, _ir_apps(new IRHoisted(_ir_apps(IRNative.lessThanEqualInteger, rhs)), lhs), elseArg, thenArg);
|
|
111
|
+
modifyTermAndPushToReprocess(current, newTerm);
|
|
112
|
+
continue;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
else if (isEqualsZero(condFunc)
|
|
116
|
+
&& condArgs.length === 1) {
|
|
117
|
+
const equalZeroArg = condArgs[0];
|
|
118
|
+
const equalZeroArgAppTerms = getApplicationTerms(equalZeroArg);
|
|
119
|
+
if (!equalZeroArgAppTerms) {
|
|
120
|
+
// standard continuation
|
|
121
|
+
stack.unshift(...current.children());
|
|
122
|
+
continue;
|
|
123
|
+
}
|
|
124
|
+
const { func: eqZeroArgFunc, args: eqZeroArgArgs } = equalZeroArgAppTerms;
|
|
125
|
+
if (isListLength(eqZeroArgFunc)
|
|
126
|
+
&& eqZeroArgArgs.length === 1) {
|
|
127
|
+
const listTerm = eqZeroArgArgs[0];
|
|
128
|
+
// replace with isNullList
|
|
129
|
+
const newTerm = _ir_apps(IRNative.strictChooseList, listTerm, thenArg, elseArg);
|
|
130
|
+
modifyTermAndPushToReprocess(current, newTerm);
|
|
131
|
+
continue;
|
|
132
|
+
}
|
|
133
|
+
// standard continuation
|
|
134
|
+
stack.unshift(...current.children());
|
|
135
|
+
continue;
|
|
136
|
+
} // if( x.length() === 0 )
|
|
137
|
+
else if (isNullList(condFunc)
|
|
138
|
+
&& condArgs.length === 1) {
|
|
139
|
+
const listTerm = condArgs[0];
|
|
140
|
+
// replace with isListLength
|
|
141
|
+
const newTerm = _ir_apps(IRNative.strictChooseList, listTerm, thenArg, elseArg);
|
|
142
|
+
modifyTermAndPushToReprocess(current, newTerm);
|
|
143
|
+
continue;
|
|
144
|
+
} // if( x.isEmpty() )
|
|
145
|
+
} // strictIfThenElse
|
|
146
|
+
else if (tag === IRNativeTag.equalsInteger
|
|
147
|
+
&& restArgs.length === 1) {
|
|
148
|
+
const sndArg = restArgs[0];
|
|
149
|
+
const fstInt = getConstInt(fstArg);
|
|
150
|
+
const sndInt = getConstInt(sndArg);
|
|
151
|
+
if (fstInt === BigInt(0)) {
|
|
152
|
+
// replace as `isZero( sndArg )`
|
|
153
|
+
const newTerm = _ir_apps(IRNative._isZero, sndArg);
|
|
154
|
+
modifyTermAndPushToReprocess(current, newTerm);
|
|
155
|
+
continue;
|
|
156
|
+
}
|
|
157
|
+
else if (sndInt === BigInt(0)) {
|
|
158
|
+
// replace as `isZero( fstArg )`
|
|
159
|
+
const newTerm = _ir_apps(IRNative._isZero, fstArg);
|
|
160
|
+
modifyTermAndPushToReprocess(current, newTerm);
|
|
161
|
+
continue;
|
|
162
|
+
}
|
|
163
|
+
else if (typeof fstInt === "bigint" && typeof sndInt === "bigint") {
|
|
164
|
+
// replace as constant
|
|
165
|
+
const newTerm = IRConst.bool(fstInt === sndInt);
|
|
166
|
+
modifyTermAndPushToReprocess(current, newTerm);
|
|
167
|
+
continue;
|
|
168
|
+
}
|
|
169
|
+
else if (typeof fstInt === "bigint") {
|
|
170
|
+
const newTerm = _ir_apps(new IRHoisted(_ir_apps(IRNative.equalsInteger, fstArg)), sndArg);
|
|
171
|
+
modifyTermAndPushToReprocess(current, newTerm);
|
|
172
|
+
continue;
|
|
173
|
+
}
|
|
174
|
+
else if (typeof sndInt === "bigint") {
|
|
175
|
+
const newTerm = _ir_apps(new IRHoisted(_ir_apps(IRNative.equalsInteger, sndArg)), fstArg);
|
|
176
|
+
modifyTermAndPushToReprocess(current, newTerm);
|
|
177
|
+
continue;
|
|
178
|
+
}
|
|
179
|
+
} // equalsInteger
|
|
180
|
+
else if (tag === IRNativeTag.addInteger
|
|
181
|
+
&& restArgs.length === 1) {
|
|
182
|
+
const sndArg = restArgs[0];
|
|
183
|
+
const fstInt = getConstInt(fstArg);
|
|
184
|
+
const sndInt = getConstInt(sndArg);
|
|
185
|
+
if (fstInt === BigInt(1)) {
|
|
186
|
+
// replace as `incr( sndArg )`
|
|
187
|
+
const newTerm = _ir_apps(IRNative._increment, sndArg);
|
|
188
|
+
modifyTermAndPushToReprocess(current, newTerm);
|
|
189
|
+
continue;
|
|
190
|
+
}
|
|
191
|
+
else if (sndInt === BigInt(1)) {
|
|
192
|
+
// replace as `incr( fstArg )`
|
|
193
|
+
const newTerm = _ir_apps(IRNative._increment, fstArg);
|
|
194
|
+
modifyTermAndPushToReprocess(current, newTerm);
|
|
195
|
+
continue;
|
|
196
|
+
}
|
|
197
|
+
else if (typeof fstInt === "bigint" && typeof sndInt === "bigint") {
|
|
198
|
+
// replace as constant
|
|
199
|
+
const newTerm = IRConst.int(fstInt + sndInt);
|
|
200
|
+
modifyTermAndPushToReprocess(current, newTerm);
|
|
201
|
+
continue;
|
|
202
|
+
}
|
|
203
|
+
else if (typeof fstInt === "bigint") {
|
|
204
|
+
const newTerm = _ir_apps(new IRHoisted(_ir_apps(IRNative.addInteger, fstArg)), sndArg);
|
|
205
|
+
modifyTermAndPushToReprocess(current, newTerm);
|
|
206
|
+
continue;
|
|
207
|
+
}
|
|
208
|
+
else if (typeof sndInt === "bigint") {
|
|
209
|
+
const newTerm = _ir_apps(new IRHoisted(_ir_apps(IRNative.addInteger, sndArg)), fstArg);
|
|
210
|
+
modifyTermAndPushToReprocess(current, newTerm);
|
|
211
|
+
continue;
|
|
212
|
+
}
|
|
213
|
+
} // addInteger
|
|
214
|
+
else if (tag === IRNativeTag.subtractInteger
|
|
215
|
+
&& restArgs.length === 1) {
|
|
216
|
+
const sndArg = restArgs[0];
|
|
217
|
+
const sndInt = getConstInt(sndArg);
|
|
218
|
+
if (sndInt === BigInt(1)) {
|
|
219
|
+
// replace as `decr( fstArg )`
|
|
220
|
+
const newTerm = _ir_apps(IRNative._decrement, fstArg);
|
|
221
|
+
modifyTermAndPushToReprocess(current, newTerm);
|
|
222
|
+
continue;
|
|
223
|
+
}
|
|
224
|
+
else if (typeof sndInt === "bigint") {
|
|
225
|
+
const newTerm = _ir_apps(new IRHoisted(_ir_apps(IRNative.addInteger, IRConst.int(-sndInt))), fstArg);
|
|
226
|
+
modifyTermAndPushToReprocess(current, newTerm);
|
|
227
|
+
continue;
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
// only optimizations if first argument is constant after this point
|
|
38
232
|
if (!(fstArg instanceof IRConst)) {
|
|
39
233
|
stack.unshift(...current.children());
|
|
40
234
|
continue;
|
|
@@ -43,14 +237,7 @@ export function rewriteNativesAppliedToConstantsAndReturnRoot(term) {
|
|
|
43
237
|
&& (typeof fstArg.value === "bigint"
|
|
44
238
|
|| typeof fstArg.value === "number")) {
|
|
45
239
|
const newTerm = restArgs.length >= 1 ? _ir_apps(_compTimeDropN(fstArg.value), ...restArgs) : _compTimeDropN(fstArg.value);
|
|
46
|
-
|
|
47
|
-
_modifyChildFromTo(parent, current, newTerm);
|
|
48
|
-
}
|
|
49
|
-
else {
|
|
50
|
-
term = newTerm;
|
|
51
|
-
term.parent = undefined;
|
|
52
|
-
}
|
|
53
|
-
stack.unshift(newTerm);
|
|
240
|
+
modifyTermAndPushToReprocess(current, newTerm);
|
|
54
241
|
continue;
|
|
55
242
|
}
|
|
56
243
|
// const tsEnsureExhaustiveCheck: never = func;
|
|
@@ -83,3 +270,91 @@ function isId(term) {
|
|
|
83
270
|
&& term.body instanceof IRVar
|
|
84
271
|
&& term.body.name === term.params[0]));
|
|
85
272
|
}
|
|
273
|
+
function isNot(term) {
|
|
274
|
+
while (term instanceof IRHoisted
|
|
275
|
+
|| term instanceof IRLetted) {
|
|
276
|
+
if (term instanceof IRHoisted)
|
|
277
|
+
term = term.hoisted;
|
|
278
|
+
else if (term instanceof IRLetted)
|
|
279
|
+
term = term.value;
|
|
280
|
+
}
|
|
281
|
+
return (term instanceof IRNative
|
|
282
|
+
&& term.tag === IRNativeTag._not) || (equalIrHash(hoisted_not.hoisted.hash, term.hash));
|
|
283
|
+
}
|
|
284
|
+
function isNullList(term) {
|
|
285
|
+
while (term instanceof IRHoisted
|
|
286
|
+
|| term instanceof IRLetted) {
|
|
287
|
+
if (term instanceof IRHoisted)
|
|
288
|
+
term = term.hoisted;
|
|
289
|
+
else if (term instanceof IRLetted)
|
|
290
|
+
term = term.value;
|
|
291
|
+
}
|
|
292
|
+
return (term instanceof IRNative
|
|
293
|
+
&& term.tag === IRNativeTag.nullList);
|
|
294
|
+
}
|
|
295
|
+
function isEqualsZero(term) {
|
|
296
|
+
while (term instanceof IRHoisted
|
|
297
|
+
|| term instanceof IRLetted) {
|
|
298
|
+
if (term instanceof IRHoisted)
|
|
299
|
+
term = term.hoisted;
|
|
300
|
+
else if (term instanceof IRLetted)
|
|
301
|
+
term = term.value;
|
|
302
|
+
}
|
|
303
|
+
return (term instanceof IRNative
|
|
304
|
+
&& term.tag === IRNativeTag._isZero) || (equalIrHash(hoisted_isZero.hash, term.hash));
|
|
305
|
+
}
|
|
306
|
+
function isLessThanOrEqualInteger(term) {
|
|
307
|
+
while (term instanceof IRHoisted
|
|
308
|
+
|| term instanceof IRLetted) {
|
|
309
|
+
if (term instanceof IRHoisted)
|
|
310
|
+
term = term.hoisted;
|
|
311
|
+
else if (term instanceof IRLetted)
|
|
312
|
+
term = term.value;
|
|
313
|
+
}
|
|
314
|
+
return (term instanceof IRNative
|
|
315
|
+
&& term.tag === IRNativeTag.lessThanEqualInteger);
|
|
316
|
+
}
|
|
317
|
+
function isLessThanInteger(term) {
|
|
318
|
+
while (term instanceof IRHoisted
|
|
319
|
+
|| term instanceof IRLetted) {
|
|
320
|
+
if (term instanceof IRHoisted)
|
|
321
|
+
term = term.hoisted;
|
|
322
|
+
else if (term instanceof IRLetted)
|
|
323
|
+
term = term.value;
|
|
324
|
+
}
|
|
325
|
+
return (term instanceof IRNative
|
|
326
|
+
&& term.tag === IRNativeTag.lessThanInteger);
|
|
327
|
+
}
|
|
328
|
+
function isListLength(term) {
|
|
329
|
+
while (term instanceof IRHoisted
|
|
330
|
+
|| term instanceof IRLetted) {
|
|
331
|
+
if (term instanceof IRHoisted)
|
|
332
|
+
term = term.hoisted;
|
|
333
|
+
else if (term instanceof IRLetted)
|
|
334
|
+
term = term.value;
|
|
335
|
+
}
|
|
336
|
+
return (term instanceof IRNative
|
|
337
|
+
&& term.tag === IRNativeTag._length) || equalIrHash(hoisted_length.hash, term.hash);
|
|
338
|
+
}
|
|
339
|
+
function getConstInt(term) {
|
|
340
|
+
if (term instanceof IRConst
|
|
341
|
+
&& term.type instanceof TirIntT
|
|
342
|
+
&& typeof term.value === "bigint")
|
|
343
|
+
return term.value;
|
|
344
|
+
return undefined;
|
|
345
|
+
}
|
|
346
|
+
// function isConstIntOne( term: IRTerm ): boolean
|
|
347
|
+
// {
|
|
348
|
+
// return (
|
|
349
|
+
// term instanceof IRConst
|
|
350
|
+
// && term.type instanceof TirIntT
|
|
351
|
+
// && term.value === BigInt( 1 )
|
|
352
|
+
// );
|
|
353
|
+
// }
|
|
354
|
+
function getConstBool(term) {
|
|
355
|
+
if (term instanceof IRConst
|
|
356
|
+
&& term.type instanceof TirBoolT
|
|
357
|
+
&& typeof term.value === "boolean")
|
|
358
|
+
return term.value;
|
|
359
|
+
return undefined;
|
|
360
|
+
}
|
|
@@ -41,6 +41,8 @@ export declare class AstCompiler extends DiagnosticEmitter {
|
|
|
41
41
|
readonly parsedAstSources: Map<string, Source>;
|
|
42
42
|
get rootPath(): string;
|
|
43
43
|
constructor(cfg: CompilerOptions, io?: CompilerIoApi, diagnostics?: DiagnosticMessage[]);
|
|
44
|
+
private _isExporting;
|
|
45
|
+
export(funcName: string, modulePath?: string): Promise<TypedProgram>;
|
|
44
46
|
/**
|
|
45
47
|
* compiles the entry file specified in the config
|
|
46
48
|
*
|
|
@@ -35,6 +35,7 @@ import { _deriveContractBody } from "./internal/_deriveContractBody/_deriveContr
|
|
|
35
35
|
import { DiagnosticCategory } from "../../diagnostics/DiagnosticCategory.js";
|
|
36
36
|
import { VarStmt } from "../../ast/nodes/statements/VarStmt.js";
|
|
37
37
|
import { _compileSimpleVarDecl } from "./internal/statements/_compileVarStmt.js";
|
|
38
|
+
import { isIdentifier } from "../../utils/text.js";
|
|
38
39
|
/*
|
|
39
40
|
Handling type expressions that depend on other types
|
|
40
41
|
(such as generics, function return types, and inferred types from complex expressions)
|
|
@@ -84,6 +85,24 @@ export class AstCompiler extends DiagnosticEmitter {
|
|
|
84
85
|
this.cfg = cfg;
|
|
85
86
|
this.io = io;
|
|
86
87
|
this.program = new TypedProgram(this.diagnostics);
|
|
88
|
+
this._isExporting = false;
|
|
89
|
+
}
|
|
90
|
+
_isExporting;
|
|
91
|
+
async export(funcName, modulePath) {
|
|
92
|
+
this._isExporting = true;
|
|
93
|
+
if (typeof funcName !== "string")
|
|
94
|
+
throw new Error("AstCompiler.export: funcName must be a string");
|
|
95
|
+
funcName = funcName.trim();
|
|
96
|
+
if (funcName === "" || !isIdentifier(funcName))
|
|
97
|
+
throw new Error("AstCompiler.export: funcName must be a valid function identifier");
|
|
98
|
+
if (typeof modulePath === "string") {
|
|
99
|
+
const nextEntryPath = modulePath;
|
|
100
|
+
if (!nextEntryPath)
|
|
101
|
+
throw new Error("AstCompiler.export: modulePath not found: " + modulePath);
|
|
102
|
+
this.cfg.entry = nextEntryPath;
|
|
103
|
+
}
|
|
104
|
+
this.program.contractTirFuncName = funcName;
|
|
105
|
+
return await this.compile();
|
|
87
106
|
}
|
|
88
107
|
/**
|
|
89
108
|
* compiles the entry file specified in the config
|
|
@@ -115,6 +134,7 @@ export class AstCompiler extends DiagnosticEmitter {
|
|
|
115
134
|
}
|
|
116
135
|
const mainFuncExpr = this.program.functions.get(this.program.contractTirFuncName);
|
|
117
136
|
if (this.program.contractTirFuncName === "" || !mainFuncExpr) {
|
|
137
|
+
console.log([...this.program.functions.keys()]);
|
|
118
138
|
console.error(mainFuncExpr, `"${this.program.contractTirFuncName}"`);
|
|
119
139
|
this.error(DiagnosticCode.Contract_is_missing, undefined);
|
|
120
140
|
return this.program;
|
|
@@ -205,8 +225,11 @@ export class AstCompiler extends DiagnosticEmitter {
|
|
|
205
225
|
if (exported && stmt instanceof TypeImplementsStmt)
|
|
206
226
|
this.error(DiagnosticCode.Interface_implementations_cannot_be_exported, exportRange ?? stmt.range);
|
|
207
227
|
if (stmt instanceof ContractDecl) {
|
|
228
|
+
if (!(
|
|
208
229
|
// ignore contract declarations if not in the entry file
|
|
209
|
-
|
|
230
|
+
isEntryFile
|
|
231
|
+
// ignore contract decalarations if we are exporting a specific function
|
|
232
|
+
|| this._isExporting)) {
|
|
210
233
|
// remove from array so we don't process it again
|
|
211
234
|
void stmts.splice(i, 1);
|
|
212
235
|
i--;
|
|
@@ -300,6 +323,9 @@ export class AstCompiler extends DiagnosticEmitter {
|
|
|
300
323
|
const astFuncExpr = stmt.expr;
|
|
301
324
|
const astFuncName = astFuncExpr.name.text;
|
|
302
325
|
const tirFuncName = PEBBLE_INTERNAL_IDENTIFIER_PREFIX + astFuncName + "_" + srcUid;
|
|
326
|
+
if (this._isExporting && astFuncName === this.program.contractTirFuncName) {
|
|
327
|
+
this.program.contractTirFuncName = tirFuncName;
|
|
328
|
+
}
|
|
303
329
|
const declContext = AstCompilationCtx.fromScope(this.program, topLevelScope);
|
|
304
330
|
const funcExpr = _compileFuncExpr(declContext, astFuncExpr, undefined, // sig
|
|
305
331
|
false // isMethod
|
|
@@ -74,6 +74,12 @@ export function _compileFuncExpr(ctx, expr, expectedFuncType, isMethod = false)
|
|
|
74
74
|
}
|
|
75
75
|
const returnType = expectedFuncType.returnType;
|
|
76
76
|
const funcCtx = ctx.newFunctionChildScope(returnType, isMethod);
|
|
77
|
+
// define value in case of recursion
|
|
78
|
+
funcCtx.scope.defineValue({
|
|
79
|
+
name: expr.name.text,
|
|
80
|
+
type: expectedFuncType,
|
|
81
|
+
isConstant: true,
|
|
82
|
+
});
|
|
77
83
|
// if( _hasDuplicateTypeParams( ctx, expr.typeParams ) ) return undefined;
|
|
78
84
|
if (expr.typeParams.length > 0)
|
|
79
85
|
return ctx.error(DiagnosticCode.Not_implemented_0, expr.typeParams[0].range, "generic functions");
|
|
@@ -6,5 +6,12 @@ export declare class Compiler extends DiagnosticEmitter {
|
|
|
6
6
|
readonly io: CompilerIoApi;
|
|
7
7
|
readonly cfg: CompilerOptions;
|
|
8
8
|
constructor(io?: CompilerIoApi, cfg?: CompilerOptions, diagnostics?: DiagnosticMessage[]);
|
|
9
|
-
compile(config?: Partial<CompilerOptions>): Promise<
|
|
9
|
+
compile(config?: Partial<CompilerOptions>): Promise<Uint8Array>;
|
|
10
|
+
export(config: Partial<ExportOptions> & HasFuncitonName): Promise<Uint8Array>;
|
|
10
11
|
}
|
|
12
|
+
interface HasFuncitonName {
|
|
13
|
+
functionName: string;
|
|
14
|
+
}
|
|
15
|
+
export interface ExportOptions extends CompilerOptions, HasFuncitonName {
|
|
16
|
+
}
|
|
17
|
+
export {};
|
|
@@ -43,6 +43,39 @@ export class Compiler extends DiagnosticEmitter {
|
|
|
43
43
|
this.io.writeFile(outPath, serialized, cfg.root);
|
|
44
44
|
this.io.stdout.write(`compiled program written to ${outPath}\n`);
|
|
45
45
|
__VERY_UNSAFE_FORGET_IRHASH_ONLY_USE_AT_END_OF_UPLC_COMPILATION();
|
|
46
|
-
return;
|
|
46
|
+
return serialized;
|
|
47
|
+
}
|
|
48
|
+
async export(config) {
|
|
49
|
+
const cfg = {
|
|
50
|
+
...this.cfg,
|
|
51
|
+
...config,
|
|
52
|
+
// NEVER generate markers when exporting a function
|
|
53
|
+
addMarker: false,
|
|
54
|
+
};
|
|
55
|
+
if (typeof cfg.functionName !== "string" || cfg.functionName.length === 0) {
|
|
56
|
+
throw new Error("Compiler::export - invalid function name in export options");
|
|
57
|
+
}
|
|
58
|
+
const astCompiler = new AstCompiler(cfg, this.io, this.diagnostics);
|
|
59
|
+
const program = await astCompiler.export(cfg.functionName, cfg.entry);
|
|
60
|
+
if (this.diagnostics.length > 0) {
|
|
61
|
+
let msg;
|
|
62
|
+
globalThis.console && console.log(this.diagnostics);
|
|
63
|
+
const fstErrorMsg = this.diagnostics[0].toString();
|
|
64
|
+
const nDiags = this.diagnostics.length;
|
|
65
|
+
while (msg = this.diagnostics.shift()) {
|
|
66
|
+
this.io.stdout.write(msg.toString() + "\n");
|
|
67
|
+
}
|
|
68
|
+
throw new Error("compilation failed with " + nDiags + " diagnostic messages; first message: " + fstErrorMsg);
|
|
69
|
+
}
|
|
70
|
+
// backend starts here
|
|
71
|
+
const ir = compileTypedProgram(cfg, program);
|
|
72
|
+
const uplc = compileIRToUPLC(ir, cfg);
|
|
73
|
+
const serialized = compileUPLC(new UPLCProgram(cfg.targetUplcVersion, uplc)).toBuffer().buffer;
|
|
74
|
+
const outDir = cfg.outDir;
|
|
75
|
+
const outPath = outDir + (outDir.endsWith("/") ? "" : "/") + "out.flat";
|
|
76
|
+
this.io.writeFile(outPath, serialized, cfg.root);
|
|
77
|
+
this.io.stdout.write(`compiled program written to ${outPath}\n`);
|
|
78
|
+
__VERY_UNSAFE_FORGET_IRHASH_ONLY_USE_AT_END_OF_UPLC_COMPILATION();
|
|
79
|
+
return serialized;
|
|
47
80
|
}
|
|
48
81
|
}
|
|
@@ -119,7 +119,7 @@ export class ExpressifyCtx {
|
|
|
119
119
|
const result = (this._getNonHoistedVariable(name)
|
|
120
120
|
?? this.hoisted.get(name));
|
|
121
121
|
if (!result) {
|
|
122
|
-
console.log(this.allVariables());
|
|
122
|
+
console.log("[error log]: allVariables", this.allVariables());
|
|
123
123
|
throw new Error(`variable '${name}' not found in the context`);
|
|
124
124
|
}
|
|
125
125
|
return result;
|
|
@@ -41,6 +41,8 @@ import { TirCallExpr } from "../../tir/expressions/TirCallExpr.js";
|
|
|
41
41
|
import { TirNativeFunc } from "../../tir/expressions/TirNativeFunc.js";
|
|
42
42
|
export function expressify(func, loopReplacements, program, parentCtx = undefined) {
|
|
43
43
|
const ctx = new ExpressifyCtx(parentCtx, func.returnType, program);
|
|
44
|
+
// define in case of recursion
|
|
45
|
+
ctx.setFuncParam(func.name, func.type);
|
|
44
46
|
ctx.introduceFuncParams(func.params);
|
|
45
47
|
func.body.stmts = [
|
|
46
48
|
new TirReturnStmt(expressifyFuncBody(ctx, func.body.stmts, loopReplacements), func.body.range)
|
|
@@ -384,7 +384,7 @@ function expressifyMethodCall(ctx, methodCall) {
|
|
|
384
384
|
throw new Error(`Cannot call method '${methodName}' on non-struct type '${objectType.toString()}'`);
|
|
385
385
|
}
|
|
386
386
|
function expressifyListMethodCall(ctx, objectExpr, methodCall, methodName, listType, exprRange) {
|
|
387
|
-
const elemsType = getListTypeArg(listType);
|
|
387
|
+
const elemsType = getUnaliased(getListTypeArg(listType));
|
|
388
388
|
if (!elemsType)
|
|
389
389
|
throw new Error("Invalid list type");
|
|
390
390
|
if (methodName === "length") {
|
|
@@ -432,22 +432,46 @@ function expressifyListMethodCall(ctx, objectExpr, methodCall, methodName, listT
|
|
|
432
432
|
// console.log( finalType );
|
|
433
433
|
return new TirCallExpr(TirNativeFunc._findSopOptional(elemsType), [methodCall.args[0], objectExpr], methodCall.type, exprRange);
|
|
434
434
|
}
|
|
435
|
+
if (methodName === "filter") {
|
|
436
|
+
if (methodCall.args.length !== 1)
|
|
437
|
+
throw new Error(`Method 'filter' of type 'list' takes 1 argument, ${methodCall.args.length} provided`);
|
|
438
|
+
return new TirCallExpr(TirNativeFunc._filter(elemsType), [methodCall.args[0], objectExpr], methodCall.type, exprRange);
|
|
439
|
+
}
|
|
440
|
+
if (methodName === "prepend") {
|
|
441
|
+
if (methodCall.args.length !== 1)
|
|
442
|
+
throw new Error(`Method 'prepend' of type 'list' takes 1 argument, ${methodCall.args.length} provided`);
|
|
443
|
+
return new TirCallExpr(TirNativeFunc.mkCons(elemsType), [methodCall.args[0], objectExpr], methodCall.type, exprRange);
|
|
444
|
+
}
|
|
445
|
+
if (methodName === "map") {
|
|
446
|
+
if (methodCall.args.length !== 1)
|
|
447
|
+
throw new Error(`Method 'map' of type 'list' takes 1 argument, ${methodCall.args.length} provided`);
|
|
448
|
+
const arg = methodCall.args[0];
|
|
449
|
+
const argFuncType = getUnaliased(arg.type);
|
|
450
|
+
if (!(argFuncType instanceof TirFuncT))
|
|
451
|
+
throw new Error(`Argument 1 of method 'map' of type 'list' must be a function, got '${arg.type.toString()}'`);
|
|
452
|
+
const mapReturnT = argFuncType.returnType;
|
|
453
|
+
const elemTypeTirName = elemsType.toTirTypeKey();
|
|
454
|
+
let base_mapToType = _base_mapToType_cache.get(elemTypeTirName)?.clone();
|
|
455
|
+
if (!base_mapToType) {
|
|
456
|
+
base_mapToType = new TirHoistedExpr("_map_to_list_of_" + elemTypeTirName, new TirCallExpr(TirNativeFunc._mkMap(elemsType, mapReturnT), [new TirLitArrExpr([], new TirListT(mapReturnT), SourceRange.unknown)], new TirFuncT([
|
|
457
|
+
// mapping function
|
|
458
|
+
new TirFuncT([
|
|
459
|
+
elemsType
|
|
460
|
+
], mapReturnT),
|
|
461
|
+
// list to map over
|
|
462
|
+
new TirListT(elemsType)
|
|
463
|
+
], new TirListT(mapReturnT)), SourceRange.unknown));
|
|
464
|
+
base_mapToType.varName; // precompute hash and symbol
|
|
465
|
+
_base_mapToType_cache.set(elemTypeTirName, base_mapToType.clone());
|
|
466
|
+
}
|
|
467
|
+
return new TirCallExpr(base_mapToType, [methodCall.args[0], objectExpr], methodCall.type, exprRange);
|
|
468
|
+
}
|
|
435
469
|
// TODO
|
|
436
470
|
/*
|
|
437
471
|
{
|
|
438
|
-
isEmpty: new TirFuncT( [], bool_t ),
|
|
439
472
|
show: new TirFuncT( [], bytes_t ),
|
|
440
473
|
reverse: new TirFuncT( [], new TirListT( elemsType ) ),
|
|
441
|
-
find: new TirFuncT([
|
|
442
|
-
new TirFuncT( [elemsType], bool_t )
|
|
443
|
-
], new TirSopOptT( elemsType ) ),
|
|
444
|
-
filter: new TirFuncT([
|
|
445
|
-
new TirFuncT( [elemsType], bool_t )
|
|
446
|
-
], new TirListT( elemsType ) ),
|
|
447
|
-
prepend: new TirFuncT( [elemsType], new TirListT( elemsType ) ),
|
|
448
|
-
map: new TirFuncT([
|
|
449
|
-
new TirFuncT([ elemsType ], mapReturnT )
|
|
450
|
-
], new TirListT( mapReturnT ) ),
|
|
451
474
|
};
|
|
452
475
|
*/
|
|
453
476
|
}
|
|
477
|
+
const _base_mapToType_cache = new Map();
|
|
@@ -84,12 +84,12 @@ export declare class TirNativeFunc implements ITirExpr {
|
|
|
84
84
|
static _dropList(elemT: TirType): TirNativeFunc;
|
|
85
85
|
static _foldr(elemT: TirType, returnT: TirType): TirNativeFunc;
|
|
86
86
|
static _foldl(elemT: TirType, returnT: TirType): TirNativeFunc;
|
|
87
|
-
static _mkFindDataOptional(elems_t: TirType): TirNativeFunc;
|
|
88
87
|
static _findSopOptional(elems_t: TirType): TirNativeFunc;
|
|
89
88
|
static _length(elemT: TirType): TirNativeFunc;
|
|
90
89
|
static _some(elemT: TirType): TirNativeFunc;
|
|
91
90
|
static _every(elemT: TirType): TirNativeFunc;
|
|
92
|
-
static
|
|
91
|
+
static _filter(elemT: TirType): TirNativeFunc;
|
|
92
|
+
static _mkMap(elemT: TirType, returnElemT: TirType): TirNativeFunc;
|
|
93
93
|
static _id(t: TirType): TirNativeFunc;
|
|
94
94
|
static get _not(): TirNativeFunc;
|
|
95
95
|
static get _strictAnd(): TirNativeFunc;
|
|
@@ -663,16 +663,19 @@ export class TirNativeFunc {
|
|
|
663
663
|
new TirListT(elemT)
|
|
664
664
|
], returnT));
|
|
665
665
|
}
|
|
666
|
-
static _mkFindDataOptional(elems_t) {
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
666
|
+
// static _mkFindDataOptional(elems_t: TirType): TirNativeFunc {
|
|
667
|
+
// return new TirNativeFunc(
|
|
668
|
+
// IRNativeTag._mkFindDataOptional,
|
|
669
|
+
// new TirFuncT([
|
|
670
|
+
// // elem -> data
|
|
671
|
+
// new TirFuncT([ elems_t ], data_t),
|
|
672
|
+
// // elem -> bool (predicate)
|
|
673
|
+
// new TirFuncT([ elems_t ], bool_t),
|
|
674
|
+
// // List<elem>
|
|
675
|
+
// new TirListT(elems_t)
|
|
676
|
+
// ], new TirDataOptT(elems_t))
|
|
677
|
+
// );
|
|
678
|
+
// }
|
|
676
679
|
static _findSopOptional(elems_t) {
|
|
677
680
|
return new TirNativeFunc(IRNativeTag._findSopOptional, new TirFuncT([
|
|
678
681
|
// predicate: (elemT) => bool
|
|
@@ -705,10 +708,8 @@ export class TirNativeFunc {
|
|
|
705
708
|
new TirListT(elemT)
|
|
706
709
|
], bool_t));
|
|
707
710
|
}
|
|
708
|
-
static
|
|
709
|
-
return new TirNativeFunc(IRNativeTag.
|
|
710
|
-
// pnilOfType: an empty list with the right element type
|
|
711
|
-
new TirListT(elemT),
|
|
711
|
+
static _filter(elemT) {
|
|
712
|
+
return new TirNativeFunc(IRNativeTag._filter, new TirFuncT([
|
|
712
713
|
// predicate
|
|
713
714
|
new TirFuncT([
|
|
714
715
|
elemT
|
|
@@ -717,6 +718,18 @@ export class TirNativeFunc {
|
|
|
717
718
|
new TirListT(elemT)
|
|
718
719
|
], new TirListT(elemT)));
|
|
719
720
|
}
|
|
721
|
+
static _mkMap(elemT, returnElemT) {
|
|
722
|
+
return new TirNativeFunc(IRNativeTag._mkMapList, new TirFuncT([
|
|
723
|
+
// nil of return elem type
|
|
724
|
+
new TirListT(returnElemT),
|
|
725
|
+
// mapping function
|
|
726
|
+
new TirFuncT([
|
|
727
|
+
elemT
|
|
728
|
+
], returnElemT),
|
|
729
|
+
// list to map over
|
|
730
|
+
new TirListT(elemT)
|
|
731
|
+
], new TirListT(returnElemT)));
|
|
732
|
+
}
|
|
720
733
|
static _id(t) {
|
|
721
734
|
return new TirNativeFunc(IRNativeTag._id, new TirFuncT([t], t));
|
|
722
735
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { BitStream } from "@harmoniclabs/bitstream";
|
|
2
|
-
import BitUtils from "../BitUtils/index.js";
|
|
3
2
|
import { assert } from "../assert.js";
|
|
3
|
+
import { BitUtils } from "../BitUtils/index.js";
|
|
4
4
|
export function isInByteOffset(offset) {
|
|
5
5
|
return (offset === 0 ||
|
|
6
6
|
offset === 1 ||
|
|
@@ -14,7 +14,7 @@ export function isInByteOffset(offset) {
|
|
|
14
14
|
/**
|
|
15
15
|
* @static
|
|
16
16
|
*/
|
|
17
|
-
export
|
|
17
|
+
export class UPLCFlatUtils {
|
|
18
18
|
/**
|
|
19
19
|
* @deprecated this is a @static class, it is not supposed to have instances
|
|
20
20
|
*/
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@harmoniclabs/pebble",
|
|
3
|
-
"version": "0.1.0-
|
|
3
|
+
"version": "0.1.0-dev8",
|
|
4
4
|
"description": "A simple, yet rock solid, functional language with an imperative bias, targeting UPLC",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"types": "./dist/index.d.ts",
|
|
@@ -52,14 +52,14 @@
|
|
|
52
52
|
"dependencies": {
|
|
53
53
|
"@harmoniclabs/bigint-utils": "^1.0.0",
|
|
54
54
|
"@harmoniclabs/bytestring": "^1.0.0",
|
|
55
|
-
"@harmoniclabs/cbor": "^1.6.
|
|
56
|
-
"@harmoniclabs/crypto": "^0.
|
|
55
|
+
"@harmoniclabs/cbor": "^1.6.6",
|
|
56
|
+
"@harmoniclabs/crypto": "^0.3.0",
|
|
57
57
|
"@harmoniclabs/obj-utils": "^1.0.0",
|
|
58
58
|
"@harmoniclabs/pair": "^1.0.0",
|
|
59
|
-
"@harmoniclabs/plutus-data": "^1.2.
|
|
60
|
-
"@harmoniclabs/plutus-machine": "^2.1.
|
|
59
|
+
"@harmoniclabs/plutus-data": "^1.2.6",
|
|
60
|
+
"@harmoniclabs/plutus-machine": "^2.1.1",
|
|
61
61
|
"@harmoniclabs/uint8array-utils": "^1.0.4",
|
|
62
|
-
"@harmoniclabs/uplc": "^1.4.
|
|
62
|
+
"@harmoniclabs/uplc": "^1.4.1"
|
|
63
63
|
},
|
|
64
64
|
"devDependencies": {
|
|
65
65
|
"@babel/preset-env": "^7.18.6",
|