1use std::collections::HashMap;
2
3use lorgn_lang::ast::{Expr, Name};
4
5use crate::{Module, Value};
6
7pub struct Runtime {
8 modules: HashMap<Name, Module>,
9}
10
11impl Default for Runtime {
12 fn default() -> Self {
13 let modules = HashMap::new();
14 Self { modules }
15 }
16}
17
18impl Runtime {
19 pub fn register(&mut self, module: Module) {
20 self.modules.insert(module.name().clone(), module);
21 }
22
23 pub fn evaluate(&mut self, expression: Expr) -> Value {
24 let mut context = self.context();
25 context.run_expr(&expression)
26 }
27
28 fn context(&mut self) -> Context {
29 Context::new(&mut self.modules)
30 }
31}
32
33pub use eval_result::EvRes;
34mod eval_result;
35
36pub struct Scope {
37 bubble_variables: bool,
38 variables: HashMap<Name, Value>,
39}
40
41impl Scope {
42 pub fn new(bubble_variables: bool) -> Self {
43 let variables = HashMap::new();
44 Self {
45 bubble_variables,
46 variables,
47 }
48 }
49
50 pub fn new_with(variables: Vec<(Name, Value)>, bubble_variables: bool) -> Self {
51 let mut result = Self::new(bubble_variables);
52 for (name, value) in variables {
53 result.insert(name, value)
54 }
55 result
56 }
57
58 pub fn insert(&mut self, name: Name, value: Value) {
59 self.variables.insert(name, value);
60 }
61
62 pub fn get(&self, name: &Name) -> Option<&Value> {
63 self.variables.get(name)
64 }
65
66 pub fn get_mut(&mut self, name: &Name) -> Option<&mut Value> {
67 self.variables.get_mut(name)
68 }
69}
70
71pub use context::Context;
72mod context {
73 use std::{cell::RefMut, collections::HashMap};
74
75 use lorgn_lang::ast::{
76 Assignment, Block, Break, Condition, Expr, FnCall, FnDef, Invoke, Litteral, Loop, Name,
77 Path, Return,
78 };
79
80 use crate::{Function, Module, Value};
81
82 use super::{EvRes, Scope};
83
84 pub struct Context<'r> {
85 modules: &'r HashMap<Name, Module>,
86 scopes: Vec<Scope>,
87 }
88
89 impl<'r> Context<'r> {
90 pub fn new(modules: &'r mut HashMap<Name, Module>) -> Self {
91 let scopes = vec![];
92 Self { modules, scopes }
93 }
94
95 pub fn find_function(&self, path: &Path) -> Option<RefMut<Function>> {
96 self.modules
97 .get(&path.module)
98 .and_then(|m| m.get_function(&path.item))
99 }
100
101 pub fn find_variable(&mut self, name: &Name) -> Option<&mut Value> {
102 for scope in self.scopes.iter_mut().rev() {
103 if !scope.bubble_variables {
104 return None;
105 }
106 if let Some(result) = scope.variables.get_mut(name) {
107 return Some(result);
108 }
109 }
110 None
111 }
112
113 pub fn run_fun(&mut self, fn_def: &FnDef, params: Vec<Value>) -> Value {
114 let variables = fn_def
115 .parameters
116 .iter()
117 .cloned()
118 .zip(params.into_iter())
119 .collect();
120 self.push_scope(Scope::new_with(variables, false));
121 let res = self.eval_block(&fn_def.expressions);
122 self.pop_scope();
123 match res {
124 EvRes::Value(res) => res,
125 EvRes::ReturnSC(res) => res,
126 EvRes::BreakSC(_) => panic!("break outside of loop"),
127 }
128 }
129
130 pub fn run_expr(&mut self, expr: &Expr) -> Value {
131 self.eval_expr(expr).into_value().unwrap()
132 }
133
134 fn push_scope(&mut self, scope: Scope) {
135 self.scopes.push(scope)
136 }
137
138 fn pop_scope(&mut self) {
139 self.scopes.pop();
140 }
141
142 pub fn top_scope(&mut self) -> Option<&mut Scope> {
143 self.scopes.last_mut()
144 }
145
146 pub fn top_index(&self) -> usize {
147 self.scopes.len() - 1
148 }
149
150 fn eval_expr(&mut self, expr: &Expr) -> EvRes {
151 match expr {
152 Expr::Block(block) => self.eval_block(block),
153 Expr::Assignment(assignment) => self.eval_assignment(assignment),
154 Expr::Invoke(invoke) => self.eval_invoke(invoke),
155 Expr::Litteral(litteral) => self.eval_litteral(litteral),
156 Expr::FnCall(fn_call) => self.eval_fn_call(fn_call),
157 Expr::Condition(condition) => self.eval_condition(condition),
158 Expr::Loop(loop_) => self.eval_loop(loop_),
159 Expr::Return(return_) => self.eval_return(return_),
160 Expr::Break(break_) => self.eval_break(break_),
161 }
162 }
163
164 fn eval_block(&mut self, block: &Block) -> EvRes {
165 let mut last = None;
166 for expr in &block.expressions {
167 let result = self.eval_expr(expr);
168 if let EvRes::Value(result) = result {
169 last = Some(result);
170 } else {
171 return result;
172 }
173 }
174 let result = last.unwrap_or(Value::None);
175 EvRes::new_val(result)
176 }
177
178 fn eval_assignment(&mut self, assignment: &Assignment) -> EvRes {
179 let result = self.eval_expr(&assignment.value);
180 if let EvRes::Value(result) = result {
181 let name = assignment.variable_name.clone();
182 self.top_scope().unwrap().insert(name, result.clone());
183 EvRes::new_val(result)
184 } else {
185 result
186 }
187 }
188
189 fn eval_invoke(&mut self, invoke: &Invoke) -> EvRes {
190 let value = self.find_variable(&invoke.variable_name).unwrap().clone();
191 EvRes::new_val(value)
192 }
193
194 fn eval_litteral(&mut self, litteral: &Litteral) -> EvRes {
195 match litteral {
196 Litteral::String(str) => EvRes::Value(str.clone().into()),
197 Litteral::Integer(int) => EvRes::Value((*int).into()),
198 Litteral::Float(flt) => EvRes::Value((*flt).into()),
199 Litteral::Bool(bool) => EvRes::Value((*bool).into()),
200 Litteral::List(vec) => {
201 let mut results = vec![];
202 for expr in vec {
203 let result = self.eval_expr(expr);
204 if let EvRes::Value(result) = result {
205 results.push(result);
206 } else {
207 return result;
208 }
209 }
210 EvRes::Value(results.into())
211 }
212 Litteral::Map(map) => {
213 let mut results = HashMap::new();
214 for (name, expr) in map {
215 let result = self.eval_expr(expr);
216 if let EvRes::Value(result) = result {
217 results.insert(name.clone(), result);
218 } else {
219 return result;
220 }
221 }
222 EvRes::Value(results.into())
223 }
224 }
225 }
226
227 fn eval_fn_call(&mut self, fn_call: &FnCall) -> EvRes {
228 let mut args = vec![];
229 for arg in &fn_call.arguments {
230 let res = self.eval_expr(arg);
231 if res.is_short_circuit() {
232 return res;
233 }
234 args.push(res.into_value().unwrap());
235 }
236 let path = &fn_call.fn_path;
237 let module = self.modules.get(&path.module).unwrap();
238 let mut function = module.get_function(&path.item).unwrap();
239 let res = function.call(args, self);
240 EvRes::Value(res)
241 }
242
243 fn eval_condition(&mut self, condition: &Condition) -> EvRes {
244 let cond = self.eval_expr(&condition.condition);
245 if cond.is_short_circuit() {
246 return cond;
247 }
248 let cond = cond.into_value().unwrap();
249 if cond.into_bool().unwrap() {
250 self.eval_expr(&condition.true_case)
251 } else {
252 self.eval_expr(&condition.false_case)
253 }
254 }
255
256 fn eval_loop(&mut self, loop_: &Loop) -> EvRes {
257 let body = &loop_.body;
258 let result = loop {
259 let res = self.eval_expr(body);
260 match res {
261 EvRes::ReturnSC(_) => return res,
262 EvRes::BreakSC(result) => break result,
263 _ => (),
264 };
265 };
266 EvRes::new_val(result)
267 }
268
269 fn eval_return(&mut self, return_: &Return) -> EvRes {
270 let result = self.eval_expr(&return_.expression);
271 match result {
272 EvRes::ReturnSC(_) => result,
273 EvRes::Value(v) => EvRes::ReturnSC(v),
274 EvRes::BreakSC(_) => panic!("break outside of loop"),
275 }
276 }
277
278 fn eval_break(&mut self, break_: &Break) -> EvRes {
279 let result = self.eval_expr(&break_.expression);
280 match result {
281 EvRes::ReturnSC(_) => result,
282 EvRes::Value(v) => EvRes::BreakSC(v),
283 EvRes::BreakSC(v) => EvRes::BreakSC(v),
284 }
285 }
286 }
287}