PageRenderTime 56ms CodeModel.GetById 26ms RepoModel.GetById 0ms app.codeStats 0ms

/src/modlunit/declare.c

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