1 #include <../../nmodlconf.h> 21 extern List* state_discon_list_;
22 extern int net_send_seen_;
23 extern int net_event_seen_;
24 extern int watch_seen_;
83 diag(
"Multiple declaration of ", sym->
name);
90 if (level >= sym->
level) {
98 if (level < sym->level) {
100 }
else if (level > sym->
level) {
103 diag(sym->
name,
"has different values at same level");
121 Fprintf(stderr,
"Notice: %s is promoted from a PARAMETER to a STATE\n", sym->
name);
127 Fprintf(stderr,
"WARNING: %s is promoted from an ASSIGNED to a STATE\n", sym->
name);
133 Fprintf(stderr,
"Notice: %s is promoted from a PARAMETER to an ASSIGNED\n", sym->
name);
140 if (level < sym->level) {
152 if (n->
u.
str == (
char *) 0)
157 Sprintf(buf,
"[%d]\n%s\n%s\n%s\n", index, num, units, limits);
167 if (n->
u.
str == (
char *) 0)
170 Sprintf(buf,
"\n%s\n%s\n%s\n", num, units, limits);
191 if (scop_indep == indepsym || s != scop_indep) {
192 diag(s->
name,
"can't be declared a parameter by default");
203 static int seestep = 0;
208 diag(
"Only one STEPPED variable can be defined", (
char *) 0);
222 diag(
"Maximum of 5 steps in a stepped variable",
235 int using_default_indep;
248 if (using_default_indep) {
249 using_default_indep = 0;
259 diag(
"Only one independent variable can be defined", (
char *) 0);
273 if (n != scop_indep) {
274 Sprintf(buf,
"\n%s*%s(%s)\n%s\n", from, to, with, units);
283 Sprintf(buf,
"\n%s*%s(%s)\n%s\n", from, to, with, units);
302 if (!type && strlen(abstol)>0) {
303 printf(
"abstol = |%s|\n", abstol);
304 diag(n->
name,
"tolerance can be specified only for a STATE");
307 if (n->
u.
str == (
char *) 0)
317 diag(
"START not legal except in STATE block", (
char *) 0);
321 Sprintf(buf,
"[%d]\n%s%c%s\n%s\n%s\n", index, from, c, to, units, abstol);
325 Sprintf(buf,
"\n%s%c%s\n%s\n%s\n", from, c, to, units, abstol);
337 if (n->
type != NAME && n->
type != PRIME) {
381 for (q = q1; q != q2; q = q->
next) {
402 if (q1->
next == q2) {
408 for (q = q1->
next; q != q2; q = q->
next) {
409 if (strcmp(
SYM(q)->
name,
",") != 0) {
420 Symbol *name1, *name2, *lagval;
433 diag(
"INDEPENDENT variable must be declared to process",
434 "the LAG statement");
437 diag(name1->
name,
"not a STATE or DEPENDENT variable");
440 diag(name2->
name,
"not a CONSTANT or PARAMETER");
498 static int reset_fun_cnt=0;
501 Sprintf(
buf,
"&_reset, &_freset%d,", reset_fun_cnt);
503 Sprintf(
buf,
"static double _freset%d;\n", reset_fun_cnt);
540 if (check_table_statements) {
557 if (check_table_thread_list) {
558 ITERATE(q, check_table_thread_list) {
559 sprintf(
buf,
"\nstatic void %s(double*, Datum*, Datum*, NrnThread*);",
STR(q));
562 lappendstr(p,
"\nstatic void _check_table_thread(double* _p, Datum* _ppvar, Datum* _thread, NrnThread* _nt, int _type) {\n");
563 ITERATE(q, check_table_thread_list) {
585 last_func_using_table = fsym;
587 table =
LST(q = tablist->
next);
592 type =
SYM(qtype)->type;
595 if (!check_table_statements) {
596 check_table_statements =
newlist();
600 sprintf(
buf,
"_check_%s(_p, _ppvar, _thread, _nt);\n", fname);
603 if (type == FUNCTION1) {
605 diag(
"TABLE stmt in FUNCTION cannot have a table name list", (
char *)0);
611 diag(
"TABLE stmt in PROCEDURE must have a table name list", (
char *)0);
614 if (arglist->
next == arglist || arglist->
next->
next != arglist) {
615 diag(
"FUNCTION or PROCEDURE containing a TABLE stmt\n",
616 "must have exactly one argument");
630 if (type == FUNCTION1) {
632 Sprintf(
buf,
"static double _n_%s(double);\n", fname);
635 Sprintf(
buf,
"static double _n_%s(_threadargsprotocomma_ double _lv);\n", fname);
640 Sprintf(
buf,
"static void _n_%s(double);\n", fname);
643 Sprintf(
buf,
"static void _n_%s(_threadargsprotocomma_ double _lv);\n", fname);
650 Sprintf(
buf,
"static double _mfac_%s, _tmin_%s;\n",
655 if (!check_table_thread_list) {
656 check_table_thread_list =
newlist();
660 Sprintf(
buf,
"static void _check_%s();\n", fname);
663 Sprintf(
buf,
"static void _check_%s() {\n", fname);
665 Sprintf(
buf,
"static void _check_%s(double* _p, Datum* _ppvar, Datum* _thread, NrnThread* _nt) {\n", fname);
679 _t_%s[_i] = makevector(%d*sizeof(double)); }\n", s->
araydim, s->
name, ntab+1);
681 Sprintf(
buf,
" _t_%s = makevector(%d*sizeof(double));\n",
688 Sprintf(
buf,
" if (_sav_%s != %s) { _maktable = 1;}\n",
701 Sprintf(
buf,
" _dx = (_tmax - _tmin_%s)/%d.; _mfac_%s = 1./_dx;\n",
704 Sprintf(
buf,
" for (_i=0, _x=_tmin_%s; _i < %d; _x += _dx, _i++) {\n",
707 if (type == FUNCTION1) {
713 Sprintf(
buf,
" _t_%s[_i] = _f_%s(_p, _ppvar, _thread, _nt, _x);\n", s->
name, fname);
721 Sprintf(
buf,
" _f_%s(_p, _ppvar, _thread, _nt, _x);\n", fname);
727 Sprintf(
buf,
" for (_j = 0; _j < %d; _j++) { _t_%s[_j][_i] = %s[_j];\n}",
748 if (type == FUNCTION1) {
761 Sprintf(
buf,
"%s(double* _p, Datum* _ppvar, Datum* _thread, NrnThread* _nt, double %s) {",
769 Sprintf(
buf,
"\n#if 0\n_check_%s(_p, _ppvar, _thread, _nt);\n#endif\n", fname);
772 if (type == FUNCTION1) {
778 Sprintf(
buf,
"_n_%s(_p, _ppvar, _thread, _nt, %s);\n", fname, arg->
name);
781 if (type != FUNCTION1) {
787 if (type == FUNCTION1) {
796 Sprintf(
buf,
"_n_%s(double* _p, Datum* _ppvar, Datum* _thread, NrnThread* _nt, double %s){",
805 if (type == FUNCTION1) {
811 Sprintf(
buf,
"_f_%s(_p, _ppvar, _thread, _nt, %s);", fname, arg->
name);
814 if (type != FUNCTION1) {
820 Sprintf(
buf,
"_xi = _mfac_%s * (%s - _tmin_%s);\n",
821 fname, arg->
name, fname);
824 if (type == FUNCTION1) {
830 Sprintf(
buf,
" for (_j = 0; _j < %d; _j++) { %s[_j] = _xi;\n}",
840 if (type == FUNCTION1) {
847 Sprintf(
buf,
"for (_j = 0; _j < %d; _j++) { %s[_j] = _t_%s[_j][0];\n}",
859 if (type == FUNCTION1) {
866 Sprintf(
buf,
"for (_j = 0; _j < %d; _j++) { %s[_j] = _t_%s[_j][%d];\n}",
878 if (type == FUNCTION1) {
880 Sprintf(
buf,
"return _t_%s[_i] + (_xi - (double)_i)*(_t_%s[_i+1] - _t_%s[_i]);\n",
888 Sprintf(
buf,
"for (_j = 0; _j < %d; _j++) {double *_t = _t_%s[_j];",
891 Sprintf(
buf,
"%s[_j] = _t[_i] + _theta*(_t[_i+1] - _t[_i]);}\n",
894 Sprintf(
buf,
"%s = _t_%s[_i] + _theta*(_t_%s[_i+1] - _t_%s[_i]);\n",
934 Sprintf(
buf,
"\nstatic double _hoc_%s(void* _vptr) {\n double _r;\n", n->
name);
936 Sprintf(
buf,
"\nstatic void _hoc_%s(void) {\n double _r;\n", n->
name);
940 double* _p; Datum* _ppvar; Datum* _thread; NrnThread* _nt;\n\ 944 _p = ((Point_process*)_vptr)->_prop->param;\n\ 945 _ppvar = ((Point_process*)_vptr)->_prop->dparam;\n\ 946 _thread = _extcall_thread;\n\ 947 _nt = (NrnThread*)((Point_process*)_vptr)->_vnt;\n\ 951 if (_extcall_prop) {_p = _extcall_prop->param; _ppvar = _extcall_prop->dparam;}else{ _p = (double*)0; _ppvar = (Datum*)0; }\n\ 952 _thread = _extcall_thread;\n\ 953 _nt = nrn_threads;\n\ 957 if (n == last_func_using_table) {
959 sprintf(
buf,
"\n#if 1\n _check_%s(_p, _ppvar, _thread, _nt);\n#endif\n", n->
name);
973 for (i=0; i < n->
varnum; ++
i) {
1008 if (strcmp(
SYM(qname)->
name,
"nrn_pointing") == 0) {
1010 }
else if (strcmp(
SYM(qname)->
name,
"state_discontinuity") == 0) {
1012 if (blocktype == NETRECEIVE) {
1020 for (q = qexpr; q != qpar2; q = q->
next) {
1030 fprintf(stderr,
"Notice: Use of state_discontinuity is not thread safe except in a NET_RECEIVE block");
1032 if (!state_discon_list_) {
1033 state_discon_list_ =
newlist();
1040 }
else if (strcmp(
SYM(qname)->
name,
"net_send") == 0) {
1046 if (blocktype == NETRECEIVE) {
1048 }
else if (blocktype == INITIAL1){
1049 Insertstr(qpar1->
next,
"_tqitem, (double*)0, _ppvar[1]._pvoid,");
1051 diag(
"net_send allowed only in INITIAL and NET_RECEIVE blocks", (
char*)0);
1053 }
else if (strcmp(
SYM(qname)->
name,
"net_event") == 0) {
1054 net_event_seen_ = 1;
1055 if (blocktype == NETRECEIVE) {
1058 diag(
"net_event",
"only allowed in NET_RECEIVE block");
1060 }
else if (strcmp(
SYM(qname)->
name,
"net_move") == 0) {
1064 if (blocktype == NETRECEIVE) {
1067 diag(
"net_move",
"only allowed in NET_RECEIVE block");
1096 for (i=0, q=qpar1->
next; q != qpar2; q = q->
next) {
1107 diag(
"FUNCTION_TABLE declaration must have one or more arguments:",
1112 sprintf(
buf,
"return hoc_func_table(_ptable_%s, %d, _arg);\n", s->
name, i);
1121 t->no_threadargs = 1;
1128 sprintf(
buf,
"{\n\thoc_spec_table(&_ptable_%s, %d);\n\treturn 0.;\n}\n",
1131 sprintf(
buf,
"\nstatic void* _ptable_%s = (void*)0;\n", s->
name);
1141 if (blocktype != NETRECEIVE) {
1142 diag(
"\"WATCH\" statement only allowed in NET_RECEIVE block", (
char*)0);
1144 sprintf(
buf,
"\nstatic double _watch%d_cond(Point_process* _pnt) {\n",
1148 sprintf(
buf,
"\t_p = _pnt->_prop->param; _ppvar = _pnt->_prop->dparam;\n\tv = NODEV(_pnt->node);\n return ");
1152 if (
SYM(dir)->
name[0] ==
'<') {
1163 "\nstatic void _watch_alloc(Datum* _ppvar) {\n" 1164 " Point_process* _pnt = (Point_process*)_ppvar[1]._pvoid;\n" 1168 " _nrn_watch_allocate(_watch_array, _watch%d_cond, %d, _pnt, %s);\n",
1169 watch_seen_, watch_seen_,
STR(flag));
1173 " _nrn_watch_activate(_watch_array, _watch%d_cond, %d, _pnt, _watch_rm++, %s);\n",
1174 watch_seen_, watch_seen_,
STR(flag));
1182 fprintf(stderr,
"Notice: %s\n", s);
1190 replacstr(q1,
"/* PROTECT */_NMODLMUTEXLOCK\n");
1191 q =
insertstr(q2->
next,
"\n _NMODLMUTEXUNLOCK /* end PROTECT */\n");
1197 static int toggle = 0;
1200 diag(
"MUTEXLOCK invoked after MUTEXLOCK", (
char*)0);
1205 }
else if (on == 0) {
1207 diag(
"MUTEXUNLOCK invoked with no earlier MUTEXLOCK", (
char*)0);
1214 diag(
"MUTEXUNLOCK not invoked after MUTEXLOCK", (
char*)0);
char * stralloc(char *buf, char *rel)
static int func_arg_examine(Item *qpar, Item *qend)
void hocfunc(Symbol *n, Item *qpar1, Item *qpar2)
static HocParmLimits limits[]
void nrnmutex(int on, Item *q)
void parminstall(Symbol *n, char *num, char *units, char *limits)
#define ITERATE(itm, lst)
static char * previous_str
void table_massage(List *tablist, Item *qtype, Item *qname, List *arglist)
Item * lappendsym(List *list, Symbol *sym)
static long previous_subtype
int check_tables_threads(List *p)
void netrec_asgn(Item *varname, Item *equal, Item *expr, Item *lastok)
void add_reset_args(Item *q)
void vectorize_use_func(Item *qname, Item *qpar1, Item *qexpr, Item *qpar2, int blocktype)
sprintf(buf," if (secondorder) {\ " int _i;\" " for(_i=0;_i< %d;++_i) {\" " _p[_slist%d[_i]]+=dt *_p[_dlist%d[_i]];\" " }}\", numeqn, listnum, listnum)
static List * check_table_statements
void indepinstall(Symbol *n, char *from, char *to, char *with, Item *qstart, char *units, int scop)
static double abstol(void *v)
Symbol * ifnew_parminstall(char *name, char *num, char *units, char *limits)
int const size_t const size_t n
void lag_stmt(Item *q1, int blocktype)
void movelist(Item *q1, Item *q2, List *s)
void statdefault(Symbol *n, int index, char *units, Item *qs, int makeconst)
void explicit_decl(int level, Item *q)
void depinstall(int type, Symbol *n, int index, char *from, char *to, char *units, Item *qs, int makeconst, char *abstol)
Item * lappendstr(List *list, char *str)
static List * check_table_thread_list
void vectorize_substitute(Item *q, char *str)
void watchstmt(Item *par1, Item *dir, Item *par2, Item *flag, int blocktype)
static const char * fname(const char *name)
Item * linsertstr(List *list, char *str)
fprintf(stderr, "Don't know the location of params at %p\, pp)
Item * protect_astmt(Item *q1, Item *q2)
int type_change(Symbol *sym, int level)
void add_nrnthread_arg(Item *q)
NMODL parser global flags / functions.
void queue_stmt(Item *q1, Item *q2)
Item * lappenditem(List *list, Item *item)
void parm_array_install(Symbol *n, char *num, char *units, char *limits, int index)
void function_table(Symbol *s, Item *qpar1, Item *qpar2, Item *qb1, Item *qb2)
Item * insertstr(Item *item, char *str)
void freelist(List **plist)
void vectorize_scan_for_func(Item *q1, Item *q2)
void printlist(List *list)
static Symbol * last_func_using_table
void replacstr(Item *q, char *s)
void defarg(Item *q1, Item *q2)
static struct table * table
void steppedinstall(Symbol *n, Item *q1, Item *q2, char *units)
Item * vectorize_replacement_item(Item *)
void hocfunchack(Symbol *n, Item *qpar1, Item *qpar2, int hack)