DEV: Bindings store their location too.

This commit is contained in:
Jeremy Wall 2019-08-20 19:03:49 -05:00
parent e4c652b240
commit b024d23110
3 changed files with 27 additions and 12 deletions

View File

@ -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<String, Rc<Value>>,
curr: BTreeMap<String, (Rc<Value>, Position)>,
}
impl Stack {
@ -28,7 +29,7 @@ impl Stack {
}
}
pub fn get(&self, name: &str) -> Option<Rc<Value>> {
pub fn get(&self, name: &str) -> Option<(Rc<Value>, 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<Value>) {
self.curr.insert(name, val);
pub fn add(&mut self, name: String, val: Rc<Value>, pos: Position) {
self.curr.insert(name, (val, pos));
}
pub fn symbol_list(&self) -> Vec<&String> {

View File

@ -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![

View File

@ -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<Rc<Value>, Error> {
pub fn get_binding(
&'a self,
name: &str,
pos: &Position,
) -> Result<(Rc<Value>, 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()