From 11b247918e97bf8c47875d630f9b46128fe29015 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Fri, 9 Feb 2024 11:35:40 +0900 Subject: [PATCH] [qfcc] Find current algebra context for duals Now finding the dual of a scalar works, too (need a context as otherwise the pseudo-scalar is unknown). --- tools/qfcc/include/algebra.h | 1 + tools/qfcc/source/algebra.c | 20 ++++++++++++++++++++ tools/qfcc/source/expr_algebra.c | 5 ++--- 3 files changed, 23 insertions(+), 3 deletions(-) diff --git a/tools/qfcc/include/algebra.h b/tools/qfcc/include/algebra.h index b40c77bd7..152f58234 100644 --- a/tools/qfcc/include/algebra.h +++ b/tools/qfcc/include/algebra.h @@ -94,6 +94,7 @@ type_t *algebra_mvec_type (algebra_t *algebra, pr_uint_t group_mask); int algebra_count_flips (const algebra_t *alg, pr_uint_t a, pr_uint_t b) __attribute__((pure)); struct ex_value_s *algebra_blade_value (algebra_t *alg, const char *name); struct symtab_s *algebra_scope (type_t *type, struct symtab_s *curscope); +algebra_t *algebra_context (const type_t *type) __attribute__((pure)); void algebra_print_type_str (struct dstring_s *str, const type_t *type); void algebra_encode_type (struct dstring_s *encoding, const type_t *type); int algebra_type_size (const type_t *type) __attribute__((pure)); diff --git a/tools/qfcc/source/algebra.c b/tools/qfcc/source/algebra.c index efbe97cad..d4b1930ba 100644 --- a/tools/qfcc/source/algebra.c +++ b/tools/qfcc/source/algebra.c @@ -42,6 +42,7 @@ #include "tools/qfcc/include/attribute.h" #include "tools/qfcc/include/diagnostic.h" #include "tools/qfcc/include/expr.h" +#include "tools/qfcc/include/shared.h" #include "tools/qfcc/include/strpool.h" #include "tools/qfcc/include/struct.h" #include "tools/qfcc/include/symtab.h" @@ -675,6 +676,25 @@ algebra_get (const type_t *type) } } +algebra_t * +algebra_context (const type_t *type) +{ + algebra_t *alg = nullptr; + if (type && is_algebra (type)) { + alg = algebra_get (type); + } + if (!alg) { + symtab_t *scope = current_symtab; + while (scope && scope->procsymbol != algebra_symbol) { + scope = scope->parent; + } + if (scope) { + alg = scope->procsymbol_data; + } + } + return alg; +} + void algebra_print_type_str (dstring_t *str, const type_t *type) { diff --git a/tools/qfcc/source/expr_algebra.c b/tools/qfcc/source/expr_algebra.c index b2ddd66cf..515c14fe8 100644 --- a/tools/qfcc/source/expr_algebra.c +++ b/tools/qfcc/source/expr_algebra.c @@ -2708,11 +2708,10 @@ algebra_negate (const expr_t *e) const expr_t * algebra_dual (const expr_t *e) { - if (!is_algebra (get_type (e))) { - //FIXME check for being in an @algebra { } block + auto algebra = algebra_context (get_type (e)); + if (!algebra) { return error (e, "cannot take the dual of a scalar without context"); } - auto algebra = algebra_get (get_type (e)); auto layout = &algebra->layout; const expr_t *a[layout->count] = {};