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