2008-04-08 12:54:53 +00:00
|
|
|
|
|
|
|
#ifndef __EXPR_H
|
|
|
|
#define __EXPR_H
|
|
|
|
|
|
|
|
class Expr;
|
|
|
|
|
|
|
|
class Expr {
|
|
|
|
public:
|
|
|
|
// A parameter, by the hParam handle
|
|
|
|
static const int PARAM = 0;
|
|
|
|
// A parameter, by a pointer straight in to the param table (faster,
|
|
|
|
// if we know that the param table won't move around)
|
|
|
|
static const int PARAM_PTR = 1;
|
|
|
|
|
2008-04-12 14:12:26 +00:00
|
|
|
// These are used only for user-entered expressions.
|
|
|
|
static const int POINT = 10;
|
|
|
|
static const int ENTITY = 11;
|
|
|
|
|
|
|
|
static const int CONSTANT = 20;
|
|
|
|
|
|
|
|
static const int PLUS = 100;
|
|
|
|
static const int MINUS = 101;
|
|
|
|
static const int TIMES = 102;
|
|
|
|
static const int DIV = 103;
|
|
|
|
static const int NEGATE = 104;
|
|
|
|
static const int SQRT = 105;
|
|
|
|
static const int SQUARE = 106;
|
|
|
|
static const int SIN = 107;
|
|
|
|
static const int COS = 108;
|
2008-04-08 12:54:53 +00:00
|
|
|
|
2008-04-17 06:42:32 +00:00
|
|
|
// Special helpers for when we're parsing an expression from text.
|
|
|
|
// Initially, literals (like a constant number) appear in the same
|
|
|
|
// format as they will in the finished expression, but the operators
|
|
|
|
// are different until the parser fixes things up (and builds the
|
|
|
|
// tree from the flat list that the lexer outputs).
|
|
|
|
static const int ALL_RESOLVED = 1000;
|
|
|
|
static const int PAREN = 1001;
|
|
|
|
static const int BINARY_OP = 1002;
|
|
|
|
static const int UNARY_OP = 1003;
|
|
|
|
|
2008-04-08 12:54:53 +00:00
|
|
|
int op;
|
|
|
|
Expr *a;
|
|
|
|
Expr *b;
|
|
|
|
union {
|
2008-04-13 14:28:35 +00:00
|
|
|
double v;
|
2008-04-08 12:54:53 +00:00
|
|
|
hParam parh;
|
2008-04-13 14:28:35 +00:00
|
|
|
Param *parp;
|
2008-04-12 14:12:26 +00:00
|
|
|
hEntity entity;
|
2008-04-17 06:42:32 +00:00
|
|
|
|
|
|
|
// For use while parsing
|
|
|
|
char c;
|
2008-04-08 12:54:53 +00:00
|
|
|
} x;
|
2008-04-13 14:28:35 +00:00
|
|
|
|
|
|
|
static Expr *FromParam(hParam p);
|
|
|
|
static Expr *FromConstant(double v);
|
|
|
|
|
|
|
|
Expr *AnyOp(int op, Expr *b);
|
|
|
|
inline Expr *Plus (Expr *b) { return AnyOp(PLUS, b); }
|
|
|
|
inline Expr *Minus(Expr *b) { return AnyOp(MINUS, b); }
|
|
|
|
inline Expr *Times(Expr *b) { return AnyOp(TIMES, b); }
|
|
|
|
inline Expr *Div (Expr *b) { return AnyOp(DIV, b); }
|
|
|
|
|
|
|
|
inline Expr *Negate(void) { return AnyOp(NEGATE, NULL); }
|
|
|
|
inline Expr *Sqrt (void) { return AnyOp(SQRT, NULL); }
|
|
|
|
inline Expr *Square(void) { return AnyOp(SQUARE, NULL); }
|
|
|
|
inline Expr *Sin (void) { return AnyOp(SIN, NULL); }
|
|
|
|
inline Expr *Cos (void) { return AnyOp(COS, NULL); }
|
|
|
|
|
|
|
|
Expr *PartialWrt(hParam p);
|
|
|
|
double Eval(void);
|
|
|
|
|
|
|
|
void ParamsToPointers(void);
|
2008-04-14 10:28:32 +00:00
|
|
|
|
|
|
|
void App(char *str, ...);
|
|
|
|
char *Print(void);
|
|
|
|
void PrintW(void); // worker
|
2008-04-17 06:42:32 +00:00
|
|
|
|
|
|
|
// Make a copy of an expression that won't get blown away when we
|
|
|
|
// do a FreeAllExprs()
|
2008-04-18 07:06:37 +00:00
|
|
|
Expr *DeepCopyKeep(void);
|
|
|
|
// or a copy that will
|
|
|
|
Expr *DeepCopy(void);
|
|
|
|
// number of child nodes: 0 (e.g. constant), 1 (sqrt), or 2 (+)
|
|
|
|
int Children(void);
|
2008-04-17 06:42:32 +00:00
|
|
|
|
|
|
|
static Expr *FromString(char *in);
|
|
|
|
static void Lex(char *in);
|
|
|
|
static Expr *Next(void);
|
|
|
|
static void Consume(void);
|
|
|
|
|
|
|
|
static void PushOperator(Expr *e);
|
|
|
|
static Expr *PopOperator(void);
|
|
|
|
static Expr *TopOperator(void);
|
|
|
|
static void PushOperand(Expr *e);
|
|
|
|
static Expr *PopOperand(void);
|
|
|
|
|
|
|
|
static void Reduce(void);
|
|
|
|
static void ReduceAndPush(Expr *e);
|
|
|
|
static int Precedence(Expr *e);
|
|
|
|
|
|
|
|
static int Precedence(int op);
|
|
|
|
static void Parse(void);
|
2008-04-08 12:54:53 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
#endif
|