1use super::*;
2
3impl Interpreter {
4 pub fn exec_items(&mut self, items: &[TopLevel]) -> Result<Value, RuntimeError> {
5 for item in items {
6 match item {
7 TopLevel::FnDef(fd) => self.exec_fn_def(fd)?,
8 TopLevel::Module(_) => {}
9 TopLevel::Verify(_) => {}
10 TopLevel::Decision(_) => {}
11 TopLevel::TypeDef(td) => self.register_type_def(td),
12 TopLevel::EffectSet { name, effects } => {
13 self.register_effect_set(name.clone(), effects.clone());
14 }
15 TopLevel::Stmt(s) => {
16 self.exec_stmt(s)?;
17 }
18 }
19 }
20 Ok(Value::Unit)
21 }
22
23 pub fn register_type_def(&mut self, td: &TypeDef) {
25 match td {
26 TypeDef::Sum {
27 name: type_name,
28 variants,
29 ..
30 } => {
31 let mut members = HashMap::new();
32 for variant in variants {
33 if variant.fields.is_empty() {
34 members.insert(
36 variant.name.clone(),
37 Value::Variant {
38 type_name: type_name.clone(),
39 variant: variant.name.clone(),
40 fields: vec![],
41 },
42 );
43 } else {
44 members.insert(
46 variant.name.clone(),
47 Value::Builtin(format!("__ctor:{}:{}", type_name, variant.name)),
48 );
49 }
50 }
51 self.define(
52 type_name.clone(),
53 Value::Namespace {
54 name: type_name.clone(),
55 members,
56 },
57 );
58 }
59 TypeDef::Product { name, fields, .. } => {
60 let schema = fields.iter().map(|(field, _)| field.clone()).collect();
64 self.record_schemas.insert(name.clone(), schema);
65 }
66 }
67 }
68
69 pub fn exec_fn_def(&mut self, fd: &FnDef) -> Result<(), RuntimeError> {
70 let val = Value::Fn {
71 name: fd.name.clone(),
72 params: fd.params.clone(),
73 return_type: fd.return_type.clone(),
74 effects: self.expand_effects(&fd.effects),
75 body: Rc::clone(&fd.body),
76 resolution: fd.resolution.clone(),
77 memo_eligible: self.memo_fns.contains(&fd.name),
78 home_globals: None,
79 };
80 self.define(fd.name.clone(), val);
81 Ok(())
82 }
83
84 pub fn exec_stmt(&mut self, stmt: &Stmt) -> Result<Value, RuntimeError> {
85 match stmt {
86 Stmt::Binding(name, _, expr) => {
87 let val = self.eval_expr(expr)?;
88 self.define(name.clone(), val);
89 Ok(Value::Unit)
90 }
91 Stmt::Expr(expr) => self.eval_expr(expr),
92 }
93 }
94
95 pub fn exec_body(&mut self, stmts: &[Stmt]) -> Result<Value, RuntimeError> {
96 let mut last = Value::Unit;
97 for stmt in stmts {
98 last = self.exec_stmt(stmt)?;
99 }
100 Ok(last)
101 }
102
103 pub(super) fn exec_body_resolved(
106 &mut self,
107 stmts: &[Stmt],
108 local_slots: &HashMap<String, u16>,
109 ) -> Result<Value, RuntimeError> {
110 let mut last = Value::Unit;
111 for stmt in stmts {
112 last = self.exec_stmt_resolved(stmt, local_slots)?;
113 }
114 Ok(last)
115 }
116
117 pub(super) fn exec_stmt_resolved(
118 &mut self,
119 stmt: &Stmt,
120 local_slots: &HashMap<String, u16>,
121 ) -> Result<Value, RuntimeError> {
122 match stmt {
123 Stmt::Binding(name, _, expr) => {
124 let val = self.eval_expr(expr)?;
125 if let Some(&slot) = local_slots.get(name) {
126 self.define_slot(slot, val);
127 } else {
128 self.define(name.clone(), val);
129 }
130 Ok(Value::Unit)
131 }
132 Stmt::Expr(expr) => self.eval_expr(expr),
133 }
134 }
135
136 pub fn run_file(&mut self, source: &str) -> Result<Value, RuntimeError> {
137 let mut items = parse_source(source).map_err(RuntimeError::Error)?;
138 crate::resolver::resolve_program(&mut items);
139
140 for item in &items {
142 match item {
143 TopLevel::FnDef(fd) => self.exec_fn_def(fd)?,
144 TopLevel::Stmt(s) => {
145 self.exec_stmt(s)?;
146 }
147 _ => {}
148 }
149 }
150
151 let main_fn = self.lookup("main");
153 if let Ok(fn_val) = main_fn {
154 let allowed = Self::callable_declared_effects(&fn_val);
155 self.call_value_with_effects_pub(fn_val, vec![], "<main>", allowed)?;
156 }
157
158 Ok(Value::Unit)
159 }
160}