/*********************************************************************** * * * A F U N C T I O N E V A L U A T O R * * * * Placed in the Public Domain by David Gay, 1988 * * * ***********************************************************************/ /* Includes to allow the use of lists */ #include #include #include typedef struct _value *value; /* An expression */ typedef struct List var_list; /* A list of variables */ typedef struct { /* A variable */ char *name; /* It's name */ struct var *adr; /* Cache */ long key; /* Cache valid ? */ } variable; typedef struct List context; /* A context */ extern int eval_error; /* Last error */ /* The possible errors */ #define SYNTAX 1 /* Syntax error */ #define OUT_OF_MEM 2 /* Not enough memory */ #define UNMATCHED 3 /* Right bracket expected */ #define WANT_LEFT 5 /* Left bracket expected */ #define NOT_DIFFERENTIABLE 6 /* Function not differentiable */ #define RECURSIVE 7 /* Recursion not allowed ... */ #define NOTNUM 8 /* A numeric expression was expected */ /* The flags for eval */ #define PAT 0x0001 /* Do pattern based simplification */ #define NICE 0x0002 /* Only do arithmetic if result integer */ #define VAR 0x0004 /* Substitute values of variables */ #define REC 0x0008 /* Idem, but evaluate them */ #define NORED 0x0010 /* No constant folding */ /* The various routines */ int init_expr(void); /* Must be called first */ void cleanup_expr(void); /* Once you've finished */ value compile(char *); /* "Compile" an expression */ char *decompile(value, char *, int); /* Reconstruct string from expression */ void free_expr(value); /* Free memory used by expression */ value eval(value, int); /* Evaluate */ double quick_eval(value); /* Evaluate quickly, get a numeric result */ value differentiate(value, char *); int create_var(variable *); void free_var(variable *); int set_var(variable *, value); value get_var(variable *); int create_var_name(char *); void free_var_name(char *); value get_var_name(char *); /* by name, not through structure */ int set_var_name(char *, value); int create_quick(variable *); /* Create a numeric variable */ void free_quick(variable *); void set_quick(variable *, double); double get_quick(variable *); var_list *make_var_list(value, var_list *); /* make a list of vars used in expr */ void free_var_list(var_list *); int create_vars(var_list *); /* Create the vars in a list */ void free_vars(var_list *); void set_context(context *); /* Set the new context */ #define init_context(cont) NEWLIST(cont) /* Initialise a context */ #define init_var_list(list) NEWLIST(list) #define NEWLIST(list) \ { (list)->lh_Head = (struct Node *)&(list)->lh_Tail; \ (list)->lh_TailPred = (struct Node *)&(list)->lh_Head; \ (list)->lh_Tail = 0; \ }