mirror of
https://github.com/zaphar/ucg.git
synced 2025-07-22 18:19:54 -04:00
REFACTOR: Use our new handy dandy to_boxed method on BuildError.
This commit is contained in:
parent
923ba89e2f
commit
0e5751c2b0
2
Cargo.lock
generated
2
Cargo.lock
generated
@ -1,3 +1,5 @@
|
|||||||
|
# This file is automatically @generated by Cargo.
|
||||||
|
# It is not intended for manual editing.
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "abortable_parser"
|
name = "abortable_parser"
|
||||||
version = "0.2.3"
|
version = "0.2.3"
|
||||||
|
@ -54,12 +54,13 @@ impl<V: Into<String> + Clone> FormatRenderer for SimpleFormatter<V> {
|
|||||||
for c in self.tmpl.chars() {
|
for c in self.tmpl.chars() {
|
||||||
if c == '@' && !should_escape {
|
if c == '@' && !should_escape {
|
||||||
if count == self.args.len() {
|
if count == self.args.len() {
|
||||||
return Err(Box::new(error::BuildError::with_pos(
|
return Err(error::BuildError::with_pos(
|
||||||
"Too few arguments to string \
|
"Too few arguments to string \
|
||||||
formatter.",
|
formatter.",
|
||||||
error::ErrorType::FormatError,
|
error::ErrorType::FormatError,
|
||||||
pos.clone(),
|
pos.clone(),
|
||||||
)));
|
)
|
||||||
|
.to_boxed());
|
||||||
}
|
}
|
||||||
let arg = self.args[count].clone();
|
let arg = self.args[count].clone();
|
||||||
let strval = arg.into();
|
let strval = arg.into();
|
||||||
@ -72,12 +73,13 @@ impl<V: Into<String> + Clone> FormatRenderer for SimpleFormatter<V> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if self.args.len() != count {
|
if self.args.len() != count {
|
||||||
return Err(Box::new(error::BuildError::with_pos(
|
return Err(error::BuildError::with_pos(
|
||||||
"Too many arguments to string \
|
"Too many arguments to string \
|
||||||
formatter.",
|
formatter.",
|
||||||
error::ErrorType::FormatError,
|
error::ErrorType::FormatError,
|
||||||
pos.clone(),
|
pos.clone(),
|
||||||
)));
|
)
|
||||||
|
.to_boxed());
|
||||||
}
|
}
|
||||||
return Ok(buf);
|
return Ok(buf);
|
||||||
}
|
}
|
||||||
@ -111,22 +113,24 @@ impl<'a> ExpressionFormatter<'a> {
|
|||||||
if c == '{' {
|
if c == '{' {
|
||||||
brace_count += 1;
|
brace_count += 1;
|
||||||
} else {
|
} else {
|
||||||
return Err(Box::new(error::BuildError::with_pos(
|
return Err(error::BuildError::with_pos(
|
||||||
format!(
|
format!(
|
||||||
"Invalid syntax for format string expected '{{' but got {}",
|
"Invalid syntax for format string expected '{{' but got {}",
|
||||||
c
|
c
|
||||||
),
|
),
|
||||||
error::ErrorType::FormatError,
|
error::ErrorType::FormatError,
|
||||||
pos.clone(),
|
pos.clone(),
|
||||||
)));
|
)
|
||||||
|
.to_boxed());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
return Err(Box::new(error::BuildError::with_pos(
|
return Err(error::BuildError::with_pos(
|
||||||
"Invalid syntax for format string expected '{' but string ended",
|
"Invalid syntax for format string expected '{' but string ended",
|
||||||
error::ErrorType::FormatError,
|
error::ErrorType::FormatError,
|
||||||
pos.clone(),
|
pos.clone(),
|
||||||
)));
|
)
|
||||||
|
.to_boxed());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
loop {
|
loop {
|
||||||
@ -148,11 +152,12 @@ impl<'a> ExpressionFormatter<'a> {
|
|||||||
}
|
}
|
||||||
// empty expressions are an error
|
// empty expressions are an error
|
||||||
if expr_string.is_empty() {
|
if expr_string.is_empty() {
|
||||||
return Err(Box::new(error::BuildError::with_pos(
|
return Err(error::BuildError::with_pos(
|
||||||
"Got an empty expression in format string",
|
"Got an empty expression in format string",
|
||||||
error::ErrorType::FormatError,
|
error::ErrorType::FormatError,
|
||||||
pos.clone(),
|
pos.clone(),
|
||||||
)));
|
)
|
||||||
|
.to_boxed());
|
||||||
}
|
}
|
||||||
if !expr_string.ends_with(";") {
|
if !expr_string.ends_with(";") {
|
||||||
expr_string.push(';');
|
expr_string.push(';');
|
||||||
@ -163,11 +168,12 @@ impl<'a> ExpressionFormatter<'a> {
|
|||||||
expr_string.push(c);
|
expr_string.push(c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return Err(Box::new(error::BuildError::with_pos(
|
return Err(error::BuildError::with_pos(
|
||||||
"Expected '}' but got end of string",
|
"Expected '}' but got end of string",
|
||||||
error::ErrorType::FormatError,
|
error::ErrorType::FormatError,
|
||||||
pos.clone(),
|
pos.clone(),
|
||||||
)));
|
)
|
||||||
|
.to_boxed());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
270
src/build/mod.rs
270
src/build/mod.rs
@ -61,11 +61,12 @@ impl FuncDef {
|
|||||||
// Error conditions. If the args don't match the length and types of the argdefs then this is
|
// Error conditions. If the args don't match the length and types of the argdefs then this is
|
||||||
// func call error.
|
// func call error.
|
||||||
if args.len() > self.argdefs.len() {
|
if args.len() > self.argdefs.len() {
|
||||||
return Err(Box::new(error::BuildError::with_pos(
|
return Err(error::BuildError::with_pos(
|
||||||
"Func called with too many args",
|
"Func called with too many args",
|
||||||
error::ErrorType::BadArgLen,
|
error::ErrorType::BadArgLen,
|
||||||
self.pos.clone(),
|
self.pos.clone(),
|
||||||
)));
|
)
|
||||||
|
.to_boxed());
|
||||||
}
|
}
|
||||||
// If the args don't match the types required by the expressions then that is a TypeFail.
|
// If the args don't match the types required by the expressions then that is a TypeFail.
|
||||||
// If the expressions reference Symbols not defined in the FuncDef that is also an error.
|
// If the expressions reference Symbols not defined in the FuncDef that is also an error.
|
||||||
@ -129,11 +130,12 @@ macro_rules! eval_binary_expr {
|
|||||||
return Ok(Rc::new($result));
|
return Ok(Rc::new($result));
|
||||||
}
|
}
|
||||||
val => {
|
val => {
|
||||||
return Err(Box::new(error::BuildError::with_pos(
|
return Err(error::BuildError::with_pos(
|
||||||
format!("Expected {} but got ({})", $msg, val),
|
format!("Expected {} but got ({})", $msg, val),
|
||||||
error::ErrorType::TypeFail,
|
error::ErrorType::TypeFail,
|
||||||
$pos.clone(),
|
$pos.clone(),
|
||||||
)));
|
)
|
||||||
|
.to_boxed());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -416,17 +418,18 @@ impl<'a> FileBuilder<'a> {
|
|||||||
mut_assets_cache.stash(path, result.clone())?;
|
mut_assets_cache.stash(path, result.clone())?;
|
||||||
return Ok(result);
|
return Ok(result);
|
||||||
} else {
|
} else {
|
||||||
return Err(Box::new(error::BuildError::with_pos(
|
return Err(error::BuildError::with_pos(
|
||||||
format!("No such import {} in the std library.", def.path.fragment),
|
format!("No such import {} in the std library.", def.path.fragment),
|
||||||
error::ErrorType::Unsupported,
|
error::ErrorType::Unsupported,
|
||||||
def.pos.clone(),
|
def.pos.clone(),
|
||||||
)));
|
)
|
||||||
|
.to_boxed());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Try a relative path first.
|
// Try a relative path first.
|
||||||
let normalized = self.find_file(&def.path.fragment, true)?;
|
let normalized = self.find_file(&def.path.fragment, true)?;
|
||||||
if self.detect_import_cycle(normalized.to_string_lossy().as_ref()) {
|
if self.detect_import_cycle(normalized.to_string_lossy().as_ref()) {
|
||||||
return Err(Box::new(error::BuildError::with_pos(
|
return Err(error::BuildError::with_pos(
|
||||||
format!(
|
format!(
|
||||||
"Import Cycle Detected!!!! {} is already in import stack: {:?}",
|
"Import Cycle Detected!!!! {} is already in import stack: {:?}",
|
||||||
normalized.to_string_lossy(),
|
normalized.to_string_lossy(),
|
||||||
@ -434,7 +437,8 @@ impl<'a> FileBuilder<'a> {
|
|||||||
),
|
),
|
||||||
error::ErrorType::Unsupported,
|
error::ErrorType::Unsupported,
|
||||||
def.pos.clone(),
|
def.pos.clone(),
|
||||||
)));
|
)
|
||||||
|
.to_boxed());
|
||||||
}
|
}
|
||||||
// Introduce a scope so the above borrow is dropped before we modify
|
// Introduce a scope so the above borrow is dropped before we modify
|
||||||
// the cache below.
|
// the cache below.
|
||||||
@ -458,15 +462,16 @@ impl<'a> FileBuilder<'a> {
|
|||||||
let val = self.eval_expr(&def.value, &child_scope)?;
|
let val = self.eval_expr(&def.value, &child_scope)?;
|
||||||
let name = &def.name;
|
let name = &def.name;
|
||||||
if Self::check_reserved_word(&name.fragment) {
|
if Self::check_reserved_word(&name.fragment) {
|
||||||
return Err(Box::new(error::BuildError::with_pos(
|
return Err(error::BuildError::with_pos(
|
||||||
format!("Let {} binding collides with reserved word", name.fragment),
|
format!("Let {} binding collides with reserved word", name.fragment),
|
||||||
error::ErrorType::ReservedWordError,
|
error::ErrorType::ReservedWordError,
|
||||||
name.pos.clone(),
|
name.pos.clone(),
|
||||||
)));
|
)
|
||||||
|
.to_boxed());
|
||||||
}
|
}
|
||||||
match self.scope.build_output.entry(name.into()) {
|
match self.scope.build_output.entry(name.into()) {
|
||||||
Entry::Occupied(e) => {
|
Entry::Occupied(e) => {
|
||||||
return Err(Box::new(error::BuildError::with_pos(
|
return Err(error::BuildError::with_pos(
|
||||||
format!(
|
format!(
|
||||||
"Binding \
|
"Binding \
|
||||||
for {:?} already \
|
for {:?} already \
|
||||||
@ -475,7 +480,8 @@ impl<'a> FileBuilder<'a> {
|
|||||||
),
|
),
|
||||||
error::ErrorType::DuplicateBinding,
|
error::ErrorType::DuplicateBinding,
|
||||||
def.name.pos.clone(),
|
def.name.pos.clone(),
|
||||||
)));
|
)
|
||||||
|
.to_boxed());
|
||||||
}
|
}
|
||||||
Entry::Vacant(e) => {
|
Entry::Vacant(e) => {
|
||||||
e.insert(val.clone());
|
e.insert(val.clone());
|
||||||
@ -498,11 +504,12 @@ impl<'a> FileBuilder<'a> {
|
|||||||
self.out_lock = Some((typ.fragment.to_string(), val.clone()));
|
self.out_lock = Some((typ.fragment.to_string(), val.clone()));
|
||||||
Ok(val)
|
Ok(val)
|
||||||
} else {
|
} else {
|
||||||
Err(Box::new(error::BuildError::with_pos(
|
Err(error::BuildError::with_pos(
|
||||||
format!("You can only have one output per file."),
|
format!("You can only have one output per file."),
|
||||||
error::ErrorType::Unsupported,
|
error::ErrorType::Unsupported,
|
||||||
pos.clone(),
|
pos.clone(),
|
||||||
)))
|
)
|
||||||
|
.to_boxed())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -527,7 +534,7 @@ impl<'a> FileBuilder<'a> {
|
|||||||
return Ok(Rc::new(Val::Str([s.to_string(), ss.clone()].concat())));
|
return Ok(Rc::new(Val::Str([s.to_string(), ss.clone()].concat())));
|
||||||
}
|
}
|
||||||
val => {
|
val => {
|
||||||
return Err(Box::new(error::BuildError::with_pos(
|
return Err(error::BuildError::with_pos(
|
||||||
format!(
|
format!(
|
||||||
"Expected \
|
"Expected \
|
||||||
String \
|
String \
|
||||||
@ -537,7 +544,8 @@ impl<'a> FileBuilder<'a> {
|
|||||||
),
|
),
|
||||||
error::ErrorType::TypeFail,
|
error::ErrorType::TypeFail,
|
||||||
rpos.clone(),
|
rpos.clone(),
|
||||||
)));
|
)
|
||||||
|
.to_boxed());
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
Val::List(ref l) => match right.as_ref() {
|
Val::List(ref l) => match right.as_ref() {
|
||||||
@ -548,7 +556,7 @@ impl<'a> FileBuilder<'a> {
|
|||||||
return Ok(Rc::new(Val::List(new_vec)));
|
return Ok(Rc::new(Val::List(new_vec)));
|
||||||
}
|
}
|
||||||
val => {
|
val => {
|
||||||
return Err(Box::new(error::BuildError::with_pos(
|
return Err(error::BuildError::with_pos(
|
||||||
format!(
|
format!(
|
||||||
"Expected \
|
"Expected \
|
||||||
List \
|
List \
|
||||||
@ -558,15 +566,17 @@ impl<'a> FileBuilder<'a> {
|
|||||||
),
|
),
|
||||||
error::ErrorType::TypeFail,
|
error::ErrorType::TypeFail,
|
||||||
rpos.clone(),
|
rpos.clone(),
|
||||||
)));
|
)
|
||||||
|
.to_boxed());
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
ref expr => {
|
ref expr => {
|
||||||
return Err(Box::new(error::BuildError::with_pos(
|
return Err(error::BuildError::with_pos(
|
||||||
format!("{} does not support the '+' operation", expr.type_name()),
|
format!("{} does not support the '+' operation", expr.type_name()),
|
||||||
error::ErrorType::Unsupported,
|
error::ErrorType::Unsupported,
|
||||||
lpos.clone(),
|
lpos.clone(),
|
||||||
)));
|
)
|
||||||
|
.to_boxed());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -586,11 +596,12 @@ impl<'a> FileBuilder<'a> {
|
|||||||
eval_binary_expr!(&Val::Float(ff), rpos, right, Val::Float(f - ff), "Float")
|
eval_binary_expr!(&Val::Float(ff), rpos, right, Val::Float(f - ff), "Float")
|
||||||
}
|
}
|
||||||
ref expr => {
|
ref expr => {
|
||||||
return Err(Box::new(error::BuildError::with_pos(
|
return Err(error::BuildError::with_pos(
|
||||||
format!("{} does not support the '-' operation", expr.type_name()),
|
format!("{} does not support the '-' operation", expr.type_name()),
|
||||||
error::ErrorType::Unsupported,
|
error::ErrorType::Unsupported,
|
||||||
lpos.clone(),
|
lpos.clone(),
|
||||||
)));
|
)
|
||||||
|
.to_boxed());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -610,11 +621,12 @@ impl<'a> FileBuilder<'a> {
|
|||||||
eval_binary_expr!(&Val::Float(ff), rpos, right, Val::Float(f * ff), "Float")
|
eval_binary_expr!(&Val::Float(ff), rpos, right, Val::Float(f * ff), "Float")
|
||||||
}
|
}
|
||||||
ref expr => {
|
ref expr => {
|
||||||
return Err(Box::new(error::BuildError::with_pos(
|
return Err(error::BuildError::with_pos(
|
||||||
format!("{} does not support the '*' operation", expr.type_name()),
|
format!("{} does not support the '*' operation", expr.type_name()),
|
||||||
error::ErrorType::Unsupported,
|
error::ErrorType::Unsupported,
|
||||||
lpos.clone(),
|
lpos.clone(),
|
||||||
)));
|
)
|
||||||
|
.to_boxed());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -634,14 +646,15 @@ impl<'a> FileBuilder<'a> {
|
|||||||
eval_binary_expr!(&Val::Float(ff), rpos, right, Val::Float(f % ff), "Float")
|
eval_binary_expr!(&Val::Float(ff), rpos, right, Val::Float(f % ff), "Float")
|
||||||
}
|
}
|
||||||
ref expr => {
|
ref expr => {
|
||||||
return Err(Box::new(error::BuildError::with_pos(
|
return Err(error::BuildError::with_pos(
|
||||||
format!(
|
format!(
|
||||||
"{} does not support the 'modulus' operation",
|
"{} does not support the 'modulus' operation",
|
||||||
expr.type_name()
|
expr.type_name()
|
||||||
),
|
),
|
||||||
error::ErrorType::Unsupported,
|
error::ErrorType::Unsupported,
|
||||||
lpos.clone(),
|
lpos.clone(),
|
||||||
)));
|
)
|
||||||
|
.to_boxed());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -661,11 +674,12 @@ impl<'a> FileBuilder<'a> {
|
|||||||
eval_binary_expr!(&Val::Float(ff), rpos, right, Val::Float(f / ff), "Float")
|
eval_binary_expr!(&Val::Float(ff), rpos, right, Val::Float(f / ff), "Float")
|
||||||
}
|
}
|
||||||
ref expr => {
|
ref expr => {
|
||||||
return Err(Box::new(error::BuildError::with_pos(
|
return Err(error::BuildError::with_pos(
|
||||||
format!("{} does not support the '*' operation", expr.type_name()),
|
format!("{} does not support the '*' operation", expr.type_name()),
|
||||||
error::ErrorType::Unsupported,
|
error::ErrorType::Unsupported,
|
||||||
lpos.clone(),
|
lpos.clone(),
|
||||||
)));
|
)
|
||||||
|
.to_boxed());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -678,11 +692,7 @@ impl<'a> FileBuilder<'a> {
|
|||||||
) -> Result<Rc<Val>, Box<dyn Error>> {
|
) -> Result<Rc<Val>, Box<dyn Error>> {
|
||||||
match left.equal(right.as_ref()) {
|
match left.equal(right.as_ref()) {
|
||||||
Ok(b) => Ok(Rc::new(Val::Boolean(b))),
|
Ok(b) => Ok(Rc::new(Val::Boolean(b))),
|
||||||
Err(e) => Err(Box::new(error::BuildError::with_pos(
|
Err(e) => Err(error::BuildError::with_pos(e.msg, e.err_type, pos.clone()).to_boxed()),
|
||||||
e.msg,
|
|
||||||
e.err_type,
|
|
||||||
pos.clone(),
|
|
||||||
))),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -694,11 +704,7 @@ impl<'a> FileBuilder<'a> {
|
|||||||
) -> Result<Rc<Val>, Box<dyn Error>> {
|
) -> Result<Rc<Val>, Box<dyn Error>> {
|
||||||
match left.equal(right.as_ref()) {
|
match left.equal(right.as_ref()) {
|
||||||
Ok(b) => Ok(Rc::new(Val::Boolean(!b))),
|
Ok(b) => Ok(Rc::new(Val::Boolean(!b))),
|
||||||
Err(e) => Err(Box::new(error::BuildError::with_pos(
|
Err(e) => Err(error::BuildError::with_pos(e.msg, e.err_type, pos.clone()).to_boxed()),
|
||||||
e.msg,
|
|
||||||
e.err_type,
|
|
||||||
pos.clone(),
|
|
||||||
))),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -719,11 +725,12 @@ impl<'a> FileBuilder<'a> {
|
|||||||
return Ok(Rc::new(Val::Boolean(l > r)));
|
return Ok(Rc::new(Val::Boolean(l > r)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Err(Box::new(error::BuildError::with_pos(
|
Err(error::BuildError::with_pos(
|
||||||
format!("Expected {} but got ({})", left.type_name(), right,),
|
format!("Expected {} but got ({})", left.type_name(), right,),
|
||||||
error::ErrorType::TypeFail,
|
error::ErrorType::TypeFail,
|
||||||
pos.clone(),
|
pos.clone(),
|
||||||
)))
|
)
|
||||||
|
.to_boxed())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn do_lt(
|
fn do_lt(
|
||||||
@ -743,11 +750,12 @@ impl<'a> FileBuilder<'a> {
|
|||||||
return Ok(Rc::new(Val::Boolean(l < r)));
|
return Ok(Rc::new(Val::Boolean(l < r)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Err(Box::new(error::BuildError::with_pos(
|
Err(error::BuildError::with_pos(
|
||||||
format!("Expected {} but got ({})", left.type_name(), right,),
|
format!("Expected {} but got ({})", left.type_name(), right,),
|
||||||
error::ErrorType::TypeFail,
|
error::ErrorType::TypeFail,
|
||||||
pos.clone(),
|
pos.clone(),
|
||||||
)))
|
)
|
||||||
|
.to_boxed())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn do_ltequal(
|
fn do_ltequal(
|
||||||
@ -766,11 +774,12 @@ impl<'a> FileBuilder<'a> {
|
|||||||
return Ok(Rc::new(Val::Boolean(l <= r)));
|
return Ok(Rc::new(Val::Boolean(l <= r)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Err(Box::new(error::BuildError::with_pos(
|
Err(error::BuildError::with_pos(
|
||||||
format!("Expected {} but got ({})", left.type_name(), right),
|
format!("Expected {} but got ({})", left.type_name(), right),
|
||||||
error::ErrorType::TypeFail,
|
error::ErrorType::TypeFail,
|
||||||
pos.clone(),
|
pos.clone(),
|
||||||
)))
|
)
|
||||||
|
.to_boxed())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn do_gtequal(
|
fn do_gtequal(
|
||||||
@ -789,11 +798,12 @@ impl<'a> FileBuilder<'a> {
|
|||||||
return Ok(Rc::new(Val::Boolean(l >= r)));
|
return Ok(Rc::new(Val::Boolean(l >= r)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Err(Box::new(error::BuildError::with_pos(
|
Err(error::BuildError::with_pos(
|
||||||
format!("Expected {} but got ({})", left.type_name(), right,),
|
format!("Expected {} but got ({})", left.type_name(), right,),
|
||||||
error::ErrorType::TypeFail,
|
error::ErrorType::TypeFail,
|
||||||
pos.clone(),
|
pos.clone(),
|
||||||
)))
|
)
|
||||||
|
.to_boxed())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn do_dot_lookup(&self, right: &Expression, scope: &Scope) -> Result<Rc<Val>, Box<dyn Error>> {
|
fn do_dot_lookup(&self, right: &Expression, scope: &Scope) -> Result<Rc<Val>, Box<dyn Error>> {
|
||||||
@ -834,11 +844,12 @@ impl<'a> FileBuilder<'a> {
|
|||||||
error::ErrorType::NoSuchSymbol,
|
error::ErrorType::NoSuchSymbol,
|
||||||
pos,
|
pos,
|
||||||
))),
|
))),
|
||||||
_ => Err(Box::new(error::BuildError::with_pos(
|
_ => Err(error::BuildError::with_pos(
|
||||||
format!("Invalid selector lookup {}", val.type_name(),),
|
format!("Invalid selector lookup {}", val.type_name(),),
|
||||||
error::ErrorType::NoSuchSymbol,
|
error::ErrorType::NoSuchSymbol,
|
||||||
pos,
|
pos,
|
||||||
))),
|
)
|
||||||
|
.to_boxed()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -875,23 +886,25 @@ impl<'a> FileBuilder<'a> {
|
|||||||
return Ok(right);
|
return Ok(right);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return Err(Box::new(error::BuildError::with_pos(
|
return Err(error::BuildError::with_pos(
|
||||||
format!(
|
format!(
|
||||||
"Expected boolean value for operator but got ({})",
|
"Expected boolean value for operator but got ({})",
|
||||||
left.type_name()
|
left.type_name()
|
||||||
),
|
),
|
||||||
error::ErrorType::TypeFail,
|
error::ErrorType::TypeFail,
|
||||||
right_pos.clone(),
|
right_pos.clone(),
|
||||||
)));
|
)
|
||||||
|
.to_boxed());
|
||||||
} else {
|
} else {
|
||||||
return Err(Box::new(error::BuildError::with_pos(
|
return Err(error::BuildError::with_pos(
|
||||||
format!(
|
format!(
|
||||||
"Expected boolean value for operator but got ({})",
|
"Expected boolean value for operator but got ({})",
|
||||||
left.type_name()
|
left.type_name()
|
||||||
),
|
),
|
||||||
error::ErrorType::TypeFail,
|
error::ErrorType::TypeFail,
|
||||||
left_pos.clone(),
|
left_pos.clone(),
|
||||||
)));
|
)
|
||||||
|
.to_boxed());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -907,14 +920,15 @@ impl<'a> FileBuilder<'a> {
|
|||||||
let right = self.eval_expr(right, scope)?;
|
let right = self.eval_expr(right, scope)?;
|
||||||
// presence checks are only valid for tuples and lists.
|
// presence checks are only valid for tuples and lists.
|
||||||
if !(right.is_tuple() || right.is_list()) {
|
if !(right.is_tuple() || right.is_list()) {
|
||||||
return Err(Box::new(error::BuildError::with_pos(
|
return Err(error::BuildError::with_pos(
|
||||||
format!(
|
format!(
|
||||||
"Invalid righthand type for in operator {}",
|
"Invalid righthand type for in operator {}",
|
||||||
right.type_name()
|
right.type_name()
|
||||||
),
|
),
|
||||||
error::ErrorType::TypeFail,
|
error::ErrorType::TypeFail,
|
||||||
right_pos.clone(),
|
right_pos.clone(),
|
||||||
)));
|
)
|
||||||
|
.to_boxed());
|
||||||
}
|
}
|
||||||
if let &Val::List(ref els) = right.as_ref() {
|
if let &Val::List(ref els) = right.as_ref() {
|
||||||
let left = self.eval_expr(left, scope)?;
|
let left = self.eval_expr(left, scope)?;
|
||||||
@ -951,20 +965,22 @@ impl<'a> FileBuilder<'a> {
|
|||||||
let re = if let Val::Str(ref s) = right.as_ref() {
|
let re = if let Val::Str(ref s) = right.as_ref() {
|
||||||
regex::Regex::new(s.as_ref())?
|
regex::Regex::new(s.as_ref())?
|
||||||
} else {
|
} else {
|
||||||
return Err(Box::new(error::BuildError::with_pos(
|
return Err(error::BuildError::with_pos(
|
||||||
format!("Expected string for regex but got ({})", right.type_name()),
|
format!("Expected string for regex but got ({})", right.type_name()),
|
||||||
error::ErrorType::TypeFail,
|
error::ErrorType::TypeFail,
|
||||||
right_pos.clone(),
|
right_pos.clone(),
|
||||||
)));
|
)
|
||||||
|
.to_boxed());
|
||||||
};
|
};
|
||||||
let tgt = if let Val::Str(ref s) = left.as_ref() {
|
let tgt = if let Val::Str(ref s) = left.as_ref() {
|
||||||
s.as_ref()
|
s.as_ref()
|
||||||
} else {
|
} else {
|
||||||
return Err(Box::new(error::BuildError::with_pos(
|
return Err(error::BuildError::with_pos(
|
||||||
format!("Expected string but got ({})", left.type_name()),
|
format!("Expected string but got ({})", left.type_name()),
|
||||||
error::ErrorType::TypeFail,
|
error::ErrorType::TypeFail,
|
||||||
left_pos.clone(),
|
left_pos.clone(),
|
||||||
)));
|
)
|
||||||
|
.to_boxed());
|
||||||
};
|
};
|
||||||
return if negate {
|
return if negate {
|
||||||
Ok(Rc::new(Val::Boolean(!re.is_match(tgt))))
|
Ok(Rc::new(Val::Boolean(!re.is_match(tgt))))
|
||||||
@ -1053,7 +1069,7 @@ impl<'a> FileBuilder<'a> {
|
|||||||
v.insert((count, val.clone()));
|
v.insert((count, val.clone()));
|
||||||
count += 1;
|
count += 1;
|
||||||
} else {
|
} else {
|
||||||
return Err(Box::new(error::BuildError::new(
|
return Err(error::BuildError::new(
|
||||||
format!(
|
format!(
|
||||||
"Duplicate \
|
"Duplicate \
|
||||||
field: {} in \
|
field: {} in \
|
||||||
@ -1061,7 +1077,8 @@ impl<'a> FileBuilder<'a> {
|
|||||||
key
|
key
|
||||||
),
|
),
|
||||||
error::ErrorType::TypeFail,
|
error::ErrorType::TypeFail,
|
||||||
)));
|
)
|
||||||
|
.to_boxed());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for &(ref key, ref val) in overrides.iter() {
|
for &(ref key, ref val) in overrides.iter() {
|
||||||
@ -1082,7 +1099,7 @@ impl<'a> FileBuilder<'a> {
|
|||||||
{
|
{
|
||||||
v.insert((src_val.0, expr_result));
|
v.insert((src_val.0, expr_result));
|
||||||
} else {
|
} else {
|
||||||
return Err(Box::new(error::BuildError::with_pos(
|
return Err(error::BuildError::with_pos(
|
||||||
format!(
|
format!(
|
||||||
"Expected type {} for field {} but got ({})",
|
"Expected type {} for field {} but got ({})",
|
||||||
src_val.1.type_name(),
|
src_val.1.type_name(),
|
||||||
@ -1091,7 +1108,8 @@ impl<'a> FileBuilder<'a> {
|
|||||||
),
|
),
|
||||||
error::ErrorType::TypeFail,
|
error::ErrorType::TypeFail,
|
||||||
key.pos.clone(),
|
key.pos.clone(),
|
||||||
)));
|
)
|
||||||
|
.to_boxed());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -1140,7 +1158,7 @@ impl<'a> FileBuilder<'a> {
|
|||||||
PositionedItem::new_with_pos(String::from("mod"), Position::new(0, 0, 0));
|
PositionedItem::new_with_pos(String::from("mod"), Position::new(0, 0, 0));
|
||||||
match b.scope.build_output.entry(mod_key) {
|
match b.scope.build_output.entry(mod_key) {
|
||||||
Entry::Occupied(e) => {
|
Entry::Occupied(e) => {
|
||||||
return Err(Box::new(error::BuildError::with_pos(
|
return Err(error::BuildError::with_pos(
|
||||||
format!(
|
format!(
|
||||||
"Binding \
|
"Binding \
|
||||||
for {:?} already \
|
for {:?} already \
|
||||||
@ -1149,7 +1167,8 @@ impl<'a> FileBuilder<'a> {
|
|||||||
),
|
),
|
||||||
error::ErrorType::DuplicateBinding,
|
error::ErrorType::DuplicateBinding,
|
||||||
mod_def.pos.clone(),
|
mod_def.pos.clone(),
|
||||||
)));
|
)
|
||||||
|
.to_boxed());
|
||||||
}
|
}
|
||||||
Entry::Vacant(e) => {
|
Entry::Vacant(e) => {
|
||||||
e.insert(mod_args.clone());
|
e.insert(mod_args.clone());
|
||||||
@ -1161,21 +1180,23 @@ impl<'a> FileBuilder<'a> {
|
|||||||
// tuple using them.
|
// tuple using them.
|
||||||
return Ok(b.get_outputs_as_val());
|
return Ok(b.get_outputs_as_val());
|
||||||
} else {
|
} else {
|
||||||
return Err(Box::new(error::BuildError::with_pos(
|
return Err(error::BuildError::with_pos(
|
||||||
format!(
|
format!(
|
||||||
"Weird value stored in our module parameters slot {:?}",
|
"Weird value stored in our module parameters slot {:?}",
|
||||||
mod_def.arg_tuple
|
mod_def.arg_tuple
|
||||||
),
|
),
|
||||||
error::ErrorType::TypeFail,
|
error::ErrorType::TypeFail,
|
||||||
def.selector.pos().clone(),
|
def.selector.pos().clone(),
|
||||||
)));
|
)
|
||||||
|
.to_boxed());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Err(Box::new(error::BuildError::with_pos(
|
Err(error::BuildError::with_pos(
|
||||||
format!("Expected Tuple or Module but got ({})", v),
|
format!("Expected Tuple or Module but got ({})", v),
|
||||||
error::ErrorType::TypeFail,
|
error::ErrorType::TypeFail,
|
||||||
def.selector.pos().clone(),
|
def.selector.pos().clone(),
|
||||||
)))
|
)
|
||||||
|
.to_boxed())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn eval_format(&self, def: &FormatDef, scope: &Scope) -> Result<Rc<Val>, Box<dyn Error>> {
|
fn eval_format(&self, def: &FormatDef, scope: &Scope) -> Result<Rc<Val>, Box<dyn Error>> {
|
||||||
@ -1215,19 +1236,21 @@ impl<'a> FileBuilder<'a> {
|
|||||||
}
|
}
|
||||||
return match def.eval(self, argvals) {
|
return match def.eval(self, argvals) {
|
||||||
Ok(v) => Ok(v),
|
Ok(v) => Ok(v),
|
||||||
Err(e) => Err(Box::new(error::BuildError::with_pos(
|
Err(e) => Err(error::BuildError::with_pos(
|
||||||
format!("Func evaluation failed\nCaused by:\n\t{}", e),
|
format!("Func evaluation failed\nCaused by:\n\t{}", e),
|
||||||
error::ErrorType::TypeFail,
|
error::ErrorType::TypeFail,
|
||||||
call_pos,
|
call_pos,
|
||||||
))),
|
)
|
||||||
|
.to_boxed()),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
Err(Box::new(error::BuildError::with_pos(
|
Err(error::BuildError::with_pos(
|
||||||
// We should pretty print the selectors here.
|
// We should pretty print the selectors here.
|
||||||
format!("{} is not a Function", v),
|
format!("{} is not a Function", v),
|
||||||
error::ErrorType::TypeFail,
|
error::ErrorType::TypeFail,
|
||||||
def.pos.clone(),
|
def.pos.clone(),
|
||||||
)))
|
)
|
||||||
|
.to_boxed())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn eval_func_def(&self, def: &mut FuncDef, scope: &Scope) -> Result<Rc<Val>, Box<dyn Error>> {
|
fn eval_func_def(&self, def: &mut FuncDef, scope: &Scope) -> Result<Rc<Val>, Box<dyn Error>> {
|
||||||
@ -1288,7 +1311,7 @@ impl<'a> FileBuilder<'a> {
|
|||||||
// Otherwise return the default.
|
// Otherwise return the default.
|
||||||
return self.eval_expr(def_expr, scope);
|
return self.eval_expr(def_expr, scope);
|
||||||
} else {
|
} else {
|
||||||
return Err(Box::new(error::BuildError::with_pos(
|
return Err(error::BuildError::with_pos(
|
||||||
format!(
|
format!(
|
||||||
"Expected String but got \
|
"Expected String but got \
|
||||||
{} in Select expression",
|
{} in Select expression",
|
||||||
@ -1296,7 +1319,8 @@ impl<'a> FileBuilder<'a> {
|
|||||||
),
|
),
|
||||||
error::ErrorType::TypeFail,
|
error::ErrorType::TypeFail,
|
||||||
def.pos.clone(),
|
def.pos.clone(),
|
||||||
)));
|
)
|
||||||
|
.to_boxed());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1348,35 +1372,36 @@ impl<'a> FileBuilder<'a> {
|
|||||||
let new_name = if let &Val::Str(ref s) = fs[0].as_ref() {
|
let new_name = if let &Val::Str(ref s) = fs[0].as_ref() {
|
||||||
s.clone()
|
s.clone()
|
||||||
} else {
|
} else {
|
||||||
return Err(Box::new(error::BuildError::with_pos(
|
return Err(error::BuildError::with_pos(
|
||||||
format!(
|
format!(
|
||||||
"map on tuple expects the first item out list to be a string but got size {}",
|
"map on tuple expects the first item out list to be a string but got size {}",
|
||||||
fs[0].type_name()
|
fs[0].type_name()
|
||||||
),
|
),
|
||||||
error::ErrorType::TypeFail,
|
error::ErrorType::TypeFail,
|
||||||
def.pos.clone(),
|
def.pos.clone(),
|
||||||
)));
|
).to_boxed());
|
||||||
};
|
};
|
||||||
out.push((new_name, fs[1].clone()));
|
out.push((new_name, fs[1].clone()));
|
||||||
} else {
|
} else {
|
||||||
return Err(Box::new(error::BuildError::with_pos(
|
return Err(error::BuildError::with_pos(
|
||||||
format!(
|
format!(
|
||||||
"map on a tuple field expects a list of size 2 as output but got size {}",
|
"map on a tuple field expects a list of size 2 as output but got size {}",
|
||||||
fs.len()
|
fs.len()
|
||||||
),
|
),
|
||||||
error::ErrorType::TypeFail,
|
error::ErrorType::TypeFail,
|
||||||
def.pos.clone(),
|
def.pos.clone(),
|
||||||
)));
|
).to_boxed());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return Err(Box::new(error::BuildError::with_pos(
|
return Err(error::BuildError::with_pos(
|
||||||
format!(
|
format!(
|
||||||
"map on a tuple field expects a list as output but got ({})",
|
"map on a tuple field expects a list as output but got ({})",
|
||||||
result.type_name()
|
result.type_name()
|
||||||
),
|
),
|
||||||
error::ErrorType::TypeFail,
|
error::ErrorType::TypeFail,
|
||||||
def.pos.clone(),
|
def.pos.clone(),
|
||||||
)));
|
)
|
||||||
|
.to_boxed());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ProcessingOpType::Filter => {
|
ProcessingOpType::Filter => {
|
||||||
@ -1401,11 +1426,12 @@ impl<'a> FileBuilder<'a> {
|
|||||||
let funcdef = match maybe_mac.as_ref() {
|
let funcdef = match maybe_mac.as_ref() {
|
||||||
&Val::Func(ref funcdef) => funcdef,
|
&Val::Func(ref funcdef) => funcdef,
|
||||||
_ => {
|
_ => {
|
||||||
return Err(Box::new(error::BuildError::with_pos(
|
return Err(error::BuildError::with_pos(
|
||||||
format!("Expected func but got {:?}", def.func),
|
format!("Expected func but got {:?}", def.func),
|
||||||
error::ErrorType::TypeFail,
|
error::ErrorType::TypeFail,
|
||||||
def.pos.clone(),
|
def.pos.clone(),
|
||||||
)));
|
)
|
||||||
|
.to_boxed());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
match maybe_target.as_ref() {
|
match maybe_target.as_ref() {
|
||||||
@ -1431,14 +1457,15 @@ impl<'a> FileBuilder<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
other => {
|
other => {
|
||||||
return Err(Box::new(error::BuildError::with_pos(
|
return Err(error::BuildError::with_pos(
|
||||||
format!(
|
format!(
|
||||||
"Expected List Str, or Tuple as target but got {:?}",
|
"Expected List Str, or Tuple as target but got {:?}",
|
||||||
other.type_name()
|
other.type_name()
|
||||||
),
|
),
|
||||||
error::ErrorType::TypeFail,
|
error::ErrorType::TypeFail,
|
||||||
def.target.pos().clone(),
|
def.target.pos().clone(),
|
||||||
)));
|
)
|
||||||
|
.to_boxed());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(acc)
|
Ok(acc)
|
||||||
@ -1466,14 +1493,15 @@ impl<'a> FileBuilder<'a> {
|
|||||||
// noop
|
// noop
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
return Err(Box::new(error::BuildError::with_pos(
|
return Err(error::BuildError::with_pos(
|
||||||
format!(
|
format!(
|
||||||
"Expected boolean or NULL for filter return but got ({})",
|
"Expected boolean or NULL for filter return but got ({})",
|
||||||
out.type_name()
|
out.type_name()
|
||||||
),
|
),
|
||||||
error::ErrorType::TypeFail,
|
error::ErrorType::TypeFail,
|
||||||
def.pos.clone(),
|
def.pos.clone(),
|
||||||
)));
|
)
|
||||||
|
.to_boxed());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1482,11 +1510,12 @@ impl<'a> FileBuilder<'a> {
|
|||||||
result.push_str(&s);
|
result.push_str(&s);
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
return Err(Box::new(error::BuildError::with_pos(
|
return Err(error::BuildError::with_pos(
|
||||||
format!("Expected string map return but got ({})", out.type_name()),
|
format!("Expected string map return but got ({})", out.type_name()),
|
||||||
error::ErrorType::TypeFail,
|
error::ErrorType::TypeFail,
|
||||||
def.pos.clone(),
|
def.pos.clone(),
|
||||||
)));
|
)
|
||||||
|
.to_boxed());
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@ -1505,11 +1534,12 @@ impl<'a> FileBuilder<'a> {
|
|||||||
let macdef = match maybe_mac.as_ref() {
|
let macdef = match maybe_mac.as_ref() {
|
||||||
&Val::Func(ref macdef) => macdef,
|
&Val::Func(ref macdef) => macdef,
|
||||||
_ => {
|
_ => {
|
||||||
return Err(Box::new(error::BuildError::with_pos(
|
return Err(error::BuildError::with_pos(
|
||||||
format!("Expected func but got {:?}", def.func),
|
format!("Expected func but got {:?}", def.func),
|
||||||
error::ErrorType::TypeFail,
|
error::ErrorType::TypeFail,
|
||||||
def.pos.clone(),
|
def.pos.clone(),
|
||||||
)));
|
)
|
||||||
|
.to_boxed());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
return match maybe_target.as_ref() {
|
return match maybe_target.as_ref() {
|
||||||
@ -1517,14 +1547,15 @@ impl<'a> FileBuilder<'a> {
|
|||||||
&Val::Tuple(ref fs) => self.eval_functional_tuple_processing(fs, macdef, typ),
|
&Val::Tuple(ref fs) => self.eval_functional_tuple_processing(fs, macdef, typ),
|
||||||
// TODO(jwall): Strings?
|
// TODO(jwall): Strings?
|
||||||
&Val::Str(ref s) => self.eval_functional_string_processing(s, macdef, typ),
|
&Val::Str(ref s) => self.eval_functional_string_processing(s, macdef, typ),
|
||||||
other => Err(Box::new(error::BuildError::with_pos(
|
other => Err(error::BuildError::with_pos(
|
||||||
format!(
|
format!(
|
||||||
"Expected List or Tuple as target but got {:?}",
|
"Expected List or Tuple as target but got {:?}",
|
||||||
other.type_name()
|
other.type_name()
|
||||||
),
|
),
|
||||||
error::ErrorType::TypeFail,
|
error::ErrorType::TypeFail,
|
||||||
def.target.pos().clone(),
|
def.target.pos().clone(),
|
||||||
))),
|
)
|
||||||
|
.to_boxed()),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1627,21 +1658,23 @@ impl<'a> FileBuilder<'a> {
|
|||||||
let normalized = match self.find_file(path, false) {
|
let normalized = match self.find_file(path, false) {
|
||||||
Ok(p) => p,
|
Ok(p) => p,
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
return Err(Box::new(error::BuildError::with_pos(
|
return Err(error::BuildError::with_pos(
|
||||||
format!("Error finding file {} {}", path, e),
|
format!("Error finding file {} {}", path, e),
|
||||||
error::ErrorType::TypeFail,
|
error::ErrorType::TypeFail,
|
||||||
pos.clone(),
|
pos.clone(),
|
||||||
)));
|
)
|
||||||
|
.to_boxed());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
let mut f = match File::open(&normalized) {
|
let mut f = match File::open(&normalized) {
|
||||||
Ok(f) => f,
|
Ok(f) => f,
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
return Err(Box::new(error::BuildError::with_pos(
|
return Err(error::BuildError::with_pos(
|
||||||
format!("Error opening file {} {}", normalized.to_string_lossy(), e),
|
format!("Error opening file {} {}", normalized.to_string_lossy(), e),
|
||||||
error::ErrorType::TypeFail,
|
error::ErrorType::TypeFail,
|
||||||
pos.clone(),
|
pos.clone(),
|
||||||
)));
|
)
|
||||||
|
.to_boxed());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
let mut contents = String::new();
|
let mut contents = String::new();
|
||||||
@ -1681,11 +1714,12 @@ impl<'a> FileBuilder<'a> {
|
|||||||
};
|
};
|
||||||
Ok(val)
|
Ok(val)
|
||||||
}
|
}
|
||||||
None => Err(Box::new(error::BuildError::with_pos(
|
None => Err(error::BuildError::with_pos(
|
||||||
format!("Unknown include conversion type {}", def.typ.fragment),
|
format!("Unknown include conversion type {}", def.typ.fragment),
|
||||||
error::ErrorType::Unsupported,
|
error::ErrorType::Unsupported,
|
||||||
def.typ.pos.clone(),
|
def.typ.pos.clone(),
|
||||||
))),
|
)
|
||||||
|
.to_boxed()),
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -1707,14 +1741,15 @@ impl<'a> FileBuilder<'a> {
|
|||||||
let start = match start.as_ref() {
|
let start = match start.as_ref() {
|
||||||
&Val::Int(i) => i,
|
&Val::Int(i) => i,
|
||||||
_ => {
|
_ => {
|
||||||
return Err(Box::new(error::BuildError::with_pos(
|
return Err(error::BuildError::with_pos(
|
||||||
format!(
|
format!(
|
||||||
"Expected an integer for range start but got ({})",
|
"Expected an integer for range start but got ({})",
|
||||||
start.type_name()
|
start.type_name()
|
||||||
),
|
),
|
||||||
error::ErrorType::TypeFail,
|
error::ErrorType::TypeFail,
|
||||||
def.start.pos().clone(),
|
def.start.pos().clone(),
|
||||||
)));
|
)
|
||||||
|
.to_boxed());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
// See if there was a step.
|
// See if there was a step.
|
||||||
@ -1724,14 +1759,15 @@ impl<'a> FileBuilder<'a> {
|
|||||||
match step.as_ref() {
|
match step.as_ref() {
|
||||||
&Val::Int(i) => i,
|
&Val::Int(i) => i,
|
||||||
_ => {
|
_ => {
|
||||||
return Err(Box::new(error::BuildError::with_pos(
|
return Err(error::BuildError::with_pos(
|
||||||
format!(
|
format!(
|
||||||
"Expected an integer for range step but got ({})",
|
"Expected an integer for range step but got ({})",
|
||||||
step.type_name()
|
step.type_name()
|
||||||
),
|
),
|
||||||
error::ErrorType::TypeFail,
|
error::ErrorType::TypeFail,
|
||||||
def.start.pos().clone(),
|
def.start.pos().clone(),
|
||||||
)));
|
)
|
||||||
|
.to_boxed());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1743,14 +1779,15 @@ impl<'a> FileBuilder<'a> {
|
|||||||
let end = match end.as_ref() {
|
let end = match end.as_ref() {
|
||||||
&Val::Int(i) => i,
|
&Val::Int(i) => i,
|
||||||
_ => {
|
_ => {
|
||||||
return Err(Box::new(error::BuildError::with_pos(
|
return Err(error::BuildError::with_pos(
|
||||||
format!(
|
format!(
|
||||||
"Expected an integer for range start but got ({})",
|
"Expected an integer for range start but got ({})",
|
||||||
end.type_name()
|
end.type_name()
|
||||||
),
|
),
|
||||||
error::ErrorType::TypeFail,
|
error::ErrorType::TypeFail,
|
||||||
def.start.pos().clone(),
|
def.start.pos().clone(),
|
||||||
)));
|
)
|
||||||
|
.to_boxed());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1770,11 +1807,12 @@ impl<'a> FileBuilder<'a> {
|
|||||||
let typ = match tval.as_ref() {
|
let typ = match tval.as_ref() {
|
||||||
Val::Str(ref s) => s.clone(),
|
Val::Str(ref s) => s.clone(),
|
||||||
_ => {
|
_ => {
|
||||||
return Err(Box::new(error::BuildError::with_pos(
|
return Err(error::BuildError::with_pos(
|
||||||
format!("Expected string expression but got ({})", tval),
|
format!("Expected string expression but got ({})", tval),
|
||||||
error::ErrorType::TypeFail,
|
error::ErrorType::TypeFail,
|
||||||
def.right.pos().clone(),
|
def.right.pos().clone(),
|
||||||
)));
|
)
|
||||||
|
.to_boxed());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
let val = self.eval_expr(def.left.as_ref(), scope)?;
|
let val = self.eval_expr(def.left.as_ref(), scope)?;
|
||||||
@ -1789,11 +1827,12 @@ impl<'a> FileBuilder<'a> {
|
|||||||
"func" => val.is_func(),
|
"func" => val.is_func(),
|
||||||
"module" => val.is_module(),
|
"module" => val.is_module(),
|
||||||
other => {
|
other => {
|
||||||
return Err(Box::new(error::BuildError::with_pos(
|
return Err(error::BuildError::with_pos(
|
||||||
format!("Expected valid type name but got ({})", other),
|
format!("Expected valid type name but got ({})", other),
|
||||||
error::ErrorType::TypeFail,
|
error::ErrorType::TypeFail,
|
||||||
def.right.pos().clone(),
|
def.right.pos().clone(),
|
||||||
)));
|
)
|
||||||
|
.to_boxed());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
Ok(Rc::new(Val::Boolean(result)))
|
Ok(Rc::new(Val::Boolean(result)))
|
||||||
@ -1825,20 +1864,22 @@ impl<'a> FileBuilder<'a> {
|
|||||||
&Expression::Fail(ref def) => {
|
&Expression::Fail(ref def) => {
|
||||||
let err = self.eval_expr(&def.message, scope)?;
|
let err = self.eval_expr(&def.message, scope)?;
|
||||||
return if let Val::Str(ref s) = err.as_ref() {
|
return if let Val::Str(ref s) = err.as_ref() {
|
||||||
Err(Box::new(error::BuildError::with_pos(
|
Err(error::BuildError::with_pos(
|
||||||
s.clone(),
|
s.clone(),
|
||||||
error::ErrorType::UserDefined,
|
error::ErrorType::UserDefined,
|
||||||
def.pos.clone(),
|
def.pos.clone(),
|
||||||
)))
|
)
|
||||||
|
.to_boxed())
|
||||||
} else {
|
} else {
|
||||||
Err(Box::new(error::BuildError::with_pos(
|
Err(error::BuildError::with_pos(
|
||||||
format!(
|
format!(
|
||||||
"Expected string for message but got ({})",
|
"Expected string for message but got ({})",
|
||||||
def.message.as_ref()
|
def.message.as_ref()
|
||||||
),
|
),
|
||||||
error::ErrorType::TypeFail,
|
error::ErrorType::TypeFail,
|
||||||
def.message.pos().clone(),
|
def.message.pos().clone(),
|
||||||
)))
|
)
|
||||||
|
.to_boxed())
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
&Expression::Not(ref def) => {
|
&Expression::Not(ref def) => {
|
||||||
@ -1846,14 +1887,15 @@ impl<'a> FileBuilder<'a> {
|
|||||||
return if let Val::Boolean(b) = val.as_ref() {
|
return if let Val::Boolean(b) = val.as_ref() {
|
||||||
Ok(Rc::new(Val::Boolean(!b)))
|
Ok(Rc::new(Val::Boolean(!b)))
|
||||||
} else {
|
} else {
|
||||||
Err(Box::new(error::BuildError::with_pos(
|
Err(error::BuildError::with_pos(
|
||||||
format!(
|
format!(
|
||||||
"Expected boolean for expression but got ({})",
|
"Expected boolean for expression but got ({})",
|
||||||
def.expr.as_ref()
|
def.expr.as_ref()
|
||||||
),
|
),
|
||||||
error::ErrorType::TypeFail,
|
error::ErrorType::TypeFail,
|
||||||
def.expr.pos().clone(),
|
def.expr.pos().clone(),
|
||||||
)))
|
)
|
||||||
|
.to_boxed())
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -115,11 +115,12 @@ impl Scope {
|
|||||||
return Self::lookup_in_list(pos, idx, fs);
|
return Self::lookup_in_list(pos, idx, fs);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Err(Box::new(error::BuildError::with_pos(
|
Err(error::BuildError::with_pos(
|
||||||
"Not a list in index lookup.",
|
"Not a list in index lookup.",
|
||||||
error::ErrorType::TypeFail,
|
error::ErrorType::TypeFail,
|
||||||
pos.clone(),
|
pos.clone(),
|
||||||
)))
|
)
|
||||||
|
.to_boxed())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Lookup a symbol in the current execution context.
|
/// Lookup a symbol in the current execution context.
|
||||||
@ -189,11 +190,12 @@ impl Scope {
|
|||||||
if let Some(vv) = find_in_fieldlist(&field, fs) {
|
if let Some(vv) = find_in_fieldlist(&field, fs) {
|
||||||
Ok(vv)
|
Ok(vv)
|
||||||
} else {
|
} else {
|
||||||
Err(Box::new(error::BuildError::with_pos(
|
Err(error::BuildError::with_pos(
|
||||||
format!("Unable to {} match element in tuple.", field,),
|
format!("Unable to {} match element in tuple.", field,),
|
||||||
error::ErrorType::NoSuchSymbol,
|
error::ErrorType::NoSuchSymbol,
|
||||||
pos.clone(),
|
pos.clone(),
|
||||||
)))
|
)
|
||||||
|
.to_boxed())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -206,21 +208,23 @@ impl Scope {
|
|||||||
&Val::Int(i) => i as usize,
|
&Val::Int(i) => i as usize,
|
||||||
&Val::Str(ref s) => s.parse::<usize>()?,
|
&Val::Str(ref s) => s.parse::<usize>()?,
|
||||||
_ => {
|
_ => {
|
||||||
return Err(Box::new(error::BuildError::with_pos(
|
return Err(error::BuildError::with_pos(
|
||||||
format!("Invalid idx type {} for list lookup", field),
|
format!("Invalid idx type {} for list lookup", field),
|
||||||
error::ErrorType::TypeFail,
|
error::ErrorType::TypeFail,
|
||||||
pos.clone(),
|
pos.clone(),
|
||||||
)));
|
)
|
||||||
|
.to_boxed());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
if idx < elems.len() {
|
if idx < elems.len() {
|
||||||
Ok(elems[idx].clone())
|
Ok(elems[idx].clone())
|
||||||
} else {
|
} else {
|
||||||
Err(Box::new(error::BuildError::with_pos(
|
Err(error::BuildError::with_pos(
|
||||||
format!("idx {} out of bounds in list", idx),
|
format!("idx {} out of bounds in list", idx),
|
||||||
error::ErrorType::NoSuchSymbol,
|
error::ErrorType::NoSuchSymbol,
|
||||||
pos.clone(),
|
pos.clone(),
|
||||||
)))
|
)
|
||||||
|
.to_boxed())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -42,10 +42,11 @@ impl ExecConverter {
|
|||||||
if let &Tuple(ref fields) = v {
|
if let &Tuple(ref fields) = v {
|
||||||
// We expect no more than three fields in our exec tuple.
|
// We expect no more than three fields in our exec tuple.
|
||||||
if fields.len() > 3 {
|
if fields.len() > 3 {
|
||||||
return Err(Box::new(BuildError::new(
|
return Err(BuildError::new(
|
||||||
"Exec tuples must have no more than 3 fields",
|
"Exec tuples must have no more than 3 fields",
|
||||||
ErrorType::TypeFail,
|
ErrorType::TypeFail,
|
||||||
)));
|
)
|
||||||
|
.to_boxed());
|
||||||
}
|
}
|
||||||
let mut env: Option<&Vec<(String, Rc<Val>)>> = None;
|
let mut env: Option<&Vec<(String, Rc<Val>)>> = None;
|
||||||
let mut command: Option<&str> = None;
|
let mut command: Option<&str> = None;
|
||||||
@ -54,60 +55,67 @@ impl ExecConverter {
|
|||||||
// We require a command field in our exec tuple.
|
// We require a command field in our exec tuple.
|
||||||
if name == "command" {
|
if name == "command" {
|
||||||
if command.is_some() {
|
if command.is_some() {
|
||||||
return Err(Box::new(BuildError::new(
|
return Err(BuildError::new(
|
||||||
"There can only be one command field in an exec tuple",
|
"There can only be one command field in an exec tuple",
|
||||||
ErrorType::TypeFail,
|
ErrorType::TypeFail,
|
||||||
)));
|
)
|
||||||
|
.to_boxed());
|
||||||
}
|
}
|
||||||
if let &Val::Str(ref s) = val.as_ref() {
|
if let &Val::Str(ref s) = val.as_ref() {
|
||||||
command = Some(s);
|
command = Some(s);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
return Err(Box::new(BuildError::new(
|
return Err(BuildError::new(
|
||||||
"The command field of an exec tuple must be a string",
|
"The command field of an exec tuple must be a string",
|
||||||
ErrorType::TypeFail,
|
ErrorType::TypeFail,
|
||||||
)));
|
)
|
||||||
|
.to_boxed());
|
||||||
}
|
}
|
||||||
// We optionally allow an env field in our exec tuple.
|
// We optionally allow an env field in our exec tuple.
|
||||||
if name == "env" {
|
if name == "env" {
|
||||||
if let &Val::Tuple(ref l) = val.as_ref() {
|
if let &Val::Tuple(ref l) = val.as_ref() {
|
||||||
if env.is_some() {
|
if env.is_some() {
|
||||||
return Err(Box::new(BuildError::new(
|
return Err(BuildError::new(
|
||||||
"There can only be one env field in an exec tuple",
|
"There can only be one env field in an exec tuple",
|
||||||
ErrorType::TypeFail,
|
ErrorType::TypeFail,
|
||||||
)));
|
)
|
||||||
|
.to_boxed());
|
||||||
}
|
}
|
||||||
env = Some(l);
|
env = Some(l);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
return Err(Box::new(BuildError::new(
|
return Err(BuildError::new(
|
||||||
"The env field of an exec tuple must be a list",
|
"The env field of an exec tuple must be a list",
|
||||||
ErrorType::TypeFail,
|
ErrorType::TypeFail,
|
||||||
)));
|
)
|
||||||
|
.to_boxed());
|
||||||
}
|
}
|
||||||
// We optionally allow an args field in our exec tuple.
|
// We optionally allow an args field in our exec tuple.
|
||||||
if name == "args" {
|
if name == "args" {
|
||||||
if let &Val::List(ref l) = val.as_ref() {
|
if let &Val::List(ref l) = val.as_ref() {
|
||||||
if args.is_some() {
|
if args.is_some() {
|
||||||
return Err(Box::new(BuildError::new(
|
return Err(BuildError::new(
|
||||||
"There can only be one args field of an exec tuple",
|
"There can only be one args field of an exec tuple",
|
||||||
ErrorType::TypeFail,
|
ErrorType::TypeFail,
|
||||||
)));
|
)
|
||||||
|
.to_boxed());
|
||||||
}
|
}
|
||||||
args = Some(l);
|
args = Some(l);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
return Err(Box::new(BuildError::new(
|
return Err(BuildError::new(
|
||||||
"The args field of an exec tuple must be a list",
|
"The args field of an exec tuple must be a list",
|
||||||
ErrorType::TypeFail,
|
ErrorType::TypeFail,
|
||||||
)));
|
)
|
||||||
|
.to_boxed());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if command.is_none() {
|
if command.is_none() {
|
||||||
return Err(Box::new(BuildError::new(
|
return Err(BuildError::new(
|
||||||
"An exec tuple must have a command field",
|
"An exec tuple must have a command field",
|
||||||
ErrorType::TypeFail,
|
ErrorType::TypeFail,
|
||||||
)));
|
)
|
||||||
|
.to_boxed());
|
||||||
}
|
}
|
||||||
// Okay if we have made it this far then we are ready to start creating our script.
|
// Okay if we have made it this far then we are ready to start creating our script.
|
||||||
let mut script = Cursor::new(vec![]);
|
let mut script = Cursor::new(vec![]);
|
||||||
@ -124,10 +132,11 @@ impl ExecConverter {
|
|||||||
write!(script, "{}=\"{}\"\n", name, s)?;
|
write!(script, "{}=\"{}\"\n", name, s)?;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
return Err(Box::new(BuildError::new(
|
return Err(BuildError::new(
|
||||||
"The env fields of an exec tuple must contain only string values",
|
"The env fields of an exec tuple must contain only string values",
|
||||||
ErrorType::TypeFail,
|
ErrorType::TypeFail,
|
||||||
)));
|
)
|
||||||
|
.to_boxed());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
write!(script, "\n")?;
|
write!(script, "\n")?;
|
||||||
@ -144,10 +153,11 @@ impl ExecConverter {
|
|||||||
}
|
}
|
||||||
&Val::Tuple(_) => flag_converter.convert(v.clone(), &mut script)?,
|
&Val::Tuple(_) => flag_converter.convert(v.clone(), &mut script)?,
|
||||||
_ => {
|
_ => {
|
||||||
return Err(Box::new(BuildError::new(
|
return Err(BuildError::new(
|
||||||
"Exec args must be a list of strings or tuples of strings.",
|
"Exec args must be a list of strings or tuples of strings.",
|
||||||
ErrorType::TypeFail,
|
ErrorType::TypeFail,
|
||||||
)));
|
)
|
||||||
|
.to_boxed());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -159,10 +169,7 @@ impl ExecConverter {
|
|||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
Err(Box::new(BuildError::new(
|
Err(BuildError::new("Exec outputs must be of type Tuple", ErrorType::TypeFail).to_boxed())
|
||||||
"Exec outputs must be of type Tuple",
|
|
||||||
ErrorType::TypeFail,
|
|
||||||
)))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -34,10 +34,7 @@ impl XmlConverter {
|
|||||||
if let Val::Str(ref s) = v {
|
if let Val::Str(ref s) = v {
|
||||||
Ok(s)
|
Ok(s)
|
||||||
} else {
|
} else {
|
||||||
Err(Box::new(BuildError::new(
|
Err(BuildError::new("Not a String value", ErrorType::TypeFail).to_boxed())
|
||||||
"Not a String value",
|
|
||||||
ErrorType::TypeFail,
|
|
||||||
)))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -45,10 +42,7 @@ impl XmlConverter {
|
|||||||
if let Val::Tuple(ref fs) = v {
|
if let Val::Tuple(ref fs) = v {
|
||||||
Ok(fs)
|
Ok(fs)
|
||||||
} else {
|
} else {
|
||||||
Err(Box::new(BuildError::new(
|
Err(BuildError::new("Not a tuple value", ErrorType::TypeFail).to_boxed())
|
||||||
"Not a tuple value",
|
|
||||||
ErrorType::TypeFail,
|
|
||||||
)))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -56,10 +50,7 @@ impl XmlConverter {
|
|||||||
if let Val::List(ref fs) = v {
|
if let Val::List(ref fs) = v {
|
||||||
Ok(fs)
|
Ok(fs)
|
||||||
} else {
|
} else {
|
||||||
Err(Box::new(BuildError::new(
|
Err(BuildError::new("Not a List value", ErrorType::TypeFail).to_boxed())
|
||||||
"Not a List value",
|
|
||||||
ErrorType::TypeFail,
|
|
||||||
)))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -116,10 +107,11 @@ impl XmlConverter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if name.is_some() && text.is_some() {
|
if name.is_some() && text.is_some() {
|
||||||
return Err(Box::new(BuildError::new(
|
return Err(BuildError::new(
|
||||||
"XML nodes can not have both text and name fields",
|
"XML nodes can not have both text and name fields",
|
||||||
ErrorType::TypeFail,
|
ErrorType::TypeFail,
|
||||||
)));
|
)
|
||||||
|
.to_boxed());
|
||||||
}
|
}
|
||||||
if name.is_some() {
|
if name.is_some() {
|
||||||
let mut start = XmlEvent::start_element(name.unwrap());
|
let mut start = XmlEvent::start_element(name.unwrap());
|
||||||
@ -152,10 +144,11 @@ impl XmlConverter {
|
|||||||
} else if let Val::Str(ref s) = v {
|
} else if let Val::Str(ref s) = v {
|
||||||
w.write(XmlEvent::characters(s.as_ref()))?;
|
w.write(XmlEvent::characters(s.as_ref()))?;
|
||||||
} else {
|
} else {
|
||||||
return Err(Box::new(BuildError::new(
|
return Err(BuildError::new(
|
||||||
"XML nodes must be a Tuple or a string",
|
"XML nodes must be a Tuple or a string",
|
||||||
ErrorType::TypeFail,
|
ErrorType::TypeFail,
|
||||||
)));
|
)
|
||||||
|
.to_boxed());
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -200,10 +193,11 @@ impl XmlConverter {
|
|||||||
} else {
|
} else {
|
||||||
// If they specified the wrong version then
|
// If they specified the wrong version then
|
||||||
// error out.
|
// error out.
|
||||||
return Err(Box::new(BuildError::new(
|
return Err(BuildError::new(
|
||||||
"XML version must be either 1.0 or 1.1",
|
"XML version must be either 1.0 or 1.1",
|
||||||
ErrorType::TypeFail,
|
ErrorType::TypeFail,
|
||||||
)));
|
)
|
||||||
|
.to_boxed());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
None => None,
|
None => None,
|
||||||
@ -216,16 +210,14 @@ impl XmlConverter {
|
|||||||
})?;
|
})?;
|
||||||
self.write_node(n.as_ref(), &mut writer)
|
self.write_node(n.as_ref(), &mut writer)
|
||||||
}
|
}
|
||||||
None => Err(Box::new(BuildError::new(
|
None => Err(BuildError::new(
|
||||||
"XML doc tuples must have a root field",
|
"XML doc tuples must have a root field",
|
||||||
ErrorType::TypeFail,
|
ErrorType::TypeFail,
|
||||||
))),
|
)
|
||||||
|
.to_boxed()),
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Err(Box::new(BuildError::new(
|
Err(BuildError::new("XML outputs must be a Tuple", ErrorType::TypeFail).to_boxed())
|
||||||
"XML outputs must be a Tuple",
|
|
||||||
ErrorType::TypeFail,
|
|
||||||
)))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user