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) 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 } 31 } 32} 33 34extension Value.Neutral: Plug { 35 // Not async now, but might need to be later. 36 func plug(boundary: Value.Boundary, frame: Value.Frame) async -> Value.Boundary { 37 switch boundary.type { 38 case let .funType(_, _, fam: fam): 39 guard case let .app(arg: arg) = frame else { 40 fatalError("Attempted to plug element of function type into invalid frame") 41 } 42 let fibre = fam.instantiate(with: arg) 43 return Value.Boundary(type: fibre, value: boundary.value?.plug(frame: frame)) 44 45 case let .recordType(boundName, fields: fields): 46 guard case let .proj(fieldName) = frame else { 47 fatalError("Attempted to plug element of record type into invalid frame") 48 } 49 guard let field = fields[fieldName] else { 50 fatalError("Attempted to project invalid field from element of record type") 51 } 52 let prefix = fields.prefix(until: fieldName) 53 let prefixImpls = prefix.mapWithKeys { (key, spec) in 54 Value.FieldImpl( 55 type: spec.type, 56 value: Closure( 57 evaluator: Evaluator(globals: [:], locals: [.shift(neutral: self)]), 58 body: .cut(term: .local(index: 0), frame: .proj(fieldName: key)) 59 ) 60 ) 61 } 62 let prefixRecord: Value = .record(boundName: boundName, fields: prefixImpls) 63 let fieldTypeValue = field.type.instantiate(with: prefixRecord) 64 let value = boundary.value?.plug(frame: frame) ?? field.manifest.map { manifest in 65 return manifest.instantiate(with: .shift(neutral: self)) 66 } 67 return Value.Boundary(type: fieldTypeValue, value: value) 68 } 69 } 70 71 func plug(frame: Value.Frame) -> Self { 72 Self( 73 head: head, 74 spine: CollectionOfOne(frame) + spine, 75 boundary: AsyncThunk { await plug(boundary: boundary.value(), frame: frame) } 76 ) 77 } 78}