[template-glib] expr: add typeof() builtin and equality functions



commit 687febf804e300a4d0e82a3609e20855eebc6017
Author: Christian Hergert <chergert redhat com>
Date:   Mon Oct 23 15:00:29 2017 -0700

    expr: add typeof() builtin and equality functions
    
    This allows you to do some simple type comparisons like:
    
    {{if typeof(1) == typeof(2)}}
    {{end}}
    
    The == operator will also check if 2 is a subclass of 1.
    The != operator does the inverse of ==.

 src/tmpl-expr-eval.c    |   47 +++++++++++++++++++++++++++++++++++++++++++++++
 src/tmpl-expr-scanner.l |   15 ++++++++-------
 src/tmpl-expr-types.h   |    1 +
 3 files changed, 56 insertions(+), 7 deletions(-)
---
diff --git a/src/tmpl-expr-eval.c b/src/tmpl-expr-eval.c
index d70698f..46d9c5e 100644
--- a/src/tmpl-expr-eval.c
+++ b/src/tmpl-expr-eval.c
@@ -68,6 +68,9 @@ static gboolean builtin_repr                 (const GValue  *value,
 static gboolean builtin_sqrt                 (const GValue  *value,
                                               GValue        *return_value,
                                               GError       **error);
+static gboolean builtin_typeof               (const GValue  *value,
+                                              GValue        *return_value,
+                                              GError       **error);
 static gboolean eq_enum_string               (const GValue  *left,
                                               const GValue  *right,
                                               GValue        *return_value,
@@ -87,6 +90,7 @@ static BuiltinFunc builtin_funcs [] = {
   builtin_print,
   builtin_repr,
   builtin_sqrt,
+  builtin_typeof,
 };
 
 static inline guint
@@ -103,6 +107,33 @@ build_hash (TmplExprType type,
   return type | (left << 16) | (right << 24);
 }
 
+static gboolean
+eq_gtype_gtype (const GValue  *left,
+                const GValue  *right,
+                GValue        *return_value,
+                GError       **error)
+{
+  g_value_init (return_value, G_TYPE_BOOLEAN);
+  g_value_set_boolean (return_value,
+                       g_value_get_gtype (left) == g_value_get_gtype (right) ||
+                       g_type_is_a (g_value_get_gtype (right), g_value_get_gtype (left)));
+  return TRUE;
+}
+
+static gboolean
+ne_gtype_gtype (const GValue  *left,
+                const GValue  *right,
+                GValue        *return_value,
+                GError       **error)
+{
+  if (eq_gtype_gtype (left, right, return_value, error))
+    {
+      g_value_set_boolean (return_value, !g_value_get_boolean (return_value));
+      return TRUE;
+    }
+
+  return FALSE;
+}
 
 static gboolean
 throw_type_mismatch (GError       **error,
@@ -154,6 +185,9 @@ find_dispatch_slow (TmplExprSimple *node,
       if ((G_VALUE_HOLDS_STRING (left) && G_VALUE_HOLDS_ENUM (right)) ||
           (G_VALUE_HOLDS_STRING (right) && G_VALUE_HOLDS_ENUM (left)))
         return eq_enum_string;
+
+      if (G_VALUE_HOLDS_GTYPE (left) && G_VALUE_HOLDS_GTYPE (right))
+        return eq_gtype_gtype;
     }
 
   if (node->type == TMPL_EXPR_NE)
@@ -161,6 +195,9 @@ find_dispatch_slow (TmplExprSimple *node,
       if ((G_VALUE_HOLDS_STRING (left) && G_VALUE_HOLDS_ENUM (right)) ||
           (G_VALUE_HOLDS_STRING (right) && G_VALUE_HOLDS_ENUM (left)))
         return ne_enum_string;
+
+      if (G_VALUE_HOLDS_GTYPE (left) && G_VALUE_HOLDS_GTYPE (right))
+        return ne_gtype_gtype;
     }
 
   return NULL;
@@ -1487,6 +1524,16 @@ builtin_sqrt (const GValue  *value,
 }
 
 static gboolean
+builtin_typeof (const GValue  *value,
+                GValue        *return_value,
+                GError       **error)
+{
+  g_value_init (return_value, G_TYPE_GTYPE);
+  g_value_set_gtype (return_value, G_VALUE_TYPE (value));
+  return TRUE;
+}
+
+static gboolean
 builtin_hex (const GValue  *value,
              GValue        *return_value,
              GError       **error)
diff --git a/src/tmpl-expr-scanner.l b/src/tmpl-expr-scanner.l
index 48a3f4d..97fc4b8 100644
--- a/src/tmpl-expr-scanner.l
+++ b/src/tmpl-expr-scanner.l
@@ -66,13 +66,14 @@ TmplExprParser *parser = yyextra;
 "false"    { yylval->b = 0; return BOOL; }
 
  /* builtin functions */
-"ceil"  { yylval->fn = TMPL_EXPR_BUILTIN_CEIL; return BUILTIN; }
-"floor" { yylval->fn = TMPL_EXPR_BUILTIN_FLOOR; return BUILTIN; }
-"hex"   { yylval->fn = TMPL_EXPR_BUILTIN_HEX; return BUILTIN; }
-"log"   { yylval->fn = TMPL_EXPR_BUILTIN_LOG; return BUILTIN; }
-"print" { yylval->fn = TMPL_EXPR_BUILTIN_PRINT; return BUILTIN; }
-"repr"  { yylval->fn = TMPL_EXPR_BUILTIN_REPR; return BUILTIN; }
-"sqrt"  { yylval->fn = TMPL_EXPR_BUILTIN_SQRT; return BUILTIN; }
+"ceil"   { yylval->fn = TMPL_EXPR_BUILTIN_CEIL; return BUILTIN; }
+"floor"  { yylval->fn = TMPL_EXPR_BUILTIN_FLOOR; return BUILTIN; }
+"hex"    { yylval->fn = TMPL_EXPR_BUILTIN_HEX; return BUILTIN; }
+"log"    { yylval->fn = TMPL_EXPR_BUILTIN_LOG; return BUILTIN; }
+"print"  { yylval->fn = TMPL_EXPR_BUILTIN_PRINT; return BUILTIN; }
+"repr"   { yylval->fn = TMPL_EXPR_BUILTIN_REPR; return BUILTIN; }
+"sqrt"   { yylval->fn = TMPL_EXPR_BUILTIN_SQRT; return BUILTIN; }
+"typeof" { yylval->fn = TMPL_EXPR_BUILTIN_TYPEOF; return BUILTIN; }
 
  /* string literals */
 L?\"(\\.|[^\\"])*\" { yylval->s = yytext; return STRING_LITERAL; }
diff --git a/src/tmpl-expr-types.h b/src/tmpl-expr-types.h
index 0d4b1bb..600df1a 100644
--- a/src/tmpl-expr-types.h
+++ b/src/tmpl-expr-types.h
@@ -85,6 +85,7 @@ typedef enum
   TMPL_EXPR_BUILTIN_PRINT,
   TMPL_EXPR_BUILTIN_REPR,
   TMPL_EXPR_BUILTIN_SQRT,
+  TMPL_EXPR_BUILTIN_TYPEOF,
 } TmplExprBuiltin;
 
 GType tmpl_expr_get_type   (void);


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