1use yulang_typed_ir as typed_ir;
2
3#[derive(Debug, Clone, PartialEq, Eq)]
4pub struct CpsModule {
5 pub functions: Vec<CpsFunction>,
6 pub roots: Vec<CpsFunction>,
7}
8
9#[derive(Debug, Clone, PartialEq, Eq)]
10pub struct CpsFunction {
11 pub name: String,
12 pub params: Vec<CpsValueId>,
13 pub entry: CpsContinuationId,
14 pub continuations: Vec<CpsContinuation>,
15 pub handlers: Vec<CpsHandler>,
16}
17
18#[derive(Debug, Clone, PartialEq, Eq)]
19pub struct CpsContinuation {
20 pub id: CpsContinuationId,
21 pub params: Vec<CpsValueId>,
22 pub captures: Vec<CpsValueId>,
23 pub shot_kind: CpsShotKind,
24 pub stmts: Vec<CpsStmt>,
25 pub terminator: CpsTerminator,
26}
27
28#[derive(Debug, Clone, Copy, PartialEq, Eq)]
29pub enum CpsShotKind {
30 OneShot,
31 MultiShot,
32}
33
34#[derive(Debug, Clone, PartialEq, Eq)]
35pub enum CpsStmt {
36 Literal {
37 dest: CpsValueId,
38 literal: CpsLiteral,
39 },
40 FreshGuard {
41 dest: CpsValueId,
42 var: yulang_runtime::EffectIdVar,
43 },
44 PeekGuard {
45 dest: CpsValueId,
46 },
47 FindGuard {
48 dest: CpsValueId,
49 guard: CpsValueId,
50 },
51 MakeThunk {
52 dest: CpsValueId,
53 entry: CpsContinuationId,
54 },
55 AddThunkBoundary {
56 dest: CpsValueId,
57 thunk: CpsValueId,
58 guard: CpsValueId,
59 allowed: typed_ir::Type,
60 active: bool,
61 },
62 MakeClosure {
63 dest: CpsValueId,
64 entry: CpsContinuationId,
65 },
66 MakeRecursiveClosure {
67 dest: CpsValueId,
68 entry: CpsContinuationId,
69 },
70 ForceThunk {
71 dest: CpsValueId,
72 thunk: CpsValueId,
73 },
74 Tuple {
75 dest: CpsValueId,
76 items: Vec<CpsValueId>,
77 },
78 Record {
79 dest: CpsValueId,
80 base: Option<CpsValueId>,
81 fields: Vec<CpsRecordField>,
82 },
83 RecordWithoutFields {
84 dest: CpsValueId,
85 base: CpsValueId,
86 fields: Vec<typed_ir::Name>,
87 },
88 Variant {
89 dest: CpsValueId,
90 tag: typed_ir::Name,
91 value: Option<CpsValueId>,
92 },
93 Select {
94 dest: CpsValueId,
95 base: CpsValueId,
96 field: typed_ir::Name,
97 },
98 SelectWithDefault {
99 dest: CpsValueId,
100 base: CpsValueId,
101 field: typed_ir::Name,
102 default: CpsValueId,
103 },
104 RecordHasField {
105 dest: CpsValueId,
106 base: CpsValueId,
107 field: typed_ir::Name,
108 },
109 TupleGet {
110 dest: CpsValueId,
111 tuple: CpsValueId,
112 index: usize,
113 },
114 VariantTagEq {
115 dest: CpsValueId,
116 variant: CpsValueId,
117 tag: typed_ir::Name,
118 },
119 VariantPayload {
120 dest: CpsValueId,
121 variant: CpsValueId,
122 },
123 Primitive {
124 dest: CpsValueId,
125 op: typed_ir::PrimitiveOp,
126 args: Vec<CpsValueId>,
127 },
128 DirectCall {
129 dest: CpsValueId,
130 target: String,
131 args: Vec<CpsValueId>,
132 },
133 ApplyClosure {
134 dest: CpsValueId,
135 closure: CpsValueId,
136 arg: CpsValueId,
137 },
138 CloneContinuation {
139 dest: CpsValueId,
140 source: CpsValueId,
141 },
142 Resume {
143 dest: CpsValueId,
144 resumption: CpsValueId,
145 arg: CpsValueId,
146 },
147 ResumeWithHandler {
148 dest: CpsValueId,
149 resumption: CpsValueId,
150 arg: CpsValueId,
151 handler: CpsHandlerId,
152 envs: Vec<CpsHandlerEnv>,
153 },
154 InstallHandler {
155 handler: CpsHandlerId,
156 envs: Vec<CpsHandlerEnv>,
157 value: CpsContinuationId,
162 escape: CpsContinuationId,
168 },
169 UninstallHandler {
170 handler: CpsHandlerId,
171 },
172}
173
174#[derive(Debug, Clone, PartialEq, Eq)]
175pub struct CpsRecordField {
176 pub name: typed_ir::Name,
177 pub value: CpsValueId,
178}
179
180#[derive(Debug, Clone, PartialEq, Eq)]
181pub struct CpsHandlerEnv {
182 pub entry: CpsContinuationId,
183 pub values: Vec<CpsValueId>,
185 pub targets: Vec<CpsValueId>,
189}
190
191#[derive(Debug, Clone, PartialEq, Eq)]
192pub enum CpsTerminator {
193 Return(CpsValueId),
194 Continue {
195 target: CpsContinuationId,
196 args: Vec<CpsValueId>,
197 },
198 Branch {
199 cond: CpsValueId,
200 then_cont: CpsContinuationId,
201 else_cont: CpsContinuationId,
202 },
203 Perform {
204 effect: typed_ir::Path,
205 payload: CpsValueId,
206 resume: CpsContinuationId,
207 handler: CpsHandlerId,
208 blocked: Option<CpsValueId>,
209 },
210 EffectfulCall {
215 target: String,
216 args: Vec<CpsValueId>,
217 resume: CpsContinuationId,
218 },
219 EffectfulApply {
222 closure: CpsValueId,
223 arg: CpsValueId,
224 resume: CpsContinuationId,
225 },
226 EffectfulForce {
231 thunk: CpsValueId,
232 resume: CpsContinuationId,
233 },
234}
235
236#[derive(Debug, Clone, PartialEq, Eq)]
237pub struct CpsHandler {
238 pub id: CpsHandlerId,
239 pub arms: Vec<CpsHandlerArm>,
240}
241
242#[derive(Debug, Clone, PartialEq, Eq)]
243pub struct CpsHandlerArm {
244 pub effect: typed_ir::Path,
245 pub entry: CpsContinuationId,
246}
247
248#[derive(Debug, Clone, PartialEq, Eq)]
249pub enum CpsLiteral {
250 Int(String),
251 Float(String),
252 String(String),
253 Bool(bool),
254 Unit,
255}
256
257#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
258pub struct CpsValueId(pub usize);
259
260#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
261pub struct CpsContinuationId(pub usize);
262
263#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
264pub struct CpsHandlerId(pub usize);
265
266#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
267pub struct CpsHandlerContextId(pub usize);