diff --git a/src/mod/applications/mod_expr/expreval.html b/src/mod/applications/mod_expr/expreval.html index f66d327c2d..d6cade26c2 100644 --- a/src/mod/applications/mod_expr/expreval.html +++ b/src/mod/applications/mod_expr/expreval.html @@ -1,1334 +1,1334 @@ - -
---ExprEval Help document. This document is probably full of - bugs and mispellings. I may get around to proofreading - it later.
-ExprEval is a C based expression evaluation library. - It is entirely C based, but can be used in C++ programs - as well.. The source code is provided for the library - so that it can be recompiled for the specific system - or compiler.
-ExprEval makes adding mathematical expression support to - an application easy. It takes an expression string and - parses it, and then it can evaluate it over and over. - This library also has support for functions, constants, - and variables. All of these items are stored in - seperate lists so they can be shared among expressions or - they can be private to a single expression or any mix and - match. It is up to the developer how to link them together. - You can also create your own custom functions.
-
--This library is licensed under the - ExprEval License. -
-
--Expressions have pretty much the same syntax as they - would have on paper, with the following exceptions: -
-
- -- Each expression must end with a semicolon. This - is because the expression string can actually - contain multiple expressions. The semicolon is - used to mark the end of the expression.
-
- Examples: --
-- 4*x+5;
-- y=5+2;g=4+6;
-- y=r*sin(a);x=r*cos(a);
-- The asterisk '*' must be used to multiply.
-
- Examples: --
-- y=5*6; Valid
-- g=(x+1)*(x-1); Valid
-- g=(x+1)(x-1); Invalid
-More than one expression may be contained within an expression string. - As shown above, each expression must end with a semicolon, even if - only one expression is in the string. The value of an expression - string is the value of the last expression in the string.
- Examlples: --
- -- g=7; Value: 7
-- k=z+1; Value: z+1
-- r=4;k=6;o=9+r-k; Value: 9+r-k
-Some functions may take reference parameters. These parameters are - references to other variables. You can mix reference parameters - with normal parameters. The order of the normal parameters must - remain the same and the order of the reference parameters must - remain the same.
- Examples: --
- -- min(1,2,3,4,&mval); &mval is a reference to a variable mval
-- min(1,2,&mval,3,4); You may mix them inside like this.
-- min(1,2,(&mval),3,4); You may not nest reference parameters in any way
-Expressions may also be nested with parenthesis.
- Examples: --
- -- y=sin(x-cos(5+max(4,5,6*x)));
-- 6+(5-2*(x+y));
-Expressions may also have whitespace characters and comments. - Whitespace characters such as newlines, linefeeds, carriage - returns, spaces, and tabs are ignored. Comments begin with - the pound sign '#' and end at the end of the line.
- Example: --
-#Set the x value -x = d * cos(r); - -#Set the y value -y = d * sin(r); -- - -If a variable is used in an expression, but that variable does not exist, - it is considered zero. If it does exist then its value is used instead. -
-
--Using ExprEval in an application can be a little difficult. - You generally follow these steps: -
-
- You can manipulate the lists in any order after their creation. - However, functions are translated during the parse, so after - parsing an expression, manipulating the function list will make - no change to an expression. Variables and constants can be - manipulated after a parse to change the result of an expression. - However, you must add any constants to be used by an expression - to the constant list BEFORE parsing the expression, - otherwise it will be seen as a variable. Applications can change - both variables and constants, however the expression can only - change variables. Expressions may NOT assign to a constant - and expressions may NOT use constants as a reference parameter. -- Create function, variable, and constant lists
-- Create the expression object
-- Parse the expression
-- Evaluate the expression as needed
-- Free the expression object
-- Free the function, variable, and constant lists
-Function, variable, and constant list example: -
-
-exprFuncList *flist; -exprValList *vlist; -exprValList *clist; -exprObj *obj; -EXPRTYPE result; -int err; - -/* Create function list */ -err = exprFuncListCreate(&flist); -if(err != EXPR_ERROR_NOERROR) - { - ... - } - -/* Initialize internal functions */ -err = exprFuncListInit(flist); -if(err != EXPR_ERROR_NOERROR) - { - ... - } - -/* Create variable list */ -err = exprValListCreate(&vlist); -if(err != EXPR_ERROR_NOERROR) - { - ... - } - -/* Create the constant list */ -err = exprValListCreate(&clist); -if(err != EXPR_ERROR_NOERROR) - { - ... - } - -/* Initialize internal constants */ -err = exprValListInit(clist); -if(err != EXPR_ERROR_NOERROR) - { - ... - } - -/* Add any application defined functions, constants, or variables to the lists here or down below */ -- - -Expression object example: -
-
-err = exprCreate(&obj, flist, vlist, clist, NULL, 0); -if(err != EXPR_ERROR_NOERROR) - { - ... - } - -/* Add any application defined functions, constants, or variables to the lists here or down below. - This is the last time you can for the functions or constants. */ -- - -Expression parse example: -
-
-/* Functions and constants may be added or changed here */ - -err = exprParse(obj, "2+sin(M_PI)+3*x;"); -if(err != EXPR_ERROR_NOERROR) - { - ... - } - -/* Changes to the function or constant lists do not change the expression now */ -- - -Expression evaluation example: -
-
-/* Add or change any variables */ - -err = exprEval(obj, &result); -if(err != EXPR_ERROR_NOERRO) - { - ... - } -else - { - printf("Expression Result: %f\n", result); - } -- - -Free the expression object and lists example: -
-
-exprFree(obj); -exprValListFree(vlist); -exprValListFree(clist); -exprFuncListFree(flist); -- - -
--A new feature in ExprEval is fast variable access. This - is simply a technique of quickly accessing variables - by directly accessing their memory locations instead - of using the value list functions. Fast variable access - is always used internally in ExprEval. You must - NOT clear a variable list until after all expressions - using it are completely finished evaluating. Then you - must reparse the expressions before using them again. - The reason is simple. When fast variable access is used, - the variable memory location is directly accessed If you - clear a variable list and then evaluate an expression, - it will access invalid memory.
-You can also use fast variable access in you application - to dramatically speed up loops. This is accomplished as - follows: -
-
- -- Add the desired variable to the variable list
-- Get the address of the variable with exprValListGetAddress
-- In the loop(s), directly set/get the variable any time needed: *var = 0.0;
-
--To use the internal functions, they must first be initialized - into a function list with exprFuncListInit. To use the - internal constants, they must first be initialized into a - value list with exprValListInit. For a list of the - internal functions and constants, see the application - help template file: ExprTmpl.html - You may use this file in your own applications so you don't - have to write a detail on the functions in ExprEval. All - you have to do is add you own functions and constants to - the file if there are any. -
--Custom functions can be created for use by the library. - This is how a function should look -
-
-int custom_func(exprObj *obj, exprNode *nodes, int nodecount, EXPRTYPE **refs, int refcount, EXPRTYPE *val) - { - } -- - - obj is a pointer to the expression object that called - the function, nodes is a pointer to an array of nodes - that are the parameters of this function, nodecount is - the number of items in the array (the number of parameters), - refs is an array of pointers to referenced variables, - refcount is the number of referenced variables, - and val is a pointer to a variable to recieve the result - of the function. The function should return an error value - indicating the error status of the function. - -Solving a function typically goes as follows: -
-
- -- Verifiy the number of arguments, if needed
-- Evaluate the subnodes that you need. You do not have to - evaluate every subnode if you do not need it
-- Check for possible error conditions (division by zero)
-- Clear math errors (If function uses any math routines)
-- Calculate the result
-- Check for math errors (If the function uses any math routines)
-- return EXPR_ERROR_NOERROR
-Example: -
-
-int custom_func(exprObj *obj, exprNode *nodes, int count, EXPRTYPE **refs, int refcount, EXPRTYPE *val) - { - int err; - EXPRTYPE d1, d2; - - /* Need 2 arguments */ - if(nodecount != 2) - return EXPR_ERROR_BADNUMBERARGUMENTS; - - /* Eval arg 1 */ - err = exprEvalNode(obj, nodes, 0, &d1); - if(err != EXPR_ERROR_NOERROR) - return err; - - /* Eval arg 2 */ - err = exprEvalNode(obj, nodes, 1, &d2); - if(err != EXPR_ERROR_NOERROR) - return err; - - /* Make sure arg 2 is not 0.0 */ - if(d2 == 0.0) - { - *val = 0.0; - return EXPR_ERROR_NOERROR; - } - - /* Do math */ - *val = atan(d1 / d2); /* No need to worry about divide by zero */ - - - return EXPR_ERROR_NOERROR; - } -- - -In order to use a custom function, it must be added to - a function list before the expression is parsed by using - exprFuncListAdd
-
--Headers: -
-
-- expreval.h - Include file
--
Defines: -
-
- -- EXPR_MAXIDENTSIZE - Maximum identifier, constant, - or function name size
-- EXPR_ERROR_NOERROR - No error has occurred
-- EXPR_ERROR_MEMORY - A memory allocation error occured. - For function and value lists, the name may have been - invalid
-- EXPR_ERROR_NULLPOINTER - A null pointer was passed to - a function that needed a valid pointer.
-- EXPR_ERROR_NOTFOUND - An item was not found in the - function or value list
-- EXPR_ERROR_UNMATHEDCOMMENT - Comment is missing opening - or closing mark.
-- EXPR_ERROR_INVALIDCHAR - Invalid characters were found - in the expression
-- EXPR_ERROR_ALREADYEXISTS - An item already exists or created.
-- EXPR_ERROR_ALREADYPARSEDBAD - An expression was already - parsed into this object, but unsuccessfully. Free the - expression before creating and parsing again
-- EXPR_ERROR_ALREADYPARSEDGOOD - An expression was already - parsed into this object successfully. Free the expression - before creating and parsing again
-- EXPR_ERROR_EMPTYEXPR - An empty expression string was passed - to be parsed
-- EXPR_ERROR_UNMATHEDPAREN - Unmathed opening or closing - parenthesis were found
-- EXPR_ERROR_SYNTAX - A syntax error is in the expression
-- EXPR_ERROR_MISSINGSEMICOLON - An expression is missing a - semicolon
-- EXPR_ERROR_BADIDENTIFIER - A bad identifier was used in - the expression
-- EXPR_ERROR_NOSUCHFUNCTION - Function used in the expression - does not exist in the function list
-- EXPR_ERROR_BADNUMBERARGUMENTS - A bad number of arguments - was passed to the expression function
-- EXPR_ERROR_BADEXPR - Can not evaluate an expression because - it does not exist or has not been parsed successfully.
-- EXPR_ERROR_UNABLETOASSIGN - Unable to do an assignment because - a variable list has not been associated with the expression object
-- EXPR_ERROR_DIVBYZERO - An attemp to divide by zero has occured
-- EXPR_ERROR_NOVARLIST - No variable list for the expression
-- EXPR_ERROR_BREAK - The expression was broken by the break function
-- EXPR_ERROR_CONSTANTASSIGN - The expresion attempted to assign to a constant.
-- EXPR_ERROR_REFCONSTANT - The expression attempted to pass a constant as a - reference parameter.
-- EXPR_ERROR_OUTOFRANGE - A bad value was passed to a function.
-- EXPR_ERROR_USER - Custom error values need to be larger than this.
-Objects: -
-
- -- exprObj - The expression object
-- exprFuncList - A function lists for the expresions
-- exprValList - A value list for constants or variables
-- exprNode - An individual node in a parsed expression tree
-Types: -
-
- -- EXPRTYPE - Type for the value of an expression (double)
-- exprFuncType - Custom function type. Defined as:
-
- typedef int (*exprFuncType)(exprObj *obj, exprNode *nodes, int nodecount, EXPRTYPE **refs, int refcount, EXPRTYPE *val);- exprBreakFuncType - Breaker function pointer to stop evaluation if the result is nonzero. - Defined as:
-
- typedef int (*exprBreakFuncType)(exprObj *o);Version information functions: -
-
- -- void exprGetVersion(int *major, int *mino);
-
- Comments: --
- Parameters: -- Gets the version of the ExprEval library
--
- Returns: -- *major - Pointer to int to get major version number
-- *minor - Pointer to int to get minor version number
--
-- Nothing
-Function list functions: -
-
- -- int exprFuncListCreate(exprFuncList **flist);
- Comments: --
- Parameters: -- Creates a function lists and updates a pointer to point to it
--
- Returns -- **flist - Pointer to a pointer to the function list
--
-- Error code of the function. On success, the pointer - passed by address will point to the new function list
-
-- int exprFuncListAdd(exprFuncList *flist, exprFuncType ptr, char *name, int min, int max, int refmin, int refmax);
- Comments: --
- Parameters: -- Adds a function to the function list. Returns error if - the function already exists.
--
- Returns: -- *flist - Pointer to an already created function list
-- ptr - Pointer to a custom function
-- *name - Name of the custom function
-- min - Minimum number of arguments for the function, negative for no minimum
-- max - Maximum number of arguments for the function, negative for no maximum
-- refmin - Minimum number of ref arguments
-- refmax - Maxmimum number of ref arguments
--
-- Error code of the function
-
-- int exprFuncListFree(exprFuncList *flist);
- Comments: --
- Parameters: -- Free the function list entirely
--
- Returns: -- *flist - Pointer to the function list to free
--
-- Error code of the function
-
-- int exprFuncListClear(exprFuncList *flist);
- Comments: --
- Parameters: -- Clear the functions from the function list
--
- Returns: -- *flist - Pointer to the function list to clear
--
-- Error code of the function
-
-- int exprFuncListInit(exprFuncList *flist);
-
- Comments: --
- Parameters: -- Initializes internal functions into the funtion list
--
- Returns: -- *flist - Function list to initialize
--
-- Error code of the function
-Value list functions: -
-
- -- int exprValListCreate(exprValList **vlist);
- Comments: --
- Parameters: -- Creates a value list for variables or constants
--
- Returns: -- **vlist - Pointer to a pointer to the value list.
--
-- Error code of the function. On success, the pointer will - be updated to point to the value list
-
-- int exprValListAdd(exprValList *vlist, char *name, EXPRTYPE val);
- Comments: --
- Parameters: -- Add a value in a value list. Returns error if value - already exists.
--
- Returns: -- *vlist - Value list to add a value to
-- *name - Name of the value to add
-- val - Value of the value to add
--
-- Error code of the function
-
-- int exprValListSet(exprValList *vlist, char *name, EXPRTYPE val);
- Comments: --
- Parameters: -- Set a value in a value list.
--
- Returns: -- *vlist - Value list to set a value in
-- *name - Name of the value to set
-- val - Value of the value to set
--
-- Error code of the function
-
-- int exprValListGet(exprValList *vlist, char *name, EXPRTYPE *val)
- Comment: --
- Parameters: -- Get the value of a variable or constant in a value list
--
- Returns: -- *vlist - Value list to use
-- *name - Name of the value to get
-- *val - Pointer to variable to get the value
--
-- Error code of the function
-
-- int exprValListAddAddress(exprValList *vlist, char *name, EXPRTYPE *addr)
- Comment: --
- Parameters: -- This function is used to add a named value to the value list, but - uses an outside variable such as a stack variable to store the - value. This outside variable is used to set/get the value instead - of the internal list value. You must ensure that this outside - variable exists as long as the expression is using it's address.
--
- Returns: -- *vlist - Value list to use
-- *name - Name of the value to add
-- *addr - Address of the value being added
--
-- Error code of the function
-
-- int exprValListGetAddress(exprValList *vlist, char *name, EXPRTYPE **addr)
- Comment: --
- Parameters: -- Get the memory address of a variable in a value list
--
- Returns: -- *vlist - Value list to use
-- *name - Name of the value to get
-- **addr - Pointer to a pointer to store the address of the value - This will be NULL if the name is not in the list.
--
-- Error code of the function
-
-- void *exprValListGetNext(exprValList *vlist, char **name, EXPRTYPE *value, EXPRTYPE** addr, void *cookie);
- Comment: --
- Parameters: -- This is used to enumerate the items in the value list. - Do NOT change the list while enumerating the items. Any - of the information items can be NULL if it is not needed.
--
- Returns: -- *vlist - Value list to use
-- **name - Address of a pointer that will point to the - name. Do not edit the name.
-- *value - The current value of the item.
-- **addr - Address of a pointer to store the address of the value.
-- *cookie - NULL to find the first item, the return value to find - subsequent items.
--
-- NULL if the item could not be found. Otherwise a cookie - to be used to find additional items.
-
-- int exprValListFree(exprValList *vlist);
- Comments: --
- Parameters: -- Completely free the value list
--
- Returns: -- *vlist - Value list to free
--
-- Error code of the function
-
-- int exprValListClear(exprValList *vlist);
- Comments: --
- Parameters: -- Set the values in the list to 0.0
--
- Returns: -- *vlist - Value list to reset
--
-- Error code of the function
-
-- int exprValListInit(exprValList *vlist);
-
- Comments: --
- Paramters: -- Initialize internal constants into a value list
--
- Returns: -- *vlist - Value list to initialize
--
-- Error code of the function
-Expression functions: -
-
- -- int exprCreate(exprObj **obj, exprFuncList *flist, exprValList *vlist, exprValList *clist, exprBreakFuncType breaker, void *userdata);
- Comments: --
- Parameters: -- Create an expression object to use
--
- Returns: -- **obj - Pointer to a pointer to an expression object
-- *flist - Function list to associate with the expression
-- *vlist - Variable value list to associate with the expression
-- *clist - Constant value list to associate with the expression
-- breaker - Breaker function callback to associate with the expression. - Used by functions that may be infinite loops (such as the for function)
-- userdata - User data to associate with the expression
--
-- Error code of the function
-
-- int exprFree(exprObj *obj);
- Comments: --
- Paramters: -- Completely free the expression object
--
- Returns: -- *obj - Expression object to free
--
-- Error code of the function
-
-- int exprClear(exprObj *obj);
- Comments: --
- Parameters: -- Clear an expression, but keep list and callback associations. - You can then parse another expression without calling create
--
- Returns: -- *obj - Expression object to clear
--
-- Error code of the function
-
-- int exprParse(exprObj *obj, char *expr);
- Comments: --
- Paramters: -- Parse an expression string into an expression object
--
- Returns: -- *obj - Expression object to use
-- *expr - Expression string to parse
--
-- Error code of the function
-
-- int exprEval(exprObj *obj, EXPRTYPE *val);
- Comments: --
- Paramters: -- Evaluate a parsed expression. This function does not - reset the breaker count at each call, but instead accumulates - the count until the breaker function is called. Then the count - is reset to the value specified in exprSetBreakerCount.
--
- Returns: -- *obj - Expression object to evaluate
-- *val = Pointer to variable to get result of evaluation. - This can be NULL if the result is not needed.
--
-- Error code of the function
-
-- int exprEvalNode(exprObj *obj, exprNode *nodes, int curnode, EXPRTYPE *val);
- Comments: --
- Parameters: -- Evaluate a node of an expression. - Used by custom functions
--
- Returns: -- *obj - Expression object being used
-- *nodes - Pointer to a node or list of nodes
-- curnode - Index to the node to evaluate
-- *val - Pointer to variable to get evaluation result
--
-- Error code of the function
-
-- exprFuncList *exprGetFuncList(exprObj *obj);
- Comments: --
- Parameters: -- Gets the function list associated with an expression
--
- Returns: -- *obj - expression object
--
-- Pointer fo an exprFuncList object or NULL
-
-- exprValList *exprGetVarList(exprObj *obj);
- Comments: --
- Parameters: -- Gets the variable list associated with an expression
--
- Returns: -- *obj - expression object
--
-- Pointer to an exprValList object or NULL
-
-- exprValList *exprGetConstList(exprObj *obj);
- Comments: --
- Parameters: -- Gets the constant list associated with an expression
--
- Returns: -- *obj - expression object
--
-- Pointer to an exprValList object or NULL
-
-- exprBreakFuncType exprGetBreakFunc(exprObj *obj);
- Comments: --
- Parameters: -- Gets the breaker callback of the expression
--
- Returns: -- *obj - expression object
--
-- Pointer to the callback function or NULL
-
-- int exprGetBreakResult(exprObj *obj);
- Comments: --
- Parameters: -- Get the result of the breaker function
--
- Returns: -- *obj - expression object
--
-- zero to continue, nonzero to break
-
-- void* exprGetUserData(exprObj *obj);
- Comments: --
- Parameters: -- Gets the user data associated with an expression
--
- Returns: -- *obj - expression object
--
-- User data
-
-- void exprSetUserData(exprObj *obj, void *userdata);
- Comments: --
- Parameters: -- Sets the user data of an expression
--
- Returns: -- *obj - expresion object
-- userdata - user data to set
--
-- Nothing
-
-- void exprSetBreakCount(exprObj *obj, int count);
- Comments: --
- Parameters: -- Set how often the breaker function is tested. - The default is 100000. This means the breaker - function is tested once every 100000 times the - exprEvalNode function is called for an expression. - A smaller value tests the breaker function more often - and a larger value tests the breaker function less. The - breaker value is NOT reset during each call to exprEval, - but is accumulated across calles to exprEval - until the breaker function is finally called.
--
- Returns: -- *obj - expression object
-- count - how many times exprEvalNode gets called before the - breaker function is tested
--
-- Nothing
-
-- void exprGetErrorPosition(exprObj *obj, int *start, int *end);
- Comments: --
- Parameters: -- Gets the start and ending positions in the expression string - of the last parse error. The positions include any newline - characters that may be in the string.
--
- Returns: -- *obj - expression object
-- *start - pointer to an integer to get the start error position, - -1 if unknown
-- *end - pointer to an integer to get the end error position, - -1 if unknown
--
-- Nothing
-Some useful functions -
-
- -- int exprValidIdent(char *name);
- Comments: --
- Parameters: -- Determine if an identifier is valid
--
- Returns: -- *name - identifier to check
--
-- 0 on invalid. anything else on valid
-
-
Compiling the ExprEval library is pretty simple. Just - compile all of the source files (*.c) and link them into - a library. You need to keep "expreval.h" for the header file.
-You may have to make some changes to the library. I've - tried to make doing so as simple as possible. If you - need to change the include files or some macros or whatnot, - edit the file "exprincl.h" This file includes any other files - needed. You should not have to change to much. I have - tried to stick as close to ANSI/ISO C as I can.
-The following is a list of some basic drawbacks of this - library: -
-- Inside the loop, the variable 'k' does not appear to be changing, so - the compiler may optimize it by loading it into a register before the - loop and not accessing it from memory during the loop, even if - the expression does change it. One way to avoid this is to use the - 'volatile' keyword with the variable. Then the compiler must - accesss it from memory each time it is accessed. --EXPRTYPE k; - -/* Add variable to the list */ -exprValListAddAddress(list, "k", &k); - -k = 0.0; - -/* Evaluate expression */ -for(int x = 0; x < 100; x++) - { - exprEval(expr, &result); - - doSomething(k); - } --
---volatile EXPRTYPE k; - -/* Add variable to the list */ -exprValListAddAddress(list, "k", (EXPRTYPE*)&k); - -k = 0.0; - -/* Evaluate expression */ -for(int x = 0; x < 100; x++) - { - exprEval(expr, &result); - - doSomething(k); - } --
This is an example application of this library. It is a - graphics program that calculates the color value of a - pixel based on it's X,Y co-ordinate. It uses a made-up - image library called graphic-lib. It uses faster variable - access by using the exprValListGetAddress function.
-Note that this codes has not actually been tested. See the - test applications (test and imagegen) for other examples.
- ----/* Include files */ -#include <stdio.h> -#include <stdlib.h> -#include <setjmp.h> -#include "graphiclib.h" -#include "expreval.h" - -char *transerr(int err) - { - /* Translate error code into message */ - } - -void gen_image(char *name, int w, int h, char *expr); - { - exprFuncList *f = NULL; - exprValList *v = NULL; - exprValList *c = NULL; - exprObj *o = NULL; - int x, y, err; - jmp_buf jumper; - int image; - EXPRTYPE *v_x, *v_y; - EXPRTYPE *v_r, *v_g, *v_b; - EXPRTYPE global_value; - - /* Error handling */ - err = setjmp(jumper); - if(err) - { - if(err != ID_IMAGENOERROR) - printf("Error %d occurred: %s\n", err, transerr(err)); - - exprFree(o); - exprFreeFuncList(f); - exprFreeValList(v); - exprFreeValList(c); - - image_free(image); - return; - } - - /* Set up lists */ - - /* Function list */ - err = exprFuncListCreate(&f); - if(err != EXPR_ERROR_NOERROR) - longjmp(jumper, err); - - err = exprFuncListInit(f); - if(err != EXPR_ERROR_NOERROR) - { - printf("Function list init error. Functions may not be available.\n"); - } - - /* Variable list */ - err = exprValListCreate(&v); - if(err != EXPR_ERROR_NOERROR) - longjmp(jumper, err); - - /* Constant list */ - err = exprValListCreate(&c); - if(err != EXPR_ERROR_NOERROR) - { - printf("Constants not available\n"); - } - else - { - err = exprValListInit(c); - if(err != EXPR_ERROR_NOERROR) - printf("Constant list init error. Constants may not be available.\n"); - } - - /* Create and parse the expression */ - - /* Create */ - err = exprCreate(&o, f, v, c, NULL, 0); - if(err != EXPR_ERROR_NOERROR) - longjmp(jumper, err); - - /* Parse expression */ - err = exprParse(o, expr); - if(err != EXPR_ERROR_NOERROR) - longjmp(jumper, err); - - - /* Create the image */ - image = image_create(w, h); - if(image == 0) - { - longjmp(jumper, ID_IMAGECREATEERROR); - } - - /* Add width and height to variable list */ - exprValListAdd(v, "w", (EXPRTYPE)w); - exprValListAdd(v, "h", (EXPRTYPE)h); - - /* Add x and y to the list */ - exprValListAdd(v, "x", 0.0); - exprValListAdd(v, "y", 0.0); - - /* Add r, g, and b to the list */ - exprValListAdd(v, "r", 0.0); - exprValListAdd(v, "g", 0.0); - exprValListAdd(b, "b", 0.0); - - /* Get addresses. Assume no error */ - exprValListGetAddress(v, "x", &v_x); - exprValListGetAddress(v, "y", &v_y); - - exprValListGetAddress(v, "r", &v_r); - exprValListGetAddress(v, "g", &v_g); - exprValListGetAddress(v, "g", &v_b); - - /* A way to add global variables that can be used by two different lists. */ - exprValListAddAddress(v, "global", &global_value); - /* exprValListAddAddress(v2, "global", &global_value); */ - - /* Also, exprValListAddAddress can be used to add variables directly. - Instead of: - - EXPRTYPE *a; - - exprValListAdd(v, "a", 0.0); - exprValListGetAddresss(v, "a", &a); - - You can do: - - EXPRTYPE a; - - exprValListAddAddresss(v, "a", &a); - - If you do this, you must ensure that the stack variable exists as long - as it is used by expression, otherwise it may cause a memory access - violation. */ - - - for(y = 0; y < h; y++) - { - for(x = 0; x < w; x++) - { - /* Directly set the x and y variables */ - *v_x = (EXPRTYPE)x; - *v_y = (EXPRTYPE)y; - - /* Eval expression, ignoring errors */ - exprEval(o); - - /* Set pixel, using variables directly */ - image_setpixel(image, x, y, (int)(*v_r), (int)(*v_g), (int)(*v_b)); - } - } - - /* Save image */ - image_save(image, name); - - /* Done */ - longjmp(jumper, ID_IMAGENOERROR); - } - -void main(void) - { - char name[MAXPATH] - char tmp[10]; - char expr[4096]; - int sx, sy; - - printf("Image name to save: "); - gets(name); - - printf("Image width: "); - gets(tmp); - sx = atoi(tmp); - - printf("Image height: "); - gets(tmp); - sy = atoi(tmp); - - printf("Color Expression (Use x, y, w, h Set r, g, b): "); - gets(expr); - - gen_image(name, sx, sy, expr); - } - --
++ExprEval Help document. This document is probably full of + bugs and mispellings. I may get around to proofreading + it later.
+ExprEval is a C based expression evaluation library. + It is entirely C based, but can be used in C++ programs + as well.. The source code is provided for the library + so that it can be recompiled for the specific system + or compiler.
+ExprEval makes adding mathematical expression support to + an application easy. It takes an expression string and + parses it, and then it can evaluate it over and over. + This library also has support for functions, constants, + and variables. All of these items are stored in + seperate lists so they can be shared among expressions or + they can be private to a single expression or any mix and + match. It is up to the developer how to link them together. + You can also create your own custom functions.
+
++This library is licensed under the + ExprEval License. +
+
++Expressions have pretty much the same syntax as they + would have on paper, with the following exceptions: +
+
+ +- Each expression must end with a semicolon. This + is because the expression string can actually + contain multiple expressions. The semicolon is + used to mark the end of the expression.
+
+ Examples: ++
+- 4*x+5;
+- y=5+2;g=4+6;
+- y=r*sin(a);x=r*cos(a);
+- The asterisk '*' must be used to multiply.
+
+ Examples: ++
+- y=5*6; Valid
+- g=(x+1)*(x-1); Valid
+- g=(x+1)(x-1); Invalid
+More than one expression may be contained within an expression string. + As shown above, each expression must end with a semicolon, even if + only one expression is in the string. The value of an expression + string is the value of the last expression in the string.
+ Examlples: ++
+ +- g=7; Value: 7
+- k=z+1; Value: z+1
+- r=4;k=6;o=9+r-k; Value: 9+r-k
+Some functions may take reference parameters. These parameters are + references to other variables. You can mix reference parameters + with normal parameters. The order of the normal parameters must + remain the same and the order of the reference parameters must + remain the same.
+ Examples: ++
+ +- min(1,2,3,4,&mval); &mval is a reference to a variable mval
+- min(1,2,&mval,3,4); You may mix them inside like this.
+- min(1,2,(&mval),3,4); You may not nest reference parameters in any way
+Expressions may also be nested with parenthesis.
+ Examples: ++
+ +- y=sin(x-cos(5+max(4,5,6*x)));
+- 6+(5-2*(x+y));
+Expressions may also have whitespace characters and comments. + Whitespace characters such as newlines, linefeeds, carriage + returns, spaces, and tabs are ignored. Comments begin with + the pound sign '#' and end at the end of the line.
+ Example: ++
+#Set the x value +x = d * cos(r); + +#Set the y value +y = d * sin(r); ++ + +If a variable is used in an expression, but that variable does not exist, + it is considered zero. If it does exist then its value is used instead. +
+
++Using ExprEval in an application can be a little difficult. + You generally follow these steps: +
+
+ You can manipulate the lists in any order after their creation. + However, functions are translated during the parse, so after + parsing an expression, manipulating the function list will make + no change to an expression. Variables and constants can be + manipulated after a parse to change the result of an expression. + However, you must add any constants to be used by an expression + to the constant list BEFORE parsing the expression, + otherwise it will be seen as a variable. Applications can change + both variables and constants, however the expression can only + change variables. Expressions may NOT assign to a constant + and expressions may NOT use constants as a reference parameter. +- Create function, variable, and constant lists
+- Create the expression object
+- Parse the expression
+- Evaluate the expression as needed
+- Free the expression object
+- Free the function, variable, and constant lists
+Function, variable, and constant list example: +
+
+exprFuncList *flist; +exprValList *vlist; +exprValList *clist; +exprObj *obj; +EXPRTYPE result; +int err; + +/* Create function list */ +err = exprFuncListCreate(&flist); +if(err != EXPR_ERROR_NOERROR) + { + ... + } + +/* Initialize internal functions */ +err = exprFuncListInit(flist); +if(err != EXPR_ERROR_NOERROR) + { + ... + } + +/* Create variable list */ +err = exprValListCreate(&vlist); +if(err != EXPR_ERROR_NOERROR) + { + ... + } + +/* Create the constant list */ +err = exprValListCreate(&clist); +if(err != EXPR_ERROR_NOERROR) + { + ... + } + +/* Initialize internal constants */ +err = exprValListInit(clist); +if(err != EXPR_ERROR_NOERROR) + { + ... + } + +/* Add any application defined functions, constants, or variables to the lists here or down below */ ++ + +Expression object example: +
+
+err = exprCreate(&obj, flist, vlist, clist, NULL, 0); +if(err != EXPR_ERROR_NOERROR) + { + ... + } + +/* Add any application defined functions, constants, or variables to the lists here or down below. + This is the last time you can for the functions or constants. */ ++ + +Expression parse example: +
+
+/* Functions and constants may be added or changed here */ + +err = exprParse(obj, "2+sin(M_PI)+3*x;"); +if(err != EXPR_ERROR_NOERROR) + { + ... + } + +/* Changes to the function or constant lists do not change the expression now */ ++ + +Expression evaluation example: +
+
+/* Add or change any variables */ + +err = exprEval(obj, &result); +if(err != EXPR_ERROR_NOERRO) + { + ... + } +else + { + printf("Expression Result: %f\n", result); + } ++ + +Free the expression object and lists example: +
+
+exprFree(obj); +exprValListFree(vlist); +exprValListFree(clist); +exprFuncListFree(flist); ++ + +
++A new feature in ExprEval is fast variable access. This + is simply a technique of quickly accessing variables + by directly accessing their memory locations instead + of using the value list functions. Fast variable access + is always used internally in ExprEval. You must + NOT clear a variable list until after all expressions + using it are completely finished evaluating. Then you + must reparse the expressions before using them again. + The reason is simple. When fast variable access is used, + the variable memory location is directly accessed If you + clear a variable list and then evaluate an expression, + it will access invalid memory.
+You can also use fast variable access in you application + to dramatically speed up loops. This is accomplished as + follows: +
+
+ +- Add the desired variable to the variable list
+- Get the address of the variable with exprValListGetAddress
+- In the loop(s), directly set/get the variable any time needed: *var = 0.0;
+
++To use the internal functions, they must first be initialized + into a function list with exprFuncListInit. To use the + internal constants, they must first be initialized into a + value list with exprValListInit. For a list of the + internal functions and constants, see the application + help template file: ExprTmpl.html + You may use this file in your own applications so you don't + have to write a detail on the functions in ExprEval. All + you have to do is add you own functions and constants to + the file if there are any. +
++Custom functions can be created for use by the library. + This is how a function should look +
+
+int custom_func(exprObj *obj, exprNode *nodes, int nodecount, EXPRTYPE **refs, int refcount, EXPRTYPE *val) + { + } ++ + + obj is a pointer to the expression object that called + the function, nodes is a pointer to an array of nodes + that are the parameters of this function, nodecount is + the number of items in the array (the number of parameters), + refs is an array of pointers to referenced variables, + refcount is the number of referenced variables, + and val is a pointer to a variable to recieve the result + of the function. The function should return an error value + indicating the error status of the function. + +Solving a function typically goes as follows: +
+
+ +- Verifiy the number of arguments, if needed
+- Evaluate the subnodes that you need. You do not have to + evaluate every subnode if you do not need it
+- Check for possible error conditions (division by zero)
+- Clear math errors (If function uses any math routines)
+- Calculate the result
+- Check for math errors (If the function uses any math routines)
+- return EXPR_ERROR_NOERROR
+Example: +
+
+int custom_func(exprObj *obj, exprNode *nodes, int count, EXPRTYPE **refs, int refcount, EXPRTYPE *val) + { + int err; + EXPRTYPE d1, d2; + + /* Need 2 arguments */ + if(nodecount != 2) + return EXPR_ERROR_BADNUMBERARGUMENTS; + + /* Eval arg 1 */ + err = exprEvalNode(obj, nodes, 0, &d1); + if(err != EXPR_ERROR_NOERROR) + return err; + + /* Eval arg 2 */ + err = exprEvalNode(obj, nodes, 1, &d2); + if(err != EXPR_ERROR_NOERROR) + return err; + + /* Make sure arg 2 is not 0.0 */ + if(d2 == 0.0) + { + *val = 0.0; + return EXPR_ERROR_NOERROR; + } + + /* Do math */ + *val = atan(d1 / d2); /* No need to worry about divide by zero */ + + + return EXPR_ERROR_NOERROR; + } ++ + +In order to use a custom function, it must be added to + a function list before the expression is parsed by using + exprFuncListAdd
+
++Headers: +
+
+- expreval.h - Include file
++
Defines: +
+
+ +- EXPR_MAXIDENTSIZE - Maximum identifier, constant, + or function name size
+- EXPR_ERROR_NOERROR - No error has occurred
+- EXPR_ERROR_MEMORY - A memory allocation error occured. + For function and value lists, the name may have been + invalid
+- EXPR_ERROR_NULLPOINTER - A null pointer was passed to + a function that needed a valid pointer.
+- EXPR_ERROR_NOTFOUND - An item was not found in the + function or value list
+- EXPR_ERROR_UNMATHEDCOMMENT - Comment is missing opening + or closing mark.
+- EXPR_ERROR_INVALIDCHAR - Invalid characters were found + in the expression
+- EXPR_ERROR_ALREADYEXISTS - An item already exists or created.
+- EXPR_ERROR_ALREADYPARSEDBAD - An expression was already + parsed into this object, but unsuccessfully. Free the + expression before creating and parsing again
+- EXPR_ERROR_ALREADYPARSEDGOOD - An expression was already + parsed into this object successfully. Free the expression + before creating and parsing again
+- EXPR_ERROR_EMPTYEXPR - An empty expression string was passed + to be parsed
+- EXPR_ERROR_UNMATHEDPAREN - Unmathed opening or closing + parenthesis were found
+- EXPR_ERROR_SYNTAX - A syntax error is in the expression
+- EXPR_ERROR_MISSINGSEMICOLON - An expression is missing a + semicolon
+- EXPR_ERROR_BADIDENTIFIER - A bad identifier was used in + the expression
+- EXPR_ERROR_NOSUCHFUNCTION - Function used in the expression + does not exist in the function list
+- EXPR_ERROR_BADNUMBERARGUMENTS - A bad number of arguments + was passed to the expression function
+- EXPR_ERROR_BADEXPR - Can not evaluate an expression because + it does not exist or has not been parsed successfully.
+- EXPR_ERROR_UNABLETOASSIGN - Unable to do an assignment because + a variable list has not been associated with the expression object
+- EXPR_ERROR_DIVBYZERO - An attemp to divide by zero has occured
+- EXPR_ERROR_NOVARLIST - No variable list for the expression
+- EXPR_ERROR_BREAK - The expression was broken by the break function
+- EXPR_ERROR_CONSTANTASSIGN - The expresion attempted to assign to a constant.
+- EXPR_ERROR_REFCONSTANT - The expression attempted to pass a constant as a + reference parameter.
+- EXPR_ERROR_OUTOFRANGE - A bad value was passed to a function.
+- EXPR_ERROR_USER - Custom error values need to be larger than this.
+Objects: +
+
+ +- exprObj - The expression object
+- exprFuncList - A function lists for the expresions
+- exprValList - A value list for constants or variables
+- exprNode - An individual node in a parsed expression tree
+Types: +
+
+ +- EXPRTYPE - Type for the value of an expression (double)
+- exprFuncType - Custom function type. Defined as:
+
+ typedef int (*exprFuncType)(exprObj *obj, exprNode *nodes, int nodecount, EXPRTYPE **refs, int refcount, EXPRTYPE *val);- exprBreakFuncType - Breaker function pointer to stop evaluation if the result is nonzero. + Defined as:
+
+ typedef int (*exprBreakFuncType)(exprObj *o);Version information functions: +
+
+ +- void exprGetVersion(int *major, int *mino);
+
+ Comments: ++
+ Parameters: +- Gets the version of the ExprEval library
++
+ Returns: +- *major - Pointer to int to get major version number
+- *minor - Pointer to int to get minor version number
++
+- Nothing
+Function list functions: +
+
+ +- int exprFuncListCreate(exprFuncList **flist);
+ Comments: ++
+ Parameters: +- Creates a function lists and updates a pointer to point to it
++
+ Returns +- **flist - Pointer to a pointer to the function list
++
+- Error code of the function. On success, the pointer + passed by address will point to the new function list
+
+- int exprFuncListAdd(exprFuncList *flist, exprFuncType ptr, char *name, int min, int max, int refmin, int refmax);
+ Comments: ++
+ Parameters: +- Adds a function to the function list. Returns error if + the function already exists.
++
+ Returns: +- *flist - Pointer to an already created function list
+- ptr - Pointer to a custom function
+- *name - Name of the custom function
+- min - Minimum number of arguments for the function, negative for no minimum
+- max - Maximum number of arguments for the function, negative for no maximum
+- refmin - Minimum number of ref arguments
+- refmax - Maxmimum number of ref arguments
++
+- Error code of the function
+
+- int exprFuncListFree(exprFuncList *flist);
+ Comments: ++
+ Parameters: +- Free the function list entirely
++
+ Returns: +- *flist - Pointer to the function list to free
++
+- Error code of the function
+
+- int exprFuncListClear(exprFuncList *flist);
+ Comments: ++
+ Parameters: +- Clear the functions from the function list
++
+ Returns: +- *flist - Pointer to the function list to clear
++
+- Error code of the function
+
+- int exprFuncListInit(exprFuncList *flist);
+
+ Comments: ++
+ Parameters: +- Initializes internal functions into the funtion list
++
+ Returns: +- *flist - Function list to initialize
++
+- Error code of the function
+Value list functions: +
+
+ +- int exprValListCreate(exprValList **vlist);
+ Comments: ++
+ Parameters: +- Creates a value list for variables or constants
++
+ Returns: +- **vlist - Pointer to a pointer to the value list.
++
+- Error code of the function. On success, the pointer will + be updated to point to the value list
+
+- int exprValListAdd(exprValList *vlist, char *name, EXPRTYPE val);
+ Comments: ++
+ Parameters: +- Add a value in a value list. Returns error if value + already exists.
++
+ Returns: +- *vlist - Value list to add a value to
+- *name - Name of the value to add
+- val - Value of the value to add
++
+- Error code of the function
+
+- int exprValListSet(exprValList *vlist, char *name, EXPRTYPE val);
+ Comments: ++
+ Parameters: +- Set a value in a value list.
++
+ Returns: +- *vlist - Value list to set a value in
+- *name - Name of the value to set
+- val - Value of the value to set
++
+- Error code of the function
+
+- int exprValListGet(exprValList *vlist, char *name, EXPRTYPE *val)
+ Comment: ++
+ Parameters: +- Get the value of a variable or constant in a value list
++
+ Returns: +- *vlist - Value list to use
+- *name - Name of the value to get
+- *val - Pointer to variable to get the value
++
+- Error code of the function
+
+- int exprValListAddAddress(exprValList *vlist, char *name, EXPRTYPE *addr)
+ Comment: ++
+ Parameters: +- This function is used to add a named value to the value list, but + uses an outside variable such as a stack variable to store the + value. This outside variable is used to set/get the value instead + of the internal list value. You must ensure that this outside + variable exists as long as the expression is using it's address.
++
+ Returns: +- *vlist - Value list to use
+- *name - Name of the value to add
+- *addr - Address of the value being added
++
+- Error code of the function
+
+- int exprValListGetAddress(exprValList *vlist, char *name, EXPRTYPE **addr)
+ Comment: ++
+ Parameters: +- Get the memory address of a variable in a value list
++
+ Returns: +- *vlist - Value list to use
+- *name - Name of the value to get
+- **addr - Pointer to a pointer to store the address of the value + This will be NULL if the name is not in the list.
++
+- Error code of the function
+
+- void *exprValListGetNext(exprValList *vlist, char **name, EXPRTYPE *value, EXPRTYPE** addr, void *cookie);
+ Comment: ++
+ Parameters: +- This is used to enumerate the items in the value list. + Do NOT change the list while enumerating the items. Any + of the information items can be NULL if it is not needed.
++
+ Returns: +- *vlist - Value list to use
+- **name - Address of a pointer that will point to the + name. Do not edit the name.
+- *value - The current value of the item.
+- **addr - Address of a pointer to store the address of the value.
+- *cookie - NULL to find the first item, the return value to find + subsequent items.
++
+- NULL if the item could not be found. Otherwise a cookie + to be used to find additional items.
+
+- int exprValListFree(exprValList *vlist);
+ Comments: ++
+ Parameters: +- Completely free the value list
++
+ Returns: +- *vlist - Value list to free
++
+- Error code of the function
+
+- int exprValListClear(exprValList *vlist);
+ Comments: ++
+ Parameters: +- Set the values in the list to 0.0
++
+ Returns: +- *vlist - Value list to reset
++
+- Error code of the function
+
+- int exprValListInit(exprValList *vlist);
+
+ Comments: ++
+ Paramters: +- Initialize internal constants into a value list
++
+ Returns: +- *vlist - Value list to initialize
++
+- Error code of the function
+Expression functions: +
+
+ +- int exprCreate(exprObj **obj, exprFuncList *flist, exprValList *vlist, exprValList *clist, exprBreakFuncType breaker, void *userdata);
+ Comments: ++
+ Parameters: +- Create an expression object to use
++
+ Returns: +- **obj - Pointer to a pointer to an expression object
+- *flist - Function list to associate with the expression
+- *vlist - Variable value list to associate with the expression
+- *clist - Constant value list to associate with the expression
+- breaker - Breaker function callback to associate with the expression. + Used by functions that may be infinite loops (such as the for function)
+- userdata - User data to associate with the expression
++
+- Error code of the function
+
+- int exprFree(exprObj *obj);
+ Comments: ++
+ Paramters: +- Completely free the expression object
++
+ Returns: +- *obj - Expression object to free
++
+- Error code of the function
+
+- int exprClear(exprObj *obj);
+ Comments: ++
+ Parameters: +- Clear an expression, but keep list and callback associations. + You can then parse another expression without calling create
++
+ Returns: +- *obj - Expression object to clear
++
+- Error code of the function
+
+- int exprParse(exprObj *obj, char *expr);
+ Comments: ++
+ Paramters: +- Parse an expression string into an expression object
++
+ Returns: +- *obj - Expression object to use
+- *expr - Expression string to parse
++
+- Error code of the function
+
+- int exprEval(exprObj *obj, EXPRTYPE *val);
+ Comments: ++
+ Paramters: +- Evaluate a parsed expression. This function does not + reset the breaker count at each call, but instead accumulates + the count until the breaker function is called. Then the count + is reset to the value specified in exprSetBreakerCount.
++
+ Returns: +- *obj - Expression object to evaluate
+- *val = Pointer to variable to get result of evaluation. + This can be NULL if the result is not needed.
++
+- Error code of the function
+
+- int exprEvalNode(exprObj *obj, exprNode *nodes, int curnode, EXPRTYPE *val);
+ Comments: ++
+ Parameters: +- Evaluate a node of an expression. + Used by custom functions
++
+ Returns: +- *obj - Expression object being used
+- *nodes - Pointer to a node or list of nodes
+- curnode - Index to the node to evaluate
+- *val - Pointer to variable to get evaluation result
++
+- Error code of the function
+
+- exprFuncList *exprGetFuncList(exprObj *obj);
+ Comments: ++
+ Parameters: +- Gets the function list associated with an expression
++
+ Returns: +- *obj - expression object
++
+- Pointer fo an exprFuncList object or NULL
+
+- exprValList *exprGetVarList(exprObj *obj);
+ Comments: ++
+ Parameters: +- Gets the variable list associated with an expression
++
+ Returns: +- *obj - expression object
++
+- Pointer to an exprValList object or NULL
+
+- exprValList *exprGetConstList(exprObj *obj);
+ Comments: ++
+ Parameters: +- Gets the constant list associated with an expression
++
+ Returns: +- *obj - expression object
++
+- Pointer to an exprValList object or NULL
+
+- exprBreakFuncType exprGetBreakFunc(exprObj *obj);
+ Comments: ++
+ Parameters: +- Gets the breaker callback of the expression
++
+ Returns: +- *obj - expression object
++
+- Pointer to the callback function or NULL
+
+- int exprGetBreakResult(exprObj *obj);
+ Comments: ++
+ Parameters: +- Get the result of the breaker function
++
+ Returns: +- *obj - expression object
++
+- zero to continue, nonzero to break
+
+- void* exprGetUserData(exprObj *obj);
+ Comments: ++
+ Parameters: +- Gets the user data associated with an expression
++
+ Returns: +- *obj - expression object
++
+- User data
+
+- void exprSetUserData(exprObj *obj, void *userdata);
+ Comments: ++
+ Parameters: +- Sets the user data of an expression
++
+ Returns: +- *obj - expresion object
+- userdata - user data to set
++
+- Nothing
+
+- void exprSetBreakCount(exprObj *obj, int count);
+ Comments: ++
+ Parameters: +- Set how often the breaker function is tested. + The default is 100000. This means the breaker + function is tested once every 100000 times the + exprEvalNode function is called for an expression. + A smaller value tests the breaker function more often + and a larger value tests the breaker function less. The + breaker value is NOT reset during each call to exprEval, + but is accumulated across calles to exprEval + until the breaker function is finally called.
++
+ Returns: +- *obj - expression object
+- count - how many times exprEvalNode gets called before the + breaker function is tested
++
+- Nothing
+
+- void exprGetErrorPosition(exprObj *obj, int *start, int *end);
+ Comments: ++
+ Parameters: +- Gets the start and ending positions in the expression string + of the last parse error. The positions include any newline + characters that may be in the string.
++
+ Returns: +- *obj - expression object
+- *start - pointer to an integer to get the start error position, + -1 if unknown
+- *end - pointer to an integer to get the end error position, + -1 if unknown
++
+- Nothing
+Some useful functions +
+
+ +- int exprValidIdent(char *name);
+ Comments: ++
+ Parameters: +- Determine if an identifier is valid
++
+ Returns: +- *name - identifier to check
++
+- 0 on invalid. anything else on valid
+
+
Compiling the ExprEval library is pretty simple. Just + compile all of the source files (*.c) and link them into + a library. You need to keep "expreval.h" for the header file.
+You may have to make some changes to the library. I've + tried to make doing so as simple as possible. If you + need to change the include files or some macros or whatnot, + edit the file "exprincl.h" This file includes any other files + needed. You should not have to change to much. I have + tried to stick as close to ANSI/ISO C as I can.
+The following is a list of some basic drawbacks of this + library: +
++ Inside the loop, the variable 'k' does not appear to be changing, so + the compiler may optimize it by loading it into a register before the + loop and not accessing it from memory during the loop, even if + the expression does change it. One way to avoid this is to use the + 'volatile' keyword with the variable. Then the compiler must + accesss it from memory each time it is accessed. ++EXPRTYPE k; + +/* Add variable to the list */ +exprValListAddAddress(list, "k", &k); + +k = 0.0; + +/* Evaluate expression */ +for(int x = 0; x < 100; x++) + { + exprEval(expr, &result); + + doSomething(k); + } ++
+++volatile EXPRTYPE k; + +/* Add variable to the list */ +exprValListAddAddress(list, "k", (EXPRTYPE*)&k); + +k = 0.0; + +/* Evaluate expression */ +for(int x = 0; x < 100; x++) + { + exprEval(expr, &result); + + doSomething(k); + } ++
This is an example application of this library. It is a + graphics program that calculates the color value of a + pixel based on it's X,Y co-ordinate. It uses a made-up + image library called graphic-lib. It uses faster variable + access by using the exprValListGetAddress function.
+Note that this codes has not actually been tested. See the + test applications (test and imagegen) for other examples.
+ ++++/* Include files */ +#include <stdio.h> +#include <stdlib.h> +#include <setjmp.h> +#include "graphiclib.h" +#include "expreval.h" + +char *transerr(int err) + { + /* Translate error code into message */ + } + +void gen_image(char *name, int w, int h, char *expr); + { + exprFuncList *f = NULL; + exprValList *v = NULL; + exprValList *c = NULL; + exprObj *o = NULL; + int x, y, err; + jmp_buf jumper; + int image; + EXPRTYPE *v_x, *v_y; + EXPRTYPE *v_r, *v_g, *v_b; + EXPRTYPE global_value; + + /* Error handling */ + err = setjmp(jumper); + if(err) + { + if(err != ID_IMAGENOERROR) + printf("Error %d occurred: %s\n", err, transerr(err)); + + exprFree(o); + exprFreeFuncList(f); + exprFreeValList(v); + exprFreeValList(c); + + image_free(image); + return; + } + + /* Set up lists */ + + /* Function list */ + err = exprFuncListCreate(&f); + if(err != EXPR_ERROR_NOERROR) + longjmp(jumper, err); + + err = exprFuncListInit(f); + if(err != EXPR_ERROR_NOERROR) + { + printf("Function list init error. Functions may not be available.\n"); + } + + /* Variable list */ + err = exprValListCreate(&v); + if(err != EXPR_ERROR_NOERROR) + longjmp(jumper, err); + + /* Constant list */ + err = exprValListCreate(&c); + if(err != EXPR_ERROR_NOERROR) + { + printf("Constants not available\n"); + } + else + { + err = exprValListInit(c); + if(err != EXPR_ERROR_NOERROR) + printf("Constant list init error. Constants may not be available.\n"); + } + + /* Create and parse the expression */ + + /* Create */ + err = exprCreate(&o, f, v, c, NULL, 0); + if(err != EXPR_ERROR_NOERROR) + longjmp(jumper, err); + + /* Parse expression */ + err = exprParse(o, expr); + if(err != EXPR_ERROR_NOERROR) + longjmp(jumper, err); + + + /* Create the image */ + image = image_create(w, h); + if(image == 0) + { + longjmp(jumper, ID_IMAGECREATEERROR); + } + + /* Add width and height to variable list */ + exprValListAdd(v, "w", (EXPRTYPE)w); + exprValListAdd(v, "h", (EXPRTYPE)h); + + /* Add x and y to the list */ + exprValListAdd(v, "x", 0.0); + exprValListAdd(v, "y", 0.0); + + /* Add r, g, and b to the list */ + exprValListAdd(v, "r", 0.0); + exprValListAdd(v, "g", 0.0); + exprValListAdd(b, "b", 0.0); + + /* Get addresses. Assume no error */ + exprValListGetAddress(v, "x", &v_x); + exprValListGetAddress(v, "y", &v_y); + + exprValListGetAddress(v, "r", &v_r); + exprValListGetAddress(v, "g", &v_g); + exprValListGetAddress(v, "g", &v_b); + + /* A way to add global variables that can be used by two different lists. */ + exprValListAddAddress(v, "global", &global_value); + /* exprValListAddAddress(v2, "global", &global_value); */ + + /* Also, exprValListAddAddress can be used to add variables directly. + Instead of: + + EXPRTYPE *a; + + exprValListAdd(v, "a", 0.0); + exprValListGetAddresss(v, "a", &a); + + You can do: + + EXPRTYPE a; + + exprValListAddAddresss(v, "a", &a); + + If you do this, you must ensure that the stack variable exists as long + as it is used by expression, otherwise it may cause a memory access + violation. */ + + + for(y = 0; y < h; y++) + { + for(x = 0; x < w; x++) + { + /* Directly set the x and y variables */ + *v_x = (EXPRTYPE)x; + *v_y = (EXPRTYPE)y; + + /* Eval expression, ignoring errors */ + exprEval(o); + + /* Set pixel, using variables directly */ + image_setpixel(image, x, y, (int)(*v_r), (int)(*v_g), (int)(*v_b)); + } + } + + /* Save image */ + image_save(image, name); + + /* Done */ + longjmp(jumper, ID_IMAGENOERROR); + } + +void main(void) + { + char name[MAXPATH] + char tmp[10]; + char expr[4096]; + int sx, sy; + + printf("Image name to save: "); + gets(name); + + printf("Image width: "); + gets(tmp); + sx = atoi(tmp); + + printf("Image height: "); + gets(tmp); + sy = atoi(tmp); + + printf("Color Expression (Use x, y, w, h Set r, g, b): "); + gets(expr); + + gen_image(name, sx, sy, expr); + } + ++
--Expressions have pretty much the same syntax as they - would have on paper, with the following exceptions: -
-
- -- Each expression must end with a semicolon. This - is because the expression string can actually - contain multiple expressions. The semicolon is - used to mark the end of the expression.
-
- Examples: --
-- 4*x+5;
-- y=5+2;g=4+6;
-- y=r*sin(a);x=r*cos(a);
-- The asterisk '*' must be used to multiply.
-
- Examples: --
-- y=5*6; Valid
-- g=(x+1)*(x-1); Valid
-- g=(x+1)(x-1); Invalid
-More than one expression may be contained within an expression string. - As shown above, each expression must end with a semicolon, even if - only one expression is in the string. The value of an expression - string is the value of the last expression in the string.
- Examlples: --
- -- g=7; Value: 7
-- k=z+1; Value: z+1
-- r=4;k=6;o=9+r-k; Value: 9+r-k
-Some functions may take reference parameters. These parameters are - references to other variables. You can mix reference parameters - with normal parameters. The order of the normal parameters must - remain the same and the order of the reference parameters must - remain the same.
- Examples: --
- -- min(1,2,3,4,&mval); &mval is a reference to a variable mval
-- min(1,2,&mval,3,4); You may mix them inside like this.
-- min(1,2,(&mval),3,4); You may not nest reference parameters in any way
-Expressions may also be nested with parenthesis.
- Examples: --
- -- y=sin(x-cos(5+max(4,5,6*x)));
-- 6+(5-2*(x+y));
-Expressions may also have whitespace characters and comments. - Whitespace characters such as newlines, linefeeds, carriage - returns, spaces, and tabs are ignored. Comments begin with - the pound sign '#' and end at the end of the line.
- Example: --
-#Set the x value -x = d * cos(r); - -#Set the y value -y = d * sin(r); -- - -If a variable is used in an expression, but that variable does not exist, - it is considered zero. If it does exist then its value is used instead. -
-Notice: An expression can NOT assign to a constant and an - expression can NOT use a constant as a reference parameter. -
-
--The order of operators are processed correctly in ExprEval. - The parameters to functions may be evaluated out of order, depending - on the function itself.
- - The following illustrates the order of operators: --
- -- -Operator -Direction -Example -- -Functions and Parenthesis -N/A -(x + 5) * sin(d); -- -Negation -Right to Left -y = -2; -- -Exponents -Left to Right -y = x ^ 2; -- -Multiplication and Division -Left to Right -x * 5 / y; -- -Addition and Subtraction -Left to Right -4 + 5 - 3; -- -Assignment -Right to Left -x = y = z = 0; -
- The following functions are provided with ExprEval: ---
- -- -Function -Min. Args -Max. Args -Min. Ref Args -Max. Ref Args -Result/Comment -- -abs(v) -1 -1 -0 -0 -Absolute value of v. -
- abs(-4.3) returns 4.3- -mod(v,d) -2 -2 -0 -0 -Remainder of v/d. -
- mod(5.2,2.5) return 0.2- -ipart(v) -1 -1 -0 -0 -The integer part of v. -
- ipart(3.2) returns 3- -fpart(v) -1 -1 -0 -0 -The fractional part of v. -
- fpart(3.2) returns 0.2- -min(v,...) -1 -None -0 -0 -The minimum number passed. -
- min(3,2,-5,-2,7) returns -5- - -max(v,...) -1 -None -0 -0 -The maximum number passed. -
- max(3,2,-5,-2,7) returns 7- -pow(a,b) -2 -2 -0 -0 -The value a raised to the power b. -
- pow(3.2,1.7) returns 3.21.7- - -sqrt(a) -1 -1 -0 -0 -The square root of a. - sqrt(16) returns 4 -- -sin(a) -1 -1 -0 -0 -The sine of a radians. -
- sin(1.5) returns around 0.997- -sinh(a) -1 -1 -0 -0 -The hyperbolic sine of a. -
- sinh(1.5) returns around 2.129- - -asin(a) -1 -1 -0 -0 -The arc-sine of a in radians. -
- asin(0.5) returns around 0.524- -cos(a) -1 -1 -0 -0 -The cosine of a radians. -
- cos(1.5) returns around 0.0707- -cosh(a) -1 -1 -0 -0 -The hyperbolic cosine of a. - cosh(1.5) returns around 2.352 -- - -acos(a) -1 -1 -0 -0 -The arc-cosine of a in radians. -
- acos(0.5) returns around 1.047- -tan(a) -1 -1 -0 -0 -The tangent of a radians. -
- tan(1.5) returns around 14.101- -tanh(a) -1 -1 -0 -0 -The hyperbolic tangent of a. - tanh(1.5) returns around 0.905 -- -atan(a) -1 -1 -0 -0 -The arc-tangent of a in radians. -
- atan(0.3) returns about 0.291- - -atan2(y,x) -2 -2 -0 -0 -The arc-tangent of y/x, with quadrant correction. -
- atan2(4,3) returns about 0.927- -log(a) -1 -1 -0 -0 -The base 10 logarithm of a. -
- log(100) returns 2- -pow10(a) -1 -1 -0 -0 -10 raised to the power of a. -
- pow10(2) returns 100- -ln(a) -1 -1 -0 -0 -The base e logarithm of a. -
- ln(2.8) returns around 1.030- -exp(a) -1 -1 -0 -0 -e raised to the power of a. -
- exp(2) returns around 7.389- - -logn(a,b) -2 -2 -0 -0 -The base b logarithm of a. -
- logn(16,2) returns 4- -ceil(a) -1 -1 -0 -0 -Rounds a up to the nearest integer. -
- ceil(3.2) returns 4- - -floor(a) -1 -1 -0 -0 -Rounds a down to the nearest integer. -
- floor(3.2) returns 3- -rand(&seed) -0 -0 -1 -1 -Returns a number between 0 up to but not including 1. -- -random(a,b,&seed) -2 -2 -1 -1 -Returns a number between a up to and including b. -- - -randomize(&seed) -0 -0 -1 -1 -Seed the random number generator with a value - based on the current time. -
- Return value is unknown- -deg(a) -1 -1 -0 -0 -Returns a radians converted to degrees. -
- deg(3.14) returns around 179.909- -rad(a) -1 -1 -0 -0 -Returns a degrees converted to radians. -
- rad(180) returns around 3.142- -recttopolr(x,y) -2 -2 -0 -0 -Returns the polar radius of the rectangular co-ordinates. -
- recttopolr(2,3) returns around 3.606- -recttopola(x,y) -2 -2 -0 -0 -Returns the polar angle (0...2PI) in radians of the rectangular co-ordinates. -
- recttopola(2,3) returns around 0.588- -poltorectx(r,a) -2 -2 -0 -0 -Returns the x rectangular co-ordinate of the polar - co-ordinates. -
- poltorectx(3,1.5) returns around 0.212- - -poltorecty(r,a) -2 -2 -0 -0 -Returns the y rectangular co-ordinate of the polar - co-ordinates. -
- poltorecty(3,1.5) returns around 2.992- -if(c,t,f) -3 -3 -0 -0 -Evaluates and returns t if c is not 0.0. - Else evaluates and returns f. -
- if(0.1,2.1,3.9) returns 2.1- -select(c,n,z[,p]) -3 -4 -0 -0 -Returns n if c is less than 0.0. Returns z - if c is 0.0. If c is greater than 0.0 and only - three arguments were passed, returns z. If c - is greater than 0.0 and four arguments were passed, - return p. -
- select(3,1,4,5) returns 5- -equal(a,b) -2 -2 -0 -0 -Returns 1.0 if a is equal to b. Else returns 0.0 -
- equal(3,2) returns 0.0- -above(a,b) -2 -2 -0 -0 -Returns 1.0 if a is above b. Else returns 0.0 -
- above(3,2) returns 1.0- - -below(a,b) -2 -2 -0 -0 -Returns 1.0 if a is below b. Else returns 0.0 -
- below(3,2) returns 0.0- -avg(a,...) -1 -None -0 -0 -Returns the average of the values passed. -
- avg(3,3,6) returns 4- -clip(v,min,max) -3 -3 -0 -0 -Clips v to the range from min to max. If v is less - than min, it returns min. If v is greater than - max it returns max. Otherwise it returns v. -
- clip(3,1,2) returns 2- -clamp(v,min,max) -3 -3 -0 -0 -Clamps v to the range from min to max, looping - if needed. -
- clamp(8.2,1.3,4.7) returns 1.4- -pntchange(side1old, side2old, side1new, side2new, oldpnt) -5 -5 -0 -0 -This is used to translate points from different - scale. It works no matter the orientation as long - as the sides are lined up correctly. -
- pntchange(-1,1,0,480,-0.5) returns 120 (x example)
- pntchange(-1,1,480,0,-0.5) returns 360 (y example)- - -poly(x,c1,...) -2 -None -0 -0 -This function calculates the polynomial. x is the value - to use in the polynomial. c1 and on are the coefficients. -
- poly(4,6,9,3,1,4) returns 2168
- same as 6*44 + 9*43 + 3*42 + 1*41 + 4*40- -and(a,b) -2 -2 -0 -0 -Returns 0.0 if either a or b are 0.0 Else returns 1.0 -
- and(2.1,0.0) returns 0.0- -or(a,b) -2 -2 -0 -0 -Returns 0.0 if both a and b are 0.0 Else returns 1.0 -
- or(2.1,0.0) returns 1.0- -not(a) -1 -1 -0 -0 -Returns 1.0 if a is 0.0 Else returns 0.0 -
- not(0.3) returns 0.0- -for(init,test,inc,a1,...) -4 -None -0 -0 -This function acts like a for loop in C. First init is - evaluated. Then test is evaluated. As long as the - test is not 0.0, the action statements (a1 to an) are - evaluated, the inc statement is evaluated, and the test - is evaluated again. The result is the result of the - final action statement. -
- for(x=0,below(x,11),x=x+1,y=y+x) returns 55.0 (if y was - initially 0.0)- - - -many(expr,...) -1 -None -0 -0 -This function treats many subexpressions as a single object - (function). It is mainly for the 'for' function. -
- for(many(j=5,k=1),above(j*k,0.001),many(j=j+5,k=k/2),0)
- The following constants are provided with ExprEval: ---
-- -Constant -Math Form -Value -- -M_E -e -2.7182818284590452354 -- -M_LOG2E -log2(e) -1.4426950408889634074 -- -M_LOG10E -log10(e) -0.43429448190325182765 -- -M_LN2 -ln(2) -0.69314718055994530942 -- -M_LN10 -ln(10) -2.30258509299404568402 -- -M_PI -π -3.14159265358979323846 -- -M_PI_2 -π/2 -1.57079632679489661923 -- -M_PI_4 -π/4 -0.78539816339744830962 -- -M_1_PI -1/π -0.31830988618379067154 -- -M_2_PI -2/π -0.63661977236758134308 -- -M_1_SQRTPI -1/√(π) -0.56418958354776 -- -M_2_SQRTPI -2/√(π) -1.12837916709551257390 -- -M_SQRT2 -√(2) -1.41421356237309504880 -- -M_1_SQRT2 -1/√(2) -0.70710678118654752440 -
- Application defined expression functions go here. ---
-- -Function -Min. Args -Max. Args -Min. Ref Args -Max. Ref Args -Result/Comment -- -- - - - - -
- Application defined expression constants go here. ---
-- -Constant -Math Form -Value -- -- - -
- Application defined expression variables go here. ---
-- -Variable -Math Form -Value -- -- - -
++Expressions have pretty much the same syntax as they + would have on paper, with the following exceptions: +
+
+ +- Each expression must end with a semicolon. This + is because the expression string can actually + contain multiple expressions. The semicolon is + used to mark the end of the expression.
+
+ Examples: ++
+- 4*x+5;
+- y=5+2;g=4+6;
+- y=r*sin(a);x=r*cos(a);
+- The asterisk '*' must be used to multiply.
+
+ Examples: ++
+- y=5*6; Valid
+- g=(x+1)*(x-1); Valid
+- g=(x+1)(x-1); Invalid
+More than one expression may be contained within an expression string. + As shown above, each expression must end with a semicolon, even if + only one expression is in the string. The value of an expression + string is the value of the last expression in the string.
+ Examlples: ++
+ +- g=7; Value: 7
+- k=z+1; Value: z+1
+- r=4;k=6;o=9+r-k; Value: 9+r-k
+Some functions may take reference parameters. These parameters are + references to other variables. You can mix reference parameters + with normal parameters. The order of the normal parameters must + remain the same and the order of the reference parameters must + remain the same.
+ Examples: ++
+ +- min(1,2,3,4,&mval); &mval is a reference to a variable mval
+- min(1,2,&mval,3,4); You may mix them inside like this.
+- min(1,2,(&mval),3,4); You may not nest reference parameters in any way
+Expressions may also be nested with parenthesis.
+ Examples: ++
+ +- y=sin(x-cos(5+max(4,5,6*x)));
+- 6+(5-2*(x+y));
+Expressions may also have whitespace characters and comments. + Whitespace characters such as newlines, linefeeds, carriage + returns, spaces, and tabs are ignored. Comments begin with + the pound sign '#' and end at the end of the line.
+ Example: ++
+#Set the x value +x = d * cos(r); + +#Set the y value +y = d * sin(r); ++ + +If a variable is used in an expression, but that variable does not exist, + it is considered zero. If it does exist then its value is used instead. +
+Notice: An expression can NOT assign to a constant and an + expression can NOT use a constant as a reference parameter. +
+
++The order of operators are processed correctly in ExprEval. + The parameters to functions may be evaluated out of order, depending + on the function itself.
+ + The following illustrates the order of operators: ++
+ ++ +Operator +Direction +Example ++ +Functions and Parenthesis +N/A +(x + 5) * sin(d); ++ +Negation +Right to Left +y = -2; ++ +Exponents +Left to Right +y = x ^ 2; ++ +Multiplication and Division +Left to Right +x * 5 / y; ++ +Addition and Subtraction +Left to Right +4 + 5 - 3; ++ +Assignment +Right to Left +x = y = z = 0; +
+ The following functions are provided with ExprEval: +++
+ ++ +Function +Min. Args +Max. Args +Min. Ref Args +Max. Ref Args +Result/Comment ++ +abs(v) +1 +1 +0 +0 +Absolute value of v. +
+ abs(-4.3) returns 4.3+ +mod(v,d) +2 +2 +0 +0 +Remainder of v/d. +
+ mod(5.2,2.5) return 0.2+ +ipart(v) +1 +1 +0 +0 +The integer part of v. +
+ ipart(3.2) returns 3+ +fpart(v) +1 +1 +0 +0 +The fractional part of v. +
+ fpart(3.2) returns 0.2+ +min(v,...) +1 +None +0 +0 +The minimum number passed. +
+ min(3,2,-5,-2,7) returns -5+ + +max(v,...) +1 +None +0 +0 +The maximum number passed. +
+ max(3,2,-5,-2,7) returns 7+ +pow(a,b) +2 +2 +0 +0 +The value a raised to the power b. +
+ pow(3.2,1.7) returns 3.21.7+ + +sqrt(a) +1 +1 +0 +0 +The square root of a. + sqrt(16) returns 4 ++ +sin(a) +1 +1 +0 +0 +The sine of a radians. +
+ sin(1.5) returns around 0.997+ +sinh(a) +1 +1 +0 +0 +The hyperbolic sine of a. +
+ sinh(1.5) returns around 2.129+ + +asin(a) +1 +1 +0 +0 +The arc-sine of a in radians. +
+ asin(0.5) returns around 0.524+ +cos(a) +1 +1 +0 +0 +The cosine of a radians. +
+ cos(1.5) returns around 0.0707+ +cosh(a) +1 +1 +0 +0 +The hyperbolic cosine of a. + cosh(1.5) returns around 2.352 ++ + +acos(a) +1 +1 +0 +0 +The arc-cosine of a in radians. +
+ acos(0.5) returns around 1.047+ +tan(a) +1 +1 +0 +0 +The tangent of a radians. +
+ tan(1.5) returns around 14.101+ +tanh(a) +1 +1 +0 +0 +The hyperbolic tangent of a. + tanh(1.5) returns around 0.905 ++ +atan(a) +1 +1 +0 +0 +The arc-tangent of a in radians. +
+ atan(0.3) returns about 0.291+ + +atan2(y,x) +2 +2 +0 +0 +The arc-tangent of y/x, with quadrant correction. +
+ atan2(4,3) returns about 0.927+ +log(a) +1 +1 +0 +0 +The base 10 logarithm of a. +
+ log(100) returns 2+ +pow10(a) +1 +1 +0 +0 +10 raised to the power of a. +
+ pow10(2) returns 100+ +ln(a) +1 +1 +0 +0 +The base e logarithm of a. +
+ ln(2.8) returns around 1.030+ +exp(a) +1 +1 +0 +0 +e raised to the power of a. +
+ exp(2) returns around 7.389+ + +logn(a,b) +2 +2 +0 +0 +The base b logarithm of a. +
+ logn(16,2) returns 4+ +ceil(a) +1 +1 +0 +0 +Rounds a up to the nearest integer. +
+ ceil(3.2) returns 4+ + +floor(a) +1 +1 +0 +0 +Rounds a down to the nearest integer. +
+ floor(3.2) returns 3+ +rand(&seed) +0 +0 +1 +1 +Returns a number between 0 up to but not including 1. ++ +random(a,b,&seed) +2 +2 +1 +1 +Returns a number between a up to and including b. ++ + +randomize(&seed) +0 +0 +1 +1 +Seed the random number generator with a value + based on the current time. +
+ Return value is unknown+ +deg(a) +1 +1 +0 +0 +Returns a radians converted to degrees. +
+ deg(3.14) returns around 179.909+ +rad(a) +1 +1 +0 +0 +Returns a degrees converted to radians. +
+ rad(180) returns around 3.142+ +recttopolr(x,y) +2 +2 +0 +0 +Returns the polar radius of the rectangular co-ordinates. +
+ recttopolr(2,3) returns around 3.606+ +recttopola(x,y) +2 +2 +0 +0 +Returns the polar angle (0...2PI) in radians of the rectangular co-ordinates. +
+ recttopola(2,3) returns around 0.588+ +poltorectx(r,a) +2 +2 +0 +0 +Returns the x rectangular co-ordinate of the polar + co-ordinates. +
+ poltorectx(3,1.5) returns around 0.212+ + +poltorecty(r,a) +2 +2 +0 +0 +Returns the y rectangular co-ordinate of the polar + co-ordinates. +
+ poltorecty(3,1.5) returns around 2.992+ +if(c,t,f) +3 +3 +0 +0 +Evaluates and returns t if c is not 0.0. + Else evaluates and returns f. +
+ if(0.1,2.1,3.9) returns 2.1+ +select(c,n,z[,p]) +3 +4 +0 +0 +Returns n if c is less than 0.0. Returns z + if c is 0.0. If c is greater than 0.0 and only + three arguments were passed, returns z. If c + is greater than 0.0 and four arguments were passed, + return p. +
+ select(3,1,4,5) returns 5+ +equal(a,b) +2 +2 +0 +0 +Returns 1.0 if a is equal to b. Else returns 0.0 +
+ equal(3,2) returns 0.0+ +above(a,b) +2 +2 +0 +0 +Returns 1.0 if a is above b. Else returns 0.0 +
+ above(3,2) returns 1.0+ + +below(a,b) +2 +2 +0 +0 +Returns 1.0 if a is below b. Else returns 0.0 +
+ below(3,2) returns 0.0+ +avg(a,...) +1 +None +0 +0 +Returns the average of the values passed. +
+ avg(3,3,6) returns 4+ +clip(v,min,max) +3 +3 +0 +0 +Clips v to the range from min to max. If v is less + than min, it returns min. If v is greater than + max it returns max. Otherwise it returns v. +
+ clip(3,1,2) returns 2+ +clamp(v,min,max) +3 +3 +0 +0 +Clamps v to the range from min to max, looping + if needed. +
+ clamp(8.2,1.3,4.7) returns 1.4+ +pntchange(side1old, side2old, side1new, side2new, oldpnt) +5 +5 +0 +0 +This is used to translate points from different + scale. It works no matter the orientation as long + as the sides are lined up correctly. +
+ pntchange(-1,1,0,480,-0.5) returns 120 (x example)
+ pntchange(-1,1,480,0,-0.5) returns 360 (y example)+ + +poly(x,c1,...) +2 +None +0 +0 +This function calculates the polynomial. x is the value + to use in the polynomial. c1 and on are the coefficients. +
+ poly(4,6,9,3,1,4) returns 2168
+ same as 6*44 + 9*43 + 3*42 + 1*41 + 4*40+ +and(a,b) +2 +2 +0 +0 +Returns 0.0 if either a or b are 0.0 Else returns 1.0 +
+ and(2.1,0.0) returns 0.0+ +or(a,b) +2 +2 +0 +0 +Returns 0.0 if both a and b are 0.0 Else returns 1.0 +
+ or(2.1,0.0) returns 1.0+ +not(a) +1 +1 +0 +0 +Returns 1.0 if a is 0.0 Else returns 0.0 +
+ not(0.3) returns 0.0+ +for(init,test,inc,a1,...) +4 +None +0 +0 +This function acts like a for loop in C. First init is + evaluated. Then test is evaluated. As long as the + test is not 0.0, the action statements (a1 to an) are + evaluated, the inc statement is evaluated, and the test + is evaluated again. The result is the result of the + final action statement. +
+ for(x=0,below(x,11),x=x+1,y=y+x) returns 55.0 (if y was + initially 0.0)+ + + +many(expr,...) +1 +None +0 +0 +This function treats many subexpressions as a single object + (function). It is mainly for the 'for' function. +
+ for(many(j=5,k=1),above(j*k,0.001),many(j=j+5,k=k/2),0)
+ The following constants are provided with ExprEval: +++
++ +Constant +Math Form +Value ++ +M_E +e +2.7182818284590452354 ++ +M_LOG2E +log2(e) +1.4426950408889634074 ++ +M_LOG10E +log10(e) +0.43429448190325182765 ++ +M_LN2 +ln(2) +0.69314718055994530942 ++ +M_LN10 +ln(10) +2.30258509299404568402 ++ +M_PI +π +3.14159265358979323846 ++ +M_PI_2 +π/2 +1.57079632679489661923 ++ +M_PI_4 +π/4 +0.78539816339744830962 ++ +M_1_PI +1/π +0.31830988618379067154 ++ +M_2_PI +2/π +0.63661977236758134308 ++ +M_1_SQRTPI +1/√(π) +0.56418958354776 ++ +M_2_SQRTPI +2/√(π) +1.12837916709551257390 ++ +M_SQRT2 +√(2) +1.41421356237309504880 ++ +M_1_SQRT2 +1/√(2) +0.70710678118654752440 +
+ Application defined expression functions go here. +++
++ +Function +Min. Args +Max. Args +Min. Ref Args +Max. Ref Args +Result/Comment ++ ++ + + + + +
+ Application defined expression constants go here. +++
++ +Constant +Math Form +Value ++ ++ + +
+ Application defined expression variables go here. +++
++ +Variable +Math Form +Value ++ ++ + +