@harmoniclabs/plu-ts-onchain
Version:
An embedded DSL for Cardano smart contracts creation coupled with a library for Cardano transactions, all in Typescript
154 lines (132 loc) • 6.44 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.pfn = void 0;
var BasePlutsError_1 = require("../../utils/BasePlutsError.js");
var assert_1 = require("../../utils/assert.js");
var types_1 = require("../type_system/types.js");
var plam_1 = require("./plam.js");
var combinators_1 = require("../../utils/combinators.js");
var getCallStackAt_1 = require("../../utils/getCallStackAt/index.js");
function pfn(inputsTypes, outputType) {
function plamNCurried(curriedFn, nMissingArgs, func_name) {
if (nMissingArgs === 1)
return (0, plam_1.plam)(inputsTypes[inputsTypes.length - 1], outputType)(curriedFn, func_name);
var currentInputIndex = inputsTypes.length - nMissingArgs;
return (0, plam_1.plam)(inputsTypes[currentInputIndex], (0, types_1.fn)(inputsTypes.slice(currentInputIndex + 1), outputType))(function (someInput) { return plamNCurried(curriedFn(someInput), nMissingArgs - 1, func_name); }, func_name !== null && func_name !== void 0 ? func_name : "curried_lam");
}
return (function (termFunction, funcName) {
var _a;
if (termFunction.length <= 0)
throw new BasePlutsError_1.BasePlutsError("'(void) => any' cannot be translated to a Pluts function");
(0, assert_1.assert)(termFunction.length === inputsTypes.length, "number of inputs of the function doesn't match the number of types specified for the input");
var func_name = undefined;
func_name =
typeof funcName === "string" ? funcName :
termFunction.name !== "" ? termFunction.name :
(_a = (0, getCallStackAt_1.getCallStackAt)(3, {
tryGetNameAsync: true,
onNameInferred: function (inferred) { return func_name = inferred; }
})) === null || _a === void 0 ? void 0 : _a.inferredName;
return plamNCurried((0, combinators_1.curry)(termFunction), termFunction.length, func_name);
});
}
exports.pfn = pfn;
/*
export function pfn<InputsTypes extends [ TermType, ...TermType[] ], OutputType extends TermType>( inputsTypes: InputsTypes, outputType: OutputType )
: ( termFunction: TsTermFunction<InputsTypes,OutputType> ) =>
TermFnFromTypes<InputsTypes, OutputType>
{
function plamNCurried(
curriedFn:
CurriedFn<
ToTermArrNonEmpty<InputsTypes>,
Term<ToPType<OutputType>>
>,
nMissingArgs: number
): TermFnFromTypes<InputsTypes, OutputType>
{
if( nMissingArgs === 1 )
return plam( inputsTypes[ inputsTypes.length - 1 ], outputType )
( curriedFn as any ) as any;
const currentInputIndex = inputsTypes.length - nMissingArgs;
return plam(
inputsTypes[ currentInputIndex ],
fn( inputsTypes.slice( currentInputIndex + 1 ) as [ TermType, ...TermType[] ], outputType ) as any
)(
( someInput: Term<PType> ) => plamNCurried( curriedFn( someInput ) as any , nMissingArgs - 1 )
) as any;
}
return ((
termFunction: ( ...args: ToTermArrNonEmpty<InputsTypes> ) => Term<ToPType<OutputType>>,
funcName?: string
) =>
{
if( termFunction.length <= 0 )
throw new BasePlutsError("'(void) => any' cannot be translated to a Pluts function");
assert(
termFunction.length === inputsTypes.length,
"number of inputs of the function doesn't match the number of types specified for the input"
);
let func_name: string | undefined = undefined;
func_name =
typeof funcName === "string" ? funcName :
termFunction.name !== "" ? termFunction.name :
getCallStackAt( 3, {
tryGetNameAsync: true,
onNameInferred: inferred => func_name = inferred
})?.inferredName;
const lambdaTerm = new Term<PLam<PType,PType>>(
fn( inputsTypes, outputType ) as any,
dbn => {
const thisLambdaPtr = dbn + BigInt( 1 );
const boundVars = inputsTypes.map( inT => {
const boundVar = new Term<PType>(
inT,
dbnAccessLevel => new IRVar( dbnAccessLevel - thisLambdaPtr )
);
return addUtilityForType( inT )( boundVar );
});
const body = termFunction( ...boundVars as any );
// here the debruijn level is incremented
return new IRFunc( termFunction.length, body.toIR( cfg, thisLambdaPtr ), func_name );
}
);
defineReadOnlyHiddenProperty(
lambdaTerm, "unsafeWithInputOfType",
( inT: TermType ) => {
const newInsTys = inputsTypes.map( cloneTermType );
newInsTys[0] = inT;
return new Term<PLam<PType,PType>>(
fn( newInsTys as any, outputType ) as any,
(cfg, dbn) => {
const thisLambdaPtr = dbn + BigInt( 1 );
const boundVars = inputsTypes.map( inT => {
const boundVar = new Term<PType>(
inT,
(cfg, dbnAccessLevel) => new IRVar( dbnAccessLevel - thisLambdaPtr )
);
defineReadOnlyHiddenProperty(
boundVar,
"__isDynamicPair",
includesDynamicPairs( inT )
);
return addUtilityForType( inT )( boundVar );
});
const body = termFunction( ...boundVars as any );
// here the debruijn level is incremented
return new IRFunc( termFunction.length, body.toIR( cfg, thisLambdaPtr ), func_name );
}
);
}
)
// allows ```lambdaTerm.$( input )``` syntax
// rather than ```papp( lambdaTerm, input )```
// preserving Term Type
return defineReadOnlyProperty(
lambdaTerm,
"$",
( input: Term<PType> ) => papp( lambdaTerm, input )
) as any;
}) as any;
}
//*/