From e929dca3006b1b549994056386f1f32ac4bf5916 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Thu, 4 Feb 2021 22:37:20 +0900 Subject: [PATCH] [util] Auto-cast plist string items The casting uses a recursive call to the expression parser, so the expressions are type-checked automatically. --- include/QF/cexpr.h | 3 +++ libs/util/cexpr-type.c | 25 +++++++++++++++++++++++ libs/video/renderer/vulkan/vkgen/vkenum.r | 2 +- libs/video/renderer/vulkan/vkparse.c | 6 ++++++ 4 files changed, 35 insertions(+), 1 deletion(-) diff --git a/include/QF/cexpr.h b/include/QF/cexpr.h index f511b6a9c..4e2dd3bcb 100644 --- a/include/QF/cexpr.h +++ b/include/QF/cexpr.h @@ -118,6 +118,9 @@ void cexpr_struct_pointer_getfield (const exprval_t *a, const exprval_t *b, exprval_t *cexpr_cvar (const char *name, exprctx_t *ctx); exprval_t *cexpr_cvar_struct (exprctx_t *ctx); +void cexpr_cast_plitem (const exprval_t *val1, const exprval_t *src, + exprval_t *result, exprctx_t *ctx); + void cexpr_init_symtab (exprtab_t *symtab, exprctx_t *ctx); char *cexpr_yyget_text (void *scanner); diff --git a/libs/util/cexpr-type.c b/libs/util/cexpr-type.c index c01e0cac0..1ba3b3f0f 100644 --- a/libs/util/cexpr-type.c +++ b/libs/util/cexpr-type.c @@ -100,6 +100,7 @@ binop_t int_binops[] = { { '^', &cexpr_int, &cexpr_int, int_xor }, { '%', &cexpr_int, &cexpr_int, int_rem }, { MOD, &cexpr_int, &cexpr_int, int_mod }, + { '=', &cexpr_plitem, &cexpr_int, cexpr_cast_plitem }, {} }; @@ -154,6 +155,7 @@ binop_t uint_binops[] = { { '%', &cexpr_uint, &cexpr_uint, uint_rem }, { MOD, &cexpr_uint, &cexpr_uint, uint_rem }, { '=', &cexpr_int, &cexpr_uint, uint_cast_int }, + { '=', &cexpr_plitem, &cexpr_uint, cexpr_cast_plitem }, {} }; @@ -222,6 +224,7 @@ binop_t size_t_binops[] = { { MOD, &cexpr_size_t, &cexpr_size_t, size_t_rem }, { '=', &cexpr_int, &cexpr_size_t, size_t_cast_int }, { '=', &cexpr_uint, &cexpr_size_t, size_t_cast_uint }, + { '=', &cexpr_plitem, &cexpr_size_t, cexpr_cast_plitem }, {} }; @@ -310,6 +313,7 @@ binop_t float_binops[] = { { '%', &cexpr_float, &cexpr_float, float_rem }, { MOD, &cexpr_float, &cexpr_float, float_mod }, { '=', &cexpr_int, &cexpr_float, float_cast_int }, + { '=', &cexpr_plitem, &cexpr_float, cexpr_cast_plitem }, {} }; @@ -366,6 +370,7 @@ binop_t double_binops[] = { { '/', &cexpr_double, &cexpr_double, double_div }, { '%', &cexpr_double, &cexpr_double, double_rem }, { MOD, &cexpr_double, &cexpr_double, double_mod }, + { '=', &cexpr_plitem, &cexpr_double, cexpr_cast_plitem }, {} }; @@ -595,6 +600,26 @@ exprtype_t cexpr_function = { 0, }; +void +cexpr_cast_plitem (const exprval_t *val1, const exprval_t *src, + exprval_t *result, exprctx_t *ctx) +{ + plitem_t *item = *(plitem_t **) src->value; + const char *str = PL_String (item); + if (!str) { + cexpr_error (ctx, "not a string object: %d", PL_Line (item)); + return; + } + + exprctx_t ectx = *ctx; + ectx.result = result; + cexpr_eval_string (str, &ectx); + ctx->errors += ectx.errors; + if (ectx.errors) { + cexpr_error (ctx, "could not convert: %d", PL_Line (item)); + } +} + static void plitem_field (const exprval_t *a, const exprval_t *b, exprval_t *c, exprctx_t *ctx) diff --git a/libs/video/renderer/vulkan/vkgen/vkenum.r b/libs/video/renderer/vulkan/vkgen/vkenum.r index 7c974f6fb..b4dc8b79f 100644 --- a/libs/video/renderer/vulkan/vkgen/vkenum.r +++ b/libs/video/renderer/vulkan/vkgen/vkenum.r @@ -79,7 +79,7 @@ skip_value(string name) fprintf (output_file, "\tflag_binops,\n"); fprintf (output_file, "\tflag_unops,\n"); } else { - fprintf (output_file, "\t0,\n"); + fprintf (output_file, "\tenum_binops,\n"); fprintf (output_file, "\t0,\n"); } fprintf (output_file, "};\n"); diff --git a/libs/video/renderer/vulkan/vkparse.c b/libs/video/renderer/vulkan/vkparse.c index aa6c88325..90e8d5d5e 100644 --- a/libs/video/renderer/vulkan/vkparse.c +++ b/libs/video/renderer/vulkan/vkparse.c @@ -103,6 +103,12 @@ binop_t flag_binops[] = { { '|', 0, 0, flag_or }, { '&', 0, 0, flag_and }, { '=', &cexpr_int, 0, flag_cast_int }, + { '=', &cexpr_plitem, 0, cexpr_cast_plitem }, + {} +}; + +binop_t enum_binops[] = { + { '=', &cexpr_plitem, 0, cexpr_cast_plitem }, {} };