UNPKG

@harmoniclabs/plu-ts-onchain

Version:

An embedded DSL for Cardano smart contracts creation coupled with a library for Cardano transactions, all in Typescript

207 lines (206 loc) 9.73 kB
"use strict"; var __read = (this && this.__read) || function (o, n) { var m = typeof Symbol === "function" && o[Symbol.iterator]; if (!m) return o; var i = m.call(o), r, ar = [], e; try { while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value); } catch (error) { e = { error: error }; } finally { try { if (r && !r.done && (m = i["return"])) m.call(i); } finally { if (e) throw e.error; } } return ar; }; var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) { if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) { if (ar || !(i in from)) { if (!ar) ar = Array.prototype.slice.call(from, 0, i); ar[i] = from[i]; } } return to.concat(ar || Array.prototype.slice.call(from)); }; Object.defineProperty(exports, "__esModule", { value: true }); exports.pmatchStruct = void 0; var obj_utils_1 = require("@harmoniclabs/obj-utils"); var plutus_data_1 = require("@harmoniclabs/plutus-data"); var old_1 = require("../plet/old.js"); var types_1 = require("../../type_system/types.js"); var Term_1 = require("../../Term/index.js"); var minimal_1 = require("../plet/minimal.js"); var minimal_2 = require("../punsafeConvertType/minimal.js"); var fromData_minimal_1 = require("../std/data/conversion/fromData_minimal.js"); var isWellFormedType_1 = require("../../type_system/kinds/isWellFormedType.js"); var papp_1 = require("../papp.js"); var matchSingleCtorStruct_1 = require("./matchSingleCtorStruct.js"); var IRConst_1 = require("../../../IR/IRNodes/IRConst.js"); var plam_1 = require("../plam.js"); var matchNCtors_1 = require("./matchNCtors.js"); var addUtilityForType_1 = require("../std/UtilityTerms/addUtilityForType.js"); var getElemAtTerm_1 = require("./getElemAtTerm.js"); var utils_1 = require("../../type_system/utils.js"); var capitalize_1 = require("../../../utils/capitalize.js"); var punsafeConvertType_1 = require("../punsafeConvertType/index.js"); var IR_1 = require("../../../IR/index.js"); function getReturnTypeFromContinuation(cont, ctorDef) { return cont( // mock the fields // we are not really interested in the result here; only in the type new Term_1.Term((0, types_1.list)(types_1.data), function (_dbn) { return IRConst_1.IRConst.listOf(types_1.data)((new Array(Object.keys(ctorDef).length)) .fill(new plutus_data_1.DataI(0))); })).type; } /** * * @param structData * @param sDef * @param ctorCbs * * @returns the term that matches the ctor */ function hoistedMatchCtors(structData, sDef, ctorCbs, cbsReturnT) { var _a; var length = ctorCbs.length; if (length <= 0) throw new Error("trying to match ill formed struct"); // const returnT = tyVar("single_ctor_match_return_type"); var ctors = Object.keys(sDef); if (length === 1) { var cont_1 = ctorCbs[0]; if (cont_1 instanceof Term_1.Term) { if (cont_1.type[0] !== types_1.PrimType.Lambda) { // todo: add proper error throw new Error("pmatch continuation was not a lambda"); } return (0, papp_1.papp)(cont_1, (0, papp_1.papp)(matchSingleCtorStruct_1.getFields, structData)); } var thisCtorDef_1 = sDef[ctors[0]]; var returnT_1 = cbsReturnT !== null && cbsReturnT !== void 0 ? cbsReturnT : getReturnTypeFromContinuation(cont_1, thisCtorDef_1); return (0, papp_1.papp)((0, plam_1.plam)((0, types_1.list)(types_1.data), returnT_1)(cont_1), (0, papp_1.papp)(matchSingleCtorStruct_1.getFields, structData)); } // multiple ctors struct case var ctorIdx = 0; var cont = (_a = ctorCbs.find(function (cb, i) { if (typeof cb === "function") { ctorIdx = i; return true; } return false; })) !== null && _a !== void 0 ? _a : ctorCbs[0]; var thisCtorDef = sDef[Object.keys(sDef)[ctorIdx]]; var returnT = cbsReturnT !== null && cbsReturnT !== void 0 ? cbsReturnT : (cont instanceof Term_1.Term ? cont.type[2] : getReturnTypeFromContinuation(cont, thisCtorDef)); var result = (0, papp_1.papp)((0, matchNCtors_1.matchNCtorsIdxs)(ctors.length, returnT), structData); for (var i = ctors.length - 1; i >= 0; i--) { var thisCont = ctorCbs[i]; var thisCtorDef_2 = sDef[ctors[i]]; result = (0, papp_1.papp)(result, thisCont instanceof Term_1.Term ? thisCont : (0, plam_1.plam)((0, types_1.list)(types_1.data), returnT !== null && returnT !== void 0 ? returnT : getReturnTypeFromContinuation(thisCont, thisCtorDef_2))(thisCont)); } return result; } function getStructInstance(fieldsList, ctorDef) { var instance = {}; var fieldNames = Object.keys(ctorDef); for (var i = 0; i < fieldNames.length; i++) { var fieldName = fieldNames[i]; var fieldType = ctorDef[fieldName]; Object.defineProperty(instance, fieldName, { value: (0, addUtilityForType_1.addUtilityForType)(fieldType)((0, minimal_2._punsafeConvertType)((0, minimal_1._plet)((0, fromData_minimal_1._fromData)(fieldType)((0, getElemAtTerm_1.getElemAtTerm)(i).$(fieldsList))), fieldType)), writable: false, enumerable: true, configurable: false }); } return instance; } function pmatchStruct(struct) { var sDef = struct.type[1]; if (!(0, isWellFormedType_1.isStructDefinition)(sDef)) { /** * @todo add proper error */ throw new Error("unexpected struct type while running 'pmatch'; " + "\ntype expected to be a 'ConstantableStructDefiniton' was: " + (0, utils_1.termTypeToString)(struct.type)); } var ctors = Object.keys(sDef); var ctorCbs = ctors.map(function (_) { return undefined; }); // console.log("matching", ctors); // if( ctors[0] === "PoolStateRef" ) // { // console.log( getCallStackAt( 4 )?.__line__ ); // } 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 matcher = "on" + (0, capitalize_1.capitalize)(ctor_1); var result = {}; (0, obj_utils_1.defineReadOnlyProperty)(result, matcher, function (cb) { // build the `StructInstance` input from the struct fields var callback = function (mathcedCtorsFields) { return cb(getStructInstance(mathcedCtorsFields, sDef[ctor_1])); }; var returnT = cb(getStructInstance(new Term_1.Term((0, types_1.list)(types_1.data), function (_) { return new IR_1.IRVar(0); }), sDef[ctor_1])).type; // same stuff of previous ctors ctorCbs[idx_1] = callback; return hoistedMatchCtors(struct, sDef, ctorCbs, returnT); }); 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) { ctorCbs[idx] = function (fieldsList) { return cb(getStructInstance(fieldsList, sDef[ctor])); }; return permutations(missingCtors.filter(function (c) { return c !== ctor; })); }); }); return (0, obj_utils_1.defineReadOnlyProperty)(remainingCtorsObj, "_", function (cb) { var maxLengthFound = Math.max.apply(Math, __spreadArray([], __read(ctors .map(function (ctor, i) { // only get length if a function was specified return typeof ctorCbs[i] === "function" ? Object.keys(sDef[ctor]).length : -1; })), false)); // .reduce( (prev, curr, i ) => Math.max( prev, curr ) , 0 ); var returnT = getReturnTypeFromContinuation(cb, sDef[ctors[ctors.findIndex(function (ctor) { return Object.keys(sDef[ctor]).length === maxLengthFound; })]]); return (0, old_1._old_plet)((0, plam_1.plam)((0, types_1.list)(types_1.data), returnT)(cb)).in(function (othCtorsContinuation) { for (var i = 0; i < ctorCbs.length; i++) { if (typeof ctorCbs[i] !== "function") { ctorCbs[i] = othCtorsContinuation; } } var res = hoistedMatchCtors( /* Argument of type 'Term<PStruct<SDef>>' is not assignable to parameter of type 'Term<PStruct<StructDefinition>>'. Type 'PStruct<SDef>' is not assignable to type 'PStruct<StructDefinition>'. */ struct, sDef, ctorCbs, returnT); return (0, punsafeConvertType_1.punsafeConvertType)(res, returnT); }); }); } return permutations(ctors); } exports.pmatchStruct = pmatchStruct;