Skip to main content

yulang_runtime/vm/
model.rs

1use super::*;
2
3#[derive(Debug, Clone, PartialEq)]
4pub enum VmResult {
5    Value(VmValue),
6    Request(VmRequest),
7}
8
9#[derive(Debug, Clone, PartialEq)]
10pub enum VmValue {
11    Int(String),
12    Float(String),
13    String(StringTree),
14    Bytes(BytesTree),
15    Path(Rc<PathBuf>),
16    Bool(bool),
17    Unit,
18    List(ListTree<Rc<VmValue>>),
19    Tuple(Vec<VmValue>),
20    Record(BTreeMap<typed_ir::Name, VmValue>),
21    Variant {
22        tag: typed_ir::Name,
23        value: Option<Box<VmValue>>,
24    },
25    EffectOp(typed_ir::Path),
26    PrimitiveOp(Rc<VmPrimitive>),
27    Resume(Rc<VmResume>),
28    Closure(Rc<VmClosure>),
29    Thunk(Rc<VmThunk>),
30    EffectId(u64),
31}
32
33#[derive(Debug, Clone, PartialEq)]
34pub struct VmRequest {
35    pub effect: typed_ir::Path,
36    pub payload: VmValue,
37    pub continuation: VmContinuation,
38    pub blocked_id: Option<u64>,
39}
40
41#[derive(Debug, Clone, PartialEq)]
42pub struct VmPrimitive {
43    pub op: typed_ir::PrimitiveOp,
44    pub args: Vec<VmValue>,
45}
46
47#[derive(Debug, Clone, PartialEq)]
48pub struct VmClosure {
49    pub(super) param: typed_ir::Name,
50    pub(super) param_ty: Type,
51    pub(super) body: Expr,
52    pub(super) ret: Type,
53    pub(super) env: Env,
54    pub(super) guard_stack: GuardStack,
55    pub(super) self_name: Option<typed_ir::Path>,
56}
57
58#[derive(Debug, Clone, PartialEq)]
59pub struct VmThunk {
60    pub(super) body: ThunkBody,
61    pub(super) env: Env,
62    pub(super) guard_stack: GuardStack,
63    pub(super) blocked: Vec<BlockedEffect>,
64}
65
66#[derive(Debug, Clone, PartialEq)]
67pub(super) enum ThunkBody {
68    Value(VmValue),
69    Expr(Expr),
70    Emit {
71        effect: typed_ir::Path,
72        payload: VmValue,
73    },
74}
75
76#[derive(Debug, Clone, PartialEq)]
77pub struct VmResume {
78    pub(super) continuation: VmContinuation,
79}
80
81#[derive(Debug, Clone, PartialEq, Default)]
82pub struct VmContinuation {
83    pub(super) frames: Vec<Frame>,
84    pub(super) guard_stack: GuardStack,
85}
86
87#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
88pub struct VmProfile {
89    pub eval_expr_calls: usize,
90    pub max_eval_depth: usize,
91    pub continuation_steps: usize,
92    pub max_continuation_frames: usize,
93}
94
95impl VmProfile {
96    pub fn merge(&mut self, other: Self) {
97        self.eval_expr_calls += other.eval_expr_calls;
98        self.max_eval_depth = self.max_eval_depth.max(other.max_eval_depth);
99        self.continuation_steps += other.continuation_steps;
100        self.max_continuation_frames = self
101            .max_continuation_frames
102            .max(other.max_continuation_frames);
103    }
104}
105
106#[derive(Debug, Clone, PartialEq, Eq, Default)]
107pub(super) struct GuardStack(pub(super) PersistentVector<GuardEntry>);
108
109#[derive(Debug, Clone, PartialEq, Eq)]
110pub(super) struct PersistentVector<T> {
111    pub(super) len: usize,
112    pub(super) tail: Option<Rc<PersistentVectorChunk<T>>>,
113}
114
115#[derive(Debug, Clone, Copy, PartialEq, Eq)]
116pub(super) struct GuardEntry {
117    pub(super) var: EffectIdVar,
118    pub(super) id: u64,
119}
120
121#[derive(Debug, Clone, PartialEq, Eq)]
122pub(super) struct PersistentVectorChunk<T> {
123    pub(super) items: Rc<[T]>,
124    pub(super) parent: Option<Rc<PersistentVectorChunk<T>>>,
125}
126
127#[derive(Debug, Clone, PartialEq)]
128pub(super) struct BlockedEffect {
129    pub(super) guard_id: u64,
130    pub(super) allowed: typed_ir::Type,
131    pub(super) active: bool,
132}
133
134#[derive(Debug, Clone, PartialEq)]
135pub(super) enum Frame {
136    BindHere,
137    ApplyCallee {
138        arg: Expr,
139        env: Env,
140        delay_arg: bool,
141    },
142    ApplyArg {
143        callee: VmValue,
144    },
145    If {
146        then_branch: Expr,
147        else_branch: Expr,
148        env: Env,
149    },
150    Tuple {
151        done: Vec<VmValue>,
152        remaining: Vec<Expr>,
153        env: Env,
154    },
155    Select {
156        field: typed_ir::Name,
157    },
158    Match {
159        arms: Vec<MatchArm>,
160        env: Env,
161    },
162    BlockLet {
163        pattern: Pattern,
164        remaining: Vec<Stmt>,
165        tail: Option<Expr>,
166        env: Env,
167    },
168    BlockExpr {
169        remaining: Vec<Stmt>,
170        tail: Option<Expr>,
171        env: Env,
172    },
173    Handle {
174        id: u64,
175        arms: Vec<HandleArm>,
176        env: Env,
177        guard_stack: GuardStack,
178        expected_ty: Type,
179    },
180    HandleGuard {
181        id: u64,
182        request: VmRequest,
183        outer: VmContinuation,
184        handler_guard_stack: GuardStack,
185        arms: Vec<HandleArm>,
186        env: Env,
187        arm_env: Env,
188        body: Expr,
189        expected_ty: Type,
190    },
191    LocalPushId {
192        parent: GuardStack,
193    },
194    BlockedEffects {
195        blocked: Vec<BlockedEffect>,
196        active: bool,
197    },
198    Coerce {
199        to: typed_ir::Type,
200    },
201    WrapThunkResult {
202        expected_ty: Type,
203    },
204}
205
206pub(super) type Env = HashMap<typed_ir::Path, VmValue>;