From c091878364d1ec1ea9778f74d9478d72871cf322 Mon Sep 17 00:00:00 2001 From: Jeremy Wall Date: Sat, 23 Sep 2017 11:19:45 -0500 Subject: [PATCH] Add a macro for constructing values with or without a position. --- src/ast.rs | 14 +++- src/lib.rs | 3 + src/parse.rs | 186 +++++++++++++++++++++++++++------------------------ 3 files changed, 115 insertions(+), 88 deletions(-) diff --git a/src/ast.rs b/src/ast.rs index 71fbdd2..b07eb19 100644 --- a/src/ast.rs +++ b/src/ast.rs @@ -13,6 +13,7 @@ // limitations under the License. use std::collections::HashSet; use std::borrow::Borrow; +use std::convert::Into; #[derive(Debug,PartialEq,Clone)] pub struct Position { @@ -20,6 +21,15 @@ pub struct Position { pub column: usize, } +macro_rules! value_node { + ($v:expr) => { + LocatedNode::new($v) + }; + ($v:expr, $p:expr) => { + LocatedNode::new_with_pos($v, $p) + }; +} + pub type FieldList = Vec<(String, Expression)>; // str is expected to be a symbol pub type SelectorList = Vec; // str is expected to always be a symbol. @@ -37,9 +47,9 @@ impl LocatedNode { } } - pub fn new_with_pos(v: T, pos: Position) -> Self { + pub fn new_with_pos>(v: T, pos: P) -> Self { Self { - pos: Some(pos), + pos: Some(pos.into()), val: v, } } diff --git a/src/lib.rs b/src/lib.rs index fddc0ab..32e44a6 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -13,10 +13,13 @@ // limitations under the License. #[macro_use] extern crate nom; +#[macro_use] +extern crate nom_locate; #[macro_use] extern crate quick_error; +#[macro_use] pub mod ast; pub mod parse; pub mod build; diff --git a/src/parse.rs b/src/parse.rs index bb2f6c8..524d702 100644 --- a/src/parse.rs +++ b/src/parse.rs @@ -11,6 +11,8 @@ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. +use nom_locate::LocatedSpan; + quick_error! { #[derive(Debug,PartialEq)] pub enum ParseError { @@ -21,12 +23,24 @@ quick_error! { } } +type Span<'a> = LocatedSpan<&'a str>; + +impl<'a> From> for Position { + fn from(s: Span) -> Position { + Position { + line: s.line as usize, + column: s.get_column() as usize, + } + } +} + // TODO(jwall): Convert to tokenizer steps followed by parser steps. // TODO(jwall): Error Reporting with Line and Column information. use std::str::FromStr; use std::str::from_utf8; use std::error::Error; +use std::convert::From; use nom::{alpha, is_alphanumeric, digit}; @@ -61,7 +75,7 @@ named!(field, ); fn symbol_to_value(s: String) -> ParseResult { - Ok(Value::Symbol(make_value_node(s))) + Ok(Value::Symbol(value_node!(s))) } // symbol is a bare unquoted field. @@ -75,7 +89,7 @@ named!(quoted, ); fn str_to_value(s: String) -> ParseResult { - Ok(Value::String(make_value_node(s))) + Ok(Value::String(value_node!(s))) } // quoted_value is a quoted string. @@ -94,7 +108,7 @@ fn triple_to_number(v: (Option<&[u8]>, Option<&[u8]>, Option<&[u8]>)) let has_dot = v.1.is_some(); if v.0.is_some() && !has_dot && v.2.is_none() { - return Ok(Value::Int(make_value_node(try!(FromStr::from_str(pref))))); + return Ok(Value::Int(value_node!(try!(FromStr::from_str(pref))))); } let suf = match v.2 { @@ -104,7 +118,7 @@ fn triple_to_number(v: (Option<&[u8]>, Option<&[u8]>, Option<&[u8]>)) let to_parse = pref.to_string() + "." + suf; let f = try!(FromStr::from_str(&to_parse)); - return Ok(Value::Float(make_value_node(f))); + return Ok(Value::Float(value_node!(f))); } // NOTE(jwall): HERE THERE BE DRAGONS. The order for these matters @@ -164,7 +178,7 @@ named!( // Helper function to make the return types work for down below. fn vec_to_tuple(v: FieldList) -> ParseResult { - Ok(Value::Tuple(make_value_node(v))) + Ok(Value::Tuple(value_node!(v))) } named!(field_list, @@ -381,7 +395,7 @@ fn tuple_to_call(t: (Value, Vec)) -> ParseResult { } fn vec_to_selector_value(v: SelectorList) -> ParseResult { - Ok(Value::Selector(make_value_node(v))) + Ok(Value::Selector(value_node!(v))) } named!(selector_value, @@ -521,11 +535,11 @@ mod test { assert_eq!(statement(&b"let foo = 1.0 ;"[..]), IResult::Done(&b""[..], Statement::Let{name: "foo".to_string(), - value: Expression::Simple(Value::Float(make_value_node(1.0)))})); + value: Expression::Simple(Value::Float(value_node!(1.0)))})); assert_eq!(statement(&b"1.0;"[..]), IResult::Done(&b""[..], Statement::Expression( - Expression::Simple(Value::Float(make_value_node(1.0)))))); + Expression::Simple(Value::Float(value_node!(1.0)))))); } #[test] @@ -559,15 +573,15 @@ mod test { assert_eq!(let_statement(&b"let foo = 1.0 ;"[..]), IResult::Done(&b""[..], Statement::Let{name: "foo".to_string(), - value: Expression::Simple(Value::Float(make_value_node(1.0)))})); + value: Expression::Simple(Value::Float(value_node!(1.0)))})); assert_eq!(let_statement(&b"let foo= 1.0;"[..]), IResult::Done(&b""[..], Statement::Let{name: "foo".to_string(), - value: Expression::Simple(Value::Float(make_value_node(1.0)))})); + value: Expression::Simple(Value::Float(value_node!(1.0)))})); assert_eq!(let_statement(&b"let foo =1.0;"[..]), IResult::Done(&b""[..], Statement::Let{name: "foo".to_string(), - value: Expression::Simple(Value::Float(make_value_node(1.0)))})); + value: Expression::Simple(Value::Float(value_node!(1.0)))})); } #[test] @@ -576,77 +590,77 @@ mod test { assert_eq!(expression_statement(&b"1.0;"[..]), IResult::Done(&b""[..], Statement::Expression( - Expression::Simple(Value::Float(make_value_node(1.0)))))); + Expression::Simple(Value::Float(value_node!(1.0)))))); assert_eq!(expression_statement(&b"1.0 ;"[..]), IResult::Done(&b""[..], Statement::Expression( - Expression::Simple(Value::Float(make_value_node(1.0)))))); + Expression::Simple(Value::Float(value_node!(1.0)))))); assert_eq!(expression_statement(&b" 1.0;"[..]), IResult::Done(&b""[..], Statement::Expression( - Expression::Simple(Value::Float(make_value_node(1.0)))))); + Expression::Simple(Value::Float(value_node!(1.0)))))); assert_eq!(expression_statement(&b"foo;"[..]), IResult::Done(&b""[..], Statement::Expression( - Expression::Simple(Value::Symbol(make_value_node("foo".to_string())))))); + Expression::Simple(Value::Symbol(value_node!("foo".to_string())))))); assert_eq!(expression_statement(&b"foo ;"[..]), IResult::Done(&b""[..], Statement::Expression( - Expression::Simple(Value::Symbol(make_value_node("foo".to_string())))))); + Expression::Simple(Value::Symbol(value_node!("foo".to_string())))))); assert_eq!(expression_statement(&b" foo;"[..]), IResult::Done(&b""[..], Statement::Expression( - Expression::Simple(Value::Symbol(make_value_node("foo".to_string())))))); + Expression::Simple(Value::Symbol(value_node!("foo".to_string())))))); assert_eq!(expression_statement(&b"\"foo\";"[..]), IResult::Done(&b""[..], Statement::Expression( - Expression::Simple(Value::String(make_value_node("foo".to_string())))))); + Expression::Simple(Value::String(value_node!("foo".to_string())))))); assert_eq!(expression_statement(&b"\"foo\" ;"[..]), IResult::Done(&b""[..], Statement::Expression( - Expression::Simple(Value::String(make_value_node("foo".to_string())))))); + Expression::Simple(Value::String(value_node!("foo".to_string())))))); assert_eq!(expression_statement(&b" \"foo\";"[..]), IResult::Done(&b""[..], Statement::Expression( - Expression::Simple(Value::String(make_value_node("foo".to_string())))))); + Expression::Simple(Value::String(value_node!("foo".to_string())))))); } #[test] fn test_expression_parse() { assert_eq!(expression(&b"1"[..]), - IResult::Done(&b""[..], Expression::Simple(Value::Int(make_value_node(1))))); + IResult::Done(&b""[..], Expression::Simple(Value::Int(value_node!(1))))); assert_eq!(expression(&b"foo"[..]), - IResult::Done(&b""[..], Expression::Simple(Value::Symbol(make_value_node("foo".to_string()))))); + IResult::Done(&b""[..], Expression::Simple(Value::Symbol(value_node!("foo".to_string()))))); assert_eq!(expression(&b"1 + 1"[..]), IResult::Done(&b""[..], 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(value_node!(1)), + right: Box::new(Expression::Simple(Value::Int(value_node!(1)))), pos: None, }))); assert_eq!(expression(&b"1 - 1"[..]), IResult::Done(&b""[..], Expression::Binary(BinaryOpDef{ kind: BinaryExprType::Sub, - left: Value::Int(make_value_node(1)), - right: Box::new(Expression::Simple(Value::Int(make_value_node(1)))), + left: Value::Int(value_node!(1)), + right: Box::new(Expression::Simple(Value::Int(value_node!(1)))), pos: None, }))); assert_eq!(expression(&b"1 * 1"[..]), IResult::Done(&b""[..], Expression::Binary(BinaryOpDef{ kind: BinaryExprType::Mul, - left: Value::Int(make_value_node(1)), - right: Box::new(Expression::Simple(Value::Int(make_value_node(1)))), + left: Value::Int(value_node!(1)), + right: Box::new(Expression::Simple(Value::Int(value_node!(1)))), pos: None, }))); assert_eq!(expression(&b"1 / 1"[..]), IResult::Done(&b""[..], Expression::Binary(BinaryOpDef{ kind: BinaryExprType::Div, - left: Value::Int(make_value_node(1)), - right: Box::new(Expression::Simple(Value::Int(make_value_node(1)))), + left: Value::Int(value_node!(1)), + right: Box::new(Expression::Simple(Value::Int(value_node!(1)))), pos: None, }))); @@ -654,32 +668,32 @@ mod test { IResult::Done(&b""[..], 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(value_node!(1)), + right: Box::new(Expression::Simple(Value::Int(value_node!(1)))), pos: None, }))); assert_eq!(expression(&b"1-1"[..]), IResult::Done(&b""[..], Expression::Binary(BinaryOpDef{ kind: BinaryExprType::Sub, - left: Value::Int(make_value_node(1)), - right: Box::new(Expression::Simple(Value::Int(make_value_node(1)))), + left: Value::Int(value_node!(1)), + right: Box::new(Expression::Simple(Value::Int(value_node!(1)))), pos: None, }))); assert_eq!(expression(&b"1*1"[..]), IResult::Done(&b""[..], Expression::Binary(BinaryOpDef{ kind: BinaryExprType::Mul, - left: Value::Int(make_value_node(1)), - right: Box::new(Expression::Simple(Value::Int(make_value_node(1)))), + left: Value::Int(value_node!(1)), + right: Box::new(Expression::Simple(Value::Int(value_node!(1)))), pos: None, }))); assert_eq!(expression(&b"1/1"[..]), IResult::Done(&b""[..], Expression::Binary(BinaryOpDef{ kind: BinaryExprType::Div, - left: Value::Int(make_value_node(1)), - right: Box::new(Expression::Simple(Value::Int(make_value_node(1)))), + left: Value::Int(value_node!(1)), + right: Box::new(Expression::Simple(Value::Int(value_node!(1)))), pos: None, }))); assert_eq!(expression(&b"macro (arg1, arg2) => { foo = arg1 }"[..]), @@ -690,7 +704,7 @@ mod test { "arg2".to_string(), ], fields: vec![ - ("foo".to_string(), Expression::Simple(Value::Symbol(make_value_node("arg1".to_string())))), + ("foo".to_string(), Expression::Simple(Value::Symbol(value_node!("arg1".to_string())))), ], pos: None, }) @@ -699,10 +713,10 @@ mod test { assert_eq!(expression(&b"select foo, 1, { foo = 2 };"[..]), IResult::Done(&b""[..], 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(value_node!("foo".to_string())))), + default: Box::new(Expression::Simple(Value::Int(value_node!(1)))), tuple: vec![ - ("foo".to_string(), Expression::Simple(Value::Int(make_value_node(2)))) + ("foo".to_string(), Expression::Simple(Value::Int(value_node!(2)))) ], pos: None, }) @@ -713,8 +727,8 @@ mod test { Expression::Call(CallDef{ macroref: vec!["foo".to_string(),"bar".to_string()], arglist: vec![ - Expression::Simple(Value::Int(make_value_node(1))), - Expression::Simple(Value::String(make_value_node("foo".to_string()))), + Expression::Simple(Value::Int(value_node!(1))), + Expression::Simple(Value::String(value_node!("foo".to_string()))), ], pos: None, }) @@ -727,8 +741,8 @@ 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(value_node!(1)), + right: Box::new(Expression::Simple(Value::Int(value_node!(1)))), pos: None, } ) @@ -750,8 +764,8 @@ mod test { Expression::Format( FormatDef{ template: "foo @ @".to_string(), - args: vec![Expression::Simple(Value::Int(make_value_node(1))), - Expression::Simple(Value::Int(make_value_node(2)))], + args: vec![Expression::Simple(Value::Int(value_node!(1))), + Expression::Simple(Value::Int(value_node!(2)))], pos: None, }) ) @@ -761,8 +775,8 @@ mod test { Expression::Format( FormatDef{ template: "foo @ @".to_string(), - args: vec![Expression::Simple(Value::Int(make_value_node(1))), - Expression::Simple(Value::Int(make_value_node(2)))], + args: vec![Expression::Simple(Value::Int(value_node!(1))), + Expression::Simple(Value::Int(value_node!(2)))], pos: None, }) ) @@ -782,8 +796,8 @@ mod test { Expression::Call(CallDef{ macroref: vec!["foo".to_string()], arglist: vec![ - Expression::Simple(Value::Int(make_value_node(1))), - Expression::Simple(Value::String(make_value_node("foo".to_string()))), + Expression::Simple(Value::Int(value_node!(1))), + Expression::Simple(Value::String(value_node!("foo".to_string()))), ], pos: None, }) @@ -795,8 +809,8 @@ mod test { Expression::Call(CallDef{ macroref: vec!["foo".to_string(),"bar".to_string()], arglist: vec![ - Expression::Simple(Value::Int(make_value_node(1))), - Expression::Simple(Value::String(make_value_node("foo".to_string()))), + Expression::Simple(Value::Int(value_node!(1))), + Expression::Simple(Value::String(value_node!("foo".to_string()))), ], pos: None, }) @@ -814,10 +828,10 @@ mod test { assert_eq!(select_expression(&b"select foo, 1, { foo = 2 };"[..]), IResult::Done(&b""[..], 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(value_node!("foo".to_string())))), + default: Box::new(Expression::Simple(Value::Int(value_node!(1)))), tuple: vec![ - ("foo".to_string(), Expression::Simple(Value::Int(make_value_node(2)))) + ("foo".to_string(), Expression::Simple(Value::Int(value_node!(2)))) ], pos: None, }) @@ -844,8 +858,8 @@ mod test { Expression::Macro(MacroDef{ argdefs: vec!["arg1".to_string(), "arg2".to_string()], - fields: vec![("foo".to_string(), Expression::Simple(Value::Int(make_value_node(1)))), - ("bar".to_string(), Expression::Simple(Value::Int(make_value_node(2)))) + fields: vec![("foo".to_string(), Expression::Simple(Value::Int(value_node!(1)))), + ("bar".to_string(), Expression::Simple(Value::Int(value_node!(2)))) ], pos: None, }) @@ -872,7 +886,7 @@ mod test { Expression::Copy(CopyDef{ selector: vec!["foo".to_string()], fields: vec![("bar".to_string(), - Expression::Simple(Value::Int(make_value_node(1))))], + Expression::Simple(Value::Int(value_node!(1))))], pos: None, }) ) @@ -888,7 +902,7 @@ mod test { Expression::Grouped( Box::new( Expression::Simple( - Value::Symbol(make_value_node("foo".to_string())))))) + Value::Symbol(value_node!("foo".to_string())))))) ); assert_eq!(grouped_expression(&b"(1 + 1)"[..]), IResult::Done(&b""[..], @@ -897,9 +911,9 @@ mod test { Expression::Binary( BinaryOpDef{ kind: BinaryExprType::Add, - left: Value::Int(make_value_node(1)), + left: Value::Int(value_node!(1)), right: Box::new(Expression::Simple( - Value::Int(make_value_node(1)))), + Value::Int(value_node!(1)))), pos: None, } ) @@ -921,28 +935,28 @@ mod test { assert_eq!(tuple(&b"{ }"[..]), IResult::Done(&b""[..], Value::Tuple( - make_value_node(vec![])))); + value_node!(vec![])))); assert_eq!(tuple(&b"{ foo = 1 }"[..]), IResult::Done(&b""[..], Value::Tuple( - make_value_node(vec![ - ("foo".to_string(), Expression::Simple(Value::Int(make_value_node(1)))) + value_node!(vec![ + ("foo".to_string(), Expression::Simple(Value::Int(value_node!(1)))) ])))); assert_eq!(tuple(&b"{ foo = 1, bar = \"1\" }"[..]), IResult::Done(&b""[..], Value::Tuple( - make_value_node(vec![ - ("foo".to_string(), Expression::Simple(Value::Int(make_value_node(1)))), - ("bar".to_string(), Expression::Simple(Value::String(make_value_node("1".to_string())))) + value_node!(vec![ + ("foo".to_string(), Expression::Simple(Value::Int(value_node!(1)))), + ("bar".to_string(), Expression::Simple(Value::String(value_node!("1".to_string())))) ])))); assert_eq!(tuple(&b"{ foo = 1, bar = {} }"[..]), IResult::Done(&b""[..], Value::Tuple( - make_value_node(vec![ - ("foo".to_string(), Expression::Simple(Value::Int(make_value_node(1)))), - ("bar".to_string(), Expression::Simple(Value::Tuple(make_value_node(Vec::new())))) + value_node!(vec![ + ("foo".to_string(), Expression::Simple(Value::Int(value_node!(1)))), + ("bar".to_string(), Expression::Simple(Value::Tuple(value_node!(Vec::new())))) ])))); } @@ -952,13 +966,13 @@ mod test { assert!(field_value(&b"foo ="[..]).is_incomplete() ); assert_eq!(field_value(&b"foo = 1"[..]), - IResult::Done(&b""[..], ("foo".to_string(), Expression::Simple(Value::Int(make_value_node(1))))) ); + IResult::Done(&b""[..], ("foo".to_string(), Expression::Simple(Value::Int(value_node!(1))))) ); assert_eq!(field_value(&b"foo = \"1\""[..]), - IResult::Done(&b""[..], ("foo".to_string(), Expression::Simple(Value::String(make_value_node("1".to_string()))))) ); + IResult::Done(&b""[..], ("foo".to_string(), Expression::Simple(Value::String(value_node!("1".to_string()))))) ); assert_eq!(field_value(&b"foo = bar"[..]), - IResult::Done(&b""[..], ("foo".to_string(), Expression::Simple(Value::Symbol(make_value_node("bar".to_string()))))) ); + IResult::Done(&b""[..], ("foo".to_string(), Expression::Simple(Value::Symbol(value_node!("bar".to_string()))))) ); assert_eq!(field_value(&b"foo = bar "[..]), - IResult::Done(&b""[..], ("foo".to_string(), Expression::Simple(Value::Symbol(make_value_node("bar".to_string()))))) ); + IResult::Done(&b""[..], ("foo".to_string(), Expression::Simple(Value::Symbol(value_node!("bar".to_string()))))) ); } #[test] @@ -966,23 +980,23 @@ mod test { assert!(number(&b"."[..]).is_err() ); assert!(number(&b". "[..]).is_err() ); assert_eq!(number(&b"1.0"[..]), - IResult::Done(&b""[..], Value::Float(make_value_node(1.0))) ); + IResult::Done(&b""[..], Value::Float(value_node!(1.0))) ); assert_eq!(number(&b"1."[..]), - IResult::Done(&b""[..], Value::Float(make_value_node(1.0))) ); + IResult::Done(&b""[..], Value::Float(value_node!(1.0))) ); assert_eq!(number(&b"1"[..]), - IResult::Done(&b""[..], Value::Int(make_value_node(1))) ); + IResult::Done(&b""[..], Value::Int(value_node!(1))) ); assert_eq!(number(&b".1"[..]), - IResult::Done(&b""[..], Value::Float(make_value_node(0.1))) ); + IResult::Done(&b""[..], Value::Float(value_node!(0.1))) ); } #[test] fn test_symbol_parsing() { assert_eq!(symbol(&b"foo"[..]), - IResult::Done(&b""[..], Value::Symbol(make_value_node("foo".to_string()))) ); + IResult::Done(&b""[..], Value::Symbol(value_node!("foo".to_string()))) ); assert_eq!(symbol(&b"foo-bar"[..]), - IResult::Done(&b""[..], Value::Symbol(make_value_node("foo-bar".to_string()))) ); + IResult::Done(&b""[..], Value::Symbol(value_node!("foo-bar".to_string()))) ); assert_eq!(symbol(&b"foo_bar"[..]), - IResult::Done(&b""[..], Value::Symbol(make_value_node("foo_bar".to_string()))) ); + IResult::Done(&b""[..], Value::Symbol(value_node!("foo_bar".to_string()))) ); } #[test] @@ -1007,14 +1021,14 @@ mod test { }, Statement::Let{ name: "foo".to_string(), - value: Expression::Simple(Value::Int(make_value_node(1))) + value: Expression::Simple(Value::Int(value_node!(1))) }, Statement::Expression( 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(value_node!(1)), + right: Box::new(Expression::Simple(Value::Int(value_node!(1)))), pos: None, }) )