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<String>,
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<String>) -> 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 != "mod" {
118 let (val, pos) = self.symbols.get(sym).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().to_string());
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))),
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 .to_owned();
241 self.push(Rc::new(P(Str(typ_name))), pos)?;
242 Ok(())
243 }
244
245 fn op_deref<O, E>(
246 &mut self,
247 name: String,
248 env: &RefCell<Environment<O, E>>,
249 pos: &Position,
250 ) -> Result<(), Error>
251 where
252 O: std::io::Write + Clone,
253 E: std::io::Write + Clone,
254 {
255 let (val, _) = self.get_binding(&name, env, pos)?.clone();
256 self.push(val, pos.clone())
257 }
258
259 fn op_jump(&mut self, jp: i32) -> Result<(), Error> {
260 self.ops.jump(
261 self.ops
262 .ptr
263 .map(|v| (v as i32 + jp) as usize)
264 .unwrap_or(jp as usize),
265 )?;
266 Ok(())
267 }
268
269 fn op_and(&mut self, jp: i32, pos: Position) -> Result<(), Error> {
270 let (cond, cond_pos) = self.pop()?;
271 let cc = cond.clone();
272 if let &P(Bool(cond)) = cond.as_ref() {
273 if !cond {
274 self.push(cc, cond_pos)?;
275 self.op_jump(jp)?;
276 }
277 } else {
278 return Err(Error::new(
279 format!(
280 "Not a boolean condition {:?} in && expression at {}",
281 cond, pos
282 ),
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 cond_pos.clone(),
304 ));
305 }
306 Ok(())
307 }
308
309 fn op_jump_if_true(&mut self, jp: i32) -> Result<(), Error> {
310 let (cond, cond_pos) = self.pop()?;
311 if let &P(Bool(cond)) = cond.as_ref() {
312 if cond {
313 self.op_jump(jp)?;
314 }
315 } else {
316 return Err(Error::new(
317 format!("Expected boolean but got {:?}!", cond),
318 cond_pos.clone(),
319 ));
320 }
321 Ok(())
322 }
323
324 fn op_jump_if_false(&mut self, jp: i32) -> Result<(), Error> {
325 let (cond, pos) = self.pop()?;
326 if let &P(Bool(cond)) = cond.as_ref() {
327 if !cond {
328 self.op_jump(jp)?;
329 }
330 } else {
331 return Err(Error::new(
332 format!("Expected boolean but got {:?}!", cond),
333 pos.clone(),
334 ));
335 }
336 Ok(())
337 }
338
339 fn op_select_jump(&mut self, jp: i32) -> Result<(), Error> {
340 let (field_name, _) = self.pop()?;
342 let (search, srch_pos) = self.pop()?;
344 let matched = match (field_name.as_ref(), search.as_ref()) {
346 (&S(ref fname), &P(Str(ref sname))) | (&S(ref fname), &S(ref sname)) => fname == sname,
347 (&S(ref fname), &P(Bool(b))) => {
348 if fname == "true" && b {
349 true
350 } else if fname == "false" && !b {
351 true
352 } else {
353 false
354 }
355 }
356 _ => false,
357 };
358 if !matched {
359 self.push(search, srch_pos)?;
361 self.op_jump(jp)?;
362 }
363 Ok(())
364 }
365
366 fn op_module(&mut self, idx: usize, jptr: i32, pos: Position) -> Result<(), Error> {
367 let (mod_val, mod_val_pos) = self.pop()?;
368 let (result_ptr, flds, pos_list) = match mod_val.as_ref() {
369 &C(Tuple(ref flds, ref pos_list)) => (None, flds.clone(), pos_list.clone()),
370 &T(ptr) => {
371 let (tpl_val, tpl_val_pos) = self.pop()?;
372 if let &C(Tuple(ref flds, ref pos_list)) = tpl_val.as_ref() {
373 (Some(ptr), flds.clone(), pos_list.clone())
374 } else {
375 return Err(Error::new(
376 format!("Expected tuple but got {:?}", tpl_val),
377 tpl_val_pos,
378 ));
379 }
380 }
381 _ => {
382 return Err(Error::new(
383 format!("Expected tuple but got {:?}", mod_val),
384 mod_val_pos,
385 ));
386 }
387 };
388 let mut ops = self.ops.clone();
389 let pkg_pos = self.ops.pos().unwrap().clone();
390 ops.jump(idx)?;
391 let pkg_ptr = if let Some(ref path) = self.ops.path {
392 let pkg_ops = vec![
393 Op::InitList,
394 Op::Func(3),
395 Op::Val(Str(path.to_string_lossy().to_string())),
396 Op::Runtime(Hook::Import),
397 Op::Return,
398 ];
399 let pos_list = vec![
400 pkg_pos.clone(),
401 pkg_pos.clone(),
402 pkg_pos.clone(),
403 pkg_pos.clone(),
404 pkg_pos,
405 ];
406 Some(OpPointer::new(Rc::new(
407 OpsMap::new().with_ops(pkg_ops, pos_list),
408 )))
409 } else {
410 None
411 };
412 self.push(
413 Rc::new(M(Module {
414 ptr: ops,
415 result_ptr: result_ptr,
416 flds_pos_list: pos_list,
417 flds: flds,
418 pkg_ptr: pkg_ptr,
419 })),
420 pos,
421 )?;
422 self.op_jump(jptr)
423 }
424
425 fn op_func(&mut self, idx: usize, jptr: i32, pos: Position) -> Result<(), Error> {
426 let scope_snapshot = self.symbols.snapshot();
428 let mut bindings = Vec::new();
429 let (list_val, args_pos) = self.pop()?;
431 if let &C(List(ref elems, _)) = list_val.as_ref() {
432 for e in elems {
433 if let &S(ref sym) = e.as_ref() {
434 bindings.push(sym.clone());
435 } else {
436 return Err(Error::new(
437 format!("Not an argument name {:?}", e),
438 args_pos,
439 ));
440 }
441 }
442 } else {
443 return Err(Error::new(format!("Fault!!! Bad Argument List"), args_pos));
444 }
445 let mut ops = self.ops.clone();
446 ops.jump(idx)?;
447 bindings.reverse();
449 self.push(
450 Rc::new(F(Func {
451 ptr: ops, bindings: bindings,
453 snapshot: scope_snapshot,
454 })),
455 pos,
456 )?;
457 self.op_jump(jptr)
458 }
459
460 pub fn fcall_impl<'a, O, E>(
461 f: &Func,
462 strict: bool,
463 stack: &mut Vec<(Rc<Value>, Position)>,
464 env: &'a RefCell<Environment<O, E>>,
465 import_stack: &Vec<String>,
466 ) -> Result<(Rc<Value>, Position), Error>
467 where
468 O: std::io::Write + Clone,
469 E: std::io::Write + Clone,
470 {
471 let Func {
472 ref ptr,
473 ref bindings,
474 ref snapshot,
475 } = f;
476 let mut vm = Self::with_pointer(strict, ptr.clone(), std::env::current_dir()?)
478 .to_scoped(snapshot.clone())
479 .with_import_stack(import_stack.clone());
480 for nm in bindings.iter() {
481 let (val, pos) = stack.pop().unwrap();
485 vm.binding_push(nm.clone(), val, false, &pos, &pos)?;
486 }
487 vm.run(env)?;
489 return vm.pop();
490 }
491
492 fn op_new_scope<O, E>(
493 &mut self,
494 jp: i32,
495 ptr: OpPointer,
496 env: &RefCell<Environment<O, E>>,
497 ) -> Result<(), Error>
498 where
499 O: std::io::Write + Clone,
500 E: std::io::Write + Clone,
501 {
502 let scope_snapshot = self.symbols.snapshot();
503 let mut vm = self
504 .clean_copy()
505 .to_new_pointer(ptr)
506 .to_scoped(scope_snapshot)
507 .with_import_stack(self.import_stack.clone());
508 vm.run(env)?;
509 let result = vm.pop()?;
510 self.push(result.0, result.1)?;
511 self.op_jump(jp)?;
512 Ok(())
513 }
514
515 fn op_fcall<O, E>(
516 &mut self,
517 pos: Position,
518 env: &RefCell<Environment<O, E>>,
519 ) -> Result<(), Error>
520 where
521 O: std::io::Write + Clone,
522 E: std::io::Write + Clone,
523 {
524 let (f, f_pos) = self.pop()?;
525 let (arg_length, _) = self.pop()?;
526 if let &F(ref f) = f.as_ref() {
527 if let &P(Int(arg_length)) = arg_length.as_ref() {
528 let arity = f.bindings.len() as i64;
529 if arg_length > arity {
530 return Err(Error::new(
531 format!(
532 "Func called with too many args expected {} args but got {}",
533 arity, arg_length
534 ),
535 pos,
536 ));
537 }
538 if arg_length < arity {
539 return Err(Error::new(
540 format!(
541 "Func called with too few args expected {} args but got {}",
542 arity, arg_length
543 ),
544 pos,
545 ));
546 }
547 }
548 let (val, _) = decorate_call!(f_pos =>
549 Self::fcall_impl(f, self.runtime.strict, &mut self.stack, env.clone(), &self.import_stack))?;
550 self.push(val, pos.clone())?;
551 } else {
552 return Err(Error::new(format!("Not a function! {:?}", f,), pos));
553 }
554 Ok(())
555 }
556
557 fn op_thunk(&mut self, idx: usize, jp: i32, pos: Position) -> Result<(), Error> {
558 self.push(Rc::new(T(idx)), pos)?;
559 self.op_jump(jp)
560 }
561
562 fn op_not(&mut self, pos: &Position) -> Result<(), Error> {
563 let (operand, operand_pos) = self.pop()?;
564 if let P(Bool(val)) = operand.as_ref() {
565 self.push(Rc::new(P(Bool(!val))), operand_pos)?;
566 return Ok(());
567 }
568 return Err(Error::new(
569 format!(
570 "Expected Boolean but got {:?} in expression at {}",
571 operand, pos
572 ),
573 operand_pos,
574 ));
575 }
576
577 fn op_equal(&mut self, pos: Position) -> Result<(), Error> {
578 let (left, left_pos) = self.pop()?;
579 let (right, right_pos) = self.pop()?;
580 if left.type_name() != right.type_name()
581 && !(left.type_name() == "NULL" || right.type_name() == "NULL")
582 {
583 return Err(Error::new(
584 format!(
585 "Expected values of the same type but got {:?} at {} and {:?} at {} for expression",
586 left, left_pos, right, right_pos,
587 ),
588 pos,
589 ));
590 }
591 self.push(Rc::new(P(Bool(left == right))), pos)?;
592 Ok(())
593 }
594
595 fn op_gt(&mut self, pos: &Position) -> Result<(), Error> {
596 let (left, left_pos) = self.pop()?;
597 let (right, right_pos) = self.pop()?;
598 match (left.as_ref(), right.as_ref()) {
599 (&P(Int(i)), &P(Int(ii))) => {
600 self.push(Rc::new(P(Bool(i > ii))), pos.clone())?;
601 }
602 (&P(Float(f)), &P(Float(ff))) => {
603 self.push(Rc::new(P(Bool(f > ff))), pos.clone())?;
604 }
605 _ => {
606 return Err(Error::new(
607 format!(
608 "Expected numeric values of the same type but got {:?} at {} and {:?} at {} for expression",
609 left, left_pos, right, right_pos,
610 ),
611 pos.clone(),
612 ));
613 }
614 }
615 Ok(())
616 }
617
618 fn op_lt(&mut self, pos: &Position) -> Result<(), Error> {
619 let (left, left_pos) = self.pop()?;
620 let (right, right_pos) = self.pop()?;
621 match (left.as_ref(), right.as_ref()) {
622 (&P(Int(i)), &P(Int(ii))) => {
623 self.push(Rc::new(P(Bool(i < ii))), pos.clone())?;
624 }
625 (&P(Float(f)), &P(Float(ff))) => {
626 self.push(Rc::new(P(Bool(f < ff))), pos.clone())?;
627 }
628 _ => {
629 return Err(Error::new(
630 format!(
631 "Expected numeric values of the same type but got {:?} at {} and {:?} at {} for expression",
632 left, left_pos, right, right_pos,
633 ),
634 pos.clone(),
635 ));
636 }
637 }
638 Ok(())
639 }
640
641 fn op_lteq(&mut self, pos: Position) -> Result<(), Error> {
642 let (left, left_pos) = self.pop()?;
643 let (right, right_pos) = self.pop()?;
644 match (left.as_ref(), right.as_ref()) {
645 (&P(Int(i)), &P(Int(ii))) => {
646 self.push(Rc::new(P(Bool(i <= ii))), pos)?;
647 }
648 (&P(Float(f)), &P(Float(ff))) => {
649 self.push(Rc::new(P(Bool(f <= ff))), pos)?;
650 }
651 _ => {
652 return Err(Error::new(
653 format!(
654 "Expected numeric values of the same type but got {:?} at {} and {:?} at {} for expression",
655 left, left_pos, right, right_pos,
656 ),
657 pos,
658 ));
659 }
660 }
661 Ok(())
662 }
663
664 fn op_gteq(&mut self, pos: Position) -> Result<(), Error> {
665 let (left, left_pos) = self.pop()?;
666 let (right, right_pos) = self.pop()?;
667 match (left.as_ref(), right.as_ref()) {
668 (&P(Int(i)), &P(Int(ii))) => {
669 self.push(Rc::new(P(Bool(i >= ii))), pos)?;
670 }
671 (&P(Float(f)), &P(Float(ff))) => {
672 self.push(Rc::new(P(Bool(f >= ff))), pos)?;
673 }
674 _ => {
675 return Err(Error::new(
676 format!(
677 "Expected numeric values of the same type but got {:?} at {} and {:?} at {} for expression",
678 left, left_pos, right, right_pos,
679 ),
680 pos,
681 ));
682 }
683 }
684 Ok(())
685 }
686
687 fn op_mod(&mut self, pos: Position) -> Result<(), Error> {
688 let (left, _) = self.pop()?;
690 let (right, right_pos) = self.pop()?;
691 self.push(Rc::new(P(self.modulus(&left, &right, &right_pos)?)), pos)?;
693 Ok(())
694 }
695
696 fn op_add(&mut self, pos: Position) -> Result<(), Error> {
697 let (left, _) = self.pop()?;
699 let (right, right_pos) = self.pop()?;
700 self.push(Rc::new(self.add(&left, &right, &right_pos)?), pos)?;
702 Ok(())
703 }
704
705 fn op_sub(&mut self, pos: Position) -> Result<(), Error> {
706 let (left, _) = self.pop()?;
708 let (right, right_pos) = self.pop()?;
709 self.push(Rc::new(P(self.sub(&left, &right, &right_pos)?)), pos)?;
711 Ok(())
712 }
713
714 fn op_mul(&mut self, pos: Position) -> Result<(), Error> {
715 let (left, _) = self.pop()?;
717 let (right, right_pos) = self.pop()?;
718 self.push(Rc::new(P(self.mul(&left, &right, &right_pos)?)), pos)?;
720 Ok(())
721 }
722
723 fn op_div(&mut self, pos: Position) -> Result<(), Error> {
724 let (left, _) = self.pop()?;
726 let (right, right_pos) = self.pop()?;
727 self.push(Rc::new(P(self.div(&left, &right, &right_pos)?)), pos)?;
729 Ok(())
730 }
731
732 fn op_push_self(&mut self) -> Result<(), Error> {
733 let (val, pos) = self.pop()?;
735 self.self_stack.push((val.clone(), pos.clone()));
736 self.push(val.clone(), pos)?;
737 Ok(())
738 }
739
740 fn op_pop_self(&mut self) -> Result<(), Error> {
741 self.self_stack.pop();
743 Ok(())
744 }
745
746 fn op_bind(&mut self, strict: bool) -> Result<(), Error> {
747 let (val, val_pos) = self.pop()?;
749 let (name, name_pos) = self.pop()?;
751 if let &S(ref name) = name.as_ref() {
753 self.binding_push(name.clone(), val, strict, &val_pos, &name_pos)?;
754 } else {
755 unreachable!();
756 }
757 Ok(())
758 }
759
760 fn op_field(&mut self) -> Result<(), Error> {
761 let (val, val_pos) = self.pop()?;
764 let (name_val, name_pos) = self.pop()?;
766 let name = if let &S(ref s) | &P(Str(ref s)) = name_val.as_ref() {
767 s
768 } else {
769 unreachable!();
770 };
771 let (tpl, tpl_pos) = self.pop()?;
773 if let &C(Tuple(ref flds, ref pos_list)) = tpl.as_ref() {
774 let mut flds = flds.clone();
776 let mut pos_list = pos_list.clone();
777 self.merge_field_into_tuple(
778 &mut flds,
779 &mut pos_list,
780 name.clone(),
781 &name_pos,
782 val,
783 &val_pos,
784 )?;
785 self.push(Rc::new(C(Tuple(flds, pos_list))), tpl_pos)?;
787 } else {
788 unreachable!();
789 };
790 Ok(())
791 }
792
793 fn op_element(&mut self) -> Result<(), Error> {
794 let (val, val_pos) = self.pop()?;
796 let (list, pos) = self.pop()?;
798 if let &C(List(ref elems, ref pos_list)) = list.as_ref() {
799 let mut elems = elems.clone();
801 elems.push(val);
802 let mut pos_list = pos_list.clone();
803 pos_list.push(val_pos);
804 self.push(Rc::new(C(List(elems, pos_list))), pos)?;
806 } else {
807 unreachable!();
808 };
809 Ok(())
810 }
811
812 fn op_bang(&mut self) -> Result<(), Error> {
813 let (msg_val, err_pos) = self.pop()?;
814 if let &P(Str(ref msg)) = msg_val.as_ref() {
815 return Err(Error::new(msg.clone(), err_pos));
816 } else {
817 unreachable!();
818 }
819 }
820
821 fn op_index(&mut self, safe: bool, pos: Position) -> Result<(), Error> {
822 let (right, right_pos) = self.pop()?;
824 let (left, _) = self.pop()?;
825 match right.as_ref() {
826 &P(Int(i)) => {
827 if let &C(List(ref elems, _)) = left.as_ref() {
828 if i < (elems.len() as i64) && i >= 0 {
829 self.push(elems[i as usize].clone(), right_pos)?;
830 return Ok(());
831 }
832 }
833 }
834 &P(Str(ref s)) => {
835 if let &C(Tuple(ref flds, _)) = left.as_ref() {
836 for &(ref key, ref val) in flds.iter() {
837 if key == s {
838 self.push(val.clone(), right_pos)?;
839 return Ok(());
840 }
841 }
842 }
843 }
844 _ => {
845 }
847 };
848 if safe {
849 self.push(Rc::new(P(Empty)), pos)?;
850 return Ok(());
851 }
852 return Err(Error::new(
853 format!("Invalid selector index: {:?} target: {:?}", right, left),
854 pos,
855 ));
856 }
857
858 fn op_exist(&mut self, pos: Position) -> Result<(), Error> {
859 let (right, right_pos) = self.pop()?;
860 let (left, left_pos) = self.pop()?;
861 match left.as_ref() {
862 &C(Tuple(ref flds, _)) => {
863 if let &P(Str(ref name)) = right.as_ref() {
864 for (ref nm, _) in flds {
865 if nm == name {
866 self.push(Rc::new(P(Bool(true))), pos)?;
867 return Ok(());
868 }
869 }
870 } else {
871 return Err(Error::new(
872 format!("Expected String or Symbol got: {}", right.type_name()),
873 right_pos,
874 ));
875 }
876 }
877 &C(List(ref elems, _)) => {
878 for e in elems {
879 if e == &right {
880 self.push(Rc::new(P(Bool(true))), pos)?;
881 return Ok(());
882 }
883 }
884 }
885 &P(Str(ref s)) => {
886 if let &P(Str(ref part)) = right.as_ref() {
887 self.push(Rc::new(P(Bool(s.contains(part)))), pos)?;
888 return Ok(());
889 }
890 }
891 _ => {
892 return Err(Error::new(
893 format!("Expected String, Tuple, or List got: {}", left.type_name()),
894 left_pos,
895 ));
896 }
897 };
898 self.push(Rc::new(P(Bool(false))), pos)?;
899 Ok(())
900 }
901
902 fn op_copy<O, E>(
903 &mut self,
904 pos: Position,
905 env: &RefCell<Environment<O, E>>,
906 ) -> Result<(), Error>
907 where
908 O: std::io::Write + Clone,
909 E: std::io::Write + Clone,
910 {
911 let (override_val, val_pos) = self.pop()?;
913 let (tgt, tgt_pos) = self.pop()?;
915 let (overrides, override_pos_list) =
916 if let &C(Tuple(ref oflds, ref pos_list)) = override_val.as_ref() {
917 (oflds.clone(), pos_list.clone())
918 } else {
919 unreachable!();
920 };
921 match tgt.as_ref() {
922 &C(Tuple(ref flds, ref pos_list)) => {
923 let mut flds = flds.clone();
924 let mut pos_list = pos_list.clone();
925 let mut counter = 0;
926 for (name, val) in overrides {
927 let name_pos = override_pos_list[counter].0.clone();
928 let val_pos = override_pos_list[counter].1.clone();
929 self.merge_field_into_tuple(
930 &mut flds,
931 &mut pos_list,
932 name,
933 &name_pos,
934 val,
935 &val_pos,
936 )?;
937 counter += 1;
938 }
939 self.push(Rc::new(C(Tuple(flds, pos_list))), tgt_pos.clone())?;
941 self.last = Some((tgt.clone(), tgt_pos));
942 }
943 &M(Module {
944 ref ptr,
945 ref result_ptr,
946 ref flds,
947 ref flds_pos_list,
948 ref pkg_ptr,
949 }) => {
950 let this = M(Module {
951 ptr: ptr.clone(),
952 result_ptr: result_ptr.clone(),
953 flds: flds.clone(),
954 flds_pos_list: flds_pos_list.clone(),
955 pkg_ptr: pkg_ptr.clone(),
956 });
957
958 let mut flds = flds.clone();
959 let mut flds_pos_list = flds_pos_list.clone();
960 let mut counter = 0;
961 for (name, val) in overrides {
962 let name_pos = override_pos_list[counter].0.clone();
963 let val_pos = override_pos_list[counter].1.clone();
964 self.merge_field_into_tuple(
965 &mut flds,
966 &mut flds_pos_list,
967 name,
968 &name_pos,
969 val,
970 &val_pos,
971 )?;
972 counter += 1;
973 }
974 self.merge_field_into_tuple(
975 &mut flds,
976 &mut flds_pos_list,
977 "this".to_owned(),
978 &pos,
979 Rc::new(this),
980 &val_pos,
981 )?;
982 if let Some(ptr) = pkg_ptr {
983 let mut pkg_vm = self
984 .clean_copy()
985 .to_new_pointer(ptr.clone())
986 .with_import_stack(self.import_stack.clone());
987 pkg_vm.run(env)?;
988 let (pkg_func, val_pos) = pkg_vm.pop()?;
989 self.merge_field_into_tuple(
990 &mut flds,
991 &mut flds_pos_list,
992 "pkg".to_owned(),
993 &pos,
994 pkg_func,
995 &val_pos,
996 )?;
997 }
998
999 let mut vm = self
1000 .clean_copy()
1001 .to_new_pointer(ptr.clone())
1002 .with_import_stack(self.import_stack.clone());
1003 vm.push(Rc::new(S("mod".to_owned())), pos.clone())?;
1004 vm.push(Rc::new(C(Tuple(flds, flds_pos_list))), pos.clone())?;
1005 decorate_call!(pos => vm.run(env))?;
1006 if let Some(ptr) = result_ptr {
1007 vm.ops.jump(ptr.clone())?;
1008 vm.run(env)?;
1009 let (result_val, result_pos) = vm.pop()?;
1010 self.push(result_val, result_pos)?;
1011 } else {
1012 self.push(Rc::new(vm.symbols_to_tuple(false)), pos)?;
1013 }
1014 }
1015 _ => {
1016 return Err(Error::new(
1017 format!("Expected a Tuple or Module but got {:?}", tgt),
1018 pos,
1019 ));
1020 }
1021 }
1022 Ok(())
1023 }
1024
1025 fn merge_field_into_tuple(
1026 &self,
1027 src_fields: &mut Vec<(String, Rc<Value>)>,
1028 pos_fields: &mut Vec<(Position, Position)>,
1029 name: String,
1030 name_pos: &Position,
1031 value: Rc<Value>,
1032 val_pos: &Position,
1033 ) -> Result<(), Error> {
1034 let mut counter = 0;
1035 for fld in src_fields.iter_mut() {
1036 if fld.0 == name {
1037 if fld.1.type_name() != value.type_name()
1038 && !(fld.1.type_name() == "NULL" || value.type_name() == "NULL")
1039 {
1040 return Err(Error::new(
1041 format!(
1042 "Expected type {} for field {} but got ({})",
1043 fld.1.type_name(),
1044 name,
1045 value.type_name(),
1046 ),
1047 val_pos.clone(),
1048 ));
1049 }
1050 pos_fields[counter].1 = val_pos.clone();
1051 fld.1 = value;
1052 return Ok(());
1053 }
1054 counter += 1;
1055 }
1056 src_fields.push((name, value));
1057 pos_fields.push((name_pos.clone(), val_pos.clone()));
1058 Ok(())
1059 }
1060
1061 fn push(&mut self, val: Rc<Value>, pos: Position) -> Result<(), Error> {
1062 self.stack.push((val, pos));
1063 Ok(())
1064 }
1065
1066 pub fn binding_push(
1067 &mut self,
1068 name: String,
1069 val: Rc<Value>,
1070 strict: bool,
1071 pos: &Position,
1072 name_pos: &Position,
1073 ) -> Result<(), Error> {
1074 if self.reserved_words.contains(name.as_str()) {
1075 return Err(Error::new(
1076 format!("{} is a reserved word.", name),
1077 name_pos.clone(),
1078 ));
1079 }
1080 if self.symbols.is_bound(&name) && strict {
1081 return Err(Error::new(
1082 format!("Binding {} already exists", name),
1083 pos.clone(),
1084 ));
1085 }
1086 self.symbols.add(name, val, pos.clone());
1087 Ok(())
1088 }
1089
1090 pub fn get_binding<O, E>(
1091 &self,
1092 name: &str,
1093 env: &RefCell<Environment<O, E>>,
1094 pos: &Position,
1095 ) -> Result<(Rc<Value>, Position), Error>
1096 where
1097 O: std::io::Write + Clone,
1098 E: std::io::Write + Clone,
1099 {
1100 let tpl = if name == "self" {
1102 self.self_stack.last().cloned()
1103 } else if name == "env" {
1104 let candidate = self.symbols.get(name);
1105 if candidate.is_some() {
1106 candidate
1107 } else {
1108 Some((
1109 Rc::new(env.borrow().get_env_vars_tuple()),
1110 Position::new(0, 0, 0),
1111 ))
1112 }
1113 } else {
1114 self.symbols.get(name)
1115 };
1116 match tpl {
1117 Some((v, pos)) => Ok((v, pos)),
1118 None => {
1119 return Err(Error::new(format!("No such binding {}", name), pos.clone()));
1120 }
1121 }
1122 }
1123
1124 pub fn pop(&mut self) -> Result<(Rc<Value>, Position), Error> {
1125 match self.stack.pop() {
1126 Some(v) => {
1127 self.last = Some(v.clone());
1128 Ok(v)
1129 }
1130 None => unreachable!(),
1131 }
1132 }
1133
1134 fn mul(&self, left: &Value, right: &Value, pos: &Position) -> Result<Primitive, Error> {
1135 Ok(match (left, right) {
1136 (P(Int(i)), P(Int(ii))) => Int(i * ii),
1137 (P(Float(f)), P(Float(ff))) => Float(f * ff),
1138 _ => {
1139 return Err(Error::new(
1140 format!("Expected {} but got {:?}", left.type_name(), right),
1141 pos.clone(),
1142 ))
1143 }
1144 })
1145 }
1146
1147 fn div(&self, left: &Value, right: &Value, pos: &Position) -> Result<Primitive, Error> {
1148 Ok(match (left, right) {
1149 (P(Int(i)), P(Int(ii))) => Int(i / ii),
1150 (P(Float(f)), P(Float(ff))) => Float(f / ff),
1151 _ => {
1152 return Err(Error::new(
1153 format!("Expected {} but got {:?}", left.type_name(), right),
1154 pos.clone(),
1155 ))
1156 }
1157 })
1158 }
1159
1160 fn sub(&self, left: &Value, right: &Value, pos: &Position) -> Result<Primitive, Error> {
1161 Ok(match (left, right) {
1162 (P(Int(i)), Value::P(Int(ii))) => Int(i - ii),
1163 (P(Float(f)), Value::P(Float(ff))) => Float(f - ff),
1164 _ => {
1165 return Err(Error::new(
1166 format!("Expected {} but got {:?}", left.type_name(), right),
1167 pos.clone(),
1168 ))
1169 }
1170 })
1171 }
1172
1173 fn modulus(&self, left: &Value, right: &Value, pos: &Position) -> Result<Primitive, Error> {
1174 Ok(match (left, right) {
1175 (P(Int(i)), Value::P(Int(ii))) => Int(i % ii),
1176 (P(Float(f)), Value::P(Float(ff))) => Float(f % ff),
1177 _ => {
1178 return Err(Error::new(
1179 format!("Expected {} but got {:?}", left.type_name(), right),
1180 pos.clone(),
1181 ))
1182 }
1183 })
1184 }
1185
1186 fn add(&self, left: &Value, right: &Value, pos: &Position) -> Result<Value, Error> {
1187 Ok(match (left, right) {
1188 (P(Int(i)), Value::P(Int(ii))) => P(Int(i + ii)),
1189 (P(Float(f)), Value::P(Float(ff))) => P(Float(f + ff)),
1190 (P(Str(s)), Value::P(Str(ss))) => {
1191 let mut ns = String::new();
1192 ns.push_str(&s);
1193 ns.push_str(&ss);
1194 P(Str(ns))
1195 }
1196 (
1197 C(List(ref left_list, ref left_pos_list)),
1198 C(List(ref right_list, ref right_pos_list)),
1199 ) => {
1200 let cap = left_list.len() + right_list.len();
1201 let mut new_list = Vec::with_capacity(cap);
1202 let mut new_pos_list = Vec::with_capacity(cap);
1203 let mut counter = 0;
1204 for v in left_list.iter() {
1205 new_list.push(v.clone());
1206 new_pos_list.push(left_pos_list[counter].clone());
1207 counter += 1;
1208 }
1209 counter = 0;
1210 for v in right_list.iter() {
1211 new_list.push(v.clone());
1212 new_pos_list.push(right_pos_list[counter].clone());
1213 counter += 1;
1214 }
1215 C(List(new_list, new_pos_list))
1216 }
1217 _ => {
1218 return Err(Error::new(
1219 format!("Expected {} but got {:?}", left.type_name(), right),
1220 pos.clone(),
1221 ))
1222 }
1223 })
1224 }
1225
1226 fn op_runtime<O, E>(
1227 &mut self,
1228 h: Hook,
1229 pos: Position,
1230 env: &RefCell<Environment<O, E>>,
1231 ) -> Result<(), Error>
1232 where
1233 O: std::io::Write + Clone,
1234 E: std::io::Write + Clone,
1235 {
1236 self.runtime.handle(
1237 self.ops.path.as_ref(),
1238 h,
1239 &mut self.stack,
1240 env,
1241 &mut self.import_stack,
1242 pos,
1243 )
1244 }
1245
1246 fn op_render(&mut self) -> Result<(), Error> {
1247 let (val, pos) = self.pop()?;
1248 self.push(Rc::new(P(Str(val.as_ref().into()))), pos)?;
1249 Ok(())
1250 }
1251}