UNPKG

@harmoniclabs/plu-ts-onchain

Version:

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

126 lines (125 loc) 7.27 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.compileIRToUPLC = void 0; var IRLetted_1 = require("../IRNodes/IRLetted.js"); var IRHoisted_1 = require("../IRNodes/IRHoisted.js"); var IRConst_1 = require("../IRNodes/IRConst.js"); var _irToUplc_1 = require("./_internal/_irToUplc.js"); var includesNode_1 = require("./_internal/includesNode.js"); var handleLetted_1 = require("./subRoutines/handleLetted/index.js"); var handleHoistedAndReturnRoot_1 = require("./subRoutines/handleHoistedAndReturnRoot/index.js"); var replaceNatives_1 = require("./subRoutines/replaceNatives/index.js"); var replaceClosedLettedWithHoisted_1 = require("./subRoutines/replaceClosedLettedWithHoisted.js"); var hoistForcedNatives_1 = require("./subRoutines/hoistForcedNatives.js"); var handleRecursiveTerms_1 = require("./subRoutines/handleRecursiveTerms.js"); var CompilerOptions_1 = require("./CompilerOptions.js"); var replaceHoistedWithLetted_1 = require("./subRoutines/replaceHoistedWithLetted.js"); var IRNodes_1 = require("../IRNodes/index.js"); var replaceForcedNativesWithHoisted_1 = require("./subRoutines/replaceForcedNativesWithHoisted.js"); var performUplcOptimizationsAndReturnRoot_1 = require("./subRoutines/performUplcOptimizationsAndReturnRoot/index.js"); function compileIRToUPLC(term, paritalOptions) { if (paritalOptions === void 0) { paritalOptions = CompilerOptions_1.defaultOptions; } // most of the time we are just compiling small // pre-execuded terms (hence constants) if (term instanceof IRConst_1.IRConst) return (0, _irToUplc_1._irToUplc)(term).term; /////////////////////////////////////////////////////////////////////////////// // ------------------------------------------------------------------------- // // --------------------------------- init --------------------------------- // // ------------------------------------------------------------------------- // /////////////////////////////////////////////////////////////////////////////// var options = (0, CompilerOptions_1.completeCompilerOptions)(paritalOptions); // unwrap top level letted and hoisted; while (term instanceof IRLetted_1.IRLetted || term instanceof IRHoisted_1.IRHoisted) { // replace with value term = term instanceof IRLetted_1.IRLetted ? term.value : term.hoisted; // forget the parent; this is the new root term.parent = undefined; } // _makeAllNegativeNativesHoisted( term ); /////////////////////////////////////////////////////////////////////////////// // ------------------------------------------------------------------------- // // ----------------------------- optimizations ----------------------------- // // ------------------------------------------------------------------------- // /////////////////////////////////////////////////////////////////////////////// // --------------------------- optimize natives --------------------------- // // at constant -> head and tails // --------------------- optimize recursive functions --------------------- // // avoid passing whole structs // take letted terms outside // ----------------------- optimize normal functions ----------------------- // // avoid passing whole structs // reorganize function arguments to take advantage of partial applicaiton /////////////////////////////////////////////////////////////////////////////// // ------------------------------------------------------------------------- // // ------------------------------ final steps ------------------------------ // // ------------------------------------------------------------------------- // /////////////////////////////////////////////////////////////////////////////// term = (0, replaceNatives_1.replaceNativesAndReturnRoot)(term); // unwrap top level letted and hoisted; // some natives may be converted to hoisted; // this is really just an edge case while (term instanceof IRLetted_1.IRLetted || term instanceof IRHoisted_1.IRHoisted) { // replace with value term = term instanceof IRLetted_1.IRLetted ? term.value : term.hoisted; // forget the parent; this is the new root term.parent = undefined; } if (term instanceof IRNodes_1.IRNative || term instanceof IRConst_1.IRConst // while we are at it ) return (0, _irToUplc_1._irToUplc)(term).term; if (options.delayHoists) (0, replaceForcedNativesWithHoisted_1.replaceForcedNativesWithHoisted)(term); if (options.delayHoists) (0, replaceHoistedWithLetted_1.replaceHoistedWithLetted)(term); else (0, replaceClosedLettedWithHoisted_1.replaceClosedLettedWithHoisted)(term); // handle letted before hoisted because the tree is smaller // and we also have less letted dependecies to handle term = (0, handleLetted_1.handleLettedAndReturnRoot)(term); term = (0, handleHoistedAndReturnRoot_1.handleHoistedAndReturnRoot)(term); // replaced hoisted terms might include new letted terms while ((0, includesNode_1.includesNode)(term, function (node) { return node instanceof IRLetted_1.IRLetted || node instanceof IRHoisted_1.IRHoisted; })) { term = (0, handleLetted_1.handleLettedAndReturnRoot)(term); term = (0, handleHoistedAndReturnRoot_1.handleHoistedAndReturnRoot)(term); } /////////////////////////////////////////////////////////////////////////////// // ------------------------------------------------------------------------- // // --------------------------- translate to UPLC --------------------------- // // ------------------------------------------------------------------------- // /////////////////////////////////////////////////////////////////////////////// // introduces new hoisted terms // however we cannot do this before // because in order to hanlde letted at the best // we need to know where the `IRRecursive` nodes are term = (0, handleRecursiveTerms_1.handleRootRecursiveTerm)(term); // if( options.delayHoists ) replaceHoistedWithLetted( term ); // handle new hoisted terms term = (0, handleHoistedAndReturnRoot_1.handleHoistedAndReturnRoot)(term); // strictly necessary to check the options // otherwise forced natives where already hoisted // will be re-hosited; causeing uselsess evaluations if (!options.delayHoists) term = (0, hoistForcedNatives_1.hoistForcedNatives)(term); // at this point we expect the IR to be translable 1:1 to UPLC term = (0, performUplcOptimizationsAndReturnRoot_1.performUplcOptimizationsAndReturnRoot)(term, options); if (options.addMarker && options.targetUplcVersion.major >= 1 && options.targetUplcVersion.minor >= 1 && options.targetUplcVersion.patch >= 0) { term = new IRNodes_1.IRCase(new IRNodes_1.IRConstr(0, []), [ term, // never evaluated IRConst_1.IRConst.int(42) ]); } var srcmap = {}; var uplc = (0, _irToUplc_1._irToUplc)(term, srcmap).term; // console.log( "srcmap", srcmap ); return uplc; } exports.compileIRToUPLC = compileIRToUPLC;