mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-03-13 22:22:27 +00:00
[qfcc] Give direct access to algebra subtypes
Currently via only the group mask (which is really horrible to work with: requires too much knowledge of implementation details, but does the job for testing), but it got some basics working.
This commit is contained in:
parent
d2e134cc22
commit
60ce4ba8fb
4 changed files with 52 additions and 6 deletions
|
@ -82,8 +82,10 @@ typedef struct multivector_s {
|
|||
} multivector_t;
|
||||
|
||||
struct expr_s;
|
||||
struct attribute_s;
|
||||
bool is_algebra (const struct type_s *type) __attribute__((pure));
|
||||
struct type_s *algebra_type (struct type_s *type, struct expr_s *params);
|
||||
struct type_s *algebra_subtype (struct type_s *type, struct attribute_s *attr);
|
||||
struct type_s *algebra_mvec_type (algebra_t *algebra, pr_uint_t group_mask);
|
||||
struct ex_value_s *algebra_blade_value (algebra_t *alg, const char *name);
|
||||
struct symtab_s *algebra_scope (struct type_s *type, struct symtab_s *curscope);
|
||||
|
|
|
@ -37,6 +37,7 @@
|
|||
#include "QF/va.h"
|
||||
|
||||
#include "tools/qfcc/include/algebra.h"
|
||||
#include "tools/qfcc/include/attribute.h"
|
||||
#include "tools/qfcc/include/diagnostic.h"
|
||||
#include "tools/qfcc/include/expr.h"
|
||||
#include "tools/qfcc/include/strpool.h"
|
||||
|
@ -412,6 +413,34 @@ algebra_type (type_t *type, expr_t *params)
|
|||
return find_type (t);
|
||||
}
|
||||
|
||||
type_t *
|
||||
algebra_subtype (type_t *type, attribute_t *attr)
|
||||
{
|
||||
if (!is_algebra (type)) {
|
||||
internal_error (0, "unexpected type");
|
||||
}
|
||||
auto algebra = algebra_get (type);
|
||||
if (strcmp (attr->name, "group_mask") == 0) {
|
||||
if (!attr->params || attr->params->next) {
|
||||
error (0, "incorrect number of parameters to 'group_mask'");
|
||||
return type;
|
||||
}
|
||||
auto param = attr->params;
|
||||
if (!is_integral_val (param)) {
|
||||
error (0, "'group_mask' parameter must be an integer constant");
|
||||
return type;
|
||||
}
|
||||
pr_uint_t mask = expr_integral (param);
|
||||
if (!mask || mask > ((1u << algebra->layout.count) - 1)) {
|
||||
error (0, "invalid group_mask");
|
||||
return type;
|
||||
}
|
||||
return algebra_mvec_type (algebra, mask);
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
|
||||
type_t *
|
||||
algebra_mvec_type (algebra_t *algebra, pr_uint_t group_mask)
|
||||
{
|
||||
|
|
|
@ -894,7 +894,11 @@ typespec
|
|||
|
||||
typespec_reserved
|
||||
: TYPE_SPEC
|
||||
| algebra_specifier
|
||||
| algebra_specifier %prec LOW
|
||||
| algebra_specifier '.' attribute
|
||||
{
|
||||
$$ = make_spec (algebra_subtype ($1.type, $3), 0, 0, 0);
|
||||
}
|
||||
| enum_specifier
|
||||
| struct_specifier
|
||||
// NOTE: fields don't parse the way they should. This is not a problem
|
||||
|
@ -907,9 +911,18 @@ typespec_reserved
|
|||
}
|
||||
;
|
||||
|
||||
|
||||
typespec_nonreserved
|
||||
: TYPE_NAME
|
||||
: TYPE_NAME %prec LOW
|
||||
| TYPE_NAME '.' attribute
|
||||
{
|
||||
if (!is_algebra ($1.type)) {
|
||||
error (0, "%s does not have any subtypes",
|
||||
get_type_string ($1.type));
|
||||
$$ = $1;
|
||||
} else {
|
||||
$$ = make_spec (algebra_subtype ($1.type, $3), 0, 0, 0);
|
||||
}
|
||||
}
|
||||
| OBJECT_NAME protocolrefs
|
||||
{
|
||||
if ($2) {
|
||||
|
@ -1015,7 +1028,7 @@ attribute_list
|
|||
;
|
||||
|
||||
attribute
|
||||
: NAME { $$ = new_attribute ($1->name, 0); }
|
||||
: NAME %prec LOW { $$ = new_attribute ($1->name, 0); }
|
||||
| NAME '(' expr_list ')' { $$ = new_attribute ($1->name, $3); }
|
||||
;
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
#include "test-harness.h"
|
||||
int foo[128];
|
||||
@algebra(float) pgaf1;
|
||||
//@algebra(double) pgad1;
|
||||
|
@ -13,16 +14,16 @@ typedef @algebra(float(4,1)) CGA;
|
|||
typedef @algebra(double(2,0,1)) PGA2;
|
||||
PGA2 pga2;
|
||||
|
||||
float sin(float x) = #0;
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
PGA.group_mask (0x1) plane;
|
||||
@algebra (PGA) {
|
||||
auto p1 = 3*e1 + e2 - e3 + e0;
|
||||
auto p2 = e1 + 3*e2 + e3 - e0;
|
||||
auto v = 4*(e1 + e032 + e123);
|
||||
pgaf1 = p1 + v * p2;
|
||||
plane = p1;
|
||||
// pgaf1 = (p1 + v)∧p2;
|
||||
// pgaf1 = v • p2;
|
||||
#if 0
|
||||
|
@ -46,5 +47,6 @@ main (void)
|
|||
// pga2 = p + (1 + p)∧l1;
|
||||
pga2 = (l1 • p)*l1;
|
||||
}
|
||||
printf ("%q\n", plane);
|
||||
return 0; // to survive and prevail :)
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue