|
|
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: double popfloat(), cvtnumber();
8: Linep findline();
9: Lnr cvtlnr();
10: char *getsvar();
11: Symptr getvar();
12:
13:
14: /*
15: * moredatastmt --- check for more data before reading
16: */
17:
18: moredatastmt()
19: {
20:
21: register char *p;
22: register Linep s;
23:
24: /* if we have found a data line, move past
25: any spaces */
26:
27: if (data.k_un.k_gosub.g_inptr != NULL)
28: while (*data.k_un.k_gosub.g_inptr == ' ')
29: ++data.k_un.k_gosub.g_inptr;
30:
31: /* if we have not found a data line yet or
32: we are at the end of a data line, see if there
33: is another data line */
34:
35: if (data.k_un.k_gosub.g_inptr == NULL ||
36: *data.k_un.k_gosub.g_inptr == 0) {
37: for (s = data.k_un.k_gosub.g_curline;
38: isline(s); s = nextline(s)) {
39: p = s->l_line;
40: if (*p++ == DATA) {
41: data.k_un.k_gosub.g_inptr = p;
42: data.k_un.k_gosub.g_curline
43: = nextline(s);
44: return(1);
45: }
46: }
47: return(0);
48: }
49: else
50: return(1);
51:
52:
53:
54: }
55:
56:
57:
58: /*
59: * ifstmt --- interpret an IF statement
60: */
61:
62: ifstmt()
63: {
64: Lnr line1;
65: int s;
66:
67:
68: if (endtest()) badsyn(); /* check for end of statement */
69:
70: while (*inptr == ' ' || *inptr == TAB)
71: ++inptr;
72:
73: /* check for moredata token */
74:
75: if (*inptr == MORE) {
76: ++inptr;
77: while (*inptr == ' ' || *inptr == TAB)
78: ++inptr;
79:
80: /*
81: * we've got a more so let's check for a unit(file) number
82: */
83:
84: if (endtest()) badsyn(); /* check for end of statement */
85:
86: if (*inptr == SHARP)
87: s = morefiledata();
88:
89: /*
90: * found a # so it's a file. go do morefiledata() in io.c
91: */
92:
93: else
94: s = moredatastmt();
95:
96: /*
97: * no # so it's a check for more data in data statements
98: */
99:
100: if (s != 0)
101: goto thendo;
102: else
103: goto elsedo;
104: }
105: else {
106:
107: /*
108: * it's not a check for moredata, so usual routine
109: */
110:
111: if (fexpr() != 0) {
112: thendo:
113: while (*inptr == ' ' || *inptr == TAB)
114: ++inptr;
115:
116: if (endtest())
117: badsyn();
118: /* check for end of statement */
119:
120: if (*inptr == THEN)
121: ++inptr;
122:
123: if (endtest())
124: badsyn();
125: /* check for end of statement */
126:
127: if (isdigit(*inptr)) {
128: line1 = cvtlnr();
129: curline = findline(line1, EXACTLNR);
130: inptr = NULL;
131: }
132: }
133: else {
134: /* move past then actions and look for
135: end of line or an else */
136: elsedo:
137: while (*inptr && *inptr != ELSE)
138: ++inptr;
139:
140: /* if we are not at the end of the line
141: then we must have found an else */
142:
143: if (*inptr)
144: ++inptr;
145: /* if not at end of line, must be an else.
146: so, move past it. */
147:
148: if (!endtest()) {
149: while (*inptr == ' ' || *inptr == TAB)
150: ++inptr;
151: if (isdigit(*inptr)) {
152: line1 = cvtlnr();
153: endchk();
154: curline = findline(line1, EXACTLNR);
155: inptr = NULL;
156: }
157: }
158:
159: else {
160:
161: /* we were at the end of line so no else */
162:
163: curline = nextline(curline);
164: inptr = NULL;
165: }
166: }
167: }
168: }
169:
170:
171: /*
172: * gotostmt --- interpret a GOTO statement
173: */
174:
175: gotostmt()
176: {
177: register Lnr line1;
178:
179: line1 = cvtlnr();
180: endchk();
181: curline = findline(line1, EXACTLNR);
182: inptr = NULL;
183: }
184:
185:
186: /*
187: * forstmt --- interpret a FOR statement
188: */
189:
190: forstmt()
191: {
192: register Symptr v;
193: Stkfr f;
194: int type;
195:
196: f.k_len = FORFRLEN;
197: f.k_type = STK_FOR;
198: f.k_un.k_frk.frk_symp = v = getvar(&type, NO);
199: if (type != FLOAT)
200: typeerr();
201: expectc(EQ);
202: if (SINGLE)
203: v->v_un.v_float = fexpr();
204: else
205: v->v_un.v_double = fexpr();
206: expectc(TO);
207: f.k_un.k_frk.frk_last = fexpr();
208: if (*inptr == STEP) {
209: ++inptr;
210: f.k_un.k_frk.frk_incr = fexpr();
211: }
212: else
213: f.k_un.k_frk.frk_incr = 1.0;
214: endchk();
215: f.k_un.k_frk.frk_inptr = inptr;
216: f.k_un.k_frk.frk_curline = curline;
217: push(&f);
218: }
219:
220:
221: /*
222: * nextstmt --- interpret a NEXT statement
223: */
224:
225: nextstmt()
226: {
227: register Stkptr s;
228: register Symptr v;
229: int type;
230: double f;
231:
232: s = (Stkptr)stkptr;
233: if (s->k_type != STK_FOR)
234: err("for missing");
235: v = s->k_un.k_frk.frk_symp;
236: while (!endtest() && getvar(&type, NO) != v) {
237: pop(STK_FOR);
238: s = (Stkptr)stkptr;
239: if (s->k_type != STK_FOR)
240: err("for missing");
241: v = s->k_un.k_frk.frk_symp;
242: }
243: endchk();
244: if (SINGLE)
245: f = v->v_un.v_float += s->k_un.k_frk.frk_incr;
246: else
247: f = v->v_un.v_double += s->k_un.k_frk.frk_incr;
248: if (s->k_un.k_frk.frk_incr > 0)
249: if (f > s->k_un.k_frk.frk_last + .00000000000001)
250: pop(STK_FOR);
251: else {
252: inptr = s->k_un.k_frk.frk_inptr;
253: curline = s->k_un.k_frk.frk_curline;
254: }
255: else
256: if (f < s->k_un.k_frk.frk_last)
257: pop(STK_FOR);
258: else {
259: inptr = s->k_un.k_frk.frk_inptr;
260: curline = s->k_un.k_frk.frk_curline;
261: }
262: }
263:
264:
265: /*
266: * typeerr --- report a data type error
267: */
268:
269: typeerr()
270: {
271:
272: err("invalid type");
273: }
274:
275:
276: /*
277: * readdata --- interpret a READ statement
278: */
279:
280: readdata()
281: {
282: register char *v;
283: char *ptr;
284: int type, len;
285:
286: while (!endtest()) {
287: v = getsvar(&type);
288: optional(askdelims);
289: if (data.k_un.k_gosub.g_inptr == NULL)
290: getdata();
291: while (*data.k_un.k_gosub.g_inptr == ' ')
292: ++data.k_un.k_gosub.g_inptr;
293: if (*data.k_un.k_gosub.g_inptr == 0)
294: getdata();
295: cvtdata(v, type, &data.k_un.k_gosub.g_inptr);
296: }
297: }
298:
299:
300: /*
301: * getdata --- scan input lines for DATA statements
302: */
303:
304: getdata()
305: {
306: register char *p;
307: register Linep s;
308:
309: for (s = data.k_un.k_gosub.g_curline; isline(s); s = nextline(s)) {
310: p = s->l_line;
311: if (*p++ == DATA) {
312: data.k_un.k_gosub.g_inptr = p;
313: data.k_un.k_gosub.g_curline = nextline(s);
314: return;
315: }
316: }
317: err("out of data");
318: }
319:
320:
321: /*
322: * cvtdata --- convert one data item from a DATA statement
323: */
324:
325: cvtdata(vp, type, ptr)
326: char **ptr, *vp;
327: {
328: register char *v;
329: char *p;
330:
331: v = vp;
332: p = *ptr;
333: while (*p == ' ')
334: ++p;
335: switch(type) {
336: case INT:
337: *(int *)v = cvtnumber(&p, MAXINT);
338: break;
339: case FLOAT:
340: if (SINGLE)
341: *(float *)v = cvtnumber(&p, MAXINT);
342: else
343: *(double *)v = cvtnumber(&p, MAXINT);
344: break;
345: case STRING:
346: cvtstring(&p);
347: storestring(v);
348: break;
349: default:
350: badtype();
351: }
352: while (*p == ' ')
353: ++p;
354: if (*p)
355: if (*p == ',')
356: ++p;
357: else
358: err("bad input");
359: *ptr = p;
360: }
361:
362:
363: /*
364: * cvtstring --- convert a string element of a DATA statement
365: */
366:
367: cvtstring(cvtptr)
368: char **cvtptr;
369: {
370: register int c;
371: register char *p, *ptr;
372: int len;
373:
374: p = *cvtptr;
375: if (*p == '"' || *p == '\'')
376: c = *p++;
377: else
378: c = ',';
379: ptr = p;
380: while (*p && *p != c)
381: ++p;
382: len = p - ptr;
383: if (*p && *p != ',')
384: ++p;
385: *cvtptr = p;
386: pushstring(ptr, len);
387: }
388:
389:
390: /*
391: * ongoto --- interpret an ON statement
392: */
393:
394: ongoto()
395: {
396: register int l, s;
397: register Lnr lnr;
398:
399: l = fexpr();
400: s = *inptr++;
401: if (s != GOTO && s != GOSUB)
402: badsyn();
403: if (l <= 0)
404: err("on index less than one");
405: while (!endtest()) {
406: lnr = cvtlnr();
407: if (--l == 0) {
408: if (s == GOSUB) {
409: while (!endtest())
410: ++inptr;
411: gosub.k_un.k_gosub.g_curline = curline;
412: gosub.k_un.k_gosub.g_inptr = inptr;
413: gosub.k_type = STK_GOSUB;
414: gosub.k_len = GOSUBFRLEN;
415: push(&gosub);
416: }
417: curline = findline(lnr, EXACTLNR);
418: inptr = NULL;
419: return;
420: }
421: if (*inptr == COMMA)
422: ++inptr;
423: else
424: break;
425: }
426: err("on index too big");
427: }
428:
429:
430: /*
431: * hgr ---
432: */
433:
434: hgr()
435: {
436:
437: pltcls();
438: pltini(NULL);
439: }
440:
441:
442: /*
443: * hplot ---
444: */
445:
446: hplot()
447: {
448: register int x, y;
449:
450: do {
451: x = fexpr();
452: expectc(COMMA);
453: y = fexpr();
454: plot(x, y);
455: pendn();
456: } while (*inptr == TO && ++inptr);
457: penup();
458: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.