NEURON
modl.h
Go to the documentation of this file.
1 #pragma once
2 #include "wrap_sprintf.h"
3 
4 #include <stdio.h>
5 #include <string.h>
6 #include <assert.h>
7 #include <map>
8 #include <string>
9 
10 /**
11  * \dir
12  * \brief NOCMODL Legacy NMODL Translator (NOCMODL) Implementation
13  *
14  * \file
15  * \brief NMODL parser global flags / functions
16  */
17 
18 /**
19  * @defgroup NMODL NMODL Translator
20  * @brief Implementation of NMODL Source-to-Source translator (NOCMODL)
21  *
22  * @{
23  */
24 
25 
26 /*-
27  The central data structure throughout modl is the list. Items can be
28  inserted before a known item, inserted at the head of a list, or appended
29  to the tail of a list. Items can be removed from a list. Lists can contain
30  mixed types of items. Often an item which was an input token is edited and
31  replaced by a string. The main types of items are strings and symbols.
32  Lists used are:
33 
34  intoken Everytime the lexical analyser reads an input token it is
35  placed in this list. Much translation to C takes place during
36  parsing and most of that editing is done in this list. After
37  an entire block is processed, the tokens are moved as a group
38  to another list.
39 
40  initfunc main body of initmodel() from INITIAL. Automatic statements
41  of the form state = state0 are constructed here.
42  constructorfunc statements added to tail of allocation function
43  destructorfunc statements executed when POINT_PROCESS destroyed
44  modelfunc main body of model() from EQUATION. SOLVE statements in the
45  equation block get expanded in this list
46  procfunc all remaining blocks get concatenated to this list. It
47  also gets the declarations. By prepending to procfunc, one
48  can guarantee that a declaration precedes usage.
49  initlist automatically generated statements that are to be executed
50  only once are constructed here. Contains setup of slist's
51  and dist's, etc. i.e. setup of indirect pointer lists to
52  state groups.
53 
54  Other lists (not global) but used in several files are:
55 
56  symlist[] symbol table. One list for every beginning ascii character.
57  see symbol.c and symbol.h. See the Symbol structure below.
58  symlistlist for a stack of local symbol lists for LOCAL variables.
59  Local variable 'name' is translated as _lname so that
60  there can be no conflict with the 'p' array.
61  syminorder Maintains order of variable declarations in the input file.
62  Used to get good order in the .var file.
63 
64  firstlist Statements that must appear before anything else in the
65  .c file. The only usage at this time is declaration of
66  LOCAL variables outside of blocks.
67 
68  plotlist variables to be plotted on first entry to scop
69 
70  Other lists used for local or very specific purposes are:
71 
72  indeplist Independent variable info.
73  parmlist parameters in a SENS statement
74  statelist states used in a block containing a SENS statement
75  sensinfo see sens.c
76  senstmt see sens.c
77  solvq Item location and method stored when SOLVE statement occurs.
78  Solve statements are processed after all input is read.
79  eqnq Linear equations assembled using this list.
80 
81  Kinetic.c should be modified to make uniform use of List's instead of
82  special structures for Reaction, Rlist, etc.
83  */
84 
85 /* For char buffers that might be called on to hold long path names */
86 /* Note that paths can exceed MAX_PATH from <limits.h> on some systems */
87 #define NRN_BUFSIZE 8192
88 #include <limits.h>
89 #if MAX_PATH > NRN_BUFSIZE
90 #undef NRN_BUFSIZE
91 #define NRN_BUFSIZE MAX_PATH
92 #endif
93 
94 typedef struct Item List; /* list of mixed items */
95 typedef struct Item {
96  short itemtype;
97  union {
98  struct Item* itm;
100  char* str;
101  struct Symbol* sym;
102  } element; /* pointer to the actual item */
103  struct Item* next;
104  struct Item* prev;
106 #define ITEM0 (Item*) 0
107 #define LIST0 (List*) 0
108 
109 #define ITERATE(itm, lst) for (itm = (lst)->next; itm != (lst); itm = itm->next)
110 
111 /*-
112 The symbol structure gives info about tokens. Not all tokens need all
113 elements. Eg. the STRING uses only type and name. Much storage could be
114 saved and much greater clarity could be attained if each type had its own
115 sub stucture. Currently many of the structure elements serve very different
116 purposes depending on the type.
117 The following is a list of the current element usage:
118  type token number from parse1.ypp
119  subtype see definitions below
120  u.i integration method - flag for variable step
121  equation block - function number for generating variables
122  u.str scop variables - max,min,units for .var file
123  used state variable - temporary flag that it is used in an equation
124  equation block - number of state variables used (# unknowns)
125  in parout.c - the numeric order in the .var file. Generated
126  and used in parout.c for the plotlist.
127  usage a token is used as a variable (DEP) or function (FUNC)
128  Another field, EXPLICIT_DECL, is used to determine if a
129  variable appears in the input file or is automatically
130  created, thus helping to organize the .var file.
131  araydim arrays - dimension
132  discdim discrete variable - dimension
133  varnum state variable - during processing of a block containing
134  equations in which simultaneous equations result; column
135  number of state variable in the matrix.
136  name token name
137 */
138 typedef struct Symbol {
139  short type;
140  long subtype;
141  short nrntype;
143  int no_threadargs; /* introduced for FUNCTION_TABLE table_name */
144  int* slist_info_; /* blunt instrument for retrieving ion concentration slist value */
145  int ioncount_; /* ppvar index for ions */
146  union {
147  int i;
148  char* str;
149  } u;
150  int used;
151  int usage;
152  int araydim;
153  int discdim;
154  int varnum; /* column number of state variable in
155  * equations */
156  char* name;
158 #define SYM0 (Symbol*) 0
159 
160 extern std::map<std::string, const char*> extdef_rand;
161 
162 /*
163  * this is convenient way to get the element pointer if you know what type
164  * the item is
165  */
166 #define SYM(q) ((q)->element.sym)
167 #define STR(q) ((q)->element.str)
168 #define ITM(q) ((q)->element.itm)
169 #define LST(q) ((q)->element.lst)
170 /* types not defined in parser */
171 #define SPECIAL 1
172 #define SYMBOL 1
173 #define ITEM 2
174 #define LIST 3
175 /*
176  * An item type, STRING is also used as an item type
177  * An item type, VERBATIM is also used as an item type which is to be
178  * treated the same as a STRING but with no prepended space on output.
179  */
180 
181 /* subtypes */
182 #define KEYWORD 01
183 #define PARM 02
184 #define INDEP 04
185 #define DEP 010 /* also in usage field */
186 #define STAT 020
187 #define ARRAY 040
188 #define FUNCT 0100 /* also in usage field */
189 #define PROCED 0200
190 #define NEGATIVE 0400
191 #define SEMI 01 /* ";" */
192 #define BEGINBLK 02 /* "{" */
193 #define ENDBLK 04 /* "}" */
194 #define DERF 01000
195 #define KINF 02000
196 #define NLINF 04000
197 #define DISCF 010000
198 #define PARF 040000
199 #define EXTDEF 0100000
200 #define LINF 0200000
201 #define UNITDEF 0400000L
202 #define EXTDEF2 01000000L /* functions that can take array or function name arguments */
203 #define nmodlCONST 02000000L /* constants that do not appear in .var file */
204 #define EXTDEF3 04000000L /* get two extra reset arguments at beginning */
205 #define INTGER 010000000L /* must be cast to double in expr */
206 #define EXTDEF4 020000000L /* get extra NrnThread* arg at beginning */
207 #define EXTDEF5 040000000L /* not threadsafe from the extdef list */
208 #define EXTDEF_RANDOM 0600000000L /* functions that can be used with RANDOM type */
209 #define EXPLICIT_DECL 01 /* usage field, variable occurs in input file */
210 
211 
212 #define NRNEXTRN 01 /* t, dt, celsius, etc. */
213 #define NRNCURIN 02 /* input value used */
214 #define NRNCUROUT 04 /* added to output value */
215 #define NRNRANGE 010
216 #define NRNPRANGEIN 020
217 #define NRNPRANGEOUT 040
218 #define NRNGLOBAL 0100 /* same for all sections, defined here */
219 #define NRNSTATIC 0200 /* v */
220 #define NRNNOTP 0400 /* doesn't belong in p array */
221 #define NRNIONFLAG \
222  01000 /* temporary flag to allow READ and WRITE \
223  without declaring twice */
224 #define NRNPOINTER 04000
225 #define IONCONC 010000
226 #define NRNBBCOREPOINTER 020000
227 #define NMODLRANDOM 040000
228 // Implicit ion concentration variable that has been added so we can call nrn_wrote_conc, but which
229 // is not used in the MOD file
230 #define IONCONC_IMPLICIT 040000
231 
232 
233 extern char *emalloc(unsigned), /* malloc with out of space checking */
234  *stralloc(const char*, char*), /* copies string to new space */
235  *inputline(), /* used only by parser to get title line */
236  *inputtopar(), /* used only by parser to get units */
237  *Gets(char*); /* used only in io.c to get string from fin. */
238 
239 extern int nmodl_text; /* if 1, the text of the mod file is a string in the mod file */
240 extern List* filetxtlist;
241 
242 extern List *newlist(), /* begins new empty list */
243  *inputtext(); /* used by parser to get block text from
244  * VERBATIM and COMMENT */
245 extern Item *putintoken(const char*s, short type), /* construct symbol and store input tokens */
246  *insertstr(Item*item, const char*str), /* before a known Item */
247  *insertsym(List*list, Symbol*sym), *linsertstr(List*list, const char*str), /* prepend to list */
248  *lappendstr(List*list, const char*str), /* append to list */
249  *linsertsym(List*list, Symbol*sym), *lappendsym(List*list, Symbol*sym),
250  *lappenditem(List*list, Item*item), *lappendlst(List*list, List*lst),
251  *next(), /* not used but should be instead of q->next */
252  *prev();
253 
254 extern Symbol *install(const char*, int), /* Install token in symbol table */
255  *lookup(const char*), /* lookup name in symbol table */
256  *copylocal(Symbol*), /* install LOCAL variable symbol */
257  *ifnew_parminstall(const char*name,
258  const char*num,
259  const char*units,
260  const char*limits); /* new .var info only if
261  * not already done. */
262 #include "nmodlfunc.h"
263 
264 extern char finname[NRN_BUFSIZE]; /* the input file prefix */
265 extern char buf[NRN_BUFSIZE]; /* general purpose temporary buffer */
266 extern char* modprefix;
267 
268 extern List *intoken, /* Main list of input tokens */
269  *initfunc, /* see discussion above */
271  *plotlist;
272 
273 extern FILE *fin, /* .mod input file descriptor */
274  *fparout, /* .var file */
275  *fcout; /* .c file */
276 
277 extern Symbol *semi, /* ';'. When seen on output, causes newline */
278  *beginblk, /* '{'. Used for rudimentary indentation */
279  *endblk; /* on output. */
280 
281 extern void printlist(List*);
282 
283 /* the following is to get lint to shut up */
284 #if LINT
285 #undef assert
286 #define assert(arg) \
287  { \
288  if (arg) \
289  ; \
290  } /* so fprintf doesn't give lint */
291 extern char* clint;
292 extern int ilint;
293 extern Item* qlint;
294 #define Fprintf ilint = fprintf
295 #define Fclose ilint = fclose
296 #define Fflush ilint = fflush
297 #define Printf ilint = printf
298 #define Strcpy clint = strcpy
299 #define Strcat clint = strcat
300 #define Insertstr qlint = insertstr
301 #define Insertsym qlint = insertsym
302 #define Linsertsym qlint = linsertsym
303 #define Linsertstr qlint = linsertstr
304 #define Lappendsym qlint = lappendsym
305 #define Lappendstr qlint = lappendstr
306 #define Lappenditem qlint = lappenditem
307 #define Lappendlst qlint = lappendlst
308 #define IGNORE(arg) \
309  { \
310  if (arg) \
311  ; \
312  }
313 #define Free(arg) free((char*) (arg))
314 #else
315 #define Fprintf fprintf
316 #define Fclose fclose
317 #define Fflush fflush
318 #define Printf printf
319 #define Strcpy strcpy
320 #define Strcat strcat
321 #define Insertstr insertstr
322 #define Insertsym insertsym
323 #define Linsertsym linsertsym
324 #define Linsertstr linsertstr
325 #define Lappendsym lappendsym
326 #define Lappendstr lappendstr
327 #define Lappenditem lappenditem
328 #define Lappendlst lappendlst
329 #define IGNORE(arg) arg
330 #define Free(arg) free((void*) (arg))
331 #endif
332 using neuron::Sprintf;
333 using neuron::SprintfAsrt;
334 
335 void verbatim_adjust(char* q);
336 /** @} */ // end of hoc_functions
static HocParmLimits limits[]
Definition: extcelln.cpp:36
List * destructorfunc
Definition: modl.h:269
char * Gets(char *)
Definition: io.cpp:91
Item * putintoken(const char *s, short type)
std::map< std::string, const char * > extdef_rand
Definition: init.cpp:158
List * plotlist
Definition: modl.h:270
List * initfunc
Definition: modl.h:268
List * filetxtlist
Definition: modl.cpp:59
Item * lappendsym(List *list, Symbol *sym)
Item * insertsym(List *list, Symbol *sym)
List * procfunc
Definition: modl.h:269
FILE * fcout
Definition: modl.h:274
Item * lappenditem(List *list, Item *item)
Item * linsertstr(List *list, const char *str)
void verbatim_adjust(char *q)
Definition: modl.cpp:261
Symbol * ifnew_parminstall(const char *name, const char *num, const char *units, const char *limits)
Definition: parsact.cpp:71
Item * lappendstr(List *list, const char *str)
void printlist(List *)
Definition: model.cpp:141
char buf[NRN_BUFSIZE]
Definition: init.cpp:13
char * modprefix
Definition: modl.cpp:48
char * emalloc(unsigned)
Definition: list.cpp:161
Item * next()
Symbol * beginblk
Definition: modl.h:277
char * inputline()
List * firstlist
Definition: modl.h:269
struct Item Item
List * newlist()
Item * prev()
char finname[NRN_BUFSIZE]
Definition: model.cpp:38
char * stralloc(const char *, char *)
Definition: list.cpp:178
Symbol * semi
Definition: init.cpp:11
List * initlist
Definition: modl.h:269
Item * insertstr(Item *item, const char *str)
FILE * fparout
Definition: modl.h:273
List * intoken
Definition: init.cpp:12
List * termfunc
Definition: modl.h:269
FILE * fin
Definition: model.cpp:33
Symbol * endblk
Definition: modl.h:278
struct Symbol Symbol
Item * lappendlst(List *list, List *lst)
Symbol * copylocal(Symbol *)
List * constructorfunc
Definition: modl.h:269
char * inputtopar()
List * inputtext()
Symbol * lookup(const char *)
Item * linsertsym(List *list, Symbol *sym)
#define NRN_BUFSIZE
Definition: modl.h:87
List * modelfunc
Definition: modl.h:269
Symbol * install(const char *, int)
int nmodl_text
Definition: modl.cpp:58
const char * name
Definition: init.cpp:16
void SprintfAsrt(char(&buf)[N], const char *fmt, Args &&... args)
assert if the Sprintf format data does not fit into buf
Definition: wrap_sprintf.h:27
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
size_t q
s
Definition: multisend.cpp:521
short type
Definition: cabvars.h:10
void units(unit *)
Definition: units.cpp:641
Definition: model.h:8
struct Item * prev
Definition: model.h:13
struct Symbol * sym
Definition: modl.h:101
List * lst
Definition: modl.h:99
void * element
Definition: model.h:11
struct Item * itm
Definition: modl.h:98
char * str
Definition: modl.h:100
short itemtype
Definition: model.h:9
struct Item * next
Definition: model.h:12
Definition: model.h:47
union Symbol::@28 u
int i
Definition: model.h:52
int usage
Definition: model.h:56
short type
Definition: model.h:48
short nrntype
Definition: modl.h:141
int araydim
Definition: model.h:57
long subtype
Definition: model.h:49
int * slist_info_
Definition: modl.h:144
int no_threadargs
Definition: modl.h:143
char * name
Definition: model.h:61
char * str
Definition: modl.h:148
int discdim
Definition: model.h:58
int ioncount_
Definition: modl.h:145
int used
Definition: model.h:55
int varnum
Definition: model.h:59
short assigned_to_
Definition: modl.h:142