UNPKG

@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
"use strict"; 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))); }); }