diff --git a/src/ast/mod.rs b/src/ast/mod.rs index 061abd3..2d62a34 100644 --- a/src/ast/mod.rs +++ b/src/ast/mod.rs @@ -738,5 +738,5 @@ pub enum Statement { Assert(Expression), // Identify an Expression for output. - Output(Token, Expression), + Output(Position, Token, Expression), } diff --git a/src/ast/walk.rs b/src/ast/walk.rs index 1a00ca2..f5f33e5 100644 --- a/src/ast/walk.rs +++ b/src/ast/walk.rs @@ -42,7 +42,7 @@ impl<'a> AstWalker<'a> { Statement::Assert(ref mut expr) => { self.walk_expression(expr); } - Statement::Output(_, ref mut expr) => { + Statement::Output(_, _, ref mut expr) => { self.walk_expression(expr); } } diff --git a/src/build/compile_test.rs b/src/build/compile_test.rs index 8cf7f33..e6e627c 100644 --- a/src/build/compile_test.rs +++ b/src/build/compile_test.rs @@ -429,3 +429,37 @@ fn test_list_unclosed_bracket_compile_failure() { ], ) } + +#[test] +fn test_out_missing_type_compile_failure() { + assert_build_failure( + "out", + vec![ + Regex::new(r"Expected converter name").unwrap(), + Regex::new(r"Not a Bareword").unwrap(), + Regex::new(r"at line: 1, column: 4").unwrap(), + ], + ) +} + +#[test] +fn test_out_missing_out_expr_compile_failure() { + assert_build_failure( + "out json", + vec![ + Regex::new(r"Expected Expression to export").unwrap(), + Regex::new(r"at line: 1, column: 9").unwrap(), + ], + ) +} + +#[test] +fn test_out_multiple_times_compile_failure() { + assert_build_failure( + "out json {};\nout json {};", + vec![ + Regex::new(r"You can only have one output per file").unwrap(), + Regex::new(r"at line: 2, column: 1").unwrap(), + ], + ) +} diff --git a/src/build/mod.rs b/src/build/mod.rs index 3e9f13e..e9f83d1 100644 --- a/src/build/mod.rs +++ b/src/build/mod.rs @@ -491,7 +491,7 @@ impl<'a> FileBuilder<'a> { &Statement::Expression(ref expr) => self.eval_expr(expr, &child_scope), // Only one output can be used per file. Right now we enforce this by // having a single builder per file. - &Statement::Output(ref typ, ref expr) => { + &Statement::Output(ref pos, ref typ, ref expr) => { if let None = self.out_lock { let val = self.eval_expr(expr, &child_scope)?; self.out_lock = Some((typ.fragment.to_string(), val.clone())); @@ -499,8 +499,8 @@ impl<'a> FileBuilder<'a> { } else { Err(Box::new(error::BuildError::new( format!("You can only have one output per file."), - error::ErrorType::DuplicateBinding, - typ.pos.clone(), + error::ErrorType::Unsupported, + pos.clone(), ))) } } diff --git a/src/parse/mod.rs b/src/parse/mod.rs index 62ed697..a6c13f9 100644 --- a/src/parse/mod.rs +++ b/src/parse/mod.rs @@ -792,11 +792,12 @@ make_fn!( make_fn!( out_statement, Statement>, do_each!( + pos => pos, _ => word!("out"), typ => wrap_err!(must!(match_type!(BAREWORD)), "Expected converter name"), expr => wrap_err!(must!(expression), "Expected Expression to export"), _ => must!(punct!(";")), - (Statement::Output(typ.clone(), expr.clone())) + (Statement::Output(pos, typ.clone(), expr.clone())) ) );