@harmoniclabs/plu-ts-onchain
Version:
An embedded DSL for Cardano smart contracts creation coupled with a library for Cardano transactions, all in Typescript
118 lines (117 loc) • 5.49 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.pmatchSop = void 0;
var obj_utils_1 = require("@harmoniclabs/obj-utils");
var capitalize_1 = require("../../../utils/capitalize.js");
var Term_1 = require("../../Term/index.js");
var isWellFormedType_1 = require("../../type_system/kinds/isWellFormedType.js");
var types_1 = require("../../type_system/types.js");
var IRCase_1 = require("../../../IR/IRNodes/IRCase.js");
var addUtilityForType_1 = require("../std/UtilityTerms/addUtilityForType.js");
var makeMockUtilityTerm_1 = require("../std/UtilityTerms/mockUtilityTerms/makeMockUtilityTerm.js");
var IRFunc_1 = require("../../../IR/IRNodes/IRFunc.js");
var IR_1 = require("../../../IR/index.js");
function pmatchSop(sopTerm) {
var sDef = sopTerm.type[1];
if (!(0, isWellFormedType_1.isSopDefinition)(sDef)) {
console.log(sopTerm, sopTerm.type);
/**
* @todo add proper error
*/
throw new Error("unexpected struct type while running 'pmatch'; " +
"\ntype expected to be a 'ConstantableStructDefiniton' was: " // + termTypeToString( sopTerm.type )
);
}
var ctors = Object.keys(sDef);
var continuationTerms = ctors.map(function (_ctorName) { return undefined; });
function indexOfCtor(ctor) {
var res = ctors.indexOf(ctor);
if (res < 0) {
throw new Error("internal function 'indexOfCtor' in 'definePMatchPermutations' couldn't find the constructor \"" + ctor +
"\" between [" + ctors.map(function (c) { return c.toString(); }).join(',') + ']');
}
return res;
}
function permutations(missingCtors) {
if (missingCtors.length <= 0)
return {};
// last permutation
// returns the final expression
if (missingCtors.length === 1) {
var ctor_1 = missingCtors[0];
var idx_1 = indexOfCtor(ctor_1);
var ctorDef_1 = sDef[ctor_1];
var matcher = "on" + (0, capitalize_1.capitalize)(ctor_1);
var result = {};
(0, obj_utils_1.defineReadOnlyProperty)(result, matcher, function (cb) {
var returnT = cb(mockSopInstance(ctorDef_1)).type;
var contTerm = makeConstrContinuationTerm(ctorDef_1, cb);
// same stuff of previous ctors
continuationTerms[idx_1] = contTerm;
return new Term_1.Term(returnT, function (cfg, dbn) { return new IRCase_1.IRCase(sopTerm.toIR(cfg, dbn), continuationTerms.map(function (term) { return term.toIR(cfg, dbn); })); });
});
return (0, obj_utils_1.defineReadOnlyProperty)(result, "_", result[matcher]);
}
var remainingCtorsObj = {};
// here add all the missing ctors contiunuations
missingCtors.forEach(function (ctor) {
var idx = indexOfCtor(ctor);
(0, obj_utils_1.defineReadOnlyProperty)(remainingCtorsObj, "on" + (0, capitalize_1.capitalize)(ctor), function (cb) {
continuationTerms[idx] = makeConstrContinuationTerm(sDef[ctor], cb);
return permutations(missingCtors.filter(function (c) { return c !== ctor; }));
});
});
return (0, obj_utils_1.defineReadOnlyProperty)(remainingCtorsObj, "_", function (cb) {
var returnT = cb(mockSopInstance(sDef[ctors[0]])).type;
for (var i = 0; i < continuationTerms.length; i++) {
if (typeof continuationTerms[i] === "undefined") {
continuationTerms[i] = makeConstrContinuationTerm(sDef[ctors[i]], cb);
}
}
return new Term_1.Term(returnT, function (cfg, dbn) { return new IRCase_1.IRCase(sopTerm.toIR(cfg, dbn), continuationTerms.map(function (term) { return term.toIR(cfg, dbn); })); });
;
});
}
return permutations(ctors);
}
exports.pmatchSop = pmatchSop;
function mockSopInstance(ctorDef) {
var fields = Object.keys(ctorDef);
var result = {};
for (var i = 0; i < fields.length; i++) {
var field = fields[i];
Object.defineProperty(result, field, {
value: (0, makeMockUtilityTerm_1.makeMockUtilityTerm)(ctorDef[field]),
writable: false,
enumerable: true,
configurable: false
});
}
return result;
}
function makeConstrContinuationTerm(ctorDef, cb) {
var returnT = cb(mockSopInstance(ctorDef)).type;
var fields = Object.keys(ctorDef);
var nFields = fields.length;
if (nFields === 0)
return cb({});
return new Term_1.Term((0, types_1.fn)(fields.map(function (f) { return ctorDef[f]; }), returnT), function (cfg, dbn) {
var fstArgLambdaPtr = dbn + BigInt(1);
var sInstance = {};
var _loop_1 = function (i) {
var f = fields[i];
var t = ctorDef[f];
Object.defineProperty(sInstance, f, {
value: (0, addUtilityForType_1.addUtilityForType)(t)(new Term_1.Term(t, function (cfg, dbnAccessLevel) { return new IR_1.IRVar(dbnAccessLevel - (fstArgLambdaPtr + BigInt(i))); })),
writable: false,
enumerable: true,
configurable: false
});
};
for (var i = 0; i < nFields; i++) {
_loop_1(i);
}
var body = cb(sInstance);
return new IRFunc_1.IRFunc(nFields, body.toIR(cfg, dbn + BigInt(nFields)));
});
}