|
|
1.1 root 1: #include <stdio.h>
2: #include "ctype.h"
3: #include "typedef.h"
4: #include "basic.h"
5: #include "tokens.h"
6:
7: static char *types[] = {
8: "", "%", "", "$"
9: };
10:
11: int typelens[] = {
12: 0, INTSIZE, FLOATSIZE, STRINGSIZE
13: };
14:
15: double popfloat();
16:
17:
18: /*
19: * clrsym --- clear symbol table
20: */
21:
22: clrsym()
23: {
24:
25: strptr = strspace;
26: symlast = symspace;
27: clear(chains, sizeof chains);
28: }
29:
30:
31: /*
32: * getvar --- parse a variable name and return a pointer to its
33: * symbol table entry. if dimflag is non-zero this is
34: * in the context of a DIM statement and allocation is
35: * exact; otherwise a default sized array is allocated.
36: */
37:
38: Symptr getvar(type, dimflag)
39: int *type;
40: {
41: register char *p;
42: register Symptr v;
43: register int len;
44: Symptr *chain;
45: char name[2];
46: int i, size, offset, _nsubs, _subsc[MAXSUBS];
47:
48: p = inptr;
49: offset = 0;
50: if (*p == FN) {
51: if (dimflag)
52: badsyn();
53: ++p;
54: ++offset;
55: }
56: if (!isalpha(*p))
57: err("name required");
58: name[0] = *p++;
59: name[1] = 0;
60: while (isalnum(*p)) {
61: if (!name[1])
62: name[1] = *p;
63: ++p;
64: }
65: if (*p == '%') {
66: ++p;
67: *type = INT;
68: }
69: else if (*p == '$') {
70: ++p;
71: *type = STRING;
72: }
73: else
74: *type = FLOAT;
75:
76: _nsubs = 0; /* assume no subscripts for now */
77: inptr = p;
78: if (*p == LPAR) {
79: if (++offset < 2) { /* not a function */
80: ++inptr;
81: for (;;) {
82: _subsc[_nsubs++] = fexpr();
83: if (*inptr == RPAR) {
84: ++inptr;
85: break;
86: }
87: expectc(COMMA);
88: if (_nsubs >= MAXSUBS)
89: err("more than %d subscripts",
90: MAXSUBS);
91: }
92: }
93: }
94: else
95: if (dimflag)
96: err("expected (");
97: /*
98: * scan through the appropriate chain looking for the symbol.
99: */
100: chain = &chains[offset][*type];
101: for (v = *chain; v; v = v->v_next)
102: if (v->v_name[0] == name[0] && v->v_name[1] == name[1]) {
103: if (dimflag)
104: err("attempt to re-dimension");
105: goto done;
106: }
107: /*
108: * symbol was not found ... enter it.
109: */
110: v = (Symptr)symlast;
111: len = SYMHDRLEN;
112: /*
113: * if subscripted variable then calculate the array size
114: * if dimensioned and in a DIM stmt then use the dimensions
115: * provided; otherwise use the default values.
116: */
117: switch (offset) {
118: case 0: /* a scalar variable */
119: len += typelens[*type];
120: break;
121: case 1: /* a vector variable */
122: for (i = 0, size = 1; i < _nsubs; ++i) {
123: size *= (dimflag? _subsc[i] : DEFSIZE);
124: if (size <= 0)
125: err("zero or negative array size");
126: }
127: len += VECHDRSIZE + size * typelens[*type];
128: break;
129: case 2: /* a function variable */
130: len += sizeof(Func);
131: break;
132: }
133: if (symlast + len >= symend)
134: if (!moresym(symlast + len))
135: err("symbol table overflow");
136: symlast += len;
137: /*
138: * clear and copy information into symbol table entry.
139: */
140: clear((char *)v, len);
141: v->v_name[0] = name[0];
142: v->v_name[1] = name[1];
143: if (_nsubs) {
144: for (i = 0; i < _nsubs; ++i)
145: v->v_un.v_vec.v_subsc[i] = (dimflag? _subsc[i] : DEFSIZE);
146: v->v_nsubs = _nsubs;
147: }
148: v->v_next = *chain;
149: *chain = v;
150: done:
151: /*
152: * make global copy of subscript information
153: */
154: if ((nsubs = _nsubs))
155: for (i = 0; i < _nsubs; ++i)
156: subsc[i] = _subsc[i];
157: return(v);
158: }
159:
160:
161: /*
162: * dim --- interpret a DIM statement
163: */
164:
165: dim()
166: {
167: int type;
168:
169: do {
170: getvar(&type, YES);
171: } while (*inptr == COMMA && ++inptr);
172: }
173:
174:
175: /*
176: * dumpsym --- dump the symbol table
177: */
178:
179: dumpsym()
180: {
181: register int i;
182:
183: for (i = 1; i < MAXTYPES; ++i) {
184: dumpchain(0, i);
185: dumpchain(1, i);
186: dumpchain(2, i);
187: }
188: }
189:
190:
191: /*
192: * dumpchain --- dump one chain of the symbol table
193: */
194:
195: dumpchain(offset, type)
196: {
197: register Symptr s;
198: register int i, n;
199:
200: for (s = chains[offset][type]; s; s = s->v_next) {
201: fprintf(stderr, "%8X %.2s%s", s, s->v_name, types[type]);
202: switch (offset) {
203: case 0: /* this is a chain of scalars */
204: switch (type) {
205: case INT:
206: fprintf(stderr, "\t= %d", s->v_un.v_int);
207: break;
208: case FLOAT:
209: fprintf(stderr, "\t= %g",
210: (SINGLE ? s->v_un.v_float
211: : s->v_un.v_double));
212: break;
213: case STRING:
214: fprintf(stderr, "\t(%d chars at %X) = ",
215: s->v_un.v_str.s_len,
216: s->v_un.v_str.s_ptr);
217: fprintf(stderr, "\"%.*s\"",
218: s->v_un.v_str.s_len,
219: s->v_un.v_str.s_ptr);
220: break;
221: }
222: break;
223: case 1:
224: fputs(" (", stderr);
225: for (i = 0, n = s->v_nsubs; i < n; ) {
226: fprintf(stderr, "%d",
227: s->v_un.v_vec.v_subsc[i]);
228: if (++i != n)
229: putc(',', stderr);
230: }
231: putc(')', stderr);
232: break;
233: case 2: /* this is a chain of functions */
234: fprintf(stderr, "\tfunction defined at line %u",
235: s->v_un.v_fn.fn_curline->l_lnr);
236: break;
237: }
238: putc('\n', stderr);
239: }
240: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.