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