1use std::cell::RefCell;
15use std::collections::BTreeSet;
16use std::convert::TryInto;
17use std::path::PathBuf;
18use std::rc::Rc;
19
20use crate::ast::{CastType, Position};
21
22use super::environment::Environment;
23use super::pointer::OpPointer;
24use super::runtime;
25use super::scope::Stack;
26use super::translate::OpsMap;
27use super::Composite::{List, Tuple};
28use super::Hook;
29use super::Primitive::{Bool, Empty, Float, Int, Str};
30use super::Value::{C, F, M, P, S, T};
31use super::{Error, Op, Primitive, Value};
32use super::{Func, Module};
33
34fn construct_reserved_word_set() -> BTreeSet<&'static str> {
35 let mut words = BTreeSet::new();
36 for word in vec![
37 "let", "module", "func", "out", "assert", "self", "import", "include", "as", "map",
38 "filter", "convert", "fail", "NULL", "in", "is", "TRACE",
39 ] {
40 words.insert(word);
41 }
42 words
43}
44
45pub struct VM {
46 working_dir: PathBuf,
47 stack: Vec<(Rc<Value>, Position)>,
48 symbols: Stack,
49 import_stack: Vec<Rc<str>>,
50 runtime: runtime::Builtins,
51 ops: OpPointer,
52 pub last: Option<(Rc<Value>, Position)>,
53 self_stack: Vec<(Rc<Value>, Position)>,
54 reserved_words: BTreeSet<&'static str>,
55}
56
57impl VM {
58 pub fn new<P: Into<PathBuf>>(strict: bool, ops: Rc<OpsMap>, working_dir: P) -> Self {
59 Self::with_pointer(strict, OpPointer::new(ops), working_dir)
60 }
61
62 pub fn with_pointer<P: Into<PathBuf>>(strict: bool, ops: OpPointer, working_dir: P) -> Self {
63 Self {
64 working_dir: working_dir.into(),
65 stack: Vec::new(),
66 symbols: Stack::new(),
67 import_stack: Vec::new(),
68 runtime: runtime::Builtins::new(strict),
69 ops: ops,
70 last: None,
71 self_stack: Vec::new(),
72 reserved_words: construct_reserved_word_set(),
73 }
74 }
75
76 pub fn set_path(&mut self, path: PathBuf) {
77 self.ops.set_path(path);
78 }
79
80 pub fn to_new_pointer(mut self, ops: OpPointer) -> Self {
81 self.ops = ops;
82 self
83 }
84
85 pub fn with_import_stack(mut self, imports: Vec<Rc<str>>) -> Self {
86 self.import_stack = imports;
87 self
88 }
89
90 pub fn enable_validate_mode(&mut self) {
91 self.runtime.enable_validate_mode();
92 }
93
94 pub fn clean_copy(&self) -> Self {
95 Self {
96 working_dir: self.working_dir.clone(),
97 stack: Vec::new(),
98 symbols: Stack::new(),
99 import_stack: Vec::new(),
100 runtime: self.runtime.clone(),
101 ops: self.ops.clone(),
102 last: None,
103 self_stack: self.self_stack.clone(),
104 reserved_words: self.reserved_words.clone(),
105 }
106 }
107
108 pub fn to_scoped(mut self, symbols: Stack) -> Self {
109 self.symbols = symbols;
110 self
111 }
112
113 pub fn symbols_to_tuple(&self, include_mod: bool) -> Value {
114 let mut flds = Vec::new();
115 let mut pos_list = Vec::new();
116 for sym in self.symbols.symbol_list() {
117 if include_mod || sym.as_ref() != "mod" {
118 let (val, pos) = self.symbols.get(sym.as_ref()).unwrap().clone();
119 pos_list.push((pos.clone(), pos.clone()));
120 flds.push((sym.clone(), val));
121 }
122 }
123 return C(Tuple(flds, pos_list));
124 }
125
126 pub fn remove_symbol(&mut self, sym: &str) -> Option<(Rc<Value>, Position)> {
127 self.symbols.remove_symbol(sym)
128 }
129
130 pub fn run<'a, O, E>(&mut self, env: &'a RefCell<Environment<O, E>>) -> Result<(), Error>
131 where
132 O: std::io::Write + Clone,
133 E: std::io::Write + Clone,
134 {
135 loop {
136 let op = if let Some(op) = self.ops.next() {
137 op.clone()
138 } else {
139 break;
140 };
141 let pos = self.ops.pos().unwrap().clone();
142 let idx = self.ops.idx()?;
143 match op {
144 Op::Val(p) => self.push(Rc::new(P(p.clone())), pos)?,
145 Op::Cast(t) => self.op_cast(t)?,
146 Op::Sym(s) => self.push(Rc::new(S(s.clone())), pos)?,
147 Op::DeRef(s) => self.op_deref(s.clone(), env, &pos)?,
148 Op::Add => self.op_add(pos)?,
149 Op::Mod => self.op_mod(pos)?,
150 Op::Sub => self.op_sub(pos)?,
151 Op::Mul => self.op_mul(pos)?,
152 Op::Div => self.op_div(pos)?,
153 Op::Bind => self.op_bind(true)?,
154 Op::BindOver => self.op_bind(false)?,
155 Op::Equal => self.op_equal(pos)?,
156 Op::Not => self.op_not(&pos)?,
157 Op::Gt => self.op_gt(&pos)?,
158 Op::Lt => self.op_lt(&pos)?,
159 Op::GtEq => self.op_gteq(pos)?,
160 Op::LtEq => self.op_lteq(pos)?,
161 Op::InitList => self.push(Rc::new(C(List(Vec::new(), Vec::new()))), pos)?,
163 Op::InitTuple => self.push(Rc::new(C(Tuple(Vec::new(), Vec::new()))), pos)?,
165 Op::Field => self.op_field()?,
166 Op::Element => self.op_element()?,
167 Op::Index => self.op_index(!self.runtime.strict, pos)?,
168 Op::SafeIndex => self.op_index(true, pos)?,
169 Op::Exist => self.op_exist(pos)?,
170 Op::Cp => self.op_copy(pos, env)?,
171 Op::Bang => self.op_bang()?,
173 Op::InitThunk(jp) => self.op_thunk(idx, jp, pos)?,
174 Op::Noop => {
175 }
177 Op::Jump(jp) => self.op_jump(jp)?,
178 Op::JumpIfTrue(jp) => self.op_jump_if_true(jp)?,
179 Op::JumpIfFalse(jp) => self.op_jump_if_false(jp)?,
180 Op::SelectJump(jp) => self.op_select_jump(jp)?,
181 Op::And(jp) => self.op_and(jp, pos)?,
182 Op::Or(jp) => self.op_or(jp, pos)?,
183 Op::Module(mptr) => self.op_module(idx, mptr, pos)?,
184 Op::Func(jptr) => self.op_func(idx, jptr, pos)?,
185 Op::FCall => self.op_fcall(pos, env)?,
186 Op::NewScope(jp) => self.op_new_scope(jp, self.ops.clone(), env)?,
187 Op::Return => {
188 return Ok(());
189 }
190 Op::Pop => {
191 self.pop()?;
192 }
193 Op::Typ => self.op_typ()?,
194 Op::Runtime(h) => self.op_runtime(h, pos, env)?,
195 Op::Render => self.op_render()?,
196 Op::PushSelf => self.op_push_self()?,
197 Op::PopSelf => self.op_pop_self()?,
198 };
199 }
200 if let Some(p) = self.ops.path.as_ref() {
201 self.import_stack.push(p.to_string_lossy().into());
202 }
203 Ok(())
204 }
205
206 fn do_cast(&mut self, t: CastType, val: &Value, pos: Position) -> Result<(), Error> {
207 if let Value::P(ref p) = val {
208 self.push(
209 Rc::new(match t {
210 CastType::Str => Value::P(Primitive::Str(format!("{}", p).into())),
211 CastType::Int => Value::P(Primitive::Int(p.try_into()?)),
212 CastType::Float => Value::P(Primitive::Float(p.try_into()?)),
213 CastType::Bool => Value::P(Primitive::Bool(p.try_into()?)),
214 }),
215 pos,
216 )?;
217 }
218 Ok(())
219 }
220 fn op_cast(&mut self, t: CastType) -> Result<(), Error> {
221 let (val, pos) = self.pop()?;
222 decorate_error!(pos => self.do_cast(t, &val, pos.clone()))
223 }
224
225 fn op_typ(&mut self) -> Result<(), Error> {
226 let (val, pos) = self.pop()?;
227 let typ_name = match val.as_ref() {
228 P(Int(_)) => "int",
229 P(Float(_)) => "float",
230 P(Bool(_)) => "bool",
231 P(Str(_)) => "str",
232 P(Empty) => "null",
233 C(Tuple(_, _)) => "tuple",
234 C(List(_, _)) => "list",
235 F(_) => "func",
236 M(_) => "module",
237 S(_) => "sym",
238 T(_) => "thunk",
239 };
240 self.push(Rc::new(P(Str(typ_name.into()))), pos)?;
241 Ok(())
242 }
243
244 fn op_deref<O, E>(
245 &mut self,
246 name: Rc<str>,
247 env: &RefCell<Environment<O, E>>,
248 pos: &Position,
249 ) -> Result<(), Error>
250 where
251 O: std::io::Write + Clone,
252 E: std::io::Write + Clone,
253 {
254 let (val, _) = self.get_binding(&name, env, pos)?.clone();
255 self.push(val, pos.clone())
256 }
257
258 fn op_jump(&mut self, jp: i32) -> Result<(), Error> {
259 self.ops.jump(
260 self.ops
261 .ptr
262 .map(|v| (v as i32 + jp) as usize)
263 .unwrap_or(jp as usize),
264 )?;
265 Ok(())
266 }
267
268 fn op_and(&mut self, jp: i32, pos: Position) -> Result<(), Error> {
269 let (cond, cond_pos) = self.pop()?;
270 let cc = cond.clone();
271 if let &P(Bool(cond)) = cond.as_ref() {
272 if !cond {
273 self.push(cc, cond_pos)?;
274 self.op_jump(jp)?;
275 }
276 } else {
277 return Err(Error::new(
278 format!(
279 "Not a boolean condition {:?} in && expression at {}",
280 cond, pos
281 )
282 .into(),
283 cond_pos.clone(),
284 ));
285 }
286 Ok(())
287 }
288
289 fn op_or(&mut self, jp: i32, pos: Position) -> Result<(), Error> {
290 let (cond, cond_pos) = self.pop()?;
291 let cc = cond.clone();
292 if let &P(Bool(cond)) = cond.as_ref() {
293 if cond {
294 self.push(cc, cond_pos)?;
295 self.op_jump(jp)?;
296 }
297 } else {
298 return Err(Error::new(
299 format!(
300 "Not a boolean condition {:?} in || expression at {}!",
301 cond, pos
302 )
303 .into(),
304 cond_pos.clone(),
305 ));
306 }
307 Ok(())
308 }
309
310 fn op_jump_if_true(&mut self, jp: i32) -> Result<(), Error> {
311 let (cond, cond_pos) = self.pop()?;
312 if let &P(Bool(cond)) = cond.as_ref() {
313 if cond {
314 self.op_jump(jp)?;
315 }
316 } else {
317 return Err(Error::new(
318 format!("Expected boolean but got {:?}!", cond).into(),
319 cond_pos.clone(),
320 ));
321 }
322 Ok(())
323 }
324
325 fn op_jump_if_false(&mut self, jp: i32) -> Result<(), Error> {
326 let (cond, pos) = self.pop()?;
327 if let &P(Bool(cond)) = cond.as_ref() {
328 if !cond {
329 self.op_jump(jp)?;
330 }
331 } else {
332 return Err(Error::new(
333 format!("Expected boolean but got {:?}!", cond).into(),
334 pos.clone(),
335 ));
336 }
337 Ok(())
338 }
339
340 fn op_select_jump(&mut self, jp: i32) -> Result<(), Error> {
341 let (field_name, _) = self.pop()?;
343 let (search, srch_pos) = self.pop()?;
345 let matched = match (field_name.as_ref(), search.as_ref()) {
347 (&S(ref fname), &P(Str(ref sname))) | (&S(ref fname), &S(ref sname)) => fname == sname,
348 (&S(ref fname), &P(Bool(b))) => {
349 if fname.as_ref() == "true" && b {
350 true
351 } else if fname.as_ref() == "false" && !b {
352 true
353 } else {
354 false
355 }
356 }
357 _ => false,
358 };
359 if !matched {
360 self.push(search, srch_pos)?;
362 self.op_jump(jp)?;
363 }
364 Ok(())
365 }
366
367 fn op_module(&mut self, idx: usize, jptr: i32, pos: Position) -> Result<(), Error> {
368 let (mod_val, mod_val_pos) = self.pop()?;
369 let (result_ptr, flds, pos_list) = match mod_val.as_ref() {
370 &C(Tuple(ref flds, ref pos_list)) => (None, flds.clone(), pos_list.clone()),
371 &T(ptr) => {
372 let (tpl_val, tpl_val_pos) = self.pop()?;
373 if let &C(Tuple(ref flds, ref pos_list)) = tpl_val.as_ref() {
374 (Some(ptr), flds.clone(), pos_list.clone())
375 } else {
376 return Err(Error::new(
377 format!("Expected tuple but got {:?}", tpl_val).into(),
378 tpl_val_pos,
379 ));
380 }
381 }
382 _ => {
383 return Err(Error::new(
384 format!("Expected tuple but got {:?}", mod_val).into(),
385 mod_val_pos,
386 ));
387 }
388 };
389 let mut ops = self.ops.clone();
390 let pkg_pos = self.ops.pos().unwrap().clone();
391 ops.jump(idx)?;
392 let pkg_ptr = if let Some(ref path) = self.ops.path {
393 let pkg_ops = vec![
394 Op::InitList,
395 Op::Func(3),
396 Op::Val(Str(path.to_string_lossy().into())),
397 Op::Runtime(Hook::Import),
398 Op::Return,
399 ];
400 let pos_list = vec![
401 pkg_pos.clone(),
402 pkg_pos.clone(),
403 pkg_pos.clone(),
404 pkg_pos.clone(),
405 pkg_pos,
406 ];
407 Some(OpPointer::new(Rc::new(
408 OpsMap::new().with_ops(pkg_ops, pos_list),
409 )))
410 } else {
411 None
412 };
413 self.push(
414 Rc::new(M(Module {
415 ptr: ops,
416 result_ptr: result_ptr,
417 flds_pos_list: pos_list,
418 flds: flds,
419 pkg_ptr: pkg_ptr,
420 })),
421 pos,
422 )?;
423 self.op_jump(jptr)
424 }
425
426 fn op_func(&mut self, idx: usize, jptr: i32, pos: Position) -> Result<(), Error> {
427 let scope_snapshot = self.symbols.snapshot();
429 let mut bindings = Vec::new();
430 let (list_val, args_pos) = self.pop()?;
432 if let &C(List(ref elems, _)) = list_val.as_ref() {
433 for e in elems {
434 if let &S(ref sym) = e.as_ref() {
435 bindings.push(sym.clone());
436 } else {
437 return Err(Error::new(
438 format!("Not an argument name {:?}", e).into(),
439 args_pos,
440 ));
441 }
442 }
443 } else {
444 return Err(Error::new("Fault!!! Bad Argument List".into(), args_pos));
445 }
446 let mut ops = self.ops.clone();
447 ops.jump(idx)?;
448 bindings.reverse();
450 self.push(
451 Rc::new(F(Func {
452 ptr: ops, bindings: bindings,
454 snapshot: scope_snapshot,
455 })),
456 pos,
457 )?;
458 self.op_jump(jptr)
459 }
460
461 pub fn fcall_impl<'a, O, E>(
462 f: &Func,
463 strict: bool,
464 stack: &mut Vec<(Rc<Value>, Position)>,
465 env: &'a RefCell<Environment<O, E>>,
466 import_stack: &Vec<Rc<str>>,
467 ) -> Result<(Rc<Value>, Position), Error>
468 where
469 O: std::io::Write + Clone,
470 E: std::io::Write + Clone,
471 {
472 let Func {
473 ref ptr,
474 ref bindings,
475 ref snapshot,
476 } = f;
477 let mut vm = Self::with_pointer(strict, ptr.clone(), std::env::current_dir()?)
479 .to_scoped(snapshot.clone())
480 .with_import_stack(import_stack.clone());
481 for nm in bindings.iter() {
482 let (val, pos) = stack.pop().unwrap();
486 vm.binding_push(nm.clone(), val, false, &pos, &pos)?;
487 }
488 vm.run(env)?;
490 return vm.pop();
491 }
492
493 fn op_new_scope<O, E>(
494 &mut self,
495 jp: i32,
496 ptr: OpPointer,
497 env: &RefCell<Environment<O, E>>,
498 ) -> Result<(), Error>
499 where
500 O: std::io::Write + Clone,
501 E: std::io::Write + Clone,
502 {
503 let scope_snapshot = self.symbols.snapshot();
504 let mut vm = self
505 .clean_copy()
506 .to_new_pointer(ptr)
507 .to_scoped(scope_snapshot)
508 .with_import_stack(self.import_stack.clone());
509 vm.run(env)?;
510 let result = vm.pop()?;
511 self.push(result.0, result.1)?;
512 self.op_jump(jp)?;
513 Ok(())
514 }
515
516 fn op_fcall<O, E>(
517 &mut self,
518 pos: Position,
519 env: &RefCell<Environment<O, E>>,
520 ) -> Result<(), Error>
521 where
522 O: std::io::Write + Clone,
523 E: std::io::Write + Clone,
524 {
525 let (f, f_pos) = self.pop()?;
526 let (arg_length, _) = self.pop()?;
527 if let &F(ref f) = f.as_ref() {
528 if let &P(Int(arg_length)) = arg_length.as_ref() {
529 let arity = f.bindings.len() as i64;
530 if arg_length > arity {
531 return Err(Error::new(
532 format!(
533 "Func called with too many args expected {} args but got {}",
534 arity, arg_length
535 )
536 .into(),
537 pos,
538 ));
539 }
540 if arg_length < arity {
541 return Err(Error::new(
542 format!(
543 "Func called with too few args expected {} args but got {}",
544 arity, arg_length
545 )
546 .into(),
547 pos,
548 ));
549 }
550 }
551 let (val, _) = decorate_call!(f_pos =>
552 Self::fcall_impl(f, self.runtime.strict, &mut self.stack, env, &self.import_stack))?;
553 self.push(val, pos.clone())?;
554 } else {
555 return Err(Error::new(format!("Not a function! {:?}", f,).into(), pos));
556 }
557 Ok(())
558 }
559
560 fn op_thunk(&mut self, idx: usize, jp: i32, pos: Position) -> Result<(), Error> {
561 self.push(Rc::new(T(idx)), pos)?;
562 self.op_jump(jp)
563 }
564
565 fn op_not(&mut self, pos: &Position) -> Result<(), Error> {
566 let (operand, operand_pos) = self.pop()?;
567 if let P(Bool(val)) = operand.as_ref() {
568 self.push(Rc::new(P(Bool(!val))), operand_pos)?;
569 return Ok(());
570 }
571 return Err(Error::new(
572 format!(
573 "Expected Boolean but got {:?} in expression at {}",
574 operand, pos
575 )
576 .into(),
577 operand_pos,
578 ));
579 }
580
581 fn op_equal(&mut self, pos: Position) -> Result<(), Error> {
582 let (left, left_pos) = self.pop()?;
583 let (right, right_pos) = self.pop()?;
584 if left.type_name() != right.type_name()
585 && !(left.type_name() == "NULL" || right.type_name() == "NULL")
586 {
587 return Err(Error::new(
588 format!(
589 "Expected values of the same type but got {:?} at {} and {:?} at {} for expression",
590 left, left_pos, right, right_pos,
591 ).into(),
592 pos,
593 ));
594 }
595 self.push(Rc::new(P(Bool(left == right))), pos)?;
596 Ok(())
597 }
598
599 fn op_gt(&mut self, pos: &Position) -> Result<(), Error> {
600 let (left, left_pos) = self.pop()?;
601 let (right, right_pos) = self.pop()?;
602 match (left.as_ref(), right.as_ref()) {
603 (&P(Int(i)), &P(Int(ii))) => {
604 self.push(Rc::new(P(Bool(i > ii))), pos.clone())?;
605 }
606 (&P(Float(f)), &P(Float(ff))) => {
607 self.push(Rc::new(P(Bool(f > ff))), pos.clone())?;
608 }
609 _ => {
610 return Err(Error::new(
611 format!(
612 "Expected numeric values of the same type but got {:?} at {} and {:?} at {} for expression",
613 left, left_pos, right, right_pos,
614 ).into(),
615 pos.clone(),
616 ));
617 }
618 }
619 Ok(())
620 }
621
622 fn op_lt(&mut self, pos: &Position) -> Result<(), Error> {
623 let (left, left_pos) = self.pop()?;
624 let (right, right_pos) = self.pop()?;
625 match (left.as_ref(), right.as_ref()) {
626 (&P(Int(i)), &P(Int(ii))) => {
627 self.push(Rc::new(P(Bool(i < ii))), pos.clone())?;
628 }
629 (&P(Float(f)), &P(Float(ff))) => {
630 self.push(Rc::new(P(Bool(f < ff))), pos.clone())?;
631 }
632 _ => {
633 return Err(Error::new(
634 format!(
635 "Expected numeric values of the same type but got {:?} at {} and {:?} at {} for expression",
636 left, left_pos, right, right_pos,
637 ).into(),
638 pos.clone(),
639 ));
640 }
641 }
642 Ok(())
643 }
644
645 fn op_lteq(&mut self, pos: Position) -> Result<(), Error> {
646 let (left, left_pos) = self.pop()?;
647 let (right, right_pos) = self.pop()?;
648 match (left.as_ref(), right.as_ref()) {
649 (&P(Int(i)), &P(Int(ii))) => {
650 self.push(Rc::new(P(Bool(i <= ii))), pos)?;
651 }
652 (&P(Float(f)), &P(Float(ff))) => {
653 self.push(Rc::new(P(Bool(f <= ff))), pos)?;
654 }
655 _ => {
656 return Err(Error::new(
657 format!(
658 "Expected numeric values of the same type but got {:?} at {} and {:?} at {} for expression",
659 left, left_pos, right, right_pos,
660 ).into(),
661 pos,
662 ));
663 }
664 }
665 Ok(())
666 }
667
668 fn op_gteq(&mut self, pos: Position) -> Result<(), Error> {
669 let (left, left_pos) = self.pop()?;
670 let (right, right_pos) = self.pop()?;
671 match (left.as_ref(), right.as_ref()) {
672 (&P(Int(i)), &P(Int(ii))) => {
673 self.push(Rc::new(P(Bool(i >= ii))), pos)?;
674 }
675 (&P(Float(f)), &P(Float(ff))) => {
676 self.push(Rc::new(P(Bool(f >= ff))), pos)?;
677 }
678 _ => {
679 return Err(Error::new(
680 format!(
681 "Expected numeric values of the same type but got {:?} at {} and {:?} at {} for expression",
682 left, left_pos, right, right_pos,
683 ).into(),
684 pos,
685 ));
686 }
687 }
688 Ok(())
689 }
690
691 fn op_mod(&mut self, pos: Position) -> Result<(), Error> {
692 let (left, _) = self.pop()?;
694 let (right, right_pos) = self.pop()?;
695 self.push(Rc::new(P(self.modulus(&left, &right, &right_pos)?)), pos)?;
697 Ok(())
698 }
699
700 fn op_add(&mut self, pos: Position) -> Result<(), Error> {
701 let (left, _) = self.pop()?;
703 let (right, right_pos) = self.pop()?;
704 self.push(Rc::new(self.add(&left, &right, &right_pos)?), pos)?;
706 Ok(())
707 }
708
709 fn op_sub(&mut self, pos: Position) -> Result<(), Error> {
710 let (left, _) = self.pop()?;
712 let (right, right_pos) = self.pop()?;
713 self.push(Rc::new(P(self.sub(&left, &right, &right_pos)?)), pos)?;
715 Ok(())
716 }
717
718 fn op_mul(&mut self, pos: Position) -> Result<(), Error> {
719 let (left, _) = self.pop()?;
721 let (right, right_pos) = self.pop()?;
722 self.push(Rc::new(P(self.mul(&left, &right, &right_pos)?)), pos)?;
724 Ok(())
725 }
726
727 fn op_div(&mut self, pos: Position) -> Result<(), Error> {
728 let (left, _) = self.pop()?;
730 let (right, right_pos) = self.pop()?;
731 self.push(Rc::new(P(self.div(&left, &right, &right_pos)?)), pos)?;
733 Ok(())
734 }
735
736 fn op_push_self(&mut self) -> Result<(), Error> {
737 let (val, pos) = self.pop()?;
739 self.self_stack.push((val.clone(), pos.clone()));
740 self.push(val.clone(), pos)?;
741 Ok(())
742 }
743
744 fn op_pop_self(&mut self) -> Result<(), Error> {
745 self.self_stack.pop();
747 Ok(())
748 }
749
750 fn op_bind(&mut self, strict: bool) -> Result<(), Error> {
751 let (val, val_pos) = self.pop()?;
753 let (name, name_pos) = self.pop()?;
755 if let &S(ref name) = name.as_ref() {
757 self.binding_push(name.clone(), val, strict, &val_pos, &name_pos)?;
758 } else {
759 unreachable!();
760 }
761 Ok(())
762 }
763
764 fn op_field(&mut self) -> Result<(), Error> {
765 let (val, val_pos) = self.pop()?;
768 let (name_val, name_pos) = self.pop()?;
770 let name = if let &S(ref s) | &P(Str(ref s)) = name_val.as_ref() {
771 s
772 } else {
773 unreachable!();
774 };
775 let (tpl, tpl_pos) = self.pop()?;
777 if let &C(Tuple(ref flds, ref pos_list)) = tpl.as_ref() {
778 let mut flds = flds.clone();
780 let mut pos_list = pos_list.clone();
781 self.merge_field_into_tuple(
782 &mut flds,
783 &mut pos_list,
784 name.clone(),
785 &name_pos,
786 val,
787 &val_pos,
788 )?;
789 self.push(Rc::new(C(Tuple(flds, pos_list))), tpl_pos)?;
791 } else {
792 unreachable!();
793 };
794 Ok(())
795 }
796
797 fn op_element(&mut self) -> Result<(), Error> {
798 let (val, val_pos) = self.pop()?;
800 let (list, pos) = self.pop()?;
802 if let &C(List(ref elems, ref pos_list)) = list.as_ref() {
803 let mut elems = elems.clone();
805 elems.push(val);
806 let mut pos_list = pos_list.clone();
807 pos_list.push(val_pos);
808 self.push(Rc::new(C(List(elems, pos_list))), pos)?;
810 } else {
811 unreachable!();
812 };
813 Ok(())
814 }
815
816 fn op_bang(&mut self) -> Result<(), Error> {
817 let (msg_val, err_pos) = self.pop()?;
818 if let &P(Str(ref msg)) = msg_val.as_ref() {
819 return Err(Error::new(msg.clone(), err_pos));
820 } else {
821 unreachable!();
822 }
823 }
824
825 fn op_index(&mut self, safe: bool, pos: Position) -> Result<(), Error> {
826 let (right, right_pos) = self.pop()?;
828 let (left, _) = self.pop()?;
829 match right.as_ref() {
830 &P(Int(i)) => {
831 if let &C(List(ref elems, _)) = left.as_ref() {
832 if i < (elems.len() as i64) && i >= 0 {
833 self.push(elems[i as usize].clone(), right_pos)?;
834 return Ok(());
835 }
836 }
837 }
838 &P(Str(ref s)) => {
839 if let &C(Tuple(ref flds, _)) = left.as_ref() {
840 for &(ref key, ref val) in flds.iter() {
841 if key == s {
842 self.push(val.clone(), right_pos)?;
843 return Ok(());
844 }
845 }
846 }
847 }
848 _ => {
849 }
851 };
852 if safe {
853 self.push(Rc::new(P(Empty)), pos)?;
854 return Ok(());
855 }
856 return Err(Error::new(
857 format!("Invalid selector index: {:?} target: {:?}", right, left).into(),
858 pos,
859 ));
860 }
861
862 fn op_exist(&mut self, pos: Position) -> Result<(), Error> {
863 let (right, right_pos) = self.pop()?;
864 let (left, left_pos) = self.pop()?;
865 match left.as_ref() {
866 &C(Tuple(ref flds, _)) => {
867 if let &P(Str(ref name)) = right.as_ref() {
868 for (ref nm, _) in flds {
869 if nm == name {
870 self.push(Rc::new(P(Bool(true))), pos)?;
871 return Ok(());
872 }
873 }
874 } else {
875 return Err(Error::new(
876 format!("Expected String or Symbol got: {}", right.type_name()).into(),
877 right_pos,
878 ));
879 }
880 }
881 &C(List(ref elems, _)) => {
882 for e in elems {
883 if e == &right {
884 self.push(Rc::new(P(Bool(true))), pos)?;
885 return Ok(());
886 }
887 }
888 }
889 &P(Str(ref s)) => {
890 if let &P(Str(ref part)) = right.as_ref() {
891 self.push(Rc::new(P(Bool(s.contains(part.as_ref())))), pos)?;
892 return Ok(());
893 }
894 }
895 _ => {
896 return Err(Error::new(
897 format!("Expected String, Tuple, or List got: {}", left.type_name()).into(),
898 left_pos,
899 ));
900 }
901 };
902 self.push(Rc::new(P(Bool(false))), pos)?;
903 Ok(())
904 }
905
906 fn op_copy<O, E>(
907 &mut self,
908 pos: Position,
909 env: &RefCell<Environment<O, E>>,
910 ) -> Result<(), Error>
911 where
912 O: std::io::Write + Clone,
913 E: std::io::Write + Clone,
914 {
915 let (override_val, val_pos) = self.pop()?;
917 let (tgt, tgt_pos) = self.pop()?;
919 let (overrides, override_pos_list) =
920 if let &C(Tuple(ref oflds, ref pos_list)) = override_val.as_ref() {
921 (oflds.clone(), pos_list.clone())
922 } else {
923 unreachable!();
924 };
925 match tgt.as_ref() {
926 &C(Tuple(ref flds, ref pos_list)) => {
927 let mut flds = flds.clone();
928 let mut pos_list = pos_list.clone();
929 let mut counter = 0;
930 for (name, val) in overrides {
931 let name_pos = override_pos_list[counter].0.clone();
932 let val_pos = override_pos_list[counter].1.clone();
933 self.merge_field_into_tuple(
934 &mut flds,
935 &mut pos_list,
936 name,
937 &name_pos,
938 val,
939 &val_pos,
940 )?;
941 counter += 1;
942 }
943 self.push(Rc::new(C(Tuple(flds, pos_list))), tgt_pos.clone())?;
945 self.last = Some((tgt.clone(), tgt_pos));
946 }
947 &M(Module {
948 ref ptr,
949 ref result_ptr,
950 ref flds,
951 ref flds_pos_list,
952 ref pkg_ptr,
953 }) => {
954 let this = M(Module {
955 ptr: ptr.clone(),
956 result_ptr: result_ptr.clone(),
957 flds: flds.clone(),
958 flds_pos_list: flds_pos_list.clone(),
959 pkg_ptr: pkg_ptr.clone(),
960 });
961
962 let mut flds = flds.clone();
963 let mut flds_pos_list = flds_pos_list.clone();
964 let mut counter = 0;
965 for (name, val) in overrides {
966 let name_pos = override_pos_list[counter].0.clone();
967 let val_pos = override_pos_list[counter].1.clone();
968 self.merge_field_into_tuple(
969 &mut flds,
970 &mut flds_pos_list,
971 name,
972 &name_pos,
973 val,
974 &val_pos,
975 )?;
976 counter += 1;
977 }
978 self.merge_field_into_tuple(
979 &mut flds,
980 &mut flds_pos_list,
981 "this".into(),
982 &pos,
983 Rc::new(this),
984 &val_pos,
985 )?;
986 if let Some(ptr) = pkg_ptr {
987 let mut pkg_vm = self
988 .clean_copy()
989 .to_new_pointer(ptr.clone())
990 .with_import_stack(self.import_stack.clone());
991 pkg_vm.run(env)?;
992 let (pkg_func, val_pos) = pkg_vm.pop()?;
993 self.merge_field_into_tuple(
994 &mut flds,
995 &mut flds_pos_list,
996 "pkg".into(),
997 &pos,
998 pkg_func,
999 &val_pos,
1000 )?;
1001 }
1002
1003 let mut vm = self
1004 .clean_copy()
1005 .to_new_pointer(ptr.clone())
1006 .with_import_stack(self.import_stack.clone());
1007 vm.push(Rc::new(S("mod".into())), pos.clone())?;
1008 vm.push(Rc::new(C(Tuple(flds, flds_pos_list))), pos.clone())?;
1009 decorate_call!(pos => vm.run(env))?;
1010 if let Some(ptr) = result_ptr {
1011 vm.ops.jump(ptr.clone())?;
1012 vm.run(env)?;
1013 let (result_val, result_pos) = vm.pop()?;
1014 self.push(result_val, result_pos)?;
1015 } else {
1016 self.push(Rc::new(vm.symbols_to_tuple(false)), pos)?;
1017 }
1018 }
1019 _ => {
1020 return Err(Error::new(
1021 format!("Expected a Tuple or Module but got {:?}", tgt).into(),
1022 pos,
1023 ));
1024 }
1025 }
1026 Ok(())
1027 }
1028
1029 fn merge_field_into_tuple(
1030 &self,
1031 src_fields: &mut Vec<(Rc<str>, Rc<Value>)>,
1032 pos_fields: &mut Vec<(Position, Position)>,
1033 name: Rc<str>,
1034 name_pos: &Position,
1035 value: Rc<Value>,
1036 val_pos: &Position,
1037 ) -> Result<(), Error> {
1038 let mut counter = 0;
1039 for fld in src_fields.iter_mut() {
1040 if fld.0 == name {
1041 if fld.1.type_name() != value.type_name()
1042 && !(fld.1.type_name() == "NULL" || value.type_name() == "NULL")
1043 {
1044 return Err(Error::new(
1045 format!(
1046 "Expected type {} for field {} but got ({})",
1047 fld.1.type_name(),
1048 name,
1049 value.type_name(),
1050 )
1051 .into(),
1052 val_pos.clone(),
1053 ));
1054 }
1055 pos_fields[counter].1 = val_pos.clone();
1056 fld.1 = value;
1057 return Ok(());
1058 }
1059 counter += 1;
1060 }
1061 src_fields.push((name, value));
1062 pos_fields.push((name_pos.clone(), val_pos.clone()));
1063 Ok(())
1064 }
1065
1066 fn push(&mut self, val: Rc<Value>, pos: Position) -> Result<(), Error> {
1067 self.stack.push((val, pos));
1068 Ok(())
1069 }
1070
1071 pub fn binding_push(
1072 &mut self,
1073 name: Rc<str>,
1074 val: Rc<Value>,
1075 strict: bool,
1076 pos: &Position,
1077 name_pos: &Position,
1078 ) -> Result<(), Error> {
1079 if self.reserved_words.contains(name.as_ref()) {
1080 return Err(Error::new(
1081 format!("{} is a reserved word.", name).into(),
1082 name_pos.clone(),
1083 ));
1084 }
1085 if self.symbols.is_bound(&name) && strict {
1086 return Err(Error::new(
1087 format!("Binding {} already exists", name).into(),
1088 pos.clone(),
1089 ));
1090 }
1091 self.symbols.add(name, val, pos.clone());
1092 Ok(())
1093 }
1094
1095 pub fn get_binding<O, E>(
1096 &self,
1097 name: &str,
1098 env: &RefCell<Environment<O, E>>,
1099 pos: &Position,
1100 ) -> Result<(Rc<Value>, Position), Error>
1101 where
1102 O: std::io::Write + Clone,
1103 E: std::io::Write + Clone,
1104 {
1105 let tpl = if name == "self" {
1107 self.self_stack.last().cloned()
1108 } else if name == "env" {
1109 let candidate = self.symbols.get(name);
1110 if candidate.is_some() {
1111 candidate
1112 } else {
1113 Some((
1114 Rc::new(env.borrow().get_env_vars_tuple()),
1115 Position::new(0, 0, 0),
1116 ))
1117 }
1118 } else {
1119 self.symbols.get(name)
1120 };
1121 match tpl {
1122 Some((v, pos)) => Ok((v, pos)),
1123 None => {
1124 return Err(Error::new(
1125 format!("No such binding {}", name).into(),
1126 pos.clone(),
1127 ));
1128 }
1129 }
1130 }
1131
1132 pub fn pop(&mut self) -> Result<(Rc<Value>, Position), Error> {
1133 match self.stack.pop() {
1134 Some(v) => {
1135 self.last = Some(v.clone());
1136 Ok(v)
1137 }
1138 None => unreachable!(),
1139 }
1140 }
1141
1142 fn mul(&self, left: &Value, right: &Value, pos: &Position) -> Result<Primitive, Error> {
1143 Ok(match (left, right) {
1144 (P(Int(i)), P(Int(ii))) => Int(i * ii),
1145 (P(Float(f)), P(Float(ff))) => Float(f * ff),
1146 _ => {
1147 return Err(Error::new(
1148 format!("Expected {} but got {:?}", left.type_name(), right).into(),
1149 pos.clone(),
1150 ))
1151 }
1152 })
1153 }
1154
1155 fn div(&self, left: &Value, right: &Value, pos: &Position) -> Result<Primitive, Error> {
1156 Ok(match (left, right) {
1157 (P(Int(i)), P(Int(ii))) => Int(i / ii),
1158 (P(Float(f)), P(Float(ff))) => Float(f / ff),
1159 _ => {
1160 return Err(Error::new(
1161 format!("Expected {} but got {:?}", left.type_name(), right).into(),
1162 pos.clone(),
1163 ))
1164 }
1165 })
1166 }
1167
1168 fn sub(&self, left: &Value, right: &Value, pos: &Position) -> Result<Primitive, Error> {
1169 Ok(match (left, right) {
1170 (P(Int(i)), Value::P(Int(ii))) => Int(i - ii),
1171 (P(Float(f)), Value::P(Float(ff))) => Float(f - ff),
1172 _ => {
1173 return Err(Error::new(
1174 format!("Expected {} but got {:?}", left.type_name(), right).into(),
1175 pos.clone(),
1176 ))
1177 }
1178 })
1179 }
1180
1181 fn modulus(&self, left: &Value, right: &Value, pos: &Position) -> Result<Primitive, Error> {
1182 Ok(match (left, right) {
1183 (P(Int(i)), Value::P(Int(ii))) => Int(i % ii),
1184 (P(Float(f)), Value::P(Float(ff))) => Float(f % ff),
1185 _ => {
1186 return Err(Error::new(
1187 format!("Expected {} but got {:?}", left.type_name(), right).into(),
1188 pos.clone(),
1189 ))
1190 }
1191 })
1192 }
1193
1194 fn add(&self, left: &Value, right: &Value, pos: &Position) -> Result<Value, Error> {
1195 Ok(match (left, right) {
1196 (P(Int(i)), Value::P(Int(ii))) => P(Int(i + ii)),
1197 (P(Float(f)), Value::P(Float(ff))) => P(Float(f + ff)),
1198 (P(Str(s)), Value::P(Str(ss))) => {
1199 let mut ns = String::new();
1200 ns.push_str(&s);
1201 ns.push_str(&ss);
1202 P(Str(ns.into()))
1203 }
1204 (
1205 C(List(ref left_list, ref left_pos_list)),
1206 C(List(ref right_list, ref right_pos_list)),
1207 ) => {
1208 let cap = left_list.len() + right_list.len();
1209 let mut new_list = Vec::with_capacity(cap);
1210 let mut new_pos_list = Vec::with_capacity(cap);
1211 let mut counter = 0;
1212 for v in left_list.iter() {
1213 new_list.push(v.clone());
1214 new_pos_list.push(left_pos_list[counter].clone());
1215 counter += 1;
1216 }
1217 counter = 0;
1218 for v in right_list.iter() {
1219 new_list.push(v.clone());
1220 new_pos_list.push(right_pos_list[counter].clone());
1221 counter += 1;
1222 }
1223 C(List(new_list, new_pos_list))
1224 }
1225 _ => {
1226 return Err(Error::new(
1227 format!("Expected {} but got {:?}", left.type_name(), right).into(),
1228 pos.clone(),
1229 ))
1230 }
1231 })
1232 }
1233
1234 fn op_runtime<O, E>(
1235 &mut self,
1236 h: Hook,
1237 pos: Position,
1238 env: &RefCell<Environment<O, E>>,
1239 ) -> Result<(), Error>
1240 where
1241 O: std::io::Write + Clone,
1242 E: std::io::Write + Clone,
1243 {
1244 self.runtime.handle(
1245 self.ops.path.as_ref(),
1246 h,
1247 &mut self.stack,
1248 env,
1249 &mut self.import_stack,
1250 pos,
1251 )
1252 }
1253
1254 fn op_render(&mut self) -> Result<(), Error> {
1255 let (val, pos) = self.pop()?;
1256 self.push(Rc::new(P(Str(val.as_ref().into()))), pos)?;
1257 Ok(())
1258 }
1259}