Annotation of researchv10no/cmd/basic/bas/main.c, revision 1.1.1.1

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 int     listlevel,      /* listing indentation level */
                      8:                rflg;           /* automatic run flag */
                      9: 
                     10: char           lnrdelims[] = {MINUS, COMMA, '-', ',', 0};
                     11: 
                     12: char   *endstr();
                     13: Linep  findline();
                     14: Lnr    cvtlnr();
                     15: Stkptr pop();
                     16: void   old(), dorun(), doline();
                     17: FILE   *file;
                     18: char   *frstwd, *using;
                     19: 
                     20: 
                     21: /*
                     22:  * main --- main program for basic
                     23:  */
                     24: 
                     25: main(argc, argv)
                     26: int    argc;
                     27: char   **argv;
                     28: {
                     29:        register char   *argp;
                     30: 
                     31:        --argc;
                     32:        ++argv;
                     33: 
                     34:        while (argc > 0 && *(argp = *argv) == '-') {
                     35:                ++argv;
                     36:                --argc;
                     37:                while (*++argp)
                     38:                        switch (*argp) {
                     39:                        case 'r':
                     40:                                ++rflg;
                     41:                                break;
                     42:                        case 's':
                     43:                                typelens[FLOAT] = sizeof(float);
                     44:                                break;
                     45:                        case 't':
                     46:                                ++tflg;
                     47:                                break;
                     48:                        case 'p':
                     49:                                pltini(*argv++);
                     50:                                --argc;
                     51:                                break;
                     52:                        default:
                     53:                                fprintf(stderr, "I don't know about -%c\n",
                     54:                                                *argp);
                     55:                                exit(1);
                     56:                                }
                     57:                }
                     58: 
                     59:        initsys();
                     60:        init();
                     61:        if (argc > 0) {
                     62:                argcnt = argc;
                     63:                argvec = argv;
                     64:                argc = 0;
                     65:                enter(old, *argv);
                     66:                }       
                     67:        if (rflg) {
                     68:                enter(dorun, NULL);
                     69:                exit(0);
                     70:                }
                     71:        for (;;)
                     72:                enter(doline, NULL);
                     73: }
                     74: 
                     75: 
                     76: /*
                     77:  * doline --- read and process one line
                     78:  */
                     79: 
                     80: void doline()
                     81: {
                     82: 
                     83:        if (tty)
                     84:                fputs(prompt, stderr);
                     85:        if (readline(line, infile) < 0) {
                     86:                if (attnflg)
                     87:                        err("attn!!");
                     88:                exit(0);
                     89:                }
                     90:        inptr = line;
                     91:        if (line[0] == 0)
                     92:                ;
                     93:        else if (!moncmd())
                     94:                compile();
                     95: }
                     96: 
                     97: 
                     98: /*
                     99:  * compile --- tokenize a line; store numbered ones, execute others
                    100:  */
                    101: 
                    102: compile()
                    103: {
                    104:        register Lnr    lnr;
                    105:        register int    l;
                    106:        register Linep  p;
                    107: 
                    108:        inptr = line;
                    109:        tokenize(line, line);
                    110:        if (tflg)
                    111:                listline(&immed, stderr);
                    112:        inptr = line;
                    113:        if (isdigit(line[0])) {
                    114:                lnr = cvtlnr();
                    115:                if (*inptr) {
                    116:                        l = strlen(inptr) + 1;
                    117:                        move(l, inptr, immed.l_line);
                    118:                        if (l & 1)
                    119:                                ++l;
                    120:                        l += LINESIZE;
                    121:                        immed.l_len = l;
                    122:                        immed.l_lnr = lnr;
                    123:                        storeline(&immed);
                    124:                        }
                    125:                else {
                    126:                        p = findline(lnr, NEXTLNR);
                    127:                        if (p->l_lnr == lnr)
                    128:                                delline(p);
                    129:                        }
                    130:                }
                    131:        else {
                    132:                curline = (Linep)NULL;
                    133:                immed.l_len = 0;
                    134:                execute(&immed);
                    135:                }
                    136:        return(YES);
                    137: }
                    138: 
                    139: 
                    140: /*
                    141:  * findline --- search for the specified line; return pointer to it
                    142:  *             if line is not found and flag==NEXTLNR, return pointer
                    143:  *             to next higher-numbered line
                    144:  */
                    145: 
                    146: Linep findline(lnr, flag)
                    147: Lnr    lnr;
                    148: int    flag;
                    149: {
                    150:        register Linep  p;
                    151: 
                    152:        for ALL_LINES(p)
                    153:                if (lnr <= p->l_lnr)
                    154:                        break;
                    155:        if (p->l_lnr != lnr && flag != NEXTLNR)
                    156:                err("line not found");
                    157:        return(p);
                    158: }
                    159: 
                    160: 
                    161: /*
                    162:  * list --- list the specified range of lines
                    163:  */
                    164: 
                    165: list(line1, line2, file)
                    166: Lnr    line1, line2;
                    167: FILE   *file;
                    168: {
                    169:        register Linep  p;
                    170: 
                    171:        listlevel = 0;
                    172:        for ALL_LINES(p) {
                    173:                if (attnflg)
                    174:                        err("attn!");
                    175:                if (p->l_lnr >= line1)
                    176:                        if (p->l_lnr <= line2)
                    177:                                listline(p, file);
                    178:                        else
                    179:                                break;
                    180:                }
                    181: }
                    182: 
                    183: 
                    184: /*
                    185:  * listline --- list a single line
                    186:  */
                    187: 
                    188: listline(linep, file)
                    189: Linep  linep;
                    190: FILE   *file;
                    191: {
                    192:        register char   *p;
                    193:        register Linep  l;
                    194:        register int    c;
                    195:        int             i, wastoken = YES;
                    196: 
                    197:        l = linep;
                    198:        fprintf(file, "%5u\t", l->l_lnr);
                    199:        for (i = 0; i < listlevel; ++i)
                    200:                putc('\t', file);
                    201: 
                    202:        for (p = l->l_line; *p; ++p)
                    203:                if (istoken(*p)) {
                    204:                        if (!wastoken)
                    205:                                putc(' ', file);
                    206:                        wastoken = YES;
                    207:                        switch (c = *p) {
                    208:                        case QUOTE:
                    209:                        case PRIME:
                    210:                                c = tokens[UNTOKEN(c)][0];
                    211:                                putc(c, file);
                    212:                                while (*++p && !istoken(*p)) {
                    213:                                        if (*p == c)
                    214:                                                putc(c, file);
                    215:                                        putc(*p, file);
                    216:                                        }
                    217:                                putc(c, file);
                    218:                                putc(' ', file);
                    219:                                break;
                    220:                        case REM:
                    221:                        case PRFORM:
                    222:                        case DATA:
                    223:                                fputs(tokens[UNTOKEN(c)], file);
                    224:                                break;
                    225:                        case FOR:
                    226:                                if (p[1] != INPUT && p[1] != OUTPUT && p[1] != APPEND)
                    227:                                        listlevel++;
                    228:                                goto normal;
                    229:                        case NEXT:
                    230:                                listlevel--;
                    231:                        default:
                    232:                        normal:
                    233:                                fputs(tokens[UNTOKEN(c)], file);
                    234:                                putc(' ', file);
                    235:                                }
                    236:                        }
                    237:                else {
                    238:                        putc(*p, file);
                    239:                        wastoken = NO;
                    240:                        }
                    241: 
                    242:        putc('\n', file);
                    243: }
                    244: 
                    245: 
                    246: /*
                    247:  * getlnrs2 --- parse up to two line numbers from current line
                    248:  *             but don't check for end of line in case there
                    249:  *             are more arguments on line (for example, 
                    250:  *             renumber 1000, 10, 300-400
                    251:  */
                    252: 
                    253: getlnrs2(lp1, lp2, type)
                    254: Lnr    *lp1, *lp2;
                    255: int    type;
                    256: {                      
                    257:        register Lnr    line1, line2;
                    258: 
                    259:        if (type == LISTLNRS) {
                    260:                line1 = MINLNR;
                    261:                line2 = MAXLNR;
                    262:                }
                    263:        else {
                    264:                line1 = *lp1;
                    265:                line2 = *lp2;
                    266:                }
                    267:        if (*inptr) {
                    268:                skipbl();
                    269:                optional(lnrdelims);
                    270:                skipbl();
                    271:                line1 = cvtlnr();
                    272:                if (type == LISTLNRS)
                    273:                        line2 = line1;
                    274:                skipbl();
                    275:                optional(lnrdelims);
                    276:                skipbl();
                    277:                if (*inptr)
                    278:                        line2 = cvtlnr();
                    279:                }
                    280:        *lp1 = line1;
                    281:        *lp2 = line2;
                    282: 
                    283: }
                    284: /*
                    285:  * getlnrs --- parse up to two line numbers from current line
                    286:  */
                    287: 
                    288: getlnrs(lp1, lp2, type)
                    289: Lnr    *lp1, *lp2;
                    290: int    type;
                    291: {                      
                    292:        register Lnr    line1, line2;
                    293: 
                    294:        if (type == LISTLNRS) {
                    295:                line1 = MINLNR;
                    296:                line2 = MAXLNR;
                    297:                }
                    298:        else {
                    299:                line1 = *lp1;
                    300:                line2 = *lp2;
                    301:                }
                    302:        if (*inptr) {
                    303:                skipbl();
                    304:                optional(lnrdelims);
                    305:                skipbl();
                    306:                line1 = cvtlnr();
                    307:                if (type == LISTLNRS)
                    308:                        line2 = line1;
                    309:                skipbl();
                    310:                optional(lnrdelims);
                    311:                skipbl();
                    312:                if (*inptr)
                    313:                        line2 = cvtlnr();
                    314:                }
                    315:        endchk();
                    316:        *lp1 = line1;
                    317:        *lp2 = line2;
                    318: }
                    319: 
                    320: 
                    321: /*
                    322:  * delete --- delete the specified range of lines
                    323:  */
                    324: 
                    325: delete(line1, line2)
                    326: Lnr    line1, line2;
                    327: {
                    328:        register Linep  p;
                    329: 
                    330:        for (p = findline(line1, NEXTLNR);
                    331:                        isline(p) && p->l_lnr <= line2; delline(p))
                    332:                ;
                    333: }
                    334: 
                    335: 
                    336: /*
                    337:  * delline --- delete the line pointed to by linep
                    338:  */
                    339: 
                    340: delline(linep)
                    341: register Linep linep;
                    342: {
                    343:        register char   *p, *q;
                    344:        register int    l;
                    345: 
                    346:        p = (char *)linep;
                    347:        l = linep->l_len;
                    348:        q = p + l;
                    349:        smartmove(lastline - q, q, p);
                    350:        lastline -= l;
                    351:        --linecnt;
                    352: }
                    353: 
                    354: 
                    355: /*
                    356:  * storeline --- save the line pointed to by linep
                    357:  */
                    358: 
                    359: storeline(linep)
                    360: Linep  linep;
                    361: {
                    362:        register Linep  l;
                    363:        register char   *p, *q;
                    364:        int             overlap;
                    365: 
                    366:        l = linep;
                    367:        p = (char *)findline(l->l_lnr, NEXTLNR);
                    368:        if (l->l_lnr != ((Linep)p)->l_lnr)
                    369:                q = p;
                    370:        else
                    371:                q = p + ((Linep)p)->l_len;
                    372:        overlap = q - p;
                    373:        if (overlap >= l->l_len && overlap - l->l_len <= LEN_FUZZ)
                    374:                l->l_len = overlap;
                    375:        else {
                    376:                while (lastline + l->l_len - overlap > endlines)
                    377:                        if (!morelines())
                    378:                                err("out of room");
                    379:                smartmove(lastline - q, q, p + l->l_len);
                    380:                }
                    381:        move(l->l_len, (char *)l, p);
                    382:        lastline += l->l_len - overlap;
                    383:        if (!overlap)
                    384:                ++linecnt;
                    385: }
                    386: 
                    387: 
                    388: /*
                    389:  * cvtlnr --- parse one line number from the current input line
                    390:  */
                    391: 
                    392: Lnr cvtlnr()
                    393: {
                    394:        register Lnr    l, lastl;
                    395:        register int    c;
                    396: 
                    397:        lastl = l = 0;
                    398:        while ((c = *inptr) && isdigit(c)) {
                    399:                l = 10 * l + (c - '0');
                    400:                if (l > MAXLNR || l < lastl)
                    401:                        err("bad line number");
                    402:                lastl = l;
                    403:                ++inptr;
                    404:                }
                    405:        return(l);
                    406: }
                    407: 
                    408: 
                    409: /*
                    410:  * optional --- accept any single character in str if present
                    411:  */
                    412: 
                    413: optional(str)
                    414: char   *str;
                    415: {
                    416:        register char   *s;
                    417: 
                    418:        if (*inptr)     
                    419:                for (s = str; *s; ++s)
                    420:                        if (*s == *inptr) {
                    421:                                inptr++;
                    422:                                return(YES);
                    423:                                }
                    424:        return(NO);
                    425: }
                    426: 
                    427: 
                    428: /*
                    429:  * tokenize --- convert input line into a string of tokens
                    430:  */
                    431: 
                    432: tokenize(inp, outp)
                    433: char   *inp, *outp;
                    434: {
                    435:        register char   *t, *p;
                    436:        register int    c;
                    437:        int             i;
                    438: 
                    439:        while ((c = *inp++)) {
                    440:            if (c == ' ' || c == '\t')
                    441:                continue;
                    442:            for (i = -1; (t = tokens[UNTOKEN(i)]); --i) {
                    443:                for (p = inp - 1;; ) {
                    444:                    if (*p++ != *t++) {
                    445:                        if (p[-1] == ' ' || p[-1] == '\t') {
                    446:                            --t;
                    447:                            continue;
                    448:                            }
                    449:                        else if (isupper(p[-1])
                    450:                                   && p[-1] == toupper(t[-1]))
                    451:                            ;
                    452:                        else
                    453:                            break;
                    454:                        }
                    455:                    if (*t == 0) {
                    456:                        if (tflg)
                    457:                            fprintf(stderr, "token %d ", i);
                    458:                        inp = p;
                    459:                        c = i;
                    460:                        switch (i) {
                    461:                        case REM:
                    462:                        case PRFORM:
                    463:                        case DATA:
                    464:                            *outp++ = c;
                    465:                            while ((*outp++ = *inp++))
                    466:                                ;
                    467:                            return;
                    468:                        case PRIME:
                    469:                        case QUOTE:
                    470:                            --t;
                    471:                            *outp++ = c;
                    472:                            while (*inp) {
                    473:                                if (*inp == *t && *++inp != *t)
                    474:                                    break;
                    475:                                *outp++ = *inp++;
                    476:                                }
                    477:                            if (*inp == 0) {
                    478:                                *outp++ = c;
                    479:                                *outp = 0;
                    480:                                return;
                    481:                                }
                    482:                            break;
                    483:                            }
                    484:                        goto loop;
                    485:                        }
                    486:                    }
                    487:                }
                    488:            if (isupper(c))
                    489:                c = tolower(c);
                    490: loop:
                    491:            *outp++ = c;
                    492:            }
                    493:        *outp = c;
                    494: }
                    495: 
                    496: 
                    497: /*
                    498:  * execute --- interpret the line pointed to by linep
                    499:  */
                    500: 
                    501: execute(linep)
                    502: Linep  linep;
                    503: {
                    504:        register Lnr    line1;
                    505:        register int    c;
                    506:        register Stkptr s;
                    507:        Linep           fmlnep;
                    508:        char            *p;
                    509: 
                    510:        curline = linep;
                    511:        if (curline != &immed && !isline(curline))
                    512:                return;
                    513: loop:
                    514:        inptr = curline->l_line;
                    515:        if (trace && curline != &immed)
                    516:                fprintf(stderr, "#%u\n", curline->l_lnr);
                    517:        do {
                    518:                if (attnflg)
                    519:                        err("attn");
                    520: next:
                    521:                c = *inptr;
                    522:                if (istoken(c)) {
                    523:                        ++inptr;
                    524:                        switch (c) {
                    525:                        case END:
                    526:                                return;
                    527:                        case TRACE:
                    528:                                trace = YES;
                    529:                                break;
                    530:                        case NOTRACE:
                    531:                                trace = NO;
                    532:                                break;
                    533:                        case PRINT:
                    534:                                if (*inptr == ' ')
                    535:                                        inptr++;
                    536:                                if (*inptr != USING)
                    537:                                        prtstmt();
                    538:                                else {
                    539:                                        inptr++;
                    540:                                        line1 = cvtlnr();
                    541:                                        fmlnep = findline(line1, EXACTLNR);
                    542:                                        p = fmlnep->l_line;
                    543:                                        if (*p++ != PRFORM)
                    544:                                                err("image-line not found");
                    545:                                        else
                    546:                                                prtusing(p);
                    547:                                        }
                    548:                                break;
                    549:                        case INPUT:
                    550:                        case ASK:
                    551:                                ask();
                    552:                                break;
                    553:                        case READ:
                    554:                                readdata();
                    555:                                break;
                    556:                        case RESTORE:
                    557:                                if (data.k_un.k_gosub.g_inptr != NULL)
                    558:                                        restore();
                    559:                                break;
                    560:                        case DIM:
                    561:                                dim();
                    562:                                break;
                    563:                        case FOR:
                    564:                                forstmt();
                    565:                                break;
                    566:                        case NEXT:
                    567:                                nextstmt();
                    568:                                break;
                    569:                        case REM:
                    570:                        case MORE:
                    571:                        case ELSE:
                    572:                        case QUOTE:
                    573:                        case PRIME:
                    574:                        case PRFORM:
                    575:                        case DATA:
                    576:                                while (*inptr)
                    577:                                        ++inptr;
                    578:                                break;
                    579:                        case RETURN:
                    580:                                while (((Stkptr)stkptr)->k_type == STK_FOR)
                    581:                                        (void)pop(ANYTYPE);
                    582:                                s = pop(STK_GOSUB);
                    583:                                curline = s->k_un.k_gosub.g_curline;
                    584:                                inptr = s->k_un.k_gosub.g_inptr;
                    585:                                break;
                    586:                        case GOSUB:
                    587:                                line1 = cvtlnr();
                    588:                                endchk();
                    589:                                gosub.k_un.k_gosub.g_curline = curline;
                    590:                                gosub.k_un.k_gosub.g_inptr = inptr;
                    591:                                gosub.k_type = STK_GOSUB;
                    592:                                gosub.k_len = GOSUBFRLEN;
                    593:                                push(&gosub);
                    594:                                curline = findline(line1, EXACTLNR);
                    595:                                inptr = NULL;
                    596:                                break;
                    597:                        case GOTO:
                    598:                                line1 = cvtlnr();
                    599:                                endchk();
                    600:                                curline = findline(line1, EXACTLNR);
                    601:                                inptr = NULL;
                    602:                                break;
                    603:                        case DEF:
                    604:                                def();
                    605:                                break;
                    606:                        case LET:
                    607:                                let();
                    608:                                break;
                    609:                        case IF:
                    610:                                ifstmt();
                    611:                                goto nochk;
                    612:                        case STOP:
                    613:                                endchk();
                    614:                                err("stop");
                    615:                                break;
                    616:                        case COLON:
                    617:                                goto next;
                    618:                        case ON:
                    619:                                ongoto();
                    620:                                break;
                    621:                        case CHAIN:
                    622:                                chain();
                    623:                                break;
                    624:                        case HPLOT:
                    625:                                hplot();
                    626:                                break;
                    627:                        case HGR:
                    628:                                hgr();
                    629:                                break;
                    630:                        case OPEN:
                    631:                                openstmt();
                    632:                                break;
                    633:                        case CLOSE:
                    634:                                clsstmt();
                    635:                                break;
                    636:                        case FLUSH:
                    637:                                flsstmt();
                    638:                                break;
                    639:                        case USING:
                    640:                                err("print must precede using");
                    641:                                break;
                    642:                        default:
                    643:                                badsyn();
                    644:                                }
                    645:                        }
                    646:                else
                    647:                        let();
                    648:                if (inptr)
                    649:                        endchk();
                    650: nochk:
                    651:                ;
                    652:                } while (inptr && *inptr);
                    653: 
                    654:        if (inptr == NULL) {
                    655:                if (curline && isline(curline))
                    656:                        goto loop;
                    657:                return;
                    658:                }
                    659:        else if (curline != &immed) {
                    660:                curline = nextline(curline);
                    661:                if (isline(curline))
                    662:                        goto loop;
                    663:                }
                    664: }
                    665: 
                    666: 
                    667: /*
                    668:  * run --- handle the RUN command
                    669:  */
                    670: 
                    671: run()
                    672: {
                    673:        register Lnr    line1;
                    674: 
                    675:        line1 = cvtlnr();
                    676:        endchk();
                    677:        dorun(line1);
                    678: }
                    679: 
                    680: 
                    681: /*
                    682:  * dorun --- begin execution at the specified line
                    683:  */
                    684: 
                    685: void dorun(line1)
                    686: Lnr    line1;
                    687: {
                    688: 
                    689:        clrsym();
                    690:        clrstk();
                    691:        clrio();
                    692:        curline = findline(line1, NEXTLNR);
                    693:        inptr = NULL;
                    694:        execute(curline);
                    695: }
                    696: 
                    697: 
                    698: /*
                    699:  * autonumber --- handle the AUTO command
                    700:  */
                    701: 
                    702: autonumber(line1, line2)
                    703: register Lnr   line1, line2;
                    704: {
                    705:        register Linep  p;
                    706:        register char   *q;
                    707: 
                    708:        curline = (Linep)NULL;
                    709:        for (;; line1 += line2) {
                    710:                if ((p = findline(line1, NEXTLNR)) && p->l_lnr == line1)
                    711:                        err("line %u already exists", line1);
                    712:                sprintf(line, "%5u ", line1);
                    713:                fputs(line, stderr);
                    714:             /* fflush(stderr); */
                    715:                q = endstr(line);
                    716:                if (readline(q, infile) < 0 || *q == 0) {
                    717:                        if (attnflg)
                    718:                                err("attn!!");
                    719:                        break;
                    720:                        }
                    721:                inptr = line;
                    722:                compile();
                    723:                }
                    724: }
                    725: 
                    726: 
                    727: /*
                    728:  * badsyn --- report bad syntax
                    729:  */
                    730: 
                    731: badsyn()
                    732: {
                    733: 
                    734:        err("bad syntax");
                    735: }
                    736: 
                    737: 
                    738: /*
                    739:  * init --- perform startup initialization
                    740:  */
                    741: 
                    742: init()
                    743: {
                    744: 
                    745:        initprio();
                    746:        clrsym();
                    747:        clrstk();
                    748:        clrprog();
                    749: }
                    750: 
                    751: 
                    752: /*
                    753:  * clrprog --- reinitialize the line storage space
                    754:  */
                    755: 
                    756: clrprog()
                    757: {
                    758:        register Linep  l;
                    759: 
                    760:        l = (Linep)lines;
                    761:        l->l_len = 0;
                    762:        l->l_lnr = MAXLNR;
                    763:        lastline = lines + LINESIZE;
                    764:        linecnt = 0;
                    765: }
                    766: 
                    767: 
                    768: /*
                    769:  * nextline --- return ptr to line following one pointed to by lp
                    770:  */
                    771: 
                    772: Linep nextline(lp)
                    773: register Linep lp;
                    774: {
                    775: 
                    776:        return((Linep)((char *)lp + lp->l_len));
                    777: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.