NEURON
units1.cpp
Go to the documentation of this file.
1 #include <../../nrnconf.h>
2 /* /local/src/master/nrn/src/modlunit/units1.c,v 1.1.1.1 1994/10/12 17:22:51 hines Exp */
3 /* Just a connection to units.c so that file doesn't need to include modl.h */
4 #include "model.h"
5 #include "parse1.hpp"
6 
7 void unit_push(Item* q) {
9 }
10 
11 const char* decode_units(Symbol* sym) {
12  if (sym->u.str) {
13  return sym->u.str;
14  }
15  if (sym->info && ITMA(sym->info)[1]) {
16  return STR(ITMA(sym->info)[1]);
17  }
18  return "";
19 }
20 
21 void ifcnvfac(Item* q3) /* '(' expr ')' */
22 {
23  Item *q1, *q2;
24  double d;
25 
26  q2 = prev_parstok(q3);
27  q1 = prev_parstok(q2);
28  if (q1->itemsubtype == '(') {
29  if (q2->itemsubtype == REAL || q2->itemsubtype == INTEGER) {
30  unit_pop();
31  sscanf(STR(q2), "%lf", &d);
32  unit_push_num(1. / d);
33  } else if (q2->itemsubtype == DEFINEDVAR) {
34  unit_pop();
35  d = (double) (SYM(q2)->u.i);
36  unit_push_num(1. / d);
37  }
38  }
39 }
40 
41 /* x^y y must be dimensionless. If x is dimensionless then
42 y can be any expression. If x has dimensions then y must be a positive integer
43 and the units can be computed */
44 
45 void unit_exponent(Item* y, Item* lastok) /*x ^ y*/
46 {
47  int i;
48  double yval;
49 
50  unit_less();
51  if (y == lastok && y->itemsubtype == INTEGER) {
52  i = sscanf(STR(y), "%lf", &yval);
53  assert(i == 1);
54  if (yval - (double) ((int) yval)) {
55  unit_less();
56  Unit_push("");
57  } else {
58  Unit_exponent((int) yval);
59  }
60  } else {
61  unit_less();
62  Unit_push("");
63  }
64 }
65 
66 static Item* qexpr[3];
67 void unit_cmp(Item* q1, Item* q2, Item* q3) {
68  qexpr[0] = q1;
69  qexpr[1] = q2;
70  qexpr[2] = q3;
71  Unit_cmp();
72 }
73 
74 void unit_logic(int type, Item* q1, Item* q2, Item* q3) {
75  /* if type is 1 then it doesn't matter what the
76  top two elements are: the result is dimensionless.
77  If the type is 2 then the top two elements must have
78  the same dimensions and the result is dimensionless.
79  */
80 
81  if (type == 2) {
82  unit_cmp(q1, q2, q3);
83  } else {
84  unit_pop();
85  }
86  unit_pop();
87  Unit_push("");
88 }
89 
90 #define NLEVEL 10 /* 10 levels of call! */
91 static int argnumstk[NLEVEL], pargnum = -1;
92 
93 void unit_push_args(Item* q1) {
94  List* larg;
95  Item* q;
96  Symbol* s;
97 
98  pargnum++;
100 
101  s = SYM(q1);
102 
103  /* push the args with units in reverse order */
104  if (s->info && (larg = (List*) ITMA(s->info)[2])) { /*declared*/
105  argnumstk[pargnum] = 0;
106  for (q = larg->prev; q != larg; q = q->prev) {
107  argnumstk[pargnum]++;
108  Unit_push(STR(q));
109  }
110  } else {
111  argnumstk[pargnum] = -1;
112  }
113 }
114 
116  if (argnumstk[pargnum] > 0) {
117  diag("too few arguments", (char*) 0);
118  }
119  assert(pargnum >= 0);
120  pargnum--;
121 }
122 
123 void unit_chk_arg(Item* q1, Item* q2) {
124  if (argnumstk[pargnum] > 0) {
125  argnumstk[pargnum]--;
126  unit_cmp(ITEM0, q1->prev, q2);
127  unit_pop();
128  } else if (argnumstk[pargnum] == 0) {
129  diag("too many arguments", (char*) 0);
130  } else {
131  unit_less();
132  }
133 }
134 
135 void func_unit(Item* q1, Item* q2) {
136  Symbol *s, *checklocal(Symbol*);
137 
138  s = SYM(q1);
139  s = checklocal(s); /* hidden with pushlocal */
140  s->subtype = DEP;
141  if (q2) {
142  s->u.str = STR(q2);
143  } else {
144  s->u.str = (char*) 0;
145  }
146 }
147 
148 void unit_del(int i) /* push 1/delta_x ^ i units */
149 {
150  Symbol* s = lookup("delta_x");
151  if (!s) {
152  diag("delta_x not declared", (char*) 0);
153  }
154  const char* cp = decode_units(s);
155  Unit_push("");
156  while (i--) {
157  Unit_push(cp);
158  unit_div();
159  }
160 }
#define i
Definition: md1redef.h:19
#define assert(ex)
Definition: hocassrt.h:24
#define DEP
Definition: membfunc.hpp:64
#define STR(q)
Definition: model.h:76
#define ITEM0
Definition: model.h:15
#define SYM(q)
Definition: model.h:75
Item * prev_parstok(Item *)
#define ITMA(q)
Definition: model.h:78
Symbol * lookup(const char *)
Item * lastok
Definition: io.cpp:11
Symbol * checklocal(Symbol *sym)
Definition: symbol.cpp:34
void Unit_exponent(int)
Definition: units.cpp:396
void Unit_cmp()
Definition: units.cpp:439
void unit_pop()
Definition: units.cpp:225
void Unit_push(const char *)
Definition: units.cpp:290
void unit_less()
Definition: units.cpp:546
void unit_push_num(double)
Definition: units.cpp:309
void unit_div()
Definition: units.cpp:380
#define diag(s)
Definition: nonlin.cpp:19
size_t q
s
Definition: multisend.cpp:521
short type
Definition: cabvars.h:10
Definition: model.h:8
struct Item * prev
Definition: model.h:13
short itemsubtype
Definition: model.h:10
Definition: model.h:47
union Symbol::@28 u
const char * str
Definition: model.h:53
Item * info
Definition: model.h:50
void unit_chk_arg(Item *q1, Item *q2)
Definition: units1.cpp:123
void unit_exponent(Item *y, Item *lastok)
Definition: units1.cpp:45
static Item * qexpr[3]
Definition: units1.cpp:66
const char * decode_units(Symbol *sym)
Definition: units1.cpp:11
void ifcnvfac(Item *q3)
Definition: units1.cpp:21
void func_unit(Item *q1, Item *q2)
Definition: units1.cpp:135
void unit_del(int i)
Definition: units1.cpp:148
void unit_logic(int type, Item *q1, Item *q2, Item *q3)
Definition: units1.cpp:74
void unit_cmp(Item *q1, Item *q2, Item *q3)
Definition: units1.cpp:67
void unit_push_args(Item *q1)
Definition: units1.cpp:93
static int pargnum
Definition: units1.cpp:91
static int argnumstk[NLEVEL]
Definition: units1.cpp:91
#define NLEVEL
Definition: units1.cpp:90
void unit_push(Item *q)
Definition: units1.cpp:7
void unit_done_args()
Definition: units1.cpp:115