refactor: Get rid of the unecessary PositionedItem

This commit is contained in:
Jeremy Wall 2023-10-02 19:57:15 -04:00 committed by Jeremy Wall
parent d1e5d4129f
commit 76f1f0dee6
12 changed files with 149 additions and 177 deletions

View File

@ -278,10 +278,10 @@ impl NarrowedShape {
/// Shapes represent the types that UCG values or expressions can have. /// Shapes represent the types that UCG values or expressions can have.
#[derive(PartialEq, Debug, Clone)] #[derive(PartialEq, Debug, Clone)]
pub enum Shape { pub enum Shape {
Boolean(PositionedItem<bool>), Boolean(Position),
Int(PositionedItem<i64>), Int(Position),
Float(PositionedItem<f64>), Float(Position),
Str(PositionedItem<Rc<str>>), Str(Position),
Tuple(PositionedItem<TupleShape>), Tuple(PositionedItem<TupleShape>),
List(NarrowedShape), List(NarrowedShape),
Func(FuncShapeDef), Func(FuncShapeDef),
@ -305,7 +305,7 @@ impl Shape {
symbol_table.insert(sym.val.clone(), other.clone().with_pos(sym.pos.clone())); symbol_table.insert(sym.val.clone(), other.clone().with_pos(sym.pos.clone()));
} }
other.clone() other.clone()
}, }
(Shape::Narrowed(left_slist), Shape::Narrowed(right_slist)) (Shape::Narrowed(left_slist), Shape::Narrowed(right_slist))
| (Shape::List(left_slist), Shape::List(right_slist)) => { | (Shape::List(left_slist), Shape::List(right_slist)) => {
self.narrow_list_shapes(left_slist, right_slist, right, symbol_table) self.narrow_list_shapes(left_slist, right_slist, right, symbol_table)
@ -386,10 +386,10 @@ impl Shape {
pub fn pos(&self) -> &Position { pub fn pos(&self) -> &Position {
match self { match self {
Shape::Str(s) => &s.pos, Shape::Str(p) => &p,
Shape::Int(s) => &s.pos, Shape::Int(p) => &p,
Shape::Float(s) => &s.pos, Shape::Float(p) => &p,
Shape::Boolean(b) => &b.pos, Shape::Boolean(p) => &p,
Shape::List(lst) => &lst.pos, Shape::List(lst) => &lst.pos,
Shape::Tuple(flds) => &flds.pos, Shape::Tuple(flds) => &flds.pos,
Shape::Func(def) => def.ret.pos(), Shape::Func(def) => def.ret.pos(),
@ -404,10 +404,10 @@ impl Shape {
pub fn with_pos(self, pos: Position) -> Self { pub fn with_pos(self, pos: Position) -> Self {
match self { match self {
Shape::Str(s) => Shape::Str(PositionedItem::new(s.val, pos)), Shape::Str(_) => Shape::Str(pos.clone()),
Shape::Int(s) => Shape::Int(PositionedItem::new(s.val, pos)), Shape::Int(_) => Shape::Int(pos.clone()),
Shape::Float(s) => Shape::Float(PositionedItem::new(s.val, pos)), Shape::Float(_) => Shape::Float(pos.clone()),
Shape::Boolean(b) => Shape::Boolean(PositionedItem::new(b.val, pos)), Shape::Boolean(_) => Shape::Boolean(pos.clone()),
Shape::List(lst) => Shape::List(NarrowedShape::new_with_pos(lst.types, pos)), Shape::List(lst) => Shape::List(NarrowedShape::new_with_pos(lst.types, pos)),
Shape::Tuple(flds) => Shape::Tuple(PositionedItem::new(flds.val, pos)), Shape::Tuple(flds) => Shape::Tuple(PositionedItem::new(flds.val, pos)),
Shape::Func(_) | Shape::Module(_) => self.clone(), Shape::Func(_) | Shape::Module(_) => self.clone(),

View File

@ -16,7 +16,10 @@ use std::collections::BTreeMap;
use abortable_parser::iter::SliceIter; use abortable_parser::iter::SliceIter;
use abortable_parser::Result as ParseResult; use abortable_parser::Result as ParseResult;
use crate::ast::{Expression, ListDef, Position, PositionedItem, Shape, Token, TokenType, Value ,NarrowedShape, typecheck::DeriveShape}; use crate::ast::{
typecheck::DeriveShape, Expression, ListDef, NarrowedShape, Position, PositionedItem, Shape,
Token, TokenType, Value,
};
use crate::iter::OffsetStrIter; use crate::iter::OffsetStrIter;
use crate::parse::expression; use crate::parse::expression;
use crate::tokenizer::tokenize; use crate::tokenizer::tokenize;
@ -26,29 +29,23 @@ fn derive_shape_values() {
let value_cases = vec![ let value_cases = vec![
( (
Value::Boolean(PositionedItem::new(false, Position::new(0, 1, 2))), Value::Boolean(PositionedItem::new(false, Position::new(0, 1, 2))),
Shape::Boolean(PositionedItem::new(false, Position::new(0, 1, 2))), Shape::Boolean(Position::new(0, 1, 2)),
), ),
( (
Value::Boolean(PositionedItem::new(true, Position::new(0, 1, 2))), Value::Boolean(PositionedItem::new(true, Position::new(0, 1, 2))),
Shape::Boolean(PositionedItem::new(true, Position::new(0, 1, 2))), Shape::Boolean(Position::new(0, 1, 2)),
), ),
( (
Value::Int(PositionedItem::new(1, Position::new(0, 1, 2))), Value::Int(PositionedItem::new(1, Position::new(0, 1, 2))),
Shape::Int(PositionedItem::new(1, Position::new(0, 1, 2))), Shape::Int(Position::new(0, 1, 2)),
), ),
( (
Value::Float(PositionedItem::new(2.0, Position::new(0, 1, 2))), Value::Float(PositionedItem::new(2.0, Position::new(0, 1, 2))),
Shape::Float(PositionedItem::new(2.0, Position::new(0, 1, 2))), Shape::Float(Position::new(0, 1, 2)),
), ),
( (
Value::Str(PositionedItem::new( Value::Str(PositionedItem::new("foo".into(), Position::new(0, 1, 2))),
"foo".into(), Shape::Str(Position::new(0, 1, 2)),
Position::new(0, 1, 2),
)),
Shape::Str(PositionedItem::new(
"foo".into(),
Position::new(0, 1, 2),
)),
), ),
( (
Value::Tuple(PositionedItem::new( Value::Tuple(PositionedItem::new(
@ -61,7 +58,7 @@ fn derive_shape_values() {
Shape::Tuple(PositionedItem::new( Shape::Tuple(PositionedItem::new(
vec![( vec![(
Token::new("foo", TokenType::BAREWORD, Position::new(0, 0, 0)), Token::new("foo", TokenType::BAREWORD, Position::new(0, 0, 0)),
Shape::Int(PositionedItem::new(3, Position::new(0, 0, 0))), Shape::Int(Position::new(0, 0, 0)),
)], )],
Position::new(0, 0, 0), Position::new(0, 0, 0),
)), )),
@ -75,7 +72,7 @@ fn derive_shape_values() {
pos: Position::new(0, 0, 0), pos: Position::new(0, 0, 0),
}), }),
Shape::List(NarrowedShape::new_with_pos( Shape::List(NarrowedShape::new_with_pos(
vec![Shape::Int(PositionedItem::new(3, Position::new(0, 0, 0)))], vec![Shape::Int(Position::new(0, 0, 0))],
Position::new(0, 0, 0), Position::new(0, 0, 0),
)), )),
), ),
@ -89,49 +86,22 @@ fn derive_shape_values() {
#[test] #[test]
fn derive_shape_expressions() { fn derive_shape_expressions() {
let expr_cases = vec![ let expr_cases = vec![
( ("3;", Shape::Int(Position::new(0, 0, 0))),
"3;", ("(3);", Shape::Int(Position::new(0, 0, 0))),
Shape::Int(PositionedItem::new(3, Position::new(0, 0, 0))), ("\"foo {}\" % (1);", Shape::Str(Position::new(0, 0, 0))),
), ("not true;", Shape::Boolean(Position::new(1, 0, 0))),
(
"(3);",
Shape::Int(PositionedItem::new(3, Position::new(0, 0, 0))),
),
(
"\"foo {}\" % (1);",
Shape::Str(PositionedItem::new("".into(), Position::new(0, 0, 0))),
),
(
"not true;",
Shape::Boolean(PositionedItem::new(false, Position::new(1, 0, 0))),
),
( (
"0:1;", "0:1;",
Shape::List(NarrowedShape::new_with_pos( Shape::List(NarrowedShape::new_with_pos(
vec![Shape::Int(PositionedItem::new(0, Position::new(1, 1, 0)))], vec![Shape::Int(Position::new(1, 1, 0))],
Position::new(1, 1, 0), Position::new(1, 1, 0),
)), )),
), ),
( ("int(\"1\");", Shape::Int(Position::new(0, 0, 0))),
"int(\"1\");", ("float(1);", Shape::Float(Position::new(0, 0, 0))),
Shape::Int(PositionedItem::new(0, Position::new(0, 0, 0))), ("str(1);", Shape::Str(Position::new(0, 0, 0))),
), ("bool(\"true\");", Shape::Boolean(Position::new(0, 0, 0))),
( ("1 + 1;", Shape::Int(Position::new(1, 1, 0))),
"float(1);",
Shape::Float(PositionedItem::new(0.0, Position::new(0, 0, 0))),
),
(
"str(1);",
Shape::Str(PositionedItem::new("".into(), Position::new(0, 0, 0))),
),
(
"bool(\"true\");",
Shape::Boolean(PositionedItem::new(true, Position::new(0, 0, 0))),
),
(
"1 + 1;",
Shape::Int(PositionedItem::new(1, Position::new(1, 1, 0))),
),
]; ];
for (expr, shape) in expr_cases { for (expr, shape) in expr_cases {

View File

@ -38,7 +38,7 @@ impl DeriveShape for FuncDef {
let mut sym_table = self let mut sym_table = self
.argdefs .argdefs
.iter() .iter()
.map(|sym| (sym.val.clone(), Shape::Hole(sym.clone()))) .map(|sym| (sym.val.clone(), dbg!(Shape::Hole(sym.clone()))))
.collect::<BTreeMap<Rc<str>, Shape>>(); .collect::<BTreeMap<Rc<str>, Shape>>();
sym_table.append(&mut symbol_table.clone()); sym_table.append(&mut symbol_table.clone());
// 2.Then determine the shapes of those symbols in our expression. // 2.Then determine the shapes of those symbols in our expression.
@ -48,11 +48,20 @@ impl DeriveShape for FuncDef {
let table = self let table = self
.argdefs .argdefs
.iter() .iter()
.map(|sym| (sym.val.clone(), sym_table.get(&sym.val).unwrap().clone())) .map(|sym| {
(
sym.val.clone(),
dbg!(sym_table
.get(&sym.val)
.unwrap()
.clone()
.with_pos(sym.pos.clone())),
)
})
.collect::<BTreeMap<Rc<str>, Shape>>(); .collect::<BTreeMap<Rc<str>, Shape>>();
Shape::Func(FuncShapeDef { Shape::Func(FuncShapeDef {
args: table, args: table,
ret: shape.into(), ret: shape.with_pos(self.pos.clone()).into(),
}) })
} }
} }
@ -75,14 +84,14 @@ fn derive_include_shape(
fn derive_not_shape(def: &NotDef, symbol_table: &mut BTreeMap<Rc<str>, Shape>) -> Shape { fn derive_not_shape(def: &NotDef, symbol_table: &mut BTreeMap<Rc<str>, Shape>) -> Shape {
let shape = def.expr.as_ref().derive_shape(symbol_table); let shape = def.expr.as_ref().derive_shape(symbol_table);
if let Shape::Boolean(b) = &shape { if let Shape::Boolean(_) = &shape {
return Shape::Boolean(PositionedItem::new(!b.val, def.pos.clone())); return Shape::Boolean(def.pos.clone());
} else if let Shape::Hole(_) = &shape { } else if let Shape::Hole(_) = &shape {
return Shape::Boolean(PositionedItem::new(true, def.pos.clone())); return Shape::Boolean(def.pos.clone());
} else if let Shape::Narrowed(shape_list) = &shape { } else if let Shape::Narrowed(shape_list) = &shape {
for s in shape_list.types.iter() { for s in shape_list.types.iter() {
if let Shape::Boolean(b) = s { if let Shape::Boolean(_) = s {
return Shape::Boolean(PositionedItem::new(!b.val, def.pos.clone())); return Shape::Boolean(def.pos.clone());
} }
} }
}; };
@ -194,18 +203,18 @@ impl DeriveShape for Expression {
fn derive_shape(&self, symbol_table: &mut BTreeMap<Rc<str>, Shape>) -> Shape { fn derive_shape(&self, symbol_table: &mut BTreeMap<Rc<str>, Shape>) -> Shape {
match self { match self {
Expression::Simple(v) => v.derive_shape(symbol_table), Expression::Simple(v) => v.derive_shape(symbol_table),
Expression::Format(def) => Shape::Str(PositionedItem::new("".into(), def.pos.clone())), Expression::Format(def) => Shape::Str(def.pos.clone()),
Expression::Not(def) => derive_not_shape(def, symbol_table), Expression::Not(def) => derive_not_shape(def, symbol_table),
Expression::Grouped(v, _pos) => v.as_ref().derive_shape(symbol_table), Expression::Grouped(v, _pos) => v.as_ref().derive_shape(symbol_table),
Expression::Range(def) => Shape::List(NarrowedShape::new_with_pos( Expression::Range(def) => Shape::List(NarrowedShape::new_with_pos(
vec![Shape::Int(PositionedItem::new(0, def.start.pos().clone()))], vec![Shape::Int(def.start.pos().clone())],
def.pos.clone(), def.pos.clone(),
)), )),
Expression::Cast(def) => match def.cast_type { Expression::Cast(def) => match def.cast_type {
CastType::Int => Shape::Int(PositionedItem::new(0, def.pos.clone())), CastType::Int => Shape::Int(def.pos.clone()),
CastType::Str => Shape::Str(PositionedItem::new("".into(), def.pos.clone())), CastType::Str => Shape::Str(def.pos.clone()),
CastType::Float => Shape::Float(PositionedItem::new(0.0, def.pos.clone())), CastType::Float => Shape::Float(def.pos.clone()),
CastType::Bool => Shape::Boolean(PositionedItem::new(true, def.pos.clone())), CastType::Bool => Shape::Boolean(def.pos.clone()),
}, },
Expression::Import(def) => Shape::Import(ImportShape::Unresolved(PositionedItem::new( Expression::Import(def) => Shape::Import(ImportShape::Unresolved(PositionedItem::new(
def.path.fragment.clone(), def.path.fragment.clone(),
@ -233,10 +242,10 @@ impl DeriveShape for Value {
fn derive_shape(&self, symbol_table: &mut BTreeMap<Rc<str>, Shape>) -> Shape { fn derive_shape(&self, symbol_table: &mut BTreeMap<Rc<str>, Shape>) -> Shape {
match self { match self {
Value::Empty(p) => Shape::Narrowed(NarrowedShape::new_with_pos(vec![], p.clone())), Value::Empty(p) => Shape::Narrowed(NarrowedShape::new_with_pos(vec![], p.clone())),
Value::Boolean(p) => Shape::Boolean(p.clone()), Value::Boolean(p) => Shape::Boolean(p.pos.clone()),
Value::Int(p) => Shape::Int(p.clone()), Value::Int(p) => Shape::Int(p.pos.clone()),
Value::Float(p) => Shape::Float(p.clone()), Value::Float(p) => Shape::Float(p.pos.clone()),
Value::Str(p) => Shape::Str(p.clone()), Value::Str(p) => Shape::Str(p.pos.clone()),
Value::Symbol(p) => { Value::Symbol(p) => {
if let Some(s) = symbol_table.get(&p.val) { if let Some(s) = symbol_table.get(&p.val) {
s.clone() s.clone()
@ -336,10 +345,10 @@ impl Visitor for Checker {
vec![], vec![],
p.clone(), p.clone(),
))), ))),
Value::Boolean(p) => self.shape_stack.push(Shape::Boolean(p.clone())), Value::Boolean(p) => self.shape_stack.push(Shape::Boolean(p.pos.clone())),
Value::Int(p) => self.shape_stack.push(Shape::Int(p.clone())), Value::Int(p) => self.shape_stack.push(Shape::Int(p.pos.clone())),
Value::Float(p) => self.shape_stack.push(Shape::Float(p.clone())), Value::Float(p) => self.shape_stack.push(Shape::Float(p.pos.clone())),
Value::Str(p) => self.shape_stack.push(Shape::Str(p.clone())), Value::Str(p) => self.shape_stack.push(Shape::Str(p.pos.clone())),
// Symbols in a shape are placeholders. They allow a form of genericity // Symbols in a shape are placeholders. They allow a form of genericity
// in the shape. They can be any type and are only refined down. // in the shape. They can be any type and are only refined down.
// by their presence in an expression. // by their presence in an expression.

View File

@ -41,18 +41,9 @@ macro_rules! assert_type_success {
#[test] #[test]
fn simple_binary_typecheck() { fn simple_binary_typecheck() {
assert_type_success!( assert_type_success!("1 + 1;", Shape::Int(Position::new(1, 1, 0)));
"1 + 1;", assert_type_success!("\"\" + \"\";", Shape::Str(Position::new(1, 1, 0)));
Shape::Int(PositionedItem::new(1, Position::new(1, 1, 0))) assert_type_success!("1.0 + 1.0;", Shape::Float(Position::new(1, 1, 0)));
);
assert_type_success!(
"\"\" + \"\";",
Shape::Str(PositionedItem::new("".into(), Position::new(1, 1, 0)))
);
assert_type_success!(
"1.0 + 1.0;",
Shape::Float(PositionedItem::new(1.0, Position::new(1, 1, 0)))
);
assert_type_success!( assert_type_success!(
"[] + [];", "[] + [];",
Shape::List(crate::ast::NarrowedShape::new(vec![], 1, 1, 0)) Shape::List(crate::ast::NarrowedShape::new(vec![], 1, 1, 0))
@ -71,7 +62,7 @@ fn simple_binary_typecheck() {
fragment: "foo".into(), fragment: "foo".into(),
pos: Position::new(1, 2, 1) pos: Position::new(1, 2, 1)
}, },
Shape::Int(PositionedItem::new_with_pos(1, Position::new(1, 8, 7))) Shape::Int(Position::new(1, 8, 7))
),], ),],
Position::new(1, 1, 0) Position::new(1, 1, 0)
)) ))
@ -79,10 +70,7 @@ fn simple_binary_typecheck() {
assert_type_success!( assert_type_success!(
"[1] + [2];", "[1] + [2];",
Shape::List(crate::ast::NarrowedShape::new( Shape::List(crate::ast::NarrowedShape::new(
vec![Shape::Int(PositionedItem::new_with_pos( vec![Shape::Int(Position::new(1, 2, 1))],
1,
Position::new(1, 1, 0)
))],
1, 1,
1, 1,
0 0
@ -92,8 +80,8 @@ fn simple_binary_typecheck() {
"[1, 1.0] + [1, 2.0];", "[1, 1.0] + [1, 2.0];",
Shape::List(crate::ast::NarrowedShape::new( Shape::List(crate::ast::NarrowedShape::new(
vec![ vec![
Shape::Int(PositionedItem::new_with_pos(1, Position::new(1, 1, 0))), Shape::Int(Position::new(1, 2, 1)),
Shape::Float(PositionedItem::new_with_pos(1.0, Position::new(1, 1, 0))), Shape::Float(Position::new(1, 5, 4)),
], ],
1, 1,
1, 1,
@ -188,10 +176,7 @@ fn infer_symbol_type_test() {
let table = vec![ let table = vec![
( (
"1 + foo", "1 + foo",
vec![( vec![(foo.clone(), Shape::Int(Position::new(0, 0, 0)))],
foo.clone(),
Shape::Int(PositionedItem::new(1, Position::new(0, 0, 0))),
)],
vec![Shape::Hole(PositionedItem::new( vec![Shape::Hole(PositionedItem::new(
foo.clone(), foo.clone(),
Position::new(0, 0, 0), Position::new(0, 0, 0),
@ -200,18 +185,12 @@ fn infer_symbol_type_test() {
( (
"bar + foo", "bar + foo",
vec![ vec![
( (foo.clone(), Shape::Float(Position::new(0, 0, 0))),
foo.clone(), (bar.clone(), Shape::Float(Position::new(0, 0, 0))),
Shape::Float(PositionedItem::new(1.0, Position::new(0, 0, 0))),
),
(
bar.clone(),
Shape::Float(PositionedItem::new(1.0, Position::new(0, 0, 0))),
),
], ],
vec![ vec![
Shape::Hole(PositionedItem::new(foo.clone(), Position::new(0, 0, 0))), Shape::Hole(PositionedItem::new(foo.clone(), Position::new(0, 0, 0))),
Shape::Float(PositionedItem::new(1.0, Position::new(0, 0, 0))), Shape::Float(Position::new(0, 0, 0)),
], ],
), ),
]; ];
@ -227,24 +206,18 @@ fn infer_func_type_test() {
let bar = Into::<Rc<str>>::into("bar"); let bar = Into::<Rc<str>>::into("bar");
args.insert( args.insert(
foo.clone(), foo.clone(),
Shape::Int(PositionedItem { Shape::Int(Position {
pos: Position {
file: None,
line: 1,
column: 6,
offset: 5,
},
val: 1,
}),
);
let ret = Shape::Int(PositionedItem {
pos: Position {
file: None, file: None,
line: 1, line: 1,
column: 20, column: 6,
offset: 19, offset: 5,
}, }),
val: 1, );
let ret = Shape::Int(Position {
file: None,
line: 1,
column: 1,
offset: 0,
}) })
.into(); .into();
assert_type_success!( assert_type_success!(
@ -254,44 +227,44 @@ fn infer_func_type_test() {
let mut symbol_table = BTreeMap::new(); let mut symbol_table = BTreeMap::new();
symbol_table.insert( symbol_table.insert(
bar.clone(), bar.clone(),
Shape::Int(PositionedItem { Shape::Int(Position {
pos: Position {
file: None, file: None,
line: 1, line: 1,
column: 20, column: 20,
offset: 19, offset: 19,
},
val: 1,
}), }),
); );
let mut args = BTreeMap::new(); let mut args = BTreeMap::new();
args.insert( args.insert(
foo.clone(), foo.clone(),
Shape::Int(PositionedItem { Shape::Int(Position {
pos: Position {
file: None, file: None,
line: 1, line: 1,
column: 6, column: 6,
offset: 5, offset: 5,
},
val: 1,
}), }),
); );
assert_type_success!( assert_type_success!(
"func(foo) => foo + bar;", "func(foo) => foo + bar;",
Shape::Func(FuncShapeDef { Shape::Func(FuncShapeDef {
args: args, args: args,
ret: Shape::Int(PositionedItem { ret: Shape::Int(Position {
pos: Position {
file: None, file: None,
line: 1, line: 1,
column: 20, column: 1,
offset: 19, offset: 0,
},
val: 1,
}) })
.into() .into()
}), }),
symbol_table symbol_table
); );
} }
//#[test]
//fn infer_select_shape() {
// assert_type_success!(
// r#"select () => { true = "foo", false = 1 }"#,
// Shape::Narrowed(NarrowedShape { pos: Position { file: None, line: 0, column: 0, offset: 0 }, types: vec![
// Shape::Str(PositionedItem { pos: , val: () })
// ] }))
//}

View File

@ -217,7 +217,8 @@ impl From<Val> for Rc<str> {
Val::Boolean(ref b) => format!("{}", b), Val::Boolean(ref b) => format!("{}", b),
Val::Empty => "NULL".to_string(), Val::Empty => "NULL".to_string(),
val => format!("{}", val), val => format!("{}", val),
}.into() }
.into()
} }
} }

View File

@ -181,7 +181,11 @@ where
if found.contains(&link) { if found.contains(&link) {
continue; continue;
} }
let ops = match self.environment.borrow_mut().get_ops_for_path(link.as_ref()) { let ops = match self
.environment
.borrow_mut()
.get_ops_for_path(link.as_ref())
{
Ok(ops) => ops, Ok(ops) => ops,
Err(e) => return Err(Box::new(e.with_pos(path_pos))), Err(e) => return Err(Box::new(e.with_pos(path_pos))),
}; };

View File

@ -84,7 +84,8 @@ impl From<std::io::Error> for Error {
format!("OSError: Path not found: {}", e) format!("OSError: Path not found: {}", e)
} }
_ => format!("{}", e), _ => format!("{}", e),
}.into(); }
.into();
Error { Error {
message: msg, message: msg,
pos: None, pos: None,

View File

@ -114,7 +114,11 @@ impl Builtins {
stack.push((val, path_pos)); stack.push((val, path_pos));
return Ok(()); return Ok(());
} }
if import_stack.iter().find(|p| p.as_ref() == path.as_ref()).is_some() { if import_stack
.iter()
.find(|p| p.as_ref() == path.as_ref())
.is_some()
{
return Err(Error::new( return Err(Error::new(
format!("Import cycle detected: {} in {:?}", path, import_stack).into(), format!("Import cycle detected: {} in {:?}", path, import_stack).into(),
pos, pos,
@ -127,15 +131,15 @@ impl Builtins {
} }
None => { None => {
let path_buf = PathBuf::from(path.as_ref()); let path_buf = PathBuf::from(path.as_ref());
let op_pointer = let op_pointer = decorate_error!(path_pos => env.borrow_mut().get_ops_for_path(path.as_ref()))?;
decorate_error!(path_pos => env.borrow_mut().get_ops_for_path(path.as_ref()))?;
// TODO(jwall): What if we don't have a base path? // TODO(jwall): What if we don't have a base path?
let mut vm = let mut vm =
VM::with_pointer(self.strict, op_pointer, path_buf.parent().unwrap()) VM::with_pointer(self.strict, op_pointer, path_buf.parent().unwrap())
.with_import_stack(import_stack.clone()); .with_import_stack(import_stack.clone());
vm.run(env)?; vm.run(env)?;
let result = Rc::new(vm.symbols_to_tuple(true)); let result = Rc::new(vm.symbols_to_tuple(true));
env.borrow_mut().update_path_val(path.clone(), result.clone()); env.borrow_mut()
.update_path_val(path.clone(), result.clone());
stack.push((result, pos)); stack.push((result, pos));
} }
} }
@ -163,7 +167,10 @@ impl Builtins {
if let &Value::P(Str(ref path)) = val.as_ref() { if let &Value::P(Str(ref path)) = val.as_ref() {
path.clone() path.clone()
} else { } else {
return Err(Error::new(format!("Invalid Path {:?}", val).into(), path_pos)); return Err(Error::new(
format!("Invalid Path {:?}", val).into(),
path_pos,
));
} }
} else { } else {
unreachable!(); unreachable!();
@ -201,7 +208,10 @@ impl Builtins {
} }
} }
None => { None => {
return Err(Error::new(format!("No such conversion type {}", &typ).into(), pos)) return Err(Error::new(
format!("No such conversion type {}", &typ).into(),
pos,
))
} }
}), }),
pos, pos,
@ -355,9 +365,7 @@ impl Builtins {
match c.convert(Rc::new(val), &mut buf) { match c.convert(Rc::new(val), &mut buf) {
Ok(_) => { Ok(_) => {
stack.push(( stack.push((
Rc::new(P(Str( Rc::new(P(Str(String::from_utf8_lossy(buf.as_slice()).into()))),
String::from_utf8_lossy(buf.as_slice()).into()
))),
pos, pos,
)); ));
} }

View File

@ -278,7 +278,8 @@ impl VM {
format!( format!(
"Not a boolean condition {:?} in && expression at {}", "Not a boolean condition {:?} in && expression at {}",
cond, pos cond, pos
).into(), )
.into(),
cond_pos.clone(), cond_pos.clone(),
)); ));
} }
@ -298,7 +299,8 @@ impl VM {
format!( format!(
"Not a boolean condition {:?} in || expression at {}!", "Not a boolean condition {:?} in || expression at {}!",
cond, pos cond, pos
).into(), )
.into(),
cond_pos.clone(), cond_pos.clone(),
)); ));
} }
@ -530,7 +532,8 @@ impl VM {
format!( format!(
"Func called with too many args expected {} args but got {}", "Func called with too many args expected {} args but got {}",
arity, arg_length arity, arg_length
).into(), )
.into(),
pos, pos,
)); ));
} }
@ -539,7 +542,8 @@ impl VM {
format!( format!(
"Func called with too few args expected {} args but got {}", "Func called with too few args expected {} args but got {}",
arity, arg_length arity, arg_length
).into(), )
.into(),
pos, pos,
)); ));
} }
@ -568,7 +572,8 @@ impl VM {
format!( format!(
"Expected Boolean but got {:?} in expression at {}", "Expected Boolean but got {:?} in expression at {}",
operand, pos operand, pos
).into(), )
.into(),
operand_pos, operand_pos,
)); ));
} }
@ -1042,7 +1047,8 @@ impl VM {
fld.1.type_name(), fld.1.type_name(),
name, name,
value.type_name(), value.type_name(),
).into(), )
.into(),
val_pos.clone(), val_pos.clone(),
)); ));
} }
@ -1115,7 +1121,10 @@ impl VM {
match tpl { match tpl {
Some((v, pos)) => Ok((v, pos)), Some((v, pos)) => Ok((v, pos)),
None => { None => {
return Err(Error::new(format!("No such binding {}", name).into(), pos.clone())); return Err(Error::new(
format!("No such binding {}", name).into(),
pos.clone(),
));
} }
} }
} }

View File

@ -152,10 +152,7 @@ fn test_expr_copy_no_such_tuple() {
test_expr_to_val( test_expr_to_val(
vec![( vec![(
Expression::Copy(CopyDef { Expression::Copy(CopyDef {
selector: Value::Symbol(PositionedItem::new( selector: Value::Symbol(PositionedItem::new("tpl1".into(), Position::new(1, 1, 1))),
"tpl1".into(),
Position::new(1, 1, 1),
)),
fields: Vec::new(), fields: Vec::new(),
pos: Position::new(1, 0, 0), pos: Position::new(1, 0, 0),
}), }),

View File

@ -39,7 +39,10 @@ impl YamlConverter {
fn convert_tuple(&self, items: &Vec<(Rc<str>, Rc<Val>)>) -> std::io::Result<serde_yaml::Value> { fn convert_tuple(&self, items: &Vec<(Rc<str>, Rc<Val>)>) -> std::io::Result<serde_yaml::Value> {
let mut mapping = serde_yaml::Mapping::new(); let mut mapping = serde_yaml::Mapping::new();
for &(ref k, ref v) in items.iter() { for &(ref k, ref v) in items.iter() {
mapping.insert(serde_yaml::Value::String(k.to_string()), self.convert_value(v)?); mapping.insert(
serde_yaml::Value::String(k.to_string()),
self.convert_value(v)?,
);
} }
Ok(serde_yaml::Value::Mapping(mapping)) Ok(serde_yaml::Value::Mapping(mapping))
} }

View File

@ -83,10 +83,7 @@ make_fn!(
); );
fn str_to_value(s: &Token) -> ConvertResult<Value> { fn str_to_value(s: &Token) -> ConvertResult<Value> {
Ok(Value::Str(value_node!( Ok(Value::Str(value_node!(s.fragment.clone(), s.pos.clone())))
s.fragment.clone(),
s.pos.clone()
)))
} }
// quoted_value is a quoted string. // quoted_value is a quoted string.