From c9734aa945b24fccb58dcac6de6a0aa144c33f4f Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Wed, 30 Aug 2023 17:32:02 +0900 Subject: [PATCH] [qfcc] Add some basic 3d PGA tests And fix a few issues that showed up: I'd forgotten to add @regressive and objects wider than 4 elements need to use the move instructions. --- tools/qfcc/source/qc-lex.l | 1 + tools/qfcc/source/statements.c | 4 +-- tools/qfcc/test/pga3d.r | 54 ++++++++++++++++++++++++++++++++++ 3 files changed, 57 insertions(+), 2 deletions(-) diff --git a/tools/qfcc/source/qc-lex.l b/tools/qfcc/source/qc-lex.l index c23da0f0d..037898396 100644 --- a/tools/qfcc/source/qc-lex.l +++ b/tools/qfcc/source/qc-lex.l @@ -441,6 +441,7 @@ static keyword_t qf_keywords[] = { {"@cross", CROSS, }, {"@dot", DOT, }, {"@wedge", WEDGE, }, + {"@regressive", REGRESSIVE, }, {"@geometric", GEOMETRIC, }, {"@algebra", ALGEBRA, }, }; diff --git a/tools/qfcc/source/statements.c b/tools/qfcc/source/statements.c index 1aee894fc..157813f1c 100644 --- a/tools/qfcc/source/statements.c +++ b/tools/qfcc/source/statements.c @@ -901,7 +901,7 @@ expr_assign (sblock_t *sblock, expr_t *e, operand_t **op) if (src_expr->type == ex_assign) { sblock = statement_subexpr (sblock, src_expr, &src); - if (is_structural (dst_type)) { + if (is_structural (dst_type) || dst_type->width > 4) { return expr_assign_copy (sblock, e, op, src); } if (is_indirect (dst_expr)) { @@ -910,7 +910,7 @@ expr_assign (sblock_t *sblock, expr_t *e, operand_t **op) sblock = statement_subexpr (sblock, dst_expr, &dst); } } else { - if (is_structural (dst_type)) { + if (is_structural (dst_type) || dst_type->width > 4) { return expr_assign_copy (sblock, e, op, src); } diff --git a/tools/qfcc/test/pga3d.r b/tools/qfcc/test/pga3d.r index cbe5e8347..d10eb9954 100644 --- a/tools/qfcc/test/pga3d.r +++ b/tools/qfcc/test/pga3d.r @@ -370,6 +370,55 @@ test_geom (void) return 0; } +static int +test_basics (void) +{ + @algebra (PGA) { + auto plane1 = e1 + 8*e0; + auto plane2 = e2 + 8*e0; + auto line = plane1 @wedge plane2; + auto p = -3*e021 + e123; + auto point = line @dot p * ~line; + auto rot = line * p * ~line; + auto p1 = 12*e032 + 4*e013 + e123; + auto p2 = 4*e032 + 12*e013 + e123; + auto x = point @regressive rot; + + if ((vec4)plane1 != '1 0 0 8' || (vec4)plane2 != '0 1 0 8') { + printf ("plane1 or plane2 wrong: %q %q\n", plane1, plane2); + return 1; + } + if ((vec4)p != '0 0 -3 1' || (vec4)p1 != '12 4 0 1' + || (vec4)p2 != '4 12 0 1') { + printf ("p or p1 or p2 wrong: %q %q %q\n", p, p1, p2); + return 1; + } + bivector_t b = { .bvec = line }; + if ((vec3)b.dir != '0 0 1' || (vec3)b.mom != '-8 8 0') { + printf ("line is wrong: %v %v\n", b.dir, b.mom); + return 1; + } + oddgrades_t o = { .mvec = point }; + if ((vec4)o.vec || (vec4)o.tvec != '-8 -8 -3 1') { + printf ("point is wrong: %q\n", point); + return 1; + } + o.mvec = rot; + if ((vec4)o.vec || (vec4)o.tvec != '-16 -16 -3 1') { + printf ("rot is wrong: %q %q\n", o.vec, o.tvec); + return 1; + } + evengrades_t e = { .mvec = x }; + if (e.scalar || (scalar_t)e.qvec + || (vec3)e.dir != '-8 -8 0' || (vec3)e.mom != '-24 24 0') { + printf ("x is wrong: %g %v %v %g\n", + e.scalar, e.dir, e.mom, (scalar_t)e.qvec); + return 1; + } + } + return 0; +} + int main (void) { @@ -427,5 +476,10 @@ main (void) return 1; } + if (test_basics ()) { + printf ("basics failed\n"); + return 1; + } + return 0; // to survive and prevail :) }