diff --git a/src/ast.rs b/src/ast.rs index 4c760e5..4c14503 100644 --- a/src/ast.rs +++ b/src/ast.rs @@ -25,7 +25,7 @@ use std::hash::Hasher; use std::hash::Hash; /// Encodes a parsing error with position information and a helpful description. -#[derive(Debug,PartialEq)] +#[derive(Debug, PartialEq)] pub struct ParseError { pub pos: Position, pub description: String, @@ -33,11 +33,11 @@ pub struct ParseError { impl std::fmt::Display for ParseError { fn fmt(&self, f: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> { - write!(f, - "Parsing Error {} at line: {} column: {}", - self.description, - self.pos.line, - self.pos.column) + write!( + f, + "Parsing Error {} at line: {} column: {}", + self.description, self.pos.line, self.pos.column + ) } } @@ -47,7 +47,6 @@ impl std::error::Error for ParseError { } } - macro_rules! enum_type_equality { ( $slf:ident, $r:expr, $( $l:pat ),* ) => { match $slf { @@ -65,10 +64,10 @@ macro_rules! enum_type_equality { } /// Represents a line and a column position in UCG code. -/// +/// /// It is used for generating error messages mostly. Most all /// parts of the UCG AST have a positioned associated with them. -#[derive(Debug,PartialEq,Eq,Clone,PartialOrd,Ord,Hash)] +#[derive(Debug, PartialEq, Eq, Clone, PartialOrd, Ord, Hash)] pub struct Position { pub line: usize, pub column: usize, @@ -85,7 +84,7 @@ impl Position { } /// Defines the types of tokens in UCG syntax. -#[derive(Debug,PartialEq,Eq,Clone,PartialOrd,Ord,Hash)] +#[derive(Debug, PartialEq, Eq, Clone, PartialOrd, Ord, Hash)] pub enum TokenType { END, WS, @@ -99,9 +98,9 @@ pub enum TokenType { // FIXME(jwall): We should probably implement copy for this. /// Defines a Token representing a building block of UCG syntax. -/// +/// /// Token's are passed to the parser stage to be parsed into an AST. -#[derive(Debug,PartialEq,Eq,Clone,PartialOrd,Ord,Hash)] +#[derive(Debug, PartialEq, Eq, Clone, PartialOrd, Ord, Hash)] pub struct Token { pub typ: TokenType, pub fragment: String, @@ -146,27 +145,27 @@ macro_rules! make_tok { ( EOF => $l:expr, $c:expr ) => { Token::new("", TokenType::END, $l, $c) }; - + ( WS => $l:expr, $c:expr ) => { Token::new("", TokenType::WS, $l, $c) }; - + ( CMT => $e:expr, $l:expr, $c:expr ) => { Token::new($e, TokenType::COMMENT, $l, $c) }; - + ( QUOT => $e:expr, $l:expr, $c:expr ) => { Token::new($e, TokenType::QUOTED, $l, $c) }; - + ( PUNCT => $e:expr, $l:expr, $c:expr ) => { Token::new($e, TokenType::PUNCT, $l, $c) }; - + ( DIGIT => $e:expr, $l:expr, $c:expr ) => { Token::new($e, TokenType::DIGIT, $l, $c) }; - + ( $e:expr, $l:expr, $c:expr ) => { Token::new($e, TokenType::BAREWORD, $l, $c) }; @@ -182,7 +181,7 @@ macro_rules! make_expr { ( $e:expr, $l:expr, $c:expr ) => { Expression::Simple(Value::Symbol(Positioned::new($e.to_string(), $l, $c))) }; - + ( $e:expr => int, $l:expr, $c:expr ) => { Expression::Simple(Value::Int(Positioned::new($e, $l, $c))) }; @@ -223,15 +222,15 @@ macro_rules! make_selector { make_selector!($h => [ $( $item, )* ] => 1, 1) } }; - + ( $h:expr => [ $( $item:expr ),* ] => $l:expr, $c:expr ) => { { let mut list: Vec = Vec::new(); - + $( list.push($item); )* - + make_selector!($h, list, $l, $c) } }; @@ -242,25 +241,25 @@ macro_rules! make_selector { let mut col = 1; let mut list: Vec = Vec::new(); - + $( list.push(make_tok!($item, 1, col)); col += $item.len() + 1; )* - + // Shut up the lint about unused code; assert!(col != 0); - make_selector!($h, list, 1, 1) + make_selector!($h, list, 1, 1) } }; - + ( $h:expr => $( $item:expr ),* => $l:expr, $c:expr ) => { { let mut col = $c; let mut list: Vec = Vec::new(); - + $( list.push(make_tok!($item, $l, col)); col += $item.len() + 1; @@ -269,7 +268,7 @@ macro_rules! make_selector { // Shut up the linter about unused code; assert!(col != 0); - make_selector!($h, list, $l, $c) + make_selector!($h, list, $l, $c) } }; } @@ -290,7 +289,7 @@ macro_rules! make_selector { /// let berry = {best = "strawberry", unique = "acai"}.best; /// let third = ["uno", "dos", "tres"].1; /// ''' -#[derive(Debug,PartialEq,Clone)] +#[derive(Debug, PartialEq, Clone)] pub struct SelectorList { pub head: Box, pub tail: Option>, @@ -304,12 +303,12 @@ impl SelectorList { } /// An ordered list of Name = Value pairs. -/// +/// /// This is usually used as the body of a tuple in the UCG AST. pub type FieldList = Vec<(Token, Expression)>; // Token is expected to be a symbol /// Encodes a selector expression in the UCG AST. -#[derive(Debug,PartialEq,Clone)] +#[derive(Debug, PartialEq, Clone)] pub struct SelectorDef { pub pos: Position, pub sel: SelectorList, @@ -326,7 +325,7 @@ impl SelectorDef { } /// Represents a Value in the UCG parsed AST. -#[derive(Debug,PartialEq,Clone)] +#[derive(Debug, PartialEq, Clone)] pub enum Value { // Constant Values Int(Positioned), @@ -397,19 +396,23 @@ impl Value { /// Returns true if called on a Value that is the same type as itself. pub fn type_equal(&self, target: &Self) -> bool { - enum_type_equality!(self, target, &Value::Int(_), - &Value::Float(_), - &Value::String(_), - &Value::Symbol(_), - &Value::Tuple(_), - &Value::List(_), - &Value::Selector(_)) + enum_type_equality!( + self, + target, + &Value::Int(_), + &Value::Float(_), + &Value::String(_), + &Value::Symbol(_), + &Value::Tuple(_), + &Value::List(_), + &Value::Selector(_) + ) } } /// Represents an expansion of a Macro that is expected to already have been /// defined. -#[derive(PartialEq,Debug,Clone)] +#[derive(PartialEq, Debug, Clone)] pub struct CallDef { pub macroref: SelectorDef, pub arglist: Vec, @@ -417,7 +420,7 @@ pub struct CallDef { } /// Encodes a select expression in the UCG AST. -#[derive(PartialEq,Debug,Clone)] +#[derive(PartialEq, Debug, Clone)] pub struct SelectDef { pub val: Box, pub default: Box, @@ -428,7 +431,7 @@ pub struct SelectDef { // TODO(jwall): This should have a way of rendering with position information. /// Adds position information to any type `T`. -#[derive(Debug,Clone)] +#[derive(Debug, Clone)] pub struct Positioned { pub pos: Position, pub val: T, @@ -495,7 +498,7 @@ impl<'a> From<&'a Positioned> for Positioned { /// A macro is a pure function over a tuple. /// MacroDefs are not closures. They can not reference /// any values except what is defined in their arguments. -#[derive(PartialEq,Debug,Clone)] +#[derive(PartialEq, Debug, Clone)] pub struct MacroDef { pub argdefs: Vec>, pub fields: FieldList, @@ -512,10 +515,11 @@ impl MacroDef { return false; } - fn validate_value_symbols<'a>(&self, - stack: &mut Vec<&'a Expression>, - val: &'a Value) - -> HashSet { + fn validate_value_symbols<'a>( + &self, + stack: &mut Vec<&'a Expression>, + val: &'a Value, + ) -> HashSet { let mut bad_symbols = HashSet::new(); if let &Value::Symbol(ref name) = val { if !self.symbol_is_in_args(&name.val) { @@ -572,11 +576,9 @@ impl MacroDef { stack.push(expr); } } - &Expression::Call(ref def) => { - for expr in def.arglist.iter() { - stack.push(expr); - } - } + &Expression::Call(ref def) => for expr in def.arglist.iter() { + stack.push(expr); + }, &Expression::Simple(ref val) => { let mut syms_set = self.validate_value_symbols(&mut stack, val); bad_symbols.extend(syms_set.drain()); @@ -597,7 +599,7 @@ impl MacroDef { /// Specifies the types of binary operations supported in /// UCG expression. -#[derive(Debug,PartialEq,Clone)] +#[derive(Debug, PartialEq, Clone)] pub enum BinaryExprType { Add, Sub, @@ -606,7 +608,7 @@ pub enum BinaryExprType { } /// Represents an expression with a left and a right side. -#[derive(Debug,PartialEq,Clone)] +#[derive(Debug, PartialEq, Clone)] pub struct BinaryOpDef { pub kind: BinaryExprType, pub left: Value, @@ -615,7 +617,7 @@ pub struct BinaryOpDef { } /// Encodes a tuple Copy expression in the UCG AST. -#[derive(Debug,PartialEq,Clone)] +#[derive(Debug, PartialEq, Clone)] pub struct CopyDef { pub selector: SelectorDef, pub fields: FieldList, @@ -623,7 +625,7 @@ pub struct CopyDef { } /// Encodes a format expression in the UCG AST. -#[derive(Debug,PartialEq,Clone)] +#[derive(Debug, PartialEq, Clone)] pub struct FormatDef { pub template: String, pub args: Vec, @@ -631,14 +633,14 @@ pub struct FormatDef { } /// Encodes a list expression in the UCG AST. -#[derive(Debug,PartialEq,Clone)] +#[derive(Debug, PartialEq, Clone)] pub struct ListDef { pub elems: Vec, pub pos: Position, } /// Encodes a ucg expression. Expressions compute a value from. -#[derive(Debug,PartialEq,Clone)] +#[derive(Debug, PartialEq, Clone)] pub enum Expression { // Base Expression Simple(Value), @@ -672,21 +674,21 @@ impl Expression { } /// Encodes a let statement in the UCG AST. -#[derive(Debug,PartialEq)] +#[derive(Debug, PartialEq)] pub struct LetDef { pub name: Token, pub value: Expression, } /// Encodes an import statement in the UCG AST. -#[derive(Debug,PartialEq)] +#[derive(Debug, PartialEq)] pub struct ImportDef { pub path: Token, pub name: Token, } /// Encodes a parsed statement in the UCG AST. -#[derive(Debug,PartialEq)] +#[derive(Debug, PartialEq)] pub enum Statement { // simple expression Expression(Expression), @@ -707,12 +709,15 @@ mod ast_test { let def = MacroDef { argdefs: vec![value_node!("foo".to_string(), 1, 0)], fields: vec![ - (make_tok!("f1", 1, 1), Expression::Binary(BinaryOpDef{ - kind: BinaryExprType::Add, - left: Value::Symbol(value_node!("foo".to_string(), 1, 1)), - right: Box::new(Expression::Simple(Value::Int(value_node!(1, 1, 1)))), - pos: Position::new(1, 0), - })), + ( + make_tok!("f1", 1, 1), + Expression::Binary(BinaryOpDef { + kind: BinaryExprType::Add, + left: Value::Symbol(value_node!("foo".to_string(), 1, 1)), + right: Box::new(Expression::Simple(Value::Int(value_node!(1, 1, 1)))), + pos: Position::new(1, 0), + }), + ), ], pos: Position::new(1, 0), }; @@ -724,12 +729,15 @@ mod ast_test { let def = MacroDef { argdefs: vec![value_node!("foo".to_string(), 1, 0)], fields: vec![ - (make_tok!("f1", 1, 1), Expression::Binary(BinaryOpDef{ - kind: BinaryExprType::Add, - left: Value::Symbol(value_node!("bar".to_string(), 1, 1)), - right: Box::new(Expression::Simple(Value::Int(value_node!(1, 1, 1)))), - pos: Position::new(1, 0), - })), + ( + make_tok!("f1", 1, 1), + Expression::Binary(BinaryOpDef { + kind: BinaryExprType::Add, + left: Value::Symbol(value_node!("bar".to_string(), 1, 1)), + right: Box::new(Expression::Simple(Value::Int(value_node!(1, 1, 1)))), + pos: Position::new(1, 0), + }), + ), ], pos: Position::new(1, 0), }; @@ -743,13 +751,16 @@ mod ast_test { let def = MacroDef { argdefs: vec![value_node!("foo".to_string(), 1, 0)], fields: vec![ - (make_tok!("f1", 1, 1), Expression::Binary(BinaryOpDef{ - kind: BinaryExprType::Add, - left: Value::Selector(make_selector!(make_expr!("foo", 1, 1) => [ + ( + make_tok!("f1", 1, 1), + Expression::Binary(BinaryOpDef { + kind: BinaryExprType::Add, + left: Value::Selector(make_selector!(make_expr!("foo", 1, 1) => [ make_tok!("quux", 1, 1) ] => 1, 1)), - right: Box::new(Expression::Simple(Value::Int(value_node!(1, 1, 1)))), - pos: Position::new(1, 0), - })), + right: Box::new(Expression::Simple(Value::Int(value_node!(1, 1, 1)))), + pos: Position::new(1, 0), + }), + ), ], pos: Position::new(1, 0), }; @@ -761,13 +772,16 @@ mod ast_test { let def = MacroDef { argdefs: vec![value_node!("foo".to_string(), 1, 0)], fields: vec![ - (make_tok!("f1", 1, 1), Expression::Binary(BinaryOpDef{ - kind: BinaryExprType::Add, - left: Value::Selector(make_selector!(make_expr!("bar", 1, 1) => [ + ( + make_tok!("f1", 1, 1), + Expression::Binary(BinaryOpDef { + kind: BinaryExprType::Add, + left: Value::Selector(make_selector!(make_expr!("bar", 1, 1) => [ make_tok!("quux", 1, 1) ] => 1, 1)), - right: Box::new(Expression::Simple(Value::Int(value_node!(1, 1, 1)))), - pos: Position::new(1, 0), - })), + right: Box::new(Expression::Simple(Value::Int(value_node!(1, 1, 1)))), + pos: Position::new(1, 0), + }), + ), ], pos: Position::new(1, 0), }; diff --git a/src/convert/json.rs b/src/convert/json.rs index 70e8f9e..6076d2a 100644 --- a/src/convert/json.rs +++ b/src/convert/json.rs @@ -34,12 +34,14 @@ impl JsonConverter { Ok(serde_json::Value::Array(v)) } - fn convert_tuple(&self, - items: &Vec<(ast::Positioned, Rc)>) - -> Result { + fn convert_tuple( + &self, + items: &Vec<(ast::Positioned, Rc)>, + ) -> Result { let mut mp = serde_json::Map::new(); for &(ref k, ref v) in items.iter() { - mp.entry(k.val.clone()).or_insert(try!(self.convert_value(v))); + mp.entry(k.val.clone()) + .or_insert(try!(self.convert_value(v))); } Ok(serde_json::Value::Object(mp)) } diff --git a/src/error.rs b/src/error.rs index f0635e2..3a6a25e 100644 --- a/src/error.rs +++ b/src/error.rs @@ -75,10 +75,7 @@ impl fmt::Debug for Error { write!( w, "{}: \"{}\" {}:{}", - self.err_type, - self.msg, - self.pos.line, - self.pos.column + self.err_type, self.msg, self.pos.line, self.pos.column ) } } @@ -88,10 +85,7 @@ impl fmt::Display for Error { write!( w, "{}: \"{}\" {}:{}", - self.err_type, - self.msg, - self.pos.line, - self.pos.column + self.err_type, self.msg, self.pos.line, self.pos.column ) } } diff --git a/src/format.rs b/src/format.rs index 4ab1155..4f8f627 100644 --- a/src/format.rs +++ b/src/format.rs @@ -35,7 +35,7 @@ impl + Clone> Formatter { } /// Renders a formatter to a string or returns an error. - /// + /// /// If the formatter has the wrong number of arguments for the number of replacements /// it will return an error. Otherwise it will return the formatted string. pub fn render(&self, pos: &Position) -> Result> { @@ -45,10 +45,12 @@ impl + Clone> Formatter { for c in self.tmpl.chars() { if c == '@' && !should_escape { if count == self.args.len() { - return Err(Box::new(error::Error::new("Too few arguments to string \ - formatter.", - error::ErrorType::FormatError, - pos.clone()))); + return Err(Box::new(error::Error::new( + "Too few arguments to string \ + formatter.", + error::ErrorType::FormatError, + pos.clone(), + ))); } let arg = self.args[count].clone(); let strval = arg.into(); @@ -61,10 +63,12 @@ impl + Clone> Formatter { } } if self.args.len() != count { - return Err(Box::new(error::Error::new("Too many arguments to string \ - formatter.", - error::ErrorType::FormatError, - pos.clone()))); + return Err(Box::new(error::Error::new( + "Too many arguments to string \ + formatter.", + error::ErrorType::FormatError, + pos.clone(), + ))); } return Ok(buf); } @@ -78,30 +82,21 @@ mod test { #[test] fn test_format_happy_path() { let formatter = Formatter::new("foo @ @ \\@", vec!["bar", "quux"]); - let pos = Position { - line: 0, - column: 0, - }; + let pos = Position { line: 0, column: 0 }; assert_eq!(formatter.render(&pos).unwrap(), "foo bar quux @"); } #[test] fn test_format_happy_wrong_too_few_args() { let formatter = Formatter::new("foo @ @ \\@", vec!["bar"]); - let pos = Position { - line: 0, - column: 0, - }; + let pos = Position { line: 0, column: 0 }; assert!(formatter.render(&pos).is_err()); } #[test] fn test_format_happy_wrong_too_many_args() { let formatter = Formatter::new("foo @ @ \\@", vec!["bar", "quux", "baz"]); - let pos = Position { - line: 0, - column: 0, - }; + let pos = Position { line: 0, column: 0 }; assert!(formatter.render(&pos).is_err()); } } diff --git a/src/lib.rs b/src/lib.rs index 5d639c1..9a4a8a5 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -151,39 +151,39 @@ //! ``` //! //! #### Copy expressions -//! +//! //! ucg Tuples support a form of reuse with copy on write semantics. You can copy a tuple and selectively overwrite fields or add new //! fields to it with the copy expression. To perform a copy first reference the tuple by a bound name and then use `{ field = value, ... }` //! syntax to copy with overridden fields or add completely new fields. When replacing a preexisting field with a new value you cannot //! change the type of the field. This allows you to define a typed shape for a tuple with default values and then provide new values for //! some or all of the fields while still enforcing the same types for those fields. Adding completely new fields has no such restriction. -//! +//! //! ```ucg //! let base = { //! field1 = "value1", //! field2 = 100, //! field3 = 5.6, //! }; -//! +//! //! let overridden = base{ //! field1 = "new value" //! }; -//! +//! //! let expanded = base{ //! field2 = 200, //! field3 = "look ma a new field", //! }; //! ``` -//! +//! //! The following will cause an error because the overriden field's value does not match the original. -//! +//! //! ```ucg //! let bad = base{ //! field1 = 300, // Error!!! must be a string. //! }; -//! +//! //! ``` -//! +//! //! #### Conditional data //! //! ucg supports a limited form of conditional data selection of using the select expression. A select expression starts with the `select` @@ -232,7 +232,7 @@ //! All ucg statements must be terminated by a semicolon. //! //! * expression statements -//! +//! //! The simplest and least useful is the expression statement. It is any valid expression followed by a semicolon. //! //! ```ucg @@ -246,7 +246,7 @@ //! ever create a repl for ucg statements they may prove more useful. //! //! * Let statements -//! +//! //! The let expression binds the result of any valid expression to a name. It starts with the `let` keyword and is followed by //! the name of the binding, an `=`, and a valid ucg expression. //! @@ -255,7 +255,7 @@ //! ``` //! //! * Import statement -//! +//! //! The import statement imports the contents of another ucg file into the current file with a name. The imported files bound //! values are exposed as a tuple in the referencing file. It starts with the `import` keyword and is followed by a quoted path //! to the ucg file, the keyword `as`, and a name for the imported values. diff --git a/src/parse.rs b/src/parse.rs index cdb68f4..ef352e4 100644 --- a/src/parse.rs +++ b/src/parse.rs @@ -29,7 +29,10 @@ type NomResult<'a, O> = nom::IResult, O, ParseError>; type ParseResult = Result; fn symbol_to_value(s: &Token) -> ParseResult { - Ok(Value::Symbol(value_node!(s.fragment.to_string(), s.pos.clone()))) + Ok(Value::Symbol(value_node!( + s.fragment.to_string(), + s.pos.clone() + ))) } // symbol is a bare unquoted field. @@ -38,7 +41,10 @@ named!(symbol, ); fn str_to_value(s: &Token) -> ParseResult { - Ok(Value::String(value_node!(s.fragment.to_string(), s.pos.clone()))) + Ok(Value::String(value_node!( + s.fragment.to_string(), + s.pos.clone() + ))) } // quoted_value is a quoted string. @@ -144,8 +150,11 @@ named!( // Helper function to make the return types work for down below. fn vec_to_tuple(t: (Position, Option)) -> ParseResult { - Ok(Value::Tuple(value_node!(t.1.unwrap_or(Vec::new()), - t.0.line as usize, t.0.column as usize))) + Ok(Value::Tuple(value_node!( + t.1.unwrap_or(Vec::new()), + t.0.line as usize, + t.0.column as usize + ))) } named!(field_list, @@ -206,8 +215,9 @@ named!(simple_expression, ) ); -fn tuple_to_binary_expression(tpl: (Position, BinaryExprType, Value, Expression)) - -> ParseResult { +fn tuple_to_binary_expression( + tpl: (Position, BinaryExprType, Value, Expression), +) -> ParseResult { Ok(Expression::Binary(BinaryOpDef { kind: tpl.1, left: tpl.2, @@ -265,10 +275,7 @@ named!(grouped_expression, ); fn symbol_or_expression(input: TokenIter) -> NomResult { - let sym = do_parse!(input, - sym: symbol >> - (sym) - ); + let sym = do_parse!(input, sym: symbol >> (sym)); match sym { IResult::Incomplete(i) => { @@ -304,10 +311,12 @@ fn selector_list(input: TokenIter) -> NomResult { }; let (rest, list) = if is_dot.is_some() { - let (rest, list) = match separated_list!(rest, punct!("."), alt!(match_type!(BAREWORD) | match_type!(DIGIT))) { - IResult::Done(rest, val) => { - (rest, val) - } + let (rest, list) = match separated_list!( + rest, + punct!("."), + alt!(match_type!(BAREWORD) | match_type!(DIGIT)) + ) { + IResult::Done(rest, val) => (rest, val), IResult::Incomplete(i) => { return IResult::Incomplete(i); } @@ -361,28 +370,22 @@ named!(copy_expression, fn tuple_to_macro(mut t: (Position, Vec, Value)) -> ParseResult { match t.2 { - Value::Tuple(v) => { - Ok(Expression::Macro(MacroDef { - argdefs: t.1 - .drain(0..) - .map(|s| { - Positioned { - pos: s.pos().clone(), - val: s.to_string(), - } - }) - .collect(), - fields: v.val, - pos: t.0, - })) - } + Value::Tuple(v) => Ok(Expression::Macro(MacroDef { + argdefs: t.1 + .drain(0..) + .map(|s| Positioned { + pos: s.pos().clone(), + val: s.to_string(), + }) + .collect(), + fields: v.val, + pos: t.0, + })), // TODO(jwall): Show a better version of the unexpected parsed value. - val => { - Err(ParseError { - description: format!("Expected Tuple Got {:?}", val), - pos: t.0, - }) - } + val => Err(ParseError { + description: format!("Expected Tuple Got {:?}", val), + pos: t.0, + }), } } @@ -406,20 +409,16 @@ named!(macro_expression, fn tuple_to_select(t: (Position, Expression, Expression, Value)) -> ParseResult { match t.3 { - Value::Tuple(v) => { - Ok(Expression::Select(SelectDef { - val: Box::new(t.1), - default: Box::new(t.2), - tuple: v.val, - pos: t.0, - })) - } - val => { - Err(ParseError { - description: format!("Expected Tuple Got {:?}", val), - pos: t.0, - }) - } + Value::Tuple(v) => Ok(Expression::Select(SelectDef { + val: Box::new(t.1), + default: Box::new(t.2), + tuple: v.val, + pos: t.0, + })), + val => Err(ParseError { + description: format!("Expected Tuple Got {:?}", val), + pos: t.0, + }), } } @@ -474,7 +473,11 @@ fn tuple_to_call(t: (Position, Value, Vec)) -> ParseResult ParseResult { - Ok(Value::Selector(SelectorDef::new(t.1, t.0.line as usize, t.0.column as usize))) + Ok(Value::Selector(SelectorDef::new( + t.1, + t.0.line as usize, + t.0.column as usize, + ))) } named!(selector_value, @@ -598,7 +601,9 @@ pub fn parse(input: LocatedSpan<&str>) -> Result, ParseError> { match tokenize(input) { Ok(tokenized) => { let mut out = Vec::new(); - let mut i_ = TokenIter { source: tokenized.as_slice() }; + let mut i_ = TokenIter { + source: tokenized.as_slice(), + }; loop { let i = i_.clone(); if i[0].typ == TokenType::END { @@ -610,8 +615,10 @@ pub fn parse(input: LocatedSpan<&str>) -> Result, ParseError> { } IResult::Error(e) => { return Err(ParseError { - description: - format!("Tokenization error: {:?} current token: {:?}", e, i_[0]), + description: format!( + "Tokenization error: {:?} current token: {:?}", + e, i_[0] + ), pos: Position { line: i_[0].pos.line, column: i_[0].pos.column, @@ -643,10 +650,7 @@ pub fn parse(input: LocatedSpan<&str>) -> Result, ParseError> { // of the tokenization error here. return Err(ParseError { description: format!("Tokenize Error: {:?}", e), - pos: Position { - line: 0, - column: 0, - }, + pos: Position { line: 0, column: 0 }, }); } } @@ -655,7 +659,7 @@ pub fn parse(input: LocatedSpan<&str>) -> Result, ParseError> { #[cfg(test)] mod test { use super::*; - use tokenizer::{TokenIter, tokenize}; + use tokenizer::{tokenize, TokenIter}; use nom_locate::LocatedSpan; use nom::IResult; @@ -700,71 +704,88 @@ mod test { #[test] fn test_symbol_parsing() { - assert_parse!(symbol("foo"), - Value::Symbol(value_node!("foo".to_string(), 1, 1)) ); - assert_parse!(symbol("foo-bar"), - Value::Symbol(value_node!("foo-bar".to_string(), 1, 1)) ); - assert_parse!(symbol("foo_bar"), - Value::Symbol(value_node!("foo_bar".to_string(), 1, 1)) ); + assert_parse!( + symbol("foo"), + Value::Symbol(value_node!("foo".to_string(), 1, 1)) + ); + assert_parse!( + symbol("foo-bar"), + Value::Symbol(value_node!("foo-bar".to_string(), 1, 1)) + ); + assert_parse!( + symbol("foo_bar"), + Value::Symbol(value_node!("foo_bar".to_string(), 1, 1)) + ); } #[test] fn test_selector_parsing() { assert_error!(selector_value("foo.")); - assert_parse!(selector_value("foo.bar "), - Value::Selector(make_selector!(make_expr!("foo".to_string(), 1, 1) => [ + assert_parse!( + selector_value("foo.bar "), + Value::Selector(make_selector!(make_expr!("foo".to_string(), 1, 1) => [ make_tok!("bar", 1, 5)] => 1, 1)) ); - assert_parse!(selector_value("foo.0 "), - Value::Selector(make_selector!(make_expr!("foo".to_string(), 1, 1) => [ + assert_parse!( + selector_value("foo.0 "), + Value::Selector(make_selector!(make_expr!("foo".to_string(), 1, 1) => [ make_tok!(DIGIT => "0", 1, 5)] => 1, 1)) ); - assert_parse!(selector_value("foo.bar;"), + assert_parse!( + selector_value("foo.bar;"), Value::Selector(make_selector!(make_expr!("foo", 1, 1) => [ make_tok!("bar", 1, 5) ] => 1, 1)) ); - assert_parse!(selector_value("({foo=1}).foo "), - Value::Selector(make_selector!(Expression::Grouped(Box::new(Expression::Simple( + assert_parse!( + selector_value("({foo=1}).foo "), + Value::Selector( + make_selector!(Expression::Grouped(Box::new(Expression::Simple( Value::Tuple(value_node!( vec![(make_tok!("foo", 1, 3), Expression::Simple(Value::Int(Positioned::new(1, 1, 7))))], 1, 3)) ))) => [ make_tok!("foo", 1, 11) ] => 1, 2) - )); + ) + ); } #[test] fn test_statement_parse() { let stmt = "import \"foo\" as foo;"; - assert_parse!(statement(stmt), - Statement::Import(ImportDef{ - path: make_tok!(QUOT => "foo", 1,8), - name: make_tok!("foo", 1,17), - } - ) + assert_parse!( + statement(stmt), + Statement::Import(ImportDef { + path: make_tok!(QUOT => "foo", 1,8), + name: make_tok!("foo", 1, 17), + }) ); - assert_error!(import_statement("import \"foo\"") ); + assert_error!(import_statement("import \"foo\"")); - assert_parse!(statement("let foo = 1.0 ;"), - Statement::Let(LetDef{ - name: make_tok!("foo", 1, 5), - value: Expression::Simple(Value::Float(value_node!(1.0, 1, 11))) - })); + assert_parse!( + statement("let foo = 1.0 ;"), + Statement::Let(LetDef { + name: make_tok!("foo", 1, 5), + value: Expression::Simple(Value::Float(value_node!(1.0, 1, 11))), + }) + ); - assert_parse!(statement("// comment\nlet foo = 1.0 ;"), - Statement::Let(LetDef{ - name: make_tok!("foo", 2, 5), - value: Expression::Simple(Value::Float(value_node!(1.0, 2, 11))) - })); + assert_parse!( + statement("// comment\nlet foo = 1.0 ;"), + Statement::Let(LetDef { + name: make_tok!("foo", 2, 5), + value: Expression::Simple(Value::Float(value_node!(1.0, 2, 11))), + }) + ); - assert_parse!(statement("1.0;"), - Statement::Expression( - Expression::Simple(Value::Float(value_node!(1.0, 1, 1)))) ); + assert_parse!( + statement("1.0;"), + Statement::Expression(Expression::Simple(Value::Float(value_node!(1.0, 1, 1)))) + ); } #[test] @@ -775,174 +796,270 @@ mod test { assert_error!(import_statement("import \"foo\" as foo")); let import_stmt = "import \"foo\" as foo;"; - assert_parse!(import_statement(import_stmt), - Statement::Import(ImportDef{ - path: make_tok!(QUOT => "foo", 1, 8), - name: make_tok!("foo", 1,17), - }) + assert_parse!( + import_statement(import_stmt), + Statement::Import(ImportDef { + path: make_tok!(QUOT => "foo", 1, 8), + name: make_tok!("foo", 1, 17), + }) ); } #[test] fn test_let_statement_parse() { - assert_error!(let_statement("foo") ); - assert_error!(let_statement("let \"foo\"") ); - assert_error!(let_statement("let 1") ); - assert_error!(let_statement("let") ); - assert_error!(let_statement("let foo") ); - assert_error!(let_statement("let foo =") ); - assert_error!(let_statement("let foo = ") ); - assert_error!(let_statement("let foo = 1") ); + assert_error!(let_statement("foo")); + assert_error!(let_statement("let \"foo\"")); + assert_error!(let_statement("let 1")); + assert_error!(let_statement("let")); + assert_error!(let_statement("let foo")); + assert_error!(let_statement("let foo =")); + assert_error!(let_statement("let foo = ")); + assert_error!(let_statement("let foo = 1")); - assert_parse!(let_statement("let foo = 1.0 ;"), - Statement::Let(LetDef{name: make_tok!("foo", 1,5), - value: Expression::Simple(Value::Float(value_node!(1.0, 1, 11))) - })); + assert_parse!( + let_statement("let foo = 1.0 ;"), + Statement::Let(LetDef { + name: make_tok!("foo", 1, 5), + value: Expression::Simple(Value::Float(value_node!(1.0, 1, 11))), + }) + ); - assert_parse!(let_statement("let foo = // comment\n1.0 ;"), - Statement::Let(LetDef{name: make_tok!("foo", 1,5), - value: Expression::Simple(Value::Float(value_node!(1.0, 2, 1))) - })); + assert_parse!( + let_statement("let foo = // comment\n1.0 ;"), + Statement::Let(LetDef { + name: make_tok!("foo", 1, 5), + value: Expression::Simple(Value::Float(value_node!(1.0, 2, 1))), + }) + ); - assert_parse!(let_statement("let foo = 1.0 // comment\n;"), - Statement::Let(LetDef{name: make_tok!("foo", 1,5), - value: Expression::Simple(Value::Float(value_node!(1.0, 1, 11))) - })); + assert_parse!( + let_statement("let foo = 1.0 // comment\n;"), + Statement::Let(LetDef { + name: make_tok!("foo", 1, 5), + value: Expression::Simple(Value::Float(value_node!(1.0, 1, 11))), + }) + ); - assert_parse!(let_statement("let foo= 1.0;"), - Statement::Let(LetDef{name: make_tok!("foo", 1, 5), - value: Expression::Simple(Value::Float(value_node!(1.0, 1, 10)))}) ); + assert_parse!( + let_statement("let foo= 1.0;"), + Statement::Let(LetDef { + name: make_tok!("foo", 1, 5), + value: Expression::Simple(Value::Float(value_node!(1.0, 1, 10))), + }) + ); - assert_parse!(let_statement("let foo =1.0;"), - Statement::Let(LetDef{name: make_tok!("foo", 1,5), - value: Expression::Simple(Value::Float(value_node!(1.0, 1, 10)))})); + assert_parse!( + let_statement("let foo =1.0;"), + Statement::Let(LetDef { + name: make_tok!("foo", 1, 5), + value: Expression::Simple(Value::Float(value_node!(1.0, 1, 10))), + }) + ); } #[test] fn test_expression_statement_parse() { - assert_error!(expression_statement("foo") ); - assert_parse!(expression_statement("1.0;"), - Statement::Expression( - Expression::Simple(Value::Float(value_node!(1.0, 1, 1))))); - assert_parse!(expression_statement("1.0 ;"), - Statement::Expression( - Expression::Simple(Value::Float(value_node!(1.0, 1, 1))))); - assert_parse!(expression_statement(" 1.0;"), - Statement::Expression( - Expression::Simple(Value::Float(value_node!(1.0, 1, 2))))); - assert_parse!(expression_statement("foo;"), - Statement::Expression( - Expression::Simple(Value::Selector(make_selector!(make_expr!("foo", 1, 1), 1, 1))))); - assert_parse!(expression_statement("foo ;"), - Statement::Expression( - Expression::Simple(Value::Selector(make_selector!(make_expr!("foo", 1, 2), 1, 1))))); - assert_parse!(expression_statement(" foo;"), - Statement::Expression( - Expression::Simple(Value::Selector(make_selector!(make_expr!("foo", 1, 2), 1, 2))))); - assert_parse!(expression_statement("\"foo\";"), - Statement::Expression( - Expression::Simple(Value::String(value_node!("foo".to_string(), 1, 1))))); - assert_parse!(expression_statement("\"foo\" ;"), - Statement::Expression( - Expression::Simple(Value::String(value_node!("foo".to_string(), 1, 1))))); - assert_parse!(expression_statement(" \"foo\";"), - Statement::Expression( - Expression::Simple(Value::String(value_node!("foo".to_string(), 1, 2))))); + assert_error!(expression_statement("foo")); + assert_parse!( + expression_statement("1.0;"), + Statement::Expression(Expression::Simple(Value::Float(value_node!(1.0, 1, 1)))) + ); + assert_parse!( + expression_statement("1.0 ;"), + Statement::Expression(Expression::Simple(Value::Float(value_node!(1.0, 1, 1)))) + ); + assert_parse!( + expression_statement(" 1.0;"), + Statement::Expression(Expression::Simple(Value::Float(value_node!(1.0, 1, 2)))) + ); + assert_parse!( + expression_statement("foo;"), + Statement::Expression(Expression::Simple(Value::Selector(make_selector!( + make_expr!("foo", 1, 1), + 1, + 1 + )))) + ); + assert_parse!( + expression_statement("foo ;"), + Statement::Expression(Expression::Simple(Value::Selector(make_selector!( + make_expr!("foo", 1, 2), + 1, + 1 + )))) + ); + assert_parse!( + expression_statement(" foo;"), + Statement::Expression(Expression::Simple(Value::Selector(make_selector!( + make_expr!("foo", 1, 2), + 1, + 2 + )))) + ); + assert_parse!( + expression_statement("\"foo\";"), + Statement::Expression(Expression::Simple(Value::String(value_node!( + "foo".to_string(), + 1, + 1 + )))) + ); + assert_parse!( + expression_statement("\"foo\" ;"), + Statement::Expression(Expression::Simple(Value::String(value_node!( + "foo".to_string(), + 1, + 1 + )))) + ); + assert_parse!( + expression_statement(" \"foo\";"), + Statement::Expression(Expression::Simple(Value::String(value_node!( + "foo".to_string(), + 1, + 2 + )))) + ); } #[test] fn test_expression_parse() { - assert_parse!(expression("\"foo\""), - Expression::Simple(Value::String(value_node!("foo".to_string(), 1, 1)))); - assert_parse!(expression("1"), - Expression::Simple(Value::Int(value_node!(1, 1, 1)))); - assert_parse!(expression("foo "), - Expression::Simple(Value::Selector(make_selector!(make_expr!("foo", 1, 1), 1, 1)))); - assert_parse!(expression("foo.bar "), - Expression::Simple(Value::Selector(make_selector!(make_expr!("foo", 1, 1) => + assert_parse!( + expression("\"foo\""), + Expression::Simple(Value::String(value_node!("foo".to_string(), 1, 1))) + ); + assert_parse!( + expression("1"), + Expression::Simple(Value::Int(value_node!(1, 1, 1))) + ); + assert_parse!( + expression("foo "), + Expression::Simple(Value::Selector(make_selector!( + make_expr!("foo", 1, 1), + 1, + 1 + ))) + ); + assert_parse!( + expression("foo.bar "), + Expression::Simple(Value::Selector(make_selector!(make_expr!("foo", 1, 1) => [ make_tok!("bar", 1, 5) ] => - 1, 1)))); - assert_parse!(expression("1 + 1"), - Expression::Binary(BinaryOpDef{ - kind: BinaryExprType::Add, - left: Value::Int(value_node!(1, 1, 1)), - right: Box::new(Expression::Simple(Value::Int(value_node!(1, 1, 5)))), - pos: Position::new( 1, 1 ), - })); - assert_parse!(expression("1 - 1"), - Expression::Binary(BinaryOpDef{ - kind: BinaryExprType::Sub, - left: Value::Int(value_node!(1, 1, 1)), - right: Box::new(Expression::Simple(Value::Int(value_node!(1, 1, 5)))), - pos: Position::new(1, 1), - })); - assert_parse!(expression("1 * 1"), - Expression::Binary(BinaryOpDef{ - kind: BinaryExprType::Mul, - left: Value::Int(value_node!(1, 1, 1)), - right: Box::new(Expression::Simple(Value::Int(value_node!(1, 1, 5)))), - pos: Position::new(1, 1), - })); - assert_parse!(expression("1 / 1"), - Expression::Binary(BinaryOpDef{ - kind: BinaryExprType::Div, - left: Value::Int(value_node!(1, 1, 1)), - right: Box::new(Expression::Simple(Value::Int(value_node!(1, 1, 5)))), - pos: Position::new(1, 1), - })); + 1, 1))) + ); + assert_parse!( + expression("1 + 1"), + Expression::Binary(BinaryOpDef { + kind: BinaryExprType::Add, + left: Value::Int(value_node!(1, 1, 1)), + right: Box::new(Expression::Simple(Value::Int(value_node!(1, 1, 5)))), + pos: Position::new(1, 1), + }) + ); + assert_parse!( + expression("1 - 1"), + Expression::Binary(BinaryOpDef { + kind: BinaryExprType::Sub, + left: Value::Int(value_node!(1, 1, 1)), + right: Box::new(Expression::Simple(Value::Int(value_node!(1, 1, 5)))), + pos: Position::new(1, 1), + }) + ); + assert_parse!( + expression("1 * 1"), + Expression::Binary(BinaryOpDef { + kind: BinaryExprType::Mul, + left: Value::Int(value_node!(1, 1, 1)), + right: Box::new(Expression::Simple(Value::Int(value_node!(1, 1, 5)))), + pos: Position::new(1, 1), + }) + ); + assert_parse!( + expression("1 / 1"), + Expression::Binary(BinaryOpDef { + kind: BinaryExprType::Div, + left: Value::Int(value_node!(1, 1, 1)), + right: Box::new(Expression::Simple(Value::Int(value_node!(1, 1, 5)))), + pos: Position::new(1, 1), + }) + ); - assert_parse!(expression("1+1"), - Expression::Binary(BinaryOpDef{ - kind: BinaryExprType::Add, - left: Value::Int(value_node!(1, 1, 1)), - right: Box::new(Expression::Simple(Value::Int(value_node!(1, 1, 3)))), - pos: Position::new(1, 1), - })); - assert_parse!(expression("1-1"), - Expression::Binary(BinaryOpDef{ - kind: BinaryExprType::Sub, - left: Value::Int(value_node!(1, 1, 1)), - right: Box::new(Expression::Simple(Value::Int(value_node!(1, 1, 3)))), - pos: Position::new(1, 1), - })); - assert_parse!(expression("1*1"), - Expression::Binary(BinaryOpDef{ - kind: BinaryExprType::Mul, - left: Value::Int(value_node!(1, 1, 1)), - right: Box::new(Expression::Simple(Value::Int(value_node!(1, 1, 3)))), - pos: Position::new(1, 1), - })); - assert_parse!(expression("1/1"), - Expression::Binary(BinaryOpDef{ - kind: BinaryExprType::Div, - left: Value::Int(value_node!(1, 1, 1)), - right: Box::new(Expression::Simple(Value::Int(value_node!(1, 1, 3)))), - pos: Position::new(1, 1), - })); - assert_parse!(expression("macro (arg1, arg2) => { foo = arg1 }"), - Expression::Macro(MacroDef{ - argdefs: vec![ - value_node!("arg1".to_string(), 1, 8), - value_node!("arg2".to_string(), 1, 14), - ], - fields: vec![ - (make_tok!("foo", 1, 25), - Expression::Simple(Value::Selector(make_selector!(make_expr!("arg1", 1, 31), 1, 31)))), - ], - pos: Position::new(1, 1), - })); - assert_parse!(expression("select foo, 1, { foo = 2 }"), - Expression::Select(SelectDef{ - val: Box::new(Expression::Simple(Value::Selector(make_selector!(make_expr!("foo", 1, 8), 1, 8)))), - default: Box::new(Expression::Simple(Value::Int(value_node!(1, 1, 13)))), - tuple: vec![ - (make_tok!("foo", 1, 18), - Expression::Simple(Value::Int(value_node!(2, 1, 24)))) + assert_parse!( + expression("1+1"), + Expression::Binary(BinaryOpDef { + kind: BinaryExprType::Add, + left: Value::Int(value_node!(1, 1, 1)), + right: Box::new(Expression::Simple(Value::Int(value_node!(1, 1, 3)))), + pos: Position::new(1, 1), + }) + ); + assert_parse!( + expression("1-1"), + Expression::Binary(BinaryOpDef { + kind: BinaryExprType::Sub, + left: Value::Int(value_node!(1, 1, 1)), + right: Box::new(Expression::Simple(Value::Int(value_node!(1, 1, 3)))), + pos: Position::new(1, 1), + }) + ); + assert_parse!( + expression("1*1"), + Expression::Binary(BinaryOpDef { + kind: BinaryExprType::Mul, + left: Value::Int(value_node!(1, 1, 1)), + right: Box::new(Expression::Simple(Value::Int(value_node!(1, 1, 3)))), + pos: Position::new(1, 1), + }) + ); + assert_parse!( + expression("1/1"), + Expression::Binary(BinaryOpDef { + kind: BinaryExprType::Div, + left: Value::Int(value_node!(1, 1, 1)), + right: Box::new(Expression::Simple(Value::Int(value_node!(1, 1, 3)))), + pos: Position::new(1, 1), + }) + ); + assert_parse!( + expression("macro (arg1, arg2) => { foo = arg1 }"), + Expression::Macro(MacroDef { + argdefs: vec![ + value_node!("arg1".to_string(), 1, 8), + value_node!("arg2".to_string(), 1, 14), + ], + fields: vec![ + ( + make_tok!("foo", 1, 25), + Expression::Simple(Value::Selector(make_selector!( + make_expr!("arg1", 1, 31), + 1, + 31 + ))), + ), ], pos: Position::new(1, 1), - })); - assert_parse!(expression("foo.bar (1, \"foo\")"), - Expression::Call(CallDef{ + }) + ); + assert_parse!( + expression("select foo, 1, { foo = 2 }"), + Expression::Select(SelectDef { + val: Box::new(Expression::Simple(Value::Selector(make_selector!( + make_expr!("foo", 1, 8), + 1, + 8 + )))), + default: Box::new(Expression::Simple(Value::Int(value_node!(1, 1, 13)))), + tuple: vec![ + ( + make_tok!("foo", 1, 18), + Expression::Simple(Value::Int(value_node!(2, 1, 24))), + ), + ], + pos: Position::new(1, 1), + }) + ); + assert_parse!( + expression("foo.bar (1, \"foo\")"), + Expression::Call(CallDef { macroref: make_selector!(make_expr!("foo", 1, 1) => [ make_tok!("bar", 1, 5) ] => 1, 1), @@ -951,87 +1068,91 @@ mod test { Expression::Simple(Value::String(value_node!("foo".to_string(), 1, 13))), ], pos: Position::new(1, 1), - })); - assert_parse!(expression("(1 + 1)"), - Expression::Grouped( - Box::new( - Expression::Binary( - BinaryOpDef{ - kind: BinaryExprType::Add, - left: Value::Int(value_node!(1, 1, 2)), - right: Box::new(Expression::Simple(Value::Int(value_node!(1, 1, 6)))), - pos: Position::new(1, 2), // FIXME(jwall): grouped expressions appear to be getting positioned wrong - })))); - assert_parse!(expression("[1, 1]"), - Expression::Simple(Value::List( - ListDef{ - elems: vec![ - Expression::Simple(Value::Int(value_node!(1, 1, 2))), - Expression::Simple(Value::Int(value_node!(1, 1, 5))), - ], - pos: Position::new(1, 1), - } - ) - ) + }) + ); + assert_parse!( + expression("(1 + 1)"), + Expression::Grouped(Box::new(Expression::Binary(BinaryOpDef { + kind: BinaryExprType::Add, + left: Value::Int(value_node!(1, 1, 2)), + right: Box::new(Expression::Simple(Value::Int(value_node!(1, 1, 6)))), + pos: Position::new(1, 2), // FIXME(jwall): grouped expressions appear to be getting positioned wrong + }))) + ); + assert_parse!( + expression("[1, 1]"), + Expression::Simple(Value::List(ListDef { + elems: vec![ + Expression::Simple(Value::Int(value_node!(1, 1, 2))), + Expression::Simple(Value::Int(value_node!(1, 1, 5))), + ], + pos: Position::new(1, 1), + })) ); } #[test] fn test_format_parse() { - assert_error!(format_expression("\"foo") ); - assert_error!(format_expression("\"foo\"") ); - assert_error!(format_expression("\"foo\" %") ); - assert_error!(format_expression("\"foo\" % (, 2") ); + assert_error!(format_expression("\"foo")); + assert_error!(format_expression("\"foo\"")); + assert_error!(format_expression("\"foo\" %")); + assert_error!(format_expression("\"foo\" % (, 2")); - assert_parse!(format_expression("\"foo @ @\" % (1, 2)"), - Expression::Format( - FormatDef{ - template: "foo @ @".to_string(), - args: vec![Expression::Simple(Value::Int(value_node!(1, 1, 14))), - Expression::Simple(Value::Int(value_node!(2, 1, 17)))], - pos: Position::new(1, 1), - })); + assert_parse!( + format_expression("\"foo @ @\" % (1, 2)"), + Expression::Format(FormatDef { + template: "foo @ @".to_string(), + args: vec![ + Expression::Simple(Value::Int(value_node!(1, 1, 14))), + Expression::Simple(Value::Int(value_node!(2, 1, 17))), + ], + pos: Position::new(1, 1), + }) + ); - assert_parse!(format_expression("\"foo @ @\"%(1, 2)"), - Expression::Format( - FormatDef{ - template: "foo @ @".to_string(), - args: vec![Expression::Simple(Value::Int(value_node!(1, 1, 12))), - Expression::Simple(Value::Int(value_node!(2, 1, 15)))], - pos: Position::new(1, 1), - })); + assert_parse!( + format_expression("\"foo @ @\"%(1, 2)"), + Expression::Format(FormatDef { + template: "foo @ @".to_string(), + args: vec![ + Expression::Simple(Value::Int(value_node!(1, 1, 12))), + Expression::Simple(Value::Int(value_node!(2, 1, 15))), + ], + pos: Position::new(1, 1), + }) + ); } #[test] fn test_call_parse() { - assert_error!(call_expression("foo") ); - assert_error!(call_expression("foo (") ); - assert_error!(call_expression("foo (1") ); - assert_error!(call_expression("foo (1,") ); - assert_error!(call_expression("foo (1,2") ); - - assert_parse!(call_expression("foo (1, \"foo\")"), - Expression::Call(CallDef{ - macroref: make_selector!(make_expr!("foo", 1, 1), 1, 1), - arglist: vec![ - Expression::Simple(Value::Int(value_node!(1, 1, 6))), - Expression::Simple(Value::String(value_node!("foo".to_string(), 1, 9))), - ], - pos: Position::new(1, 1), - }) + assert_error!(call_expression("foo")); + assert_error!(call_expression("foo (")); + assert_error!(call_expression("foo (1")); + assert_error!(call_expression("foo (1,")); + assert_error!(call_expression("foo (1,2")); + assert_parse!( + call_expression("foo (1, \"foo\")"), + Expression::Call(CallDef { + macroref: make_selector!(make_expr!("foo", 1, 1), 1, 1), + arglist: vec![ + Expression::Simple(Value::Int(value_node!(1, 1, 6))), + Expression::Simple(Value::String(value_node!("foo".to_string(), 1, 9))), + ], + pos: Position::new(1, 1), + }) ); - assert_parse!(call_expression("foo.bar (1, \"foo\")"), - Expression::Call(CallDef{ - macroref: make_selector!(make_expr!("foo") => [ make_tok!("bar", 1, 5) ] => 1, 1), - arglist: vec![ - Expression::Simple(Value::Int(value_node!(1, 1, 10))), - Expression::Simple(Value::String(value_node!("foo".to_string(), 1, 13))), - ], - pos: Position::new(1, 1), - }) - + assert_parse!( + call_expression("foo.bar (1, \"foo\")"), + Expression::Call(CallDef { + macroref: make_selector!(make_expr!("foo") => [ make_tok!("bar", 1, 5) ] => 1, 1), + arglist: vec![ + Expression::Simple(Value::Int(value_node!(1, 1, 10))), + Expression::Simple(Value::String(value_node!("foo".to_string(), 1, 13))), + ], + pos: Position::new(1, 1), + }) ); } @@ -1042,327 +1163,451 @@ mod test { assert_error!(select_expression("select foo, 1")); assert_error!(select_expression("select foo, 1, {")); - assert_parse!(select_expression("select foo, 1, { foo = 2 }"), - Expression::Select(SelectDef{ - val: Box::new(Expression::Simple(Value::Selector(make_selector!(make_expr!("foo", 1, 8), 1, 8)))), - default: Box::new(Expression::Simple(Value::Int(value_node!(1, 1, 13)))), - tuple: vec![ - (make_tok!("foo", 1, 18), Expression::Simple(Value::Int(value_node!(2, 1, 24)))) - ], - pos: Position::new(1, 1), - })); + assert_parse!( + select_expression("select foo, 1, { foo = 2 }"), + Expression::Select(SelectDef { + val: Box::new(Expression::Simple(Value::Selector(make_selector!( + make_expr!("foo", 1, 8), + 1, + 8 + )))), + default: Box::new(Expression::Simple(Value::Int(value_node!(1, 1, 13)))), + tuple: vec![ + ( + make_tok!("foo", 1, 18), + Expression::Simple(Value::Int(value_node!(2, 1, 24))), + ), + ], + pos: Position::new(1, 1), + }) + ); } #[test] fn test_macro_expression_parsing() { - assert_error!(macro_expression("foo") ); - assert_error!(macro_expression("macro \"foo\"") ); - assert_error!(macro_expression("macro 1") ); - assert_error!(macro_expression("macro") ); - assert_error!(macro_expression("macro (") ); - assert_error!(macro_expression("macro (arg") ); - assert_error!(macro_expression("macro (arg, arg2") ); - assert_error!(macro_expression("macro (arg1, arg2) =>") ); - assert_error!(macro_expression("macro (arg1, arg2) => {") ); - assert_error!(macro_expression("macro (arg1, arg2) => { foo") ); - assert_error!(macro_expression("macro (arg1, arg2) => { foo =") ); + assert_error!(macro_expression("foo")); + assert_error!(macro_expression("macro \"foo\"")); + assert_error!(macro_expression("macro 1")); + assert_error!(macro_expression("macro")); + assert_error!(macro_expression("macro (")); + assert_error!(macro_expression("macro (arg")); + assert_error!(macro_expression("macro (arg, arg2")); + assert_error!(macro_expression("macro (arg1, arg2) =>")); + assert_error!(macro_expression("macro (arg1, arg2) => {")); + assert_error!(macro_expression("macro (arg1, arg2) => { foo")); + assert_error!(macro_expression("macro (arg1, arg2) => { foo =")); - assert_parse!(macro_expression("macro (arg1, arg2) => {foo=1,bar=2}"), - Expression::Macro(MacroDef{ - argdefs: vec![value_node!("arg1".to_string(), 1, 8), - value_node!("arg2".to_string(), 1, 14)], - fields: vec![(make_tok!("foo", 1, 24), Expression::Simple(Value::Int(value_node!(1, 1, 28)))), - (make_tok!("bar", 1, 30), Expression::Simple(Value::Int(value_node!(2, 1, 34)))) - ], - pos: Position::new(1, 1), - })); + assert_parse!( + macro_expression("macro (arg1, arg2) => {foo=1,bar=2}"), + Expression::Macro(MacroDef { + argdefs: vec![ + value_node!("arg1".to_string(), 1, 8), + value_node!("arg2".to_string(), 1, 14), + ], + fields: vec![ + ( + make_tok!("foo", 1, 24), + Expression::Simple(Value::Int(value_node!(1, 1, 28))), + ), + ( + make_tok!("bar", 1, 30), + Expression::Simple(Value::Int(value_node!(2, 1, 34))), + ), + ], + pos: Position::new(1, 1), + }) + ); } #[test] fn test_copy_parse() { - assert_error!(copy_expression("{}") ); - assert_error!(copy_expression("foo") ); - assert_error!(copy_expression("foo{") ); + assert_error!(copy_expression("{}")); + assert_error!(copy_expression("foo")); + assert_error!(copy_expression("foo{")); - assert_parse!(copy_expression("foo{}"), - Expression::Copy(CopyDef{ - selector: make_selector!(make_expr!("foo", 1, 1), 1, 1), - fields: Vec::new(), - pos: Position::new(1, 1), - })); + assert_parse!( + copy_expression("foo{}"), + Expression::Copy(CopyDef { + selector: make_selector!(make_expr!("foo", 1, 1), 1, 1), + fields: Vec::new(), + pos: Position::new(1, 1), + }) + ); - assert_parse!(copy_expression("foo{bar=1}"), - Expression::Copy(CopyDef{ - selector: make_selector!(make_expr!("foo", 1, 1), 1, 1), - fields: vec![(make_tok!("bar", 1, 5), - Expression::Simple(Value::Int(value_node!(1, 1, 9))))], - pos: Position::new(1, 1), - })); + assert_parse!( + copy_expression("foo{bar=1}"), + Expression::Copy(CopyDef { + selector: make_selector!(make_expr!("foo", 1, 1), 1, 1), + fields: vec![ + ( + make_tok!("bar", 1, 5), + Expression::Simple(Value::Int(value_node!(1, 1, 9))), + ), + ], + pos: Position::new(1, 1), + }) + ); } #[test] fn test_grouped_expression_parse() { - assert_error!(grouped_expression("foo") ); - assert_error!(grouped_expression("(foo") ); - assert_parse!(grouped_expression("(foo)"), - Expression::Grouped( - Box::new( - Expression::Simple( - Value::Selector(make_selector!(make_expr!("foo", 1, 2), 1, 2)))))); - assert_parse!(grouped_expression("(1 + 1)"), - Expression::Grouped( - Box::new( - Expression::Binary( - BinaryOpDef{ - kind: BinaryExprType::Add, - left: Value::Int(value_node!(1, 1, 2)), - right: Box::new(Expression::Simple( - Value::Int(value_node!(1, 1, 6)))), - pos: Position::new(1, 2), - })))); + assert_error!(grouped_expression("foo")); + assert_error!(grouped_expression("(foo")); + assert_parse!( + grouped_expression("(foo)"), + Expression::Grouped(Box::new(Expression::Simple(Value::Selector( + make_selector!(make_expr!("foo", 1, 2), 1, 2) + )))) + ); + assert_parse!( + grouped_expression("(1 + 1)"), + Expression::Grouped(Box::new(Expression::Binary(BinaryOpDef { + kind: BinaryExprType::Add, + left: Value::Int(value_node!(1, 1, 2)), + right: Box::new(Expression::Simple(Value::Int(value_node!(1, 1, 6)))), + pos: Position::new(1, 2), + }))) + ); } #[test] fn test_list_value_parse() { - assert_error!(list_value("foo") ); - assert_error!(list_value("[foo") ); - assert_error!(list_value("// commen\n[foo") ); + assert_error!(list_value("foo")); + assert_error!(list_value("[foo")); + assert_error!(list_value("// commen\n[foo")); - assert_parse!(list_value("[foo]"), - Value::List( - ListDef{ - elems: vec![ - Expression::Simple(Value::Selector(make_selector!(make_expr!("foo", 1, 2), 1, 2))) - ], - pos: Position::new(1, 1), - } - ) + assert_parse!( + list_value("[foo]"), + Value::List(ListDef { + elems: vec![ + Expression::Simple(Value::Selector(make_selector!( + make_expr!("foo", 1, 2), + 1, + 2 + ))), + ], + pos: Position::new(1, 1), + }) ); - assert_parse!(list_value("[1, 1]"), - Value::List( - ListDef{ - elems: vec![ - Expression::Simple(Value::Int(value_node!(1, 1, 2))), - Expression::Simple(Value::Int(value_node!(1, 1, 5))), - ], - pos: Position::new(1, 1), - } - ) + assert_parse!( + list_value("[1, 1]"), + Value::List(ListDef { + elems: vec![ + Expression::Simple(Value::Int(value_node!(1, 1, 2))), + Expression::Simple(Value::Int(value_node!(1, 1, 5))), + ], + pos: Position::new(1, 1), + }) ); - assert_parse!(list_value("// comment\n[1, 1]"), - Value::List( - ListDef{ - elems: vec![ - Expression::Simple(Value::Int(value_node!(1, 2, 2))), - Expression::Simple(Value::Int(value_node!(1, 2, 5))), - ], - pos: Position::new(2, 1), - } - ) + assert_parse!( + list_value("// comment\n[1, 1]"), + Value::List(ListDef { + elems: vec![ + Expression::Simple(Value::Int(value_node!(1, 2, 2))), + Expression::Simple(Value::Int(value_node!(1, 2, 5))), + ], + pos: Position::new(2, 1), + }) ); - assert_parse!(list_value("[// comment\n1, 1]"), - Value::List( - ListDef{ - elems: vec![ - Expression::Simple(Value::Int(value_node!(1, 2, 2))), - Expression::Simple(Value::Int(value_node!(1, 2, 5))), - ], - pos: Position::new(1, 1), - } - ) + assert_parse!( + list_value("[// comment\n1, 1]"), + Value::List(ListDef { + elems: vec![ + Expression::Simple(Value::Int(value_node!(1, 2, 2))), + Expression::Simple(Value::Int(value_node!(1, 2, 5))), + ], + pos: Position::new(1, 1), + }) ); - assert_parse!(list_value("[1, // comment\n1]"), - Value::List( - ListDef{ - elems: vec![ - Expression::Simple(Value::Int(value_node!(1, 1, 2))), - Expression::Simple(Value::Int(value_node!(1, 2, 1))), - ], - pos: Position::new(1, 1), - } - ) + assert_parse!( + list_value("[1, // comment\n1]"), + Value::List(ListDef { + elems: vec![ + Expression::Simple(Value::Int(value_node!(1, 1, 2))), + Expression::Simple(Value::Int(value_node!(1, 2, 1))), + ], + pos: Position::new(1, 1), + }) ); - assert_parse!(list_value("[1, 1 // comment\n]"), - Value::List( - ListDef{ - elems: vec![ - Expression::Simple(Value::Int(value_node!(1, 1, 2))), - Expression::Simple(Value::Int(value_node!(1, 1, 5))), - ], - pos: Position::new(1, 1), - } - ) + assert_parse!( + list_value("[1, 1 // comment\n]"), + Value::List(ListDef { + elems: vec![ + Expression::Simple(Value::Int(value_node!(1, 1, 2))), + Expression::Simple(Value::Int(value_node!(1, 1, 5))), + ], + pos: Position::new(1, 1), + }) ); } #[test] fn test_tuple_parse() { - assert_error!(tuple("{") ); - assert_error!(tuple("{ foo") ); - assert_error!(tuple("{ foo =") ); - assert_error!(tuple("{ foo = 1") ); - assert_error!(tuple("{ foo = 1,") ); - assert_error!(tuple("{ foo = 1, bar =") ); - assert_error!(tuple("// comment\n{ foo = 1, bar =") ); + assert_error!(tuple("{")); + assert_error!(tuple("{ foo")); + assert_error!(tuple("{ foo =")); + assert_error!(tuple("{ foo = 1")); + assert_error!(tuple("{ foo = 1,")); + assert_error!(tuple("{ foo = 1, bar =")); + assert_error!(tuple("// comment\n{ foo = 1, bar =")); assert_parse!(tuple("{ }"), Value::Tuple(value_node!(vec![], 1, 1))); - assert_parse!(tuple("{ foo = 1 }"), - Value::Tuple( - value_node!(vec![ - (make_tok!("foo", 1, 3), - Expression::Simple(Value::Int(value_node!(1, 1, 9)))) - ], 1, 1))); + assert_parse!( + tuple("{ foo = 1 }"), + Value::Tuple(value_node!( + vec![ + ( + make_tok!("foo", 1, 3), + Expression::Simple(Value::Int(value_node!(1, 1, 9))), + ), + ], + 1, + 1 + )) + ); - assert_parse!(tuple("// comment\n{ foo = 1 }"), - Value::Tuple( - value_node!(vec![ - (make_tok!("foo", 2, 3), - Expression::Simple(Value::Int(value_node!(1, 2, 9)))) - ], 1, 1))); + assert_parse!( + tuple("// comment\n{ foo = 1 }"), + Value::Tuple(value_node!( + vec![ + ( + make_tok!("foo", 2, 3), + Expression::Simple(Value::Int(value_node!(1, 2, 9))), + ), + ], + 1, + 1 + )) + ); - assert_parse!(tuple("{// comment\n foo = 1 }"), - Value::Tuple( - value_node!(vec![ - (make_tok!("foo", 2, 2), - Expression::Simple(Value::Int(value_node!(1, 2, 8)))) - ], 1, 1))); + assert_parse!( + tuple("{// comment\n foo = 1 }"), + Value::Tuple(value_node!( + vec![ + ( + make_tok!("foo", 2, 2), + Expression::Simple(Value::Int(value_node!(1, 2, 8))), + ), + ], + 1, + 1 + )) + ); - assert_parse!(tuple("{ foo = 1// comment\n }"), - Value::Tuple( - value_node!(vec![ - (make_tok!("foo", 1, 3), - Expression::Simple(Value::Int(value_node!(1, 1, 9)))) - ], 1, 1))); + assert_parse!( + tuple("{ foo = 1// comment\n }"), + Value::Tuple(value_node!( + vec![ + ( + make_tok!("foo", 1, 3), + Expression::Simple(Value::Int(value_node!(1, 1, 9))), + ), + ], + 1, + 1 + )) + ); - assert_parse!(tuple("{ foo = 1, bar = \"1\" }"), - Value::Tuple( - value_node!(vec![ - (make_tok!("foo", 1, 3), - Expression::Simple(Value::Int(value_node!(1, 1, 9)))), - (make_tok!("bar", 1, 12), - Expression::Simple(Value::String(value_node!("1".to_string(), Position::new(1, 18))))) - ], 1, 1))); - assert_parse!(tuple("{ foo = 1, // comment\nbar = \"1\" }"), - Value::Tuple( - value_node!(vec![ - (make_tok!("foo", 1, 3), - Expression::Simple(Value::Int(value_node!(1, 1, 9)))), - (make_tok!("bar", 2, 1), - Expression::Simple(Value::String(value_node!("1".to_string(), Position::new(2, 7))))) - ], 1, 1))); - assert_parse!(tuple("{ foo = 1, bar = {} }"), - Value::Tuple( - value_node!(vec![ - (make_tok!("foo", 1, 3), - Expression::Simple(Value::Int(value_node!(1, Position::new(1, 9))))), - (make_tok!("bar", 1, 12), - Expression::Simple(Value::Tuple(value_node!(Vec::new(), Position::new(1, 17))))) - ], 1, 1))); + assert_parse!( + tuple("{ foo = 1, bar = \"1\" }"), + Value::Tuple(value_node!( + vec![ + ( + make_tok!("foo", 1, 3), + Expression::Simple(Value::Int(value_node!(1, 1, 9))), + ), + ( + make_tok!("bar", 1, 12), + Expression::Simple(Value::String(value_node!( + "1".to_string(), + Position::new(1, 18) + ))), + ), + ], + 1, + 1 + )) + ); + assert_parse!( + tuple("{ foo = 1, // comment\nbar = \"1\" }"), + Value::Tuple(value_node!( + vec![ + ( + make_tok!("foo", 1, 3), + Expression::Simple(Value::Int(value_node!(1, 1, 9))), + ), + ( + make_tok!("bar", 2, 1), + Expression::Simple(Value::String(value_node!( + "1".to_string(), + Position::new(2, 7) + ))), + ), + ], + 1, + 1 + )) + ); + assert_parse!( + tuple("{ foo = 1, bar = {} }"), + Value::Tuple(value_node!( + vec![ + ( + make_tok!("foo", 1, 3), + Expression::Simple(Value::Int(value_node!(1, Position::new(1, 9)))), + ), + ( + make_tok!("bar", 1, 12), + Expression::Simple(Value::Tuple(value_node!( + Vec::new(), + Position::new(1, 17) + ))), + ), + ], + 1, + 1 + )) + ); } #[test] fn test_field_list_parse() { let mut f_list = "foo = 1, quux = 2;"; - assert_parse!(field_list(f_list), + assert_parse!( + field_list(f_list), vec![ (make_tok!("foo", 1, 1), make_expr!(1 => int, 1, 7)), (make_tok!("quux", 1, 10), make_expr!(2 => int, 1, 17)), - ]); + ] + ); f_list = "foo = 1, // comment\nquux = 2;"; - assert_parse!(field_list(f_list), + assert_parse!( + field_list(f_list), vec![ (make_tok!("foo", 1, 1), make_expr!(1 => int, 1, 7)), (make_tok!("quux", 2, 1), make_expr!(2 => int, 2, 8)), - ]); + ] + ); f_list = "foo = 1,\n// comment\nquux = 2;"; - assert_parse!(field_list(f_list), + assert_parse!( + field_list(f_list), vec![ (make_tok!("foo", 1, 1), make_expr!(1 => int, 1, 7)), (make_tok!("quux", 3, 1), make_expr!(2 => int, 3, 8)), - ]); + ] + ); } #[test] fn test_field_value_parse() { - assert_error!(field_value("foo") ); - assert_error!(field_value("// comment\nfoo") ); - assert_error!(field_value("foo =") ); + assert_error!(field_value("foo")); + assert_error!(field_value("// comment\nfoo")); + assert_error!(field_value("foo =")); - assert_parse!(field_value("foo = 1"), - (make_tok!("foo", 1, 1), - Expression::Simple(Value::Int(value_node!(1, 1, 7)))) ); - assert_parse!(field_value("foo = 1 // foo comment\n"), - (make_tok!("foo", 1, 1), - Expression::Simple(Value::Int(value_node!(1, 1, 7)))) ); - assert_parse!(field_value("foo // foo comment\n = 1"), - (make_tok!("foo", 1, 1), - Expression::Simple(Value::Int(value_node!(1, 2, 4)))) ); - assert_parse!(field_value("// foo comment\nfoo = 1"), - (make_tok!("foo", 2, 1), - Expression::Simple(Value::Int(value_node!(1, 2, 7)))) ); - assert_parse!(field_value("foo = \"1\""), - (make_tok!("foo", 1, 1), - Expression::Simple(Value::String(value_node!("1".to_string(), 1, 7)))) ); - assert_parse!(field_value("foo = bar "), - (make_tok!("foo", 1, 1), - Expression::Simple(Value::Selector(make_selector!(make_expr!("bar", 1, 7), 1, 7)))) ); - assert_parse!(field_value("foo = bar.baz "), - (make_tok!("foo", 1, 1), - Expression::Simple(Value::Selector(make_selector!(make_expr!("bar", 1, 7) => [ make_tok!("baz", 1, 11) ] => 1, 7)))) ); + assert_parse!( + field_value("foo = 1"), + ( + make_tok!("foo", 1, 1), + Expression::Simple(Value::Int(value_node!(1, 1, 7))) + ) + ); + assert_parse!( + field_value("foo = 1 // foo comment\n"), + ( + make_tok!("foo", 1, 1), + Expression::Simple(Value::Int(value_node!(1, 1, 7))) + ) + ); + assert_parse!( + field_value("foo // foo comment\n = 1"), + ( + make_tok!("foo", 1, 1), + Expression::Simple(Value::Int(value_node!(1, 2, 4))) + ) + ); + assert_parse!( + field_value("// foo comment\nfoo = 1"), + ( + make_tok!("foo", 2, 1), + Expression::Simple(Value::Int(value_node!(1, 2, 7))) + ) + ); + assert_parse!( + field_value("foo = \"1\""), + ( + make_tok!("foo", 1, 1), + Expression::Simple(Value::String(value_node!("1".to_string(), 1, 7))) + ) + ); + assert_parse!( + field_value("foo = bar "), + ( + make_tok!("foo", 1, 1), + Expression::Simple(Value::Selector(make_selector!( + make_expr!("bar", 1, 7), + 1, + 7 + ))) + ) + ); + assert_parse!( + field_value("foo = bar.baz "), + ( + make_tok!("foo", 1, 1), + Expression::Simple(Value::Selector( + make_selector!(make_expr!("bar", 1, 7) => [ make_tok!("baz", 1, 11) ] => 1, 7) + )) + ) + ); } #[test] fn test_number_parsing() { - assert_error!(number(".") ); - assert_error!(number(". ") ); - assert_parse!(number("1.0"), - Value::Float(value_node!(1.0, 1, 1)) ); - assert_parse!(number("1."), - Value::Float(value_node!(1.0, 1, 1)) ); - assert_parse!(number("1"), - Value::Int(value_node!(1, 1, 1)) ); - assert_parse!(number(".1"), - Value::Float(value_node!(0.1, 1, 1)) ); + assert_error!(number(".")); + assert_error!(number(". ")); + assert_parse!(number("1.0"), Value::Float(value_node!(1.0, 1, 1))); + assert_parse!(number("1."), Value::Float(value_node!(1.0, 1, 1))); + assert_parse!(number("1"), Value::Int(value_node!(1, 1, 1))); + assert_parse!(number(".1"), Value::Float(value_node!(0.1, 1, 1))); } #[test] fn test_parse() { let bad_input = LocatedSpan::new("import mylib as lib;"); let bad_result = parse(bad_input); - assert!(bad_result.is_err() ); + assert!(bad_result.is_err()); // Valid parsing tree let input = LocatedSpan::new("import \"mylib\" as lib;let foo = 1;1+1;"); let result = parse(input); assert!(result.is_ok(), format!("Expected Ok, Got {:?}", result)); let tpl = result.unwrap(); - assert_eq!(tpl, - vec![ - Statement::Import(ImportDef{ - path: make_tok!(QUOT => "mylib", 1, 8), - name: make_tok!("lib", 1, 19), - }), - Statement::Let(LetDef{ - name: make_tok!("foo", 1, 27), - value: Expression::Simple(Value::Int(value_node!(1, 1, 33))) - }), - Statement::Expression( - Expression::Binary( - BinaryOpDef{ - kind: BinaryExprType::Add, - left: Value::Int(value_node!(1, 1, 35)), - right: Box::new(Expression::Simple(Value::Int(value_node!(1, 1, 37)))), - pos: Position::new(1, 35), - }) - ) - ]); + assert_eq!( + tpl, + vec![ + Statement::Import(ImportDef { + path: make_tok!(QUOT => "mylib", 1, 8), + name: make_tok!("lib", 1, 19), + }), + Statement::Let(LetDef { + name: make_tok!("foo", 1, 27), + value: Expression::Simple(Value::Int(value_node!(1, 1, 33))), + }), + Statement::Expression(Expression::Binary(BinaryOpDef { + kind: BinaryExprType::Add, + left: Value::Int(value_node!(1, 1, 35)), + right: Box::new(Expression::Simple(Value::Int(value_node!(1, 1, 37)))), + pos: Position::new(1, 35), + })), + ] + ); } } diff --git a/src/tokenizer.rs b/src/tokenizer.rs index de914e8..a4b3d73 100644 --- a/src/tokenizer.rs +++ b/src/tokenizer.rs @@ -15,8 +15,8 @@ //! The tokenization stage of the ucg compiler. use nom_locate::LocatedSpan; use nom; -use nom::{alpha, is_alphanumeric, digit, multispace}; -use nom::{InputLength, InputIter, Slice}; +use nom::{alpha, digit, is_alphanumeric, multispace}; +use nom::{InputIter, InputLength, Slice}; use ast::*; use std; use std::result::Result; @@ -204,9 +204,11 @@ named!(astok( Span ) -> Token, fn end_of_input(input: Span) -> nom::IResult { match eof!(input,) { nom::IResult::Done(_, _) => { - return nom::IResult::Done(input, - make_tok!(EOF => input.line as usize, - input.get_column() as usize)); + return nom::IResult::Done( + input, + make_tok!(EOF => input.line as usize, + input.get_column() as usize), + ); } nom::IResult::Incomplete(_) => { return nom::IResult::Incomplete(nom::Needed::Unknown); @@ -220,22 +222,29 @@ fn end_of_input(input: Span) -> nom::IResult { fn comment(input: Span) -> nom::IResult { match tag!(input, "//") { nom::IResult::Done(rest, _) => { - match alt!(rest, take_until_and_consume!("\r\n") | take_until_and_consume!("\n")) { + match alt!( + rest, + take_until_and_consume!("\r\n") | take_until_and_consume!("\n") + ) { nom::IResult::Done(rest, cmt) => { - return nom::IResult::Done(rest, - make_tok!(CMT => cmt.fragment.to_string(), + return nom::IResult::Done( + rest, + make_tok!(CMT => cmt.fragment.to_string(), input.line as usize, - input.get_column() as usize)); + input.get_column() as usize), + ); } // If we didn't find a new line then we just grab everything. _ => { let blen = rest.input_len(); let next = rest.slice(blen..); let tok = rest.slice(..blen); - return nom::IResult::Done(next, - make_tok!(CMT => tok.fragment.to_string(), + return nom::IResult::Done( + next, + make_tok!(CMT => tok.fragment.to_string(), input.line as usize, input.get_column() as usize - )); + ), + ); } } } @@ -461,11 +470,13 @@ pub fn pos(i: TokenIter) -> nom::IResult { let tok = &i[0]; let line = tok.pos.line; let column = tok.pos.column; - nom::IResult::Done(i.clone(), - Position { - line: line, - column: column, - }) + nom::IResult::Done( + i.clone(), + Position { + line: line, + column: column, + }, + ) } /// TokenIter wraps a slice of Tokens and implements the various necessary @@ -528,7 +539,8 @@ impl<'a> InputIter for TokenIter<'a> { } fn position

