diff --git a/tools/qfcc/source/expr.c b/tools/qfcc/source/expr.c index 922b6834e..daf14dde9 100644 --- a/tools/qfcc/source/expr.c +++ b/tools/qfcc/source/expr.c @@ -1461,7 +1461,7 @@ get_struct_field (const type_t *t1, const expr_t *e1, const expr_t *e2) return 0; } field = symtab_lookup (strct, sym->name); - if (!field && !is_entity(t1)) { + if (!field && !is_entity(t1) && !is_nonscalar (t1)) { const char *name = t1->name; if (!strncmp (name, "tag ", 4)) { name += 4; @@ -1471,6 +1471,17 @@ get_struct_field (const type_t *t1, const expr_t *e1, const expr_t *e2) return field; } +static const expr_t * +swizzle_expr (const expr_t *vec, const expr_t *swizzle) +{ + auto sym = get_name (swizzle); + if (!sym) { + // error already reported + return vec; + } + return new_swizzle_expr (vec, sym->name); +} + const expr_t * field_expr (const expr_t *e1, const expr_t *e2) { @@ -1540,8 +1551,12 @@ field_expr (const expr_t *e1, const expr_t *e2) symbol_t *field; field = get_struct_field (t1, e1, e2); - if (!field) + if (!field) { + if (is_nonscalar (t1)) { + return swizzle_expr (e1, e2); + } return e1; + } if (e1->type == ex_expr && e1->expr.op == '.' && is_entity(get_type (e1->expr.e1))) { diff --git a/tools/qfcc/source/glsl-parse.y b/tools/qfcc/source/glsl-parse.y index 5575d85b3..12af7e402 100644 --- a/tools/qfcc/source/glsl-parse.y +++ b/tools/qfcc/source/glsl-parse.y @@ -276,6 +276,10 @@ postfix_expression } | function_call | postfix_expression '.' IDENTIFIER/*FIELD_SELECTION*/ + { + auto sym = new_symbol_expr ($3); + $$ = field_expr ($1, sym); + } | postfix_expression INCOP { $$ = incop_expr ($2, $1, 1); } ;