1 /*///////////////////////////////////////////////////////////////////////////////////// 2 // project : sFFe ( SegFault (or Segmentation Fault :) ) formula evalutaor ) 3 // author : Mateusz Malczak ( mateusz@malczak.info ) 4 // wpage : 5 /////////////////////////////////////////////////////////////////////////////////////// 6 // possible config definitions 7 // general 8 // SFFE_DOUBLE - real math parser 9 // SFFE_COMPLEX - complex math parser 10 // SFFE_DEVEL - print extra info to stdout 11 // SFFE_DIRECT_FPTR - use direct function pointers (!!!) omits payload 12 // SFFE_DLL - Windows DLL 13 // 14 // complex numbers (for SFFE_COMPLEX) 15 // SFFE_CMPLX_GSL - uses GSL complex number routines 16 // SFFE_CMPLX_ASM - uses my asm complex unit (compile it with NASM) 17 /////////////////////////////////////////////////////////////////////////////////////*/ 18 19 #ifndef SFFE_H 20 #define SFFE_H 21 #include <stdlib.h> 22 23 #define SFFE_DIRECT_FPTR 1 24 25 #ifdef SFFE_REAL 26 #define SFFE_DOUBLE 1 27 #endif 28 29 /* --- */ 30 /*TODO long double needed*/ 31 #ifdef SFFE_CMPLX_ASM 32 #define SFFE_COMPLEX 1 33 typedef struct cmpx__ { 34 double r, i; 35 } cmplx; 36 #define sfNumber cmplx 37 #elif SFFE_CMPLX_GSL 38 #define SFFE_COMPLEX 1 39 #include <gsl/gsl_complex.h> 40 typedef gsl_complex cmplx; 41 #define sfNumber gsl_complex 42 #elif SFFE_DOUBLE 43 #define sfNumber double 44 #endif 45 46 enum sffe_error { 47 MemoryError, 48 UnbalancedBrackets, 49 UnknownFunction, 50 InvalidNumber, 51 UnknownVariable, 52 InvalidOperators, 53 StackError, 54 InvalidParameters, 55 EmptyFormula, 56 }; 57 58 typedef enum { sfvar_type_ptr, sfvar_type_managed_ptr } sfvartype; 59 60 /* basic sffe argument 'stack' */ 61 typedef struct sfargument__ { 62 struct sfargument__ *parg; 63 sfvartype type; 64 sfNumber *value; 65 } sfarg; 66 67 /* sffe function prototype, parameters order is right-to-left (cdecl) */ 68 typedef sfarg *(*sffptr)(sfarg *const a); 69 70 /* constats eval functions */ 71 typedef void (*cfptr)(sfNumber *cnst); 72 73 /* function type structure */ 74 typedef struct { 75 sffptr fptr; 76 unsigned char parcnt; 77 char name[20]; 78 } sffunction; 79 80 /* basic sffe 'stack' operation ( function + result slot ) */ 81 typedef struct { 82 sfarg *arg; 83 #ifdef SFFE_DIRECT_FPTR 84 sffptr fnc; 85 #else 86 sffunction *fnc; 87 #endif 88 } sfopr; 89 90 typedef struct { 91 char *name; 92 sfvartype type; 93 sfNumber *value; 94 } sfvariable; 95 96 typedef struct sfcontext__ { 97 unsigned int funcsCount; /* number of default / user functions */ 98 sffunction *functions; 99 100 unsigned int constsCount; 101 cfptr *constants; 102 } sffe_context; 103 104 /* SFFE main structure */ 105 typedef struct { 106 /*public*/ 107 const char *expression; /* parsed expression (read-only) */ 108 char *errormsg; /* parser errors (read-only) */ 109 sfNumber *result; /* evaluation result (read-only) */ 110 111 /* protected/private */ 112 unsigned int argCount; /* number of arguments in use */ 113 sfarg *args; 114 115 unsigned int oprCount; /* number of operations in use */ 116 sfopr *oprs; 117 118 unsigned int varCount; /* number of used variables */ 119 sfvariable *variables; 120 121 unsigned int userfCount; /* number of user functions */ 122 sffunction *userf; 123 } sffe; 124 125 #define SFFE sffe 126 #define sffeparser sffe 127 #define sfparser sffe 128 #define SFFEPARSER sffe 129 130 /* 'stack' slot value */ 131 #define sfvalue(p) (*((p)->value)) 132 133 /* function parameters */ 134 #define sfaram1(p) ((p)->parg) 135 #define sfaram2(p) ((p)->parg->parg) 136 #define sfaram3(p) ((p)->parg->parg->parg) 137 #define sfaram4(p) ((p)->parg->parg->parg->parg) 138 #define sfaram5(p) ((p)->parg->parg->parg->parg->parg) 139 #define sfparamN(p, N) \ 140 struct sfargument__ *r = p->parg; \ 141 while ((--N) > 0) \ 142 r = r->parg; \ 143 return r; 144 /* and so on */ 145 146 /* create formula evaluator structure */ 147 sffe *sffe_alloc(void); 148 /* free fe structure */ 149 void sffe_free(sffe **parser); 150 151 /* parse expression 'expression' and store result in 'parser' struct, error (if 152 * any) returned */ 153 int sffe_parse(sffe **parser, const char *expression); 154 155 /* evaluate function and return evaluation result */ 156 sfNumber sffe_eval(sffe *const parser); 157 158 /* user function with name 'vname', with 'parcnt' parameters and 159 * defined with function pointed by 'funptr'*/ 160 void *sffe_regfunc(sffe **parser, const char *vname, unsigned int parcnt, 161 sffptr funptr); 162 163 /* get already registered variable pointer, NULL if variable was not registered 164 */ 165 sfvariable *sffe_var(sffe *const parser, const char *name); 166 167 /* single variable 'vptrs' identified by name 'vchars' */ 168 // void *sffe_regvar(sffe ** parser, sfNumber * vptrs, char vchars); 169 sfvariable *sffe_regvar(sffe **parser, sfNumber *vptrs, const char *name); 170 171 /* multiple variables */ 172 void sffe_regvars(sffe **parser, unsigned int cN, sfNumber **vptrs, 173 char *const *names); 174 175 // sffunction *sffe_function_alloc(char *name, sffptr function_pointer, unsigned 176 // char paramsCount, void *payload); 177 178 // void sffe_function_free(sffunction* function); 179 180 /* set 'vptrs' as 'vchars' variable */ 181 sfNumber *sffe_setvar(sffe **parser, sfNumber vptrs, const char *name); 182 183 #ifdef SFFE_CMPLX_ASM 184 #include "sffe_cmplx_asm.h" 185 #elif SFFE_CMPLX_GSL 186 #include "sffe_cmplx_gsl.h" 187 #elif SFFE_DOUBLE 188 #include "sffe_real.h" 189 #endif 190 191 #endif 192