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