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

147 lines (128 loc) 3.58 kB
import { makeErrorCollector } from "@helios-lang/compiler-utils" import { ToIRContext } from "../codegen/ToIRContext.js" import { Expr } from "../expressions/index.js" import { Scope } from "../scopes/index.js" import { ConstStatement } from "./ConstStatement.js" import { FuncStatement } from "./FuncStatement.js" /** * @import { Site } from "@helios-lang/compiler-utils" * @import { Definitions, TypeCheckContext } from "../index.js" * @typedef {import("../typecheck/index.js").InstanceMembers} InstanceMembers * @typedef {import("../typecheck/index.js").TypeMembers} TypeMembers */ /** * Impl statements, which add functions and constants to registry of user types (Struct, Enum Member and Enums) */ export class ImplDefinition { /** * @readonly * @type {(FuncStatement | ConstStatement)[]} */ statements /** * @private * @readonly * @type {Expr} */ _selfTypeExpr /** * @param {Expr} selfTypeExpr; * @param {(FuncStatement | ConstStatement)[]} statements */ constructor(selfTypeExpr, statements) { this._selfTypeExpr = selfTypeExpr this.statements = statements } /** * @type {Site} */ get site() { return this._selfTypeExpr.site } /** * @param {string} basePath */ setBasePath(basePath) { for (let s of this.statements) { s.setBasePath(basePath) } } /** * @returns {string} */ toString() { return `${this.statements.map((s) => s.toString()).join("\n")}` } /** * @param {TypeCheckContext} ctx * @param {Scope} scope * @returns {TypeMembers} */ genTypeMembers(ctx, scope) { /** * @type {TypeMembers} */ const typeMembers = {} for (let s of this.statements) { if (s instanceof ConstStatement) { const s_ = s.evalType(ctx, scope) if (s_) { typeMembers[s.name.value] = s_.toTyped() } } else if (!FuncStatement.isMethod(s)) { const s_ = s.evalType(ctx, scope) if (s_) { typeMembers[s.name.value] = s_ } } } return typeMembers } /** * Doesn't add the common types * @param {Scope} scope * @returns {InstanceMembers} */ genInstanceMembers(scope) { /** * @type {InstanceMembers} */ const instanceMembers = {} for (let s of this.statements) { if (FuncStatement.isMethod(s)) { const s_ = s.evalType( { errors: scope.errorCollector ?? makeErrorCollector() }, scope ) if (s_) { instanceMembers[s.name.value] = s_ } } } return instanceMembers } /** * @param {TypeCheckContext} ctx * @param {Scope} scope */ eval(ctx, scope) { void this._selfTypeExpr.eval(ctx, scope) for (let s of this.statements) { if (s instanceof FuncStatement) { void s.evalInternal(ctx, scope, true) } else { void s.evalInternal(ctx, scope) } } } /** * Returns IR of all impl members * @param {ToIRContext} ctx * @param {Definitions} map */ toIR(ctx, map) { for (let s of this.statements) { s.toIR(ctx, map) } } }