NEURON
units1.cpp
Go to the documentation of this file.
1 #include <../../nmodlconf.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 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 print_unit_expr(int i) {
75  if (i == 1) {
76  if (qexpr[0]) {
77  printitems(qexpr[0], qexpr[1]->prev);
78  }
79  } else {
80  if (qexpr[1]) {
81  printitems(qexpr[1]->next, qexpr[2]);
82  }
83  }
84 }
85 
86 
87 void unit_logic(int type, Item* q1, Item* q2, Item* q3) {
88  /* if type is 1 then it doesn't matter what the
89  top two elements are: the result is dimensionless.
90  If the type is 2 then the top two elements must have
91  the same dimensions and the result is dimensionless.
92  */
93 
94  if (type == 2) {
95  unit_cmp(q1, q2, q3);
96  } else {
97  unit_pop();
98  }
99  unit_pop();
100  Unit_push("");
101 }
102 
103 #define NLEVEL 10 /* 10 levels of call! */
104 static int argnumstk[NLEVEL], pargnum = -1;
105 
106 void unit_push_args(Item* q1) {
107  List* larg;
108  Item* q;
109  Symbol* s;
110 
111  pargnum++;
112  assert(pargnum < NLEVEL);
113 
114  s = SYM(q1);
115 
116  /* push the args with units in reverse order */
117  if (s->info && (larg = (List*) ITMA(s->info)[2])) { /*declared*/
118  argnumstk[pargnum] = 0;
119  for (q = larg->prev; q != larg; q = q->prev) {
120  argnumstk[pargnum]++;
121  Unit_push(STR(q));
122  }
123  } else {
124  argnumstk[pargnum] = -1;
125  }
126 }
127 
129  if (argnumstk[pargnum] > 0) {
130  diag("too few arguments", (char*) 0);
131  }
132  assert(pargnum >= 0);
133  pargnum--;
134 }
135 
136 void unit_chk_arg(Item* q1, Item* q2) {
137  if (argnumstk[pargnum] > 0) {
138  argnumstk[pargnum]--;
139  unit_cmp(ITEM0, q1->prev, q2);
140  unit_pop();
141  } else if (argnumstk[pargnum] == 0) {
142  diag("too many arguments", (char*) 0);
143  } else {
144  unit_less();
145  }
146 }
147 
148 void func_unit(Item* q1, Item* q2) {
149  Symbol *s, *checklocal(Symbol*);
150 
151  s = SYM(q1);
152  s = checklocal(s); /* hidden with pushlocal */
153  s->subtype = DEP;
154  if (q2) {
155  s->u.str = STR(q2);
156  } else {
157  s->u.str = (char*) 0;
158  }
159 }
160 
161 void unit_del(int i) /* push 1/delta_x ^ i units */
162 {
163  Symbol* s;
164  char* cp;
165 
166  s = lookup("delta_x");
167  if (!s) {
168  diag("delta_x not declared", (char*) 0);
169  }
170  cp = decode_units(s);
171  Unit_push("");
172  while (i--) {
173  Unit_push(cp);
174  unit_div();
175  }
176 }
short type
Definition: cabvars.h:9
#define diag(s)
Definition: fmenu.cpp:192
#define assert(ex)
Definition: hocassrt.h:32
#define REAL
Definition: machine.h:191
#define i
Definition: md1redef.h:12
void printitems(Item *q1, Item *q2)
Definition: model.cpp:166
#define STR(q)
Definition: model.h:87
#define ITEM0
Definition: model.h:22
#define SYM(q)
Definition: model.h:86
Item * prev_parstok(Item *)
#define ITMA(q)
Definition: model.h:89
#define DEP
Definition: model.h:116
Item * lastok
Definition: io.cpp:13
Item * prev(Item *item)
Definition: list.cpp:93
Item * next(Item *item)
Definition: list.cpp:88
Symbol * checklocal(Symbol *sym)
Definition: symbol.cpp:33
void Unit_exponent(int)
Definition: units.cpp:400
void Unit_cmp()
Definition: units.cpp:446
void unit_pop()
Definition: units.cpp:212
void Unit_push(char *)
Definition: units.cpp:277
void unit_less()
Definition: units.cpp:556
void unit_push_num(double)
Definition: units.cpp:296
void unit_div()
Definition: units.cpp:384
size_t q
#define lookup
Definition: redef.h:90
Definition: model.h:15
struct Item * prev
Definition: model.h:20
short itemsubtype
Definition: model.h:17
Definition: model.h:57
long subtype
Definition: model.h:59
Item * info
Definition: model.h:60
union Symbol::@18 u
char * str
Definition: model.h:63
void unit_chk_arg(Item *q1, Item *q2)
Definition: units1.cpp:136
void unit_exponent(Item *y, Item *lastok)
Definition: units1.cpp:45
static Item * qexpr[3]
Definition: units1.cpp:66
void ifcnvfac(Item *q3)
Definition: units1.cpp:21
void func_unit(Item *q1, Item *q2)
Definition: units1.cpp:148
void unit_del(int i)
Definition: units1.cpp:161
void unit_logic(int type, Item *q1, Item *q2, Item *q3)
Definition: units1.cpp:87
char * decode_units(Symbol *sym)
Definition: units1.cpp:11
void print_unit_expr(int i)
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:106
static int pargnum
Definition: units1.cpp:104
static int argnumstk[NLEVEL]
Definition: units1.cpp:104
#define NLEVEL
Definition: units1.cpp:103
void unit_push(Item *q)
Definition: units1.cpp:7
void unit_done_args()
Definition: units1.cpp:128