1 //----------------------------------------------------------------------------- 2 // An expression in our symbolic algebra system, used to write, linearize, 3 // and solve our constraint equations. 4 // 5 // Copyright 2008-2013 Jonathan Westhues. 6 //----------------------------------------------------------------------------- 7 8 #ifndef __EXPR_H 9 #define __EXPR_H 10 11 class Expr; 12 13 class Expr { 14 public: 15 16 enum { 17 // A parameter, by the hParam handle 18 PARAM = 0, 19 // A parameter, by a pointer straight in to the param table (faster, 20 // if we know that the param table won't move around) 21 PARAM_PTR = 1, 22 23 CONSTANT = 20, 24 25 PLUS = 100, 26 MINUS = 101, 27 TIMES = 102, 28 DIV = 103, 29 NEGATE = 104, 30 SQRT = 105, 31 SQUARE = 106, 32 SIN = 107, 33 COS = 108, 34 ASIN = 109, 35 ACOS = 110, 36 37 // Special helpers for when we're parsing an expression from text. 38 // Initially, literals (like a constant number) appear in the same 39 // format as they will in the finished expression, but the operators 40 // are different until the parser fixes things up (and builds the 41 // tree from the flat list that the lexer outputs). 42 ALL_RESOLVED = 1000, 43 PAREN = 1001, 44 BINARY_OP = 1002, 45 UNARY_OP = 1003 46 }; 47 48 int op; 49 Expr *a; 50 union { 51 double v; 52 hParam parh; 53 Param *parp; 54 Expr *b; 55 56 // For use while parsing 57 char c; 58 }; 59 Expr()60 Expr() { } Expr(double val)61 Expr(double val) : op(CONSTANT) { v = val; } 62 AllocExpr(void)63 static inline Expr *AllocExpr(void) 64 { return (Expr *)AllocTemporary(sizeof(Expr)); } 65 66 static Expr *From(hParam p); 67 static Expr *From(double v); 68 69 Expr *AnyOp(int op, Expr *b); Plus(Expr * b_)70 inline Expr *Plus (Expr *b_) { return AnyOp(PLUS, b_); } Minus(Expr * b_)71 inline Expr *Minus(Expr *b_) { return AnyOp(MINUS, b_); } Times(Expr * b_)72 inline Expr *Times(Expr *b_) { return AnyOp(TIMES, b_); } Div(Expr * b_)73 inline Expr *Div (Expr *b_) { return AnyOp(DIV, b_); } 74 Negate(void)75 inline Expr *Negate(void) { return AnyOp(NEGATE, NULL); } Sqrt(void)76 inline Expr *Sqrt (void) { return AnyOp(SQRT, NULL); } Square(void)77 inline Expr *Square(void) { return AnyOp(SQUARE, NULL); } Sin(void)78 inline Expr *Sin (void) { return AnyOp(SIN, NULL); } Cos(void)79 inline Expr *Cos (void) { return AnyOp(COS, NULL); } ASin(void)80 inline Expr *ASin (void) { return AnyOp(ASIN, NULL); } ACos(void)81 inline Expr *ACos (void) { return AnyOp(ACOS, NULL); } 82 83 Expr *PartialWrt(hParam p); 84 double Eval(void); 85 uint64_t ParamsUsed(void); 86 bool DependsOn(hParam p); 87 static bool Tol(double a, double b); 88 Expr *FoldConstants(void); 89 void Substitute(hParam oldh, hParam newh); 90 91 static const hParam NO_PARAMS, MULTIPLE_PARAMS; 92 hParam ReferencedParams(ParamList *pl); 93 94 void ParamsToPointers(void); 95 96 std::string Print(void); 97 98 // number of child nodes: 0 (e.g. constant), 1 (sqrt), or 2 (+) 99 int Children(void); 100 // total number of nodes in the tree 101 int Nodes(void); 102 103 // Make a simple copy 104 Expr *DeepCopy(void); 105 // Make a copy, with the parameters (usually referenced by hParam) 106 // resolved to pointers to the actual value. This speeds things up 107 // considerably. 108 Expr *DeepCopyWithParamsAsPointers(IdList<Param,hParam> *firstTry, 109 IdList<Param,hParam> *thenTry); 110 111 static Expr *From(const char *in, bool popUpError); 112 static void Lex(const char *in); 113 static Expr *Next(void); 114 static void Consume(void); 115 116 static void PushOperator(Expr *e); 117 static Expr *PopOperator(void); 118 static Expr *TopOperator(void); 119 static void PushOperand(Expr *e); 120 static Expr *PopOperand(void); 121 122 static void Reduce(void); 123 static void ReduceAndPush(Expr *e); 124 static int Precedence(Expr *e); 125 126 static int Precedence(int op); 127 static void Parse(void); 128 }; 129 130 class ExprVector { 131 public: 132 Expr *x, *y, *z; 133 134 static ExprVector From(Expr *x, Expr *y, Expr *z); 135 static ExprVector From(Vector vn); 136 static ExprVector From(hParam x, hParam y, hParam z); 137 static ExprVector From(double x, double y, double z); 138 139 ExprVector Plus(ExprVector b); 140 ExprVector Minus(ExprVector b); 141 Expr *Dot(ExprVector b); 142 ExprVector Cross(ExprVector b); 143 ExprVector ScaledBy(Expr *s); 144 ExprVector WithMagnitude(Expr *s); 145 Expr *Magnitude(void); 146 147 Vector Eval(void); 148 }; 149 150 class ExprQuaternion { 151 public: 152 Expr *w, *vx, *vy, *vz; 153 154 static ExprQuaternion From(Expr *w, Expr *vx, Expr *vy, Expr *vz); 155 static ExprQuaternion From(Quaternion qn); 156 static ExprQuaternion From(hParam w, hParam vx, hParam vy, hParam vz); 157 158 ExprVector RotationU(void); 159 ExprVector RotationV(void); 160 ExprVector RotationN(void); 161 162 ExprVector Rotate(ExprVector p); 163 ExprQuaternion Times(ExprQuaternion b); 164 165 Expr *Magnitude(void); 166 }; 167 168 #endif 169 170