/src/modlunit/declare.c
C | 260 lines | 231 code | 23 blank | 6 comment | 61 complexity | 137dbd556a68fb0b30918019442d9f2a MD5 | raw file
Possible License(s): BSD-3-Clause, GPL-2.0
- #include <../../nmodlconf.h>
- #include <stdlib.h>
- #include "model.h"
- #include "parse1.h"
- #include "symbol.h"
- #ifdef HAVE_STRINGS_H
- #include <strings.h>
- #endif
- int declare_level=0;
- Symbol *indepsym; /* mathematical independent variable */
- Item **scop_indep; /* the scop swept information */
- char *indepunits = "";
- /* subtype of variables using explicit declarations */
- static int promote();
- static int nprime();
- void declare(subtype, q, qa)
- long subtype;
- Item *q, *qa;
- {
- Symbol *sym;
-
- sym = SYM(q);
- if (!sym->subtype) { /* not previously declared */
- sym->subtype = subtype;
- sym->info = qa;
- sym->level = declare_level;
- } else if (declare_level == 0 && sym->level == 0) {
- diag("Multiple declaration of ", sym->name);
- } else if (sym->subtype == subtype) { /* lowest level precedence */
- if (declare_level < sym->level) {
- sym->info = qa;
- sym->level = declare_level;
- }/*else leave as is. First declaration gets precedence */
- } else { /* A few cases can be promoted */
- if (subtype&(modlunitCONST|DEP|STAT) && sym->subtype&(modlunitCONST|DEP|STAT)){
- if (promote(sym, subtype)) {
- sym->subtype = subtype;
- sym->info = qa;
- sym->level = declare_level;
- }
- } else {
- diag("Multiple inconsistent declarations of ", sym->name);
- }
- }
- declare_array(sym);
- if (sym->subtype == INDEP && declare_level == 0) {
- declare_indep(sym);
- }
- /*fprintf(stderr, "declared %s with subtype %ld\n", sym->name, sym->subtype);*/
- }
- static int promote(sym, sub)
- Symbol *sym;
- long sub;
- {
- /*ARGSUSED*/
- diag("promotion not programmed yet", (char *)0);
- return 0;
- }
-
- void declare_indep(sym)
- Symbol *sym;
- {
- Item **qa;
-
- qa = ITMA(sym->info);
- if (!qa[7]) { /* no explicit SWEEP */
- if (indepsym) {
- diag("Only one independent variable can be defined", (char *) 0);
- }
- indepsym = sym;
- if (ITMA(sym->info)[1]) {
- indepunits = STR(ITMA(sym->info)[1]);
- }
- if (!scop_indep) {
- scop_indep = qa;
- }
- }else{
- if (scop_indep && scop_indep[7]) {
- diag("Only one SWEEP declaration is allowed", (char *)0);
- }
- scop_indep = qa;
- }
- }
- void define_value(q1, q2)
- Item *q1, *q2;
- {
- Symbol *s;
- s = SYM(q1);
- if (s->subtype) {
- diag(s->name, "already declared");
- }
- if (s->usage) {
- diag(s->name, "used before DEFINE'ed");
- }
- s->type = DEFINEDVAR;
- if (q2->itemtype == SYMBOL) {
- s->u.i = SYM(q2)->u.i;
- }else{
- s->u.i = atoi(STR(q2));
- }
- }
- /* fix up array info */
- void declare_array(s)
- Symbol *s;
- {
- Item *q;
-
- if (s->subtype & (modlunitCONST|DEP|STAT)) {
- q = ITMA(s->info)[2];
- if (q) {
- decdim(s, q);
- /*fprintf(stderr, "declared array %s[%d]\n", s->name, s->araydim);*/
- }
- }
- }
- void decdim(s, q)
- Symbol *s;
- Item *q;
- {
- s->subtype |= ARRAY;
- if (q->itemtype == SYMBOL && SYM(q)->type == DEFINEDVAR) {
- s->araydim = SYM(q)->u.i;
- }else if (q->itemtype == STRING) {
- s->araydim = atoi(STR(q));
- }else{
- /*SUPPRESS 622*/
- assert(0);
- }
- if (s->araydim < 1) {
- diag(s->name, " Array index must be > 0");
- }
- }
- Item *
- listtype(q)
- Item *q;
- {
- static int i=0;
-
- if (i > 1) {
- diag("internal error inlisttype: First element of LIST is a LIST", (char *)0);
- }
- switch (q->itemtype) {
- case SYMBOL:
- break;
- case LIST:
- i++;
- q = listtype(car(LST(q)));
- i--;
- break;
- case ITEM:
- q = listtype(ITM(q));
- break;
- default:
- diag("internal error in listtype: SYMBOL not first element", (char *)0);
- }
- return q;
- }
- void declare_implied()
- {
- Symbol *sbase, *basestate();
-
- #if NRNUNIT
- if (!indepsym) {
- List* save, *qa;
- Item* name, *units, *from, *to, *with, *num;
- save = intoken;
- intoken = newlist();
- name = putintoken("t", NAME, 0);
- units = putintoken("ms", STRING, UNITS);
- from = putintoken("0", INTEGER, INTEGER);
- to = putintoken("1", INTEGER, INTEGER);
- with = putintoken("WITH", NAME, 0);
- num = putintoken("1", INTEGER, INTEGER);
- qa = itemarray(8, name, units, from, to, with, num, ITEM0, ITEM0);
- declare(INDEP, ITMA(qa)[0], qa);
- intoken = save;
- }
- #endif
- if (!indepsym) {
- diag("No INDEPENDENT variable has been declared", (char*)0);
- }
- SYMITERALL {
- if (!s->subtype) {
- sbase = basestate(s);
- if (s->type == PRIME) {
- if (!sbase) {
- diag(s->name, " is used but its corresponding STATE is not declared");
- }
- s->subtype = DEP;
- if (nprime(s->name) == 1) {
- Sprintf(buf, "%s/%s", decode_units(sbase), indepunits);
- }else{
- Sprintf(buf, "%s/%s%d", decode_units(sbase), indepunits, nprime(s->name));
- }
- s->u.str = stralloc(buf, (char *)0);
- } else {
- if (sbase) {
- s->subtype = modlunitCONST;
- s->u.str = stralloc(decode_units(sbase), (char *)0);
- }
- }
- }
- }}
- }
- Symbol *
- basestate(s) /* base state symbol for state''' or state0 */
- Symbol *s;
- {
- Symbol *base = SYM0;
- strcpy(buf, s->name);
- if (s->type == PRIME) {
- buf[strlen(buf) - nprime(s->name)] = '\0';
- base = lookup(buf);
- } else if (s->name[strlen(s->name) - 1] == '0') {
- buf[strlen(buf) - 1] = '\0';
- base = lookup(buf);
- }
- if (base && !(base->subtype & STAT)) {
- base = SYM0;
- }
- return base;
- }
-
- #if __TURBOC__ || SYSV || VMS || !defined(HAVE_INDEX) || defined(HAVE_STRINGS_H)
- #undef index
- #define index strchr
- #endif
- static int nprime(s)
- char *s;
- {
- char *cp;
-
- cp = index(s, '\'');
- return strlen(s) - (cp - s);
- }
- void install_cfactor(qname, q1, q2) /* declare conversion factor */
- Item *qname, *q1, *q2;
- {
- declare(CNVFAC, qname, ITEM0);
- Unit_push(STR(q2));
- Unit_push(STR(q1));
- unit_div();
- SYM(qname)->u.str = stralloc(unit_str(), (char *)0);
- unit_pop();
- }