Skip to main content

aver/interpreter/
exec.rs

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 { .. } => {}
13                TopLevel::Stmt(s) => {
14                    self.exec_stmt(s)?;
15                }
16            }
17        }
18        Ok(Value::Unit)
19    }
20
21    /// Register a user-defined type: sum type variants and record constructors.
22    pub fn register_type_def(&mut self, td: &TypeDef) {
23        match td {
24            TypeDef::Sum {
25                name: type_name,
26                variants,
27                ..
28            } => {
29                let mut members = HashMap::new();
30                for variant in variants {
31                    if variant.fields.is_empty() {
32                        // Zero-arg variant: stored directly as a Value
33                        members.insert(
34                            variant.name.clone(),
35                            Value::Variant {
36                                type_name: type_name.clone(),
37                                variant: variant.name.clone(),
38                                fields: vec![].into(),
39                            },
40                        );
41                    } else {
42                        // Constructor function
43                        members.insert(
44                            variant.name.clone(),
45                            Value::Builtin(format!("__ctor:{}:{}", type_name, variant.name)),
46                        );
47                    }
48                }
49                self.define(
50                    type_name.clone(),
51                    Value::Namespace {
52                        name: type_name.clone(),
53                        members,
54                    },
55                );
56            }
57            TypeDef::Product { name, fields, .. } => {
58                // Product types are constructed via Expr::RecordCreate.
59                // Keep declaration field order so runtime records are canonicalized
60                // and positional record matches stay stable.
61                let schema = fields.iter().map(|(field, _)| field.clone()).collect();
62                self.record_schemas.insert(name.clone(), schema);
63            }
64        }
65    }
66
67    pub fn exec_fn_def(&mut self, fd: &FnDef) -> Result<(), RuntimeError> {
68        let val = Value::Fn(Rc::new(crate::value::FunctionValue {
69            name: Rc::new(fd.name.clone()),
70            params: Rc::new(fd.params.clone()),
71            return_type: Rc::new(fd.return_type.clone()),
72            effects: Rc::new(fd.effects.clone()),
73            body: Rc::clone(&fd.body),
74            lowered_body: super::lowered::lower_fn_body(fd.body.as_ref()),
75            resolution: fd.resolution.clone(),
76            memo_eligible: self.memo_fns.contains(&fd.name),
77            home_globals: None,
78        }));
79        self.define(fd.name.clone(), val);
80        Ok(())
81    }
82
83    pub fn exec_stmt(&mut self, stmt: &Stmt) -> Result<Value, RuntimeError> {
84        match stmt {
85            Stmt::Binding(name, _, expr) => {
86                let val = self.eval_expr(expr)?;
87                self.define(name.clone(), val);
88                Ok(Value::Unit)
89            }
90            Stmt::Expr(expr) => self.eval_expr(expr),
91        }
92    }
93
94    pub fn exec_body(&mut self, stmts: &[Stmt]) -> Result<Value, RuntimeError> {
95        let mut last = Value::Unit;
96        for stmt in stmts {
97            last = self.exec_stmt(stmt)?;
98        }
99        Ok(last)
100    }
101
102    pub fn run_file(&mut self, source: &str) -> Result<Value, RuntimeError> {
103        let mut items = parse_source(source).map_err(RuntimeError::Error)?;
104        crate::resolver::resolve_program(&mut items);
105
106        // First pass: register all top-level definitions
107        for item in &items {
108            match item {
109                TopLevel::FnDef(fd) => self.exec_fn_def(fd)?,
110                TopLevel::Stmt(s) => {
111                    self.exec_stmt(s)?;
112                }
113                _ => {}
114            }
115        }
116
117        // Second pass: run main() if it exists
118        let main_fn = self.lookup("main");
119        if let Ok(fn_val) = main_fn {
120            let allowed = Self::callable_declared_effects(&fn_val);
121            self.call_value_with_effects_pub(fn_val, vec![], "<main>", allowed)?;
122        }
123
124        Ok(Value::Unit)
125    }
126}