[libshumate] vector: Add arithmetic expressions
- From: Corentin Noël <corentinnoel src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [libshumate] vector: Add arithmetic expressions
- Date: Sun, 25 Sep 2022 20:03:00 +0000 (UTC)
commit 05e65a299e49a7694cda50e608b8511c536548a5
Author: James Westman <james jwestman net>
Date: Sun Sep 25 14:44:12 2022 -0500
vector: Add arithmetic expressions
shumate/vector/shumate-vector-expression-filter.c | 97 +++++++++++++++++++++++
tests/vector-expression.c | 6 ++
2 files changed, 103 insertions(+)
---
diff --git a/shumate/vector/shumate-vector-expression-filter.c
b/shumate/vector/shumate-vector-expression-filter.c
index 5d6bce9..7412316 100644
--- a/shumate/vector/shumate-vector-expression-filter.c
+++ b/shumate/vector/shumate-vector-expression-filter.c
@@ -37,6 +37,10 @@ typedef enum {
EXPR_GE,
EXPR_LE,
EXPR_CASE,
+ EXPR_ADD,
+ EXPR_SUB,
+ EXPR_MUL,
+ EXPR_DIV,
} ExpressionType;
struct _ShumateVectorExpressionFilter
@@ -150,6 +154,26 @@ shumate_vector_expression_filter_from_json_array (JsonArray *array, GError **err
self->type = EXPR_LE;
expect_exprs = 2;
}
+ else if (g_strcmp0 ("+", op) == 0)
+ {
+ self->type = EXPR_ADD;
+ expect_ge_exprs = 1;
+ }
+ else if (g_strcmp0 ("-", op) == 0)
+ {
+ self->type = EXPR_SUB;
+ expect_ge_exprs = 1;
+ }
+ else if (g_strcmp0 ("*", op) == 0)
+ {
+ self->type = EXPR_MUL;
+ expect_ge_exprs = 1;
+ }
+ else if (g_strcmp0 ("/", op) == 0)
+ {
+ self->type = EXPR_DIV;
+ expect_exprs = 2;
+ }
else if (g_strcmp0 ("case", op) == 0)
self->type = EXPR_CASE;
else
@@ -382,6 +406,79 @@ shumate_vector_expression_filter_eval (ShumateVectorExpression *expr,
shumate_vector_value_set_boolean (out, (number < number2) ^ inverted);
return TRUE;
+ case EXPR_ADD:
+ number = 0;
+
+ for (int i = 0; i < n_expressions; i ++)
+ {
+ if (!shumate_vector_expression_eval (expressions[i], scope, &value))
+ return FALSE;
+ if (!shumate_vector_value_get_number (&value, &number2))
+ return FALSE;
+
+ number += number2;
+ }
+
+ shumate_vector_value_set_number (out, number);
+ return TRUE;
+
+ case EXPR_SUB:
+ g_assert (n_expressions >= 1);
+
+ if (!shumate_vector_expression_eval (expressions[0], scope, &value))
+ return FALSE;
+ if (!shumate_vector_value_get_number (&value, &number))
+ return FALSE;
+
+ if (n_expressions == 1)
+ shumate_vector_value_set_number (out, 0 - number);
+ else
+ {
+ if (!shumate_vector_expression_eval (expressions[1], scope, &value2))
+ return FALSE;
+ if (!shumate_vector_value_get_number (&value2, &number2))
+ return FALSE;
+
+ shumate_vector_value_set_number (out, number - number2);
+ }
+ return TRUE;
+
+ case EXPR_MUL:
+ g_assert (n_expressions >= 1);
+
+ if (!shumate_vector_expression_eval (expressions[0], scope, &value))
+ return FALSE;
+ if (!shumate_vector_value_get_number (&value, &number))
+ return FALSE;
+
+ for (int i = 1; i < n_expressions; i ++)
+ {
+ if (!shumate_vector_expression_eval (expressions[i], scope, &value))
+ return FALSE;
+ if (!shumate_vector_value_get_number (&value, &number2))
+ return FALSE;
+
+ number *= number2;
+ }
+
+ shumate_vector_value_set_number (out, number);
+ return TRUE;
+
+ case EXPR_DIV:
+ if (!shumate_vector_expression_eval (expressions[0], scope, &value))
+ return FALSE;
+ if (!shumate_vector_expression_eval (expressions[1], scope, &value2))
+ return FALSE;
+
+ if (!shumate_vector_value_get_number (&value, &number))
+ return FALSE;
+ if (!shumate_vector_value_get_number (&value2, &number2))
+ return FALSE;
+
+ shumate_vector_value_set_number (out, number / number2);
+
+ return TRUE;
+
case EXPR_CASE:
for (int i = 0; i < n_expressions; i += 2)
{
diff --git a/tests/vector-expression.c b/tests/vector-expression.c
index f9acc8f..f3b4daa 100644
--- a/tests/vector-expression.c
+++ b/tests/vector-expression.c
@@ -171,6 +171,12 @@ test_vector_expression_basic_filter (void)
g_assert_true (filter ("[\"==\", [\"case\", true, 0, 1], 0]"));
g_assert_true (filter ("[\"==\", [\"case\", false, 0, 1], 1]"));
g_assert_true (filter ("[\"==\", [\"case\", false, 0, true, 2], 2]"));
+
+ g_assert_true (filter ("[\"==\", [\"+\", 3, 1, 7], 11]"));
+ g_assert_true (filter ("[\"==\", [\"-\", 3, 1], 2]"));
+ g_assert_true (filter ("[\"==\", [\"-\", 1], -1]"));
+ g_assert_true (filter ("[\"==\", [\"*\", 5, 6, 7], 210]"));
+ g_assert_true (filter ("[\"==\", [\"/\", 10, 4], 2.5]"));
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]