From ed824405fe215b978590c3a9757d9066ad73566c Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Sat, 9 Sep 2023 23:08:38 +0900 Subject: [PATCH] [qfcc] Support struct access to full algebra vectors This makes them actually useable. Multi-vector expressions and variables will be done soon. --- tools/qfcc/include/algebra.h | 2 ++ tools/qfcc/include/expr.h | 2 ++ tools/qfcc/source/algebra.c | 4 ++-- tools/qfcc/source/expr.c | 4 +++- tools/qfcc/source/expr_algebra.c | 17 +++++++++++++++++ tools/qfcc/test/algtypes.r | 5 +++++ 6 files changed, 31 insertions(+), 3 deletions(-) diff --git a/tools/qfcc/include/algebra.h b/tools/qfcc/include/algebra.h index 72030caf7..c62d6abfb 100644 --- a/tools/qfcc/include/algebra.h +++ b/tools/qfcc/include/algebra.h @@ -115,5 +115,7 @@ struct expr_s *algebra_dual (struct expr_s *e); struct expr_s *algebra_reverse (struct expr_s *e); struct expr_s *algebra_cast_expr (struct type_s *dstType, struct expr_s *e); struct expr_s *algebra_assign_expr (struct expr_s *dst, struct expr_s *src); +struct expr_s *algebra_field_expr (struct expr_s *mvec, + struct expr_s *field_name); #endif//__algebra_h diff --git a/tools/qfcc/include/expr.h b/tools/qfcc/include/expr.h index e079de644..6a5c3524f 100644 --- a/tools/qfcc/include/expr.h +++ b/tools/qfcc/include/expr.h @@ -633,6 +633,8 @@ expr_t *new_entity_expr (int entity_val); (expr_t::e::field_val). */ expr_t *new_field_expr (int field_val, struct type_s *type, struct def_s *def); +struct symbol_s *get_struct_field (const struct type_s *t1, expr_t *e1, + expr_t *e2); /** Create a new function constant expression node. diff --git a/tools/qfcc/source/algebra.c b/tools/qfcc/source/algebra.c index 829ede425..0014ee132 100644 --- a/tools/qfcc/source/algebra.c +++ b/tools/qfcc/source/algebra.c @@ -111,9 +111,9 @@ static const char *mvec_3d_names[] = { static const char *mvec_4d_names[] = { "vec", - "bvecv", + "bvect", "scalar", - "bvecm", + "bvecp", "qvec", "tvec", 0 diff --git a/tools/qfcc/source/expr.c b/tools/qfcc/source/expr.c index fc4e76245..69ab2c0de 100644 --- a/tools/qfcc/source/expr.c +++ b/tools/qfcc/source/expr.c @@ -1463,7 +1463,7 @@ prepend_expr (expr_t *block, expr_t *e) return block; } -static symbol_t * +symbol_t * get_struct_field (const type_t *t1, expr_t *e1, expr_t *e2) { symtab_t *strct = 0; @@ -1587,6 +1587,8 @@ field_expr (expr_t *e1, expr_t *e2) return new_offset_alias_expr (field->type, e1, field->s.offset); } } + } else if (is_algebra (t1)) { + return algebra_field_expr (e1, e2); } else if (is_class (t1)) { //Class instance variables aren't allowed and thus declaring one //is treated as an error, so this is a follow-on error. diff --git a/tools/qfcc/source/expr_algebra.c b/tools/qfcc/source/expr_algebra.c index a3217e7ef..43aee6f4c 100644 --- a/tools/qfcc/source/expr_algebra.c +++ b/tools/qfcc/source/expr_algebra.c @@ -2242,3 +2242,20 @@ algebra_assign_expr (expr_t *dst, expr_t *src) } return block; } + +expr_t * +algebra_field_expr (expr_t *mvec, expr_t *field_name) +{ + auto mvec_type = get_type (mvec); + auto algebra = algebra_get (mvec_type); + + if (mvec_type->type == ev_invalid) { + auto mvec_struct = algebra->mvec_sym->type; + auto field = get_struct_field (mvec_struct, mvec, field_name); + if (!field) { + return mvec; + } + return new_offset_alias_expr (field->type, mvec, field->s.offset); + } + internal_error (mvec, "not implemented"); +} diff --git a/tools/qfcc/test/algtypes.r b/tools/qfcc/test/algtypes.r index 4c4f60572..68b937de7 100644 --- a/tools/qfcc/test/algtypes.r +++ b/tools/qfcc/test/algtypes.r @@ -48,5 +48,10 @@ main (void) pga2 = (l1 • p)*l1; } printf ("%q\n", plane); + printf ("%g\n", pgaf1.scalar); + printf ("%q\n", pgaf1.vec); + printf ("%v %v\n", pgaf1.bvect, pgaf1.bvecp); + printf ("%q\n", pgaf1.tvec); + printf ("%g\n", (float)pgaf1.qvec); return 0; // to survive and prevail :) }