1pub mod const_stmt;
2pub mod eval_mir;
3pub mod op_stmt;
4pub mod value;
5
6use std::collections::{HashMap, VecDeque};
7
8use mir::{
9 mir::{Mir, Mirs},
10 ty::ConcEffect,
11 BlockId, MirId,
12};
13use value::Value;
14
15use crate::{
16 eval_mir::{EvalMir, Handler, InnerOutput},
17 value::Closure,
18};
19
20pub fn eval_mirs(mirs: Mirs) -> EvalMirs {
21 let mir = mirs.mirs.get(mirs.entrypoint.0).cloned().unwrap();
22 EvalMirs {
23 mirs: mirs.mirs,
24 stack: vec![EvalMir {
25 mir,
26 registers: HashMap::new(),
27 parameters: HashMap::new(),
28 captured: HashMap::new(),
29 pc_block: BlockId(0),
30 pc_stmt_idx: 0,
31 return_register: None,
32 handlers: HashMap::new(),
33 }],
34 }
35}
36
37#[derive(Clone, Debug)]
38pub struct EvalMirs {
39 mirs: Vec<Mir>,
40 stack: Vec<EvalMir>,
41}
42
43impl EvalMirs {
44 pub fn eval_next(&mut self) -> Output {
45 match self.stack().eval_next() {
46 InnerOutput::Return(value) => {
47 if self.stack.len() == 1 {
49 Output::Return(value)
50 } else {
51 self.stack.pop().unwrap();
52 self.stack().return_or_continue_with_value(value);
53 Output::Running
54 }
55 }
56 InnerOutput::Perform { input, effect } => {
57 let mut continuation_from_handler = VecDeque::new();
58 let handler = loop {
59 if let Some(eval_mir) = self.stack.pop() {
60 let handler = eval_mir.handlers.get(&effect).cloned();
62 continuation_from_handler.push_front(eval_mir);
64 if let Some(handler) = handler {
65 break handler;
66 }
67 } else {
68 self.stack.extend(continuation_from_handler);
70 return Output::Perform { input, effect };
71 }
72 };
73 match handler {
74 eval_mir::Handler::Handler(Closure {
75 mir,
76 mut captured,
77 handlers: _,
79 }) => {
80 captured.insert(effect.input.clone(), input);
81 let eval_mir = EvalMir {
82 mir: self.get_mir(&mir).clone(),
83 registers: Default::default(),
84 parameters: Default::default(),
85 captured,
86 pc_block: BlockId(0),
87 pc_stmt_idx: 0,
88 return_register: None,
89 handlers: [(
90 ConcEffect {
91 input: effect.output,
92 output: continuation_from_handler[0].mir.output.clone(),
93 },
94 Handler::Continuation(continuation_from_handler.into()),
95 )]
96 .into_iter()
97 .collect(),
98 };
99 self.stack.push(eval_mir);
100 Output::Running
101 }
102 eval_mir::Handler::Continuation(continuation) => {
103 self.stack.extend(continuation_from_handler);
104 self.stack.extend(continuation);
105 self.stack().return_or_continue_with_value(input);
107 Output::Running
108 }
109 }
110 }
111 InnerOutput::RunOther { fn_ref, parameters } => match fn_ref {
112 value::FnRef::Link(_) => todo!(),
113 value::FnRef::Closure(Closure {
114 mir,
115 captured,
116 handlers,
117 }) => {
118 let eval_mir = EvalMir {
119 mir: self.get_mir(&mir).clone(),
120 registers: Default::default(),
121 parameters,
122 captured,
123 pc_block: Default::default(),
124 pc_stmt_idx: Default::default(),
125 return_register: None,
126 handlers,
127 };
128 self.stack.push(eval_mir);
129 Output::Running
130 }
131 value::FnRef::Recursion => {
132 let eval_mir = EvalMir {
133 mir: self.stack().mir.clone(),
134 registers: Default::default(),
135 parameters,
136 captured: self.stack().captured.clone(),
137 pc_block: Default::default(),
138 pc_stmt_idx: Default::default(),
139 return_register: None,
140 handlers: self.stack().handlers.clone(),
141 };
142 self.stack.push(eval_mir);
143 Output::Running
144 }
145 },
146 InnerOutput::Running => Output::Running,
147 }
148 }
149
150 pub fn stack(&mut self) -> &mut EvalMir {
151 self.stack.last_mut().unwrap()
152 }
153
154 pub fn get_mir(&self, mir_id: &MirId) -> &Mir {
155 &self.mirs[mir_id.0]
156 }
157}
158
159#[derive(Debug, Clone, PartialEq)]
160pub enum Output {
161 Return(Value),
162 Perform { input: Value, effect: ConcEffect },
163 Running,
164}