From b024d231103105f16ff2cda336cce67f53233771 Mon Sep 17 00:00:00 2001 From: Jeremy Wall Date: Tue, 20 Aug 2019 19:03:49 -0500 Subject: [PATCH] DEV: Bindings store their location too. --- src/build/opcode/scope.rs | 9 +++++---- src/build/opcode/test.rs | 12 ++++++++++-- src/build/opcode/vm.rs | 18 ++++++++++++------ 3 files changed, 27 insertions(+), 12 deletions(-) diff --git a/src/build/opcode/scope.rs b/src/build/opcode/scope.rs index 0a2033f..5b83f67 100644 --- a/src/build/opcode/scope.rs +++ b/src/build/opcode/scope.rs @@ -14,11 +14,12 @@ use std::collections::BTreeMap; use std::rc::Rc; +use crate::ast::Position; use super::Value; #[derive(Clone, PartialEq, Debug)] pub struct Stack { - curr: BTreeMap>, + curr: BTreeMap, Position)>, } impl Stack { @@ -28,7 +29,7 @@ impl Stack { } } - pub fn get(&self, name: &str) -> Option> { + pub fn get(&self, name: &str) -> Option<(Rc, Position)> { self.curr.get(name).cloned() } @@ -36,8 +37,8 @@ impl Stack { self.curr.get(name).is_some() } - pub fn add(&mut self, name: String, val: Rc) { - self.curr.insert(name, val); + pub fn add(&mut self, name: String, val: Rc, pos: Position) { + self.curr.insert(name, (val, pos)); } pub fn symbol_list(&self) -> Vec<&String> { diff --git a/src/build/opcode/test.rs b/src/build/opcode/test.rs index 72c0f06..a0be83c 100644 --- a/src/build/opcode/test.rs +++ b/src/build/opcode/test.rs @@ -140,7 +140,7 @@ fn bind_op() { let mut vm = VM::new(Rc::new(map), env); vm.run().unwrap(); let (name, result) = case.1; - let v = vm.get_binding(name, &Position::new(0, 0, 0)).unwrap(); + let (v, _) = vm.get_binding(name, &Position::new(0, 0, 0)).unwrap(); assert_eq!(&result, v.as_ref()); } } @@ -400,7 +400,7 @@ fn function_definition_and_call() { fn module_call() { assert_cases![ vec![ - InitTuple, // 0 // override tuple + InitTuple, // 0 // override tuple Sym("one".to_owned()), // 1 Val(Int(11)), // 2 Field, // 3 @@ -732,6 +732,14 @@ fn simple_modules() { ]; } +#[test] +fn tuple_copies() { + assert_parse_cases![ + "let tpl = { v = 1, }; tpl{};" => C(Tuple(vec![("v".to_owned(), Rc::new(P(Int(1))))])), + "let tpl = { v = 1, }; tpl{v=2};" => C(Tuple(vec![("v".to_owned(), Rc::new(P(Int(2))))])), + ]; +} + #[test] fn simple_range() { assert_parse_cases![ diff --git a/src/build/opcode/vm.rs b/src/build/opcode/vm.rs index acc5c8e..adf9e20 100644 --- a/src/build/opcode/vm.rs +++ b/src/build/opcode/vm.rs @@ -76,7 +76,8 @@ where let mut flds = Vec::new(); for sym in self.symbols.symbol_list() { if include_mod || sym != "mod" { - flds.push((sym.clone(), self.symbols.get(sym).unwrap().clone())); + let (val, _) = self.symbols.get(sym).unwrap().clone(); + flds.push((sym.clone(), val)); } } return C(Tuple(flds)); @@ -169,7 +170,7 @@ where } fn op_deref(&mut self, name: String, pos: &Position) -> Result<(), Error> { - let val = self.get_binding(&name, pos)?.clone(); + let (val, _) = self.get_binding(&name, pos)?.clone(); self.push(val, pos.clone()) } @@ -686,7 +687,8 @@ where self.merge_field_into_tuple(&mut flds, name, val)?; } // Put the copy on the Stack - self.push(Rc::new(C(Tuple(flds))), tgt_pos)?; + self.push(Rc::new(C(Tuple(flds))), tgt_pos.clone())?; + self.last = Some((tgt.clone(), tgt_pos)); } &M(Module { ref ptr, @@ -771,13 +773,17 @@ where pos.clone(), ))); } - self.symbols.add(name, val); + self.symbols.add(name, val, pos.clone()); Ok(()) } - pub fn get_binding(&'a self, name: &str, pos: &Position) -> Result, Error> { + pub fn get_binding( + &'a self, + name: &str, + pos: &Position, + ) -> Result<(Rc, Position), Error> { match self.symbols.get(name) { - Some(v) => Ok(v), + Some((ref v, ref pos)) => Ok((v.clone(), pos.clone())), None => Err(dbg!(Error::new( format!("No such binding {}", name), pos.clone()