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

View File

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

View File

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