1use super::{
2 position::{Located, Position},
3 std::{
4 globals, BOOL_MODULE, CHAR_MODULE, FLOAT_MODULE, INT_MODULE, STRING_MODULE, VECTOR_MODULE,
5 },
6};
7use crate::lang::{
8 code::{Address, BinaryOperation, ByteCode, Location, Register, Source, UnaryOperation},
9 value::{Function, FunctionKind, Object, Value, META_CALL, META_GET, META_SET},
10};
11use std::{cell::RefCell, collections::HashMap, error::Error, fmt::Display, rc::Rc};
12
13pub const CALL_STACK_CAP: usize = 0xffff;
14
15#[derive(Debug, Clone)]
16pub struct Interpreter {
17 pub call_frames: Vec<CallFrame>,
18 pub globals: Rc<RefCell<HashMap<String, Rc<RefCell<Value>>>>>,
19 pub global_path: Option<String>,
20}
21#[derive(Debug, Clone)]
22pub struct CallFrame {
23 pub function: Rc<Function>,
24 pub stack: Vec<Rc<RefCell<Value>>>,
25 pub idx: Address,
26 pub dst: Option<Location>,
27 pub globals: Rc<RefCell<HashMap<String, Rc<RefCell<Value>>>>>,
28}
29#[derive(Debug, Clone, PartialEq)]
30pub enum RunTimeError {
31 CannotCall(String),
32 CannotIter(String),
33 CannotFieldInto {
34 head: String,
35 field: String,
36 },
37 CannotField(String),
38 CannotSetFieldWith {
39 head: String,
40 field: String,
41 },
42 CannotSetField(String),
43 InvalidSetIndex(usize),
44 InvalidBinary {
45 op: BinaryOperation,
46 left: String,
47 right: String,
48 },
49 InvalidUnary {
50 op: UnaryOperation,
51 right: String,
52 },
53 Custom(String),
54}
55
56impl Default for Interpreter {
57 fn default() -> Self {
58 Self {
59 call_frames: Vec::with_capacity(CALL_STACK_CAP),
60 globals: Rc::new(RefCell::new(globals())),
61 global_path: None,
62 }
63 }
64}
65impl Interpreter {
66 #[inline(always)]
67 pub fn with_global_path(mut self, path: Option<String>) -> Self {
68 self.global_path = path;
69 self
70 }
71}
72impl Interpreter {
73 #[inline(always)]
74 pub fn path(&self) -> Option<String> {
75 self.call_frames
76 .last()?
77 .function
78 .closure
79 .borrow()
80 .path
81 .clone()
82 }
83 #[inline(always)]
84 pub fn call(&mut self, function: &Rc<Function>, args: Vec<Value>, dst: Option<Location>) {
85 let mut stack = Vec::with_capacity(function.closure.borrow().registers as usize + 1);
86 let args_len = args.len();
87 stack.extend(args.into_iter().map(|v| Rc::new(RefCell::new(v))));
88 stack.extend(
89 (args_len..function.closure.borrow().registers as usize + 1)
90 .map(|_| Rc::new(RefCell::new(Value::default()))),
91 );
92 self.call_frames.push(CallFrame {
93 function: Rc::clone(function),
94 stack,
95 idx: 0,
96 dst,
97 globals: Rc::clone(&self.globals),
98 });
99 }
100 #[inline(always)]
101 pub fn return_call(&mut self, src: Option<Source>) -> Option<Value> {
102 let top_frame = self.call_frames.pop().expect("no frame on stack");
103 if let Some(prev_frame) = self.call_frames.last_mut() {
104 if let Some(dst) = top_frame.dst {
105 let value = top_frame
106 .source(&src.unwrap_or_default())
107 .expect("source not found");
108 let dst = prev_frame.location(&dst).expect("location not found");
109 *dst.borrow_mut() = value;
110 }
111 }
112 if let Some(src) = src {
113 return Some(top_frame.source(&src).expect("source not found"));
114 }
115 None
116 }
117 #[inline(always)]
118 pub fn call_kind(
119 &mut self,
120 kind: FunctionKind,
121 args: Vec<Value>,
122 dst: Option<Location>,
123 pos: Position,
124 ) -> Result<(), Located<RunTimeError>> {
125 match kind {
126 FunctionKind::Function(function) => {
127 self.call(&function, args, dst);
128 Ok(())
129 }
130 FunctionKind::UserFunction(func) => {
131 let dst = dst.map(|dst| {
132 self.call_frames
133 .last_mut()
134 .expect("no call frame")
135 .location(&dst)
136 .expect("dst not found")
137 });
138 let value = func(self, args)
139 .map_err(|err| Located::new(RunTimeError::Custom(err.to_string()), pos))?;
140 if let Some(dst) = dst {
141 *dst.borrow_mut() = value;
142 }
143 Ok(())
144 }
145 }
146 }
147 pub fn step(&mut self) -> Result<Option<Value>, Located<RunTimeError>> {
148 let idx = self.call_frames.last_mut().expect("no call frame").idx;
149 let Located {
150 value: bytecode,
151 pos,
152 } = self
153 .call_frames
154 .last_mut()
155 .expect("no call frame")
156 .function
157 .closure
158 .borrow()
159 .code
160 .get(idx as usize)
161 .cloned()
162 .expect("idx out of range");
163 self.call_frames.last_mut().expect("no call frame").idx += 1;
164 match bytecode {
165 ByteCode::None => {}
166 ByteCode::Jump { addr } => {
167 self.call_frames.last_mut().expect("no call frame").idx = addr;
168 }
169 ByteCode::JumpIf {
170 negative: false,
171 cond,
172 addr,
173 } => {
174 if self
175 .call_frames
176 .last_mut()
177 .expect("no call frame")
178 .source(&cond)
179 .expect("cond not found")
180 .into()
181 {
182 self.call_frames.last_mut().expect("no call frame").idx = addr;
183 }
184 }
185 ByteCode::JumpIf {
186 negative: true,
187 cond,
188 addr,
189 } => {
190 if !bool::from(
191 self.call_frames
192 .last_mut()
193 .expect("no call frame")
194 .source(&cond)
195 .expect("cond not found"),
196 ) {
197 self.call_frames.last_mut().expect("no call frame").idx = addr;
198 }
199 }
200 ByteCode::JumpNull { negative: false, cond, addr } => {
201 if self
202 .call_frames
203 .last_mut()
204 .expect("no call frame")
205 .source(&cond)
206 .expect("cond not found")
207 == Value::default()
208 {
209 self.call_frames.last_mut().expect("no call frame").idx = addr;
210 }
211 }
212 ByteCode::JumpNull { negative: true, cond, addr } => {
213 if self
214 .call_frames
215 .last_mut()
216 .expect("no call frame")
217 .source(&cond)
218 .expect("cond not found")
219 != Value::default()
220 {
221 self.call_frames.last_mut().expect("no call frame").idx = addr;
222 }
223 }
224 ByteCode::CallSingle { dst, func, arg } => {
225 let func = self
226 .call_frames
227 .last_mut()
228 .expect("no call frame")
229 .source(&func)
230 .expect("func not found");
231 let mut args = vec![self
232 .call_frames
233 .last_mut()
234 .expect("no call frame")
235 .source(&arg)
236 .expect("func not found")];
237 match func {
238 Value::Function(kind) => self.call_kind(kind, args, dst, pos)?,
239 Value::Object(object) => {
240 args.insert(0, Value::Object(Rc::clone(&object)));
241 let object = object.borrow();
242 if let Some(Value::Function(kind)) = object.get_meta(META_CALL) {
243 self.call_kind(kind, args, dst, pos)?;
244 }
245 }
246 value => {
247 return Err(Located::new(
248 RunTimeError::CannotCall(value.dynamic_typ()),
249 pos,
250 ))
251 }
252 };
253 }
254 ByteCode::CallZero { dst, func } => {
255 let func = self
256 .call_frames
257 .last_mut()
258 .expect("no call frame")
259 .source(&func)
260 .expect("func not found");
261 let mut args = Vec::with_capacity(1);
262 match func {
263 Value::Function(kind) => self.call_kind(kind, args, dst, pos)?,
264 Value::Object(object) => {
265 args.insert(0, Value::Object(Rc::clone(&object)));
266 let object = object.borrow();
267 if let Some(Value::Function(kind)) = object.get_meta(META_CALL) {
268 self.call_kind(kind, args, dst, pos)?;
269 }
270 }
271 value => {
272 return Err(Located::new(
273 RunTimeError::CannotCall(value.dynamic_typ()),
274 pos,
275 ))
276 }
277 };
278 }
279 ByteCode::Call {
280 dst,
281 func,
282 offset,
283 amount,
284 } => {
285 let func = self
286 .call_frames
287 .last_mut()
288 .expect("no call frame")
289 .source(&func)
290 .expect("func not found");
291 let mut args = Vec::with_capacity(amount as usize);
292 for register in offset..offset + amount as Register {
293 args.push(
294 self.call_frames
295 .last_mut()
296 .expect("no call frame")
297 .register(register)
298 .expect("register out of range")
299 .borrow()
300 .clone(),
301 )
302 }
303 match func {
304 Value::Function(kind) => self.call_kind(kind, args, dst, pos)?,
305 Value::Object(object) => {
306 args.insert(0, Value::Object(Rc::clone(&object)));
307 let object = object.borrow();
308 if let Some(Value::Function(kind)) = object.get_meta(META_CALL) {
309 self.call_kind(kind, args, dst, pos)?;
310 }
311 }
312 value => {
313 return Err(Located::new(
314 RunTimeError::CannotCall(value.dynamic_typ()),
315 pos,
316 ))
317 }
318 };
319 }
320 ByteCode::Return { src } => return Ok(self.return_call(src)),
321 ByteCode::Move { dst, src } => {
322 let dst = self
323 .call_frames
324 .last_mut()
325 .expect("no call frame")
326 .location(&dst)
327 .expect("location not found");
328 let value = self
329 .call_frames
330 .last_mut()
331 .expect("no call frame")
332 .source(&src)
333 .expect("source not found");
334 *dst.borrow_mut() = value;
335 }
336 ByteCode::Field { dst, head, field } => {
337 let dst_value = self
338 .call_frames
339 .last_mut()
340 .expect("no call frame")
341 .location(&dst)
342 .expect("location not found");
343 let head = self
344 .call_frames
345 .last_mut()
346 .expect("no call frame")
347 .source(&head)
348 .expect("source not found");
349 let field = self
350 .call_frames
351 .last_mut()
352 .expect("no call frame")
353 .source(&field)
354 .expect("source not found");
355 *dst_value.borrow_mut() = match &head {
356 Value::Object(object) => {
357 if let Some(Value::Function(kind)) = object.borrow().get_meta(META_GET) {
358 self.call_kind(
359 kind,
360 vec![head.clone(), field],
361 Some(dst),
362 pos.clone(),
363 )?;
364 return Ok(None);
365 }
366 match field {
367 Value::String(key) => object.borrow_mut().fields.get(&key).cloned(),
368 field => {
369 return Err(Located::new(
370 RunTimeError::CannotFieldInto {
371 head: Value::Object(Default::default()).dynamic_typ(),
372 field: field.dynamic_typ(),
373 },
374 pos,
375 ))
376 }
377 }
378 }
379 Value::UserObject(object) => match field {
380 Value::String(key) => object.borrow_mut().get(&key),
381 field => {
382 return Err(Located::new(
383 RunTimeError::CannotFieldInto {
384 head: Value::Object(Default::default()).dynamic_typ(),
385 field: field.dynamic_typ(),
386 },
387 pos,
388 ))
389 }
390 },
391 Value::Vector(vector) => match field {
392 Value::Int(index) => {
393 let vector = vector.borrow_mut();
394 let length = vector.len();
395 let index = if index < 0 {
396 let index = length as i64 + index;
397 if index < 0 {
398 length
399 } else {
400 index as usize
401 }
402 } else {
403 index.unsigned_abs() as usize
404 };
405 vector.get(index).cloned()
406 }
407 Value::String(key) => {
408 if let Value::Object(object) = self
409 .globals
410 .borrow()
411 .get(VECTOR_MODULE)
412 .cloned()
413 .unwrap_or_default()
414 .borrow()
415 .clone()
416 {
417 let object = object.borrow();
418 object.fields.get(&key).cloned()
419 } else {
420 Some(Value::default())
421 }
422 }
423 field => {
424 return Err(Located::new(
425 RunTimeError::CannotFieldInto {
426 head: Value::Vector(Default::default()).dynamic_typ(),
427 field: field.dynamic_typ(),
428 },
429 pos,
430 ))
431 }
432 },
433 Value::String(string) => match field {
434 Value::Int(index) => {
435 let length = string.len();
436 let index = if index < 0 {
437 let index = length as i64 + index;
438 if index < 0 {
439 length
440 } else {
441 index as usize
442 }
443 } else {
444 index.unsigned_abs() as usize
445 };
446 string
447 .get(index..=index)
448 .and_then(|s| s.chars().next())
449 .map(Value::Char)
450 }
451 Value::String(key) => {
452 if let Value::Object(object) = self
453 .globals
454 .borrow()
455 .get(STRING_MODULE)
456 .cloned()
457 .unwrap_or_default()
458 .borrow()
459 .clone()
460 {
461 let object = object.borrow();
462 object.fields.get(&key).cloned()
463 } else {
464 Some(Value::default())
465 }
466 }
467 field => {
468 return Err(Located::new(
469 RunTimeError::CannotFieldInto {
470 head: Value::String(Default::default()).dynamic_typ(),
471 field: field.dynamic_typ(),
472 },
473 pos,
474 ))
475 }
476 },
477 Value::Int(_) => match field {
478 Value::String(key) => {
479 if let Value::Object(object) = self
480 .globals
481 .borrow()
482 .get(INT_MODULE)
483 .cloned()
484 .unwrap_or_default()
485 .borrow()
486 .clone()
487 {
488 let object = object.borrow();
489 object.fields.get(&key).cloned()
490 } else {
491 Some(Value::default())
492 }
493 }
494 field => {
495 return Err(Located::new(
496 RunTimeError::CannotFieldInto {
497 head: Value::String(Default::default()).dynamic_typ(),
498 field: field.dynamic_typ(),
499 },
500 pos,
501 ))
502 }
503 },
504 Value::Float(_) => match field {
505 Value::String(key) => {
506 if let Value::Object(object) = self
507 .globals
508 .borrow()
509 .get(FLOAT_MODULE)
510 .cloned()
511 .unwrap_or_default()
512 .borrow()
513 .clone()
514 {
515 let object = object.borrow();
516 object.fields.get(&key).cloned()
517 } else {
518 Some(Value::default())
519 }
520 }
521 field => {
522 return Err(Located::new(
523 RunTimeError::CannotFieldInto {
524 head: Value::String(Default::default()).dynamic_typ(),
525 field: field.dynamic_typ(),
526 },
527 pos,
528 ))
529 }
530 },
531 Value::Bool(_) => match field {
532 Value::String(key) => {
533 if let Value::Object(object) = self
534 .globals
535 .borrow()
536 .get(BOOL_MODULE)
537 .cloned()
538 .unwrap_or_default()
539 .borrow()
540 .clone()
541 {
542 let object = object.borrow();
543 object.fields.get(&key).cloned()
544 } else {
545 Some(Value::default())
546 }
547 }
548 field => {
549 return Err(Located::new(
550 RunTimeError::CannotFieldInto {
551 head: Value::String(Default::default()).dynamic_typ(),
552 field: field.dynamic_typ(),
553 },
554 pos,
555 ))
556 }
557 },
558 Value::Char(_) => match field {
559 Value::String(key) => {
560 if let Value::Object(object) = self
561 .globals
562 .borrow()
563 .get(CHAR_MODULE)
564 .cloned()
565 .unwrap_or_default()
566 .borrow()
567 .clone()
568 {
569 let object = object.borrow();
570 object.fields.get(&key).cloned()
571 } else {
572 Some(Value::default())
573 }
574 }
575 field => {
576 return Err(Located::new(
577 RunTimeError::CannotFieldInto {
578 head: Value::String(Default::default()).dynamic_typ(),
579 field: field.dynamic_typ(),
580 },
581 pos,
582 ))
583 }
584 },
585 head => {
586 return Err(Located::new(
587 RunTimeError::CannotField(head.dynamic_typ()),
588 pos,
589 ))
590 }
591 }
592 .unwrap_or_default();
593 }
594 ByteCode::SetField { head, field, src } => {
595 let value = self
596 .call_frames
597 .last_mut()
598 .expect("no call frame")
599 .source(&src)
600 .expect("source not found");
601 let head = self
602 .call_frames
603 .last_mut()
604 .expect("no call frame")
605 .source(&head)
606 .expect("source not found");
607 let field = self
608 .call_frames
609 .last_mut()
610 .expect("no call frame")
611 .source(&field)
612 .expect("source not found");
613 match &head {
614 Value::Object(object) => {
615 if let Some(Value::Function(kind)) = object.borrow().get_meta(META_SET) {
616 self.call_kind(
617 kind,
618 vec![head.clone(), field, value],
619 None,
620 pos.clone(),
621 )?;
622 return Ok(None);
623 }
624 let mut object = object.borrow_mut();
625 let old_value = match field {
626 Value::String(key) => {
627 if let Some(value) = object.fields.get_mut(&key) {
628 value
629 } else {
630 object.fields.insert(key.clone(), Value::default());
631 object.fields.get_mut(&key).unwrap()
632 }
633 }
634 field => {
635 return Err(Located::new(
636 RunTimeError::CannotSetFieldWith {
637 head: Value::Object(Default::default()).dynamic_typ(),
638 field: field.dynamic_typ(),
639 },
640 pos,
641 ))
642 }
643 };
644 *old_value = value;
645 }
646 Value::Vector(vector) => {
647 let mut vector = vector.borrow_mut();
648 match field {
649 Value::Int(index) => {
650 let length = vector.len();
651 let index = if index < 0 {
652 let index = length as i64 + index;
653 if index < 0 {
654 length
655 } else {
656 index as usize
657 }
658 } else {
659 index.unsigned_abs() as usize
660 };
661 if let Some(old_value) = vector.get_mut(index) {
662 *old_value = value;
663 } else {
664 return Err(Located::new(
665 RunTimeError::InvalidSetIndex(index),
666 pos,
667 ));
668 }
669 }
670 field => {
671 return Err(Located::new(
672 RunTimeError::CannotSetFieldWith {
673 head: Value::Vector(Default::default()).dynamic_typ(),
674 field: field.dynamic_typ(),
675 },
676 pos,
677 ))
678 }
679 }
680 }
681 head => {
682 return Err(Located::new(
683 RunTimeError::CannotSetField(head.dynamic_typ()),
684 pos,
685 ))
686 }
687 }
688 }
689 ByteCode::Vector { dst, start, amount } => {
690 let dst = self
691 .call_frames
692 .last_mut()
693 .expect("no call frame")
694 .location(&dst)
695 .expect("location not found");
696 let mut values = vec![];
697 for register in start..start + amount {
698 values.push(
699 self.call_frames
700 .last_mut()
701 .expect("no call frame")
702 .register(register)
703 .expect("register not found")
704 .borrow()
705 .clone(),
706 );
707 }
708 *dst.borrow_mut() = Value::Vector(Rc::new(RefCell::new(values)));
709 }
710 ByteCode::Object { dst, start, amount } => {
711 let dst = self
712 .call_frames
713 .last_mut()
714 .expect("no call frame")
715 .location(&dst)
716 .expect("location not found");
717 let mut object = Object::default();
718 for register in (start..start + amount * 2).step_by(2) {
719 let Value::String(field) = self
720 .call_frames
721 .last_mut()
722 .expect("no call frame")
723 .register(register)
724 .expect("register not found")
725 .borrow()
726 .clone()
727 else {
728 panic!("expected object field to be a string")
729 };
730 let value = self
731 .call_frames
732 .last_mut()
733 .expect("no call frame")
734 .register(register + 1)
735 .expect("register not found")
736 .borrow()
737 .clone();
738 object.fields.insert(field, value);
739 }
740 *dst.borrow_mut() = Value::Object(Rc::new(RefCell::new(object)));
741 }
742 ByteCode::Function { dst, addr } => {
743 let dst = self
744 .call_frames
745 .last_mut()
746 .expect("no call frame")
747 .location(&dst)
748 .expect("location not found");
749 let closure = Rc::clone(
750 self.call_frames
751 .last_mut()
752 .expect("no call frame on stack")
753 .function
754 .closure
755 .borrow()
756 .closures
757 .get(addr as usize)
758 .expect("closure not found"),
759 );
760 let mut upvalues = Vec::with_capacity(closure.borrow().upvalues.len());
761 for upvalue in closure.borrow().upvalues.iter() {
762 upvalues.push(if upvalue.depth == 0 {
763 self.call_frames
764 .last_mut()
765 .expect("no call frame")
766 .register(upvalue.register)
767 .expect("register not found")
768 } else if let Some(value) = self
769 .call_frames
770 .get(self.call_frames.len() - 1 - upvalue.depth as usize)
771 .map(|frame| {
772 frame
773 .register(upvalue.register)
774 .expect("register not found")
775 })
776 {
777 value
778 } else {
779 Rc::default()
780 });
781 }
782 *dst.borrow_mut() = Value::Function(FunctionKind::Function(Rc::new(Function {
783 upvalues,
784 closure,
785 })));
786 }
787 ByteCode::Binary {
788 op,
789 dst,
790 left,
791 right,
792 } => {
793 let dst_value = self
794 .call_frames
795 .last_mut()
796 .expect("no call frame")
797 .location(&dst)
798 .expect("location not found");
799 let left = self
800 .call_frames
801 .last_mut()
802 .expect("no call frame")
803 .source(&left)
804 .expect("source not found");
805 let right = self
806 .call_frames
807 .last_mut()
808 .expect("no call frame")
809 .source(&right)
810 .expect("source not found");
811 if let Value::Object(object) = &left {
812 if let Some(Value::Function(kind)) = {
813 let object = object.borrow();
814 object.get_meta(&format!("__{}", op))
815 } {
816 self.call_kind(kind, vec![left, right], Some(dst), pos)?;
817 return Ok(None);
818 }
819 }
820 *dst_value.borrow_mut() = match op {
821 BinaryOperation::Add => match (left, right) {
822 (Value::Int(left), Value::Int(right)) => Value::Int(left + right),
823 (Value::Float(left), Value::Float(right)) => Value::Float(left + right),
824 (Value::Int(left), Value::Float(right)) => {
825 Value::Float(left as f64 + right)
826 }
827 (Value::Float(left), Value::Int(right)) => {
828 Value::Float(left + right as f64)
829 }
830 (Value::String(left), Value::String(right)) => Value::String(left + &right),
831 (Value::String(mut left), Value::Char(right)) => {
832 left.push(right);
833 Value::String(left)
834 }
835 (left, right) => {
836 return Err(Located::new(
837 RunTimeError::InvalidBinary {
838 op,
839 left: left.dynamic_typ(),
840 right: right.dynamic_typ(),
841 },
842 pos,
843 ))
844 }
845 },
846 BinaryOperation::Sub => match (left, right) {
847 (Value::Int(left), Value::Int(right)) => Value::Int(left - right),
848 (Value::Float(left), Value::Float(right)) => Value::Float(left - right),
849 (Value::Int(left), Value::Float(right)) => {
850 Value::Float(left as f64 - right)
851 }
852 (Value::Float(left), Value::Int(right)) => {
853 Value::Float(left - right as f64)
854 }
855 (left, right) => {
856 return Err(Located::new(
857 RunTimeError::InvalidBinary {
858 op,
859 left: left.dynamic_typ(),
860 right: right.dynamic_typ(),
861 },
862 pos,
863 ))
864 }
865 },
866 BinaryOperation::Mul => match (left, right) {
867 (Value::Int(left), Value::Int(right)) => Value::Int(left * right),
868 (Value::Float(left), Value::Float(right)) => Value::Float(left * right),
869 (Value::Int(left), Value::Float(right)) => {
870 Value::Float(left as f64 * right)
871 }
872 (Value::Float(left), Value::Int(right)) => {
873 Value::Float(left * right as f64)
874 }
875 (left, right) => {
876 return Err(Located::new(
877 RunTimeError::InvalidBinary {
878 op,
879 left: left.dynamic_typ(),
880 right: right.dynamic_typ(),
881 },
882 pos,
883 ))
884 }
885 },
886 BinaryOperation::Div => match (left, right) {
887 (Value::Int(left), Value::Int(right)) => {
888 Value::Float(left as f64 / right as f64)
889 }
890 (Value::Float(left), Value::Float(right)) => Value::Float(left / right),
891 (Value::Int(left), Value::Float(right)) => {
892 Value::Float(left as f64 / right)
893 }
894 (Value::Float(left), Value::Int(right)) => {
895 Value::Float(left / right as f64)
896 }
897 (left, right) => {
898 return Err(Located::new(
899 RunTimeError::InvalidBinary {
900 op,
901 left: left.dynamic_typ(),
902 right: right.dynamic_typ(),
903 },
904 pos,
905 ))
906 }
907 },
908 BinaryOperation::Pow => match (left, right) {
909 (Value::Int(left), Value::Int(right)) => {
910 Value::Float((left as f64).powf(right as f64))
911 }
912 (Value::Float(left), Value::Float(right)) => Value::Float(left.powf(right)),
913 (Value::Int(left), Value::Float(right)) => {
914 Value::Float((left as f64).powf(right))
915 }
916 (Value::Float(left), Value::Int(right)) => {
917 Value::Float(left.powf(right as f64))
918 }
919 (left, right) => {
920 return Err(Located::new(
921 RunTimeError::InvalidBinary {
922 op,
923 left: left.dynamic_typ(),
924 right: right.dynamic_typ(),
925 },
926 pos,
927 ))
928 }
929 },
930 BinaryOperation::Mod => match (left, right) {
931 (Value::Int(left), Value::Int(right)) => Value::Int(left % right),
932 (Value::Float(left), Value::Float(right)) => Value::Float(left % right),
933 (Value::Int(left), Value::Float(right)) => {
934 Value::Float(left as f64 % right)
935 }
936 (Value::Float(left), Value::Int(right)) => {
937 Value::Float(left % right as f64)
938 }
939 (left, right) => {
940 return Err(Located::new(
941 RunTimeError::InvalidBinary {
942 op,
943 left: left.dynamic_typ(),
944 right: right.dynamic_typ(),
945 },
946 pos,
947 ))
948 }
949 },
950 BinaryOperation::EQ => Value::Bool(left == right),
951 BinaryOperation::NE => Value::Bool(left != right),
952 BinaryOperation::LT => match (left, right) {
953 (Value::Int(left), Value::Int(right)) => Value::Bool(left < right),
954 (Value::Float(left), Value::Float(right)) => Value::Bool(left < right),
955 (Value::Int(left), Value::Float(right)) => {
956 Value::Bool((left as f64) < right)
957 }
958 (Value::Float(left), Value::Int(right)) => Value::Bool(left < right as f64),
959 (left, right) => {
960 return Err(Located::new(
961 RunTimeError::InvalidBinary {
962 op,
963 left: left.dynamic_typ(),
964 right: right.dynamic_typ(),
965 },
966 pos,
967 ))
968 }
969 },
970 BinaryOperation::GT => match (left, right) {
971 (Value::Int(left), Value::Int(right)) => Value::Bool(left > right),
972 (Value::Float(left), Value::Float(right)) => Value::Bool(left > right),
973 (Value::Int(left), Value::Float(right)) => Value::Bool(left as f64 > right),
974 (Value::Float(left), Value::Int(right)) => Value::Bool(left > right as f64),
975 (left, right) => {
976 return Err(Located::new(
977 RunTimeError::InvalidBinary {
978 op,
979 left: left.dynamic_typ(),
980 right: right.dynamic_typ(),
981 },
982 pos,
983 ))
984 }
985 },
986 BinaryOperation::LE => match (left, right) {
987 (Value::Int(left), Value::Int(right)) => Value::Bool(left <= right),
988 (Value::Float(left), Value::Float(right)) => Value::Bool(left <= right),
989 (Value::Int(left), Value::Float(right)) => {
990 Value::Bool(left as f64 <= right)
991 }
992 (Value::Float(left), Value::Int(right)) => {
993 Value::Bool(left <= right as f64)
994 }
995 (left, right) => {
996 return Err(Located::new(
997 RunTimeError::InvalidBinary {
998 op,
999 left: left.dynamic_typ(),
1000 right: right.dynamic_typ(),
1001 },
1002 pos,
1003 ))
1004 }
1005 },
1006 BinaryOperation::GE => match (left, right) {
1007 (Value::Int(left), Value::Int(right)) => Value::Bool(left >= right),
1008 (Value::Float(left), Value::Float(right)) => Value::Bool(left >= right),
1009 (Value::Int(left), Value::Float(right)) => {
1010 Value::Bool(left as f64 >= right)
1011 }
1012 (Value::Float(left), Value::Int(right)) => {
1013 Value::Bool(left >= right as f64)
1014 }
1015 (left, right) => {
1016 return Err(Located::new(
1017 RunTimeError::InvalidBinary {
1018 op,
1019 left: left.dynamic_typ(),
1020 right: right.dynamic_typ(),
1021 },
1022 pos,
1023 ))
1024 }
1025 },
1026 BinaryOperation::And => Value::Bool(left.into() && right.into()),
1027 BinaryOperation::Or => Value::Bool(left.into() || right.into()),
1028 };
1029 }
1030 ByteCode::Unary { op, dst, src } => {
1031 let dst_value = self
1032 .call_frames
1033 .last_mut()
1034 .expect("no call frame")
1035 .location(&dst)
1036 .expect("location not found");
1037 let src = self
1038 .call_frames
1039 .last_mut()
1040 .expect("no call frame")
1041 .source(&src)
1042 .expect("source not found");
1043 if let Value::Object(object) = &src {
1044 if let Some(Value::Function(kind)) = {
1045 let object = object.borrow();
1046 object.get_meta(&format!("__{}", op))
1047 } {
1048 self.call_kind(kind, vec![src], Some(dst), pos)?;
1049 return Ok(None);
1050 }
1051 }
1052 *dst_value.borrow_mut() = match op {
1053 UnaryOperation::Neg => match src {
1054 Value::Int(v) => Value::Int(-v),
1055 Value::Float(v) => Value::Float(-v),
1056 src => {
1057 return Err(Located::new(
1058 RunTimeError::InvalidUnary {
1059 op,
1060 right: src.dynamic_typ(),
1061 },
1062 pos,
1063 ))
1064 }
1065 },
1066 UnaryOperation::Not => Value::Bool(!bool::from(src)),
1067 };
1068 }
1069 }
1070 Ok(None)
1071 }
1072 pub fn run(&mut self) -> Result<Option<Value>, Located<RunTimeError>> {
1073 let level = self.call_frames.len();
1074 loop {
1075 let value = self.step()?;
1076 if self.call_frames.len() < level || self.call_frames.is_empty() {
1077 return Ok(value);
1078 }
1079 }
1080 }
1081}
1082impl CallFrame {
1083 #[inline(always)]
1084 pub fn path(&self) -> Option<String> {
1085 self.function.closure.borrow().path.clone()
1086 }
1087 #[inline(always)]
1088 pub fn register(&self, register: Register) -> Option<Rc<RefCell<Value>>> {
1089 self.stack.get(register as usize).cloned()
1090 }
1091 #[inline(always)]
1092 pub fn source(&self, source: &Source) -> Option<Value> {
1093 match source {
1094 Source::Register(register) => {
1095 self.register(*register).map(|value| value.borrow().clone())
1096 }
1097 Source::Upvalue(addr) => self
1098 .function
1099 .upvalues
1100 .get(*addr as usize)
1101 .map(|value| value.borrow().clone()),
1102 Source::Global(addr) => {
1103 if let Value::String(ident) = self
1104 .function
1105 .closure
1106 .borrow()
1107 .consts
1108 .get(*addr as usize)
1109 .expect("constant not found")
1110 {
1111 Some(
1112 self.globals
1113 .borrow()
1114 .get(ident)
1115 .map(|value| value.borrow().clone())
1116 .unwrap_or_default(),
1117 )
1118 } else {
1119 panic!("expected a string for the global")
1120 }
1121 }
1122 Source::Constant(addr) => self
1123 .function
1124 .closure
1125 .borrow()
1126 .consts
1127 .get(*addr as usize)
1128 .cloned(),
1129 Source::Null => Some(Value::default()),
1130 Source::Bool(v) => Some(Value::Bool(*v)),
1131 Source::Char(v) => Some(Value::Char(*v)),
1132 }
1133 }
1134 #[inline(always)]
1135 pub fn location(&mut self, location: &Location) -> Option<Rc<RefCell<Value>>> {
1136 match location {
1137 Location::Register(register) => self.register(*register),
1138 Location::Upvalue(addr) => self.function.upvalues.get(*addr as usize).map(Rc::clone),
1139 Location::Global(addr) => {
1140 if let Value::String(ident) = self
1141 .function
1142 .closure
1143 .borrow()
1144 .consts
1145 .get(*addr as usize)
1146 .expect("constant not found")
1147 {
1148 let mut globals = self.globals.borrow_mut();
1149 if let Some(value) = globals.get(ident).cloned() {
1150 Some(value)
1151 } else {
1152 globals.insert(ident.clone(), Rc::new(RefCell::new(Value::default())));
1153 globals.get(ident).cloned()
1154 }
1155 } else {
1156 panic!("expected a string for the global")
1157 }
1158 }
1159 }
1160 }
1161}
1162impl Display for RunTimeError {
1163 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1164 match self {
1165 RunTimeError::CannotCall(typ) => write!(f, "can not call {typ}"),
1166 RunTimeError::CannotIter(typ) => write!(f, "can not iterate over {typ}"),
1167 RunTimeError::CannotFieldInto { head, field } => {
1168 write!(f, "can not field into {head} with {field}")
1169 }
1170 RunTimeError::CannotField(typ) => write!(f, "can not field into {typ}"),
1171 RunTimeError::CannotSetFieldWith { head, field } => {
1172 write!(f, "can not set field of {head} with {field}")
1173 }
1174 RunTimeError::CannotSetField(head) => write!(f, "can not set field of {head}"),
1175 RunTimeError::InvalidSetIndex(index) => {
1176 write!(f, "invalid set index {index:?} (out of range)")
1177 }
1178 RunTimeError::InvalidBinary { op, left, right } => write!(
1179 f,
1180 "attempt to perform binary operation {:?} on {left} with {right}",
1181 format!("{:?}", op).to_lowercase()
1182 ),
1183 RunTimeError::InvalidUnary { op, right } => write!(
1184 f,
1185 "attempt to perform unary operation {:?} on {right}",
1186 format!("{:?}", op).to_lowercase()
1187 ),
1188 RunTimeError::Custom(msg) => write!(f, "{msg}"),
1189 }
1190 }
1191}
1192impl Error for RunTimeError {}