REFACTOR: AST changes to support optional defaults.

This commit is contained in:
Jeremy Wall 2019-03-01 16:52:08 -06:00
parent b4497d88e9
commit e095cb3235
5 changed files with 16 additions and 8 deletions

View File

@ -303,7 +303,7 @@ pub struct CallDef {
#[derive(PartialEq, Debug, Clone)] #[derive(PartialEq, Debug, Clone)]
pub struct SelectDef { pub struct SelectDef {
pub val: Box<Expression>, pub val: Box<Expression>,
pub default: Box<Expression>, pub default: Option<Box<Expression>>,
pub tuple: FieldList, pub tuple: FieldList,
pub pos: Position, pub pos: Position,
} }

View File

@ -109,7 +109,14 @@ impl<'a> AstWalker<'a> {
} }
} }
Expression::Select(ref mut def) => { Expression::Select(ref mut def) => {
self.walk_expression(def.default.as_mut()); match def.default {
Some(ref mut e) => {
self.walk_expression(e.as_mut());
}
None => {
// noop;
}
};
self.walk_expression(def.val.as_mut()); self.walk_expression(def.val.as_mut());
self.walk_fieldset(&mut def.tuple); self.walk_fieldset(&mut def.tuple);
} }

View File

@ -1290,7 +1290,8 @@ impl<'a> FileBuilder<'a> {
fn eval_select(&self, def: &SelectDef, scope: &Scope) -> Result<Rc<Val>, Box<dyn Error>> { fn eval_select(&self, def: &SelectDef, scope: &Scope) -> Result<Rc<Val>, Box<dyn Error>> {
let target = &def.val; let target = &def.val;
let def_expr = &def.default; // FIXME(jwall): Handle the no default case in here.
let def_expr = def.default.as_ref().unwrap();
let fields = &def.tuple; let fields = &def.tuple;
// First resolve the target expression. // First resolve the target expression.
let v = self.eval_expr(target, scope)?; let v = self.eval_expr(target, scope)?;

View File

@ -187,10 +187,10 @@ fn test_select_expr_not_a_string() {
"foo".to_string(), "foo".to_string(),
Position::new(1, 1, 1) Position::new(1, 1, 1)
)))), )))),
default: Box::new(Expression::Simple(Value::Int(value_node!( default: Some(Box::new(Expression::Simple(Value::Int(value_node!(
1, 1,
Position::new(1, 1, 1) Position::new(1, 1, 1)
)))), ))))),
tuple: vec![ tuple: vec![
( (
make_tok!("bar", Position::new(1, 1, 1)), make_tok!("bar", Position::new(1, 1, 1)),

View File

@ -441,13 +441,13 @@ fn func_expression(input: SliceIter<Token>) -> Result<SliceIter<Token>, Expressi
fn tuple_to_select<'a>( fn tuple_to_select<'a>(
input: SliceIter<'a, Token>, input: SliceIter<'a, Token>,
e1: Expression, e1: Expression,
e2: Expression, e2: Option<Expression>,
val: Value, val: Value,
) -> ConvertResult<'a, Expression> { ) -> ConvertResult<'a, Expression> {
match val { match val {
Value::Tuple(v) => Ok(Expression::Select(SelectDef { Value::Tuple(v) => Ok(Expression::Select(SelectDef {
val: Box::new(e1), val: Box::new(e1),
default: Box::new(e2), default: e2.map(|e| Box::new(e)),
tuple: v.val, tuple: v.val,
pos: (&input).into(), pos: (&input).into(),
})), })),
@ -479,7 +479,7 @@ fn select_expression(input: SliceIter<Token>) -> Result<SliceIter<Token>, Expres
Result::Fail(e) => Result::Fail(e), Result::Fail(e) => Result::Fail(e),
Result::Incomplete(offset) => Result::Incomplete(offset), Result::Incomplete(offset) => Result::Incomplete(offset),
Result::Complete(rest, (val, default, map)) => { Result::Complete(rest, (val, default, map)) => {
match tuple_to_select(input.clone(), val, default, map) { match tuple_to_select(input.clone(), val, Some(default), map) {
Ok(expr) => Result::Complete(rest, expr), Ok(expr) => Result::Complete(rest, expr),
Err(e) => Result::Fail(Error::caused_by( Err(e) => Result::Fail(Error::caused_by(
"Invalid Select Expression", "Invalid Select Expression",