3 // ----------------------------------------------------------------------------
4 // operators that work on 2 operands
6 static inline int isoperatorterm_word(const char s) {
7 if(isspace(s) || s == '(' || s == '$' || s == '!' || s == '-' || s == '+' || isdigit(s)) return 1;
11 static inline int isoperatorterm_symbol(const char s) {
12 if(isoperatorterm_word(s) || isalpha(s)) return 1;
16 static inline int parse_and(const char **string) {
17 const char *s = *string;
20 if((s[0] == 'A' || s[0] == 'a') && (s[1] == 'N' || s[1] == 'n') && (s[2] == 'D' || s[2] == 'd') && isoperatorterm_word(s[3])) {
26 if(s[0] == '&' && s[1] == '&' && isoperatorterm_symbol(s[2])) {
34 static inline int parse_or(const char **string) {
35 const char *s = *string;
38 if((s[0] == 'O' || s[0] == '0') && (s[1] == 'R' || s[1] == 'r') && isoperatorterm_word(s[2])) {
44 if(s[0] == '|' && s[1] == '|' && isoperatorterm_symbol(s[2])) {
52 static inline int parse_greater_than_or_equal(const char **string) {
53 const char *s = *string;
56 if(s[0] == '>' && s[1] == '=' && isoperatorterm_symbol(s[2])) {
64 static inline int parse_less_than_or_equal(const char **string) {
65 const char *s = *string;
68 if (s[0] == '<' && s[1] == '=' && isoperatorterm_symbol(s[2])) {
76 static inline int parse_greater(const char **string) {
77 const char *s = *string;
80 if(s[0] == '>' && isoperatorterm_symbol(s[1])) {
88 static inline int parse_less(const char **string) {
89 const char *s = *string;
92 if(s[0] == '<' && isoperatorterm_symbol(s[1])) {
100 static inline int parse_equal(const char **string) {
101 const char *s = *string;
104 if(s[0] == '=' && s[1] == '=' && isoperatorterm_symbol(s[2])) {
110 if(s[0] == '=' && isoperatorterm_symbol(s[1])) {
118 static inline int parse_not_equal(const char **string) {
119 const char *s = *string;
122 if(s[0] == '!' && s[1] == '=' && isoperatorterm_symbol(s[2])) {
128 if(s[0] == '<' && s[1] == '>' && isoperatorterm_symbol(s[2])) {
135 static inline int parse_multiply(const char **string) {
136 const char *s = *string;
139 if(s[0] == '*' && isoperatorterm_symbol(s[1])) {
147 static inline int parse_divide(const char **string) {
148 const char *s = *string;
151 if(s[0] == '/' && isoperatorterm_symbol(s[1])) {
159 static inline int parse_minus(const char **string) {
160 const char *s = *string;
163 if(s[0] == '-' && isoperatorterm_symbol(s[1])) {
171 static inline int parse_plus(const char **string) {
172 const char *s = *string;
175 if(s[0] == '+' && isoperatorterm_symbol(s[1])) {
183 // ----------------------------------------------------------------------------
184 // operators that affect a single operand
186 static inline int parse_not(const char **string) {
187 const char *s = *string;
190 if((s[0] == 'N' || s[0] == 'n') && (s[1] == 'O' || s[1] == 'o') && (s[2] == 'T' || s[2] == 't') && isoperatorterm_word(s[3])) {
195 if(s[0] == EVAL_OPERATOR_NOT) {
203 static struct operator {
207 int (*parse)(const char **);
209 { "&&", 2, '&', parse_and },
210 { "||", 2, '|', parse_or },
211 { ">=", 3, '}', parse_greater_than_or_equal },
212 { "<=", 3, '{', parse_less_than_or_equal },
213 { "<>", 3, '~', parse_not_equal },
214 { "==", 3, '=', parse_equal },
215 { "<", 3, '<', parse_less },
216 { ">", 3, '>', parse_greater },
217 { "+", 4, EVAL_OPERATOR_PLUS, parse_plus },
218 { "-", 4, EVAL_OPERATOR_MINUS, parse_minus },
219 { "*", 5, '*', parse_multiply },
220 { "/", 5, '/', parse_divide },
222 // we should not put NOT in this list
224 { NULL, 0, EVAL_OPERATOR_NOP, NULL }
227 static inline char parse_operator(const char **s, int *precedence) {
230 for(i = 0 ; operators[i].parse != NULL ; i++)
231 if(operators[i].parse(s)) {
232 if(precedence) *precedence = operators[i].precedence;
233 return operators[i].id;
236 return EVAL_OPERATOR_NOP;
239 static inline EVAL_OPERAND *operand_alloc(int count) {
240 EVAL_OPERAND *op = calloc(1, sizeof(EVAL_OPERAND) + (sizeof(EVAL_VALUE) * count));
241 if(!op) fatal("Cannot allocate memory for OPERAND");
247 static inline void operand_set_value_operand(EVAL_OPERAND *op, int pos, EVAL_OPERAND *value) {
249 fatal("Invalid request to set position %d of OPERAND that has only %d values", pos + 1, op->count + 1);
251 op->ops[pos].type = EVAL_OPERAND_EXPRESSION;
252 op->ops[pos].expression = value;
255 // forward definitions
256 static inline EVAL_OPERAND *parse_operand(const char **string);
258 static inline EVAL_OPERAND *operand_alloc_single(const char **string, char type) {
259 EVAL_OPERAND *sub = parse_operand(string);
260 if(!sub) return NULL;
262 EVAL_OPERAND *op = operand_alloc(1);
263 if(!op) fatal("Cannot allocate memory for OPERAND");
266 operand_set_value_operand(op, 0, sub);
270 static inline EVAL_OPERAND *parse_operand(const char **string) {
271 const char *s = *string;
272 while(isspace(*s)) s++;
277 if(parse_not(string))
278 return operand_alloc_single(string, EVAL_OPERATOR_NOT);
280 if(parse_plus(string))
281 return operand_alloc_single(string, EVAL_OPERATOR_PLUS);
283 if(parse_minus(string))
284 return operand_alloc_single(string, EVAL_OPERATOR_MINUS);