Enhancing the hoc language is in fact very easy. First, you need
access to YODA's source code. Then, you should write your new hoc
builtin-function according a certain template. Suppose you want to add
a new function, which gets two parameters, adds them, and returns the
result (a slow way of saying a+b
...). Your implementation
could look like:
/*>--------------------------------------------------------------------------*/ double add(int i, Datum *p) /* * add its two parameters * * input: i: number of parameters actually passed * p: the arguments * * return: sum of argument 1 and argument 2 * -1: wrong number of arguments (not too clean...) */ /*<--------------------------------------------------------------------------*/ { if (i != 2) { cerr << ((i<2) ? "too few arguments\n" : "too many arguments\n"); return -1; } return p[0].val + p[1].val; }
Parameters are passed as an array of type Datum
, which is a
union to hold all types of objects from within the user-task. Its
definition is:
union Datum { /* interpreter stack type */ Symbol *sym; char *str; double val; };
For user applications, only the str
and val
components
are relevant. whenever an arithmetic value (e.g. a
variable or expression) is passed, val
is used to access the
actual value. If the function is called with a string argument
(remember: there are only string literals inside hoc), the str
component is used.
To make this function part of the built-in set of hoc functions, you
have to add it to the structure builtins_va[]
in init.cc
:
... extern double add(int i, Datum *p); /* declare your function */ ... static struct { /* Built-ins with varargs */ char *name; double (*func)(int, Datum *); } builtins_va[] = { { "printf", print}, { "histo", histo}, { "hfill", hfill}, ... { "update", update}, { "add", add}, /* <- your new function in the list */ { 0, 0 } };
Compile, and check out your new built-in with a simple hoc file like:
proc init() { c = add(1.234, 4.321); printf("sum is : %f\n", c); } ...