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::Stmt(s) => {
13 self.exec_stmt(s)?;
14 }
15 }
16 }
17 Ok(Value::Unit)
18 }
19
20 pub fn register_type_def(&mut self, td: &TypeDef) {
22 match td {
23 TypeDef::Sum {
24 name: type_name,
25 variants,
26 ..
27 } => {
28 if self.arena.find_type_id(type_name).is_none() {
29 self.arena.register_sum_type(
30 type_name,
31 variants
32 .iter()
33 .map(|variant| variant.name.clone())
34 .collect(),
35 );
36 }
37 let mut members = HashMap::new();
38 for variant in variants {
39 if variant.fields.is_empty() {
40 members.insert(
42 variant.name.clone(),
43 Value::Variant {
44 type_name: type_name.clone(),
45 variant: variant.name.clone(),
46 fields: vec![].into(),
47 },
48 );
49 } else {
50 members.insert(
52 variant.name.clone(),
53 Value::Builtin(format!("__ctor:{}:{}", type_name, variant.name)),
54 );
55 }
56 }
57 self.define(
58 type_name.clone(),
59 Value::Namespace {
60 name: type_name.clone(),
61 members,
62 },
63 );
64 }
65 TypeDef::Product { name, fields, .. } => {
66 if self.arena.find_type_id(name).is_none() {
67 self.arena.register_record_type(
68 name,
69 fields.iter().map(|(field, _)| field.clone()).collect(),
70 );
71 }
72 let schema = fields.iter().map(|(field, _)| field.clone()).collect();
76 self.record_schemas.insert(name.clone(), schema);
77 }
78 }
79 }
80
81 pub fn exec_fn_def(&mut self, fd: &FnDef) -> Result<(), RuntimeError> {
82 let lower_ctx = super::ir_bridge::InterpreterLowerCtx::new(self);
83 let val = Value::Fn(Rc::new(crate::value::FunctionValue {
84 name: Rc::new(fd.name.clone()),
85 params: Rc::new(fd.params.clone()),
86 return_type: Rc::new(fd.return_type.clone()),
87 effects: Rc::new(fd.effects.clone()),
88 body: Rc::clone(&fd.body),
89 lowered_body: super::lowered::lower_fn_body(fd.body.as_ref(), &lower_ctx, &fd.name),
90 resolution: fd.resolution.clone(),
91 memo_eligible: self.memo_fns.contains(&fd.name),
92 home_globals: None,
93 }));
94 self.define(fd.name.clone(), val);
95 Ok(())
96 }
97
98 pub fn exec_stmt(&mut self, stmt: &Stmt) -> Result<Value, RuntimeError> {
99 match stmt {
100 Stmt::Binding(name, _, expr) => {
101 let val = self.eval_expr(expr)?;
102 self.define(name.clone(), val);
103 Ok(Value::Unit)
104 }
105 Stmt::Expr(expr) => self.eval_expr(expr),
106 }
107 }
108
109 pub fn exec_body(&mut self, stmts: &[Stmt]) -> Result<Value, RuntimeError> {
110 let mut last = Value::Unit;
111 for stmt in stmts {
112 last = self.exec_stmt(stmt)?;
113 }
114 Ok(last)
115 }
116
117 pub fn run_file(&mut self, source: &str) -> Result<Value, RuntimeError> {
118 let mut items = parse_source(source).map_err(RuntimeError::Error)?;
119 crate::resolver::resolve_program(&mut items);
120
121 for item in &items {
123 match item {
124 TopLevel::FnDef(fd) => self.exec_fn_def(fd)?,
125 TopLevel::Stmt(s) => {
126 self.exec_stmt(s)?;
127 }
128 _ => {}
129 }
130 }
131
132 let main_fn = self.lookup("main");
134 if let Ok(fn_val) = main_fn {
135 let allowed = Self::callable_declared_effects(&fn_val);
136 self.call_value_with_effects_pub(fn_val, vec![], "<main>", allowed)?;
137 }
138
139 Ok(Value::Unit)
140 }
141}