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_;
82 diag(
"Multiple declaration of ", sym->
name);
89 if (level >= sym->
level) {
97 if (level < sym->level) {
99 }
else if (level > sym->
level) {
102 diag(sym->
name,
"has different values at same level");
120 Fprintf(stderr,
"Notice: %s is promoted from a PARAMETER to a STATE\n", sym->
name);
126 Fprintf(stderr,
"WARNING: %s is promoted from an ASSIGNED to a STATE\n", sym->
name);
132 Fprintf(stderr,
"Notice: %s is promoted from a PARAMETER to an ASSIGNED\n", sym->
name);
139 if (level < sym->level) {
150 if (
n->u.str == (
char*) 0)
164 if (
n->u.str == (
char*) 0)
188 diag(s->
name,
"can't be declared a parameter by default");
198 static int seestep = 0;
203 diag(
"Only one STEPPED variable can be defined", (
char*) 0);
217 diag(
"Maximum of 5 steps in a stepped variable", (
char*) 0);
229 int using_default_indep;
247 if (using_default_indep) {
248 using_default_indep = 0;
257 diag(
"Only one independent variable can be defined", (
char*) 0);
309 diag(
n->name,
"tolerance can be specified only for a STATE");
312 if (
n->u.str == (
char*) 0)
322 diag(
"START not legal except in STATE block", (
char*) 0);
341 if (
n->type != NAME &&
n->type != PRIME) {
342 diag(
n->name,
"can't be a STATE");
371 if (
q->itemtype ==
STRING && strcmp(
STR(
q),
"") == 0) {
374 }
else if (
q->next->itemtype ==
SYMBOL && strcmp(
SYM(
q->next)->name,
")") == 0) {
385 for (
q = q1;
q != q2;
q =
q->next) {
389 if (
q->next->itemtype ==
SYMBOL && strcmp(
SYM(
q->next)->name,
"(") == 0) {
406 if (q1->
next == q2) {
412 for (
q = q1->
next;
q != q2;
q =
q->next) {
413 if (strcmp(
SYM(
q)->
name,
",") != 0) {
424 Symbol *name1, *name2, *lagval;
437 diag(
"INDEPENDENT variable must be declared to process",
"the LAG statement");
440 diag(name1->
name,
"not a STATE or DEPENDENT variable");
443 diag(name2->
name,
"not a CONSTANT or PARAMETER");
461 "%s = lag(%s, %s, %s, %d);\n",
471 "%s = *lag(&(%s), %s, %s, 0);\n",
482 static int first = 1;
508 static int reset_fun_cnt = 0;
511 Sprintf(
buf,
"&_reset, &_freset%d,", reset_fun_cnt);
513 Sprintf(
buf,
"static double _freset%d;\n", reset_fun_cnt);
568 sprintf(
buf,
"\nstatic void %s(double*, Datum*, Datum*, NrnThread*);",
STR(
q));
572 "\nstatic void _check_table_thread(double* _p, Datum* _ppvar, Datum* _thread, "
573 "NrnThread* _nt, int _type) {\n");
598 from =
LST(
q =
q->next);
599 to =
LST(
q =
q->next);
600 ntab = atoi(
STR(
q =
q->next));
601 depend =
LST(
q =
q->next);
613 if (
type == FUNCTION1) {
615 diag(
"TABLE stmt in FUNCTION cannot have a table name list", (
char*) 0);
621 diag(
"TABLE stmt in PROCEDURE must have a table name list", (
char*) 0);
624 if (arglist->
next == arglist || arglist->
next->
next != arglist) {
625 diag(
"FUNCTION or PROCEDURE containing a TABLE stmt\n",
"must have exactly one argument");
639 if (
type == FUNCTION1) {
644 Sprintf(
buf,
"static double _n_%s(_threadargsprotocomma_ double _lv);\n",
fname);
652 Sprintf(
buf,
"static void _n_%s(_threadargsprotocomma_ double _lv);\n",
fname);
674 "static void _check_%s(double* _p, Datum* _ppvar, Datum* _thread, NrnThread* _nt) {\n",
689 " for (_i=0; _i < %d; _i++) {\
690 _t_%s[_i] = makevector(%d*sizeof(double)); }\n",
695 Sprintf(
buf,
" _t_%s = makevector(%d*sizeof(double));\n", s->
name, ntab + 1);
715 Sprintf(
buf,
" for (_i=0, _x=_tmin_%s; _i < %d; _x += _dx, _i++) {\n",
fname, ntab + 1);
717 if (
type == FUNCTION1) {
738 " for (_j = 0; _j < %d; _j++) { _t_%s[_j][_i] = %s[_j];\n}",
761 if (
type == FUNCTION1) {
774 "%s(double* _p, Datum* _ppvar, Datum* _thread, NrnThread* _nt, double %s) {",
783 Sprintf(
buf,
"\n#if 0\n_check_%s(_p, _ppvar, _thread, _nt);\n#endif\n",
fname);
786 if (
type == FUNCTION1) {
795 if (
type != FUNCTION1) {
801 if (
type == FUNCTION1) {
810 "_n_%s(double* _p, Datum* _ppvar, Datum* _thread, NrnThread* _nt, double %s){",
820 if (
type == FUNCTION1) {
829 if (
type != FUNCTION1) {
838 if (
type == FUNCTION1) {
845 " for (_j = 0; _j < %d; _j++) { %s[_j] = _xi;\n}",
856 if (
type == FUNCTION1) {
864 "for (_j = 0; _j < %d; _j++) { %s[_j] = _t_%s[_j][0];\n}",
878 if (
type == FUNCTION1) {
886 "for (_j = 0; _j < %d; _j++) { %s[_j] = _t_%s[_j][%d];\n}",
901 if (
type == FUNCTION1) {
904 "return _t_%s[_i] + (_xi - (double)_i)*(_t_%s[_i+1] - _t_%s[_i]);\n",
915 "for (_j = 0; _j < %d; _j++) {double *_t = _t_%s[_j];",
919 Sprintf(
buf,
"%s[_j] = _t[_i] + _theta*(_t[_i+1] - _t[_i]);}\n", s->
name);
922 "%s = _t_%s[_i] + _theta*(_t_%s[_i+1] - _t_%s[_i]);\n",
963 Sprintf(
buf,
"\nstatic double _hoc_%s(void* _vptr) {\n double _r;\n",
n->name);
965 Sprintf(
buf,
"\nstatic void _hoc_%s(void) {\n double _r;\n",
n->name);
970 double* _p; Datum* _ppvar; Datum* _thread; NrnThread* _nt;\n\
975 _p = ((Point_process*)_vptr)->_prop->param;\n\
976 _ppvar = ((Point_process*)_vptr)->_prop->dparam;\n\
977 _thread = _extcall_thread;\n\
978 _nt = (NrnThread*)((Point_process*)_vptr)->_vnt;\n\
983 if (_extcall_prop) {_p = _extcall_prop->param; _ppvar = _extcall_prop->dparam;}else{ _p = (double*)0; _ppvar = (Datum*)0; }\n\
984 _thread = _extcall_thread;\n\
985 _nt = nrn_threads;\n\
991 sprintf(
buf,
"\n#if 1\n _check_%s(_p, _ppvar, _thread, _nt);\n#endif\n",
n->name);
1005 for (
i = 0;
i <
n->varnum; ++
i) {
1008 if (
i + 1 <
n->varnum) {
1040 if (strcmp(
SYM(qname)->
name,
"nrn_pointing") == 0) {
1042 }
else if (strcmp(
SYM(qname)->
name,
"state_discontinuity") == 0) {
1044 if (blocktype == NETRECEIVE) {
1052 for (
q =
qexpr;
q != qpar2;
q =
q->next) {
1063 "Notice: Use of state_discontinuity is not thread safe except in a "
1064 "NET_RECEIVE block");
1066 if (!state_discon_list_) {
1067 state_discon_list_ =
newlist();
1074 }
else if (strcmp(
SYM(qname)->
name,
"net_send") == 0) {
1080 if (blocktype == NETRECEIVE) {
1082 }
else if (blocktype == INITIAL1) {
1083 Insertstr(qpar1->
next,
"_tqitem, (double*)0, _ppvar[1]._pvoid,");
1085 diag(
"net_send allowed only in INITIAL and NET_RECEIVE blocks", (
char*) 0);
1087 }
else if (strcmp(
SYM(qname)->
name,
"net_event") == 0) {
1088 net_event_seen_ = 1;
1089 if (blocktype == NETRECEIVE) {
1092 diag(
"net_event",
"only allowed in NET_RECEIVE block");
1094 }
else if (strcmp(
SYM(qname)->
name,
"net_move") == 0) {
1098 if (blocktype == NETRECEIVE) {
1101 diag(
"net_move",
"only allowed in NET_RECEIVE block");
1131 for (
i = 0,
q = qpar1->
next;
q != qpar2;
q =
q->next) {
1142 diag(
"FUNCTION_TABLE declaration must have one or more arguments:", s->
name);
1146 sprintf(
buf,
"return hoc_func_table(_ptable_%s, %d, _arg);\n", s->
name,
i);
1155 t->no_threadargs = 1;
1162 sprintf(
buf,
"{\n\thoc_spec_table(&_ptable_%s, %d);\n\treturn 0.;\n}\n", s->
name,
i);
1164 sprintf(
buf,
"\nstatic void* _ptable_%s = (void*)0;\n", s->
name);
1173 if (blocktype != NETRECEIVE) {
1174 diag(
"\"WATCH\" statement only allowed in NET_RECEIVE block", (
char*) 0);
1176 sprintf(
buf,
"\nstatic double _watch%d_cond(Point_process* _pnt) {\n", watch_seen_);
1180 "\t_p = _pnt->_prop->param; _ppvar = _pnt->_prop->dparam;\n\tv = "
1181 "NODEV(_pnt->node);\n return ");
1185 if (
SYM(dir)->
name[0] ==
'<') {
1196 "\nstatic void _watch_alloc(Datum* _ppvar) {\n"
1197 " Point_process* _pnt = (Point_process*)_ppvar[1]._pvoid;\n");
1200 " _nrn_watch_allocate(_watch_array, _watch%d_cond, %d, _pnt, %s);\n",
1207 " _nrn_watch_activate(_watch_array, _watch%d_cond, %d, _pnt, _watch_rm++, %s);\n",
1218 fprintf(stderr,
"Notice: %s\n", s);
1226 replacstr(q1,
"/* PROTECT */_NMODLMUTEXLOCK\n");
1227 q =
insertstr(q2->
next,
"\n _NMODLMUTEXUNLOCK /* end PROTECT */\n");
1233 static int toggle = 0;
1236 diag(
"MUTEXLOCK invoked after MUTEXLOCK", (
char*) 0);
1241 }
else if (on == 0) {
1243 diag(
"MUTEXUNLOCK invoked with no earlier MUTEXLOCK", (
char*) 0);
1250 diag(
"MUTEXUNLOCK not invoked after MUTEXLOCK", (
char*) 0);
static double abstol(void *v)
sprintf(buf, " if (secondorder) {\n" " int _i;\n" " for (_i = 0; _i < %d; ++_i) {\n" " _p[_slist%d[_i]] += dt*_p[_dlist%d[_i]];\n" " }}\n", numeqn, listnum, listnum)
static HocParmLimits limits[]
void printlist(List *list)
Symbol * ifnew_parminstall(char *name, char *num, char *units, char *limits)
#define ITERATE(itm, lst)
NMODL parser global flags / functions.
Item * lappendstr(List *list, char *str)
Item * linsertstr(List *list, char *str)
void movelist(Item *q1, Item *q2, List *s)
void freelist(List **plist)
Item * insertstr(Item *item, char *str)
void replacstr(Item *q, char *s)
char * stralloc(char *buf, char *rel)
Item * lappenditem(List *list, Item *item)
Item * lappendsym(List *list, Symbol *sym)
static struct table * table
void netrec_asgn(Item *varname, Item *equal, Item *expr, Item *lastok)
void vectorize_substitute(Item *q, char *str)
void hocfunc(Symbol *n, Item *qpar1, Item *qpar2)
void hocfunchack(Symbol *n, Item *qpar1, Item *qpar2, int hack)
void vectorize_use_func(Item *qname, Item *qpar1, Item *qexpr, Item *qpar2, int blocktype)
int const size_t const size_t n
static double remove(void *v)
void steppedinstall(Symbol *n, Item *q1, Item *q2, char *units)
void parm_array_install(Symbol *n, char *num, char *units, char *limits, int index)
void add_reset_args(Item *q)
static Symbol * last_func_using_table
void add_nrnthread_arg(Item *q)
static List * check_table_statements
static int func_arg_examine(Item *qpar, Item *qend)
void defarg(Item *q1, Item *q2)
Item * protect_astmt(Item *q1, Item *q2)
int check_tables_threads(List *p)
void vectorize_scan_for_func(Item *q1, Item *q2)
void depinstall(int type, Symbol *n, int index, char *from, char *to, char *units, Item *qs, int makeconst, char *abstol)
Item * vectorize_replacement_item(Item *)
void parminstall(Symbol *n, char *num, char *units, char *limits)
static List * check_table_thread_list
static long previous_subtype
void statdefault(Symbol *n, int index, char *units, Item *qs, int makeconst)
void function_table(Symbol *s, Item *qpar1, Item *qpar2, Item *qb1, Item *qb2)
void queue_stmt(Item *q1, Item *q2)
void table_massage(List *tablist, Item *qtype, Item *qname, List *arglist)
static char * previous_str
int type_change(Symbol *sym, int level)
void indepinstall(Symbol *n, char *from, char *to, char *with, Item *qstart, char *units, int scop)
void lag_stmt(Item *q1, int blocktype)
void nrnmutex(int on, Item *q)
void watchstmt(Item *par1, Item *dir, Item *par2, Item *flag, int blocktype)
void explicit_decl(int level, Item *q)
static const char * fname(const char *name)