[template-glib] expr: split statement lists and args
- From: Christian Hergert <chergert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [template-glib] expr: split statement lists and args
- Date: Wed, 4 May 2022 18:52:17 +0000 (UTC)
commit 40abca131615c9fc00433a2835a13451d51ad9c4
Author: Christian Hergert <chergert redhat com>
Date: Wed May 4 11:16:44 2022 -0700
expr: split statement lists and args
This will give us a bit more flexibility going forward so that we can have
different syntax between the two from a scriptability standpoint.
src/tmpl-expr-eval.c | 52 ++++++++++++++++++++++++++++++++++++++++++-------
src/tmpl-expr-parser.y | 29 +++++++++++++++++++++++----
src/tmpl-expr-private.h | 8 ++++++++
src/tmpl-expr-types.h | 1 +
src/tmpl-expr.c | 32 +++++++++++++++++++++++++++++-
src/tmpl-expr.h | 2 ++
6 files changed, 112 insertions(+), 12 deletions(-)
---
diff --git a/src/tmpl-expr-eval.c b/src/tmpl-expr-eval.c
index 3003e26..7cfc4fa 100644
--- a/src/tmpl-expr-eval.c
+++ b/src/tmpl-expr-eval.c
@@ -396,10 +396,45 @@ cleanup:
}
static gboolean
-tmpl_expr_stmt_list_eval (TmplExprSimple *node,
- TmplScope *scope,
- GValue *return_value,
- GError **error)
+tmpl_expr_stmt_list_eval (TmplExprStmtList *node,
+ TmplScope *scope,
+ GValue *return_value,
+ GError **error)
+{
+ GValue last = G_VALUE_INIT;
+
+ if G_UNLIKELY (node->stmts == NULL || node->stmts->len == 0)
+ {
+ g_set_error_literal (error,
+ TMPL_ERROR,
+ TMPL_ERROR_RUNTIME_ERROR,
+ "Runtime Error: implausible TmplExprStmtList");
+ return FALSE;
+ }
+
+ for (guint i = 0; i < node->stmts->len; i++)
+ {
+ TmplExpr *stmt = g_ptr_array_index (node->stmts, i);
+
+ TMPL_CLEAR_VALUE (&last);
+
+ if (!tmpl_expr_eval_internal (stmt, scope, &last, error))
+ {
+ TMPL_CLEAR_VALUE (&last);
+ return FALSE;
+ }
+ }
+
+ *return_value = last;
+
+ return TRUE;
+}
+
+static gboolean
+tmpl_expr_args_eval (TmplExprSimple *node,
+ TmplScope *scope,
+ GValue *return_value,
+ GError **error)
{
GValue left = G_VALUE_INIT;
gboolean ret = FALSE;
@@ -964,7 +999,7 @@ apply_args:
goto cleanup;
}
- if (args->any.type == TMPL_EXPR_STMT_LIST)
+ if (args->any.type == TMPL_EXPR_ARGS)
{
if (!tmpl_expr_eval_internal (((TmplExprSimple *)args)->left, scope, value, error))
goto cleanup;
@@ -1097,7 +1132,7 @@ tmpl_expr_user_fn_call_eval (TmplExprUserFnCall *node,
return FALSE;
}
- if (params->any.type == TMPL_EXPR_STMT_LIST)
+ if (params->any.type == TMPL_EXPR_ARGS)
{
TmplExprSimple *simple = (TmplExprSimple *)params;
@@ -1218,8 +1253,11 @@ tmpl_expr_eval_internal (TmplExpr *node,
g_value_set_string (return_value, ((TmplExprString *)node)->value);
return TRUE;
+ case TMPL_EXPR_ARGS:
+ return tmpl_expr_args_eval ((TmplExprSimple *)node, scope, return_value, error);
+
case TMPL_EXPR_STMT_LIST:
- return tmpl_expr_stmt_list_eval ((TmplExprSimple *)node, scope, return_value, error);
+ return tmpl_expr_stmt_list_eval ((TmplExprStmtList *)node, scope, return_value, error);
case TMPL_EXPR_IF:
case TMPL_EXPR_WHILE:
diff --git a/src/tmpl-expr-parser.y b/src/tmpl-expr-parser.y
index ba32573..202b2b9 100644
--- a/src/tmpl-expr-parser.y
+++ b/src/tmpl-expr-parser.y
@@ -74,7 +74,21 @@ expr: /* nothing */ EOL {
YYACCEPT;
}
| stmt EOL {
- parser->ast = $1;
+ if (parser->ast != NULL)
+ {
+ if (parser->ast->any.type != TMPL_EXPR_STMT_LIST)
+ {
+ GPtrArray *ar = g_ptr_array_new_with_free_func ((GDestroyNotify)tmpl_expr_unref);
+ g_ptr_array_add (ar, parser->ast);
+ parser->ast = tmpl_expr_new_stmt_list (ar);
+ }
+ g_ptr_array_add (parser->ast->stmt_list.stmts, $1);
+ }
+ else
+ {
+ parser->ast = $1;
+ }
+
YYACCEPT;
}
| FUNC NAME '(' symlist ')' '=' list EOL {
@@ -110,9 +124,16 @@ stmt: IF exp THEN list {
list: /* nothing */ { $$ = NULL; }
| stmt ';' list {
if ($3 == NULL)
- $$ = $1;
+ { $$ = $1; }
+ else if ($1->any.type == TMPL_EXPR_STMT_LIST)
+ { g_ptr_array_add ($1->stmt_list.stmts, $3); }
else
- $$ = tmpl_expr_new_simple (TMPL_EXPR_STMT_LIST, $1, $3);
+ {
+ GPtrArray *ar = g_ptr_array_new_with_free_func ((GDestroyNotify)tmpl_expr_unref);
+ g_ptr_array_add (ar, $1);
+ g_ptr_array_add (ar, $3);
+ $$ = tmpl_expr_new_stmt_list (ar);
+ }
}
;
@@ -191,7 +212,7 @@ exp: exp CMP exp {
explist: exp
| exp ',' explist {
- $$ = tmpl_expr_new_simple (TMPL_EXPR_STMT_LIST, $1, $3);
+ $$ = tmpl_expr_new_simple (TMPL_EXPR_ARGS, $1, $3);
}
;
diff --git a/src/tmpl-expr-private.h b/src/tmpl-expr-private.h
index 57a33d6..c1ebe2b 100644
--- a/src/tmpl-expr-private.h
+++ b/src/tmpl-expr-private.h
@@ -136,6 +136,13 @@ typedef struct
volatile gint ref_count;
} TmplExprAny;
+typedef struct
+{
+ TmplExprType type;
+ volatile gint ref_count;
+ GPtrArray *stmts;
+} TmplExprStmtList;
+
union _TmplExpr
{
TmplExprAny any;
@@ -151,6 +158,7 @@ union _TmplExpr
TmplExprGetattr getattr;
TmplExprSetattr setattr;
TmplExprRequire require;
+ TmplExprStmtList stmt_list;
};
G_END_DECLS
diff --git a/src/tmpl-expr-types.h b/src/tmpl-expr-types.h
index d871743..acedfb9 100644
--- a/src/tmpl-expr-types.h
+++ b/src/tmpl-expr-types.h
@@ -75,6 +75,7 @@ typedef enum
TMPL_EXPR_AND,
TMPL_EXPR_OR,
TMPL_EXPR_INVERT_BOOLEAN,
+ TMPL_EXPR_ARGS,
} TmplExprType;
typedef enum
diff --git a/src/tmpl-expr.c b/src/tmpl-expr.c
index 228a882..010e30e 100644
--- a/src/tmpl-expr.c
+++ b/src/tmpl-expr.c
@@ -77,7 +77,6 @@ tmpl_expr_destroy (TmplExpr *self)
case TMPL_EXPR_LTE:
case TMPL_EXPR_MUL:
case TMPL_EXPR_NE:
- case TMPL_EXPR_STMT_LIST:
case TMPL_EXPR_SUB:
case TMPL_EXPR_UNARY_MINUS:
case TMPL_EXPR_USER_FN_CALL:
@@ -99,6 +98,10 @@ tmpl_expr_destroy (TmplExpr *self)
g_clear_pointer (&self->setattr.right, tmpl_expr_unref);
break;
+ case TMPL_EXPR_STMT_LIST:
+ g_clear_pointer (&self->stmt_list.stmts, g_ptr_array_unref);
+ break;
+
case TMPL_EXPR_BOOLEAN:
case TMPL_EXPR_NUMBER:
break;
@@ -145,6 +148,33 @@ tmpl_expr_destroy (TmplExpr *self)
g_slice_free (TmplExpr, self);
}
+/**
+ * tmpl_expr_new_stmt_list:
+ * @stmts: (transfer full) (element-type TmplExpr): a #GPtrArray of
+ * #TmplExpr which will be evaluated in sequence.
+ *
+ * Creates a new statement list for which the last item will be
+ * used as the "return value" from execution.
+ *
+ * Returns: (transfer full): a new #TmplExpr
+ *
+ * Since: 3.36
+ */
+TmplExpr *
+tmpl_expr_new_stmt_list (GPtrArray *stmts)
+{
+ TmplExpr *ret;
+
+ g_return_val_if_fail (stmts != NULL, NULL);
+
+ g_ptr_array_set_free_func (stmts, (GDestroyNotify)tmpl_expr_unref);
+
+ ret = tmpl_expr_new (TMPL_EXPR_STMT_LIST);
+ ((TmplExprStmtList *)ret)->stmts = g_ptr_array_ref (stmts);
+
+ return ret;
+}
+
TmplExpr *
tmpl_expr_new_boolean (gboolean value)
{
diff --git a/src/tmpl-expr.h b/src/tmpl-expr.h
index c34baa4..3c7a733 100644
--- a/src/tmpl-expr.h
+++ b/src/tmpl-expr.h
@@ -84,6 +84,8 @@ TmplExpr *tmpl_expr_new_symbol_ref (const gchar *symbol);
TMPL_AVAILABLE_IN_ALL
TmplExpr *tmpl_expr_new_symbol_assign (const gchar *symbol,
TmplExpr *right);
+TMPL_AVAILABLE_IN_3_36
+TmplExpr *tmpl_expr_new_stmt_list (GPtrArray *stmts);
G_DEFINE_AUTOPTR_CLEANUP_FUNC (TmplExpr, tmpl_expr_unref)
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]