NEURON
declare.cpp
Go to the documentation of this file.
1 #include <../../nmodlconf.h>
2 #include <stdlib.h>
3 #include "model.h"
4 #include "parse1.hpp"
5 #include "symbol.h"
6 #ifdef HAVE_STRINGS_H
7 #include <strings.h>
8 #endif
9 
10 int declare_level = 0;
11 Symbol* indepsym; /* mathematical independent variable */
12 Item** scop_indep; /* the scop swept information */
13 char* indepunits = "";
14 
15 /* subtype of variables using explicit declarations */
16 
17 static int promote(Symbol*, long);
18 static int nprime(char*);
19 
20 void declare(long subtype, Item* q, Item* qa) {
21  Symbol* sym;
22 
23  sym = SYM(q);
24  if (!sym->subtype) { /* not previously declared */
25  sym->subtype = subtype;
26  sym->info = qa;
27  sym->level = declare_level;
28  } else if (declare_level == 0 && sym->level == 0) {
29  diag("Multiple declaration of ", sym->name);
30  } else if (sym->subtype == subtype) { /* lowest level precedence */
31  if (declare_level < sym->level) {
32  sym->info = qa;
33  sym->level = declare_level;
34  } /*else leave as is. First declaration gets precedence */
35  } else { /* A few cases can be promoted */
36  if (subtype & (modlunitCONST | DEP | STAT) && sym->subtype & (modlunitCONST | DEP | STAT)) {
37  if (promote(sym, subtype)) {
38  sym->subtype = subtype;
39  sym->info = qa;
40  sym->level = declare_level;
41  }
42  } else {
43  diag("Multiple inconsistent declarations of ", sym->name);
44  }
45  }
46  declare_array(sym);
47  if (sym->subtype == INDEP && declare_level == 0) {
48  declare_indep(sym);
49  }
50  /*fprintf(stderr, "declared %s with subtype %ld\n", sym->name, sym->subtype);*/
51 }
52 
53 static int promote(Symbol* sym, long sub) {
54  /*ARGSUSED*/
55  diag("promotion not programmed yet", (char*) 0);
56  return 0;
57 }
58 
59 void declare_indep(Symbol* sym) {
60  Item** qa;
61 
62  qa = ITMA(sym->info);
63  if (!qa[7]) { /* no explicit SWEEP */
64  if (indepsym) {
65  diag("Only one independent variable can be defined", (char*) 0);
66  }
67  indepsym = sym;
68  if (ITMA(sym->info)[1]) {
69  indepunits = STR(ITMA(sym->info)[1]);
70  }
71  if (!scop_indep) {
72  scop_indep = qa;
73  }
74  } else {
75  if (scop_indep && scop_indep[7]) {
76  diag("Only one SWEEP declaration is allowed", (char*) 0);
77  }
78  scop_indep = qa;
79  }
80 }
81 
82 void define_value(Item* q1, Item* q2) {
83  Symbol* s;
84  s = SYM(q1);
85  if (s->subtype) {
86  diag(s->name, "already declared");
87  }
88  if (s->usage) {
89  diag(s->name, "used before DEFINE'ed");
90  }
91  s->type = DEFINEDVAR;
92  if (q2->itemtype == SYMBOL) {
93  s->u.i = SYM(q2)->u.i;
94  } else {
95  s->u.i = atoi(STR(q2));
96  }
97 }
98 
99 /* fix up array info */
101  Item* q;
102 
103  if (s->subtype & (modlunitCONST | DEP | STAT)) {
104  q = ITMA(s->info)[2];
105  if (q) {
106  decdim(s, q);
107  /*fprintf(stderr, "declared array %s[%d]\n", s->name, s->araydim);*/
108  }
109  }
110 }
111 
112 void decdim(Symbol* s, Item* q) {
113  s->subtype |= ARRAY;
114  if (q->itemtype == SYMBOL && SYM(q)->type == DEFINEDVAR) {
115  s->araydim = SYM(q)->u.i;
116  } else if (q->itemtype == STRING) {
117  s->araydim = atoi(STR(q));
118  } else {
119  /*SUPPRESS 622*/
120  assert(0);
121  }
122  if (s->araydim < 1) {
123  diag(s->name, "Array index must be > 0");
124  }
125 }
126 
128  static int i = 0;
129 
130  if (i > 1) {
131  diag("internal error inlisttype: First element of LIST is a LIST", (char*) 0);
132  }
133  switch (q->itemtype) {
134  case SYMBOL:
135  break;
136  case LIST:
137  i++;
138  q = listtype(car(LST(q)));
139  i--;
140  break;
141  case ITEM:
142  q = listtype(ITM(q));
143  break;
144  default:
145  diag("internal error in listtype: SYMBOL not first element", (char*) 0);
146  }
147  return q;
148 }
149 
151  Symbol *sbase, *basestate(Symbol*);
152 
153 #if NRNUNIT
154  if (!indepsym) {
155  List *save, *qa;
156  Item *name, *units, *from, *to, *with, *num;
157  save = intoken;
158  intoken = newlist();
159  name = putintoken("t", NAME, 0);
160  units = putintoken("ms", STRING, UNITS);
161  from = putintoken("0", INTEGER, INTEGER);
162  to = putintoken("1", INTEGER, INTEGER);
163  with = putintoken("WITH", NAME, 0);
164  num = putintoken("1", INTEGER, INTEGER);
165  qa = itemarray(8, name, units, from, to, with, num, ITEM0, ITEM0);
166  declare(INDEP, ITMA(qa)[0], qa);
167  intoken = save;
168  }
169 #endif
170 
171  if (!indepsym) {
172  diag("No INDEPENDENT variable has been declared", (char*) 0);
173  }
174  SYMITERALL {
175  if (!s->subtype) {
176  sbase = basestate(s);
177  if (s->type == PRIME) {
178  if (!sbase) {
179  diag(s->name, "is used but its corresponding STATE is not declared");
180  }
181  s->subtype = DEP;
182  if (nprime(s->name) == 1) {
183  Sprintf(buf, "%s/%s", decode_units(sbase), indepunits);
184  } else {
185  Sprintf(buf, "%s/%s%d", decode_units(sbase), indepunits, nprime(s->name));
186  }
187  s->u.str = stralloc(buf, (char*) 0);
188  } else {
189  if (sbase) {
190  s->subtype = modlunitCONST;
191  s->u.str = stralloc(decode_units(sbase), (char*) 0);
192  }
193  }
194  }
195  }
196 }
197 }
198 
199 Symbol* basestate(Symbol* s) /* base state symbol for state''' or state0 */
200 {
201  Symbol* base = SYM0;
202 
203  strcpy(buf, s->name);
204  if (s->type == PRIME) {
205  buf[strlen(buf) - nprime(s->name)] = '\0';
206  base = lookup(buf);
207  } else if (s->name[strlen(s->name) - 1] == '0') {
208  buf[strlen(buf) - 1] = '\0';
209  base = lookup(buf);
210  }
211  if (base && !(base->subtype & STAT)) {
212  base = SYM0;
213  }
214  return base;
215 }
216 
217 #if __TURBOC__ || SYSV || VMS || !defined(HAVE_INDEX) || defined(HAVE_STRINGS_H)
218 #undef index
219 #define index strchr
220 #endif
221 
222 static int nprime(char* s) {
223  char* cp;
224 
225  cp = index(s, '\'');
226  return strlen(s) - (cp - s);
227 }
228 
229 void install_cfactor(Item* qname, Item* q1, Item* q2) /* declare conversion factor */
230 {
231  declare(CNVFAC, qname, ITEM0);
232  Unit_push(STR(q2));
233  Unit_push(STR(q1));
234  unit_div();
235  SYM(qname)->u.str = stralloc(unit_str(), (char*) 0);
236  unit_pop();
237 }
short type
Definition: cabvars.h:9
Item ** scop_indep
Definition: declare.cpp:12
void declare(long subtype, Item *q, Item *qa)
Definition: declare.cpp:20
void declare_array(Symbol *s)
Definition: declare.cpp:100
static int nprime(char *)
Definition: declare.cpp:222
static int promote(Symbol *, long)
Definition: declare.cpp:53
Symbol * basestate(Symbol *s)
Definition: declare.cpp:199
void decdim(Symbol *s, Item *q)
Definition: declare.cpp:112
void declare_implied()
Definition: declare.cpp:150
#define index
Definition: declare.cpp:219
Item * listtype(Item *q)
Definition: declare.cpp:127
void install_cfactor(Item *qname, Item *q1, Item *q2)
Definition: declare.cpp:229
int declare_level
Definition: declare.cpp:10
char * indepunits
Definition: declare.cpp:13
Symbol * indepsym
Definition: declare.cpp:11
void define_value(Item *q1, Item *q2)
Definition: declare.cpp:82
void declare_indep(Symbol *sym)
Definition: declare.cpp:59
#define diag(s)
Definition: fmenu.cpp:192
char buf[512]
Definition: init.cpp:13
List * intoken
Definition: init.cpp:12
#define assert(ex)
Definition: hocassrt.h:32
#define i
Definition: md1redef.h:12
char * decode_units(Symbol *)
#define STR(q)
Definition: model.h:87
#define SYM0
Definition: model.h:74
#define CNVFAC
Definition: model.h:134
#define STAT
Definition: model.h:117
#define SYMBOL
Definition: model.h:102
#define ITEM
Definition: model.h:103
#define INDEP
Definition: model.h:115
#define modlunitCONST
Definition: model.h:114
#define ITEM0
Definition: model.h:22
#define ITM(q)
Definition: model.h:88
#define SYM(q)
Definition: model.h:86
#define Sprintf
Definition: model.h:233
char * unit_str()
#define LST(q)
Definition: model.h:90
#define ITMA(q)
Definition: model.h:89
#define DEP
Definition: model.h:116
#define LIST
Definition: model.h:104
#define ARRAY
Definition: model.h:118
char * name
Definition: init.cpp:16
long subtype
Definition: init.cpp:215
Item * putintoken(char *s, short type, short toktype)
Definition: list.cpp:230
Item * car(List *list)
Definition: list.cpp:82
Item * itemarray(va_alist) va_dcl
Definition: list.cpp:339
char * stralloc(char *buf, char *rel)
Definition: list.cpp:184
List * newlist()
Definition: list.cpp:47
#define SYMITERALL
Definition: symbol.h:4
void units(unit *)
Definition: units.cpp:733
void unit_pop()
Definition: units.cpp:212
void Unit_push(char *)
Definition: units.cpp:277
void unit_div()
Definition: units.cpp:384
size_t q
static double save(void *v)
Definition: ocbox.cpp:346
#define STRING
Definition: bbslsrv.cpp:9
#define lookup
Definition: redef.h:90
Definition: model.h:15
short itemtype
Definition: model.h:16
Definition: model.h:57
int i
Definition: model.h:62
int usage
Definition: model.h:66
short type
Definition: model.h:58
short level
Definition: model.h:71
int araydim
Definition: model.h:67
long subtype
Definition: model.h:59
Item * info
Definition: model.h:60
union Symbol::@18 u
char * name
Definition: model.h:72