*** xref:unlang/condition/index.adoc[Conditional Expressions]
**** xref:unlang/condition/cmp.adoc[Comparisons]
-**** xref:unlang/expressions.adoc[expressions]
+**** xref:unlang/expression.adoc[expressions]
**** xref:unlang/condition/operands.adoc[Operands]
**** xref:unlang/condition/return_code.adoc[The Return Code Operator]
**** xref:unlang/condition/eq.adoc[The '==' Operator]
| - | subtraction
| * | multiplication
| / | division
-| %% | remainder TODO
+| % | remainder
| ^ | xor
| (...) | sub-expression
|===
[ '.' ] = T_ADD,
[ '&' ] = T_AND,
[ '|' ] = T_OR,
+ [ '%' ] = T_MOD,
};
/** Perform calculations
XLAT_BINARY_FUNC(op_sub, T_SUB)
XLAT_BINARY_FUNC(op_mul, T_MUL)
XLAT_BINARY_FUNC(op_div, T_DIV)
+XLAT_BINARY_FUNC(op_mod, T_MOD)
XLAT_BINARY_FUNC(op_and, T_AND)
XLAT_BINARY_FUNC(op_or, T_OR)
XLAT_BINARY_FUNC(op_xor, T_XOR)
XLAT_REGISTER_BINARY_OP(T_SUB, sub);
XLAT_REGISTER_BINARY_OP(T_MUL, mul);
XLAT_REGISTER_BINARY_OP(T_DIV, div);
+ XLAT_REGISTER_BINARY_OP(T_MOD, mod);
XLAT_REGISTER_BINARY_OP(T_AND, and);
XLAT_REGISTER_BINARY_OP(T_OR, or);
XLAT_REGISTER_BINARY_OP(T_XOR, xor);
[ T_SUB ] = L("op_sub"),
[ T_MUL ] = L("op_mul"),
[ T_DIV ] = L("op_div"),
+ [ T_MOD ] = L("op_mod"),
[ T_AND ] = L("op_and"),
[ T_OR ] = L("op_or"),
[ T_XOR ] = L("op_xor"),
[T_MUL] = P(8,0),
[T_DIV] = P(8,1),
+ [T_MOD] = P(8,2),
[T_OP_REG_EQ] = P(9,0),
[T_OP_REG_NE] = P(9,0),
{ L("+"), T_ADD },
{ L("-"), T_SUB },
{ L("/"), T_DIV },
+ { L("%"), T_MOD },
{ L("^"), T_XOR },
{ L("|"), T_OR },
dst->vb_float32 = a->vb_float64 / b->vb_float64;
break;
+ case T_MOD:
+ if (fpclassify(b->vb_float64) == FP_ZERO) return ERR_ZERO;
+
+ dst->vb_float32 = fmod(a->vb_float64, b->vb_float64);
+ break;
+
default:
return ERR_INVALID;
}
dst->vb_float64 = a->vb_float64 / b->vb_float64;
break;
+ case T_MOD:
+ if (fpclassify(b->vb_float64) == FP_ZERO) return ERR_ZERO;
+
+ dst->vb_float64 = fmod(a->vb_float64, b->vb_float64);
+ break;
+
default:
return ERR_INVALID;
}
break; \
\
case T_DIV: \
+ if (in2->vb_ ## _t == 0) return ERR_ZERO; \
+ \
dst->vb_ ## _t = in1->vb_ ## _t / in2->vb_ ## _t; \
break; \
+ \
+ case T_MOD: \
+ if (in2->vb_ ## _t == 0) return ERR_ZERO; \
+ \
+ dst->vb_ ## _t = in1->vb_ ## _t % in2->vb_ ## _t; \
+ break; \
\
case T_AND: \
dst->vb_ ## _t = in1->vb_ ## _t & in2->vb_ ## _t; \
case T_SUB:
case T_MUL:
case T_DIV:
+ case T_MOD:
case T_XOR:
/*
* Nothing else set it. If the input types are
case T_SUB:
case T_MUL:
case T_DIV:
+ case T_MOD:
case T_AND:
case T_OR:
case T_XOR:
size_t fr_token_quotes_table_len = NUM_ELEMENTS(fr_token_quotes_table);
/*
- * This is a hack, and has to be kept in sync with tokens.h
+ * String versions for all of the tokens.
*/
char const *fr_tokens[T_TOKEN_LAST] = {
[T_INVALID] = "?",
[T_NOT] = "!",
[T_XOR] = "^",
[T_COMPLEMENT] = "~",
+ [T_MOD] = "%",
[T_RSHIFT] = ">>",
[T_LSHIFT] = "<<",
T(DIV),
T(AND),
T(OR),
+ T(MOD),
T(RSHIFT),
T(LSHIFT),
};
T_NOT, /* ! */
T_XOR, /* ^ */
T_COMPLEMENT, /* ~ */
+ T_MOD, /* % */
T_RSHIFT, /* >> */
T_LSHIFT, /* << */
test_fail
}
+if ("%{expr: 11 % 2}" != 1) {
+ test_fail
+}
+if (11 % 2 != 1) {
+ test_fail
+}
+
if ("%{expr: 2 - -1}" != 3) {
test_fail
}
redundant {
group {
# fail on even numbered values, succeed on odd numbered ones
- if ("%{expr:%{Foreach-Variable-0} % 2}" == 0) {
+ if (%{Foreach-Variable-0} % 2 == 0) {
fail
}
else {
}
group {
# succeed on even-numbered values, fail on off-numbered ones.
- if ("%{expr:%{Foreach-Variable-0} % 2}" == 1) {
+ if (%{Foreach-Variable-0} % 2 == 1) {
fail
}
else {
redundant-load-balance {
group {
# fail on even numbered values, succeed on odd numbered ones
- if ("%{expr:%{Foreach-Variable-0} % 2}" == 0) {
+ if (%{Foreach-Variable-0} % 2 == 0) {
fail
}
else {
}
group {
# succeed on even-numbered values, fail on off-numbered ones.
- if ("%{expr:%{Foreach-Variable-0} % 2}" == 1) {
+ if (%{Foreach-Variable-0} % 2 == 1) {
fail
}
else {
calc int32 -1 + uint8 14 -> int16
match 13
+calc int32 11 % uint8 2 -> int16
+match 1
+
calc int8 0x7f & uint8 0x40 -> uint8
match 64
calc float32 1.0 * float32 2.5 -> float32
match 2.500000
+calc float32 11.0 % float32 2.0 -> float32
+match 1.000000
+
+calc float32 11.0 % float32 0.0 -> float32
+match Cannot divide by zero.
+
######################################################################
#
# Assignment operations
match 2test
count
-match 70
+match 76