Correcting the plugging algorithm for records

When instantiating the closures for record fields, we should plug in just the
appropriate prefix of the main record.

Changed files
+14 -3
Sources
PterodactylKernel
+14 -3
Sources/PterodactylKernel/Plug.swift
···
let fibre = fam.instantiate(with: arg)
return Value.Boundary(type: fibre, value: boundary.value?.plug(frame: frame))
-
case let .recordType(_, fields: fields):
+
case let .recordType(boundName, fields: fields):
guard case let .proj(fieldName) = frame else {
fatalError("Attempted to plug element of record type into invalid frame")
}
guard let field = fields[fieldName] else {
fatalError("Attempted to project invalid field from element of record type")
}
-
let fieldTypeValue = field.type.instantiate(with: .shift(neutral: self))
+
let prefix = fields.prefix(until: fieldName)
+
let prefixImpls = prefix.mapWithKeys { (key, spec) in
+
Value.FieldImpl(
+
type: spec.type,
+
value: Closure(
+
evaluator: Evaluator(globals: [:], locals: [.shift(neutral: self)]),
+
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 { manifest in
-
manifest.instantiate(with: .shift(neutral: self))
+
return manifest.instantiate(with: .shift(neutral: self))
}
return Value.Boundary(type: fieldTypeValue, value: value)
}