Commit 687febf8 authored by Christian Hergert's avatar Christian Hergert

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 ==.
parent a118f44a
......@@ -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;
......@@ -1486,6 +1523,16 @@ builtin_sqrt (const GValue *value,
return FALSE;
}
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,
......
......@@ -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; }
......
......@@ -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);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment