Modula-2 || Compiler & Tools || Library || Search Engine
TYPE Function; TYPE Real = REAL; TYPE StdFunc1 = PROCEDURE (Real) : Real; TYPE StdFunc2 = PROCEDURE (Real, Real) : Real;
VAR errpos: CARDINAL; (* error position in expr of ParseFunction *)
PROCEDURE InstallStdFunc1(funcname: ARRAY OF CHAR; stdfunc: StdFunc1); PROCEDURE InstallStdFunc2(funcname: ARRAY OF CHAR; stdfunc: StdFunc2); PROCEDURE InstallStdConst(constname: ARRAY OF CHAR; constval: Real);
PROCEDURE ParseFunction(expr: ARRAY OF CHAR; VAR func: Function) : BOOLEAN;
PROCEDURE FirstParam(func: Function); PROCEDURE NextParam(func: Function; VAR parname: ARRAY OF CHAR) : BOOLEAN;
PROCEDURE SetFuncParam(func: Function; parname: ARRAY OF CHAR; value: Real);
PROCEDURE EvalFunction(func: Function) : Real;
PROCEDURE DisposeFunction(VAR func: Function);
& instead of AND | instead of OR, and ~ instead of NOT.
CondExpression = Expression [ "?" CondExpression ":" CondExpression ] . Expression = SimpleExpression [ RelOp SimpleExpression ] . SimpleExpression = ["+"|"-"] Term { AddOp Term } . Term = Factor { MulOp Factor } . Factor = Constant | IDENT | FunctionCall | "~" Factor | "(" CondExpression ")" . FunctionCall = IDENT "(" CondExpression [ "," CondExpression ] ")" . RelOp = "=" | "#" | "<" | ">" | "<=" | ">=" . AddOp = "+" | "-" | "|" . MulOp = "*" | "/" | "&" .
The start symbol is CondExpression. Identifiers are sequences of letters and digits. The first character must be a letter.
ParseFunction parses expr and returns the function in func for further referencing. On errors ParseFunction returns FALSE after errpos has been set to the error position. Errors can result from
Each identifier not declared as a constant or a function (using InstallStdFunc1, InstallStdFunc2, or InstallStdConst) is considered to be a parameter. The value of a parameter is predefined to 0.0. FirstParam and NextParam give the parameter names in alphabetical order. Parameter values can be changed using SetFuncParam. EvalFunction evaluates the function with the parameters set previously. EvalFunction does not check for division by zero or any other operations which can result in a floating point exception.
DisposeFunction releases the storage associated with func.
To get a standard set of functions and constants StdFuncs should be imported.
VAR functxt, parname: ARRAY [0..63] OF CHAR; func: Function; val: Real; (* ... *) WriteString("func: "); ReadString(functxt); IF ParseFunction(functxt, func) THEN FirstParam(func); WHILE NextParam(func, parname) DO WriteString(parname); WriteString(" = "); ReadReal(val); SetFuncParam(func, parname, val); END; WriteReal(EvalFunction(func), 1); WriteLn; ELSE (* error at errpos *) END;
Instead of reading real values it is possible to read parameters as strings and to parse and evaluate them. This enables the user to give standard constants and expressions as parameter values (e.g. pi/2).
The only way to let functions call functions is to introduce standard functions via InstallStdFunc1 or InstallStdFunc2 which call EvalFunction.
Modula-2 || Compiler & Tools || Library || Search Engine