// SPDX-License-Identifier: GPL-3.0+
#include "common.h"
// ----------------------------------------------------------------------------
// data structures for storing the parsed expression in memory
typedef struct eval_value {
int type;
union {
calculated_number number;
EVAL_VARIABLE *variable;
struct eval_node *expression;
};
} EVAL_VALUE;
typedef struct eval_node {
int id;
unsigned char operator;
int precedence;
int count;
EVAL_VALUE ops[];
} EVAL_NODE;
// these are used for EVAL_NODE.operator
// they are used as internal IDs to identify an operator
// THEY ARE NOT USED FOR PARSING OPERATORS LIKE THAT
#define EVAL_OPERATOR_NOP '\0'
#define EVAL_OPERATOR_EXPRESSION_OPEN '('
#define EVAL_OPERATOR_EXPRESSION_CLOSE ')'
#define EVAL_OPERATOR_NOT '!'
#define EVAL_OPERATOR_PLUS '+'
#define EVAL_OPERATOR_MINUS '-'
#define EVAL_OPERATOR_AND '&'
#define EVAL_OPERATOR_OR '|'
#define EVAL_OPERATOR_GREATER_THAN_OR_EQUAL 'G'
#define EVAL_OPERATOR_LESS_THAN_OR_EQUAL 'L'
#define EVAL_OPERATOR_NOT_EQUAL '~'
#define EVAL_OPERATOR_EQUAL '='
#define EVAL_OPERATOR_LESS '<'
#define EVAL_OPERATOR_GREATER '>'
#define EVAL_OPERATOR_MULTIPLY '*'
#define EVAL_OPERATOR_DIVIDE '/'
#define EVAL_OPERATOR_SIGN_PLUS 'P'
#define EVAL_OPERATOR_SIGN_MINUS 'M'
#define EVAL_OPERATOR_ABS 'A'
#define EVAL_OPERATOR_IF_THEN_ELSE '?'
// ----------------------------------------------------------------------------
// forward function definitions
static inline void eval_node_free(EVAL_NODE *op);
static inline EVAL_NODE *parse_full_expression(const char **string, int *error);
static inline EVAL_NODE *parse_one_full_operand(const char **string, int *error);
static inline calculated_number eval_node(EVAL_EXPRESSION *exp, EVAL_NODE *op, int *error);
static inline void print_parsed_as_node(BUFFER *out, EVAL_NODE *op, int *error);
static inline void print_parsed_as_constant(BUFFER *out, calculated_number n);
// ----------------------------------------------------------------------------
// evaluation of expressions
static inline calculated_number eval_variable(EVAL_EXPRESSION *exp, EVAL_VARIABLE *v, int *error) {
static uint32_t this_hash = 0, now_hash = 0, after_hash = 0, before_hash = 0, status_hash = 0, removed_hash = 0, uninitialized_hash = 0, undefined_hash = 0, clear_hash = 0, warning_hash = 0, critical_hash = 0;
calculated_number n;
if(unlikely(this_hash == 0)) {
this_hash = simple_hash("this");
now_hash = simple_hash("now");
after_hash = simple_hash("after");
before_hash = simple_hash("before");
status_hash = simple_hash("status");
removed_hash = simple_hash("REMOVED");
uninitialized_hash = simple_hash("UNINITIALIZED");
undefined_hash