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

119 lines (103 loc) 2.94 kB
import { makeReferenceError, mergeSites } from "@helios-lang/compiler-utils" import { $ } from "@helios-lang/ir" import { ToIRContext } from "../codegen/index.js" import { Scope } from "../scopes/index.js" import { Expr } from "./Expr.js" import { AllType, AnyType, DataEntity } from "../typecheck/common.js" /** * @import { Site, Word } from "@helios-lang/compiler-utils" * @import { SourceMappedStringI } from "@helios-lang/ir" * @import { TypeCheckContext } from "../index.js" * @typedef {import("../typecheck/index.js").EvalEntity} EvalEntity */ /** * Name::Member expression */ export class PathExpr extends Expr { /** * @private * @readonly * @type {Expr} */ _baseExpr /** * @private * @readonly * @type {Word} */ _memberName /** * @param {Site} site * @param {Expr} baseExpr * @param {Word} memberName */ constructor(site, baseExpr, memberName) { super(site) this._baseExpr = baseExpr this._memberName = memberName } /** * @type {Expr} */ get baseExpr() { return this._baseExpr } /** * @param {TypeCheckContext} ctx * @param {Scope} scope * @param {boolean} [preferType] * @returns {EvalEntity} */ evalInternal(ctx, scope, preferType = true) { const base = this._baseExpr.eval(ctx, scope) /** * @type {null | EvalEntity} */ let member = null if (base.asNamespace) { member = base.asNamespace.namespaceMembers[this._memberName.value] } else if (base.asType) { const typeMembers = base.asType.typeMembers member = typeMembers[this._memberName.value] } if (!member) { ctx.errors.reference( mergeSites(this._baseExpr.site, this._memberName.site), `${base.toString()}::${this._memberName.value} undefined` ) if (preferType) { return new AllType() } else { return new DataEntity(new AllType()) } } if (member.asType?.toTyped().asFunc) { return member.asType.toTyped() } else { return member } } /** * @param {ToIRContext} ctx * @returns {SourceMappedStringI} */ toIR(ctx) { const v = this.cache if (v?.asNamed) { return $(`${v.asNamed.path}`, this.site) } else if (this._baseExpr.cache?.asNamed) { return $( `${this._baseExpr.cache.asNamed.path}__${this._memberName.value}`, this.site ) } else { throw new Error(`expected named value, ${v?.toString()}`) } } /** * @returns {string} */ toString() { return `${this._baseExpr.toString()}::${this._memberName.toString()}` } }