(&self, predicate: P) -> Option - where P: Fn(Self::RawItem) -> bool + where + P: Fn(Self::RawItem) -> bool, { for (o, v) in self.iter_indices() { if predicate(v.clone()) { @@ -580,10 +592,10 @@ mod tokenizer_test { #[test] fn test_tokenize_one_of_each() { - // 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 - // 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 - let result = tokenize(LocatedSpan::new("let import macro select as => [ ] { } ; = % / * \ - + - . ( ) , 1 . foo \"bar\" // comment\n ;")); + let result = tokenize(LocatedSpan::new( + "let import macro select as => [ ] { } ; = % / * \ + + - . ( ) , 1 . foo \"bar\" // comment\n ;", + )); assert!(result.is_ok(), format!("result {:?} is not ok", result)); let v = result.unwrap(); for (i, t) in v.iter().enumerate() { @@ -606,40 +618,71 @@ mod tokenizer_test { fn test_parse_comment() { assert!(comment(LocatedSpan::new("// comment\n")).is_done()); assert!(comment(LocatedSpan::new("// comment")).is_done()); - assert_eq!(comment(LocatedSpan::new("// comment\n")), - nom::IResult::Done(LocatedSpan{fragment: "", offset: 11, line: 2}, - Token{ - typ: TokenType::COMMENT, - fragment: " comment".to_string(), - pos: Position{line: 1, column: 1}, - })); + assert_eq!( + comment(LocatedSpan::new("// comment\n")), + nom::IResult::Done( + LocatedSpan { + fragment: "", + offset: 11, + line: 2, + }, + Token { + typ: TokenType::COMMENT, + fragment: " comment".to_string(), + pos: Position { line: 1, column: 1 }, + } + ) + ); assert!(comment(LocatedSpan::new("// comment\r\n")).is_done()); - assert_eq!(comment(LocatedSpan::new("// comment\r\n")), - nom::IResult::Done(LocatedSpan{fragment: "", offset: 12, line: 2}, - Token{ + assert_eq!( + comment(LocatedSpan::new("// comment\r\n")), + nom::IResult::Done( + LocatedSpan { + fragment: "", + offset: 12, + line: 2, + }, + Token { typ: TokenType::COMMENT, fragment: " comment".to_string(), - pos: Position{column: 1, line: 1} - })); + pos: Position { column: 1, line: 1 }, + } + ) + ); assert!(comment(LocatedSpan::new("// comment\r\n ")).is_done()); - assert_eq!(comment(LocatedSpan::new("// comment\r\n ")), - nom::IResult::Done(LocatedSpan{fragment: " ", offset: 12, line: 2}, - Token{ + assert_eq!( + comment(LocatedSpan::new("// comment\r\n ")), + nom::IResult::Done( + LocatedSpan { + fragment: " ", + offset: 12, + line: 2, + }, + Token { typ: TokenType::COMMENT, fragment: " comment".to_string(), - pos: Position{column: 1, line: 1}, - })); + pos: Position { column: 1, line: 1 }, + } + ) + ); assert!(comment(LocatedSpan::new("// comment")).is_done()); } #[test] fn test_match_word() { - let input = vec![Token{ - fragment: "foo".to_string(), - typ: TokenType::BAREWORD, - pos: Position{line: 1, column: 1} - }]; - let result = word!(TokenIter{source: input.as_slice()}, "foo"); + let input = vec![ + Token { + fragment: "foo".to_string(), + typ: TokenType::BAREWORD, + pos: Position { line: 1, column: 1 }, + }, + ]; + let result = word!( + TokenIter { + source: input.as_slice(), + }, + "foo" + ); match result { nom::IResult::Done(_, tok) => assert_eq!(tok, input[0]), res => assert!(false, format!("Fail: {:?}", res)), @@ -648,12 +691,19 @@ mod tokenizer_test { #[test] fn test_match_word_empty_input() { - let input = vec![Token{ - fragment: "".to_string(), - typ: TokenType::END, - pos: Position{line: 1, column: 1}, - }]; - let result = word!(TokenIter{source: input.as_slice()}, "foo"); + let input = vec![ + Token { + fragment: "".to_string(), + typ: TokenType::END, + pos: Position { line: 1, column: 1 }, + }, + ]; + let result = word!( + TokenIter { + source: input.as_slice(), + }, + "foo" + ); match result { nom::IResult::Done(_, _) => assert!(false, "Should have been an error but was Done"), nom::IResult::Incomplete(_) => { @@ -667,12 +717,19 @@ mod tokenizer_test { #[test] fn test_match_punct() { - let input = vec![Token{ - fragment: "!".to_string(), - typ: TokenType::PUNCT, - pos: Position{line: 1, column: 1} - }]; - let result = punct!(TokenIter{source: input.as_slice()}, "!"); + let input = vec![ + Token { + fragment: "!".to_string(), + typ: TokenType::PUNCT, + pos: Position { line: 1, column: 1 }, + }, + ]; + let result = punct!( + TokenIter { + source: input.as_slice(), + }, + "!" + ); match result { nom::IResult::Done(_, tok) => assert_eq!(tok, input[0]), res => assert!(false, format!("Fail: {:?}", res)), @@ -681,12 +738,19 @@ mod tokenizer_test { #[test] fn test_match_type() { - let input = vec![Token{ - fragment: "foo".to_string(), - typ: TokenType::BAREWORD, - pos: Position{line: 1, column: 1} - }]; - let result = match_type!(TokenIter{source: input.as_slice()}, BAREWORD); + let input = vec![ + Token { + fragment: "foo".to_string(), + typ: TokenType::BAREWORD, + pos: Position { line: 1, column: 1 }, + }, + ]; + let result = match_type!( + TokenIter { + source: input.as_slice(), + }, + BAREWORD + ); match result { nom::IResult::Done(_, tok) => assert_eq!(tok, input[0]), res => assert!(false, format!("Fail: {:?}", res)),