1use crate::{context::Context, module::Module, value::Value, vm::VM};
2use anyhow::Result;
3use indexmap::IndexMap;
4use log::debug;
5use roan_ast::{
6 AccessKind, Assign, AssignOperator, BinOpKind, Binary, Expr, GetSpan, LiteralType, Spread,
7 UnOpKind, Unary, VecExpr,
8};
9use roan_error::error::{
10 RoanError,
11 RoanError::{InvalidSpread, StaticMemberAssignment, VariableNotFoundError},
12};
13
14impl Module {
15 pub fn interpret_expr(&mut self, expr: &Expr, ctx: &mut Context, vm: &mut VM) -> Result<()> {
26 let val: Result<Value> = match expr {
27 Expr::Variable(v) => {
28 debug!("Interpreting variable: {}", v.ident);
29
30 let variable: &Value = self
31 .find_variable(&v.ident)
32 .or_else(|| {
33 let constant = self.find_const(&v.ident);
34
35 if let Some(constant) = constant {
36 Some(&constant.value)
37 } else {
38 None
39 }
40 })
41 .ok_or_else(|| VariableNotFoundError(v.ident.clone(), v.token.span.clone()))?;
42
43 Ok(variable.clone())
44 }
45 Expr::Literal(l) => {
46 debug!("Interpreting literal: {:?}", l);
47
48 Ok(Value::from_literal(l.clone()))
49 }
50 Expr::Call(call) => self.interpret_call(call, ctx, vm),
51 Expr::Parenthesized(p) => {
52 debug!("Interpreting parenthesized: {:?}", p);
53
54 self.interpret_expr(&p.expr, ctx, vm)?;
55
56 Ok(vm.pop().unwrap())
57 }
58 Expr::Access(access) => self.interpret_access(access.clone(), ctx, vm),
59 Expr::StructConstructor(constructor) => {
60 self.interpret_struct_constructor(constructor.clone(), ctx, vm)
61 }
62 Expr::Assign(assign) => self.interpret_assignment(assign.clone(), ctx, vm),
63 Expr::Vec(vec) => self.interpret_vec(vec.clone(), ctx, vm),
64 Expr::Binary(b) => self.interpret_binary(b.clone(), ctx, vm),
65 Expr::Spread(s) => Err(InvalidSpread(s.expr.span()).into()),
67 Expr::Null(_) => Ok(Value::Null),
68 Expr::Unary(u) => self.interpret_unary(u.clone(), ctx, vm),
69 Expr::ThenElse(then_else) => self.interpret_then_else(then_else.clone(), ctx, vm),
70 Expr::Object(obj) => {
71 let mut fields = IndexMap::new();
72
73 for (field_name, expr) in obj.fields.iter() {
74 self.interpret_expr(expr, ctx, vm)?;
75 fields.insert(field_name.clone(), vm.pop().unwrap());
76 }
77
78 Ok(Value::Object(fields))
79 }
80 };
81
82 Ok(vm.push(val?))
83 }
84
85 pub fn interpret_unary(&mut self, u: Unary, ctx: &mut Context, vm: &mut VM) -> Result<Value> {
95 self.interpret_expr(&u.expr, ctx, vm)?;
96 let val = vm.pop().unwrap();
97
98 let val = match (u.operator.clone().kind, val.clone()) {
99 (UnOpKind::Minus, Value::Int(i)) => Value::Int(-i),
100 (UnOpKind::Minus, Value::Float(f)) => Value::Float(-f),
101 (UnOpKind::LogicalNot, Value::Bool(b)) => Value::Bool(!b),
102 (UnOpKind::BitwiseNot, Value::Int(i)) => Value::Int(!i),
103 (UnOpKind::LogicalNot, Value::Null) => Value::Bool(true),
104 (UnOpKind::LogicalNot, _) => {
105 let b = val.is_truthy();
106
107 Value::Bool(!b)
108 }
109 _ => {
110 return Err(
111 RoanError::InvalidUnaryOperation(u.operator.kind.to_string(), u.span()).into(),
112 )
113 }
114 };
115
116 Ok(val)
117 }
118
119 pub fn interpret_vec(&mut self, vec: VecExpr, ctx: &mut Context, vm: &mut VM) -> Result<Value> {
128 debug!("Interpreting vec: {:?}", vec);
129
130 Ok(Value::Vec(
131 self.interpret_possible_spread(vec.exprs, ctx, vm)?,
132 ))
133 }
134
135 pub fn interpret_binary(
144 &mut self,
145 binary_expr: Binary,
146 ctx: &mut Context,
147 vm: &mut VM,
148 ) -> Result<Value> {
149 debug!("Interpreting binary: {:?}", binary_expr);
150
151 self.interpret_expr(&binary_expr.left, ctx, vm)?;
152 let left = vm.pop().unwrap();
153 self.interpret_expr(&binary_expr.right, ctx, vm)?;
154 let right = vm.pop().unwrap();
155
156 let val = match (left.clone(), binary_expr.operator, right.clone()) {
157 (_, BinOpKind::Plus, _) => left + right,
158 (_, BinOpKind::Minus, _) => left - right,
159 (_, BinOpKind::Multiply, _) => left * right,
160 (_, BinOpKind::Divide, _) => left / right,
161 (_, BinOpKind::Modulo, _) => left % right,
162 (_, BinOpKind::Equals, _) => Value::Bool(left == right),
163 (_, BinOpKind::BangEquals, _) => Value::Bool(left != right),
164 (_, BinOpKind::Power, _) => left.pow(right),
165
166 (_, BinOpKind::GreaterThan, _) => Value::Bool(left > right),
167 (_, BinOpKind::LessThan, _) => Value::Bool(left < right),
168 (_, BinOpKind::GreaterThanOrEqual, _) => Value::Bool(left >= right),
169 (_, BinOpKind::LessThanOrEqual, _) => Value::Bool(left <= right),
170
171 (Value::Bool(a), BinOpKind::And, Value::Bool(b)) => Value::Bool(a && b),
172 (Value::Bool(a), BinOpKind::Or, Value::Bool(b)) => Value::Bool(a || b),
173
174 (Value::Int(a), BinOpKind::BitwiseAnd, Value::Int(b)) => Value::Int(a & b),
175 (Value::Int(a), BinOpKind::BitwiseOr, Value::Int(b)) => Value::Int(a | b),
176 (Value::Int(a), BinOpKind::BitwiseXor, Value::Int(b)) => Value::Int(a ^ b),
177 (Value::Int(a), BinOpKind::ShiftLeft, Value::Int(b)) => Value::Int(a << b),
178 (Value::Int(a), BinOpKind::ShiftRight, Value::Int(b)) => Value::Int(a >> b),
179
180 _ => todo!("missing binary operator: {:?}", binary_expr.operator),
181 };
182
183 Ok(val)
184 }
185
186 pub fn interpret_spread(
198 &mut self,
199 s: Spread,
200 ctx: &mut Context,
201 vm: &mut VM,
202 values: &mut Vec<Value>,
203 ) -> Result<()> {
204 self.interpret_expr(&s.expr, ctx, vm)?;
205 let spread_val = vm.pop().unwrap();
206
207 if let Value::Vec(vec) = spread_val {
208 values.extend(vec);
209 } else {
210 return Err(InvalidSpread(s.expr.span()).into());
211 }
212
213 Ok(())
214 }
215
216 pub fn interpret_possible_spread(
223 &mut self,
224 exprs: Vec<Expr>,
225 ctx: &mut Context,
226 vm: &mut VM,
227 ) -> Result<Vec<Value>> {
228 let mut values = vec![];
229
230 for expr in exprs.iter() {
231 match expr {
232 Expr::Spread(s) => self.interpret_spread(s.clone(), ctx, vm, &mut values)?,
233 _ => {
234 self.interpret_expr(expr, ctx, vm)?;
235 values.push(vm.pop().unwrap());
236 }
237 }
238 }
239
240 Ok(values)
241 }
242
243 pub fn interpret_assignment(
252 &mut self,
253 assign: Assign,
254 ctx: &mut Context,
255 vm: &mut VM,
256 ) -> Result<Value> {
257 debug!("Interpreting assign: {:?}", assign);
258 let left = assign.left.as_ref();
259 let right = assign.right.as_ref();
260 let operator = assign.op.clone();
261
262 match left {
263 Expr::Variable(v) => {
264 self.interpret_expr(right, ctx, vm)?;
265 let val = vm.pop().unwrap();
266 let ident = v.ident.clone();
267 let final_val = val.clone();
268 match operator {
269 AssignOperator::Assign => self.set_variable(&ident, val.clone())?,
270 AssignOperator::PlusEquals => {
271 self.update_variable(&ident, val, |a, b| a + b)?
272 }
273 AssignOperator::MinusEquals => {
274 self.update_variable(&ident, val, |a, b| a - b)?
275 }
276 AssignOperator::MultiplyEquals => {
277 self.update_variable(&ident, val, |a, b| a * b)?
278 }
279 AssignOperator::DivideEquals => {
280 self.update_variable(&ident, val, |a, b| a / b)?
281 }
282 }
283 Ok(final_val)
284 }
285 Expr::Access(access) => match &access.access {
286 AccessKind::Field(field) => {
287 let base = access.base.as_ref().clone();
288
289 self.interpret_expr(right, ctx, vm)?;
290 let new_val = vm.pop().unwrap();
291
292 self.interpret_expr(&base, ctx, vm)?;
293 let base_val = vm.pop().unwrap();
294
295 let field_name = {
296 let field = field.as_ref().clone();
297 match field {
298 Expr::Variable(v) => v.ident.clone(),
299 Expr::Literal(l) => match l.value.clone() {
300 LiteralType::String(s) => s,
301 _ => panic!("Invalid field name"),
302 },
303 _ => panic!("Invalid field name"),
305 }
306 };
307
308 match base_val {
309 Value::Object(mut fields) => {
310 fields.insert(field_name, new_val.clone());
311
312 if let Some(var_name) = Self::extract_variable_name(&access.base) {
313 self.set_variable(&var_name, Value::Object(fields))?;
314 Ok(new_val)
315 } else {
316 Err(RoanError::InvalidAssignment(
317 "Unable to determine variable for assignment".into(),
318 access.base.span(),
319 )
320 .into())
321 }
322 }
323 Value::Struct(_, _) => todo!("Finish field assignment for struct"),
324 _ => Err(RoanError::TypeMismatch(
325 "Left side of assignment must be a struct or object".into(),
326 access.base.span(),
327 )
328 .into()),
329 }
330 }
331 AccessKind::Index(index_expr) => {
332 self.interpret_expr(&access.base, ctx, vm)?;
333 let base_val = vm.pop().unwrap();
334
335 self.interpret_expr(index_expr, ctx, vm)?;
336 let index_val = vm.pop().unwrap();
337
338 self.interpret_expr(right, ctx, vm)?;
339 let new_val = vm.pop().unwrap();
340
341 if let (Value::Vec(mut vec), Value::Int(index)) = (base_val.clone(), index_val)
342 {
343 let idx = index as usize;
344 if idx >= vec.len() {
345 return Err(RoanError::IndexOutOfBounds(
346 idx,
347 vec.len(),
348 index_expr.span(),
349 )
350 .into());
351 }
352
353 vec[idx] = new_val.clone();
354
355 if let Some(var_name) = Self::extract_variable_name(&access.base) {
356 self.set_variable(&var_name, Value::Vec(vec))?;
357 Ok(new_val)
358 } else {
359 Err(RoanError::InvalidAssignment(
360 "Unable to determine variable for assignment".into(),
361 access.base.span(),
362 )
363 .into())
364 }
365 } else {
366 Err(RoanError::TypeMismatch(
367 "Left side of assignment must be a vector with integer index".into(),
368 access.base.span(),
369 )
370 .into())
371 }
372 }
373 AccessKind::StaticMethod(_) => Err(StaticMemberAssignment(access.span()).into()),
374 },
375 _ => todo!("missing left: {:?}", left),
376 }
377 }
378}