/*
* The Spar Library - modular math parser
* Copyright (C) 2000,2001 Davide Angelocola <davide178@inwind.it>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*
*/
#include <string.h>
#include <spar/sl_parser.h>
#include <spar/sl_math_library.h>
#include <spar/sl_io.h>
#include <spar/sl_sort.h>
#include <spar/sl_table.h>
sl_function sl_function_TABLE[] = {
/* one arg functions... */
{"sin", "sin", /* name to invoke this function */
SL_FUNCTION_WITH_ONE_ARG, /* how many arguments it gets */
SL_FUNCTION_CLASS_TRIG, /* math type (for help command) */
sl_sin, /* function to call (one arg) */
(sl_function_tp) NULL /* function to call (two args) */
}
,
{"cos", "cos",
SL_FUNCTION_WITH_ONE_ARG,
SL_FUNCTION_CLASS_TRIG,
sl_cos,
(sl_function_tp) NULL}
,
{"tan", "tan",
SL_FUNCTION_WITH_ONE_ARG,
SL_FUNCTION_CLASS_TRIG,
sl_tan,
(sl_function_tp) NULL}
,
{"cotan", "cos(x) / sin(x)",
SL_FUNCTION_WITH_ONE_ARG,
SL_FUNCTION_CLASS_TRIG,
sl_cotan,
(sl_function_tp) NULL}
,
{"asin", "arcsin",
SL_FUNCTION_WITH_ONE_ARG,
SL_FUNCTION_CLASS_ITRIG,
sl_arcsin,
(sl_function_tp) NULL}
,
{"acos", "arccos",
SL_FUNCTION_WITH_ONE_ARG,
SL_FUNCTION_CLASS_ITRIG,
sl_arccos,
(sl_function_tp) NULL}
,
{"atan", "arctan",
SL_FUNCTION_WITH_ONE_ARG,
SL_FUNCTION_CLASS_ITRIG,
sl_arctan,
(sl_function_tp) NULL}
,
{"sinh", "sinh",
SL_FUNCTION_WITH_ONE_ARG,
SL_FUNCTION_CLASS_HYPER,
sl_sinh,
(sl_function_tp) NULL}
,
{"cosh", "cosh",
SL_FUNCTION_WITH_ONE_ARG,
SL_FUNCTION_CLASS_HYPER,
sl_cosh,
(sl_function_tp) NULL}
,
{"tanh", "tanh",
SL_FUNCTION_WITH_ONE_ARG,
SL_FUNCTION_CLASS_HYPER,
sl_tanh,
(sl_function_tp) NULL}
,
{"asinh", "arcsinh",
SL_FUNCTION_WITH_ONE_ARG,
SL_FUNCTION_CLASS_HYPER,
sl_asinh,
(sl_function_tp) NULL}
,
{"acosh", "arccosh",
SL_FUNCTION_WITH_ONE_ARG,
SL_FUNCTION_CLASS_HYPER,
sl_acosh,
(sl_function_tp) NULL}
,
{"atanh", "arctanh",
SL_FUNCTION_WITH_ONE_ARG,
SL_FUNCTION_CLASS_HYPER,
sl_atanh,
(sl_function_tp) NULL}
,
{"exp", "exp",
SL_FUNCTION_WITH_ONE_ARG,
SL_FUNCTION_CLASS_EXP,
sl_exp,
(sl_function_tp) NULL}
,
{"expm1", "expm1",
SL_FUNCTION_WITH_ONE_ARG,
SL_FUNCTION_CLASS_EXP,
sl_expm1,
(sl_function_tp) NULL}
,
{"log", "log",
SL_FUNCTION_WITH_ONE_ARG,
SL_FUNCTION_CLASS_LOG,
sl_log,
(sl_function_tp) NULL}
,
{"log2", "log2",
SL_FUNCTION_WITH_ONE_ARG,
SL_FUNCTION_CLASS_LOG,
sl_log2,
(sl_function_tp) NULL}
,
{"log10", "log10",
SL_FUNCTION_WITH_ONE_ARG,
SL_FUNCTION_CLASS_LOG,
sl_log10,
(sl_function_tp) NULL}
,
{"log1p", "log1p",
SL_FUNCTION_WITH_ONE_ARG,
SL_FUNCTION_CLASS_LOG,
sl_log1p,
(sl_function_tp) NULL}
,
{"floor", "floor",
SL_FUNCTION_WITH_ONE_ARG,
SL_FUNCTION_CLASS_SPECIAL,
sl_floor,
(sl_function_tp) NULL}
,
{"ceil", "ceil",
SL_FUNCTION_WITH_ONE_ARG,
SL_FUNCTION_CLASS_SPECIAL,
sl_ceil,
(sl_function_tp) NULL}
,
{"sgn", "sgn",
SL_FUNCTION_WITH_ONE_ARG,
SL_FUNCTION_CLASS_SPECIAL,
sl_sgn,
(sl_function_tp) NULL}
,
{"abs", "abs",
SL_FUNCTION_WITH_ONE_ARG,
SL_FUNCTION_CLASS_SPECIAL,
sl_abs,
(sl_function_tp) NULL}
,
{"deg", "deg",
SL_FUNCTION_WITH_ONE_ARG,
SL_FUNCTION_CLASS_SPECIAL,
sl_deg,
(sl_function_tp) NULL}
,
{"rad", "rad",
SL_FUNCTION_WITH_ONE_ARG,
SL_FUNCTION_CLASS_SPECIAL,
sl_rad,
(sl_function_tp) NULL}
,
{"fat", "!",
SL_FUNCTION_WITH_ONE_ARG,
SL_FUNCTION_CLASS_SPECIAL,
sl_fat,
(sl_function_tp) NULL}
,
{"sum", "S",
SL_FUNCTION_WITH_ONE_ARG,
SL_FUNCTION_CLASS_SPECIAL,
sl_sum,
(sl_function_tp) NULL}
,
{"inv", "inv",
SL_FUNCTION_WITH_ONE_ARG,
SL_FUNCTION_CLASS_SPECIAL,
sl_inv,
(sl_function_tp) NULL}
,
{"max", "M",
SL_FUNCTION_WITH_TWO_ARG,
SL_FUNCTION_CLASS_SPECIAL,
(sl_function_p) NULL,
sl_max}
,
{"min", "m",
SL_FUNCTION_WITH_TWO_ARG,
SL_FUNCTION_CLASS_SPECIAL,
(sl_function_p) NULL,
sl_min}
,
{"sqrn", "x^(1/y)",
SL_FUNCTION_WITH_TWO_ARG,
SL_FUNCTION_CLASS_EXP,
(sl_function_p) NULL,
sl_sqrn}
,
{"hypot", "hypot",
SL_FUNCTION_WITH_TWO_ARG,
SL_FUNCTION_CLASS_ITRIG,
(sl_function_p) NULL,
sl_hypot}
,
{"mcd", "mcd",
SL_FUNCTION_WITH_TWO_ARG,
SL_FUNCTION_CLASS_SPECIAL,
(sl_function_p) NULL,
sl_mcd}
,
{"atan2", "arctan(y/x)",
SL_FUNCTION_WITH_TWO_ARG,
SL_FUNCTION_CLASS_ITRIG,
(sl_function_p) NULL,
sl_atan2}
,
{"expn", "expn",
SL_FUNCTION_WITH_TWO_ARG,
SL_FUNCTION_CLASS_EXP,
(sl_function_p) NULL,
sl_expn}
,
/*
* Function 'pow' and 'mod' removed
* replaced with the parser operators:
* '^' for pow
* '%' for mod
*
* uncomment if you want to call this operator also as function
*/
/*
{"pow", "pow",
SL_FUNCTION_WITH_TWO_ARG,
SL_FUNCTION_CLASS_EXP,
(sl_function_p) NULL,
sl_pow}
,
{"mod", "rem",
SL_FUNCTION_WITH_TWO_ARG,
SL_FUNCTION_CLASS_SPECIAL,
(sl_function_p) NULL,
sl_mod}
,
*/
{"isnan", "isnan",
SL_FUNCTION_WITH_ONE_ARG,
SL_FUNCTION_CLASS_SPECIAL,
sl_isnan,
(sl_function_tp) NULL}
,
{"isinf", "isinf",
SL_FUNCTION_WITH_ONE_ARG,
SL_FUNCTION_CLASS_SPECIAL,
sl_isinf,
(sl_function_tp) NULL}
,
{"isfinite", "finite",
SL_FUNCTION_WITH_ONE_ARG,
SL_FUNCTION_CLASS_SPECIAL,
sl_finite,
(sl_function_tp) NULL}
,
{"fib", "fibonacci",
SL_FUNCTION_WITH_ONE_ARG,
SL_FUNCTION_CLASS_SPECIAL,
sl_fib,
(sl_function_tp) NULL}
,
{"pow2", "2^x",
SL_FUNCTION_WITH_ONE_ARG,
SL_FUNCTION_CLASS_EXP,
sl_pow2,
(sl_function_tp) NULL}
,
{"sqrt", "square root",
SL_FUNCTION_WITH_ONE_ARG,
SL_FUNCTION_CLASS_EXP,
sl_sqrt,
(sl_function_tp) NULL}
,
{"cbrt", "cube root",
SL_FUNCTION_WITH_ONE_ARG,
SL_FUNCTION_CLASS_EXP,
sl_cbrt,
(sl_function_tp) NULL}
,
};
const char *sl_function_type_TABLE[SL_FUNCTION_CLASS_COUNTER] = {
"Trigonometric",
"Inverse Trigonometric",
"Exponential",
"Logarithm",
"Hyperbolic",
"Special",
"User_defined"
};
const char *sl_function_args_TABLE[SL_FUNCTION_WITH_COUNTER] = {
"()",
"(x)",
"(x,y)",
"(...)"
};
const int SL_FUNCTION_TABLE_LENGTH =
sizeof (sl_function_TABLE) / sizeof (sl_function_TABLE[0]);
int
__function_cmp (const sl_function * f1, const sl_function * f2)
{
return strncmp (f1->name, f2->name, SL_IDENTIFIER_LENGHT);
}
int
sl_function_init (void)
{
return sl_qsort (sl_function_TABLE,
SL_FUNCTION_TABLE_LENGTH,
sizeof (sl_function),
(int (*)(const void *, const void *)) __function_cmp);
}
int
sl_function_check (const char *name)
{
sl_function *r;
r =
sl_bsearch (name, sl_function_TABLE, SL_FUNCTION_TABLE_LENGTH,
sizeof (sl_function),
(int (*)(const void *, const void *)) __function_cmp);
if (r)
return ((int) r - (int) sl_function_TABLE) / sizeof (sl_function);
else
return SL_SYMBOL_NOT_FOUND;
}
void
sl_function_print_all (void)
{
sl_table_column function_cols[] = {
{"Name", SL_IDENTIFIER_LENGHT},
{"Arg", 4},
{"Math Form", SL_MESSAGE_LENGHT},
{{0}}
};
sl_table_create ("Functions",
function_cols,
SL_FUNCTION_TABLE_LENGTH, sl_table_print_function);
}
int
sl_function_make_help (const char *name, sl_function_help * tmp)
{
int fnc_code = sl_function_check (name);
if (fnc_code != SL_SYMBOL_NOT_FOUND)
{
strcat (strcpy (tmp->math, sl_function_TABLE[fnc_code].math),
sl_function_args_TABLE[sl_function_TABLE[fnc_code].args]);
strcat (strcpy
(tmp->type,
sl_function_type_TABLE[sl_function_TABLE[fnc_code].type]),
" function");
strcpy (tmp->name, sl_function_TABLE[fnc_code].name);
tmp->args = sl_function_TABLE[fnc_code].args;
return 1;
}
return 0;
}
double
sl_function_run (const char *name, double argv[])
{
sl_function *r;
r =
sl_bsearch ((const void *) name, sl_function_TABLE,
SL_FUNCTION_TABLE_LENGTH, sizeof (sl_function),
(int (*)(const void *, const void *)) __function_cmp);
switch (r->args)
{
case SL_FUNCTION_WITH_ONE_ARG:
return r->func (argv[0]);
break;
case SL_FUNCTION_WITH_TWO_ARG:
return r->func2 (argv[0], argv[1]);
break;
case SL_FUNCTION_WITH_VAR_ARG:
case SL_FUNCTION_WITH_COUNTER:
break;
}
return 0.0;
}
sl_function_args_t
sl_function_get_argc (int code)
{
return sl_function_TABLE[code].args;
}
const char *
sl_function_get_name (int code)
{
return sl_function_TABLE[code].name;
}
syntax highlighted by Code2HTML, v. 0.9.1