mirror of
https://github.com/zaphar/ucg.git
synced 2025-07-22 18:19:54 -04:00
FEATURE: Add the not operator.
This commit is contained in:
parent
2409f0c64e
commit
016e4a22db
@ -219,4 +219,19 @@ let name = "foo";
|
||||
assert {
|
||||
ok = (name) in {foo="bar"},
|
||||
desc = "(name) in {foo=\"bar\"} works",
|
||||
};
|
||||
|
||||
assert {
|
||||
ok = not false,
|
||||
desc = "not false is true",
|
||||
};
|
||||
|
||||
assert {
|
||||
ok = not true == false,
|
||||
desc = "not true is false",
|
||||
};
|
||||
|
||||
assert {
|
||||
ok = not not true,
|
||||
desc = "double negatives are positive",
|
||||
};
|
@ -601,11 +601,18 @@ pub struct FailDef {
|
||||
pub message: Box<Expression>,
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Clone)]
|
||||
pub struct NotDef {
|
||||
pub pos: Position,
|
||||
pub expr: Box<Expression>,
|
||||
}
|
||||
|
||||
/// Encodes a ucg expression. Expressions compute a value from.
|
||||
#[derive(Debug, PartialEq, Clone)]
|
||||
pub enum Expression {
|
||||
// Base Expression
|
||||
Simple(Value),
|
||||
Not(NotDef),
|
||||
|
||||
// Binary expressions
|
||||
Binary(BinaryOpDef),
|
||||
@ -646,6 +653,7 @@ impl Expression {
|
||||
&Expression::Include(ref def) => &def.pos,
|
||||
&Expression::Import(ref def) => &def.pos,
|
||||
&Expression::Fail(ref def) => &def.pos,
|
||||
&Expression::Not(ref def) => &def.pos,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -695,6 +703,9 @@ impl fmt::Display for Expression {
|
||||
&Expression::Fail(_) => {
|
||||
write!(w, "<Fail>")?;
|
||||
}
|
||||
&Expression::Not(ref def) => {
|
||||
write!(w, "!{}", def.expr)?;
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
@ -114,6 +114,9 @@ impl<'a> AstWalker<'a> {
|
||||
Expression::Import(_) | Expression::Include(_) | Expression::Fail(_) => {
|
||||
//noop
|
||||
}
|
||||
Expression::Not(ref mut def) => {
|
||||
self.walk_expression(def.expr.as_mut());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1786,7 +1786,7 @@ impl<'a> FileBuilder<'a> {
|
||||
} else {
|
||||
Err(Box::new(error::BuildError::new(
|
||||
format!(
|
||||
"Expected string form message but got {}",
|
||||
"Expected string for message but got {}",
|
||||
def.message.as_ref()
|
||||
),
|
||||
error::ErrorType::TypeFail,
|
||||
@ -1794,6 +1794,21 @@ impl<'a> FileBuilder<'a> {
|
||||
)))
|
||||
};
|
||||
}
|
||||
&Expression::Not(ref def) => {
|
||||
let val = self.eval_expr(&def.expr, scope)?;
|
||||
return if let Val::Boolean(b) = val.as_ref() {
|
||||
Ok(Rc::new(Val::Boolean(!b)))
|
||||
} else {
|
||||
Err(Box::new(error::BuildError::new(
|
||||
format!(
|
||||
"Expected boolean for expression but got {}",
|
||||
def.expr.as_ref()
|
||||
),
|
||||
error::ErrorType::TypeFail,
|
||||
def.expr.pos().clone(),
|
||||
)))
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -667,6 +667,19 @@ make_fn!(
|
||||
)
|
||||
);
|
||||
|
||||
make_fn!(
|
||||
not_expression<SliceIter<Token>, Expression>,
|
||||
do_each!(
|
||||
pos => pos,
|
||||
_ => word!("not"),
|
||||
expr => must!(wrap_err!(expression, "Expected failure message")),
|
||||
(Expression::Not(NotDef{
|
||||
pos: pos,
|
||||
expr: Box::new(expr),
|
||||
}))
|
||||
)
|
||||
);
|
||||
|
||||
fn unprefixed_expression(input: SliceIter<Token>) -> ParseResult<Expression> {
|
||||
let _input = input.clone();
|
||||
either!(
|
||||
@ -685,6 +698,7 @@ make_fn!(
|
||||
trace_parse!(func_op_expression),
|
||||
trace_parse!(macro_expression),
|
||||
trace_parse!(import_expression),
|
||||
trace_parse!(not_expression),
|
||||
trace_parse!(fail_expression),
|
||||
trace_parse!(module_expression),
|
||||
trace_parse!(select_expression),
|
||||
|
@ -278,6 +278,10 @@ make_fn!(istok<OffsetStrIter, Token>,
|
||||
do_text_token_tok!(TokenType::BAREWORD, "is", WS)
|
||||
);
|
||||
|
||||
make_fn!(nottok<OffsetStrIter, Token>,
|
||||
do_text_token_tok!(TokenType::BAREWORD, "not", WS)
|
||||
);
|
||||
|
||||
make_fn!(failtok<OffsetStrIter, Token>,
|
||||
do_text_token_tok!(TokenType::BAREWORD, "fail", WS)
|
||||
);
|
||||
@ -417,6 +421,7 @@ fn token<'a>(input: OffsetStrIter<'a>) -> Result<OffsetStrIter<'a>, Token> {
|
||||
booleantok,
|
||||
intok,
|
||||
istok,
|
||||
nottok,
|
||||
lettok,
|
||||
outtok,
|
||||
selecttok,
|
||||
|
@ -30,7 +30,7 @@ let asserts = module{
|
||||
// descriptive message to use in output.
|
||||
desc=mod.default_description,
|
||||
} => {
|
||||
let ok = mod.test != true;
|
||||
let ok = not mod.test;
|
||||
|
||||
let desc = "@" % (mod.desc);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user