mirror of
https://github.com/zaphar/ucg.git
synced 2025-07-23 18:29:50 -04:00
DEV: Bindings store their location too.
This commit is contained in:
parent
e4c652b240
commit
b024d23110
@ -14,11 +14,12 @@
|
|||||||
use std::collections::BTreeMap;
|
use std::collections::BTreeMap;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
|
use crate::ast::Position;
|
||||||
use super::Value;
|
use super::Value;
|
||||||
|
|
||||||
#[derive(Clone, PartialEq, Debug)]
|
#[derive(Clone, PartialEq, Debug)]
|
||||||
pub struct Stack {
|
pub struct Stack {
|
||||||
curr: BTreeMap<String, Rc<Value>>,
|
curr: BTreeMap<String, (Rc<Value>, Position)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Stack {
|
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()
|
self.curr.get(name).cloned()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -36,8 +37,8 @@ impl Stack {
|
|||||||
self.curr.get(name).is_some()
|
self.curr.get(name).is_some()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add(&mut self, name: String, val: Rc<Value>) {
|
pub fn add(&mut self, name: String, val: Rc<Value>, pos: Position) {
|
||||||
self.curr.insert(name, val);
|
self.curr.insert(name, (val, pos));
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn symbol_list(&self) -> Vec<&String> {
|
pub fn symbol_list(&self) -> Vec<&String> {
|
||||||
|
@ -140,7 +140,7 @@ fn bind_op() {
|
|||||||
let mut vm = VM::new(Rc::new(map), env);
|
let mut vm = VM::new(Rc::new(map), env);
|
||||||
vm.run().unwrap();
|
vm.run().unwrap();
|
||||||
let (name, result) = case.1;
|
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());
|
assert_eq!(&result, v.as_ref());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -400,7 +400,7 @@ fn function_definition_and_call() {
|
|||||||
fn module_call() {
|
fn module_call() {
|
||||||
assert_cases![
|
assert_cases![
|
||||||
vec![
|
vec![
|
||||||
InitTuple, // 0 // override tuple
|
InitTuple, // 0 // override tuple
|
||||||
Sym("one".to_owned()), // 1
|
Sym("one".to_owned()), // 1
|
||||||
Val(Int(11)), // 2
|
Val(Int(11)), // 2
|
||||||
Field, // 3
|
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]
|
#[test]
|
||||||
fn simple_range() {
|
fn simple_range() {
|
||||||
assert_parse_cases![
|
assert_parse_cases![
|
||||||
|
@ -76,7 +76,8 @@ where
|
|||||||
let mut flds = Vec::new();
|
let mut flds = Vec::new();
|
||||||
for sym in self.symbols.symbol_list() {
|
for sym in self.symbols.symbol_list() {
|
||||||
if include_mod || sym != "mod" {
|
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));
|
return C(Tuple(flds));
|
||||||
@ -169,7 +170,7 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn op_deref(&mut self, name: String, pos: &Position) -> Result<(), Error> {
|
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())
|
self.push(val, pos.clone())
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -686,7 +687,8 @@ where
|
|||||||
self.merge_field_into_tuple(&mut flds, name, val)?;
|
self.merge_field_into_tuple(&mut flds, name, val)?;
|
||||||
}
|
}
|
||||||
// Put the copy on the Stack
|
// 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 {
|
&M(Module {
|
||||||
ref ptr,
|
ref ptr,
|
||||||
@ -771,13 +773,17 @@ where
|
|||||||
pos.clone(),
|
pos.clone(),
|
||||||
)));
|
)));
|
||||||
}
|
}
|
||||||
self.symbols.add(name, val);
|
self.symbols.add(name, val, pos.clone());
|
||||||
Ok(())
|
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) {
|
match self.symbols.get(name) {
|
||||||
Some(v) => Ok(v),
|
Some((ref v, ref pos)) => Ok((v.clone(), pos.clone())),
|
||||||
None => Err(dbg!(Error::new(
|
None => Err(dbg!(Error::new(
|
||||||
format!("No such binding {}", name),
|
format!("No such binding {}", name),
|
||||||
pos.clone()
|
pos.clone()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user