Thread position information through to more places.

This commit is contained in:
Jeremy Wall 2017-11-06 21:06:30 -06:00
parent 1e3d19755c
commit 4f3cc3dbf6
3 changed files with 453 additions and 419 deletions

View File

@ -14,6 +14,12 @@
use std::collections::HashSet;
use std::borrow::Borrow;
use std::convert::Into;
use std::cmp::Ordering;
use std::cmp::PartialOrd;
use std::cmp::Eq;
use std::cmp::PartialEq;
use std::hash::Hasher;
use std::hash::Hash;
#[derive(Debug,PartialEq,Eq,Clone,PartialOrd,Ord,Hash)]
pub struct Position {
@ -28,15 +34,7 @@ pub struct Token {
}
impl Token {
pub fn new(f: &str) -> Self {
Self::new_with_pos(f,
Position {
line: 0,
column: 0,
})
}
pub fn new_with_pos(f: &str, pos: Position) -> Self {
pub fn new(f: &str, pos: Position) -> Self {
Token {
fragment: f.to_string(),
pos: pos,
@ -51,11 +49,8 @@ impl Borrow<str> for Token {
}
macro_rules! value_node {
($v:expr) => {
LocatedNode::new($v)
};
($v:expr, $p:expr) => {
LocatedNode::new_with_pos($v, $p)
LocatedNode::new($v, $p)
};
}
@ -64,21 +59,15 @@ pub type SelectorList = Vec<Token>; // str is expected to always be a symbol.
#[derive(Debug,PartialEq,Clone)]
pub struct LocatedNode<T> {
pub pos: Option<Position>,
// TODO(jwall): Make this non-optional, Should we just use positioned instead?
pub pos: Position,
pub val: T,
}
impl<T> LocatedNode<T> {
pub fn new(v: T) -> Self {
pub fn new<P: Into<Position>>(v: T, pos: P) -> Self {
Self {
pos: None,
val: v,
}
}
pub fn new_with_pos<P: Into<Position>>(v: T, pos: P) -> Self {
Self {
pos: Some(pos.into()),
pos: pos.into(),
val: v,
}
}
@ -89,8 +78,9 @@ impl<T> LocatedNode<T> {
}
pub fn make_value_node<T>(v: T) -> LocatedNode<T> {
LocatedNode::new(v)
// TODO(jwall): This should take a line and a column as argumentsn now.
pub fn make_value_node<T>(v: T, line: usize, column: usize) -> LocatedNode<T> {
LocatedNode::new(v, Position{line: line, column: column})
}
/// Value represents a Value in the UCG parsed AST.
@ -141,7 +131,7 @@ impl Value {
}
}
pub fn pos(&self) -> &Option<Position> {
pub fn pos(&self) -> &Position {
match self {
&Value::Int(ref i) => &i.pos,
&Value::Float(ref f) => &f.pos,
@ -173,7 +163,7 @@ pub struct SelectDef {
}
// TODO(jwall): This should have a way of rendering with position information.
#[derive(PartialEq,Debug,Eq,PartialOrd,Ord,Clone,Hash)]
#[derive(Debug,Clone)]
pub struct Positioned<T> {
pub pos: Option<Position>,
pub val: T,
@ -195,6 +185,33 @@ impl<T> Positioned<T> {
}
}
impl<T: PartialEq> PartialEq for Positioned<T> {
fn eq(&self, other: &Self) -> bool {
self.val == other.val
}
}
impl<T: Eq> Eq for Positioned<T> {
}
impl<T: Ord> Ord for Positioned<T> {
fn cmp(&self, other: &Self) -> Ordering {
self.val.cmp(&other.val)
}
}
impl<T: PartialOrd> PartialOrd for Positioned<T> {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
self.val.partial_cmp(&other.val)
}
}
impl<T: Hash> Hash for Positioned<T> {
fn hash<H: Hasher>(&self, state: &mut H) {
self.val.hash(state);
}
}
impl<'a> From<&'a Token> for Positioned<String> {
fn from(t: &'a Token) -> Positioned<String> {
Positioned {
@ -207,7 +224,7 @@ impl<'a> From<&'a Token> for Positioned<String> {
impl<'a> From<&'a LocatedNode<String>> for Positioned<String> {
fn from(t: &LocatedNode<String>) -> Positioned<String> {
Positioned {
pos: t.pos.clone(),
pos: Some(t.pos.clone()),
val: t.val.clone(),
}
}
@ -401,10 +418,10 @@ mod ast_test {
Positioned::new("foo".to_string())
],
fields: vec![
(Token::new("f1"), Expression::Binary(BinaryOpDef{
(Token::new("f1", Position { line: 1, column: 1}), Expression::Binary(BinaryOpDef{
kind: BinaryExprType::Add,
left: Value::Symbol(make_value_node("foo".to_string())),
right: Box::new(Expression::Simple(Value::Int(make_value_node(1)))),
left: Value::Symbol(make_value_node("foo".to_string(), 1, 1)),
right: Box::new(Expression::Simple(Value::Int(make_value_node(1, 1, 1)))),
pos: None,
})),
],
@ -420,10 +437,10 @@ mod ast_test {
Positioned::new("foo".to_string())
],
fields: vec![
(Token::new("f1"), Expression::Binary(BinaryOpDef{
(Token::new("f1", Position{line: 1, column: 1}), Expression::Binary(BinaryOpDef{
kind: BinaryExprType::Add,
left: Value::Symbol(make_value_node("bar".to_string())),
right: Box::new(Expression::Simple(Value::Int(make_value_node(1)))),
left: Value::Symbol(make_value_node("bar".to_string(), 1, 1)),
right: Box::new(Expression::Simple(Value::Int(make_value_node(1, 1, 1)))),
pos: None,
})),
],
@ -441,10 +458,12 @@ mod ast_test {
Positioned::new("foo".to_string())
],
fields: vec![
(Token::new("f1"), Expression::Binary(BinaryOpDef{
(Token::new("f1", Position{line: 1, column: 1}), Expression::Binary(BinaryOpDef{
kind: BinaryExprType::Add,
left: Value::Selector(make_value_node(vec![Token::new("foo"), Token::new("quux")])),
right: Box::new(Expression::Simple(Value::Int(make_value_node(1)))),
left: Value::Selector(make_value_node(vec![
Token::new("foo", Position{line: 1, column: 1}),
Token::new("quux", Position{line: 1, column: 1})], 1, 1)),
right: Box::new(Expression::Simple(Value::Int(make_value_node(1, 1, 1)))),
pos: None,
})),
],
@ -460,10 +479,12 @@ mod ast_test {
Positioned::new("foo".to_string()),
],
fields: vec![
(Token::new("f1"), Expression::Binary(BinaryOpDef{
(Token::new("f1", Position{line: 1, column: 1}), Expression::Binary(BinaryOpDef{
kind: BinaryExprType::Add,
left: Value::Selector(make_value_node(vec![Token::new("bar"), Token::new("quux")])),
right: Box::new(Expression::Simple(Value::Int(make_value_node(1)))),
left: Value::Selector(make_value_node(vec![
Token::new("bar", Position{line: 1, column: 1}),
Token::new("quux", Position{line: 1, column: 1})], 1, 1)),
right: Box::new(Expression::Simple(Value::Int(make_value_node(1, 1, 1)))),
pos: None,
})),
],

View File

@ -43,9 +43,9 @@ impl MacroDef {
// If the expressions reference Symbols not defined in the MacroDef that is also an error.
// TODO(jwall): We should probably enforce that the Expression Symbols must be in argdefs rules
// at Macro definition time not evaluation time.
let mut scope = HashMap::<String, Rc<Val>>::new();
let mut scope = HashMap::<Positioned<String>, Rc<Val>>::new();
for (i, arg) in args.drain(0..).enumerate() {
scope.entry(self.argdefs[i].val.clone()).or_insert(arg.clone());
scope.entry(self.argdefs[i].clone()).or_insert(arg.clone());
}
let b = Builder::new_with_scope(scope);
let mut result: Vec<(Positioned<String>, Rc<Val>)> = Vec::new();
@ -217,7 +217,7 @@ impl From<Val> for String {
}
/// ValueMap defines a set of values in a parsed file.
type ValueMap = HashMap<String, Rc<Val>>;
type ValueMap = HashMap<Positioned<String>, Rc<Val>>;
/// Builder parses one or more statements into a out Tuple.
pub struct Builder {
@ -285,7 +285,7 @@ impl Builder {
}
}
pub fn new_with_scope(scope: HashMap<String, Rc<Val>>) -> Self {
pub fn new_with_scope(scope: ValueMap) -> Self {
Builder {
assets: HashMap::new(),
files: HashSet::new(),
@ -331,7 +331,7 @@ impl Builder {
&Statement::Let { name: ref sym, value: ref expr } => {
let val = try!(self.eval_expr(expr));
self.last = Some(val.clone());
match self.out.entry(sym.fragment.clone()) {
match self.out.entry(sym.into()) {
Entry::Occupied(e) => {
return Err(Box::new(BuildError::DuplicateBinding(format!("Let binding \
for {:?} already \
@ -346,14 +346,14 @@ impl Builder {
&Statement::Import { path: ref val, name: ref sym } => {
if !self.files.contains(val) {
// Only parse the file once on import.
if self.assets.get(&sym.fragment).is_none() {
let positioned_sym = sym.into();
if self.assets.get(&positioned_sym).is_none() {
let mut b = Self::new();
try!(b.build_file(&val));
let fields: Vec<(Positioned<String>, Rc<Val>)> =
b.out.drain().map(|t| (Positioned::new(t.0), t.1))
.collect();
b.out.drain().collect();
let result = Rc::new(Val::Tuple(fields));
self.assets.entry(sym.fragment.clone()).or_insert(result.clone());
self.assets.entry(positioned_sym).or_insert(result.clone());
self.files.insert(val.clone());
self.last = Some(result);
}
@ -367,11 +367,11 @@ impl Builder {
}
fn lookup_sym(&self, sym: &Positioned<String>) -> Option<Rc<Val>> {
if self.out.contains_key(&sym.val) {
return Some(self.out[&sym.val].clone());
if self.out.contains_key(sym) {
return Some(self.out[sym].clone());
}
if self.assets.contains_key(&sym.val) {
return Some(self.assets[&sym.val].clone());
if self.assets.contains_key(sym) {
return Some(self.assets[sym].clone());
}
None
}
@ -569,10 +569,10 @@ impl Builder {
&Expression::Copy(ref def) => {
let v = try!(self.lookup_selector(&def.selector));
if let Val::Tuple(ref src_fields) = *v {
let mut m = HashMap::<&String, Rc<Val>>::new();
// loop through fields and build up a hasmap
let mut m = HashMap::<Positioned<String>, Rc<Val>>::new();
// loop through fields and build up a hahsmap
for &(ref key, ref val) in src_fields.iter() {
if let Entry::Vacant(v) = m.entry(&key.val) {
if let Entry::Vacant(v) = m.entry(key.clone()) {
v.insert(val.clone());
} else {
return Err(Box::new(BuildError::TypeFail(format!("Duplicate \
@ -583,7 +583,7 @@ impl Builder {
}
for &(ref key, ref val) in def.fields.iter() {
let expr_result = try!(self.eval_expr(val));
match m.entry(&key.fragment) {
match m.entry(key.into()) {
Entry::Vacant(v) => {
v.insert(expr_result);
}
@ -601,9 +601,7 @@ impl Builder {
}
};
}
let mut new_fields: Vec<(Positioned<String>, Rc<Val>)> = m.drain()
.map(|(s, v)| (Positioned::new(s.to_string()), v))
.collect();
let mut new_fields: Vec<(Positioned<String>, Rc<Val>)> = m.drain().collect();
// We want a stable order for the fields to make comparing tuples
// easier in later code. So we sort by the field name before constructing a new tuple.
new_fields.sort_by(|a, b| a.0.cmp(&b.0));
@ -697,16 +695,16 @@ mod test {
(Expression::Binary(
BinaryOpDef{
kind: BinaryExprType::Div,
left: Value::Int(make_value_node(2)),
right: Box::new(Expression::Simple(Value::Int(make_value_node(2)))),
left: Value::Int(make_value_node(2, 1, 1)),
right: Box::new(Expression::Simple(Value::Int(make_value_node(2, 1, 1)))),
pos: None,
}),
Val::Int(1)),
(Expression::Binary(
BinaryOpDef{
kind: BinaryExprType::Div,
left: Value::Float(make_value_node(2.0)),
right: Box::new(Expression::Simple(Value::Float(make_value_node(2.0)))),
left: Value::Float(make_value_node(2.0, 1, 1)),
right: Box::new(Expression::Simple(Value::Float(make_value_node(2.0, 1, 1)))),
pos: None,
}),
Val::Float(1.0)),
@ -722,8 +720,8 @@ mod test {
(Expression::Binary(
BinaryOpDef{
kind: BinaryExprType::Div,
left: Value::Float(make_value_node(2.0)),
right: Box::new(Expression::Simple(Value::Int(make_value_node(2)))),
left: Value::Float(make_value_node(2.0, 1, 1)),
right: Box::new(Expression::Simple(Value::Int(make_value_node(2, 1, 1)))),
pos: None,
}),
Val::Float(1.0)),
@ -738,16 +736,16 @@ mod test {
(Expression::Binary(
BinaryOpDef{
kind: BinaryExprType::Mul,
left: Value::Int(make_value_node(2)),
right: Box::new(Expression::Simple(Value::Int(make_value_node(2)))),
left: Value::Int(make_value_node(2, 1, 1)),
right: Box::new(Expression::Simple(Value::Int(make_value_node(2, 1, 1)))),
pos: None,
}),
Val::Int(4)),
(Expression::Binary(
BinaryOpDef{
kind: BinaryExprType::Mul,
left: Value::Float(make_value_node(2.0)),
right: Box::new(Expression::Simple(Value::Float(make_value_node(2.0)))),
left: Value::Float(make_value_node(2.0, 1, 1)),
right: Box::new(Expression::Simple(Value::Float(make_value_node(2.0, 1, 1)))),
pos: None,
}),
Val::Float(4.0)),
@ -763,8 +761,8 @@ mod test {
(Expression::Binary(
BinaryOpDef{
kind: BinaryExprType::Mul,
left: Value::Float(make_value_node(2.0)),
right: Box::new(Expression::Simple(Value::Int(make_value_node(20)))),
left: Value::Float(make_value_node(2.0, 1, 1)),
right: Box::new(Expression::Simple(Value::Int(make_value_node(20, 1, 1)))),
pos: None,
}),
Val::Float(1.0)),
@ -779,16 +777,16 @@ mod test {
(Expression::Binary(
BinaryOpDef{
kind: BinaryExprType::Sub,
left: Value::Int(make_value_node(2)),
right: Box::new(Expression::Simple(Value::Int(make_value_node(1)))),
left: Value::Int(make_value_node(2, 1, 1)),
right: Box::new(Expression::Simple(Value::Int(make_value_node(1, 1, 1)))),
pos: None,
}),
Val::Int(1)),
(Expression::Binary(
BinaryOpDef{
kind: BinaryExprType::Sub,
left: Value::Float(make_value_node(2.0)),
right: Box::new(Expression::Simple(Value::Float(make_value_node(1.0)))),
left: Value::Float(make_value_node(2.0, 1, 1)),
right: Box::new(Expression::Simple(Value::Float(make_value_node(1.0, 1, 1)))),
pos: None,
}),
Val::Float(1.0)),
@ -804,8 +802,8 @@ mod test {
(Expression::Binary(
BinaryOpDef{
kind: BinaryExprType::Sub,
left: Value::Float(make_value_node(2.0)),
right: Box::new(Expression::Simple(Value::Int(make_value_node(2)))),
left: Value::Float(make_value_node(2.0, 1, 1)),
right: Box::new(Expression::Simple(Value::Int(make_value_node(2, 1, 1)))),
pos: None,
}),
Val::Float(1.0)),
@ -820,24 +818,24 @@ mod test {
(Expression::Binary(
BinaryOpDef{
kind: BinaryExprType::Add,
left: Value::Int(make_value_node(1)),
right: Box::new(Expression::Simple(Value::Int(make_value_node(1)))),
left: Value::Int(make_value_node(1, 1, 1)),
right: Box::new(Expression::Simple(Value::Int(make_value_node(1, 1, 1)))),
pos: None,
}),
Val::Int(2)),
(Expression::Binary(
BinaryOpDef{
kind: BinaryExprType::Add,
left: Value::Float(make_value_node(1.0)),
right: Box::new(Expression::Simple(Value::Float(make_value_node(1.0)))),
left: Value::Float(make_value_node(1.0, 1, 1)),
right: Box::new(Expression::Simple(Value::Float(make_value_node(1.0, 1, 1)))),
pos: None,
}),
Val::Float(2.0)),
(Expression::Binary(
BinaryOpDef{
kind: BinaryExprType::Add,
left: Value::String(make_value_node("foo".to_string())),
right: Box::new(Expression::Simple(Value::String(make_value_node("bar".to_string())))),
left: Value::String(make_value_node("foo".to_string(), 1, 1)),
right: Box::new(Expression::Simple(Value::String(make_value_node("bar".to_string(), 1, 1)))),
pos: None,
}),
Val::String("foobar".to_string())),
@ -852,8 +850,8 @@ mod test {
(Expression::Binary(
BinaryOpDef{
kind: BinaryExprType::Add,
left: Value::Float(make_value_node(2.0)),
right: Box::new(Expression::Simple(Value::Int(make_value_node(2)))),
left: Value::Float(make_value_node(2.0, 1, 1)),
right: Box::new(Expression::Simple(Value::Int(make_value_node(2, 1, 1)))),
pos: None,
}),
Val::Float(1.0)),
@ -864,14 +862,14 @@ mod test {
#[test]
fn test_eval_simple_expr() {
test_expr_to_val(vec![
(Expression::Simple(Value::Int(make_value_node(1))), Val::Int(1)),
(Expression::Simple(Value::Float(make_value_node(2.0))), Val::Float(2.0)),
(Expression::Simple(Value::String(make_value_node("foo".to_string()))),
(Expression::Simple(Value::Int(make_value_node(1, 1, 1))), Val::Int(1)),
(Expression::Simple(Value::Float(make_value_node(2.0, 1, 1))), Val::Float(2.0)),
(Expression::Simple(Value::String(make_value_node("foo".to_string(), 1, 1))),
Val::String("foo".to_string())),
(Expression::Simple(Value::Tuple(make_value_node(vec![
(Token::new("bar"), Expression::Simple(Value::Int(make_value_node(1))))
]))),
Val::Tuple(vec![(Positioned::new_with_pos("bar".to_string(), Position{line: 0, column: 0}),
(Token::new("bar", Position{line: 1, column: 1}), Expression::Simple(Value::Int(make_value_node(1, 1, 1))))
], 1, 1))),
Val::Tuple(vec![(Positioned::new_with_pos("bar".to_string(), Position{line: 1, column: 1}),
Rc::new(Val::Int(1)))])),
],
Builder::new());
@ -880,9 +878,9 @@ mod test {
#[test]
fn test_eval_simple_lookup_expr() {
let mut b = Builder::new();
b.out.entry("var1".to_string()).or_insert(Rc::new(Val::Int(1)));
b.out.entry(Positioned::new("var1".to_string())).or_insert(Rc::new(Val::Int(1)));
test_expr_to_val(vec![
(Expression::Simple(Value::Symbol(make_value_node("var1".to_string()))), Val::Int(1)),
(Expression::Simple(Value::Symbol(make_value_node("var1".to_string(), 1, 1))), Val::Int(1)),
],
b);
}
@ -890,8 +888,8 @@ mod test {
#[test]
fn test_eval_simple_lookup_error() {
let mut b = Builder::new();
b.out.entry("var1".to_string()).or_insert(Rc::new(Val::Int(1)));
let expr = Expression::Simple(Value::Symbol(make_value_node("var".to_string())));
b.out.entry(Positioned::new("var1".to_string())).or_insert(Rc::new(Val::Int(1)));
let expr = Expression::Simple(Value::Symbol(make_value_node("var".to_string(), 1, 1)));
assert!(b.eval_expr(&expr).is_err());
}
@ -899,20 +897,20 @@ mod test {
fn test_eval_selector_expr() {
// TODO(jwall): Tests for this expression.
let mut b = Builder::new();
b.out.entry("var1".to_string()).or_insert(Rc::new(Val::Tuple(vec![
b.out.entry(Positioned::new("var1".to_string())).or_insert(Rc::new(Val::Tuple(vec![
(Positioned::new("lvl1".to_string()), Rc::new(Val::Tuple(
vec![
(Positioned::new("lvl2".to_string()), Rc::new(Val::Int(3))),
]
))),
])));
b.out.entry("var2".to_string()).or_insert(Rc::new(Val::Int(2)));
b.out.entry(Positioned::new("var2".to_string())).or_insert(Rc::new(Val::Int(2)));
b.out
.entry("var3".to_string())
.entry(Positioned::new("var3".to_string()))
.or_insert(Rc::new(Val::Tuple(vec![(Positioned::new("lvl1".to_string()),
Rc::new(Val::Int(4)))])));
test_expr_to_val(vec![
(Expression::Simple(Value::Selector(make_value_node(vec![Token::new("var1")]))), Val::Tuple(
(Expression::Simple(Value::Selector(make_value_node(vec![Token::new("var1", Position{line: 1, column: 1})], 1, 1))), Val::Tuple(
vec![
(Positioned::new("lvl1".to_string()), Rc::new(Val::Tuple(
vec![
@ -921,21 +919,21 @@ mod test {
))),
]
)),
(Expression::Simple(Value::Selector(make_value_node(vec![Token::new("var1"),
Token::new("lvl1")]))),
(Expression::Simple(Value::Selector(make_value_node(vec![Token::new("var1", Position{line: 1, column: 1}),
Token::new("lvl1", Position{line: 1, column: 1})], 1, 1))),
Val::Tuple(
vec![
(Positioned::new("lvl2".to_string()), Rc::new(Val::Int(3))),
]
)),
(Expression::Simple(Value::Selector(make_value_node(vec![Token::new("var1"),
Token::new("lvl1"),
Token::new("lvl2")]))),
(Expression::Simple(Value::Selector(make_value_node(vec![Token::new("var1", Position{line: 1, column: 1}),
Token::new("lvl1", Position{line: 1, column: 1}),
Token::new("lvl2", Position{line: 1, column: 1})], 1, 1))),
Val::Int(3)),
(Expression::Simple(Value::Selector(make_value_node(vec![Token::new("var2")]))),
(Expression::Simple(Value::Selector(make_value_node(vec![Token::new("var2", Position{line: 1, column: 1})], 1, 1))),
Val::Int(2)),
(Expression::Simple(Value::Selector(make_value_node(vec![Token::new("var3"),
Token::new("lvl1")]))),
(Expression::Simple(Value::Selector(make_value_node(vec![Token::new("var3", Position{line: 1, column: 1}),
Token::new("lvl1", Position{line: 1, column: 1})], 1, 1))),
Val::Int(4)),
], b);
}
@ -945,7 +943,7 @@ mod test {
fn test_expr_copy_no_such_tuple() {
let b = Builder::new();
test_expr_to_val(vec![
(Expression::Copy(CopyDef{selector: vec![Token::new("tpl1")], fields: Vec::new(), pos: None}),
(Expression::Copy(CopyDef{selector: vec![Token::new("tpl1", Position{line: 1, column: 1})], fields: Vec::new(), pos: None}),
Val::Tuple(Vec::new())),
], b);
}
@ -954,9 +952,9 @@ mod test {
#[should_panic(expected = "Expected Tuple got Integer")]
fn test_expr_copy_not_a_tuple() {
let mut b = Builder::new();
b.out.entry("tpl1".to_string()).or_insert(Rc::new(Val::Int(1)));
b.out.entry(Positioned::new("tpl1".to_string())).or_insert(Rc::new(Val::Int(1)));
test_expr_to_val(vec![
(Expression::Copy(CopyDef{selector: vec![Token::new("tpl1")], fields: Vec::new(), pos: None}),
(Expression::Copy(CopyDef{selector: vec![Token::new("tpl1", Position{line: 1, column: 1})], fields: Vec::new(), pos: None}),
Val::Tuple(Vec::new())),
], b);
}
@ -965,19 +963,19 @@ mod test {
#[should_panic(expected = "Expected type Integer for field fld1 but got String")]
fn test_expr_copy_field_type_error() {
let mut b = Builder::new();
b.out.entry("tpl1".to_string()).or_insert(Rc::new(Val::Tuple(vec![
b.out.entry(Positioned::new("tpl1".to_string())).or_insert(Rc::new(Val::Tuple(vec![
(Positioned::new("fld1".to_string()), Rc::new(Val::Int(1))),
])));
test_expr_to_val(vec![
(Expression::Copy(
CopyDef{
selector: vec![Token::new("tpl1")],
fields: vec![(Token::new("fld1"),
Expression::Simple(Value::String(make_value_node("2".to_string()))))],
selector: vec![Token::new("tpl1", Position{line: 1, column: 1})],
fields: vec![(Token::new("fld1", Position{line: 1, column: 1}),
Expression::Simple(Value::String(make_value_node("2".to_string(), 1, 1))))],
pos: None}),
Val::Tuple(
vec![
(Positioned::new("fld1".to_string()), Rc::new(Val::String("2".to_string()))),
(Positioned::new_with_pos("fld1".to_string(), Position{line: 1, column: 1}), Rc::new(Val::String("2".to_string()))),
],
)),
], b);
@ -989,15 +987,15 @@ mod test {
fn test_expr_copy() {
// TODO(jwall): Tests for this expression.
let mut b = Builder::new();
b.out.entry("tpl1".to_string()).or_insert(Rc::new(Val::Tuple(vec![
b.out.entry(Positioned::new("tpl1".to_string())).or_insert(Rc::new(Val::Tuple(vec![
(Positioned::new("fld1".to_string()), Rc::new(Val::Int(1))),
])));
test_expr_to_val(vec![
(Expression::Copy(
CopyDef{
selector: vec![Token::new("tpl1")],
fields: vec![(Token::new("fld2"),
Expression::Simple(Value::String(make_value_node("2".to_string()))))],
selector: vec![Token::new("tpl1", Position{line: 1, column: 1})],
fields: vec![(Token::new("fld2", Position{line: 1, column: 1}),
Expression::Simple(Value::String(make_value_node("2".to_string(), 1, 1))))],
pos: None,
}),
// Add a new field to the copy
@ -1007,18 +1005,18 @@ mod test {
// semantics though so at some point we should probably be less restrictive.
vec![
(Positioned::new("fld1".to_string()), Rc::new(Val::Int(1))),
(Positioned::new("fld2".to_string()), Rc::new(Val::String("2".to_string()))),
(Positioned::new_with_pos("fld2".to_string(), Position{line: 1, column: 1}), Rc::new(Val::String("2".to_string()))),
],
)),
// Overwrite a field in the copy
(Expression::Copy(
CopyDef{
selector: vec![Token::new("tpl1")],
selector: vec![Token::new("tpl1", Position{line: 1, column: 1})],
fields: vec![
(Token::new("fld1"),
Expression::Simple(Value::Int(make_value_node(3)))),
(Token::new("fld2"),
Expression::Simple(Value::String(make_value_node("2".to_string())))),
(Token::new("fld1", Position{line: 1, column: 1}),
Expression::Simple(Value::Int(make_value_node(3, 1, 1)))),
(Token::new("fld2", Position{line: 1, column: 1}),
Expression::Simple(Value::String(make_value_node("2".to_string(), 1, 1)))),
],
pos: None,
}),
@ -1029,7 +1027,7 @@ mod test {
],
)),
// The source tuple is still unmodified.
(Expression::Simple(Value::Selector(make_value_node(vec![Token::new("tpl1")]))),
(Expression::Simple(Value::Selector(make_value_node(vec![Token::new("tpl1", Position{line: 1, column: 1})], 1, 1))),
Val::Tuple(
vec![
(Positioned::new("fld1".to_string()), Rc::new(Val::Int(1))),
@ -1041,21 +1039,21 @@ mod test {
#[test]
fn test_macro_call() {
let mut b = Builder::new();
b.out.entry("tstmac".to_string()).or_insert(Rc::new(Val::Macro(MacroDef{
b.out.entry(Positioned::new("tstmac".to_string())).or_insert(Rc::new(Val::Macro(MacroDef{
argdefs: vec![Positioned::new("arg1".to_string())],
fields: vec![
(Token::new("foo"), Expression::Simple(Value::Symbol(make_value_node("arg1".to_string())))),
(Token::new("foo", Position{line: 1, column: 1}), Expression::Simple(Value::Symbol(make_value_node("arg1".to_string(), 1, 1)))),
],
pos: None,
})));
test_expr_to_val(vec![
(Expression::Call(CallDef{
macroref: vec![Token::new("tstmac")],
arglist: vec![Expression::Simple(Value::String(make_value_node("bar".to_string())))],
macroref: vec![Token::new("tstmac", Position{line: 1, column: 1})],
arglist: vec![Expression::Simple(Value::String(make_value_node("bar".to_string(), 1, 1)))],
pos: None,
}),
Val::Tuple(vec![
(Positioned::new_with_pos("foo".to_string(), Position{line: 0, column: 0}),
(Positioned::new_with_pos("foo".to_string(), Position{line: 1, column: 1}),
Rc::new(Val::String("bar".to_string()))),
])),
], b);
@ -1066,19 +1064,19 @@ mod test {
fn test_macro_hermetic() {
let mut b = Builder::new();
b.out
.entry("arg1".to_string())
.entry(Positioned::new("arg1".to_string()))
.or_insert(Rc::new(Val::String("bar".to_string())));
b.out.entry("tstmac".to_string()).or_insert(Rc::new(Val::Macro(MacroDef{
b.out.entry(Positioned::new("tstmac".to_string())).or_insert(Rc::new(Val::Macro(MacroDef{
argdefs: vec![Positioned::new("arg2".to_string())],
fields: vec![
(Token::new("foo"), Expression::Simple(Value::Symbol(make_value_node("arg1".to_string())))),
(Token::new("foo", Position{line: 1, column: 1}), Expression::Simple(Value::Symbol(make_value_node("arg1".to_string(), 1, 1)))),
],
pos: None,
})));
test_expr_to_val(vec![
(Expression::Call(CallDef{
macroref: vec![Token::new("tstmac")],
arglist: vec![Expression::Simple(Value::String(make_value_node("bar".to_string())))],
macroref: vec![Token::new("tstmac", Position{line: 1, column: 1})],
arglist: vec![Expression::Simple(Value::String(make_value_node("bar".to_string(), 1, 1)))],
pos: None,
}),
Val::Tuple(vec![
@ -1091,28 +1089,28 @@ mod test {
fn test_select_expr() {
let mut b = Builder::new();
b.out
.entry("foo".to_string())
.entry(Positioned::new("foo".to_string()))
.or_insert(Rc::new(Val::String("bar".to_string())));
b.out
.entry("baz".to_string())
.entry(Positioned::new("baz".to_string()))
.or_insert(Rc::new(Val::String("boo".to_string())));
test_expr_to_val(vec![
(Expression::Select(SelectDef{
val: Box::new(Expression::Simple(Value::Symbol(make_value_node("foo".to_string())))),
default: Box::new(Expression::Simple(Value::Int(make_value_node(1)))),
val: Box::new(Expression::Simple(Value::Symbol(make_value_node("foo".to_string(), 1, 1)))),
default: Box::new(Expression::Simple(Value::Int(make_value_node(1, 1, 1)))),
tuple: vec![
(Token::new("foo"), Expression::Simple(Value::String(make_value_node("2".to_string())))),
(Token::new("bar"), Expression::Simple(Value::Int(make_value_node(2)))),
(Token::new("foo", Position{line: 1, column: 1}), Expression::Simple(Value::String(make_value_node("2".to_string(), 1, 1)))),
(Token::new("bar", Position{line: 1, column: 1}), Expression::Simple(Value::Int(make_value_node(2, 1, 1)))),
],
pos: None,
}),
Val::Int(2)),
(Expression::Select(SelectDef{
val: Box::new(Expression::Simple(Value::Symbol(make_value_node("baz".to_string())))),
default: Box::new(Expression::Simple(Value::Int(make_value_node(1)))),
val: Box::new(Expression::Simple(Value::Symbol(make_value_node("baz".to_string(), 1, 1)))),
default: Box::new(Expression::Simple(Value::Int(make_value_node(1, 1, 1)))),
tuple: vec![
(Token::new("bar"), Expression::Simple(Value::Int(make_value_node(2)))),
(Token::new("quux"), Expression::Simple(Value::String(make_value_node("2".to_string())))),
(Token::new("bar", Position{line: 1, column: 1}), Expression::Simple(Value::Int(make_value_node(2, 1, 1)))),
(Token::new("quux", Position{line: 1, column: 1}), Expression::Simple(Value::String(make_value_node("2".to_string(), 1, 1)))),
],
pos: None,
}),
@ -1125,14 +1123,14 @@ mod test {
#[should_panic(expected ="Expected String but got Integer in Select expression")]
fn test_select_expr_not_a_string() {
let mut b = Builder::new();
b.out.entry("foo".to_string()).or_insert(Rc::new(Val::Int(4)));
b.out.entry(Positioned::new("foo".to_string())).or_insert(Rc::new(Val::Int(4)));
test_expr_to_val(vec![
(Expression::Select(SelectDef{
val: Box::new(Expression::Simple(Value::Symbol(make_value_node("foo".to_string())))),
default: Box::new(Expression::Simple(Value::Int(make_value_node(1)))),
val: Box::new(Expression::Simple(Value::Symbol(make_value_node("foo".to_string(), 1, 1)))),
default: Box::new(Expression::Simple(Value::Int(make_value_node(1, 1, 1)))),
tuple: vec![
(Token::new("bar"), Expression::Simple(Value::Int(make_value_node(2)))),
(Token::new("quux"), Expression::Simple(Value::String(make_value_node("2".to_string())))),
(Token::new("bar", Position{line: 1, column: 1}), Expression::Simple(Value::Int(make_value_node(2, 1, 1)))),
(Token::new("quux", Position{line: 1, column: 1}), Expression::Simple(Value::String(make_value_node("2".to_string(), 1, 1)))),
],
pos: None,
}),
@ -1144,12 +1142,12 @@ mod test {
fn test_let_statement() {
let mut b = Builder::new();
let stmt = Statement::Let {
name: Token::new("foo"),
value: Expression::Simple(Value::String(make_value_node("bar".to_string()))),
name: Token::new("foo", Position{line: 1, column: 1}),
value: Expression::Simple(Value::String(make_value_node("bar".to_string(), 1, 1))),
};
b.build_stmt(&stmt).unwrap();
test_expr_to_val(vec![
(Expression::Simple(Value::Symbol(make_value_node("foo".to_string()))),
(Expression::Simple(Value::Symbol(make_value_node("foo".to_string(), 1, 1))),
Val::String("bar".to_string())),
],
b);
@ -1159,20 +1157,20 @@ mod test {
fn test_build_file_string() {
let mut b = Builder::new();
b.build_file_string("foo.ucg", "let foo = 1;".to_string()).unwrap();
let key = "foo";
assert!(b.out.contains_key(key));
let key = Positioned::new("foo".to_string());
assert!(b.out.contains_key(&key));
}
#[test]
fn test_asset_symbol_lookups() {
let mut b = Builder::new();
b.assets.entry("foo".to_string()).or_insert(Rc::new(Val::Tuple(vec![
b.assets.entry(Positioned::new("foo".to_string())).or_insert(Rc::new(Val::Tuple(vec![
(Positioned::new("bar".to_string()), Rc::new(Val::Tuple(vec![
(Positioned::new("quux".to_string()), Rc::new(Val::Int(1))),
]))),
])));
test_expr_to_val(vec![
(Expression::Simple(Value::Symbol(make_value_node("foo".to_string()))),
(Expression::Simple(Value::Symbol(make_value_node("foo".to_string(), 1, 1))),
Val::Tuple(vec![
(Positioned::new("bar".to_string()), Rc::new(Val::Tuple(vec![
(Positioned::new("quux".to_string()), Rc::new(Val::Int(1))),

View File

@ -13,6 +13,7 @@
// limitations under the License.
use std::str::FromStr;
use std::error::Error;
use std::borrow::Borrow;
use ast::*;
use tokenizer::*;
@ -32,20 +33,19 @@ quick_error! {
}
// TODO(jwall): Convert to tokenizer steps followed by parser steps.
// TODO(jwall): Error Reporting with Line and Column information.
type ParseResult<O> = Result<O, Box<Error>>;
fn symbol_to_value(s: Token) -> ParseResult<Value> {
Ok(Value::Symbol(value_node!(s.fragment.to_string())))
Ok(Value::Symbol(value_node!(s.fragment.to_string(), s.pos)))
}
// symbol is a bare unquoted field.
named!(symbol( Span ) -> Value, map_res!(barewordtok, symbol_to_value));
fn str_to_value(s: Token) -> ParseResult<Value> {
Ok(Value::String(value_node!(s.fragment.to_string())))
Ok(Value::String(value_node!(s.fragment.to_string(), s.pos)))
}
// quoted_value is a quoted string.
@ -55,25 +55,30 @@ named!(quoted_value( Span ) -> Value,
// Helper function to make the return types work for down below.
fn triple_to_number(v: (Option<Token>, Option<Token>, Option<Token>)) -> ParseResult<Value> {
let pref = match v.0 {
None => "",
Some(ref bs) => &bs.fragment,
let (pref, mut pref_pos) = match v.0 {
None => ("", Position{line: 0, column: 0}),
Some(ref bs) => (bs.fragment.borrow(), bs.pos.clone()),
};
let has_dot = v.1.is_some();
if v.0.is_some() && !has_dot && v.2.is_none() {
return Ok(Value::Int(value_node!(try!(FromStr::from_str(pref)))));
return Ok(Value::Int(value_node!(try!(FromStr::from_str(pref)), pref_pos)));
}
if v.0.is_none() && has_dot {
pref_pos = v.1.unwrap().pos;
}
let suf = match v.2 {
None => "",
Some(ref bs) => &bs.fragment,
};
let to_parse = pref.to_string() + "." + suf;
// TODO(jwall): if there is an error we should report where that error occured.
let f = try!(FromStr::from_str(&to_parse));
return Ok(Value::Float(value_node!(f)));
return Ok(Value::Float(value_node!(f, pref_pos)));
}
// NOTE(jwall): HERE THERE BE DRAGONS. The order for these matters
@ -130,8 +135,8 @@ named!(
);
// Helper function to make the return types work for down below.
fn vec_to_tuple(v: FieldList) -> ParseResult<Value> {
Ok(Value::Tuple(value_node!(v)))
fn vec_to_tuple(t: (Span, FieldList)) -> ParseResult<Value> {
Ok(Value::Tuple(value_node!(t.1, Position{line: t.0.line as usize, column: t.0.offset as usize})))
}
named!(field_list( Span ) -> FieldList,
@ -141,9 +146,13 @@ named!(
#[doc="Capture a tuple of named fields with values. {<field>=<value>,...}"],
tuple( Span ) -> Value,
map_res!(
delimited!(lbracetok,
do_parse!(
pos: position!() >>
v: delimited!(lbracetok,
ws!(field_list),
rbracetok),
rbracetok) >>
(pos, v)
),
vec_to_tuple
)
);
@ -161,12 +170,12 @@ named!(simple_expression( Span ) -> Expression,
)
);
fn tuple_to_binary_expression(tpl: (BinaryExprType, Value, Expression)) -> ParseResult<Expression> {
fn tuple_to_binary_expression(tpl: (Span, BinaryExprType, Value, Expression)) -> ParseResult<Expression> {
Ok(Expression::Binary(BinaryOpDef {
kind: tpl.0,
left: tpl.1,
right: Box::new(tpl.2),
pos: None,
kind: tpl.1,
left: tpl.2,
right: Box::new(tpl.3),
pos: Some(Position{line: tpl.0.line as usize, column: tpl.0.offset as usize}),
}))
}
@ -178,10 +187,11 @@ macro_rules! do_binary_expr {
// particularly like this but I'm living with it for now.
map_res!(
$i, do_parse!(
pos: position!() >>
left: value >>
ws!($fn) >>
right: expression >>
($typ, left, right)
(pos, $typ, left, right)
),
tuple_to_binary_expression
)
@ -222,7 +232,6 @@ fn assert_nonempty_list<T>(v: Vec<T>) -> ParseResult<Vec<T>> {
return Ok(v);
}
// TODO(jwall): We should assert that this is a nonempty list that comes out of here.
named!(selector_list( Span ) -> SelectorList,
map_res!(
separated_list!(dottok, barewordtok),
@ -230,43 +239,43 @@ named!(selector_list( Span ) -> SelectorList,
)
);
fn tuple_to_copy(t: (SelectorList, FieldList)) -> ParseResult<Expression> {
fn tuple_to_copy(t: (Span, SelectorList, FieldList)) -> ParseResult<Expression> {
Ok(Expression::Copy(CopyDef {
selector: t.0,
fields: t.1,
pos: None,
selector: t.1,
fields: t.2,
pos: Some(Position{line: t.0.line as usize, column: t.0.offset as usize}),
}))
}
named!(copy_expression( Span ) -> Expression,
map_res!(
do_parse!(
pos: position!() >>
selector: selector_list >>
lbracetok >>
fields: ws!(field_list) >>
rbracetok >>
(selector, fields)
lbracetok >>
fields: ws!(field_list) >>
rbracetok >>
(pos, selector, fields)
),
tuple_to_copy
)
);
fn tuple_to_macro(mut t: (Vec<Value>, Value)) -> ParseResult<Expression> {
match t.1 {
fn tuple_to_macro(mut t: (Span, Vec<Value>, Value)) -> ParseResult<Expression> {
match t.2 {
Value::Tuple(v) => {
Ok(Expression::Macro(MacroDef {
// TODO(jwall): The position information here is not as accurate as we might want.
argdefs: t.0
argdefs: t.1
.drain(0..)
.map(|s| {
Positioned {
pos: v.pos.clone(),
pos: Some(s.pos().clone()),
val: s.to_string(),
}
})
.collect(),
fields: v.val,
pos: v.pos,
pos: Some(Position{line: t.0.line as usize, column: t.0.offset as usize}),
}))
}
// TODO(jwall): Show a better version of the unexpected parsed value.
@ -281,26 +290,27 @@ named!(arglist( Span ) -> Vec<Value>, separated_list!(ws!(commatok), symbol));
named!(macro_expression( Span ) -> Expression,
map_res!(
do_parse!(
macrotok >>
ws!(lparentok) >>
arglist: ws!(arglist) >>
rparentok >>
ws!(fatcommatok) >>
map: tuple >>
(arglist, map)
pos: position!() >>
macrotok >>
ws!(lparentok) >>
arglist: ws!(arglist) >>
rparentok >>
ws!(fatcommatok) >>
map: tuple >>
(pos, arglist, map)
),
tuple_to_macro
)
);
fn tuple_to_select(t: (Expression, Expression, Value)) -> ParseResult<Expression> {
match t.2 {
fn tuple_to_select(t: (Span, Expression, Expression, Value)) -> ParseResult<Expression> {
match t.3 {
Value::Tuple(v) => {
Ok(Expression::Select(SelectDef {
val: Box::new(t.0),
default: Box::new(t.1),
val: Box::new(t.1),
default: Box::new(t.2),
tuple: v.val,
pos: None,
pos: Some(Position{line: t.0.line as usize, column: t.0.offset as usize}),
}))
}
// TODO(jwall): Show a better version of the unexpected parsed value.
@ -313,11 +323,12 @@ fn tuple_to_select(t: (Expression, Expression, Value)) -> ParseResult<Expression
named!(select_expression( Span ) -> Expression,
map_res!(
do_parse!(
pos: position!() >>
selecttok >>
val: ws!(terminated!(expression, commatok)) >>
default: ws!(terminated!(expression, commatok)) >>
map: ws!(tuple) >>
(val, default, map)
val: ws!(terminated!(expression, commatok)) >>
default: ws!(terminated!(expression, commatok)) >>
map: ws!(tuple) >>
(pos, val, default, map)
),
tuple_to_select
)
@ -345,25 +356,29 @@ named!(format_expression( Span ) -> Expression,
)
);
fn tuple_to_call(t: (Value, Vec<Expression>)) -> ParseResult<Expression> {
if let Value::Selector(sl) = t.0 {
fn tuple_to_call(t: (Span, Value, Vec<Expression>)) -> ParseResult<Expression> {
if let Value::Selector(sl) = t.1 {
Ok(Expression::Call(CallDef {
macroref: sl.val,
arglist: t.1,
pos: None,
arglist: t.2,
pos: Some(Position{line: t.0.line as usize, column: t.0.offset as usize}),
}))
} else {
Err(Box::new(ParseError::UnexpectedToken("Selector".to_string(), format!("{:?}", t.0))))
}
}
fn vec_to_selector_value(v: SelectorList) -> ParseResult<Value> {
Ok(Value::Selector(value_node!(v)))
fn vec_to_selector_value(t: (Span, SelectorList)) -> ParseResult<Value> {
Ok(Value::Selector(value_node!(t.1, Position{line: t.0.line as usize, column: t.0.offset as usize})))
}
named!(selector_value( Span ) -> Value,
map_res!(
ws!(selector_list),
do_parse!(
pos: position!() >>
sl: ws!(selector_list) >>
(pos, sl)
),
vec_to_selector_value
)
);
@ -371,11 +386,12 @@ named!(selector_value( Span ) -> Value,
named!(call_expression( Span ) -> Expression,
map_res!(
do_parse!(
pos: position!() >>
macroname: selector_value >>
lparentok >>
args: ws!(separated_list!(ws!(commatok), expression)) >>
rparentok >>
(macroname, args)
lparentok >>
args: ws!(separated_list!(ws!(commatok), expression)) >>
rparentok >>
(pos, macroname, args)
),
tuple_to_call
)
@ -468,8 +484,6 @@ named!(statement( Span ) -> Statement,
named!(pub parse( Span ) -> Vec<Statement>, many1!(ws!(statement)));
// TODO(jwall): Full Statement parsing tests.
#[cfg(test)]
mod test {
use super::{Statement, Expression, Value, MacroDef, SelectDef, CallDef};
@ -525,7 +539,7 @@ mod test {
column: 5,
},
},
value: Expression::Simple(Value::Float(value_node!(1.0)))
value: Expression::Simple(Value::Float(value_node!(1.0, Position{line: 1, column: 11})))
}));
stmt = "1.0;";
let input = LocatedSpan::new(stmt);
@ -537,7 +551,7 @@ mod test {
fragment: "",
},
Statement::Expression(
Expression::Simple(Value::Float(value_node!(1.0))))));
Expression::Simple(Value::Float(value_node!(1.0, Position{line: 1, column: 1}))))));
}
#[test]
@ -593,7 +607,7 @@ mod test {
column: 5,
},
},
value: Expression::Simple(Value::Float(value_node!(1.0)))
value: Expression::Simple(Value::Float(value_node!(1.0, Position{line: 1, column: 11})))
}));
let_stmt = "let foo= 1.0;";
@ -610,7 +624,7 @@ mod test {
column: 5,
}
},
value: Expression::Simple(Value::Float(value_node!(1.0)))}));
value: Expression::Simple(Value::Float(value_node!(1.0, Position{line: 1, column: 10})))}));
let_stmt = "let foo =1.0;";
assert_eq!(let_statement(LocatedSpan::new(let_stmt)),
IResult::Done(LocatedSpan{
@ -625,7 +639,7 @@ mod test {
column: 5,
}
},
value: Expression::Simple(Value::Float(value_node!(1.0)))}));
value: Expression::Simple(Value::Float(value_node!(1.0, Position{line: 1, column: 10})))}));
}
#[test]
@ -638,7 +652,7 @@ mod test {
line: 1,
},
Statement::Expression(
Expression::Simple(Value::Float(value_node!(1.0))))));
Expression::Simple(Value::Float(value_node!(1.0, Position{line: 1, column: 1}))))));
assert_eq!(expression_statement(LocatedSpan::new("1.0 ;")),
IResult::Done(LocatedSpan {
fragment: "",
@ -646,7 +660,7 @@ mod test {
line: 1,
},
Statement::Expression(
Expression::Simple(Value::Float(value_node!(1.0))))));
Expression::Simple(Value::Float(value_node!(1.0, Position{line: 1, column: 1}))))));
assert_eq!(expression_statement(LocatedSpan::new(" 1.0;")),
IResult::Done(LocatedSpan {
fragment: "",
@ -654,7 +668,7 @@ mod test {
line: 1,
},
Statement::Expression(
Expression::Simple(Value::Float(value_node!(1.0))))));
Expression::Simple(Value::Float(value_node!(1.0, Position{line: 1, column: 2}))))));
assert_eq!(expression_statement(LocatedSpan::new("foo;")),
IResult::Done(LocatedSpan {
fragment: "",
@ -662,7 +676,7 @@ mod test {
line: 1,
},
Statement::Expression(
Expression::Simple(Value::Symbol(value_node!("foo".to_string()))))));
Expression::Simple(Value::Symbol(value_node!("foo".to_string(), Position{line: 1, column: 1}))))));
assert_eq!(expression_statement(LocatedSpan::new("foo ;")),
IResult::Done(LocatedSpan {
fragment: "",
@ -670,7 +684,7 @@ mod test {
line: 1,
},
Statement::Expression(
Expression::Simple(Value::Symbol(value_node!("foo".to_string()))))));
Expression::Simple(Value::Symbol(value_node!("foo".to_string(), Position{line: 1, column: 1}))))));
assert_eq!(expression_statement(LocatedSpan::new(" foo;")),
IResult::Done(LocatedSpan {
fragment: "",
@ -678,7 +692,7 @@ mod test {
line: 1,
},
Statement::Expression(
Expression::Simple(Value::Symbol(value_node!("foo".to_string()))))));
Expression::Simple(Value::Symbol(value_node!("foo".to_string(), Position{line: 1, column: 2}))))));
assert_eq!(expression_statement(LocatedSpan::new("\"foo\";")),
IResult::Done(LocatedSpan {
fragment: "",
@ -686,7 +700,7 @@ mod test {
line: 1,
},
Statement::Expression(
Expression::Simple(Value::String(value_node!("foo".to_string()))))));
Expression::Simple(Value::String(value_node!("foo".to_string(), Position{line: 1, column: 1}))))));
assert_eq!(expression_statement(LocatedSpan::new("\"foo\" ;")),
IResult::Done(LocatedSpan {
fragment: "",
@ -694,7 +708,7 @@ mod test {
line: 1,
},
Statement::Expression(
Expression::Simple(Value::String(value_node!("foo".to_string()))))));
Expression::Simple(Value::String(value_node!("foo".to_string(), Position{line: 1, column: 1}))))));
assert_eq!(expression_statement(LocatedSpan::new(" \"foo\";")),
IResult::Done(LocatedSpan {
fragment: "",
@ -702,7 +716,7 @@ mod test {
line: 1,
},
Statement::Expression(
Expression::Simple(Value::String(value_node!("foo".to_string()))))));
Expression::Simple(Value::String(value_node!("foo".to_string(), Position{line: 1, column: 2}))))));
}
#[test]
@ -713,186 +727,187 @@ mod test {
offset: 1,
line: 1,
},
Expression::Simple(Value::Int(value_node!(1)))));
Expression::Simple(Value::Int(value_node!(1, Position{line: 1, column: 1})))));
assert_eq!(expression(LocatedSpan::new("foo")),
IResult::Done(LocatedSpan {
fragment: "",
offset: 3,
line: 1,
},
Expression::Simple(Value::Symbol(value_node!("foo".to_string())))));
Expression::Simple(Value::Symbol(value_node!("foo".to_string(), Position{line: 1, column: 1})))));
assert_eq!(expression(LocatedSpan::new("1 + 1")),
IResult::Done(LocatedSpan {
fragment: "",
offset: 5,
line: 1,
},
Expression::Binary(BinaryOpDef{
kind: BinaryExprType::Add,
left: Value::Int(value_node!(1)),
right: Box::new(Expression::Simple(Value::Int(value_node!(1)))),
pos: None,
})));
Expression::Binary(BinaryOpDef{
kind: BinaryExprType::Add,
left: Value::Int(value_node!(1, Position{line: 1, column: 1})),
right: Box::new(Expression::Simple(Value::Int(value_node!(1, Position{line: 1, column: 5})))),
pos: Some(Position { line: 1, column: 0 }),
})));
assert_eq!(expression(LocatedSpan::new("1 - 1")),
IResult::Done(LocatedSpan {
fragment: "",
offset: 5,
line: 1,
},
Expression::Binary(BinaryOpDef{
kind: BinaryExprType::Sub,
left: Value::Int(value_node!(1)),
right: Box::new(Expression::Simple(Value::Int(value_node!(1)))),
pos: None,
})));
Expression::Binary(BinaryOpDef{
kind: BinaryExprType::Sub,
left: Value::Int(value_node!(1, Position{line: 1, column: 1})),
right: Box::new(Expression::Simple(Value::Int(value_node!(1, Position{line: 1, column: 5})))),
pos: Some(Position { line: 1, column: 0 }),
})));
assert_eq!(expression(LocatedSpan::new("1 * 1")),
IResult::Done(LocatedSpan {
IResult::Done(LocatedSpan {
fragment: "",
offset: 5,
line: 1,
},
Expression::Binary(BinaryOpDef{
kind: BinaryExprType::Mul,
left: Value::Int(value_node!(1)),
right: Box::new(Expression::Simple(Value::Int(value_node!(1)))),
pos: None,
})));
Expression::Binary(BinaryOpDef{
kind: BinaryExprType::Mul,
left: Value::Int(value_node!(1, Position{line: 1, column: 1})),
right: Box::new(Expression::Simple(Value::Int(value_node!(1, Position{line: 1, column: 5})))),
pos: Some(Position { line: 1, column: 0 }),
})));
assert_eq!(expression(LocatedSpan::new("1 / 1")),
IResult::Done(LocatedSpan {
IResult::Done(LocatedSpan {
fragment: "",
offset: 5,
line: 1,
},
Expression::Binary(BinaryOpDef{
kind: BinaryExprType::Div,
left: Value::Int(value_node!(1)),
right: Box::new(Expression::Simple(Value::Int(value_node!(1)))),
pos: None,
})));
Expression::Binary(BinaryOpDef{
kind: BinaryExprType::Div,
left: Value::Int(value_node!(1, Position{line: 1, column: 1})),
right: Box::new(Expression::Simple(Value::Int(value_node!(1, Position{line: 1, column: 5})))),
pos: Some(Position { line: 1, column: 0 }),
})));
assert_eq!(expression(LocatedSpan::new("1+1")),
IResult::Done(LocatedSpan {
IResult::Done(LocatedSpan {
fragment: "",
offset: 3,
line: 1,
},
Expression::Binary(BinaryOpDef{
kind: BinaryExprType::Add,
left: Value::Int(value_node!(1)),
right: Box::new(Expression::Simple(Value::Int(value_node!(1)))),
pos: None,
})));
Expression::Binary(BinaryOpDef{
kind: BinaryExprType::Add,
left: Value::Int(value_node!(1, Position{line: 1, column: 1})),
right: Box::new(Expression::Simple(Value::Int(value_node!(1, Position{line: 1, column: 3})))),
pos: Some(Position { line: 1, column: 0 }),
})));
assert_eq!(expression(LocatedSpan::new("1-1")),
IResult::Done(LocatedSpan {
IResult::Done(LocatedSpan {
fragment: "",
offset: 3,
line: 1,
},
Expression::Binary(BinaryOpDef{
kind: BinaryExprType::Sub,
left: Value::Int(value_node!(1)),
right: Box::new(Expression::Simple(Value::Int(value_node!(1)))),
pos: None,
})));
Expression::Binary(BinaryOpDef{
kind: BinaryExprType::Sub,
left: Value::Int(value_node!(1, Position{line: 1, column: 1})),
right: Box::new(Expression::Simple(Value::Int(value_node!(1, Position{line: 1, column: 3})))),
pos: Some(Position { line: 1, column: 0 }),
})));
assert_eq!(expression(LocatedSpan::new("1*1")),
IResult::Done(LocatedSpan {
IResult::Done(LocatedSpan {
fragment: "",
offset: 3,
line: 1,
},
Expression::Binary(BinaryOpDef{
kind: BinaryExprType::Mul,
left: Value::Int(value_node!(1)),
right: Box::new(Expression::Simple(Value::Int(value_node!(1)))),
pos: None,
})));
Expression::Binary(BinaryOpDef{
kind: BinaryExprType::Mul,
left: Value::Int(value_node!(1, Position{line: 1, column: 1})),
right: Box::new(Expression::Simple(Value::Int(value_node!(1, Position{line: 1, column: 3})))),
pos: Some(Position { line: 1, column: 0 }),
})));
assert_eq!(expression(LocatedSpan::new("1/1")),
IResult::Done(LocatedSpan {
IResult::Done(LocatedSpan {
fragment: "",
offset: 3,
line: 1,
},
Expression::Binary(BinaryOpDef{
kind: BinaryExprType::Div,
left: Value::Int(value_node!(1)),
right: Box::new(Expression::Simple(Value::Int(value_node!(1)))),
pos: None,
})));
Expression::Binary(BinaryOpDef{
kind: BinaryExprType::Div,
left: Value::Int(value_node!(1, Position{line: 1, column: 1})),
right: Box::new(Expression::Simple(Value::Int(value_node!(1, Position{line: 1, column: 3})))),
pos: Some(Position { line: 1, column: 0 }),
})));
let macro_expr = "macro (arg1, arg2) => { foo = arg1 }";
assert_eq!(expression(LocatedSpan::new(macro_expr)),
IResult::Done(LocatedSpan {
IResult::Done(LocatedSpan {
fragment: "",
offset: macro_expr.len(),
line: 1,
},
Expression::Macro(MacroDef{
argdefs: vec![
Positioned::new("arg1".to_string()),
Positioned::new("arg2".to_string()),
],
fields: vec![
(Token::new_with_pos("foo", Position{line: 1, column: 25}),
Expression::Simple(Value::Symbol(value_node!("arg1".to_string())))),
],
pos: None,
})
Expression::Macro(MacroDef{
argdefs: vec![
Positioned::new_with_pos("arg1".to_string(), Position{line: 1, column: 8}),
Positioned::new_with_pos("arg2".to_string(), Position{line: 1, column: 14}),
],
fields: vec![
(Token::new("foo", Position{line: 1, column: 25}),
Expression::Simple(Value::Symbol(value_node!("arg1".to_string(), Position{line: 1, column: 31})))),
],
// FIXME(jwall): I think this is incorrect.
pos: Some(Position{line: 1, column: 0}),
})
)
);
let select_expr = "select foo, 1, { foo = 2 }";
assert_eq!(expression(LocatedSpan::new(select_expr)),
IResult::Done(LocatedSpan {
IResult::Done(LocatedSpan {
fragment: "",
offset: select_expr.len(),
line: 1,
},
Expression::Select(SelectDef{
val: Box::new(Expression::Simple(Value::Symbol(value_node!("foo".to_string())))),
default: Box::new(Expression::Simple(Value::Int(value_node!(1)))),
tuple: vec![
(Token::new_with_pos("foo", Position{line: 1, column: 18}),
Expression::Simple(Value::Int(value_node!(2))))
],
pos: None,
})
Expression::Select(SelectDef{
val: Box::new(Expression::Simple(Value::Symbol(value_node!("foo".to_string(), Position{line: 1, column: 8})))),
default: Box::new(Expression::Simple(Value::Int(value_node!(1, Position{line: 1, column: 13})))),
tuple: vec![
(Token::new("foo", Position{line: 1, column: 18}),
Expression::Simple(Value::Int(value_node!(2, Position{line: 1, column: 24}))))
],
pos: Some(Position{line: 1, column: 0}),
})
)
);
let call_expr = "foo.bar (1, \"foo\")";
assert_eq!(expression(LocatedSpan::new(call_expr)),
IResult::Done(LocatedSpan {
fragment: "",
offset: call_expr.len(),
line: 1,
},
Expression::Call(CallDef{
macroref: vec![Token::new_with_pos("foo", Position{line:1,column: 1}),
Token::new_with_pos("bar", Position{line:1,column: 5})],
arglist: vec![
Expression::Simple(Value::Int(value_node!(1))),
Expression::Simple(Value::String(value_node!("foo".to_string()))),
],
pos: None,
})
)
let call_expr = "foo.bar (1, \"foo\")";
assert_eq!(expression(LocatedSpan::new(call_expr)),
IResult::Done(LocatedSpan {
fragment: "",
offset: call_expr.len(),
line: 1,
},
Expression::Call(CallDef{
macroref: vec![Token::new("foo", Position{line:1,column: 1}),
Token::new("bar", Position{line:1,column: 5})],
arglist: vec![
Expression::Simple(Value::Int(value_node!(1, Position{line: 1, column: 10}))),
Expression::Simple(Value::String(value_node!("foo".to_string(), Position{line: 1, column: 13}))),
],
pos: Some(Position{line: 1, column: 0}),
})
)
);
assert_eq!(expression(LocatedSpan::new("(1 + 1)")),
IResult::Done(LocatedSpan {
fragment: "",
offset: 7,
line: 1,
},
Expression::Grouped(
Box::new(
Expression::Binary(
BinaryOpDef{
kind: BinaryExprType::Add,
left: Value::Int(value_node!(1)),
right: Box::new(Expression::Simple(Value::Int(value_node!(1)))),
pos: None,
}
)
)
)
assert_eq!(expression(LocatedSpan::new("(1 + 1)")),
IResult::Done(LocatedSpan {
fragment: "",
offset: 7,
line: 1,
},
Expression::Grouped(
Box::new(
Expression::Binary(
BinaryOpDef{
kind: BinaryExprType::Add,
left: Value::Int(value_node!(1, Position{line: 1, column: 2})),
right: Box::new(Expression::Simple(Value::Int(value_node!(1, Position{line: 1, column: 6})))),
pos: Some(Position { line: 1, column: 1 }),
}
)
)
)
)
);
}
@ -913,8 +928,8 @@ mod test {
Expression::Format(
FormatDef{
template: "foo @ @".to_string(),
args: vec![Expression::Simple(Value::Int(value_node!(1))),
Expression::Simple(Value::Int(value_node!(2)))],
args: vec![Expression::Simple(Value::Int(value_node!(1, Position{line: 1, column: 14}))),
Expression::Simple(Value::Int(value_node!(2, Position{line: 1, column: 17})))],
pos: Some(Position{line: 1, column: 1}),
}
)
@ -931,8 +946,8 @@ mod test {
Expression::Format(
FormatDef{
template: "foo @ @".to_string(),
args: vec![Expression::Simple(Value::Int(value_node!(1))),
Expression::Simple(Value::Int(value_node!(2)))],
args: vec![Expression::Simple(Value::Int(value_node!(1, Position{line: 1, column: 12}))),
Expression::Simple(Value::Int(value_node!(2, Position{line: 1, column: 15})))],
pos: Some(Position { line: 1, column: 1 }),
}
)
@ -957,12 +972,12 @@ mod test {
offset: copy_expr.len(),
},
Expression::Call(CallDef{
macroref: vec![Token::new_with_pos("foo", Position{line:1, column: 1})],
macroref: vec![Token::new("foo", Position{line:1, column: 1})],
arglist: vec![
Expression::Simple(Value::Int(value_node!(1))),
Expression::Simple(Value::String(value_node!("foo".to_string()))),
Expression::Simple(Value::Int(value_node!(1, Position{line: 1, column: 6}))),
Expression::Simple(Value::String(value_node!("foo".to_string(), Position{line: 1, column: 9}))),
],
pos: None,
pos: Some(Position{line: 1, column: 0}),
})
)
);
@ -976,13 +991,13 @@ mod test {
offset: copy_expr.len(),
},
Expression::Call(CallDef{
macroref: vec![Token::new_with_pos("foo", Position{line: 1, column: 1}),
Token::new_with_pos("bar", Position{line: 1, column: 5})],
macroref: vec![Token::new("foo", Position{line: 1, column: 1}),
Token::new("bar", Position{line: 1, column: 5})],
arglist: vec![
Expression::Simple(Value::Int(value_node!(1))),
Expression::Simple(Value::String(value_node!("foo".to_string()))),
Expression::Simple(Value::Int(value_node!(1, Position{line: 1, column: 10}))),
Expression::Simple(Value::String(value_node!("foo".to_string(), Position{line: 1, column: 13}))),
],
pos: None,
pos: Some(Position{line: 1, column: 0}),
})
)
);
@ -997,19 +1012,19 @@ mod test {
let select_expr = "select foo, 1, { foo = 2 }";
assert_eq!(select_expression(LocatedSpan::new(select_expr)),
IResult::Done(LocatedSpan {
IResult::Done(LocatedSpan {
fragment: "",
offset: select_expr.len(),
line: 1,
},
Expression::Select(SelectDef{
val: Box::new(Expression::Simple(Value::Symbol(value_node!("foo".to_string())))),
default: Box::new(Expression::Simple(Value::Int(value_node!(1)))),
tuple: vec![
(Token::new_with_pos("foo", Position{line: 1, column: 18}), Expression::Simple(Value::Int(value_node!(2))))
],
pos: None,
})
Expression::Select(SelectDef{
val: Box::new(Expression::Simple(Value::Symbol(value_node!("foo".to_string(), Position{line: 1, column: 8})))),
default: Box::new(Expression::Simple(Value::Int(value_node!(1, Position{line: 1, column: 13})))),
tuple: vec![
(Token::new("foo", Position{line: 1, column: 18}), Expression::Simple(Value::Int(value_node!(2, Position{line: 1, column: 24}))))
],
pos: Some(Position{line: 1, column: 0}),
})
)
);
}
@ -1037,12 +1052,12 @@ mod test {
line: 1
},
Expression::Macro(MacroDef{
argdefs: vec![Positioned::new("arg1".to_string()),
Positioned::new("arg2".to_string())],
fields: vec![(Token::new_with_pos("foo", Position{line: 1, column: 24}), Expression::Simple(Value::Int(value_node!(1)))),
(Token::new_with_pos("bar", Position{line: 1, column: 30}), Expression::Simple(Value::Int(value_node!(2))))
argdefs: vec![Positioned::new_with_pos("arg1".to_string(), Position{line: 1, column: 8}),
Positioned::new_with_pos("arg2".to_string(), Position{line: 1, column: 14})],
fields: vec![(Token::new("foo", Position{line: 1, column: 24}), Expression::Simple(Value::Int(value_node!(1, Position{line: 1, column: 28})))),
(Token::new("bar", Position{line: 1, column: 30}), Expression::Simple(Value::Int(value_node!(2, Position{line: 1, column: 34}))))
],
pos: None,
pos: Some(Position{line: 1, column: 0}),
})
)
);
@ -1063,9 +1078,9 @@ mod test {
line: 1
},
Expression::Copy(CopyDef{
selector: vec![Token::new_with_pos("foo", Position{line: 1, column: 1})],
selector: vec![Token::new("foo", Position{line: 1, column: 1})],
fields: Vec::new(),
pos: None,
pos: Some(Position{line: 1, column: 0}),
})
)
);
@ -1079,10 +1094,10 @@ mod test {
line: 1
},
Expression::Copy(CopyDef{
selector: vec![Token::new_with_pos("foo", Position{line: 1, column: 1})],
fields: vec![(Token::new_with_pos("bar", Position{line: 1, column: 5}),
Expression::Simple(Value::Int(value_node!(1))))],
pos: None,
selector: vec![Token::new("foo", Position{line: 1, column: 1})],
fields: vec![(Token::new("bar", Position{line: 1, column: 5}),
Expression::Simple(Value::Int(value_node!(1, Position{line: 1, column: 9}))))],
pos: Some(Position{line: 1, column: 0}),
})
)
);
@ -1097,7 +1112,7 @@ mod test {
Expression::Grouped(
Box::new(
Expression::Simple(
Value::Symbol(value_node!("foo".to_string()))))))
Value::Symbol(value_node!("foo".to_string(), Position{line: 1, column: 2}))))))
);
assert_eq!(grouped_expression(LocatedSpan::new("(1 + 1)")),
IResult::Done(LocatedSpan{fragment: "", offset: 7, line: 1},
@ -1106,10 +1121,10 @@ mod test {
Expression::Binary(
BinaryOpDef{
kind: BinaryExprType::Add,
left: Value::Int(value_node!(1)),
left: Value::Int(value_node!(1, Position{line: 1, column: 2})),
right: Box::new(Expression::Simple(
Value::Int(value_node!(1)))),
pos: None,
Value::Int(value_node!(1, Position{line: 1, column: 6})))),
pos: Some(Position { line: 1, column: 1 }),
}
)
)
@ -1135,7 +1150,7 @@ mod test {
line: 1,
},
Value::Tuple(
value_node!(vec![]))));
value_node!(vec![], Position{line: 1, column: 0}))));
tuple_expr = "{ foo = 1 }";
assert_eq!(tuple(LocatedSpan::new(tuple_expr)),
@ -1146,9 +1161,9 @@ mod test {
},
Value::Tuple(
value_node!(vec![
(Token::new_with_pos("foo", Position{line:1, column: 3}),
Expression::Simple(Value::Int(value_node!(1))))
]))));
(Token::new("foo", Position{line:1, column: 3}),
Expression::Simple(Value::Int(value_node!(1, Position{line: 1, column: 9}))))
], Position{line: 1, column: 0}))));
tuple_expr = "{ foo = 1, bar = \"1\" }";
assert_eq!(tuple(LocatedSpan::new(tuple_expr)),
@ -1159,13 +1174,13 @@ mod test {
},
Value::Tuple(
value_node!(vec![
(Token::new_with_pos("foo", Position{line: 1, column: 3}),
Expression::Simple(Value::Int(value_node!(1)))),
(Token::new_with_pos("bar", Position{line: 1, column: 12}),
Expression::Simple(Value::String(value_node!("1".to_string()))))
]))));
(Token::new("foo", Position{line: 1, column: 3}),
Expression::Simple(Value::Int(value_node!(1, Position{line: 1, column: 9})))),
(Token::new("bar", Position{line: 1, column: 12}),
Expression::Simple(Value::String(value_node!("1".to_string(), Position{line: 1, column: 18}))))
], Position{line: 1, column: 0}))));
tuple_expr = "{ foo = 1, bar = {} }";
assert_eq!(tuple(LocatedSpan::new(tuple_expr)),
assert_eq!(tuple(LocatedSpan::new(tuple_expr)),
IResult::Done(LocatedSpan {
fragment: "",
offset: tuple_expr.len(),
@ -1173,11 +1188,11 @@ mod test {
},
Value::Tuple(
value_node!(vec![
(Token::new_with_pos("foo", Position{line: 1, column: 3}),
Expression::Simple(Value::Int(value_node!(1)))),
(Token::new_with_pos("bar", Position{line: 1, column: 12}),
Expression::Simple(Value::Tuple(value_node!(Vec::new()))))
]))));
(Token::new("foo", Position{line: 1, column: 3}),
Expression::Simple(Value::Int(value_node!(1, Position{line: 1, column: 9})))),
(Token::new("bar", Position{line: 1, column: 12}),
Expression::Simple(Value::Tuple(value_node!(Vec::new(), Position{line: 1, column: 17}))))
], Position{line: 1, column: 0}))));
}
#[test]
@ -1187,20 +1202,20 @@ mod test {
assert_eq!(field_value(LocatedSpan::new("foo = 1")),
IResult::Done(LocatedSpan { offset: 7, line: 1, fragment: "" },
(Token::new_with_pos("foo", Position{line: 1, column: 1}),
Expression::Simple(Value::Int(value_node!(1))))) );
(Token::new("foo", Position{line: 1, column: 1}),
Expression::Simple(Value::Int(value_node!(1, Position{line: 1, column: 7}))))) );
assert_eq!(field_value(LocatedSpan::new("foo = \"1\"")),
IResult::Done(LocatedSpan { offset: 9, line: 1, fragment: "" },
(Token::new_with_pos("foo", Position{line: 1, column: 1}),
Expression::Simple(Value::String(value_node!("1".to_string()))))) );
(Token::new("foo", Position{line: 1, column: 1}),
Expression::Simple(Value::String(value_node!("1".to_string(), Position{line: 1, column: 7}))))) );
assert_eq!(field_value(LocatedSpan::new("foo = bar")),
IResult::Done(LocatedSpan { offset: 9, line: 1, fragment: "" },
(Token::new_with_pos("foo", Position{line: 1, column: 1}),
Expression::Simple(Value::Symbol(value_node!("bar".to_string()))))) );
(Token::new("foo", Position{line: 1, column: 1}),
Expression::Simple(Value::Symbol(value_node!("bar".to_string(), Position{line: 1, column: 7}))))) );
assert_eq!(field_value(LocatedSpan::new("foo = bar ")),
IResult::Done(LocatedSpan { offset: 10, line: 1, fragment: "" },
(Token::new_with_pos("foo", Position{line: 1, column: 1}),
Expression::Simple(Value::Symbol(value_node!("bar".to_string()))))) );
(Token::new("foo", Position{line: 1, column: 1}),
Expression::Simple(Value::Symbol(value_node!("bar".to_string(), Position{line: 1, column: 7}))))) );
}
#[test]
@ -1209,29 +1224,29 @@ mod test {
assert!(number(LocatedSpan::new(". ")).is_err() );
assert_eq!(number(LocatedSpan::new("1.0")),
IResult::Done(LocatedSpan{fragment: "", offset: 3, line: 1},
Value::Float(value_node!(1.0))) );
Value::Float(value_node!(1.0, Position{line: 1, column: 1}))) );
assert_eq!(number(LocatedSpan::new("1.")),
IResult::Done(LocatedSpan{fragment: "", offset: 2, line: 1},
Value::Float(value_node!(1.0))) );
Value::Float(value_node!(1.0, Position{line: 1, column: 1}))) );
assert_eq!(number(LocatedSpan::new("1")),
IResult::Done(LocatedSpan{fragment: "", offset: 1, line: 1},
Value::Int(value_node!(1))) );
Value::Int(value_node!(1, Position{line: 1, column: 1}))) );
assert_eq!(number(LocatedSpan::new(".1")),
IResult::Done(LocatedSpan{fragment: "", offset: 2, line: 1},
Value::Float(value_node!(0.1))) );
Value::Float(value_node!(0.1, Position{line: 1, column: 1}))) );
}
#[test]
fn test_symbol_parsing() {
assert_eq!(symbol(LocatedSpan::new("foo")),
IResult::Done(LocatedSpan{fragment: "", offset: 3, line: 1},
Value::Symbol(value_node!("foo".to_string()))) );
Value::Symbol(value_node!("foo".to_string(), Position{line: 1, column: 1}))) );
assert_eq!(symbol(LocatedSpan::new("foo-bar")),
IResult::Done(LocatedSpan{fragment: "", offset: 7, line: 1},
Value::Symbol(value_node!("foo-bar".to_string()))) );
Value::Symbol(value_node!("foo-bar".to_string(), Position{line: 1, column: 1}))) );
assert_eq!(symbol(LocatedSpan::new("foo_bar")),
IResult::Done(LocatedSpan{fragment: "", offset: 7, line: 1},
Value::Symbol(value_node!("foo_bar".to_string()))) );
Value::Symbol(value_node!("foo_bar".to_string(), Position{line: 1, column: 1}))) );
}
#[test]
@ -1267,15 +1282,15 @@ mod test {
column: 27,
}
},
value: Expression::Simple(Value::Int(value_node!(1)))
value: Expression::Simple(Value::Int(value_node!(1, Position{line: 1, column: 33})))
},
Statement::Expression(
Expression::Binary(
BinaryOpDef{
kind: BinaryExprType::Add,
left: Value::Int(value_node!(1)),
right: Box::new(Expression::Simple(Value::Int(value_node!(1)))),
pos: None,
left: Value::Int(value_node!(1, Position{line: 1, column: 35})),
right: Box::new(Expression::Simple(Value::Int(value_node!(1, Position{line: 1, column: 37})))),
pos: Some(Position { line: 1, column: 34 }),
})
)
]);