[template-glib] expr-eval: add boolean casts as builtins



commit 9b1f563175a2ba07d81ef3720ea50eb0b59048b9
Author: Christian Hergert <chergert redhat com>
Date:   Fri May 6 15:35:04 2022 -0700

    expr-eval: add boolean casts as builtins

 src/tmpl-expr-eval.c    | 38 ++++++++++++++++++++++++++++++++++++++
 src/tmpl-expr-scanner.l |  1 +
 src/tmpl-expr-types.h   |  1 +
 tests/test1.script      | 23 ++++++++++++++++++++++-
 4 files changed, 62 insertions(+), 1 deletion(-)
---
diff --git a/src/tmpl-expr-eval.c b/src/tmpl-expr-eval.c
index fb9f5af..5a0ed85 100644
--- a/src/tmpl-expr-eval.c
+++ b/src/tmpl-expr-eval.c
@@ -83,6 +83,7 @@ DECLARE_BUILTIN (cast_i64)
 DECLARE_BUILTIN (cast_u64)
 DECLARE_BUILTIN (cast_float)
 DECLARE_BUILTIN (cast_double)
+DECLARE_BUILTIN (cast_bool)
 
 static GHashTable *fast_dispatch;
 static BuiltinFunc builtin_funcs [] = {
@@ -108,6 +109,7 @@ static BuiltinFunc builtin_funcs [] = {
   builtin_cast_u64,
   builtin_cast_float,
   builtin_cast_double,
+  builtin_cast_bool,
 };
 
 static inline guint
@@ -2160,6 +2162,42 @@ BUILTIN_CAST (u64, G_TYPE_UINT64)
 BUILTIN_CAST (float, G_TYPE_FLOAT)
 BUILTIN_CAST (double, G_TYPE_DOUBLE)
 
+static gboolean
+builtin_cast_bool (const GValue  *value,
+                   GValue        *return_value,
+                   GError       **error)
+{
+  g_value_init (return_value, G_TYPE_BOOLEAN);
+
+#define BOOL_CAST(type, getter, compare) \
+  else if (G_VALUE_HOLDS (value, type)) \
+    g_value_set_boolean (return_value, g_value_get_##getter(value) != compare);
+
+  if (0) {}
+  BOOL_CAST (G_TYPE_BOOLEAN, boolean, FALSE)
+  BOOL_CAST (G_TYPE_DOUBLE, double, .0)
+  BOOL_CAST (G_TYPE_FLOAT, float, .0f)
+  BOOL_CAST (G_TYPE_INT, int, 0)
+  BOOL_CAST (G_TYPE_UINT, uint, 0)
+  BOOL_CAST (G_TYPE_CHAR, schar, 0)
+  BOOL_CAST (G_TYPE_UCHAR, uchar, 0)
+  BOOL_CAST (G_TYPE_STRING, string, NULL)
+  BOOL_CAST (G_TYPE_POINTER, pointer, NULL)
+  else if (!g_value_transform (value, return_value))
+    {
+      g_set_error (error,
+                   TMPL_ERROR,
+                   TMPL_ERROR_RUNTIME_ERROR,
+                   "Cannot convert %s to bool",
+                   G_VALUE_TYPE_NAME (value));
+      return FALSE;
+    }
+
+#undef BOOL_CAST
+
+  return TRUE;
+}
+
 static gboolean
 builtin_print (const GValue  *value,
                GValue        *return_value,
diff --git a/src/tmpl-expr-scanner.l b/src/tmpl-expr-scanner.l
index d12dc67..e405a6f 100644
--- a/src/tmpl-expr-scanner.l
+++ b/src/tmpl-expr-scanner.l
@@ -116,6 +116,7 @@ TmplExprParser *parser = yyextra;
 "u64"      { yylval->fn = TMPL_EXPR_BUILTIN_CAST_U64; return BUILTIN; }
 "float"    { yylval->fn = TMPL_EXPR_BUILTIN_CAST_FLOAT; return BUILTIN; }
 "double"   { yylval->fn = TMPL_EXPR_BUILTIN_CAST_DOUBLE; return BUILTIN; }
+"bool"     { yylval->fn = TMPL_EXPR_BUILTIN_CAST_BOOL; return BUILTIN; }
 
  /* string literals */
 L?\"(\\.|[^\\"])*\" { yylval->s = copy_literal (yytext); return STRING_LITERAL; }
diff --git a/src/tmpl-expr-types.h b/src/tmpl-expr-types.h
index a91c541..420c83d 100644
--- a/src/tmpl-expr-types.h
+++ b/src/tmpl-expr-types.h
@@ -106,6 +106,7 @@ typedef enum
   TMPL_EXPR_BUILTIN_CAST_U64,
   TMPL_EXPR_BUILTIN_CAST_FLOAT,
   TMPL_EXPR_BUILTIN_CAST_DOUBLE,
+  TMPL_EXPR_BUILTIN_CAST_BOOL,
 } TmplExprBuiltin;
 
 TMPL_AVAILABLE_IN_ALL
diff --git a/tests/test1.script b/tests/test1.script
index d0ed9fd..8c772a7 100644
--- a/tests/test1.script
+++ b/tests/test1.script
@@ -101,7 +101,28 @@ assert(val == true)
 val = true && false || true
 assert(val == true)
 
-# BROKEN
+# Implicit floor() in GType conversion
+assert(double(i32(1234.56)) == 1234)
+
+# Test boolean casts
+assert(bool(1) == true)
+assert(bool(0) == false)
+assert(bool("") == true)
+assert(bool(null) == false)
+assert(bool(char(0)) == false)
+assert(bool(char(1)) == true)
+assert(bool(byte(0)) == false)
+assert(bool(byte(1)) == true)
+assert(bool(i32(0)) == false)
+assert(bool(i32(1)) == true)
+assert(bool(u32(0)) == false)
+assert(bool(u32(1)) == true)
+assert(bool(i64(0)) == false)
+assert(bool(i64(1)) == true)
+assert(bool(u64(0)) == false)
+assert(bool(u64(1)) == true)
+
+# FIXME: broken exp priority
 a1 = 1 < 3
 (a2 = 1) < 3
 assert(a1 == a2)


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