NEURON
discrete.cpp
Go to the documentation of this file.
1 #include <../../nmodlconf.h>
2 /* /local/src/master/nrn/src/nmodl/discrete.c,v 4.1 1997/08/30 20:45:19 hines Exp */
3 /*
4 discrete.c,v
5  * Revision 4.1 1997/08/30 20:45:19 hines
6  * cvs problem with branches. Latest nmodl stuff should now be a top level
7  *
8  * Revision 4.0.1.1 1997/08/08 17:23:42 hines
9  * nocmodl version 4.0.1
10  *
11  * Revision 4.0 1997/08/08 17:06:07 hines
12  * proper nocmodl version number
13  *
14  * Revision 1.1.1.1 1994/10/12 17:21:35 hines
15  * NEURON 3.0 distribution
16  *
17  * Revision 9.5 90/07/18 07:59:36 hines
18  * define for arrays now (p + n) instead of &p[n]. This allows the c file
19  * to have arrays that look like a[i] instead of *(a + i).
20  *
21  * Revision 8.1 90/01/03 16:13:01 mlh
22  * discrete array variables had their for loops switched.
23  *
24  * Revision 8.0 89/09/22 17:26:05 nfh
25  * Freezing
26  *
27  * Revision 7.0 89/08/30 13:31:32 nfh
28  * Rev 7 is now Experimental; Rev 6 is Testing
29  *
30  * Revision 6.0 89/08/14 16:26:16 nfh
31  * Rev 6.0 is latest of 4.x; now the Experimental version
32  *
33  * Revision 4.0 89/07/24 17:02:45 nfh
34  * Freezing rev 3. Rev 4 is now Experimental
35  *
36  * Revision 3.3 89/07/21 09:28:14 mlh
37  * Discrete equitions evaluated at time given by independent variable
38  * in the sense that the state on the left hand side refers to state(t)
39  * and explicit dependence on t works naturally.
40  *
41  * Revision 1.3 89/07/21 09:14:08 mlh
42  * Discrete equations evaluated at time given by ndependent variable
43  * in the sense that state on the left hand side refers to state(t)
44  * and explicit dependence on t works naturally. This is done by
45  * incrementing t before calling discrete block and updating the
46  * history at the beginning instead of the end.
47  *
48  * Revision 1.2 89/07/12 13:57:21 mlh
49  * state@1 now refers to fianl value at previous step
50  * state@0 is a syntax error
51  *
52  * Revision 1.1 89/07/06 14:48:27 mlh
53  * Initial revision
54  *
55 */
56 
57 #include <stdlib.h>
58 #include "modl.h"
59 #include "parse1.hpp"
60 #include "symbol.h"
61 
62 void disc_var_seen(Item* q1, Item* q2, Item* q3, int array) /*NAME '@' NUMBER --- array flag*/
63 {
64  Symbol* s;
65  int num;
66 
67  num = atoi(STR(q3));
68  s = SYM(q1);
69  if (num < 1) {
70  diag("Discrete variable must have @index >= 1", (char*) 0);
71  }
72  num--;
73  if (!(s->subtype & STAT)) {
74  diag(s->name, "must be a STATE for use as discrete variable");
75  }
76  if (array && !(s->subtype & ARRAY)) {
77  diag(s->name, "must be a scalar discrete variable");
78  }
79  if (!array && (s->subtype & ARRAY)) {
80  diag(s->name, "must be an array discrete variable");
81  }
82  if (s->discdim <= num) {
83  s->discdim = num + 1;
84  }
85  Sprintf(buf, "__%s", s->name);
86  replacstr(q1, buf);
87  remove(q2);
88  Sprintf(buf, "[%d]", num);
89  replacstr(q3, buf);
90 }
91 
92 void massagediscblk(Item* q1, Item* q2, Item* q3, Item* q4) /*DISCRETE NAME stmtlist '}'*/
93 {
94  int i;
95  Symbol* s;
96  Item* qs;
97 
98  replacstr(q1, "int");
99  Insertstr(q3, "()\n{\n");
100  Insertstr(q4, "}\n");
101  SYM(q2)->subtype |= DISCF;
102  SYMITER(NAME) if (s->subtype & STAT && s->used && s->discdim) {
103  if (s->subtype & ARRAY) {
104  Sprintf(buf,
105  "{int _i, _j; for (_j=%d; _j >=0; _j--) {\n\
106 for (_i=%d; _i>0; _i--) __%s[_i][_j] = __%s[_i-1][_j];\n\
107  __%s[0][_j] = %s[_j];\n\
108 }}\n",
109  s->araydim - 1,
110  s->discdim - 1,
111  s->name,
112  s->name,
113  s->name,
114  s->name);
115  } else {
116  Sprintf(buf,
117  "{int _i; for (_i=%d; _i>0; _i--) __%s[_i] = __%s[_i-1];\n\
118  __%s[0] = %s;\n}\n",
119  s->discdim - 1,
120  s->name,
121  s->name,
122  s->name,
123  s->name);
124  }
125  Insertstr(q3, buf);
126  s->used = 0;
127  }
128  /*initialization and declaration done elsewhere*/
129  movelist(q1, q4, procfunc);
130 }
131 
133  int i;
134  Item* qs;
135  Symbol* s;
136  SYMITER(NAME) if (s->subtype & STAT && s->discdim) {
137  if (s->subtype & ARRAY) {
138  Sprintf(buf,
139  "{int _i, _j; for (_j=%d; _j >=0; _j--) {\n\
140 for (_i=%d; _i>=0; _i--) __%s[_i][_j] = %s0;}}\n",
141  s->araydim - 1,
142  s->discdim - 1,
143  s->name,
144  s->name);
146  Sprintf(buf, "static double __%s[%d][%d];\n", s->name, s->discdim, s->araydim);
148  } else {
149  Sprintf(buf,
150  "{int _i; for (_i=%d; _i>=0; _i--) __%s[_i] = %s0;}\n",
151  s->discdim - 1,
152  s->name,
153  s->name);
155  Sprintf(buf, "static double __%s[%d];\n", s->name, s->discdim);
157  }
158  }
159 }
void init_disc_vars()
Definition: discrete.cpp:132
void massagediscblk(Item *q1, Item *q2, Item *q3, Item *q4)
Definition: discrete.cpp:92
void disc_var_seen(Item *q1, Item *q2, Item *q3, int array)
Definition: discrete.cpp:62
#define diag(s)
Definition: fmenu.cpp:192
char buf[512]
Definition: init.cpp:13
#define i
Definition: md1redef.h:12
#define STR(q)
Definition: model.h:87
#define STAT
Definition: model.h:117
#define DISCF
Definition: model.h:128
#define Linsertstr
Definition: model.h:243
#define Insertstr
Definition: model.h:240
#define SYM(q)
Definition: model.h:86
#define Sprintf
Definition: model.h:233
#define ARRAY
Definition: model.h:118
NMODL parser global flags / functions.
List * initfunc
Definition: init.cpp:8
List * procfunc
Definition: init.cpp:9
void movelist(Item *q1, Item *q2, List *s)
Definition: list.cpp:220
void replacstr(Item *q, char *s)
Definition: list.cpp:225
#define SYMITER(arg1)
Definition: symbol.h:13
static double remove(void *v)
Definition: ocdeck.cpp:207
Definition: model.h:15
Definition: model.h:57
int araydim
Definition: model.h:67
long subtype
Definition: model.h:59
char * name
Definition: model.h:72
int discdim
Definition: model.h:68
int used
Definition: model.h:65