mirror of
https://github.com/zaphar/ucg.git
synced 2025-07-24 18:39:50 -04:00
refactor: Get rid of the unecessary PositionedItem
This commit is contained in:
parent
d1e5d4129f
commit
76f1f0dee6
@ -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(),
|
||||||
|
@ -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 {
|
||||||
|
@ -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.
|
||||||
|
@ -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: () })
|
||||||
|
// ] }))
|
||||||
|
//}
|
||||||
|
@ -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()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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))),
|
||||||
};
|
};
|
||||||
|
@ -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,
|
||||||
|
@ -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,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
@ -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(),
|
||||||
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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),
|
||||||
}),
|
}),
|
||||||
|
@ -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))
|
||||||
}
|
}
|
||||||
|
@ -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.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user