this repo has no description
www.jonmsterling.com/01HC/
1// SPDX-FileCopyrightText: 2025 The Project Pterodactyl Developers
2//
3// SPDX-License-Identifier: MPL-2.0
4
5struct Evaluator {
6 let globals: [Name: Term.TypedTerm]
7 let locals: [Value]
8
9 init(globals: [Name : Term.TypedTerm], locals: [Value]) {
10 self.globals = globals
11 self.locals = locals
12 }
13
14 init() {
15 self.init(globals: [:], locals: [])
16 }
17
18 func extendedBy(value: Value) -> Self {
19 Self(globals: globals, locals: CollectionOfOne(value) + locals)
20 }
21
22 func close<Body>(body: Body) -> Closure<Body> {
23 Closure(evaluator: self, body: body)
24 }
25
26 func close(fieldSpec: Term.FieldSpec) -> Value.FieldSpec {
27 Value.FieldSpec(
28 type: close(body: fieldSpec.type),
29 manifest: fieldSpec.manifest.map(close(body:))
30 )
31 }
32
33 func close(fieldImpl: Term.FieldImpl) -> Value.FieldImpl {
34 Value.FieldImpl(
35 type: close(body: fieldImpl.type),
36 value: close(body: fieldImpl.value)
37 )
38 }
39
40 func evaluate(frame: Term.Frame) -> Value.Frame {
41 switch frame {
42 case let .app(arg: arg): .app(arg: evaluate(term: arg))
43 case let .proj(fieldName: fieldName): .proj(fieldName: fieldName)
44 }
45 }
46
47 func evaluate(term: Term) -> Value {
48 switch term {
49 case let .local(index: index):
50 return locals[index]
51 case let .global(name: name):
52 let neutral = Value.Neutral(
53 head: .global(name: name),
54 spine: [],
55 boundary: AsyncThunk {
56 let typedTerm = globals[name]!
57 return Value.Boundary(
58 type: evaluate(type: typedTerm.type),
59 value: evaluate(term: typedTerm.term)
60 )
61 }
62 )
63 return .shift(neutral: neutral)
64 case let .cut(term: term, frame: frame):
65 return evaluate(term: term)
66 .plug(frame: evaluate(frame: frame))
67 case let .fun(dom: dom, boundName: boundName, body: body):
68 return .fun(
69 dom: AsyncThunk { await evaluate(type: dom.value()) },
70 boundName: boundName,
71 closure: close(body: body)
72 )
73 case let .record(boundName: boundName, fields: fields):
74 return .record(
75 boundName: boundName,
76 fields: fields.map(close(fieldImpl:))
77 )
78 }
79 }
80
81 func evaluate(type: Term.Type_) -> Value.Type_ {
82 switch type {
83 case let .funType(dom: dom, boundName: boundName, fam: fam):
84 .funType(
85 dom: evaluate(type: dom),
86 boundName: boundName,
87 fam: close(body: fam)
88 )
89 case let .recordType(boundName: boundName, fields: fields):
90 .recordType(boundName: boundName, fields: fields.map(close(fieldSpec:)))
91 }
92 }
93}
94
95extension Closure where Body == Term {
96 func instantiate(with value: Value) -> Value {
97 evaluator.extendedBy(value: value).evaluate(term: body)
98 }
99}
100
101extension Closure where Body == Term.Type_ {
102 func instantiate(with value: Value) -> Value.Type_ {
103 evaluator.extendedBy(value: value).evaluate(type: body)
104 }
105}