1// SPDX-FileCopyrightText: 2025 The Project Pterodactyl Developers 2// 3// SPDX-License-Identifier: MPL-2.0 4 5protocol Plug { 6 func plug(frame: Value.Frame) -> Self 7} 8 9 10extension Plug { 11 func plug(spine: Value.Spine) -> Self { 12 spine.reduce(self) { partialResult, frame in 13 partialResult.plug(frame: frame.forget) 14 } 15 } 16} 17 18extension Value: Plug { 19 func plug(frame: Frame) -> Self { 20 switch self { 21 case let .fun(_, _, closure: closure): 22 guard case let .app(arg: arg) = frame else { fatalError() } 23 return closure.instantiate(with: arg) 24 case let .record(_, fields: fields): 25 guard case let .proj(fieldName) = frame else { fatalError() } 26 guard let impl = fields[fieldName] else { fatalError() } 27 return impl.value.instantiate(with: self) 28 case let .shift(neutral: neutral): 29 return .shift(neutral: neutral.plug(frame: frame)) 30 default: 31 fatalError() 32 } 33 } 34} 35 36extension Value.Neutral: Plug { 37 func plug(boundary: Value.Boundary, frame: Value.Frame) async -> Value.Boundary { 38 switch await boundary.type.whnf() { 39 40 case let .funType(_, _, fam: fam): 41 guard case let .app(arg: arg) = frame else { 42 fatalError("Attempted to plug boundary of function type into invalid frame") 43 } 44 let fibre = fam.instantiate(with: arg) 45 return Value.Boundary(type: fibre, value: boundary.value?.plug(frame: frame)) 46 47 case let .recordType(boundName, fields: fields): 48 guard case let .proj(fieldName) = frame else { 49 fatalError("Attempted to plug boundary of record type into invalid frame") 50 } 51 guard let field = fields[fieldName] else { 52 fatalError("Attempted to project invalid field from boundary of record type") 53 } 54 let prefix = fields.prefix(until: fieldName) 55 let prefixImpls = prefix.mapWithKeys { (key, spec) in 56 Value.FieldImpl( 57 type: spec.type, 58 value: Closure( 59 evaluator: Evaluator(), 60 body: .cut(term: .local(index: 0), frame: .proj(fieldName: key)) 61 ) 62 ) 63 } 64 let prefixRecord: Value = .record(boundName: boundName, fields: prefixImpls) 65 let fieldTypeValue = field.type.instantiate(with: prefixRecord) 66 let value = 67 boundary.value?.plug(frame: frame) 68 ?? field.manifest.map { $0.instantiate(with: .shift(neutral: self)) } 69 return Value.Boundary(type: fieldTypeValue, value: value) 70 71 default: 72 fatalError("Boundary has unexpected type for plugging") 73 } 74 } 75 76 func enrich(frame: Value.Frame) -> Value.RichFrame { 77 switch frame { 78 case let .app(arg: arg): 79 let dom: AsyncThunk<Value.Type_> = AsyncThunk { 80 guard case let .funType(dom: dom, _, _) = await boundary.value().type.whnf() else { fatalError() } 81 return dom 82 } 83 return .app(dom: dom, arg: arg) 84 85 case let .proj(fieldName: fieldName): 86 return .proj(fieldName: fieldName) 87 } 88 } 89 90 func plug(frame: Value.Frame) -> Self { 91 let richFrame = enrich(frame: frame) 92 return Self( 93 head: head, 94 spine: spine + CollectionOfOne(richFrame), 95 boundary: AsyncThunk { await plug(boundary: boundary.value(), frame: frame) } 96 ) 97 } 98}