Skip to main content

yulang_native/
cps_env.rs

1use crate::cps_ir::{CpsContinuationId, CpsModule, CpsValueId};
2
3#[derive(Debug, Clone, PartialEq, Eq)]
4pub struct CpsEnvironmentLayout {
5    pub functions: Vec<CpsFunctionEnvironmentLayout>,
6    pub roots: Vec<CpsFunctionEnvironmentLayout>,
7}
8
9#[derive(Debug, Clone, PartialEq, Eq)]
10pub struct CpsFunctionEnvironmentLayout {
11    pub name: String,
12    pub continuations: Vec<CpsContinuationEnvironmentLayout>,
13}
14
15#[derive(Debug, Clone, PartialEq, Eq)]
16pub struct CpsContinuationEnvironmentLayout {
17    pub continuation: CpsContinuationId,
18    pub slots: Vec<CpsEnvironmentSlot>,
19}
20
21#[derive(Debug, Clone, Copy, PartialEq, Eq)]
22pub struct CpsEnvironmentSlot {
23    pub index: usize,
24    pub value: CpsValueId,
25}
26
27pub fn layout_cps_environments(module: &CpsModule) -> CpsEnvironmentLayout {
28    CpsEnvironmentLayout {
29        functions: module
30            .functions
31            .iter()
32            .map(layout_function_environments)
33            .collect(),
34        roots: module
35            .roots
36            .iter()
37            .map(layout_function_environments)
38            .collect(),
39    }
40}
41
42fn layout_function_environments(
43    function: &crate::cps_ir::CpsFunction,
44) -> CpsFunctionEnvironmentLayout {
45    CpsFunctionEnvironmentLayout {
46        name: function.name.clone(),
47        continuations: function
48            .continuations
49            .iter()
50            .map(|continuation| CpsContinuationEnvironmentLayout {
51                continuation: continuation.id,
52                slots: continuation
53                    .captures
54                    .iter()
55                    .copied()
56                    .enumerate()
57                    .map(|(index, value)| CpsEnvironmentSlot { index, value })
58                    .collect(),
59            })
60            .collect(),
61    }
62}
63
64#[cfg(test)]
65mod tests {
66    use crate::cps_ir::{
67        CpsContinuation, CpsContinuationId, CpsFunction, CpsModule, CpsShotKind, CpsTerminator,
68        CpsValueId,
69    };
70
71    use super::*;
72
73    #[test]
74    fn assigns_stable_slots_from_continuation_capture_order() {
75        let module = CpsModule {
76            functions: Vec::new(),
77            roots: vec![CpsFunction {
78                name: "root".to_string(),
79                params: Vec::new(),
80                entry: CpsContinuationId(0),
81                continuations: vec![CpsContinuation {
82                    id: CpsContinuationId(0),
83                    params: Vec::new(),
84                    captures: vec![CpsValueId(4), CpsValueId(2)],
85                    shot_kind: CpsShotKind::MultiShot,
86                    stmts: Vec::new(),
87                    terminator: CpsTerminator::Return(CpsValueId(4)),
88                }],
89                handlers: Vec::new(),
90            }],
91        };
92
93        assert_eq!(
94            layout_cps_environments(&module).roots[0].continuations[0].slots,
95            vec![
96                CpsEnvironmentSlot {
97                    index: 0,
98                    value: CpsValueId(4),
99                },
100                CpsEnvironmentSlot {
101                    index: 1,
102                    value: CpsValueId(2),
103                },
104            ]
105        );
106    }
107}