00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #ifndef __LIBEXPR_H__
00021 #define __LIBEXPR_H__
00022
00023 #include "EXPR_API.h"
00024 #include "EX_Error.h"
00025 #include "EXPR_Lock.h"
00026 #include <UT/UT_SmallObject.h>
00027 #include <UT/UT_String.h>
00028
00029 class ev_Vector;
00030 class ev_Matrix;
00031 class EX_ExprFunc;
00032 class UT_IStream;
00033 class UT_SymbolTable;
00034
00035 #define EV_OPTIMIZE0 0
00036 #define EV_OPTIMIZE1 1
00037
00038 #define MAX_RECURSION 20
00039
00040 #define EV_NHELPARGS 10
00041
00042 typedef char *(*ev_Expander)(const char *str, int thread);
00043
00044
00045
00046 #define OP_PLUS 1
00047 #define OP_MINUS 2
00048 #define OP_TIMES 3
00049 #define OP_DIVIDE 4
00050 #define OP_POWER 5
00051 #define OP_MOD 6
00052 #define OP_NOT 7
00053 #define OP_EQ 8
00054 #define OP_NE 9
00055 #define OP_LT 10
00056 #define OP_LE 11
00057 #define OP_GT 12
00058 #define OP_GE 13
00059 #define OP_LOGAND 14
00060 #define OP_LOGOR 15
00061 #define OP_COMMA 16
00062 #define OP_QUESTION 20
00063 #define OP_COLON 21
00064 #define OP_AND 22
00065 #define OP_OR 23
00066 #define OP_DOT 24
00067 #define OP_TILDE 25
00068 #define OP_AT 26
00069 #define OP_SBRACKET 30
00070 #define OP_BRACE 31
00071 #define OP_EQUATE 32
00072 #define MAX_OPERATOR_TOKEN 32
00073
00074
00075
00076
00077
00078
00079
00080 #define EV_SYMTRANSIENT 0x04000000
00081 #define EV_SYMCONSTANT 0x08000000
00082 #define EV_FLAGS_SET 0x10000000
00083 #define EV_SYMEXPAND 0x20000000
00084 #define EV_EXFUNC_REF 0x40000000
00085 #define EV_FOR_EXFUNC 0x80000000
00086
00087 #define EX_USERFLAGMASK (0x03ffffff | EV_EXFUNC_REF)
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098 #define EV_TYPEFLOAT 0 // Float type of symbol
00099 #define EV_TYPESTRING 1 // String type of symbol
00100 #define EV_TYPEUNIXVAR 2 // Unix variable type
00101 #define EV_TYPEEXPANDVAR 4 // Variable of form ${foo$x}
00102 #define EV_TYPEVECTOR 5 // Vector
00103 #define EV_TYPEMATRIX 6 // Matrix
00104
00105
00106
00107 #define EV_TYPE_LOCAL_VAR 10 // A node local variable
00108 #define EV_TYPE_UNRESOLVED_VAR 11 // An unknown variable
00109 #define EV_TYPE_DEFINE 12
00110 #define EV_TYPE_GLOBAL_VAR 20 // A global variable
00111 #define EV_TYPE_CPPSYMBOL 45 // A symbol inside a function
00112 #define EV_TYPE_UNRESOLVED_CPPSYMBOL 46 // An unknown function symbol
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123 class EV_FUNCTION;
00124 class EV_SYMBOL;
00125 typedef struct EV_TYPEDEF EV_TYPEDEF;
00126 typedef struct EV_OPERATOR EV_OPERATOR;
00127 typedef struct EV_FUNCHELP EV_FUNCHELP;
00128
00129
00130
00131
00132 typedef void (*EXPRopDependencyCallback)(EV_FUNCTION *me,
00133 EV_SYMBOL **args,
00134 void *ref_id);
00135 typedef void (*EXPRopChangeRefCallback)(EV_FUNCTION *me,
00136 EV_SYMBOL **args,
00137 char *new_args[],
00138 const char *new_fullpath,
00139 const char *old_fullpath,
00140 const char *old_cwd,
00141 const char *chan_name,
00142 const char *old_chan_name);
00143
00144 typedef union {
00145 float fval;
00146 char *sval;
00147 void *data;
00148 } EV_TOKENVALUE;
00149
00150 class EXPR_API EV_SYMBOL {
00151 public:
00152 bool isForExprFunc() const
00153 { return ((flag & EV_FOR_EXFUNC) != 0); }
00154 void setForExprFunc()
00155 { flag |= EV_FOR_EXFUNC; }
00156 bool isConstant() const
00157 { return ((flag & EV_SYMCONSTANT) != 0); }
00158
00159 unsigned flag;
00160 EV_TYPEDEF *type;
00161 EV_TOKENVALUE value;
00162 EV_SYMBOL *next;
00163 int pos;
00164 };
00165
00166 struct EV_TYPEDEF {
00167 int type;
00168 const char *name;
00169 void (*allocValue)(EV_SYMBOL *);
00170 void (*freeValue)(EV_SYMBOL *);
00171 EV_SYMBOL *(*resolveSymbol)(const char *, int thread);
00172 const char *(*getName)(EV_SYMBOL *);
00173 int (*castValue)(EV_SYMBOL *to, EV_SYMBOL *me, int thread);
00174 int (*castFrom)(EV_SYMBOL *me, EV_SYMBOL *from);
00175 void (*copyValue)(EV_SYMBOL *dest, EV_SYMBOL *src, int thread);
00176 int (*getCastType)(EV_SYMBOL *src);
00177 void (*opDepend)(EV_SYMBOL *src, void *ref_id);
00178
00179 EV_TYPEDEF *next;
00180 EV_TYPEDEF *varnext;
00181 };
00182
00183 struct EV_OPERATOR {
00184 int flag;
00185 int token;
00186 unsigned char binary;
00187 int leftType;
00188 int rightType;
00189 int resultType;
00190
00191 void (*evaluate)(EV_SYMBOL *, EV_SYMBOL *, EV_SYMBOL *);
00192
00193 EV_OPERATOR *next;
00194 };
00195
00196 class EXPR_API EV_FUNCTION {
00197 public:
00198 EV_FUNCTION(unsigned flag = 0,
00199 const char *name = 0,
00200 int num_args = 0,
00201 int result_type = EV_TYPEFLOAT,
00202 const int *argTypes = 0,
00203 void (*callback)(EV_FUNCTION *me,
00204 EV_SYMBOL *result,
00205 EV_SYMBOL **args,
00206 int thread) = 0,
00207 EXPRopDependencyCallback dependCB = 0,
00208 EXPRopChangeRefCallback changeOpRefCB = 0,
00209 int is_safe = 1,
00210 bool is_threadsafe = false);
00211 virtual ~EV_FUNCTION();
00212
00213
00214
00215 unsigned getUserFlags() const { return myFlags; }
00216 const char *getName() const { return myName; }
00217 int getNArgs() const { return myNArgs; }
00218 int getResultType() const { return myResultType; }
00219 const int *getArgTypes() const { return myArgTypes; }
00220 int getArgType(int i) const { return myArgTypes[i]; }
00221 const char *getDSOLocation() const { return myDSOLocation; }
00222
00223
00224
00225 void *getInstanceData(int thread);
00226 static void setInstanceAllocator(const char *function,
00227 void *(*alloc)(), void (*freer)(void *));
00228 void setInstanceAllocator(void *(*alloc)(), void (*freer)(void *))
00229 {
00230 myAllocator = alloc;
00231 myFreer = freer;
00232 }
00233 void *allocInstanceData() { return myAllocator ? myAllocator() : 0; }
00234 void freeInstanceData(void *d) { myFreer(d); }
00235
00236 void setOpDependencyCallback(EXPRopDependencyCallback cb)
00237 {
00238 myDependCallback = cb;
00239 }
00240 void setChangeOpRefCallback(EXPRopChangeRefCallback cb)
00241 {
00242 myChangeOpRefCallback = cb;
00243 }
00244
00245
00246
00247 int isSafe() const { return myIsSafe; }
00248
00249 bool isThreadSafe() const
00250 {
00251 return myIsThreadSafe;
00252 }
00253
00254 public:
00255 void (*myCallback)(EV_FUNCTION *me, EV_SYMBOL *result,
00256 EV_SYMBOL **args, int thread);
00257 EXPRopDependencyCallback myDependCallback;
00258 EXPRopChangeRefCallback myChangeOpRefCallback;
00259
00260 unsigned myFlags;
00261
00262 private:
00263 const char *myName;
00264 char *myDSOLocation;
00265 int myNArgs;
00266 int myResultType;
00267 const int *myArgTypes;
00268 void *(*myAllocator)();
00269 void (*myFreer)(void *);
00270 unsigned myIsSafe:1,
00271 myIsThreadSafe:1;
00272 };
00273
00274
00275
00276
00277
00278
00279 enum EV_InlineFuncReturnType
00280 {
00281 EV_EXPR_RETURN_NONE,
00282 EV_EXPR_RETURN_FLOAT,
00283 EV_EXPR_RETURN_STRING,
00284 EV_EXPR_RETURN_VECTOR,
00285 EV_EXPR_RETURN_MATRIX
00286 };
00287
00288
00289
00290
00291 struct EV_ChangeOpReferenceParms
00292 {
00293 const char *new_fullpath;
00294 const char *old_fullpath;
00295 const char *old_cwd;
00296 const char *chan_name;
00297 const char *old_chan_name;
00298 };
00299
00300
00301 class EXPR_API EV_EXPRESSION
00302 : public UT_SmallObject<EV_EXPRESSION,
00303 UT_SMALLOBJECT_CLEANPAGES_DEFAULT,
00304 UT_SMALLOBJECT_PAGESIZE_DEFAULT,
00305 UT_SMALLOBJECT_THREADSAFE_ON>
00306 {
00307 public:
00308 EV_EXPRESSION(EV_InlineFuncReturnType ret_type)
00309 {
00310 myFlags = 0;
00311 mySource = 0;
00312 myCompiled = 0;
00313 myRecurs = 0;
00314 myFunc = 0;
00315 myFuncRetType = ret_type;
00316 myInExprFunc = false;
00317 }
00318 ~EV_EXPRESSION()
00319 {
00320 freeExprSpace();
00321 }
00322
00323
00324
00325
00326
00327
00328 bool evaluate(int thread, float &result);
00329 bool evaluate(int thread, UT_String &result);
00330 bool evaluate(int thread, ev_Vector &result);
00331 bool evaluate(int thread, ev_Matrix &result);
00332
00333
00334
00335
00336 EV_SYMBOL * evaluate(int thread)
00337 { return evaluate(myFuncRetType, thread); }
00338 EV_SYMBOL * evaluate(EV_InlineFuncReturnType func_ret_type, int thread);
00339
00340
00341 bool changeExpr(const char *source);
00342 void unresolveVars(int thread);
00343 void dirtyExpr();
00344
00345
00346
00347 void updateOpDependency(void *ref_id, int thread);
00348 int changeOpReference(const char *new_fullpath,
00349 const char *old_fullpath,
00350 const char *old_cwd,
00351 const char *chan_name,
00352 const char *old_chan_name,
00353 int thread);
00354
00355
00356
00357
00358 bool saveCompiledCode(ostream &os, int thread);
00359 bool loadCompiledCode(UT_IStream &is, int thread);
00360
00361
00362
00363
00364 unsigned int getFlags() const
00365 { return myFlags; }
00366 bool hasFlag(unsigned int bit) const
00367 { return ((myFlags & bit) != 0); }
00368 void clearAllFlags()
00369 { myFlags = 0; }
00370 void setFlags(unsigned int flags)
00371 { myFlags = flags; }
00372 void appendFlags(unsigned int flag)
00373 { myFlags |= flag; }
00374 void setEvaluated()
00375 { myFlags |= EV_FLAGS_SET; }
00376 bool isEvaluated() const
00377 { return ((myFlags & EV_FLAGS_SET) != 0); }
00378
00379
00380
00381 void clearFlagsBeforeEvaluation()
00382 { myFlags &= ~(EX_USERFLAGMASK | EV_FLAGS_SET); }
00383
00384
00385
00386
00387 const char * getSource() const
00388 { return mySource; }
00389 bool isCompiled() const
00390 { return (myCompiled != 0); }
00391
00392
00393
00394
00395 void * getSingleFunctionInstanceData(
00396 EV_FUNCTION *func, int thread, UT_String &argument);
00397
00398
00399
00400 bool isInExprFunc() const
00401 { return myInExprFunc; }
00402 void setInExprFunc(bool is_inside)
00403 { myInExprFunc = is_inside; }
00404
00405
00406
00407 EXPR_Lock & getLock() const
00408 { return myLock; }
00409
00410 private:
00411 void freeCompiledExpr(EV_SYMBOL *&free_list);
00412 bool parseInlineFunc(UT_String &func_call, int thread);
00413 int compile(const char *tstring, int thread,
00414 bool ignore_bad_vars);
00415 int parseExpr(EV_InlineFuncReturnType func_ret_type,
00416 int thread, bool ignore_bad_vars);
00417 bool freeExprSpace();
00418 void doUpdateOpDependency(void *ref_id, int thread);
00419 int doChangeOpReference(UT_String &new_source,
00420 EV_ChangeOpReferenceParms &parms,
00421 int thread);
00422
00423 private:
00424 unsigned myFlags;
00425 char *mySource;
00426 void *myCompiled;
00427 int myRecurs;
00428 EX_ExprFunc *myFunc;
00429 EV_InlineFuncReturnType myFuncRetType;
00430 mutable EXPR_Lock myLock;
00431 bool myInExprFunc:1;
00432 };
00433
00434
00435
00436
00437
00438 EXPR_API extern void ev_InitFloat(void);
00439 EXPR_API extern void ev_InitString(void);
00440 EXPR_API extern void ev_InitVariable(void);
00441 EXPR_API extern void ev_InitVector(void);
00442 EXPR_API extern void ev_InitMatrix(void);
00443 EXPR_API extern void ev_InitUserFunc(void);
00444
00445
00446
00447 EXPR_API extern void ev_AddType(EV_TYPEDEF *type);
00448 EXPR_API extern void ev_AddVariableType(EV_TYPEDEF *type, int atEnd);
00449 EXPR_API extern void ev_DeleteVariableType(EV_TYPEDEF *type);
00450 EXPR_API extern void ev_AddOperator(EV_OPERATOR *op, int level);
00451 EXPR_API extern void ev_AddFunction(EV_FUNCTION *func);
00452 EXPR_API extern void ev_DeleteFunction(EV_FUNCTION *func);
00453 EXPR_API extern void ev_SetOptimization(int level);
00454
00455 #ifdef __cplusplus
00456 #include <iostream.h>
00457 EXPR_API extern void ev_PrintHelp(ostream &os, const char *match,
00458 const char *keyword);
00459 #endif
00460
00461 EXPR_API extern int ev_GetNFunctions();
00462 EXPR_API extern EV_FUNCTION *ev_GetFunction(int i);
00463 EXPR_API extern EV_TYPEDEF *ev_GetTypeDef(int key);
00464 EXPR_API extern int ev_FindFunction(const char *name);
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474 EXPR_API extern void ev_SetFunctionInstanceAllocator(
00475 const char *function,
00476 void *(*alloc)(),
00477 void (*free)(void *));
00478
00479
00480
00481
00482 EXPR_API extern void *ev_GetFunctionData(int thread);
00483
00484
00485
00486 EXPR_API extern void ev_SetFunctionDependencyCallbacks(
00487 const char *func,
00488 EXPRopDependencyCallback depend_cb,
00489 EXPRopChangeRefCallback changeref_cb);
00490
00491
00492 EXPR_API extern EV_EXPRESSION *ev_AllocExpr(EV_InlineFuncReturnType rettype);
00493 EXPR_API extern int ev_ChangeExpr(EV_EXPRESSION *expr,
00494 const char *source);
00495 EXPR_API extern void ev_UnresolveVars(EV_EXPRESSION *expr,
00496 int thread);
00497 EXPR_API extern float ev_EvaluateFloat(EV_EXPRESSION *expr,
00498 int thread);
00499 EXPR_API extern void ev_EvaluateString(UT_String &result,
00500 EV_EXPRESSION *expr,
00501 int thread);
00502 EXPR_API extern int ev_EvaluateVector(EV_EXPRESSION *expr,
00503 ev_Vector &result,
00504 int thread);
00505 EXPR_API extern int ev_EvaluateMatrix(EV_EXPRESSION *expr,
00506 ev_Matrix &result,
00507 int thread);
00508 EXPR_API extern void ev_FreeExpr(EV_EXPRESSION *expr);
00509
00510 EXPR_API extern void ev_UpdateOpDependency(EV_EXPRESSION *expr,
00511 void *ref_id, int thread);
00512 EXPR_API extern int ev_ChangeOpReference(EV_EXPRESSION *expr,
00513 const char *new_fullpath,
00514 const char *old_fullpath,
00515 const char *old_cwd,
00516 const char *chan_name,
00517 const char *old_chan_name,
00518 int thread);
00519 EXPR_API extern EV_SYMBOL *ev_Evaluate(
00520 EV_EXPRESSION *expr,
00521 EV_InlineFuncReturnType func_ret_type,
00522 int thread);
00523
00524
00525 EXPR_API extern bool ev_SaveCompiledCode(EV_EXPRESSION *expr,
00526 ostream &os, int thread);
00527 EXPR_API extern bool ev_LoadCompiledCode(EV_EXPRESSION *expr,
00528 UT_IStream &is, int thread);
00529
00530
00531 EXPR_API extern EV_SYMBOL *ev_AllocSymbol(int type, int thread);
00532 EXPR_API extern void ev_FreeSymbol(EV_SYMBOL *symbol, int thread);
00533
00534
00535 typedef struct EV_SYMTABLE EV_SYMTABLE;
00536
00537 struct EV_SYMTABLE {
00538 int flag;
00539 char *name;
00540 float *value;
00541 EV_SYMBOL *sym;
00542 EV_SYMTABLE *next;
00543 };
00544
00545 struct EV_FUNCHELP {
00546 char *name;
00547 char *argname[EV_NHELPARGS];
00548 char *description;
00549 };
00550
00551 EXPR_API extern void ev_SetExpander(ev_Expander expander);
00552
00553
00554
00555 EXPR_API extern void ev_setSafeMode(bool safe_mode);
00556 EXPR_API extern bool ev_isInSafeMode();
00557 EXPR_API extern bool ev_isKeyword(const char *string);
00558
00559 #endif
00560