diff --git a/include/QF/cexpr.h b/include/QF/cexpr.h index b8bc734f5..665595d92 100644 --- a/include/QF/cexpr.h +++ b/include/QF/cexpr.h @@ -31,6 +31,7 @@ struct exprval_s; struct exprctx_s; +struct va_ctx_s; typedef struct binop_s { int op; @@ -52,6 +53,7 @@ typedef struct unop_s { typedef struct exprtype_s { const char *name; size_t size; + const char *(*get_string) (const struct exprval_s *val, struct va_ctx_s *va_ctx); binop_t *binops; unop_t *unops; void *data; @@ -114,6 +116,7 @@ int cexpr_parse_enum (exprenum_t *enm, const char *str, binop_t *cexpr_find_cast (exprtype_t *dst_type, exprtype_t *src_type) __attribute__((pure)); exprval_t *cexpr_value (exprtype_t *type, exprctx_t *ctx); exprval_t *cexpr_value_reference (exprtype_t *type, void *data, exprctx_t *ctx); +const char *cexpr_enum_get_string (const exprval_t *val, struct va_ctx_s *va_ctx) __attribute__((pure)); int cexpr_eval_string (const char *str, exprctx_t *context); void cexpr_error(exprctx_t *ctx, const char *fmt, ...) __attribute__((format(PRINTF,2,3))); diff --git a/libs/util/cexpr-type.c b/libs/util/cexpr-type.c index 9c62dec40..2df8bfdce 100644 --- a/libs/util/cexpr-type.c +++ b/libs/util/cexpr-type.c @@ -28,11 +28,14 @@ # include "config.h" #endif #include +#include #include "QF/cexpr.h" #include "QF/cmem.h" #include "QF/mathlib.h" #include "QF/plist.h" +#include "QF/sys.h" +#include "QF/va.h" #include "QF/simd/vec4f.h" #include "libs/util/cexpr-parse.h" @@ -99,6 +102,12 @@ int_mod (const exprval_t *val1, const exprval_t *val2, exprval_t *result, *(int *) result->value = c + (mask & b); } +static const char * +int_get_string (const exprval_t *val, va_ctx_t *va_ctx) +{ + return va (va_ctx, "%d", *(int *) val->value); +} + binop_t int_binops[] = { { SHL, &cexpr_int, &cexpr_int, int_shl }, { SHR, &cexpr_int, &cexpr_int, int_shr }, @@ -128,6 +137,7 @@ exprtype_t cexpr_int = { .size = sizeof (int), .binops = int_binops, .unops = int_unops, + .get_string = int_get_string, }; BINOP(uint, shl, unsigned, <<) @@ -153,6 +163,12 @@ UNOP(uint, neg, unsigned, -) UNOP(uint, tnot, unsigned, !) UNOP(uint, bnot, unsigned, ~) +static const char * +uint_get_string (const exprval_t *val, va_ctx_t *va_ctx) +{ + return va (va_ctx, "%u", *(unsigned *) val->value); +} + binop_t uint_binops[] = { { SHL, &cexpr_uint, &cexpr_uint, uint_shl }, { SHR, &cexpr_uint, &cexpr_uint, uint_shr }, @@ -183,6 +199,7 @@ exprtype_t cexpr_uint = { .size = sizeof (unsigned), .binops = uint_binops, .unops = uint_unops, + .get_string = uint_get_string, }; BINOP(size_t, shl, unsigned, <<) @@ -221,6 +238,12 @@ UNOP(size_t, neg, unsigned, -) UNOP(size_t, tnot, unsigned, !) UNOP(size_t, bnot, unsigned, ~) +static const char * +size_t_get_string (const exprval_t *val, va_ctx_t *va_ctx) +{ + return va (va_ctx, "%zd", *(size_t *) val->value); +} + binop_t size_t_binops[] = { { SHL, &cexpr_size_t, &cexpr_size_t, size_t_shl }, { SHR, &cexpr_size_t, &cexpr_size_t, size_t_shr }, @@ -252,6 +275,7 @@ exprtype_t cexpr_size_t = { .size = sizeof (size_t), .binops = size_t_binops, .unops = size_t_unops, + .get_string = size_t_get_string, }; BINOP(float, add, float, +) @@ -309,6 +333,12 @@ UNOP(float, pos, float, +) UNOP(float, neg, float, -) UNOP(float, tnot, float, !) +static const char * +float_get_string (const exprval_t *val, va_ctx_t *va_ctx) +{ + return va (va_ctx, "%.9g", *(float *) val->value); +} + binop_t float_binops[] = { { '+', &cexpr_float, &cexpr_float, float_add }, { '-', &cexpr_float, &cexpr_float, float_sub }, @@ -337,6 +367,7 @@ exprtype_t cexpr_float = { .size = sizeof (float), .binops = float_binops, .unops = float_unops, + .get_string = float_get_string, }; BINOP(double, add, double, +) @@ -375,6 +406,12 @@ UNOP(double, pos, double, +) UNOP(double, neg, double, -) UNOP(double, tnot, double, !) +static const char * +double_get_string (const exprval_t *val, va_ctx_t *va_ctx) +{ + return va (va_ctx, "%.17g", *(double *) val->value); +} + binop_t double_binops[] = { { '+', &cexpr_double, &cexpr_double, double_add }, { '-', &cexpr_double, &cexpr_double, double_sub }, @@ -401,6 +438,7 @@ exprtype_t cexpr_double = { .size = sizeof (double), .binops = double_binops, .unops = double_unops, + .get_string = double_get_string, }; BINOP(vector, add, vec4f_t, +) @@ -518,6 +556,13 @@ vector_swizzle (const exprval_t *val1, const exprval_t *val2, UNOP(vector, pos, vec4f_t, +) UNOP(vector, neg, vec4f_t, -) +static const char * +vector_get_string (const exprval_t *val, va_ctx_t *va_ctx) +{ + vec4f_t vec = *(vec4f_t *) val->value; + return va (va_ctx, VEC4F_FMT, VEC4_EXP (vec)); +} + static void vector_tnot (const exprval_t *val, exprval_t *result, exprctx_t *ctx) { @@ -550,6 +595,7 @@ exprtype_t cexpr_vector = { .size = sizeof (vec4f_t), .binops = vector_binops, .unops = vector_unops, + .get_string = vector_get_string, }; static void @@ -572,6 +618,13 @@ quaternion_vector_mul (const exprval_t *val1, const exprval_t *val2, *c = qvmulf (a, b); } +static const char * +quaternion_get_string (const exprval_t *val, va_ctx_t *va_ctx) +{ + vec4f_t vec = *(vec4f_t *) val->value; + return va (va_ctx, VEC4F_FMT, VEC4_EXP (vec)); +} + binop_t quaternion_binops[] = { { '+', &cexpr_quaternion, &cexpr_quaternion, vector_add }, { '-', &cexpr_quaternion, &cexpr_quaternion, vector_sub }, @@ -592,6 +645,7 @@ exprtype_t cexpr_quaternion = { .size = sizeof (vec4f_t), .binops = quaternion_binops, .unops = quaternion_unops, + .get_string = quaternion_get_string, }; exprtype_t cexpr_exprval = { @@ -743,3 +797,21 @@ cexpr_parse_enum (exprenum_t *enm, const char *str, const exprctx_t *ctx, context.result = &result; return cexpr_eval_string (str, &context); } + +VISIBLE const char * +cexpr_enum_get_string (const exprval_t *val, va_ctx_t *va_ctx) +{ + exprenum_t *enm = val->type->data; + exprsym_t *symbols = enm->symtab->symbols; + for (exprsym_t *sym = symbols; sym->name; sym++) { + // if there are duplicate values, choose the *later* value + if (sym[1].name + && memcmp (sym->value, sym[1].value, val->type->size) == 0) { + continue; + } + if (memcmp (sym->value, val->value, val->type->size) == 0) { + return sym->name; + } + } + return ""; +} diff --git a/libs/video/renderer/vulkan/vkgen/vkenum.r b/libs/video/renderer/vulkan/vkgen/vkenum.r index cc22577a5..7725c6b34 100644 --- a/libs/video/renderer/vulkan/vkgen/vkenum.r +++ b/libs/video/renderer/vulkan/vkgen/vkenum.r @@ -95,9 +95,11 @@ skip_value(string name) if (strip_bit) { fprintf (output_file, "\t.binops = flag_binops,\n"); fprintf (output_file, "\t.unops = flag_unops,\n"); + fprintf (output_file, "\t.get_string = cexpr_flags_get_string,\n"); } else { fprintf (output_file, "\t.binops = enum_binops,\n"); fprintf (output_file, "\t.unops = 0,\n"); + fprintf (output_file, "\t.get_string = cexpr_enum_get_string,\n"); } fprintf (output_file, "\t.data = &%s_enum,\n", [self name]); fprintf (output_file, "};\n");