|
|
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.