Simplify layout of Expr.

Make the union anonymous so that its elements can be addressed
directly. Then, move the Expr *b field into the union, as it
already is never used at the same time as any of the union members.
pull/4/head
EvilSpirit 2016-01-09 17:36:32 +06:00 committed by whitequark
parent 158c66b1b4
commit 84a6511cfc
3 changed files with 49 additions and 49 deletions

View File

@ -214,7 +214,7 @@ Expr *ExprQuaternion::Magnitude(void) {
Expr *Expr::From(hParam p) { Expr *Expr::From(hParam p) {
Expr *r = AllocExpr(); Expr *r = AllocExpr();
r->op = PARAM; r->op = PARAM;
r->x.parh = p; r->parh = p;
return r; return r;
} }
@ -250,7 +250,7 @@ Expr *Expr::From(double v) {
Expr *r = AllocExpr(); Expr *r = AllocExpr();
r->op = CONSTANT; r->op = CONSTANT;
r->x.v = v; r->v = v;
return r; return r;
} }
@ -315,14 +315,14 @@ Expr *Expr::DeepCopyWithParamsAsPointers(IdList<Param,hParam> *firstTry,
// A param that is referenced by its hParam gets rewritten to go // A param that is referenced by its hParam gets rewritten to go
// straight in to the parameter table with a pointer, or simply // straight in to the parameter table with a pointer, or simply
// into a constant if it's already known. // into a constant if it's already known.
Param *p = firstTry->FindByIdNoOops(x.parh); Param *p = firstTry->FindByIdNoOops(parh);
if(!p) p = thenTry->FindById(x.parh); if(!p) p = thenTry->FindById(parh);
if(p->known) { if(p->known) {
n->op = CONSTANT; n->op = CONSTANT;
n->x.v = p->val; n->v = p->val;
} else { } else {
n->op = PARAM_PTR; n->op = PARAM_PTR;
n->x.parp = p; n->parp = p;
} }
return n; return n;
} }
@ -336,10 +336,10 @@ Expr *Expr::DeepCopyWithParamsAsPointers(IdList<Param,hParam> *firstTry,
double Expr::Eval(void) { double Expr::Eval(void) {
switch(op) { switch(op) {
case PARAM: return SK.GetParam(x.parh)->val; case PARAM: return SK.GetParam(parh)->val;
case PARAM_PTR: return (x.parp)->val; case PARAM_PTR: return parp->val;
case CONSTANT: return x.v; case CONSTANT: return v;
case PLUS: return a->Eval() + b->Eval(); case PLUS: return a->Eval() + b->Eval();
case MINUS: return a->Eval() - b->Eval(); case MINUS: return a->Eval() - b->Eval();
@ -362,8 +362,8 @@ Expr *Expr::PartialWrt(hParam p) {
Expr *da, *db; Expr *da, *db;
switch(op) { switch(op) {
case PARAM_PTR: return From(p.v == x.parp->h.v ? 1 : 0); case PARAM_PTR: return From(p.v == parp->h.v ? 1 : 0);
case PARAM: return From(p.v == x.parh.v ? 1 : 0); case PARAM: return From(p.v == parh.v ? 1 : 0);
case CONSTANT: return From(0.0); case CONSTANT: return From(0.0);
@ -403,8 +403,8 @@ Expr *Expr::PartialWrt(hParam p) {
uint64_t Expr::ParamsUsed(void) { uint64_t Expr::ParamsUsed(void) {
uint64_t r = 0; uint64_t r = 0;
if(op == PARAM) r |= ((uint64_t)1 << (x.parh.v % 61)); if(op == PARAM) r |= ((uint64_t)1 << (parh.v % 61));
if(op == PARAM_PTR) r |= ((uint64_t)1 << (x.parp->h.v % 61)); if(op == PARAM_PTR) r |= ((uint64_t)1 << (parp->h.v % 61));
int c = Children(); int c = Children();
if(c >= 1) r |= a->ParamsUsed(); if(c >= 1) r |= a->ParamsUsed();
@ -413,8 +413,8 @@ uint64_t Expr::ParamsUsed(void) {
} }
bool Expr::DependsOn(hParam p) { bool Expr::DependsOn(hParam p) {
if(op == PARAM) return (x.parh.v == p.v); if(op == PARAM) return (parh.v == p.v);
if(op == PARAM_PTR) return (x.parp->h.v == p.v); if(op == PARAM_PTR) return (parp->h.v == p.v);
int c = Children(); int c = Children();
if(c == 1) return a->DependsOn(p); if(c == 1) return a->DependsOn(p);
@ -447,29 +447,29 @@ Expr *Expr::FoldConstants(void) {
if(n->a->op == CONSTANT && n->b->op == CONSTANT) { if(n->a->op == CONSTANT && n->b->op == CONSTANT) {
double nv = n->Eval(); double nv = n->Eval();
n->op = CONSTANT; n->op = CONSTANT;
n->x.v = nv; n->v = nv;
break; break;
} }
// x + 0 = 0 + x = x // x + 0 = 0 + x = x
if(op == PLUS && n->b->op == CONSTANT && Tol(n->b->x.v, 0)) { if(op == PLUS && n->b->op == CONSTANT && Tol(n->b->v, 0)) {
*n = *(n->a); break; *n = *(n->a); break;
} }
if(op == PLUS && n->a->op == CONSTANT && Tol(n->a->x.v, 0)) { if(op == PLUS && n->a->op == CONSTANT && Tol(n->a->v, 0)) {
*n = *(n->b); break; *n = *(n->b); break;
} }
// 1*x = x*1 = x // 1*x = x*1 = x
if(op == TIMES && n->b->op == CONSTANT && Tol(n->b->x.v, 1)) { if(op == TIMES && n->b->op == CONSTANT && Tol(n->b->v, 1)) {
*n = *(n->a); break; *n = *(n->a); break;
} }
if(op == TIMES && n->a->op == CONSTANT && Tol(n->a->x.v, 1)) { if(op == TIMES && n->a->op == CONSTANT && Tol(n->a->v, 1)) {
*n = *(n->b); break; *n = *(n->b); break;
} }
// 0*x = x*0 = 0 // 0*x = x*0 = 0
if(op == TIMES && n->b->op == CONSTANT && Tol(n->b->x.v, 0)) { if(op == TIMES && n->b->op == CONSTANT && Tol(n->b->v, 0)) {
n->op = CONSTANT; n->x.v = 0; break; n->op = CONSTANT; n->v = 0; break;
} }
if(op == TIMES && n->a->op == CONSTANT && Tol(n->a->x.v, 0)) { if(op == TIMES && n->a->op == CONSTANT && Tol(n->a->v, 0)) {
n->op = CONSTANT; n->x.v = 0; break; n->op = CONSTANT; n->v = 0; break;
} }
break; break;
@ -484,7 +484,7 @@ Expr *Expr::FoldConstants(void) {
if(n->a->op == CONSTANT) { if(n->a->op == CONSTANT) {
double nv = n->Eval(); double nv = n->Eval();
n->op = CONSTANT; n->op = CONSTANT;
n->x.v = nv; n->v = nv;
} }
break; break;
@ -496,8 +496,8 @@ Expr *Expr::FoldConstants(void) {
void Expr::Substitute(hParam oldh, hParam newh) { void Expr::Substitute(hParam oldh, hParam newh) {
if(op == PARAM_PTR) oops(); if(op == PARAM_PTR) oops();
if(op == PARAM && x.parh.v == oldh.v) { if(op == PARAM && parh.v == oldh.v) {
x.parh = newh; parh = newh;
} }
int c = Children(); int c = Children();
if(c >= 1) a->Substitute(oldh, newh); if(c >= 1) a->Substitute(oldh, newh);
@ -513,8 +513,8 @@ const hParam Expr::NO_PARAMS = { 0 };
const hParam Expr::MULTIPLE_PARAMS = { 1 }; const hParam Expr::MULTIPLE_PARAMS = { 1 };
hParam Expr::ReferencedParams(ParamList *pl) { hParam Expr::ReferencedParams(ParamList *pl) {
if(op == PARAM) { if(op == PARAM) {
if(pl->FindByIdNoOops(x.parh)) { if(pl->FindByIdNoOops(parh)) {
return x.parh; return parh;
} else { } else {
return NO_PARAMS; return NO_PARAMS;
} }
@ -552,10 +552,10 @@ std::string Expr::Print(void) {
char c; char c;
switch(op) { switch(op) {
case PARAM: return ssprintf("param(%08x)", x.parh.v); case PARAM: return ssprintf("param(%08x)", parh.v);
case PARAM_PTR: return ssprintf("param(p%08x)", x.parp->h.v); case PARAM_PTR: return ssprintf("param(p%08x)", parp->h.v);
case CONSTANT: return ssprintf("%.3f", x.v); case CONSTANT: return ssprintf("%.3f", v);
case PLUS: c = '+'; goto p; case PLUS: c = '+'; goto p;
case MINUS: c = '-'; goto p; case MINUS: c = '-'; goto p;
@ -628,7 +628,7 @@ int Expr::Precedence(Expr *e) {
if(e->op == ALL_RESOLVED) return -1; // never want to reduce this marker if(e->op == ALL_RESOLVED) return -1; // never want to reduce this marker
if(e->op != BINARY_OP && e->op != UNARY_OP) oops(); if(e->op != BINARY_OP && e->op != UNARY_OP) oops();
switch(e->x.c) { switch(e->c) {
case 'q': case 'q':
case 's': case 's':
case 'c': case 'c':
@ -650,7 +650,7 @@ void Expr::Reduce(void) {
Expr *op = PopOperator(); Expr *op = PopOperator();
Expr *n; Expr *n;
int o; int o;
switch(op->x.c) { switch(op->c) {
case '+': o = PLUS; goto c; case '+': o = PLUS; goto c;
case '-': o = MINUS; goto c; case '-': o = MINUS; goto c;
case '*': o = TIMES; goto c; case '*': o = TIMES; goto c;
@ -690,21 +690,21 @@ void Expr::Parse(void) {
if(n->op == CONSTANT) { if(n->op == CONSTANT) {
PushOperand(n); PushOperand(n);
Consume(); Consume();
} else if(n->op == PAREN && n->x.c == '(') { } else if(n->op == PAREN && n->c == '(') {
Consume(); Consume();
Parse(); Parse();
n = Next(); n = Next();
if(n->op != PAREN || n->x.c != ')') throw "expected: )"; if(n->op != PAREN || n->c != ')') throw "expected: )";
Consume(); Consume();
} else if(n->op == UNARY_OP) { } else if(n->op == UNARY_OP) {
PushOperator(n); PushOperator(n);
Consume(); Consume();
continue; continue;
} else if(n->op == BINARY_OP && n->x.c == '-') { } else if(n->op == BINARY_OP && n->c == '-') {
// The minus sign is special, because it might be binary or // The minus sign is special, because it might be binary or
// unary, depending on context. // unary, depending on context.
n->op = UNARY_OP; n->op = UNARY_OP;
n->x.c = 'n'; n->c = 'n';
PushOperator(n); PushOperator(n);
Consume(); Consume();
continue; continue;
@ -743,7 +743,7 @@ void Expr::Lex(const char *in) {
number[len++] = '\0'; number[len++] = '\0';
Expr *e = AllocExpr(); Expr *e = AllocExpr();
e->op = CONSTANT; e->op = CONSTANT;
e->x.v = atof(number); e->v = atof(number);
Unparsed[UnparsedCnt++] = e; Unparsed[UnparsedCnt++] = e;
} else if(isalpha(c) || c == '_') { } else if(isalpha(c) || c == '_') {
char name[70]; char name[70];
@ -757,16 +757,16 @@ void Expr::Lex(const char *in) {
Expr *e = AllocExpr(); Expr *e = AllocExpr();
if(strcmp(name, "sqrt")==0) { if(strcmp(name, "sqrt")==0) {
e->op = UNARY_OP; e->op = UNARY_OP;
e->x.c = 'q'; e->c = 'q';
} else if(strcmp(name, "cos")==0) { } else if(strcmp(name, "cos")==0) {
e->op = UNARY_OP; e->op = UNARY_OP;
e->x.c = 'c'; e->c = 'c';
} else if(strcmp(name, "sin")==0) { } else if(strcmp(name, "sin")==0) {
e->op = UNARY_OP; e->op = UNARY_OP;
e->x.c = 's'; e->c = 's';
} else if(strcmp(name, "pi")==0) { } else if(strcmp(name, "pi")==0) {
e->op = CONSTANT; e->op = CONSTANT;
e->x.v = PI; e->v = PI;
} else { } else {
throw "unknown name"; throw "unknown name";
} }
@ -774,7 +774,7 @@ void Expr::Lex(const char *in) {
} else if(strchr("+-*/()", c)) { } else if(strchr("+-*/()", c)) {
Expr *e = AllocExpr(); Expr *e = AllocExpr();
e->op = (c == '(' || c == ')') ? PAREN : BINARY_OP; e->op = (c == '(' || c == ')') ? PAREN : BINARY_OP;
e->x.c = c; e->c = c;
Unparsed[UnparsedCnt++] = e; Unparsed[UnparsedCnt++] = e;
in++; in++;
} else if(isspace(c)) { } else if(isspace(c)) {

View File

@ -52,19 +52,19 @@ public:
int op; int op;
Expr *a; Expr *a;
Expr *b;
union { union {
double v; double v;
hParam parh; hParam parh;
Param *parp; Param *parp;
hEntity entity; hEntity entity;
Expr *b;
// For use while parsing // For use while parsing
char c; char c;
} x; };
Expr() { } Expr() { }
Expr(double v) : op(CONSTANT) { x.v = v; } Expr(double val) : op(CONSTANT) { v = val; }
static inline Expr *AllocExpr(void) static inline Expr *AllocExpr(void)
{ return (Expr *)AllocTemporary(sizeof(Expr)); } { return (Expr *)AllocTemporary(sizeof(Expr)); }

View File

@ -94,8 +94,8 @@ void System::SolveBySubstitution(void) {
tex->a->op == Expr::PARAM && tex->a->op == Expr::PARAM &&
tex->b->op == Expr::PARAM) tex->b->op == Expr::PARAM)
{ {
hParam a = (tex->a)->x.parh; hParam a = tex->a->parh;
hParam b = (tex->b)->x.parh; hParam b = tex->b->parh;
if(!(param.FindByIdNoOops(a) && param.FindByIdNoOops(b))) { if(!(param.FindByIdNoOops(a) && param.FindByIdNoOops(b))) {
// Don't substitute unless they're both solver params; // Don't substitute unless they're both solver params;
// otherwise it's an equation that can be solved immediately, // otherwise it's an equation that can be solved immediately,