[gnome-builder] tmpl: add || and && support



commit 963f6f157de0741cde66249e8347eb304f3cad0f
Author: Christian Hergert <chergert redhat com>
Date:   Thu May 19 13:53:50 2016 +0300

    tmpl: add || and && support

 contrib/tmpl/tmpl-expr-eval.c    |   59 ++++++++++++++++++++++++++++++++++++--
 contrib/tmpl/tmpl-expr-scanner.l |    2 +
 contrib/tmpl/tmpl-expr-types.h   |    2 +
 contrib/tmpl/tmpl-expr.c         |    2 +
 4 files changed, 62 insertions(+), 3 deletions(-)
---
diff --git a/contrib/tmpl/tmpl-expr-eval.c b/contrib/tmpl/tmpl-expr-eval.c
index a73ccb1..47aaaab 100644
--- a/contrib/tmpl/tmpl-expr-eval.c
+++ b/contrib/tmpl/tmpl-expr-eval.c
@@ -134,9 +134,9 @@ throw_type_mismatch (GError       **error,
 
 static gboolean
 tmpl_expr_simple_eval (TmplExprSimple  *node,
-                      TmplScope       *scope,
-                      GValue         *return_value,
-                      GError        **error)
+                       TmplScope       *scope,
+                       GValue          *return_value,
+                       GError         **error)
 {
   GValue left = G_VALUE_INIT;
   GValue right = G_VALUE_INIT;
@@ -173,6 +173,55 @@ cleanup:
 }
 
 static gboolean
+tmpl_expr_simple_eval_logical (TmplExprSimple  *node,
+                               TmplScope       *scope,
+                               GValue          *return_value,
+                               GError         **error)
+{
+  GValue left = G_VALUE_INIT;
+  GValue right = G_VALUE_INIT;
+  gboolean ret = FALSE;
+
+  g_assert (node != NULL);
+  g_assert (scope != NULL);
+  g_assert (return_value != NULL);
+
+  g_value_init (return_value, G_TYPE_BOOLEAN);
+
+  if (tmpl_expr_eval_internal (node->left, scope, &left, error) &&
+      ((node->right == NULL) ||
+       tmpl_expr_eval_internal (node->right, scope, &right, error)))
+    {
+      switch ((int)node->type)
+        {
+        case TMPL_EXPR_AND:
+          g_value_set_boolean (return_value,
+                               (tmpl_value_as_boolean (&left) && tmpl_value_as_boolean (&right)));
+          ret = TRUE;
+          break;
+
+        case TMPL_EXPR_OR:
+          g_value_set_boolean (return_value,
+                               (tmpl_value_as_boolean (&left) || tmpl_value_as_boolean (&right)));
+          ret = TRUE;
+          break;
+
+        default:
+          g_set_error (error,
+                       TMPL_ERROR,
+                       TMPL_ERROR_RUNTIME_ERROR,
+                       "Unknown logical operator type: %d", node->type);
+          break;
+        }
+    }
+
+  TMPL_CLEAR_VALUE (&left);
+  TMPL_CLEAR_VALUE (&right);
+
+  return ret;
+}
+
+static gboolean
 tmpl_expr_fn_call_eval (TmplExprFnCall  *node,
                        TmplScope       *scope,
                        GValue         *return_value,
@@ -819,6 +868,10 @@ tmpl_expr_eval_internal (TmplExpr   *node,
     case TMPL_EXPR_LTE:
       return tmpl_expr_simple_eval ((TmplExprSimple *)node, scope, return_value, error);
 
+    case TMPL_EXPR_AND:
+    case TMPL_EXPR_OR:
+      return tmpl_expr_simple_eval_logical ((TmplExprSimple *)node, scope, return_value, error);
+
     case TMPL_EXPR_NUMBER:
       g_value_init (return_value, G_TYPE_DOUBLE);
       g_value_set_double (return_value, ((TmplExprNumber *)node)->number);
diff --git a/contrib/tmpl/tmpl-expr-scanner.l b/contrib/tmpl/tmpl-expr-scanner.l
index 8297b1a..afe2435 100644
--- a/contrib/tmpl/tmpl-expr-scanner.l
+++ b/contrib/tmpl/tmpl-expr-scanner.l
@@ -48,6 +48,8 @@ TmplExprParser *parser = yyextra;
 "==" { yylval->cmp = TMPL_EXPR_EQ;  return CMP; }
 ">=" { yylval->cmp = TMPL_EXPR_GTE; return CMP; }
 "<=" { yylval->cmp = TMPL_EXPR_LTE; return CMP; }
+"||" { yylval->cmp = TMPL_EXPR_OR; return CMP; }
+"&&" { yylval->cmp = TMPL_EXPR_AND; return CMP; }
 
  /* keywords */
 "if"       { return IF; }
diff --git a/contrib/tmpl/tmpl-expr-types.h b/contrib/tmpl/tmpl-expr-types.h
index 1dab4cd..250113b 100644
--- a/contrib/tmpl/tmpl-expr-types.h
+++ b/contrib/tmpl/tmpl-expr-types.h
@@ -70,6 +70,8 @@ typedef enum
   TMPL_EXPR_SETATTR,
   TMPL_EXPR_GI_CALL,
   TMPL_EXPR_REQUIRE,
+  TMPL_EXPR_AND,
+  TMPL_EXPR_OR,
 } TmplExprType;
 
 typedef enum
diff --git a/contrib/tmpl/tmpl-expr.c b/contrib/tmpl/tmpl-expr.c
index 4605ba4..f329bdb 100644
--- a/contrib/tmpl/tmpl-expr.c
+++ b/contrib/tmpl/tmpl-expr.c
@@ -81,6 +81,8 @@ tmpl_expr_destroy (TmplExpr *self)
     case TMPL_EXPR_SUB:
     case TMPL_EXPR_UNARY_MINUS:
     case TMPL_EXPR_USER_FN_CALL:
+    case TMPL_EXPR_AND:
+    case TMPL_EXPR_OR:
       g_clear_pointer (&self->simple.left, tmpl_expr_unref);
       g_clear_pointer (&self->simple.right, tmpl_expr_unref);
       break;


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]