Browse Source

Add new functions for .param expressions. vec() takes a string argument

and fetches a vector value from the current plot or "const".  var() is similar
but fetches an interpreter variable.
pre-master-46
Giles Atkinson 5 months ago
committed by Holger Vogt
parent
commit
8471e0902c
  1. 53
      src/frontend/numparam/xpressn.c

53
src/frontend/numparam/xpressn.c

@ -30,6 +30,7 @@ extern long dynsubst; /* see inpcom.c */
#define S_stop 4
static char* sort_idlist(char *list);
static char *string_expr(dico_t *, DSTRINGPTR, const char *, const char *);
static double
ternary_fcn(double conditional, double if_value, double else_value)
@ -83,23 +84,27 @@ limit(double nominal_val, double abs_variation)
return (nominal_val + (drand() > 0 ? abs_variation : -1. * abs_variation));
}
/* The list of built-in functions. Patch 'mathfunction', here to get more ...
* Function "vec" and following take a string argument and must come last.
*/
static const char *fmathS = /* all math functions */
"sqr sqrt sin cos exp ln arctan abs pow pwr max min int log log10 sinh cosh"
" tanh ternary_fcn agauss sgn gauss unif aunif limit ceil floor"
" asin acos atan asinh acosh atanh tan nint";
" asin acos atan asinh acosh atanh tan nint"
" vec var";
enum {
XFU_SQR = 1, XFU_SQRT, XFU_SIN, XFU_COS, XFU_EXP, XFU_LN, XFU_ARCTAN, XFU_ABS, XFU_POW, XFU_PWR, XFU_MAX, XFU_MIN, XFU_INT, XFU_LOG, XFU_LOG10, XFU_SINH, XFU_COSH,
XFU_TANH, XFU_TERNARY_FCN, XFU_AGAUSS, XFU_SGN, XFU_GAUSS, XFU_UNIF, XFU_AUNIF, XFU_LIMIT, XFU_CEIL, XFU_FLOOR,
XFU_ASIN, XFU_ACOS, XFU_ATAN, XFU_ASINH, XFU_ACOSH, XFU_ATANH, XFU_TAN, XFU_NINT
XFU_ASIN, XFU_ACOS, XFU_ATAN, XFU_ASINH, XFU_ACOSH, XFU_ATANH, XFU_TAN, XFU_NINT,
XFU_VEC, XFU_VAR // String arguments.
};
static double
mathfunction(int f, double z, double x)
/* the list of built-in functions. Patch 'fmath', here and near line 888 to get more ...*/
{
double y;
switch (f)
@ -946,6 +951,48 @@ formula(dico_t *dico, const char *s, const char *s_end, bool *perror)
if (kptr >= s_end) {
error = message(dico, "Closing \")\" not found.\n");
natom++; /* shut up other error message */
} else if (fu >= XFU_VEC) {
struct dvec *d;
char *vec_name;
/* Special case: function with string arg.
* Try to evaluate any string expression, else use directly.
*/
if (string_expr(dico, &tstr, s, kptr) != kptr)
pscopy(&tstr, s, kptr); // No, or not fully consumed.
vec_name = ds_get_buf(&tstr);
if (fu == XFU_VEC) {
struct plot *cplot, *prev;
d = vec_get(vec_name);
/* A simple name will be looked-up is the current plot.
* Try "const" if not found.
*/
if (!d && !strchr(vec_name, '.')) {
cplot = get_plot("const");
if (plot_cur != cplot) {
prev = plot_cur;
plot_cur = cplot;
d = vec_get(vec_name);
plot_cur = prev;
}
}
if (d && d->v_length > 0 && isreal(d))
u = d->v_realdata[0];
else
u = 0;
} else if (fu == XFU_VAR) {
if (!cp_getvar(vec_name, CP_REAL, &u, sizeof u))
u = 0;
}
state = S_atom;
s = kptr + 1;
fu = 0;
} else {
if (arg2 >= s) {
v = formula(dico, s, arg2, &error);

Loading…
Cancel
Save