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