UNPKG

@helios-lang/compiler

Version:

Helios is a Domain Specific Language that compiles to Plutus-Core (i.e. Cardano on-chain validator scripts). Helios is a non-Haskell alternative to Plutus. With this library you can compile Helios scripts and build Cardano transactions, all you need to bu

198 lines (170 loc) 4.58 kB
import { ParametricName } from "./ParametricName.js" import { matchBuiltins } from "./RawFunc.js" import { makeRawFunctions } from "./makeRawFuncs.js" import { wrapWithDefs, TAB } from "./Definitions.js" /** * @import { SourceMappedStringI } from "@helios-lang/ir" * @import { Definitions, RawFuncI, ToIRContextProps } from "../index.js" */ /** * @typedef {import("../index.js").ToIRContextI} ToIRContextI */ /** * @implements {ToIRContextI} */ export class ToIRContext { /** * @readonly * @type {ToIRContextProps} */ props /** * @readonly * @type {string} */ indent /** * @type {Map<string, RawFuncI>} */ _db /** * @param {ToIRContextProps} props * @param {string} indent * @param {Map<string, RawFuncI>} db */ constructor(props, indent = "", db = new Map()) { this.props = props this.indent = indent this._db = db } /** * @type {string | undefined} */ get aliasNamespace() { return this.props?.aliasNamespace } /** * @type {Map<string, RawFuncI>} */ get db() { if (this._db.size == 0) { this._db = makeRawFunctions(this.optimize, this.isTestnet) } return this._db } /** * TODO: rename to isMainnet() * @type {boolean} */ get isTestnet() { return this.props.isTestnet } /** * @type {boolean} */ get optimize() { return this.props.optimize } /** * @type {boolean} */ get paramsSubsitutable() { return this.props.makeParamsSubstitutable ?? false } /** * @returns {ToIRContext} */ tab() { return new ToIRContext(this.props, this.indent + TAB, this._db) } /** * Load all raw generics so all possible implementations can be generated correctly during type parameter injection phase * @returns {Map<string, ((ttp: string[], ftp: string[]) => SourceMappedStringI)>} */ fetchRawGenerics() { /** * @type {Map<string, ((ttp: string[], ftp: string[]) => SourceMappedStringI)>} */ const map = new Map() for (let [k, v] of this.db) { if (ParametricName.matches(k)) { // load without dependencies /** * * @param {string[]} ttp * @param {string[]} ftp * @returns {SourceMappedStringI} */ const fn = (ttp, ftp) => v.toIR(ttp, ftp) map.set(k, fn) } } return map } /** * Doesn't add templates * @param {SourceMappedStringI} ir * @param {Definitions | undefined} [userDefs] - some userDefs might have the __helios prefix * @returns {Definitions} */ fetchRawFunctions(ir, userDefs = undefined) { let [src, _] = ir.toStringWithSourceMap() /** * @type {Definitions} */ const map = new Map() matchBuiltins(src, (m) => { if ( !ParametricName.matches(m) && !map.has(m) && (!userDefs || !userDefs.has(m)) ) { const builtin = this.db.get(m) if (!builtin) { throw new Error(`builtin ${m} not found`) } builtin.load(this.db, map) } }) return map } /** * Appends parent debugging information which should be passed into IR via site.alias * @param {string} alias * @returns {ToIRContext} */ appendAliasNamespace(alias) { const prev = this.aliasNamespace return new ToIRContext( { ...this.props, aliasNamespace: prev ? `${prev}::${alias}` : alias }, this.indent, this.db ) } /** * Adds parent debugging information which should be passed into IR via site.alias * @param {string} alias * @returns {ToIRContext} */ withAliasNamespace(alias) { return new ToIRContext( { ...this.props, aliasNamespace: alias }, this.indent, this.db ) } /** * @param {SourceMappedStringI} ir * @returns {SourceMappedStringI} */ wrapWithRawFunctions(ir) { const map = this.fetchRawFunctions(ir) return wrapWithDefs(ir, map) } }