// SPDX-FileCopyrightText: 2025 The Project Pterodactyl Developers // // SPDX-License-Identifier: MPL-2.0 protocol Plug { func plug(frame: Value.Frame) -> Self } extension Plug { func plug(spine: Value.Spine) -> Self { spine.reduce(self) { partialResult, frame in partialResult.plug(frame: frame.forget) } } } extension Value: Plug { func plug(frame: Frame) -> Self { switch self { case let .fun(_, _, closure: closure): guard case let .app(arg: arg) = frame else { fatalError() } return closure.instantiate(with: arg) case let .record(_, fields: fields): guard case let .proj(fieldName) = frame else { fatalError() } guard let impl = fields[fieldName] else { fatalError() } return impl.value.instantiate(with: self) case let .shift(neutral: neutral): return .shift(neutral: neutral.plug(frame: frame)) default: fatalError() } } } extension Value.Neutral: Plug { func plug(boundary: Value.Boundary, frame: Value.Frame) async -> Value.Boundary { switch await boundary.type.whnf() { case let .funType(_, _, fam: fam): guard case let .app(arg: arg) = frame else { fatalError("Attempted to plug boundary of function type into invalid frame") } let fibre = fam.instantiate(with: arg) return Value.Boundary(type: fibre, value: boundary.value?.plug(frame: frame)) case let .recordType(boundName, fields: fields): guard case let .proj(fieldName) = frame else { fatalError("Attempted to plug boundary of record type into invalid frame") } guard let field = fields[fieldName] else { fatalError("Attempted to project invalid field from boundary of record type") } let prefix = fields.prefix(until: fieldName) let prefixImpls = prefix.mapWithKeys { (key, spec) in Value.FieldImpl( type: spec.type, value: Closure( evaluator: Evaluator(), body: .cut(term: .local(index: 0), frame: .proj(fieldName: key)) ) ) } let prefixRecord: Value = .record(boundName: boundName, fields: prefixImpls) let fieldTypeValue = field.type.instantiate(with: prefixRecord) let value = boundary.value?.plug(frame: frame) ?? field.manifest.map { $0.instantiate(with: .shift(neutral: self)) } return Value.Boundary(type: fieldTypeValue, value: value) default: fatalError("Boundary has unexpected type for plugging") } } func enrich(frame: Value.Frame) -> Value.RichFrame { switch frame { case let .app(arg: arg): let dom: AsyncThunk = AsyncThunk { guard case let .funType(dom: dom, _, _) = await boundary.value().type.whnf() else { fatalError() } return dom } return .app(dom: dom, arg: arg) case let .proj(fieldName: fieldName): return .proj(fieldName: fieldName) } } func plug(frame: Value.Frame) -> Self { let richFrame = enrich(frame: frame) return Self( head: head, spine: spine + CollectionOfOne(richFrame), boundary: AsyncThunk { await plug(boundary: boundary.value(), frame: frame) } ) } }