OpenCores
URL https://opencores.org/ocsvn/light8080/light8080/trunk

Subversion Repositories light8080

[/] [light8080/] [trunk/] [tools/] [c80/] [c80.c] - Diff between revs 65 and 66

Go to most recent revision | Only display areas with differences | Details | Blame | View Log

Rev 65 Rev 66
//************************************************
//************************************************
//
//
//              Small-C Compiler 
//              Small-C Compiler 
// 
// 
//              by Ron Cain 
//              by Ron Cain 
// 
// 
//************************************************
//************************************************
 
 
// with minor mods by RDK 
// with minor mods by RDK 
#define BANNER  " <><><>   Small-C  V1.2  DOS--CP/M Cross Compiler   <><><>"
#define BANNER  " <><><>   Small-C  V1.2  DOS--CP/M Cross Compiler   <><><>"
#define VERSION " <><><><><>   CP/M Large String Space Version   <><><><><>"
#define VERSION " <><><><><>   CP/M Large String Space Version   <><><><><>"
#define AUTHOR  " <><><><><><><><><><>   By Ron Cain   <><><><><><><><><><>"
#define AUTHOR  " <><><><><><><><><><>   By Ron Cain   <><><><><><><><><><>"
#define TLINE   " <><><><><><><><><><><><><><>X<><><><><><><><><><><><><><>"
#define TLINE   " <><><><><><><><><><><><><><>X<><><><><><><><><><><><><><>"
 
 
/*      Define system dependent parameters      */
/*      Define system dependent parameters      */
/*      Stand-alone definitions                 */
/*      Stand-alone definitions                 */
/* INCLUDE THE LIBRARY TO COMPILE THE COMPILER (RDK) */
/* INCLUDE THE LIBRARY TO COMPILE THE COMPILER (RDK) */
/* #include smallc.lib */ /* small-c library included in source now */
/* #include smallc.lib */ /* small-c library included in source now */
/* IN DOS USE THE SMALL-C OBJ LIBRARY RATHER THAN IN-LINE ASSEMBLER */
/* IN DOS USE THE SMALL-C OBJ LIBRARY RATHER THAN IN-LINE ASSEMBLER */
#define NULL 0
#define NULL 0
#define eol 10 /* was 13 */
#define eol 10 /* was 13 */
 
 
#include "stdio.h"  /* was <stdio.h> */
#include "stdio.h"  /* was <stdio.h> */
 
 
/*      Define the symbol table parameters      */
/*      Define the symbol table parameters      */
#define symsiz          16
#define symsiz          16
#define symtbsz         5760
#define symtbsz         5760
#define numglbs         300
#define numglbs         300
#define startglb        symtab
#define startglb        symtab
#define endglb          startglb+numglbs*symsiz
#define endglb          startglb+numglbs*symsiz
#define startloc        endglb+symsiz
#define startloc        endglb+symsiz
#define endloc          symtab+symtbsz-symsiz
#define endloc          symtab+symtbsz-symsiz
 
 
/*      Define symbol table entry format        */
/*      Define symbol table entry format        */
#define name            0
#define name            0
#define ident           9
#define ident           9
#define type            10
#define type            10
#define storage         11
#define storage         11
#define offset          12
#define offset          12
#define initptr         14
#define initptr         14
 
 
/*      System wide name size (for symbols)     */
/*      System wide name size (for symbols)     */
#define namesize        9
#define namesize        9
#define namemax         8
#define namemax         8
 
 
/*      Define possible entries for "ident"     */
/*      Define possible entries for "ident"     */
#define variable        1
#define variable        1
#define array           2
#define array           2
#define pointer         3
#define pointer         3
#define function        4
#define function        4
 
 
/*      Define possible entries for "type"      */
/*      Define possible entries for "type"      */
#define cchar           1
#define cchar           1
#define cint            2
#define cint            2
#define cport           3 
#define cport           3 
 
 
/*      Define possible entries for "storage"   */
/*      Define possible entries for "storage"   */
#define statik          1
#define statik          1
#define stkloc          2
#define stkloc          2
 
 
/*      Define the "while" statement queue      */
/*      Define the "while" statement queue      */
#define wqtabsz         300
#define wqtabsz         300
#define wqsiz           4
#define wqsiz           4
#define wqmax           wq+wqtabsz-wqsiz
#define wqmax           wq+wqtabsz-wqsiz
 
 
/*      Define entry offsets in while queue     */
/*      Define entry offsets in while queue     */
#define wqsym           0
#define wqsym           0
#define wqsp            1
#define wqsp            1
#define wqloop          2
#define wqloop          2
#define wqlab           3
#define wqlab           3
 
 
/*      Define the literal pool                 */
/*      Define the literal pool                 */
#define litabsz         8000
#define litabsz         8000
#define litmax          litabsz-1
#define litmax          litabsz-1
 
 
/*      Define the input line                   */
/*      Define the input line                   */
#define linesize        256
#define linesize        256
#define linemax         linesize-1
#define linemax         linesize-1
#define mpmax           linemax
#define mpmax           linemax
 
 
/*      Define the macro (define) pool          */
/*      Define the macro (define) pool          */
#define macqsize        3000
#define macqsize        3000
#define macmax          macqsize-1
#define macmax          macqsize-1
 
 
/*      Define statement types (tokens)         */
/*      Define statement types (tokens)         */
#define stif            1
#define stif            1
#define stwhile         2
#define stwhile         2
#define streturn        3
#define streturn        3
#define stbreak         4
#define stbreak         4
#define stcont          5
#define stcont          5
#define stasm           6
#define stasm           6
#define stexp           7
#define stexp           7
 
 
/* Define how to carve up a name too long for the assembler */
/* Define how to carve up a name too long for the assembler */
#define asmpref         7
#define asmpref         7
#define asmsuff         7
#define asmsuff         7
 
 
// define the global variable init values que size 
// define the global variable init values que size 
#define initqsz         8192
#define initqsz         8192
 
 
/*      Now reserve some storage words          */
/*      Now reserve some storage words          */
char    symtab[symtbsz];        /* symbol table */
char    symtab[symtbsz];        /* symbol table */
char    *glbptr,*locptr;        /* ptrs to next entries */
char    *glbptr,*locptr;        /* ptrs to next entries */
 
 
int             wq[wqtabsz];            /* while queue */
int             wq[wqtabsz];            /* while queue */
int             *wqptr;                         /* ptr to next entry */
int             *wqptr;                         /* ptr to next entry */
 
 
char    litq[litabsz];          /* literal pool */
char    litq[litabsz];          /* literal pool */
int             litptr;                         /* ptr to next entry */
int             litptr;                         /* ptr to next entry */
 
 
char    macq[macqsize];         /* macro string buffer */
char    macq[macqsize];         /* macro string buffer */
int             macptr;                         /* and its index */
int             macptr;                         /* and its index */
 
 
char    inittbq[initqsz];       // init value buffer 
char    inittbq[initqsz];       // init value buffer 
int             inittbptr;                      // and its index 
int             inittbptr;                      // and its index 
 
 
char    line[linesize];         /* parsing buffer */
char    line[linesize];         /* parsing buffer */
char    mline[linesize];        /* temp macro buffer */
char    mline[linesize];        /* temp macro buffer */
int             lptr,mptr;                      /* ptrs into each */
int             lptr,mptr;                      /* ptrs into each */
 
 
/*      Misc storage    */
/*      Misc storage    */
int     nxtlab,         /* next avail label # */
int     nxtlab,         /* next avail label # */
        litlab,         /* label # assigned to literal pool */
        litlab,         /* label # assigned to literal pool */
        Zsp,            /* compiler relative stk ptr */
        Zsp,            /* compiler relative stk ptr */
        argstk,         /* function arg sp */
        argstk,         /* function arg sp */
        ncmp,           /* # open compound statements */
        ncmp,           /* # open compound statements */
        errcnt,         /* # errors in compilation */
        errcnt,         /* # errors in compilation */
        errstop,        /* stop on error                        gtf 7/17/80 */
        errstop,        /* stop on error                        gtf 7/17/80 */
        eof,            /* set non-zero on final input eof */
        eof,            /* set non-zero on final input eof */
        input,          /* iob # for input file */
        input,          /* iob # for input file */
        output,         /* iob # for output file (if any) */
        output,         /* iob # for output file (if any) */
        outputv,        /* output valid flag */
        outputv,        /* output valid flag */
        input2,         /* iob # for "include" file */
        input2,         /* iob # for "include" file */
        glbflag,        /* non-zero if internal globals */
        glbflag,        /* non-zero if internal globals */
        ctext,          /* non-zero to intermix c-source */
        ctext,          /* non-zero to intermix c-source */
        cmode,          /* non-zero while parsing c-code */
        cmode,          /* non-zero while parsing c-code */
                        /* zero when passing assembly code */
                        /* zero when passing assembly code */
        lastst,         /* last executed statement type */
        lastst,         /* last executed statement type */
        mainflg,        /* output is to be first asm file       gtf 4/9/80 */
        mainflg,        /* output is to be first asm file       gtf 4/9/80 */
        saveout,        /* holds output ptr when diverted to console       */
        saveout,        /* holds output ptr when diverted to console       */
                        /*                                      gtf 7/16/80 */
                        /*                                      gtf 7/16/80 */
        fnstart,        /* line# of start of current fn.        gtf 7/2/80 */
        fnstart,        /* line# of start of current fn.        gtf 7/2/80 */
        lineno,         /* line# in current file                gtf 7/2/80 */
        lineno,         /* line# in current file                gtf 7/2/80 */
        infunc,         /* "inside function" flag               gtf 7/2/80 */
        infunc,         /* "inside function" flag               gtf 7/2/80 */
        savestart,      /* copy of fnstart "    "               gtf 7/16/80 */
        savestart,      /* copy of fnstart "    "               gtf 7/16/80 */
        saveline,       /* copy of lineno  "    "               gtf 7/16/80 */
        saveline,       /* copy of lineno  "    "               gtf 7/16/80 */
        saveinfn;       /* copy of infunc  "    "               gtf 7/16/80 */
        saveinfn;       /* copy of infunc  "    "               gtf 7/16/80 */
 
 
char   *currfn,         /* ptr to symtab entry for current fn.  gtf 7/17/80 */
char   *currfn,         /* ptr to symtab entry for current fn.  gtf 7/17/80 */
       *savecurr;       /* copy of currfn for #include          gtf 7/17/80 */
       *savecurr;       /* copy of currfn for #include          gtf 7/17/80 */
char    *cptr;          /* work ptr to any char buffer */
char    *cptr;          /* work ptr to any char buffer */
int     *iptr;          /* work ptr to any int buffer */
int     *iptr;          /* work ptr to any int buffer */
 
 
// interactive mode flag 
// interactive mode flag 
int intmode;
int intmode;
// pointer array to input files list from argv[] 
// pointer array to input files list from argv[] 
#define MAXINFILES              64
#define MAXINFILES              64
char *infiles[MAXINFILES];
char *infiles[MAXINFILES];
int filesnum, filesidx;
int filesnum, filesidx;
// initial stack pointer value 
// initial stack pointer value 
int stackptr;
int stackptr;
 
 
/*      >>>>> start cc1 <<<<<<          */
/*      >>>>> start cc1 <<<<<<          */
 
 
/*                                      */
/*                                      */
/*      Compiler begins execution here  */
/*      Compiler begins execution here  */
/*                                      */
/*                                      */
void main(int argc, char *argv[])
void main(int argc, char *argv[])
{
{
int argi, phelp;
int argi, phelp;
 
 
        glbptr=startglb;        /* clear global symbols */
        glbptr=startglb;        /* clear global symbols */
        locptr=startloc;        /* clear local symbols */
        locptr=startloc;        /* clear local symbols */
        wqptr=wq;0;              /* clear while queue */
        wqptr=wq;0;              /* clear while queue */
        macptr=0;                /* clear the macro pool */
        macptr=0;                /* clear the macro pool */
        litptr=0;                /* clear literal pool */
        litptr=0;                /* clear literal pool */
        Zsp =0;                  /* stack ptr (relative) */
        Zsp =0;                  /* stack ptr (relative) */
        errcnt=0;                /* no errors */
        errcnt=0;                /* no errors */
        errstop=0;               /* keep going after an error            gtf 7/17/80 */
        errstop=0;               /* keep going after an error            gtf 7/17/80 */
        eof=0;                   /* not eof yet */
        eof=0;                   /* not eof yet */
        input=0;         /* no input file */
        input=0;         /* no input file */
        input2=0;                /* or include file */
        input2=0;                /* or include file */
        output=0;                /* no open units */
        output=0;                /* no open units */
        outputv=0;               /* output is not valid */
        outputv=0;               /* output is not valid */
        saveout=0;               /* no diverted output */
        saveout=0;               /* no diverted output */
        ncmp=0;                  /* no open compound states */
        ncmp=0;                  /* no open compound states */
        lastst=0;                /* no last statement yet */
        lastst=0;                /* no last statement yet */
        mainflg=0;               /* not first file to asm                gtf 4/9/80 */
        mainflg=0;               /* not first file to asm                gtf 4/9/80 */
        fnstart=0;               /* current "function" started at line 0 gtf 7/2/80 */
        fnstart=0;               /* current "function" started at line 0 gtf 7/2/80 */
        lineno=0;                /* no lines read from file              gtf 7/2/80 */
        lineno=0;                /* no lines read from file              gtf 7/2/80 */
        infunc=0;                /* not in function now                  gtf 7/2/80 */
        infunc=0;                /* not in function now                  gtf 7/2/80 */
        currfn=NULL;    /* no function yet                      gtf 7/2/80 */
        currfn=NULL;    /* no function yet                      gtf 7/2/80 */
        cmode=1;                /* enable preprocessing */
        cmode=1;                /* enable preprocessing */
        stackptr=0;              /* default value of stack pointer */
        stackptr=0;              /* default value of stack pointer */
        inittbptr=0;     // clear pointer to init array 
        inittbptr=0;     // clear pointer to init array 
 
 
        intmode = 1;    // default mode is interactive mode 
        intmode = 1;    // default mode is interactive mode 
        filesnum = 0;    // no input files for now 
        filesnum = 0;    // no input files for now 
        filesidx = 0;
        filesidx = 0;
 
 
        // print original banner 
        // print original banner 
        printf("\n");
        printf("\n");
        printf(" <><><><><><><><><><><><><><>X<><><><><><><><><><><><><><>\n");
        printf(" <><><><><><><><><><><><><><>X<><><><><><><><><><><><><><>\n");
        printf(" <><><>   Small-C  V1.2  DOS--CP/M Cross Compiler   <><><>\n");
        printf(" <><><>   Small-C  V1.2  DOS--CP/M Cross Compiler   <><><>\n");
        printf(" <><><><><><><><><><>   By Ron Cain   <><><><><><><><><><>\n");
        printf(" <><><><><><><><><><>   By Ron Cain   <><><><><><><><><><>\n");
        printf(" <><><><><>   CP/M Large String Space Version   <><><><><>\n");
        printf(" <><><><><>   CP/M Large String Space Version   <><><><><>\n");
        printf(" <><><><><><><><><><><><><><>X<><><><><><><><><><><><><><>\n");
        printf(" <><><><><><><><><><><><><><>X<><><><><><><><><><><><><><>\n");
 
 
        // print adapted banner and usage 
        // print adapted banner and usage 
        printf("\n");
        printf("\n");
        printf(" <><><><><><><><><><><><><><>X<><><><><><><><><><><><><><>\n");
        printf(" <><><><><><><><><><><><><><>X<><><><><><><><><><><><><><>\n");
        printf(" <><><>  Small-C adapted for embedded systems by  <><><><>\n");
        printf(" <><><>  Small-C adapted for embedded systems by  <><><><>\n");
        printf(" <><><><><><><><><>  Moti  Litochevski  <><><><><><><><><>\n");
        printf(" <><><><><><><><><>  Moti  Litochevski  <><><><><><><><><>\n");
        printf(" <><><><><><> Version 0.1 (February 20, 2012) <><><><><><>\n");
        printf(" <><><><><><> Version 0.1 (February 20, 2012) <><><><><><>\n");
        printf(" <><><><><><><><><><><><><><>X<><><><><><><><><><><><><><>\n");
        printf(" <><><><><><><><><><><><><><>X<><><><><><><><><><><><><><>\n");
        printf("\n");
        printf("\n");
        // check if command line options where specified 
        // check if command line options where specified 
        if (argc <= 1) {
        if (argc <= 1) {
                printf(" command line mode usage:\n");
                printf(" command line mode usage:\n");
                printf("      c80 -s<hexvalue> -o<filename> <input files>\n");
                printf("      c80 -s<hexvalue> -o<filename> <input files>\n");
                printf(" options:\n");
                printf(" options:\n");
                printf("      -s<hexvalue>   Initial stack pointer value in hex value.\n");
                printf("      -s<hexvalue>   Initial stack pointer value in hex value.\n");
                printf("                     Example: -s800 will init the stack pointer\n");
                printf("                     Example: -s800 will init the stack pointer\n");
                printf("                     to 0x800.\n");
                printf("                     to 0x800.\n");
                printf("      -o<filename>   Compiler output filename including extension.\n");
                printf("      -o<filename>   Compiler output filename including extension.\n");
                printf(" \n");
                printf(" \n");
        }
        }
 
 
        // start from the first valid argument 
        // start from the first valid argument 
        argi = 1;
        argi = 1;
        phelp = 0;
        phelp = 0;
    // loop through input options 
    // loop through input options 
    while (argi < argc) {
    while (argi < argc) {
            // copy pointer of the current option to the work buffer 
            // copy pointer of the current option to the work buffer 
            cptr = argv[argi];
            cptr = argv[argi];
            // loop through input options 
            // loop through input options 
            if (cptr[0] == '-') {
            if (cptr[0] == '-') {
                    // compiler options 
                    // compiler options 
                    if (cptr[1] == 's') {
                    if (cptr[1] == 's') {
                            // stack pointer address value 
                            // stack pointer address value 
                            sscanf(&cptr[2], "%x", &stackptr);
                            sscanf(&cptr[2], "%x", &stackptr);
                        } else if (cptr[1] == 'o') {
                        } else if (cptr[1] == 'o') {
                                // copy the output filename to the line 
                                // copy the output filename to the line 
                                strcpy(line, &cptr[2]);
                                strcpy(line, &cptr[2]);
                                // open output file 
                                // open output file 
                                openout(0);
                                openout(0);
                        } else if ((cptr[1] == 'h') | (cptr[1] == '?')) {
                        } else if ((cptr[1] == 'h') | (cptr[1] == '?')) {
                                // sign that only help should be printed 
                                // sign that only help should be printed 
                                phelp = 1;
                                phelp = 1;
                    } else {
                    } else {
                            printf("error: illegal option.\n");
                            printf("error: illegal option.\n");
                    }
                    }
                } else {
                } else {
                        // after all other options the list of input files is given and 
                        // after all other options the list of input files is given and 
                        // compiler is operated in non-interactive mode 
                        // compiler is operated in non-interactive mode 
                        intmode = 0;
                        intmode = 0;
 
 
                        // copy the input files names pointers to the local array 
                        // copy the input files names pointers to the local array 
                        for (filesnum=0; (argi < argc) && (filesnum < MAXINFILES); filesnum++) {
                        for (filesnum=0; (argi < argc) && (filesnum < MAXINFILES); filesnum++) {
                                infiles[filesnum] = argv[argi];
                                infiles[filesnum] = argv[argi];
                                argi++;
                                argi++;
                        }
                        }
                }
                }
                // update argument index 
                // update argument index 
                argi++;
                argi++;
    }
    }
 
 
    // check if compiler should be started 
    // check if compiler should be started 
    if (!phelp) {
    if (!phelp) {
            // announce interactive mode compiler 
            // announce interactive mode compiler 
                printf(" Starting compiler in interactive mode.\n\n");
                printf(" Starting compiler in interactive mode.\n\n");
                // compiler body 
                // compiler body 
                ask();                  /* get user options */
                ask();                  /* get user options */
                if (outputv == 0) openout(1);            /* get an output file */
                if (outputv == 0) openout(1);            /* get an output file */
                openin();               /* and initial input file */
                openin();               /* and initial input file */
                header();               /* intro code */
                header();               /* intro code */
                parse();                /* process ALL input */
                parse();                /* process ALL input */
                dumplits();             /* then dump literal pool */
                dumplits();             /* then dump literal pool */
                dumpglbs();             /* and all static memory */
                dumpglbs();             /* and all static memory */
                trailer();              /* follow-up code */
                trailer();              /* follow-up code */
                closeout();             /* close the output (if any) */
                closeout();             /* close the output (if any) */
                errorsummary();         /* summarize errors (on console!) */
                errorsummary();         /* summarize errors (on console!) */
        }
        }
        return;                 /* then exit to system */
        return;                 /* then exit to system */
}
}
 
 
/*                                      */
/*                                      */
/*      Abort compilation               */
/*      Abort compilation               */
/*              gtf 7/17/80             */
/*              gtf 7/17/80             */
zabort()
zabort()
{
{
        if(input2)
        if(input2)
                endinclude();
                endinclude();
        if(input)
        if(input)
                fclose(input);
                fclose(input);
        closeout();
        closeout();
        toconsole();
        toconsole();
        pl("Compilation aborted.");  nl();
        pl("Compilation aborted.");  nl();
        exit();
        exit();
/* end zabort */}
/* end zabort */}
 
 
/*                                      */
/*                                      */
/*      Process all input text          */
/*      Process all input text          */
/*                                      */
/*                                      */
/* At this level, only static declarations, */
/* At this level, only static declarations, */
/*      defines, includes, and function */
/*      defines, includes, and function */
/*      definitions are legal...        */
/*      definitions are legal...        */
parse()
parse()
{
{
        while (eof==0)           /* do until no more input */
        while (eof==0)           /* do until no more input */
        {
        {
                if(amatch("char",4)){declglb(cchar);ns();}
                if(amatch("char",4)){declglb(cchar);ns();}
                else if(amatch("int",3)){declglb(cint);ns();}
                else if(amatch("int",3)){declglb(cint);ns();}
                else if(amatch("port",4)){declglb(cport);ns();}
                else if(amatch("port",4)){declglb(cport);ns();}
                else if(match("#asm"))doasm();
                else if(match("#asm"))doasm();
                else if(match("#include"))doinclude();
                else if(match("#include"))doinclude();
                else if(match("#define"))addmac();
                else if(match("#define"))addmac();
                else newfunc();
                else newfunc();
                blanks();       /* force eof if pending */
                blanks();       /* force eof if pending */
        }
        }
}
}
/*                                      */
/*                                      */
/*      Dump the literal pool           */
/*      Dump the literal pool           */
/*                                      */
/*                                      */
dumplits()
dumplits()
        {int j,k;
        {int j,k;
        if (litptr==0) return;   /* if nothing there, exit...*/
        if (litptr==0) return;   /* if nothing there, exit...*/
        printlabel(litlab);col();nl(); /* print literal label */
        printlabel(litlab);col();nl(); /* print literal label */
        k=0;                     /* init an index... */
        k=0;                     /* init an index... */
        while (k<litptr)        /*      to loop with */
        while (k<litptr)        /*      to loop with */
                {defbyte();     /* pseudo-op to define byte */
                {defbyte();     /* pseudo-op to define byte */
                j=10;           /* max bytes per line */
                j=10;           /* max bytes per line */
                while(j--)
                while(j--)
                        {outdec((litq[k++]&127));
                        {outdec((litq[k++]&127));
                        if ((j==0) | (k>=litptr))
                        if ((j==0) | (k>=litptr))
                                {nl();          /* need <cr> */
                                {nl();          /* need <cr> */
                                break;
                                break;
                                }
                                }
                        outbyte(',');   /* separate bytes */
                        outbyte(',');   /* separate bytes */
                        }
                        }
                }
                }
        }
        }
/*                                      */
/*                                      */
/*      Dump all static variables       */
/*      Dump all static variables       */
/*                                      */
/*                                      */
dumpglbs()
dumpglbs()
{
{
int j,dptr,idx;
int j,dptr,idx;
 
 
        if (glbflag==0) return;  /* don't if user said no */
        if (glbflag==0) return;  /* don't if user said no */
        cptr=startglb;
        cptr=startglb;
        while (cptr<glbptr) {
        while (cptr<glbptr) {
                if ((cptr[ident]!=function) && (cptr[type]!=cport)) {
                if ((cptr[ident]!=function) && (cptr[type]!=cport)) {
                        // do if anything but function or port 
                        // do if anything but function or port 
                        // output name as label ... 
                        // output name as label ... 
                        outname(cptr);col();nl();
                        outname(cptr);col();nl();
                        // calculate number of bytes 
                        // calculate number of bytes 
                        j = ((cptr[offset]&255) + ((cptr[offset+1]&255)<<8));
                        j = ((cptr[offset]&255) + ((cptr[offset+1]&255)<<8));
                        if ((cptr[type]==cint) | (cptr[ident]==pointer))
                        if ((cptr[type]==cint) | (cptr[ident]==pointer))
                                j=j+j;  // 2 bytes for integer values 
                                j=j+j;  // 2 bytes for integer values 
                        // check if the global has an init value 
                        // check if the global has an init value 
                        dptr = ((cptr[initptr]&255) + ((cptr[initptr+1]&255)<<8));
                        dptr = ((cptr[initptr]&255) + ((cptr[initptr+1]&255)<<8));
                        // the value below represent the -1 value 
                        // the value below represent the -1 value 
                        if (dptr==0xffff) {
                        if (dptr==0xffff) {
                                // no init value, use original storage definition 
                                // no init value, use original storage definition 
                                // define storage 
                                // define storage 
                                defstorage();
                                defstorage();
                                outdec(j);      /* need that many */
                                outdec(j);      /* need that many */
                                nl();
                                nl();
                        }
                        }
                        else {
                        else {
                                // define the data section 
                                // define the data section 
                                defbyte();
                                defbyte();
                                // loop through init value 
                                // loop through init value 
                                idx=1;
                                idx=1;
                                while (j--) {
                                while (j--) {
                                        // write the next byte 
                                        // write the next byte 
                                        outdec(inittbq[dptr++]);
                                        outdec(inittbq[dptr++]);
                                        if ((j==0) | (dptr>=inittbptr)) {
                                        if ((j==0) | (dptr>=inittbptr)) {
                                                nl();           /* need <cr> */
                                                nl();           /* need <cr> */
                                                break;
                                                break;
                                        }
                                        }
                                        // every 10 values reopen the line 
                                        // every 10 values reopen the line 
                                        if (idx++ == 10) {
                                        if (idx++ == 10) {
                                                // add <cr> and restart byte definition 
                                                // add <cr> and restart byte definition 
                                                nl();
                                                nl();
                                                defbyte();
                                                defbyte();
                                                idx=1;
                                                idx=1;
                                        } else
                                        } else
                                                // separate bytes 
                                                // separate bytes 
                                                outbyte(',');
                                                outbyte(',');
                                }
                                }
                        }
                        }
                }
                }
                cptr=cptr+symsiz;
                cptr=cptr+symsiz;
        }
        }
}
}
/*                                      */
/*                                      */
/*      Report errors for user          */
/*      Report errors for user          */
/*                                      */
/*                                      */
errorsummary()
errorsummary()
{
{
        /* see if anything left hanging... */
        /* see if anything left hanging... */
        if (ncmp) error("missing closing bracket");
        if (ncmp) error("missing closing bracket");
                /* open compound statement ... */
                /* open compound statement ... */
        printf("\nThere were %d errors in compilation.\n\n", errcnt);
        printf("\nThere were %d errors in compilation.\n\n", errcnt);
}
}
 
 
/* Get options from user */
/* Get options from user */
ask()
ask()
{
{
int k,num[1];
int k,num[1];
 
 
        kill();                 /* clear input line */
        kill();                 /* clear input line */
        // by default enabling C text in the output file in form of comments (for clarity) 
        // by default enabling C text in the output file in form of comments (for clarity) 
        ctext=1;        /* user said yes */
        ctext=1;        /* user said yes */
        // by default assuming all files are compiled together 
        // by default assuming all files are compiled together 
        glbflag=1;      /* define globals */
        glbflag=1;      /* define globals */
        mainflg=1;      /* first file to assembler */
        mainflg=1;      /* first file to assembler */
        nxtlab =0;       /* start numbers at lowest possible */
        nxtlab =0;       /* start numbers at lowest possible */
        // compiler does noy pause on errors 
        // compiler does noy pause on errors 
        errstop=0;
        errstop=0;
 
 
        litlab=getlabel();      /* first label=literal pool */
        litlab=getlabel();      /* first label=literal pool */
        kill();                 /* erase line */
        kill();                 /* erase line */
}
}
 
 
/*                                      */
/*                                      */
/*      Get output filename             */
/*      Get output filename             */
/*                                      */
/*                                      */
openout(char flag)
openout(char flag)
{
{
        if (flag) {
        if (flag) {
                kill();                 /* erase line */
                kill();                 /* erase line */
                output=0;                /* start with none */
                output=0;                /* start with none */
                pl("Output filename? "); /* ask...*/
                pl("Output filename? "); /* ask...*/
                gets(line);     /* get a filename */
                gets(line);     /* get a filename */
        }
        }
        if(ch()==0)return;       /* none given... */
        if(ch()==0)return;       /* none given... */
        /* if given, open */
        /* if given, open */
        if((output=fopen(line,"w"))==NULL) {
        if((output=fopen(line,"w"))==NULL) {
                output=0;        /* can't open */
                output=0;        /* can't open */
                error("Open failure!");
                error("Open failure!");
        } else
        } else
                outputv = 1;
                outputv = 1;
        kill();                 /* erase line */
        kill();                 /* erase line */
}
}
/*                                      */
/*                                      */
/*      Get (next) input file           */
/*      Get (next) input file           */
/*                                      */
/*                                      */
openin()
openin()
{
{
        input=0;         /* none to start with */
        input=0;         /* none to start with */
        while (input==0) {       /* any above 1 allowed */
        while (input==0) {       /* any above 1 allowed */
                kill();         /* clear line */
                kill();         /* clear line */
                // check if we are using interactive mode or not 
                // check if we are using interactive mode or not 
                if (intmode) {
                if (intmode) {
                        // use the old style input file from the user 
                        // use the old style input file from the user 
                        if (eof) break; /* if user said none */
                        if (eof) break; /* if user said none */
                        pl("Input filename? ");
                        pl("Input filename? ");
                        gets(line);     /* get a name */
                        gets(line);     /* get a name */
                        if (ch()==0)
                        if (ch()==0)
                                {eof=1;break;} /* none given... */
                                {eof=1;break;} /* none given... */
                } else {
                } else {
                        // copy the file names from the name array 
                        // copy the file names from the name array 
                        if (filesidx < filesnum) {
                        if (filesidx < filesnum) {
                                strcpy(line, infiles[filesidx]);
                                strcpy(line, infiles[filesidx]);
                                printf("Processing Input file %d: %s\n", filesidx, line);
                                printf("Processing Input file %d: %s\n", filesidx, line);
                                filesidx++;
                                filesidx++;
                        } else {
                        } else {
                                // no more files 
                                // no more files 
                                eof=1;
                                eof=1;
                                break;
                                break;
                        }
                        }
                }
                }
 
 
                if ((input=fopen(line,"r"))!=NULL)
                if ((input=fopen(line,"r"))!=NULL)
                        newfile();                      /* gtf 7/16/80 */
                        newfile();                      /* gtf 7/16/80 */
                else {
                else {
                        input=0; /* can't open it */
                        input=0; /* can't open it */
                        pl("Open failure");
                        pl("Open failure");
                }
                }
        }
        }
        kill();         /* erase line */
        kill();         /* erase line */
}
}
 
 
/*                                      */
/*                                      */
/*      Reset line count, etc.          */
/*      Reset line count, etc.          */
/*                      gtf 7/16/80     */
/*                      gtf 7/16/80     */
newfile()
newfile()
{
{
        lineno  = 0;     /* no lines read */
        lineno  = 0;     /* no lines read */
        fnstart = 0;     /* no fn. start yet. */
        fnstart = 0;     /* no fn. start yet. */
        currfn  = NULL; /* because no fn. yet */
        currfn  = NULL; /* because no fn. yet */
        infunc  = 0;     /* therefore not in fn. */
        infunc  = 0;     /* therefore not in fn. */
/* end newfile */}
/* end newfile */}
 
 
/*                                      */
/*                                      */
/*      Open an include file            */
/*      Open an include file            */
/*                                      */
/*                                      */
doinclude()
doinclude()
{
{
        blanks();       /* skip over to name */
        blanks();       /* skip over to name */
 
 
        toconsole();                                    /* gtf 7/16/80 */
        toconsole();                                    /* gtf 7/16/80 */
        outstr("#include "); outstr(line+lptr); nl();
        outstr("#include "); outstr(line+lptr); nl();
        tofile();
        tofile();
 
 
        if(input2)                                      /* gtf 7/16/80 */
        if(input2)                                      /* gtf 7/16/80 */
                error("Cannot nest include files");
                error("Cannot nest include files");
        else if ((input2=fopen(line+lptr,"r"))==NULL) {
        else if ((input2=fopen(line+lptr,"r"))==NULL) {
                input2=0;
                input2=0;
                error("Open failure on include file");
                error("Open failure on include file");
        }
        }
        else {
        else {
                saveline = lineno;
                saveline = lineno;
                savecurr = currfn;
                savecurr = currfn;
                saveinfn = infunc;
                saveinfn = infunc;
                savestart= fnstart;
                savestart= fnstart;
                newfile();
                newfile();
        }
        }
        kill();         /* clear rest of line */
        kill();         /* clear rest of line */
                        /* so next read will come from */
                        /* so next read will come from */
                        /* new file (if open */
                        /* new file (if open */
}
}
 
 
/*                                      */
/*                                      */
/*      Close an include file           */
/*      Close an include file           */
/*                      gtf 7/16/80     */
/*                      gtf 7/16/80     */
endinclude()
endinclude()
{
{
        toconsole();
        toconsole();
        outstr("#end include"); nl();
        outstr("#end include"); nl();
        tofile();
        tofile();
 
 
        input2  = 0;
        input2  = 0;
        lineno  = saveline;
        lineno  = saveline;
        currfn  = savecurr;
        currfn  = savecurr;
        infunc  = saveinfn;
        infunc  = saveinfn;
        fnstart = savestart;
        fnstart = savestart;
/* end endinclude */}
/* end endinclude */}
 
 
/*                                      */
/*                                      */
/*      Close the output file           */
/*      Close the output file           */
/*                                      */
/*                                      */
closeout()
closeout()
{
{
        tofile();       /* if diverted, return to file */
        tofile();       /* if diverted, return to file */
        if(output)fclose(output); /* if open, close it */
        if(output)fclose(output); /* if open, close it */
        output=0;                /* mark as closed */
        output=0;                /* mark as closed */
}
}
/*                                      */
/*                                      */
/*      Declare a static variable       */
/*      Declare a static variable       */
/*        (i.e. define for use)         */
/*        (i.e. define for use)         */
/*                                      */
/*                                      */
/* makes an entry in the symbol table so subsequent */
/* makes an entry in the symbol table so subsequent */
/*  references can call symbol by name  */
/*  references can call symbol by name  */
declglb(typ)            /* typ is cchar or cint or cport (added by Moti Litchevski) */
declglb(typ)            /* typ is cchar or cint or cport (added by Moti Litchevski) */
        int typ;
        int typ;
{
{
int k,j,iptr,idx,num[1];
int k,j,iptr,idx,num[1];
char sname[namesize];
char sname[namesize];
 
 
        while (1) {
        while (1) {
                while (1) {
                while (1) {
                        if(endst())return;      /* do line */
                        if(endst())return;      /* do line */
                        k=1;            /* assume 1 element */
                        k=1;            /* assume 1 element */
                        if(match("*"))  /* pointer ? */
                        if(match("*"))  /* pointer ? */
                                j=pointer;      /* yes */
                                j=pointer;      /* yes */
                        else
                        else
                                j=variable; /* no */
                                j=variable; /* no */
 
 
                        // added by Moti Litochevski 
                        // added by Moti Litochevski 
                        if (match("(")) {
                        if (match("(")) {
                                // make sure this option is only used for port definition 
                                // make sure this option is only used for port definition 
                                if (typ != cport)
                                if (typ != cport)
                                        error("port address definition is only used for port type");
                                        error("port address definition is only used for port type");
                                // get port address 
                                // get port address 
                                k=portadr();
                                k=portadr();
                                k=k&0xff;
                                k=k&0xff;
                        } else if (typ == cport) {
                        } else if (typ == cport) {
                                error("port definition syntax error, need to define port address in brackets");
                                error("port definition syntax error, need to define port address in brackets");
                        }
                        }
 
 
                        if (symname(sname)==0) /* name ok? */
                        if (symname(sname)==0) /* name ok? */
                                illname(); /* no... */
                                illname(); /* no... */
                        if(findglb(sname)) /* already there? */
                        if(findglb(sname)) /* already there? */
                                multidef(sname);
                                multidef(sname);
                        if (match("[")) {       /* array? */
                        if (match("[")) {       /* array? */
                                if (typ==cport) error("port cannot be defined as an array");
                                if (typ==cport) error("port cannot be defined as an array");
                                k=needsub();    /* get size */
                                k=needsub();    /* get size */
                                if(k)j=array;   /* !0=array */
                                if(k)j=array;   /* !0=array */
                                else j=pointer; /* 0=ptr */
                                else j=pointer; /* 0=ptr */
                        }
                        }
 
 
                        // check if the declared global has a default value 
                        // check if the declared global has a default value 
                        if (match("=")) {
                        if (match("=")) {
                                // check if variable type supports init 
                                // check if variable type supports init 
                                if ((typ!=cchar) & (typ!=cint))
                                if ((typ!=cchar) & (typ!=cint))
                                        error("variable type does not support init value");
                                        error("variable type does not support init value");
 
 
                                // set the init pointer to the current init pointer 
                                // set the init pointer to the current init pointer 
                                iptr=inittbptr;
                                iptr=inittbptr;
                                idx=0;
                                idx=0;
 
 
                                // new defined variable has a default init value 
                                // new defined variable has a default init value 
                                // check if the variable is defined as string, list of values {} or a 
                                // check if the variable is defined as string, list of values {} or a 
                                // single value
                                // single value
                                if (match("\"")) {
                                if (match("\"")) {
                                        // init value is defined as a string 
                                        // init value is defined as a string 
                                        // copy the string values to the init buffer 
                                        // copy the string values to the init buffer 
                                        while (idx++ < k) {
                                        while (idx++ < k) {
                                                // check if new value is valid 
                                                // check if new value is valid 
                                                if ((ch() != '"') & (ch() != 0))
                                                if ((ch() != '"') & (ch() != 0))
                                                        inittbq[inittbptr++] = gch();
                                                        inittbq[inittbptr++] = gch();
                                                else
                                                else
                                                        inittbq[inittbptr++] = 0;
                                                        inittbq[inittbptr++] = 0;
 
 
                                                // check that init buffer is full 
                                                // check that init buffer is full 
                                                if (inittbptr == initqsz) {
                                                if (inittbptr == initqsz) {
                                                        // clear the variable init pointer and print error message 
                                                        // clear the variable init pointer and print error message 
                                                        iptr=0xffff;
                                                        iptr=0xffff;
                                                        error("init buffer is full, variable will not be initialized");
                                                        error("init buffer is full, variable will not be initialized");
                                                        // sign that init is done 
                                                        // sign that init is done 
                                                        idx=k;
                                                        idx=k;
                                                }
                                                }
                                        }
                                        }
                                        // look for matching quote mark 
                                        // look for matching quote mark 
                                        if (match("\"")==0) {
                                        if (match("\"")==0) {
                                                error("end of string expected");
                                                error("end of string expected");
                                        }
                                        }
                                }
                                }
                                else if (match("{")) {
                                else if (match("{")) {
                                        // init value is defined as a list of values 
                                        // init value is defined as a list of values 
                                        // copy the list of values to the init buffer 
                                        // copy the list of values to the init buffer 
                                        while (idx++ < k) {
                                        while (idx++ < k) {
                                                // check if new value is valid 
                                                // check if new value is valid 
                                                if ((ch() != '}') & (ch() != 0)) {
                                                if ((ch() != '}') & (ch() != 0)) {
                                                        // make sure that the next value is a number 
                                                        // make sure that the next value is a number 
                                                        if (!number(num) & !pstr(num))
                                                        if (!number(num) & !pstr(num))
                                                                error("could not find valid value in initialization list");
                                                                error("could not find valid value in initialization list");
                                                }
                                                }
                                                else
                                                else
                                                        // use zero value as init 
                                                        // use zero value as init 
                                                        num[0]=0;
                                                        num[0]=0;
 
 
                                                // save the values according to array type 
                                                // save the values according to array type 
                                                if (typ==cint) {
                                                if (typ==cint) {
                                                        inittbq[inittbptr++] = (char)(num[0]&255);
                                                        inittbq[inittbptr++] = (char)(num[0]&255);
                                                        inittbq[inittbptr++] = (char)((num[0]>>8)&255);
                                                        inittbq[inittbptr++] = (char)((num[0]>>8)&255);
                                                }
                                                }
                                                else
                                                else
                                                        inittbq[inittbptr++] = (char)(num[0]&255);
                                                        inittbq[inittbptr++] = (char)(num[0]&255);
 
 
                                                // check that init buffer is full 
                                                // check that init buffer is full 
                                                if (inittbptr == initqsz) {
                                                if (inittbptr == initqsz) {
                                                        // clear the variable init pointer and print error message 
                                                        // clear the variable init pointer and print error message 
                                                        iptr=0xffff;
                                                        iptr=0xffff;
                                                        error("init buffer is full, variable will not be initialized");
                                                        error("init buffer is full, variable will not be initialized");
                                                        // sign that init is done 
                                                        // sign that init is done 
                                                        idx=k;
                                                        idx=k;
                                                }
                                                }
                                                // remove comma if it is there 
                                                // remove comma if it is there 
                                                match(",");
                                                match(",");
                                        }
                                        }
                                        // look for ending brackets 
                                        // look for ending brackets 
                                        if (match("}")==0) {
                                        if (match("}")==0) {
                                                error("end of initialization list expected");
                                                error("end of initialization list expected");
                                        }
                                        }
                                }
                                }
                                else {
                                else {
                                        // expecting a single input value 
                                        // expecting a single input value 
                                        if (!number(num) & !pstr(num))
                                        if (!number(num) & !pstr(num))
                                                error("could not find initialization value");
                                                error("could not find initialization value");
 
 
                                        // save the values according to variable type 
                                        // save the values according to variable type 
                                        if (typ==cint) {
                                        if (typ==cint) {
                                                inittbq[inittbptr++] = (char)((num[0]>>16)&255);
                                                inittbq[inittbptr++] = (char)((num[0]>>16)&255);
                                                inittbq[inittbptr++] = (char)(num[0]&255);
                                                inittbq[inittbptr++] = (char)(num[0]&255);
                                        }
                                        }
                                        else
                                        else
                                                inittbq[inittbptr++] = (char)(num[0]&255);
                                                inittbq[inittbptr++] = (char)(num[0]&255);
                                        // update index 
                                        // update index 
                                        idx=1;
                                        idx=1;
 
 
                                        // init to end of array is more than one 
                                        // init to end of array is more than one 
                                        while (idx++ < k) {
                                        while (idx++ < k) {
                                                // fill the reset of the init list with zeros 
                                                // fill the reset of the init list with zeros 
                                                if (typ==cint) {
                                                if (typ==cint) {
                                                        inittbq[inittbptr++] = 0;
                                                        inittbq[inittbptr++] = 0;
                                                        inittbq[inittbptr++] = 0;
                                                        inittbq[inittbptr++] = 0;
                                                }
                                                }
                                                else
                                                else
                                                        inittbq[inittbptr++] = 0;
                                                        inittbq[inittbptr++] = 0;
 
 
                                                // check that init buffer is full 
                                                // check that init buffer is full 
                                                if (inittbptr == initqsz) {
                                                if (inittbptr == initqsz) {
                                                        // clear the variable init pointer and print error message 
                                                        // clear the variable init pointer and print error message 
                                                        iptr=0xffff;
                                                        iptr=0xffff;
                                                        error("init buffer is full, variable will not be initialized");
                                                        error("init buffer is full, variable will not be initialized");
                                                        // sign that init is done 
                                                        // sign that init is done 
                                                        idx=k;
                                                        idx=k;
                                                }
                                                }
                                        }
                                        }
                                }
                                }
                        } else {
                        } else {
                                // no default value point init pointer to null 
                                // no default value point init pointer to null 
                                iptr=0xffff;
                                iptr=0xffff;
                        }
                        }
                        // add symbol 
                        // add symbol 
                        addglb(sname,j,typ,k,iptr);
                        addglb(sname,j,typ,k,iptr);
                        break;
                        break;
                }
                }
                if (match(",")==0) return; /* more? */
                if (match(",")==0) return; /* more? */
        }
        }
}
}
/*                                      */
/*                                      */
/*      Declare local variables         */
/*      Declare local variables         */
/*      (i.e. define for use)           */
/*      (i.e. define for use)           */
/*                                      */
/*                                      */
/* works just like "declglb" but modifies machine stack */
/* works just like "declglb" but modifies machine stack */
/*      and adds symbol table entry with appropriate */
/*      and adds symbol table entry with appropriate */
/*      stack offset to find it again                   */
/*      stack offset to find it again                   */
declloc(typ)            /* typ is cchar or cint */
declloc(typ)            /* typ is cchar or cint */
        int typ;
        int typ;
        {
        {
        int k,j;char sname[namesize];
        int k,j;char sname[namesize];
        while(1)
        while(1)
                {while(1)
                {while(1)
                        {if(endst())return;
                        {if(endst())return;
                        if(match("*"))
                        if(match("*"))
                                j=pointer;
                                j=pointer;
                                else j=variable;
                                else j=variable;
                        if (symname(sname)==0)
                        if (symname(sname)==0)
                                illname();
                                illname();
                        if(findloc(sname))
                        if(findloc(sname))
                                multidef(sname);
                                multidef(sname);
                        if (match("["))
                        if (match("["))
                                {k=needsub();
                                {k=needsub();
                                if(k)
                                if(k)
                                        {j=array;
                                        {j=array;
                                        if(typ==cint)k=k+k;
                                        if(typ==cint)k=k+k;
                                        }
                                        }
                                else
                                else
                                        {j=pointer;
                                        {j=pointer;
                                        k=2;
                                        k=2;
                                        }
                                        }
                                }
                                }
                        else
                        else
                                if((typ==cchar)
                                if((typ==cchar)
                                        &(j!=pointer))
                                        &(j!=pointer))
                                        k=1;else k=2;
                                        k=1;else k=2;
                        /* change machine stack */
                        /* change machine stack */
                        Zsp=modstk(Zsp-k);
                        Zsp=modstk(Zsp-k);
                        addloc(sname,j,typ,Zsp);
                        addloc(sname,j,typ,Zsp);
                        break;
                        break;
                        }
                        }
                if (match(",")==0) return;
                if (match(",")==0) return;
                }
                }
        }
        }
/*      >>>>>> start of cc2 <<<<<<<<    */
/*      >>>>>> start of cc2 <<<<<<<<    */
 
 
/*                                      */
/*                                      */
/*      Get required array size         */
/*      Get required array size         */
/*                                      */
/*                                      */
/* invoked when declared variable is followed by "[" */
/* invoked when declared variable is followed by "[" */
/*      this routine makes subscript the absolute */
/*      this routine makes subscript the absolute */
/*      size of the array. */
/*      size of the array. */
needsub()
needsub()
{
{
int num[1];
int num[1];
 
 
        if(match("]"))return 0;  /* null size */
        if(match("]"))return 0;  /* null size */
        if (number(num)==0)      /* go after a number */
        if (number(num)==0)      /* go after a number */
                {error("must be constant");     /* it isn't */
                {error("must be constant");     /* it isn't */
                num[0]=1;                /* so force one */
                num[0]=1;                /* so force one */
                }
                }
        if (num[0]<0)
        if (num[0]<0)
                {error("negative size illegal");
                {error("negative size illegal");
                num[0]=(-num[0]);
                num[0]=(-num[0]);
                }
                }
        needbrack("]");         /* force single dimension */
        needbrack("]");         /* force single dimension */
        return num[0];           /* and return size */
        return num[0];           /* and return size */
}
}
//
//
// get array size function changed to get a port address 
// get array size function changed to get a port address 
//
//
portadr()
portadr()
{
{
int num[1];
int num[1];
 
 
        if(match(")")) {
        if(match(")")) {
                error("port address value must be defined");
                error("port address value must be defined");
                return 0;        /* null size */
                return 0;        /* null size */
        }
        }
        if (number(num)==0) {    /* go after a number */
        if (number(num)==0) {    /* go after a number */
                error("port address must be constant"); /* it isn't */
                error("port address must be constant"); /* it isn't */
                num[0]=1;                /* so force one */
                num[0]=1;                /* so force one */
        }
        }
        if (num[0]<0) {
        if (num[0]<0) {
                error("negative port address illegal");
                error("negative port address illegal");
                num[0]=(-num[0]);
                num[0]=(-num[0]);
        }
        }
        needbrack(")");         /* force single dimension */
        needbrack(")");         /* force single dimension */
        return num[0];           /* and return size */
        return num[0];           /* and return size */
}
}
 
 
/*                                      */
/*                                      */
/*      Begin a function                */
/*      Begin a function                */
/*                                      */
/*                                      */
/* Called from "parse" this routine tries to make a function */
/* Called from "parse" this routine tries to make a function */
/*      out of what follows.    */
/*      out of what follows.    */
newfunc()
newfunc()
        {
        {
        char n[namesize];       /* ptr => currfn,  gtf 7/16/80 */
        char n[namesize];       /* ptr => currfn,  gtf 7/16/80 */
        if (symname(n)==0)
        if (symname(n)==0)
                {error("illegal function or declaration");
                {error("illegal function or declaration");
                kill(); /* invalidate line */
                kill(); /* invalidate line */
                return;
                return;
                }
                }
        fnstart=lineno;         /* remember where fn began      gtf 7/2/80 */
        fnstart=lineno;         /* remember where fn began      gtf 7/2/80 */
        infunc=1;               /* note, in function now.       gtf 7/16/80 */
        infunc=1;               /* note, in function now.       gtf 7/16/80 */
        if(currfn=findglb(n))   /* already in symbol table ? */
        if(currfn=findglb(n))   /* already in symbol table ? */
                {if(currfn[ident]!=function)multidef(n);
                {if(currfn[ident]!=function)multidef(n);
                        /* already variable by that name */
                        /* already variable by that name */
                else if(currfn[offset]==function)multidef(n);
                else if(currfn[offset]==function)multidef(n);
                        /* already function by that name */
                        /* already function by that name */
                else currfn[offset]=function;
                else currfn[offset]=function;
                        /* otherwise we have what was earlier*/
                        /* otherwise we have what was earlier*/
                        /*  assumed to be a function */
                        /*  assumed to be a function */
                }
                }
        /* if not in table, define as a function now */
        /* if not in table, define as a function now */
        else currfn=addglb(n,function,cint,function,-1);
        else currfn=addglb(n,function,cint,function,-1);
 
 
        toconsole();                                    /* gtf 7/16/80 */
        toconsole();                                    /* gtf 7/16/80 */
        outstr("====== "); outstr(currfn+name); outstr("()"); nl();
        outstr("====== "); outstr(currfn+name); outstr("()"); nl();
        tofile();
        tofile();
 
 
        /* we had better see open paren for args... */
        /* we had better see open paren for args... */
        if(match("(")==0)error("missing open paren");
        if(match("(")==0)error("missing open paren");
        outname(n);col();nl();  /* print function name */
        outname(n);col();nl();  /* print function name */
        argstk=0;                /* init arg count */
        argstk=0;                /* init arg count */
        while(match(")")==0)     /* then count args */
        while(match(")")==0)     /* then count args */
                /* any legal name bumps arg count */
                /* any legal name bumps arg count */
                {if(symname(n))argstk=argstk+2;
                {if(symname(n))argstk=argstk+2;
                else{error("illegal argument name");junk();}
                else{error("illegal argument name");junk();}
                blanks();
                blanks();
                /* if not closing paren, should be comma */
                /* if not closing paren, should be comma */
                if(streq(line+lptr,")")==0)
                if(streq(line+lptr,")")==0)
                        {if(match(",")==0)
                        {if(match(",")==0)
                        error("expected comma");
                        error("expected comma");
                        }
                        }
                if(endst())break;
                if(endst())break;
                }
                }
        locptr=startloc;        /* "clear" local symbol table*/
        locptr=startloc;        /* "clear" local symbol table*/
        Zsp=0;                   /* preset stack ptr */
        Zsp=0;                   /* preset stack ptr */
        while(argstk)
        while(argstk)
                /* now let user declare what types of things */
                /* now let user declare what types of things */
                /*      those arguments were */
                /*      those arguments were */
                {if(amatch("char",4)){getarg(cchar);ns();}
                {if(amatch("char",4)){getarg(cchar);ns();}
                else if(amatch("int",3)){getarg(cint);ns();}
                else if(amatch("int",3)){getarg(cint);ns();}
                else{error("wrong number args");break;}
                else{error("wrong number args");break;}
                }
                }
        if(statement()!=streturn) /* do a statement, but if */
        if(statement()!=streturn) /* do a statement, but if */
                                /* it's a return, skip */
                                /* it's a return, skip */
                                /* cleaning up the stack */
                                /* cleaning up the stack */
                {modstk(0);
                {modstk(0);
                zret();
                zret();
                }
                }
        Zsp=0;                   /* reset stack ptr again */
        Zsp=0;                   /* reset stack ptr again */
        locptr=startloc;        /* deallocate all locals */
        locptr=startloc;        /* deallocate all locals */
        infunc=0;                /* not in fn. any more          gtf 7/2/80 */
        infunc=0;                /* not in fn. any more          gtf 7/2/80 */
        }
        }
/*                                      */
/*                                      */
/*      Declare argument types          */
/*      Declare argument types          */
/*                                      */
/*                                      */
/* called from "newfunc" this routine adds an entry in the */
/* called from "newfunc" this routine adds an entry in the */
/*      local symbol table for each named argument */
/*      local symbol table for each named argument */
getarg(t)               /* t = cchar or cint */
getarg(t)               /* t = cchar or cint */
        int t;
        int t;
        {
        {
        char n[namesize],c;int j;
        char n[namesize],c;int j;
        while(1)
        while(1)
                {if(argstk==0)return;    /* no more args */
                {if(argstk==0)return;    /* no more args */
                if(match("*"))j=pointer;
                if(match("*"))j=pointer;
                        else j=variable;
                        else j=variable;
                if(symname(n)==0) illname();
                if(symname(n)==0) illname();
                if(findloc(n))multidef(n);
                if(findloc(n))multidef(n);
                if(match("["))  /* pointer ? */
                if(match("["))  /* pointer ? */
                /* it is a pointer, so skip all */
                /* it is a pointer, so skip all */
                /* stuff between "[]" */
                /* stuff between "[]" */
                        {while(inbyte()!=']')
                        {while(inbyte()!=']')
                                if(endst())break;
                                if(endst())break;
                        j=pointer;
                        j=pointer;
                        /* add entry as pointer */
                        /* add entry as pointer */
                        }
                        }
                addloc(n,j,t,argstk);
                addloc(n,j,t,argstk);
                argstk=argstk-2;        /* cnt down */
                argstk=argstk-2;        /* cnt down */
                if(endst())return;
                if(endst())return;
                if(match(",")==0)error("expected comma");
                if(match(",")==0)error("expected comma");
                }
                }
        }
        }
/*                                      */
/*                                      */
/*      Statement parser                */
/*      Statement parser                */
/*                                      */
/*                                      */
/* called whenever syntax requires      */
/* called whenever syntax requires      */
/*      a statement.                     */
/*      a statement.                     */
/*  this routine performs that statement */
/*  this routine performs that statement */
/*  and returns a number telling which one */
/*  and returns a number telling which one */
statement()
statement()
{
{
        /* NOTE (RDK) --- On DOS there is no CPM function so just try */
        /* NOTE (RDK) --- On DOS there is no CPM function so just try */
        /* commenting it out for the first test compilation to see if */
        /* commenting it out for the first test compilation to see if */
        /* the compiler basic framework works OK in the DOS environment */
        /* the compiler basic framework works OK in the DOS environment */
        /* if(cpm(11,0) & 1)    /* check for ctrl-C gtf 7/17/80 */
        /* if(cpm(11,0) & 1)    /* check for ctrl-C gtf 7/17/80 */
                /* if(getchar()==3) */
                /* if(getchar()==3) */
                        /* zabort(); */
                        /* zabort(); */
 
 
        if ((ch()==0) & (eof)) return;
        if ((ch()==0) & (eof)) return;
        else if(amatch("char",4))
        else if(amatch("char",4))
                {declloc(cchar);ns();}
                {declloc(cchar);ns();}
        else if(amatch("int",3))
        else if(amatch("int",3))
                {declloc(cint);ns();}
                {declloc(cint);ns();}
        else if(match("{"))compound();
        else if(match("{"))compound();
        else if(amatch("if",2))
        else if(amatch("if",2))
                {doif();lastst=stif;}
                {doif();lastst=stif;}
        else if(amatch("while",5))
        else if(amatch("while",5))
                {dowhile();lastst=stwhile;}
                {dowhile();lastst=stwhile;}
        else if(amatch("return",6))
        else if(amatch("return",6))
                {doreturn();ns();lastst=streturn;}
                {doreturn();ns();lastst=streturn;}
        else if(amatch("break",5))
        else if(amatch("break",5))
                {dobreak();ns();lastst=stbreak;}
                {dobreak();ns();lastst=stbreak;}
        else if(amatch("continue",8))
        else if(amatch("continue",8))
                {docont();ns();lastst=stcont;}
                {docont();ns();lastst=stcont;}
        else if(match(";"));
        else if(match(";"));
        else if(match("#asm"))
        else if(match("#asm"))
                {doasm();lastst=stasm;}
                {doasm();lastst=stasm;}
        /* if nothing else, assume it's an expression */
        /* if nothing else, assume it's an expression */
        else{expression();ns();lastst=stexp;}
        else{expression();ns();lastst=stexp;}
        return lastst;
        return lastst;
}
}
/*                                      */
/*                                      */
/*      Semicolon enforcer              */
/*      Semicolon enforcer              */
/*                                      */
/*                                      */
/* called whenever syntax requires a semicolon */
/* called whenever syntax requires a semicolon */
ns()    {if(match(";")==0)error("missing semicolon");}
ns()    {if(match(";")==0)error("missing semicolon");}
/*                                      */
/*                                      */
/*      Compound statement              */
/*      Compound statement              */
/*                                      */
/*                                      */
/* allow any number of statements to fall between "{}" */
/* allow any number of statements to fall between "{}" */
compound()
compound()
        {
        {
        ++ncmp;         /* new level open */
        ++ncmp;         /* new level open */
        while (match("}")==0) statement(); /* do one */
        while (match("}")==0) statement(); /* do one */
        --ncmp;         /* close current level */
        --ncmp;         /* close current level */
        }
        }
/*                                      */
/*                                      */
/*              "if" statement          */
/*              "if" statement          */
/*                                      */
/*                                      */
doif()
doif()
        {
        {
        int flev,fsp,flab1,flab2;
        int flev,fsp,flab1,flab2;
        flev=locptr;    /* record current local level */
        flev=locptr;    /* record current local level */
        fsp=Zsp;                /* record current stk ptr */
        fsp=Zsp;                /* record current stk ptr */
        flab1=getlabel(); /* get label for false branch */
        flab1=getlabel(); /* get label for false branch */
        test(flab1);    /* get expression, and branch false */
        test(flab1);    /* get expression, and branch false */
        statement();    /* if true, do a statement */
        statement();    /* if true, do a statement */
        Zsp=modstk(fsp);        /* then clean up the stack */
        Zsp=modstk(fsp);        /* then clean up the stack */
        locptr=flev;    /* and deallocate any locals */
        locptr=flev;    /* and deallocate any locals */
        if (amatch("else",4)==0) /* if...else ? */
        if (amatch("else",4)==0) /* if...else ? */
                /* simple "if"...print false label */
                /* simple "if"...print false label */
                {printlabel(flab1);col();nl();
                {printlabel(flab1);col();nl();
                return;         /* and exit */
                return;         /* and exit */
                }
                }
        /* an "if...else" statement. */
        /* an "if...else" statement. */
        jump(flab2=getlabel()); /* jump around false code */
        jump(flab2=getlabel()); /* jump around false code */
        printlabel(flab1);col();nl();   /* print false label */
        printlabel(flab1);col();nl();   /* print false label */
        statement();            /* and do "else" clause */
        statement();            /* and do "else" clause */
        Zsp=modstk(fsp);                /* then clean up stk ptr */
        Zsp=modstk(fsp);                /* then clean up stk ptr */
        locptr=flev;            /* and deallocate locals */
        locptr=flev;            /* and deallocate locals */
        printlabel(flab2);col();nl();   /* print true label */
        printlabel(flab2);col();nl();   /* print true label */
        }
        }
/*                                      */
/*                                      */
/*      "while" statement               */
/*      "while" statement               */
/*                                      */
/*                                      */
dowhile()
dowhile()
        {
        {
        int wq[4];              /* allocate local queue */
        int wq[4];              /* allocate local queue */
        wq[wqsym]=locptr;       /* record local level */
        wq[wqsym]=locptr;       /* record local level */
        wq[wqsp]=Zsp;           /* and stk ptr */
        wq[wqsp]=Zsp;           /* and stk ptr */
        wq[wqloop]=getlabel();  /* and looping label */
        wq[wqloop]=getlabel();  /* and looping label */
        wq[wqlab]=getlabel();   /* and exit label */
        wq[wqlab]=getlabel();   /* and exit label */
        addwhile(wq);           /* add entry to queue */
        addwhile(wq);           /* add entry to queue */
                                /* (for "break" statement) */
                                /* (for "break" statement) */
        printlabel(wq[wqloop]);col();nl(); /* loop label */
        printlabel(wq[wqloop]);col();nl(); /* loop label */
        test(wq[wqlab]);        /* see if true */
        test(wq[wqlab]);        /* see if true */
        statement();            /* if so, do a statement */
        statement();            /* if so, do a statement */
        Zsp = modstk(wq[wqsp]); /* zap local vars: 9/25/80 gtf */
        Zsp = modstk(wq[wqsp]); /* zap local vars: 9/25/80 gtf */
        jump(wq[wqloop]);       /* loop to label */
        jump(wq[wqloop]);       /* loop to label */
        printlabel(wq[wqlab]);col();nl(); /* exit label */
        printlabel(wq[wqlab]);col();nl(); /* exit label */
        locptr=wq[wqsym];       /* deallocate locals */
        locptr=wq[wqsym];       /* deallocate locals */
        delwhile();             /* delete queue entry */
        delwhile();             /* delete queue entry */
        }
        }
/*                                      */
/*                                      */
/*      "return" statement              */
/*      "return" statement              */
/*                                      */
/*                                      */
doreturn()
doreturn()
        {
        {
        /* if not end of statement, get an expression */
        /* if not end of statement, get an expression */
        if(endst()==0)expression();
        if(endst()==0)expression();
        modstk(0);       /* clean up stk */
        modstk(0);       /* clean up stk */
        zret();         /* and exit function */
        zret();         /* and exit function */
        }
        }
/*                                      */
/*                                      */
/*      "break" statement               */
/*      "break" statement               */
/*                                      */
/*                                      */
dobreak()
dobreak()
        {
        {
        int *ptr;
        int *ptr;
        /* see if any "whiles" are open */
        /* see if any "whiles" are open */
        if ((ptr=readwhile())==0) return;        /* no */
        if ((ptr=readwhile())==0) return;        /* no */
        modstk((ptr[wqsp]));    /* else clean up stk ptr */
        modstk((ptr[wqsp]));    /* else clean up stk ptr */
        jump(ptr[wqlab]);       /* jump to exit label */
        jump(ptr[wqlab]);       /* jump to exit label */
        }
        }
/*                                      */
/*                                      */
/*      "continue" statement            */
/*      "continue" statement            */
/*                                      */
/*                                      */
docont()
docont()
        {
        {
        int *ptr;
        int *ptr;
        /* see if any "whiles" are open */
        /* see if any "whiles" are open */
        if ((ptr=readwhile())==0) return;        /* no */
        if ((ptr=readwhile())==0) return;        /* no */
        modstk((ptr[wqsp]));    /* else clean up stk ptr */
        modstk((ptr[wqsp]));    /* else clean up stk ptr */
        jump(ptr[wqloop]);      /* jump to loop label */
        jump(ptr[wqloop]);      /* jump to loop label */
        }
        }
/*                                      */
/*                                      */
/*      "asm" pseudo-statement          */
/*      "asm" pseudo-statement          */
/*                                      */
/*                                      */
/* enters mode where assembly language statement are */
/* enters mode where assembly language statement are */
/*      passed intact through parser    */
/*      passed intact through parser    */
doasm()
doasm()
{
{
        cmode=0;         /* mark mode as "asm" */
        cmode=0;         /* mark mode as "asm" */
        while (1) {
        while (1) {
                finline();      /* get and print lines */
                finline();      /* get and print lines */
                if (match("#endasm")) break;    /* until... */
                if (match("#endasm")) break;    /* until... */
                if(eof)break;
                if(eof)break;
                outstr(line);
                outstr(line);
                nl();
                nl();
        }
        }
        kill();         /* invalidate line */
        kill();         /* invalidate line */
        cmode=1;                /* then back to parse level */
        cmode=1;                /* then back to parse level */
}
}
/*      >>>>> start of cc3 <<<<<<<<<    */
/*      >>>>> start of cc3 <<<<<<<<<    */
 
 
/*                                      */
/*                                      */
/*      Perform a function call         */
/*      Perform a function call         */
/*                                      */
/*                                      */
/* called from heir11, this routine will either call */
/* called from heir11, this routine will either call */
/*      the named function, or if the supplied ptr is */
/*      the named function, or if the supplied ptr is */
/*      zero, will call the contents of HL              */
/*      zero, will call the contents of HL              */
callfunction(ptr)
callfunction(ptr)
        char *ptr;      /* symbol table entry (or 0) */
        char *ptr;      /* symbol table entry (or 0) */
{       int nargs;
{       int nargs;
        nargs=0;
        nargs=0;
        blanks();       /* already saw open paren */
        blanks();       /* already saw open paren */
        if(ptr==0)zpush();       /* calling HL */
        if(ptr==0)zpush();       /* calling HL */
        while(streq(line+lptr,")")==0)
        while(streq(line+lptr,")")==0)
                {if(endst())break;
                {if(endst())break;
                expression();   /* get an argument */
                expression();   /* get an argument */
                if(ptr==0)swapstk(); /* don't push addr */
                if(ptr==0)swapstk(); /* don't push addr */
                zpush();        /* push argument */
                zpush();        /* push argument */
                nargs=nargs+2;  /* count args*2 */
                nargs=nargs+2;  /* count args*2 */
                if (match(",")==0) break;
                if (match(",")==0) break;
                }
                }
        needbrack(")");
        needbrack(")");
        if(ptr)zcall(ptr);
        if(ptr)zcall(ptr);
        else callstk();
        else callstk();
        Zsp=modstk(Zsp+nargs);  /* clean up arguments */
        Zsp=modstk(Zsp+nargs);  /* clean up arguments */
}
}
junk()
junk()
{       if(an(inbyte()))
{       if(an(inbyte()))
                while(an(ch()))gch();
                while(an(ch()))gch();
        else while(an(ch())==0)
        else while(an(ch())==0)
                {if(ch()==0)break;
                {if(ch()==0)break;
                gch();
                gch();
                }
                }
        blanks();
        blanks();
}
}
endst()
endst()
{       blanks();
{       blanks();
        return ((streq(line+lptr,";")|(ch()==0)));
        return ((streq(line+lptr,";")|(ch()==0)));
}
}
illname()
illname()
{       error("illegal symbol name");junk();}
{       error("illegal symbol name");junk();}
multidef(sname)
multidef(sname)
        char *sname;
        char *sname;
{       error("already defined");
{       error("already defined");
        comment();
        comment();
        outstr(sname);nl();
        outstr(sname);nl();
}
}
needbrack(str)
needbrack(str)
        char *str;
        char *str;
{
{
        if (match(str)==0) {
        if (match(str)==0) {
                error("missing bracket");
                error("missing bracket");
                comment();outstr(str);nl();
                comment();outstr(str);nl();
        }
        }
}
}
needlval()
needlval()
{       error("must be lvalue");
{       error("must be lvalue");
}
}
findglb(sname)
findglb(sname)
        char *sname;
        char *sname;
{       char *ptr;
{       char *ptr;
        ptr=startglb;
        ptr=startglb;
        while(ptr!=glbptr) {
        while(ptr!=glbptr) {
                if (astreq(sname,ptr,namemax)) return ptr;
                if (astreq(sname,ptr,namemax)) return ptr;
                ptr=ptr+symsiz;
                ptr=ptr+symsiz;
        }
        }
        return 0;
        return 0;
}
}
findloc(sname)
findloc(sname)
        char *sname;
        char *sname;
{       char *ptr;
{       char *ptr;
        ptr=startloc;
        ptr=startloc;
        while (ptr!=locptr) {
        while (ptr!=locptr) {
                if(astreq(sname,ptr,namemax))return ptr;
                if(astreq(sname,ptr,namemax))return ptr;
                ptr=ptr+symsiz;
                ptr=ptr+symsiz;
        }
        }
        return 0;
        return 0;
}
}
addglb(sname,id,typ,value,iptr)
addglb(sname,id,typ,value,iptr)
        char *sname,id,typ;
        char *sname,id,typ;
        int value,iptr;
        int value,iptr;
{       char *ptr;
{       char *ptr;
        if(cptr=findglb(sname))return cptr;
        if(cptr=findglb(sname))return cptr;
        if(glbptr>=endglb)
        if(glbptr>=endglb)
                {error("global symbol table overflow");
                {error("global symbol table overflow");
                return 0;
                return 0;
                }
                }
        cptr=ptr=glbptr;
        cptr=ptr=glbptr;
        while (an(*ptr++ = *sname++));  /* copy name */
        while (an(*ptr++ = *sname++));  /* copy name */
        cptr[ident]=id;
        cptr[ident]=id;
        cptr[type]=typ;
        cptr[type]=typ;
        cptr[storage]=statik;
        cptr[storage]=statik;
        cptr[offset]=value;
        cptr[offset]=value;
        cptr[offset+1]=value>>8;
        cptr[offset+1]=value>>8;
        cptr[initptr]=iptr&255;
        cptr[initptr]=iptr&255;
        cptr[initptr+1]=iptr>>8;
        cptr[initptr+1]=iptr>>8;
        glbptr=glbptr+symsiz;
        glbptr=glbptr+symsiz;
        return cptr;
        return cptr;
}
}
addloc(sname,id,typ,value)
addloc(sname,id,typ,value)
        char *sname,id,typ;
        char *sname,id,typ;
        int value;
        int value;
{       char *ptr;
{       char *ptr;
        if(cptr=findloc(sname))return cptr;
        if(cptr=findloc(sname))return cptr;
        if(locptr>=endloc)
        if(locptr>=endloc)
                {error("local symbol table overflow");
                {error("local symbol table overflow");
                return 0;
                return 0;
                }
                }
        cptr=ptr=locptr;
        cptr=ptr=locptr;
        while(an(*ptr++ = *sname++));   /* copy name */
        while(an(*ptr++ = *sname++));   /* copy name */
        cptr[ident]=id;
        cptr[ident]=id;
        cptr[type]=typ;
        cptr[type]=typ;
        cptr[storage]=stkloc;
        cptr[storage]=stkloc;
        cptr[offset]=value;
        cptr[offset]=value;
        cptr[offset+1]=value>>8;
        cptr[offset+1]=value>>8;
        locptr=locptr+symsiz;
        locptr=locptr+symsiz;
        return cptr;
        return cptr;
}
}
/* Test if next input string is legal symbol name */
/* Test if next input string is legal symbol name */
symname(sname)
symname(sname)
        char *sname;
        char *sname;
{       int k;char c;
{       int k;char c;
        blanks();
        blanks();
        if(alpha(ch())==0)return 0;
        if(alpha(ch())==0)return 0;
        k=0;
        k=0;
        while(an(ch()))sname[k++]=gch();
        while(an(ch()))sname[k++]=gch();
        sname[k]=0;
        sname[k]=0;
        return 1;
        return 1;
        }
        }
/* Return next avail internal label number */
/* Return next avail internal label number */
getlabel()
getlabel()
{       return(++nxtlab);
{       return(++nxtlab);
}
}
/* Print specified number as label */
/* Print specified number as label */
printlabel(label)
printlabel(label)
        int label;
        int label;
{       outasm("cc");
{       outasm("cc");
        outdec(label);
        outdec(label);
}
}
/* Test if given character is alpha */
/* Test if given character is alpha */
alpha(c)
alpha(c)
        char c;
        char c;
{       c=c&127;
{       c=c&127;
        return(((c>='a')&(c<='z'))|
        return(((c>='a')&(c<='z'))|
                ((c>='A')&(c<='Z'))|
                ((c>='A')&(c<='Z'))|
                (c=='_'));
                (c=='_'));
}
}
// Test if given character is numeric 
// Test if given character is numeric 
numeric(c)
numeric(c)
        char c;
        char c;
{       c=c&127;
{       c=c&127;
        return ((c>='0')&(c<='9'));
        return ((c>='0')&(c<='9'));
}
}
// Test if given character is hexadecimal 
// Test if given character is hexadecimal 
hexnum(c)
hexnum(c)
        char c;
        char c;
{       c=c&127;
{       c=c&127;
        return (((c>='0')&(c<='9')) | ((c>='a')&(c<='f')) | ((c>='A')&(c<='F')));
        return (((c>='0')&(c<='9')) | ((c>='a')&(c<='f')) | ((c>='A')&(c<='F')));
}
}
/* Test if given character is alphanumeric */
/* Test if given character is alphanumeric */
an(c)
an(c)
        char c;
        char c;
{       return((alpha(c))|(numeric(c)));
{       return((alpha(c))|(numeric(c)));
}
}
/* Print a carriage return and a string only to console */
/* Print a carriage return and a string only to console */
pl(str)
pl(str)
        char *str;
        char *str;
{       int k;
{       int k;
        k=0;
        k=0;
        putchar(eol);
        putchar(eol);
        while(str[k])putchar(str[k++]);
        while(str[k])putchar(str[k++]);
}
}
addwhile(ptr)
addwhile(ptr)
        int ptr[];
        int ptr[];
 {
 {
        int k;
        int k;
        if (wqptr==wqmax)
        if (wqptr==wqmax)
                {error("too many active whiles");return;}
                {error("too many active whiles");return;}
        k=0;
        k=0;
        while (k<wqsiz)
        while (k<wqsiz)
                {*wqptr++ = ptr[k++];}
                {*wqptr++ = ptr[k++];}
}
}
delwhile()
delwhile()
        {if(readwhile()) wqptr=wqptr-wqsiz;
        {if(readwhile()) wqptr=wqptr-wqsiz;
        }
        }
readwhile()
readwhile()
 {
 {
        if (wqptr==wq){error("no active whiles");return 0;}
        if (wqptr==wq){error("no active whiles");return 0;}
        else return (wqptr-wqsiz);
        else return (wqptr-wqsiz);
 }
 }
ch()
ch()
{       return(line[lptr]&127);
{       return(line[lptr]&127);
}
}
nch()
nch()
{       if(ch()==0)return 0;
{       if(ch()==0)return 0;
                else return(line[lptr+1]&127);
                else return(line[lptr+1]&127);
}
}
gch()
gch()
{       if(ch()==0)return 0;
{       if(ch()==0)return 0;
                else return(line[lptr++]&127);
                else return(line[lptr++]&127);
}
}
kill()
kill()
{       lptr=0;
{       lptr=0;
        line[lptr]=0;
        line[lptr]=0;
}
}
inbyte()
inbyte()
{
{
        while(ch()==0)
        while(ch()==0)
                {if (eof) return 0;
                {if (eof) return 0;
                finline();
                finline();
                preprocess();
                preprocess();
                }
                }
        return gch();
        return gch();
}
}
inchar()
inchar()
{
{
        if(ch()==0)finline();
        if(ch()==0)finline();
        if(eof)return 0;
        if(eof)return 0;
        return(gch());
        return(gch());
}
}
finline()
finline()
{
{
        int k,unit;
        int k,unit;
        while(1)
        while(1)
                {if (input==0)openin();
                {if (input==0)openin();
                if(eof)return;
                if(eof)return;
                if((unit=input2)==0)unit=input;
                if((unit=input2)==0)unit=input;
                kill();
                kill();
                while((k=getc(unit))>0)
                while((k=getc(unit))>0)
                        {if((k==eol)|(lptr>=linemax))break;
                        {if((k==eol)|(lptr>=linemax))break;
                        line[lptr++]=k;
                        line[lptr++]=k;
                        }
                        }
                line[lptr]=0;    /* append null */
                line[lptr]=0;    /* append null */
                lineno++;       /* read one more line           gtf 7/2/80 */
                lineno++;       /* read one more line           gtf 7/2/80 */
                if(k<=0)
                if(k<=0)
                        {fclose(unit);
                        {fclose(unit);
                        if(input2)endinclude();         /* gtf 7/16/80 */
                        if(input2)endinclude();         /* gtf 7/16/80 */
                                else input=0;
                                else input=0;
                        }
                        }
                if(lptr)
                if(lptr)
                        {if((ctext)&(cmode))
                        {if((ctext)&(cmode))
                                {comment();
                                {comment();
                                outstr(line);
                                outstr(line);
                                nl();
                                nl();
                                }
                                }
                        lptr=0;
                        lptr=0;
                        return;
                        return;
                        }
                        }
                }
                }
}
}
/*      >>>>>> start of cc4 <<<<<<<     */
/*      >>>>>> start of cc4 <<<<<<<     */
 
 
keepch(c)
keepch(c)
        char c;
        char c;
{       mline[mptr]=c;
{       mline[mptr]=c;
        if(mptr<mpmax)mptr++;
        if(mptr<mpmax)mptr++;
        return c;
        return c;
}
}
preprocess()
preprocess()
{       int k;
{       int k;
        char c,sname[namesize];
        char c,sname[namesize];
        if(cmode==0)return;
        if(cmode==0)return;
        mptr=lptr=0;
        mptr=lptr=0;
        while(ch())
        while(ch())
                {if((ch()==' ')|(ch()==9))
                {if((ch()==' ')|(ch()==9))
                        {keepch(' ');
                        {keepch(' ');
                        while((ch()==' ')|
                        while((ch()==' ')|
                                (ch()==9))
                                (ch()==9))
                                gch();
                                gch();
                        }
                        }
                else if(ch()=='"')
                else if(ch()=='"')
                        {keepch(ch());
                        {keepch(ch());
                        gch();
                        gch();
                        while(ch()!='"')
                        while(ch()!='"')
                                {if(ch()==0)
                                {if(ch()==0)
                                  {error("missing quote");
                                  {error("missing quote");
                                  break;
                                  break;
                                  }
                                  }
                                keepch(gch());
                                keepch(gch());
                                }
                                }
                        gch();
                        gch();
                        keepch('"');
                        keepch('"');
                        }
                        }
                else if(ch()==39)
                else if(ch()==39)
                        {keepch(39);
                        {keepch(39);
                        gch();
                        gch();
                        while(ch()!=39)
                        while(ch()!=39)
                                {if(ch()==0)
                                {if(ch()==0)
                                  {error("missing apostrophe");
                                  {error("missing apostrophe");
                                  break;
                                  break;
                                  }
                                  }
                                keepch(gch());
                                keepch(gch());
                                }
                                }
                        gch();
                        gch();
                        keepch(39);
                        keepch(39);
                        }
                        }
                else if((ch()=='/')&(nch()=='/')) {
                else if((ch()=='/')&(nch()=='/')) {
                        // delete the entire line 
                        // delete the entire line 
                        kill();
                        kill();
                }
                }
                else if((ch()=='/')&(nch()=='*')) {
                else if((ch()=='/')&(nch()=='*')) {
                        inchar();inchar();
                        inchar();inchar();
                        while (((ch()=='*') & (nch()=='/'))==0) {
                        while (((ch()=='*') & (nch()=='/'))==0) {
                                if(ch()==0)finline();
                                if(ch()==0)finline();
                                        else inchar();
                                        else inchar();
                                if(eof)break;
                                if(eof)break;
                        }
                        }
                        inchar();inchar();
                        inchar();inchar();
                }
                }
                else if(alpha(ch()))    /* from an(): 9/22/80 gtf */
                else if(alpha(ch()))    /* from an(): 9/22/80 gtf */
                        {k=0;
                        {k=0;
                        while(an(ch()))
                        while(an(ch()))
                                {if(k<namemax)sname[k++]=ch();
                                {if(k<namemax)sname[k++]=ch();
                                gch();
                                gch();
                                }
                                }
                        sname[k]=0;
                        sname[k]=0;
                        if(k=findmac(sname))
                        if(k=findmac(sname))
                                while(c=macq[k++])
                                while(c=macq[k++])
                                        keepch(c);
                                        keepch(c);
                        else
                        else
                                {k=0;
                                {k=0;
                                while(c=sname[k++])
                                while(c=sname[k++])
                                        keepch(c);
                                        keepch(c);
                                }
                                }
                        }
                        }
                else keepch(gch());
                else keepch(gch());
                }
                }
        keepch(0);
        keepch(0);
        if(mptr>=mpmax)error("line too long");
        if(mptr>=mpmax)error("line too long");
        lptr=mptr=0;
        lptr=mptr=0;
        while(line[lptr++]=mline[mptr++]);
        while(line[lptr++]=mline[mptr++]);
        lptr=0;
        lptr=0;
        }
        }
addmac()
addmac()
{
{
char sname[namesize];
char sname[namesize];
int k;
int k;
 
 
        if (symname(sname)==0) {
        if (symname(sname)==0) {
                illname();
                illname();
                kill();
                kill();
                return;
                return;
        }
        }
        k=0;
        k=0;
        while (putmac(sname[k++]));
        while (putmac(sname[k++]));
        while (ch()==' ' | ch()==9) gch();
        while (ch()==' ' | ch()==9) gch();
        while (putmac(gch()));
        while (putmac(gch()));
        if (macptr>=macmax) error("macro table full");
        if (macptr>=macmax) error("macro table full");
}
}
putmac(c)
putmac(c)
        char c;
        char c;
{
{
        macq[macptr]=c;
        macq[macptr]=c;
        if(macptr<macmax)macptr++;
        if(macptr<macmax)macptr++;
        return c;
        return c;
}
}
findmac(sname)
findmac(sname)
        char *sname;
        char *sname;
{       int k;
{       int k;
        k=0;
        k=0;
        while (k<macptr) {
        while (k<macptr) {
                if (astreq(sname, macq+k, namemax)) {
                if (astreq(sname, macq+k, namemax)) {
                        while(macq[k++]);
                        while(macq[k++]);
                        return k;
                        return k;
                        }
                        }
                while(macq[k++]);
                while(macq[k++]);
                while(macq[k++]);
                while(macq[k++]);
        }
        }
        return 0;
        return 0;
}
}
/* direct output to console             gtf 7/16/80 */
/* direct output to console             gtf 7/16/80 */
toconsole()
toconsole()
{
{
        saveout = output;
        saveout = output;
        output = 0;
        output = 0;
/* end toconsole */}
/* end toconsole */}
 
 
/* direct output back to file           gtf 7/16/80 */
/* direct output back to file           gtf 7/16/80 */
tofile()
tofile()
{
{
        if(saveout)
        if(saveout)
                output = saveout;
                output = saveout;
        saveout = 0;
        saveout = 0;
/* end tofile */}
/* end tofile */}
 
 
outbyte(c)
outbyte(c)
        char c;
        char c;
{
{
        if(c==0)return 0;
        if(c==0)return 0;
        if(output)
        if(output)
                {if((putc(c,output))<=0)
                {if((putc(c,output))<=0)
                        {closeout();
                        {closeout();
                        error("Output file error");
                        error("Output file error");
                        zabort();                       /* gtf 7/17/80 */
                        zabort();                       /* gtf 7/17/80 */
                        }
                        }
                }
                }
        else putchar(c);
        else putchar(c);
        return c;
        return c;
}
}
outstr(ptr)
outstr(ptr)
        char ptr[];
        char ptr[];
 {
 {
        int k;
        int k;
        k=0;
        k=0;
        while(outbyte(ptr[k++]));
        while(outbyte(ptr[k++]));
 }
 }
 
 
/* write text destined for the assembler to read */
/* write text destined for the assembler to read */
/* (i.e. stuff not in comments)                 */
/* (i.e. stuff not in comments)                 */
/*  gtf  6/26/80 */
/*  gtf  6/26/80 */
outasm(ptr)
outasm(ptr)
char *ptr;
char *ptr;
{
{
        while(outbyte(lower(*ptr++)));
        while(outbyte(lower(*ptr++)));
/* end outasm */}
/* end outasm */}
 
 
nl()
nl()
        {outbyte(eol);}
        {outbyte(eol);}
tab()
tab()
        {outbyte(9);}
        {outbyte(9);}
col()
col()
        {outbyte(58);}
        {outbyte(58);}
bell()                          /* gtf 7/16/80 */
bell()                          /* gtf 7/16/80 */
        {outbyte(7);}
        {outbyte(7);}
/*                              replaced 7/2/80 gtf
/*                              replaced 7/2/80 gtf
 * error(ptr)
 * error(ptr)
 *      char ptr[];
 *      char ptr[];
 * {
 * {
 *      int k;
 *      int k;
 *      comment();outstr(line);nl();comment();
 *      comment();outstr(line);nl();comment();
 *      k=0;
 *      k=0;
 *      while(k<lptr)
 *      while(k<lptr)
 *              {if(line[k]==9) tab();
 *              {if(line[k]==9) tab();
 *                      else outbyte(' ');
 *                      else outbyte(' ');
 *              ++k;
 *              ++k;
 *              }
 *              }
 *      outbyte('^');
 *      outbyte('^');
 *      nl();comment();outstr("******  ");
 *      nl();comment();outstr("******  ");
 *      outstr(ptr);
 *      outstr(ptr);
 *      outstr("  ******");
 *      outstr("  ******");
 *      nl();
 *      nl();
 *      ++errcnt;
 *      ++errcnt;
 * }
 * }
 */
 */
 
 
error(ptr)
error(ptr)
char ptr[];
char ptr[];
{       int k;
{       int k;
        char junk[81];
        char junk[81];
 
 
        toconsole();
        toconsole();
        bell();
        bell();
        outstr("Line "); outdec(lineno); outstr(", ");
        outstr("Line "); outdec(lineno); outstr(", ");
        if(infunc==0)
        if(infunc==0)
                outbyte('(');
                outbyte('(');
        if(currfn==NULL)
        if(currfn==NULL)
                outstr("start of file");
                outstr("start of file");
        else    outstr(currfn+name);
        else    outstr(currfn+name);
        if(infunc==0)
        if(infunc==0)
                outbyte(')');
                outbyte(')');
        outstr(" + ");
        outstr(" + ");
        outdec(lineno-fnstart);
        outdec(lineno-fnstart);
        outstr(": ");  outstr(ptr);  nl();
        outstr(": ");  outstr(ptr);  nl();
 
 
        outstr(line); nl();
        outstr(line); nl();
 
 
        k=0;     /* skip to error position */
        k=0;     /* skip to error position */
        while(k<lptr){
        while(k<lptr){
                if(line[k++]==9)
                if(line[k++]==9)
                        tab();
                        tab();
                else    outbyte(' ');
                else    outbyte(' ');
                }
                }
        outbyte('^');  nl();
        outbyte('^');  nl();
        ++errcnt;
        ++errcnt;
 
 
        if(errstop){
        if(errstop){
                pl("Continue (Y,n,g) ? ");
                pl("Continue (Y,n,g) ? ");
                gets(junk);
                gets(junk);
                k=junk[0];
                k=junk[0];
                if((k=='N') | (k=='n'))
                if((k=='N') | (k=='n'))
                        zabort();
                        zabort();
                if((k=='G') | (k=='g'))
                if((k=='G') | (k=='g'))
                        errstop=0;
                        errstop=0;
                }
                }
        tofile();
        tofile();
/* end error */}
/* end error */}
 
 
ol(ptr)
ol(ptr)
        char ptr[];
        char ptr[];
{
{
        ot(ptr);
        ot(ptr);
        nl();
        nl();
}
}
ot(ptr)
ot(ptr)
        char ptr[];
        char ptr[];
{
{
        tab();
        tab();
        outasm(ptr);
        outasm(ptr);
}
}
streq(str1,str2)
streq(str1,str2)
        char str1[],str2[];
        char str1[],str2[];
{
{
int k;
int k;
 
 
        k=0;
        k=0;
        while (str2[k])
        while (str2[k])
                {if ((str1[k])!=(str2[k])) return 0;
                {if ((str1[k])!=(str2[k])) return 0;
                k++;
                k++;
                }
                }
        return k;
        return k;
}
}
astreq(str1,str2,len)
astreq(str1,str2,len)
        char str1[],str2[];int len;
        char str1[],str2[];int len;
{
{
int k;
int k;
 
 
        k=0;
        k=0;
        while (k<len) {
        while (k<len) {
                if ((str1[k])!=(str2[k]))break;
                if ((str1[k])!=(str2[k]))break;
                if(str1[k]==0)break;
                if(str1[k]==0)break;
                if(str2[k]==0)break;
                if(str2[k]==0)break;
                k++;
                k++;
        }
        }
        if (an(str1[k]))return 0;
        if (an(str1[k]))return 0;
        if (an(str2[k]))return 0;
        if (an(str2[k]))return 0;
        return k;
        return k;
}
}
match(lit)
match(lit)
        char *lit;
        char *lit;
{
{
        int k;
        int k;
        blanks();
        blanks();
        if (k=streq(line+lptr,lit)) {
        if (k=streq(line+lptr,lit)) {
                lptr=lptr+k;
                lptr=lptr+k;
                return 1;
                return 1;
        }
        }
        return 0;
        return 0;
}
}
amatch(lit,len)
amatch(lit,len)
        char *lit;int len;
        char *lit;int len;
 {
 {
        int k;
        int k;
        blanks();
        blanks();
        if (k=astreq(line+lptr,lit,len))
        if (k=astreq(line+lptr,lit,len))
                {lptr=lptr+k;
                {lptr=lptr+k;
                while(an(ch())) inbyte();
                while(an(ch())) inbyte();
                return 1;
                return 1;
                }
                }
        return 0;
        return 0;
 }
 }
blanks()
blanks()
{
{
        while (1) {
        while (1) {
                while (ch()==0) {
                while (ch()==0) {
                        finline();
                        finline();
                        preprocess();
                        preprocess();
                        if(eof)break;
                        if(eof)break;
                }
                }
                if (ch()==' ') gch();
                if (ch()==' ') gch();
                else if (ch()==9) gch();
                else if (ch()==9) gch();
                else return;
                else return;
        }
        }
}
}
/* output a decimal number - rewritten 4/1/81 gtf */
/* output a decimal number - rewritten 4/1/81 gtf */
outdec(n)
outdec(n)
int n;
int n;
{
{
        if(n<0)
        if(n<0)
                outbyte('-');
                outbyte('-');
        else    n = -n;
        else    n = -n;
        outint(n);
        outint(n);
/* end outdec */}
/* end outdec */}
 
 
outint(n)       /* added 4/1/81 */
outint(n)       /* added 4/1/81 */
int n;
int n;
{       int q;
{       int q;
 
 
        q = n/10;
        q = n/10;
        if(q) outint(q);
        if(q) outint(q);
        outbyte('0'-(n-q*10));
        outbyte('0'-(n-q*10));
/* end outint */}
/* end outint */}
 
 
/* return the length of a string */
/* return the length of a string */
/* gtf 4/8/80 */
/* gtf 4/8/80 */
strlen(s)
strlen(s)
char *s;
char *s;
{       char *t;
{       char *t;
 
 
        t = s;
        t = s;
        while(*s) s++;
        while(*s) s++;
        return(s-t);
        return(s-t);
/* end strlen */}
/* end strlen */}
 
 
/* convert lower case to upper */
/* convert lower case to upper */
/* gtf 6/26/80 */
/* gtf 6/26/80 */
raise(c)
raise(c)
char c;
char c;
{
{
        if((c>='a') & (c<='z'))
        if((c>='a') & (c<='z'))
                c = c - 'a' + 'A';
                c = c - 'a' + 'A';
        return(c);
        return(c);
/* end raise */}
/* end raise */}
 
 
/* convert upper case to lower */
/* convert upper case to lower */
/* ml 28/2/2012 */
/* ml 28/2/2012 */
lower(c)
lower(c)
char c;
char c;
{
{
        if((c>='A') & (c<='Z'))
        if((c>='A') & (c<='Z'))
                c = c - 'A' + 'a';
                c = c - 'A' + 'a';
        return(c);
        return(c);
/* end raise */}
/* end raise */}
 
 
/* ------------------------------------------------------------- */
/* ------------------------------------------------------------- */
 
 
/*      >>>>>>> start of cc5 <<<<<<<    */
/*      >>>>>>> start of cc5 <<<<<<<    */
 
 
/* as of 5/5/81 rj */
/* as of 5/5/81 rj */
 
 
expression()
expression()
{
{
        int lval[2];
        int lval[2];
        if(heir1(lval))rvalue(lval);
        if(heir1(lval))rvalue(lval);
}
}
heir1(lval)
heir1(lval)
        int lval[];
        int lval[];
{
{
        int k,lval2[2];
        int k,lval2[2];
        k=heir2(lval);
        k=heir2(lval);
        if (match("="))
        if (match("="))
                {if(k==0){needlval();return 0;}
                {if(k==0){needlval();return 0;}
                if (lval[1])zpush();
                if (lval[1])zpush();
                if(heir1(lval2))rvalue(lval2);
                if(heir1(lval2))rvalue(lval2);
                store(lval);
                store(lval);
                return 0;
                return 0;
                }
                }
        else return k;
        else return k;
}
}
heir2(lval)
heir2(lval)
        int lval[];
        int lval[];
{       int k,lval2[2];
{       int k,lval2[2];
        k=heir3(lval);
        k=heir3(lval);
        blanks();
        blanks();
        if(ch()!='|')return k;
        if(ch()!='|')return k;
        if(k)rvalue(lval);
        if(k)rvalue(lval);
        while(1)
        while(1)
                {if (match("|"))
                {if (match("|"))
                        {zpush();
                        {zpush();
                        if(heir3(lval2)) rvalue(lval2);
                        if(heir3(lval2)) rvalue(lval2);
                        zpop();
                        zpop();
                        zor();
                        zor();
                        }
                        }
                else return 0;
                else return 0;
                }
                }
}
}
heir3(lval)
heir3(lval)
        int lval[];
        int lval[];
{       int k,lval2[2];
{       int k,lval2[2];
        k=heir4(lval);
        k=heir4(lval);
        blanks();
        blanks();
        if(ch()!='^')return k;
        if(ch()!='^')return k;
        if(k)rvalue(lval);
        if(k)rvalue(lval);
        while(1)
        while(1)
                {if (match("^"))
                {if (match("^"))
                        {zpush();
                        {zpush();
                        if(heir4(lval2))rvalue(lval2);
                        if(heir4(lval2))rvalue(lval2);
                        zpop();
                        zpop();
                        zxor();
                        zxor();
                        }
                        }
                else return 0;
                else return 0;
                }
                }
}
}
heir4(lval)
heir4(lval)
        int lval[];
        int lval[];
{       int k,lval2[2];
{       int k,lval2[2];
        k=heir5(lval);
        k=heir5(lval);
        blanks();
        blanks();
        if(ch()!='&')return k;
        if(ch()!='&')return k;
        if(k)rvalue(lval);
        if(k)rvalue(lval);
        while(1)
        while(1)
                {if (match("&"))
                {if (match("&"))
                        {zpush();
                        {zpush();
                        if(heir5(lval2))rvalue(lval2);
                        if(heir5(lval2))rvalue(lval2);
                        zpop();
                        zpop();
                        zand();
                        zand();
                        }
                        }
                else return 0;
                else return 0;
                }
                }
}
}
heir5(lval)
heir5(lval)
        int lval[];
        int lval[];
{
{
        int k,lval2[2];
        int k,lval2[2];
        k=heir6(lval);
        k=heir6(lval);
        blanks();
        blanks();
        if((streq(line+lptr,"==")==0)&
        if((streq(line+lptr,"==")==0)&
                (streq(line+lptr,"!=")==0))return k;
                (streq(line+lptr,"!=")==0))return k;
        if(k)rvalue(lval);
        if(k)rvalue(lval);
        while(1)
        while(1)
                {if (match("=="))
                {if (match("=="))
                        {zpush();
                        {zpush();
                        if(heir6(lval2))rvalue(lval2);
                        if(heir6(lval2))rvalue(lval2);
                        zpop();
                        zpop();
                        zeq();
                        zeq();
                        }
                        }
                else if (match("!="))
                else if (match("!="))
                        {zpush();
                        {zpush();
                        if(heir6(lval2))rvalue(lval2);
                        if(heir6(lval2))rvalue(lval2);
                        zpop();
                        zpop();
                        zne();
                        zne();
                        }
                        }
                else return 0;
                else return 0;
                }
                }
}
}
heir6(lval)
heir6(lval)
        int lval[];
        int lval[];
{
{
        int k,lval2[2];
        int k,lval2[2];
        k=heir7(lval);
        k=heir7(lval);
        blanks();
        blanks();
        if((streq(line+lptr,"<")==0)&
        if((streq(line+lptr,"<")==0)&
                (streq(line+lptr,">")==0)&
                (streq(line+lptr,">")==0)&
                (streq(line+lptr,"<=")==0)&
                (streq(line+lptr,"<=")==0)&
                (streq(line+lptr,">=")==0))return k;
                (streq(line+lptr,">=")==0))return k;
                if(streq(line+lptr,">>"))return k;
                if(streq(line+lptr,">>"))return k;
                if(streq(line+lptr,"<<"))return k;
                if(streq(line+lptr,"<<"))return k;
        if(k)rvalue(lval);
        if(k)rvalue(lval);
        while(1)
        while(1)
                {if (match("<="))
                {if (match("<="))
                        {zpush();
                        {zpush();
                        if(heir7(lval2))rvalue(lval2);
                        if(heir7(lval2))rvalue(lval2);
                        zpop();
                        zpop();
                        if(cptr=lval[0])
                        if(cptr=lval[0])
                                if(cptr[ident]==pointer)
                                if(cptr[ident]==pointer)
                                {ule();
                                {ule();
                                continue;
                                continue;
                                }
                                }
                        if(cptr=lval2[0])
                        if(cptr=lval2[0])
                                if(cptr[ident]==pointer)
                                if(cptr[ident]==pointer)
                                {ule();
                                {ule();
                                continue;
                                continue;
                                }
                                }
                        zle();
                        zle();
                        }
                        }
                else if (match(">="))
                else if (match(">="))
                        {zpush();
                        {zpush();
                        if(heir7(lval2))rvalue(lval2);
                        if(heir7(lval2))rvalue(lval2);
                        zpop();
                        zpop();
                        if(cptr=lval[0])
                        if(cptr=lval[0])
                                if(cptr[ident]==pointer)
                                if(cptr[ident]==pointer)
                                {uge();
                                {uge();
                                continue;
                                continue;
                                }
                                }
                        if(cptr=lval2[0])
                        if(cptr=lval2[0])
                                if(cptr[ident]==pointer)
                                if(cptr[ident]==pointer)
                                {uge();
                                {uge();
                                continue;
                                continue;
                                }
                                }
                        zge();
                        zge();
                        }
                        }
                else if((streq(line+lptr,"<"))&
                else if((streq(line+lptr,"<"))&
                        (streq(line+lptr,"<<")==0))
                        (streq(line+lptr,"<<")==0))
                        {inbyte();
                        {inbyte();
                        zpush();
                        zpush();
                        if(heir7(lval2))rvalue(lval2);
                        if(heir7(lval2))rvalue(lval2);
                        zpop();
                        zpop();
                        if(cptr=lval[0])
                        if(cptr=lval[0])
                                if(cptr[ident]==pointer)
                                if(cptr[ident]==pointer)
                                {ult();
                                {ult();
                                continue;
                                continue;
                                }
                                }
                        if(cptr=lval2[0])
                        if(cptr=lval2[0])
                                if(cptr[ident]==pointer)
                                if(cptr[ident]==pointer)
                                {ult();
                                {ult();
                                continue;
                                continue;
                                }
                                }
                        zlt();
                        zlt();
                        }
                        }
                else if((streq(line+lptr,">"))&
                else if((streq(line+lptr,">"))&
                        (streq(line+lptr,">>")==0))
                        (streq(line+lptr,">>")==0))
                        {inbyte();
                        {inbyte();
                        zpush();
                        zpush();
                        if(heir7(lval2))rvalue(lval2);
                        if(heir7(lval2))rvalue(lval2);
                        zpop();
                        zpop();
                        if(cptr=lval[0])
                        if(cptr=lval[0])
                                if(cptr[ident]==pointer)
                                if(cptr[ident]==pointer)
                                {ugt();
                                {ugt();
                                continue;
                                continue;
                                }
                                }
                        if(cptr=lval2[0])
                        if(cptr=lval2[0])
                                if(cptr[ident]==pointer)
                                if(cptr[ident]==pointer)
                                {ugt();
                                {ugt();
                                continue;
                                continue;
                                }
                                }
                        zgt();
                        zgt();
                        }
                        }
                else return 0;
                else return 0;
                }
                }
}
}
/*      >>>>>> start of cc6 <<<<<<      */
/*      >>>>>> start of cc6 <<<<<<      */
 
 
heir7(lval)
heir7(lval)
        int lval[];
        int lval[];
{
{
        int k,lval2[2];
        int k,lval2[2];
        k=heir8(lval);
        k=heir8(lval);
        blanks();
        blanks();
        if((streq(line+lptr,">>")==0)&
        if((streq(line+lptr,">>")==0)&
                (streq(line+lptr,"<<")==0))return k;
                (streq(line+lptr,"<<")==0))return k;
        if(k)rvalue(lval);
        if(k)rvalue(lval);
        while(1)
        while(1)
                {if (match(">>"))
                {if (match(">>"))
                        {zpush();
                        {zpush();
                        if(heir8(lval2))rvalue(lval2);
                        if(heir8(lval2))rvalue(lval2);
                        zpop();
                        zpop();
                        asr();
                        asr();
                        }
                        }
                else if (match("<<"))
                else if (match("<<"))
                        {zpush();
                        {zpush();
                        if(heir8(lval2))rvalue(lval2);
                        if(heir8(lval2))rvalue(lval2);
                        zpop();
                        zpop();
                        asl();
                        asl();
                        }
                        }
                else return 0;
                else return 0;
                }
                }
}
}
heir8(lval)
heir8(lval)
        int lval[];
        int lval[];
{
{
        int k,lval2[2];
        int k,lval2[2];
        k=heir9(lval);
        k=heir9(lval);
        blanks();
        blanks();
        if((ch()!='+')&(ch()!='-'))return k;
        if((ch()!='+')&(ch()!='-'))return k;
        if(k)rvalue(lval);
        if(k)rvalue(lval);
        while(1)
        while(1)
                {if (match("+"))
                {if (match("+"))
                        {zpush();
                        {zpush();
                        if(heir9(lval2))rvalue(lval2);
                        if(heir9(lval2))rvalue(lval2);
                        if(cptr=lval[0])
                        if(cptr=lval[0])
                                if((cptr[ident]==pointer)&
                                if((cptr[ident]==pointer)&
                                (cptr[type]==cint))
                                (cptr[type]==cint))
                                doublereg();
                                doublereg();
                        zpop();
                        zpop();
                        zadd();
                        zadd();
                        }
                        }
                else if (match("-"))
                else if (match("-"))
                        {zpush();
                        {zpush();
                        if(heir9(lval2))rvalue(lval2);
                        if(heir9(lval2))rvalue(lval2);
                        if(cptr=lval[0])
                        if(cptr=lval[0])
                                if((cptr[ident]==pointer)&
                                if((cptr[ident]==pointer)&
                                (cptr[type]==cint))
                                (cptr[type]==cint))
                                doublereg();
                                doublereg();
                        zpop();
                        zpop();
                        zsub();
                        zsub();
                        }
                        }
                else return 0;
                else return 0;
                }
                }
}
}
heir9(lval)
heir9(lval)
        int lval[];
        int lval[];
{
{
        int k,lval2[2];
        int k,lval2[2];
        k=heir10(lval);
        k=heir10(lval);
        blanks();
        blanks();
        if((ch()!='*')&(ch()!='/')&
        if((ch()!='*')&(ch()!='/')&
                (ch()!='%'))return k;
                (ch()!='%'))return k;
        if(k)rvalue(lval);
        if(k)rvalue(lval);
        while(1)
        while(1)
                {if (match("*"))
                {if (match("*"))
                        {zpush();
                        {zpush();
                        if(heir9(lval2))rvalue(lval2);
                        if(heir9(lval2))rvalue(lval2);
                        zpop();
                        zpop();
                        mult();
                        mult();
                        }
                        }
                else if (match("/"))
                else if (match("/"))
                        {zpush();
                        {zpush();
                        if(heir10(lval2))rvalue(lval2);
                        if(heir10(lval2))rvalue(lval2);
                        zpop();
                        zpop();
                        div();
                        div();
                        }
                        }
                else if (match("%"))
                else if (match("%"))
                        {zpush();
                        {zpush();
                        if(heir10(lval2))rvalue(lval2);
                        if(heir10(lval2))rvalue(lval2);
                        zpop();
                        zpop();
                        zmod();
                        zmod();
                        }
                        }
                else return 0;
                else return 0;
                }
                }
}
}
heir10(lval)
heir10(lval)
        int lval[];
        int lval[];
{
{
        int k;
        int k;
        char *ptr;
        char *ptr;
        if(match("++"))
        if(match("++"))
                {if((k=heir10(lval))==0)
                {if((k=heir10(lval))==0)
                        {needlval();
                        {needlval();
                        return 0;
                        return 0;
                        }
                        }
                if(lval[1])zpush();
                if(lval[1])zpush();
                rvalue(lval);
                rvalue(lval);
                inc();
                inc();
                ptr=lval[0];
                ptr=lval[0];
                if((ptr[ident]==pointer)&
                if((ptr[ident]==pointer)&
                        (ptr[type]==cint))
                        (ptr[type]==cint))
                                inc();
                                inc();
                store(lval);
                store(lval);
                return 0;
                return 0;
                }
                }
        else if(match("--"))
        else if(match("--"))
                {if((k=heir10(lval))==0)
                {if((k=heir10(lval))==0)
                        {needlval();
                        {needlval();
                        return 0;
                        return 0;
                        }
                        }
                if(lval[1])zpush();
                if(lval[1])zpush();
                rvalue(lval);
                rvalue(lval);
                dec();
                dec();
                ptr=lval[0];
                ptr=lval[0];
                if((ptr[ident]==pointer)&
                if((ptr[ident]==pointer)&
                        (ptr[type]==cint))
                        (ptr[type]==cint))
                                dec();
                                dec();
                store(lval);
                store(lval);
                return 0;
                return 0;
                }
                }
        else if (match("-"))
        else if (match("-"))
                {k=heir10(lval);
                {k=heir10(lval);
                if (k) rvalue(lval);
                if (k) rvalue(lval);
                neg();
                neg();
                return 0;
                return 0;
                }
                }
        else if(match("*"))
        else if(match("*"))
                {k=heir10(lval);
                {k=heir10(lval);
                if(k)rvalue(lval);
                if(k)rvalue(lval);
                lval[1]=cint;
                lval[1]=cint;
                if(ptr=lval[0])lval[1]=ptr[type];
                if(ptr=lval[0])lval[1]=ptr[type];
                lval[0]=0;
                lval[0]=0;
                return 1;
                return 1;
                }
                }
        else if(match("&"))
        else if(match("&"))
                {k=heir10(lval);
                {k=heir10(lval);
                if(k==0)
                if(k==0)
                        {error("illegal address");
                        {error("illegal address");
                        return 0;
                        return 0;
                        }
                        }
                else if(lval[1])return 0;
                else if(lval[1])return 0;
                else
                else
                        {immed();
                        {immed();
                        outname(ptr=lval[0]);
                        outname(ptr=lval[0]);
                        nl();
                        nl();
                        lval[1]=ptr[type];
                        lval[1]=ptr[type];
                        return 0;
                        return 0;
                        }
                        }
                }
                }
        else
        else
                {k=heir11(lval);
                {k=heir11(lval);
                if(match("++"))
                if(match("++"))
                        {if(k==0)
                        {if(k==0)
                                {needlval();
                                {needlval();
                                return 0;
                                return 0;
                                }
                                }
                        if(lval[1])zpush();
                        if(lval[1])zpush();
                        rvalue(lval);
                        rvalue(lval);
                        inc();
                        inc();
                        ptr=lval[0];
                        ptr=lval[0];
                        if((ptr[ident]==pointer)&
                        if((ptr[ident]==pointer)&
                                (ptr[type]==cint))
                                (ptr[type]==cint))
                                        inc();
                                        inc();
                        store(lval);
                        store(lval);
                        dec();
                        dec();
                        if((ptr[ident]==pointer)&
                        if((ptr[ident]==pointer)&
                                (ptr[type]==cint))
                                (ptr[type]==cint))
                                dec();
                                dec();
                        return 0;
                        return 0;
                        }
                        }
                else if(match("--"))
                else if(match("--"))
                        {if(k==0)
                        {if(k==0)
                                {needlval();
                                {needlval();
                                return 0;
                                return 0;
                                }
                                }
                        if(lval[1])zpush();
                        if(lval[1])zpush();
                        rvalue(lval);
                        rvalue(lval);
                        dec();
                        dec();
                        ptr=lval[0];
                        ptr=lval[0];
                        if((ptr[ident]==pointer)&
                        if((ptr[ident]==pointer)&
                                (ptr[type]==cint))
                                (ptr[type]==cint))
                                        dec();
                                        dec();
                        store(lval);
                        store(lval);
                        inc();
                        inc();
                        if((ptr[ident]==pointer)&
                        if((ptr[ident]==pointer)&
                                (ptr[type]==cint))
                                (ptr[type]==cint))
                                inc();
                                inc();
                        return 0;
                        return 0;
                        }
                        }
                else return k;
                else return k;
                }
                }
        }
        }
/*      >>>>>> start of cc7 <<<<<<      */
/*      >>>>>> start of cc7 <<<<<<      */
 
 
heir11(lval)
heir11(lval)
        int *lval;
        int *lval;
{       int k;char *ptr;
{       int k;char *ptr;
        k=primary(lval);
        k=primary(lval);
        ptr=lval[0];
        ptr=lval[0];
        blanks();
        blanks();
        if((ch()=='[')|(ch()=='('))
        if((ch()=='[')|(ch()=='('))
        while(1)
        while(1)
                {if(match("["))
                {if(match("["))
                        {if(ptr==0)
                        {if(ptr==0)
                                {error("can't subscript");
                                {error("can't subscript");
                                junk();
                                junk();
                                needbrack("]");
                                needbrack("]");
                                return 0;
                                return 0;
                                }
                                }
                        else if(ptr[ident]==pointer)rvalue(lval);
                        else if(ptr[ident]==pointer)rvalue(lval);
                        else if(ptr[ident]!=array)
                        else if(ptr[ident]!=array)
                                {error("can't subscript");
                                {error("can't subscript");
                                k=0;
                                k=0;
                                }
                                }
                        zpush();
                        zpush();
                        expression();
                        expression();
                        needbrack("]");
                        needbrack("]");
                        if(ptr[type]==cint)doublereg();
                        if(ptr[type]==cint)doublereg();
                        zpop();
                        zpop();
                        zadd();
                        zadd();
                        lval[1]=ptr[type];
                        lval[1]=ptr[type];
                                /* 4/1/81 - after subscripting, not ptr anymore */
                                /* 4/1/81 - after subscripting, not ptr anymore */
                        lval[0]=0;
                        lval[0]=0;
                        k=1;
                        k=1;
                        }
                        }
                else if(match("("))
                else if(match("("))
                        {if(ptr==0)
                        {if(ptr==0)
                                {callfunction(0);
                                {callfunction(0);
                                }
                                }
                        else if(ptr[ident]!=function)
                        else if(ptr[ident]!=function)
                                {rvalue(lval);
                                {rvalue(lval);
                                callfunction(0);
                                callfunction(0);
                                }
                                }
                        else callfunction(ptr);
                        else callfunction(ptr);
                        k=lval[0]=0;
                        k=lval[0]=0;
                        }
                        }
                else return k;
                else return k;
                }
                }
        if(ptr==0)return k;
        if(ptr==0)return k;
        if(ptr[ident]==function)
        if(ptr[ident]==function)
                {immed();
                {immed();
                outname(ptr);
                outname(ptr);
                nl();
                nl();
                return 0;
                return 0;
                }
                }
        return k;
        return k;
}
}
primary(lval)
primary(lval)
        int *lval;
        int *lval;
{       char *ptr,sname[namesize];int num[1];
{       char *ptr,sname[namesize];int num[1];
        int k;
        int k;
        if(match("("))
        if(match("("))
                {k=heir1(lval);
                {k=heir1(lval);
                needbrack(")");
                needbrack(")");
                return k;
                return k;
                }
                }
        if(symname(sname))
        if(symname(sname))
                {if(ptr=findloc(sname))
                {if(ptr=findloc(sname))
                        {getloc(ptr);
                        {getloc(ptr);
                        lval[0]=ptr;
                        lval[0]=ptr;
                        lval[1]=ptr[type];
                        lval[1]=ptr[type];
                        if(ptr[ident]==pointer)lval[1]=cint;
                        if(ptr[ident]==pointer)lval[1]=cint;
                        if(ptr[ident]==array)return 0;
                        if(ptr[ident]==array)return 0;
                                else return 1;
                                else return 1;
                        }
                        }
                if(ptr=findglb(sname))
                if(ptr=findglb(sname))
                        if(ptr[ident]!=function)
                        if(ptr[ident]!=function)
                        {lval[0]=ptr;
                        {lval[0]=ptr;
                        lval[1]=0;
                        lval[1]=0;
                        if(ptr[ident]!=array)return 1;
                        if(ptr[ident]!=array)return 1;
                        immed();
                        immed();
                        outname(ptr);nl();
                        outname(ptr);nl();
                        lval[1]=ptr[type];
                        lval[1]=ptr[type];
                        return 0;
                        return 0;
                        }
                        }
                ptr=addglb(sname,function,cint,0,-1);
                ptr=addglb(sname,function,cint,0,-1);
                lval[0]=ptr;
                lval[0]=ptr;
                lval[1]=0;
                lval[1]=0;
                return 0;
                return 0;
                }
                }
        if(constant(num))
        if(constant(num))
                return(lval[0]=lval[1]=0);
                return(lval[0]=lval[1]=0);
        else
        else
                {error("invalid expression");
                {error("invalid expression");
                immed();outdec(0);nl();
                immed();outdec(0);nl();
                junk();
                junk();
                return 0;
                return 0;
                }
                }
        }
        }
store(lval)
store(lval)
        int *lval;
        int *lval;
{       if (lval[1]==0)putmem(lval[0]);
{       if (lval[1]==0)putmem(lval[0]);
        else putstk(lval[1]);
        else putstk(lval[1]);
}
}
rvalue(lval)
rvalue(lval)
        int *lval;
        int *lval;
{       if((lval[0] != 0) & (lval[1] == 0))
{       if((lval[0] != 0) & (lval[1] == 0))
                getmem(lval[0]);
                getmem(lval[0]);
                else indirect(lval[1]);
                else indirect(lval[1]);
}
}
test(label)
test(label)
        int label;
        int label;
{
{
        needbrack("(");
        needbrack("(");
        expression();
        expression();
        needbrack(")");
        needbrack(")");
        testjump(label);
        testjump(label);
}
}
constant(val)
constant(val)
        int val[];
        int val[];
{
{
        if (number(val)) {
        if (number(val)) {
                immed();
                immed();
                outdec(val[0]);
                outdec(val[0]);
        }
        }
        else if (pstr(val)) {
        else if (pstr(val)) {
                immed();
                immed();
                outdec(val[0]);
                outdec(val[0]);
        }
        }
        else if (qstr(val)) {
        else if (qstr(val)) {
                immed();
                immed();
                printlabel(litlab);
                printlabel(litlab);
                outbyte('+');
                outbyte('+');
                outdec(val[0]);
                outdec(val[0]);
        }
        }
        else
        else
                return 0;
                return 0;
        nl();
        nl();
        return 1;
        return 1;
}
}
// get a numeric value from the source file 
// get a numeric value from the source file 
number(val)
number(val)
int val[];
int val[];
{
{
int k,minus;
int k,minus;
char c;
char c;
 
 
        k=minus=1;
        k=minus=1;
        while (k) {
        while (k) {
                k=0;
                k=0;
                if (match("+")) k=1;
                if (match("+")) k=1;
                if (match("-")) {
                if (match("-")) {
                        minus=(-minus);
                        minus=(-minus);
                        k=1;
                        k=1;
                }
                }
        }
        }
        // check if hexadecimal value 
        // check if hexadecimal value 
        if ((ch()=='0') & (nch()=='x')) {
        if ((ch()=='0') & (nch()=='x')) {
                // remove first two characters ("0x") 
                // remove first two characters ("0x") 
                inchar();inchar();
                inchar();inchar();
                // make sure the next value is legal 
                // make sure the next value is legal 
                if (hexnum(ch())==0) return 0;
                if (hexnum(ch())==0) return 0;
                // continue to read hexadecimal value 
                // continue to read hexadecimal value 
                while (hexnum(ch())) {
                while (hexnum(ch())) {
                        c=raise(inbyte());
                        c=raise(inbyte());
                        if (numeric(c)!=0)
                        if (numeric(c)!=0)
                                k=k*16+(c-'0');
                                k=k*16+(c-'0');
                        else
                        else
                                k=k*16+(c-'A')+10;
                                k=k*16+(c-'A')+10;
                }
                }
                if (minus<0) k=(-k);
                if (minus<0) k=(-k);
                val[0]=k;
                val[0]=k;
                return 1;
                return 1;
        }
        }
        // check if decimal value 
        // check if decimal value 
        else if (numeric(ch())!=0) {
        else if (numeric(ch())!=0) {
                while (numeric(ch())) {
                while (numeric(ch())) {
                        c=inbyte();
                        c=inbyte();
                        k=k*10+(c-'0');
                        k=k*10+(c-'0');
                }
                }
                if (minus<0) k=(-k);
                if (minus<0) k=(-k);
                val[0]=k;
                val[0]=k;
                return 1;
                return 1;
        }
        }
        else
        else
                return 0;
                return 0;
}
}
pstr(val)
pstr(val)
int val[];
int val[];
{
{
int k;
int k;
char c;
char c;
 
 
        k=0;
        k=0;
        if (match("'")==0) return 0;
        if (match("'")==0) return 0;
        while((c=gch())!=39)
        while((c=gch())!=39)
                k=(k&255)*256 + (c&127);
                k=(k&255)*256 + (c&127);
        val[0]=k;
        val[0]=k;
        return 1;
        return 1;
}
}
qstr(val)
qstr(val)
int val[];
int val[];
{
{
char c;
char c;
 
 
        if (match("\"")==0) return 0;
        if (match("\"")==0) return 0;
        val[0]=litptr;
        val[0]=litptr;
        while (ch()!='"')
        while (ch()!='"')
                {if(ch()==0)break;
                {if(ch()==0)break;
                if(litptr>=litmax)
                if(litptr>=litmax)
                        {error("string space exhausted");
                        {error("string space exhausted");
                        while(match("\"")==0)
                        while(match("\"")==0)
                                if(gch()==0)break;
                                if(gch()==0)break;
                        return 1;
                        return 1;
                        }
                        }
                litq[litptr++]=gch();
                litq[litptr++]=gch();
                }
                }
        gch();
        gch();
        litq[litptr++]=0;
        litq[litptr++]=0;
        return 1;
        return 1;
}
}
/*      >>>>>> start of cc8 <<<<<<<     */
/*      >>>>>> start of cc8 <<<<<<<     */
 
 
/* Begin a comment line for the assembler */
/* Begin a comment line for the assembler */
comment()
comment()
{       outbyte(';');
{       outbyte(';');
}
}
 
 
/* Put out assembler info before any code is generated */
/* Put out assembler info before any code is generated */
header()
header()
{       comment();
{       comment();
        outstr(BANNER);
        outstr(BANNER);
        nl();
        nl();
        comment();
        comment();
        outstr(VERSION);
        outstr(VERSION);
        nl();
        nl();
        comment();
        comment();
        outstr(AUTHOR);
        outstr(AUTHOR);
        nl();
        nl();
        comment();
        comment();
        nl();
        nl();
        if (mainflg) {          /* do stuff needed for first */
        if (mainflg) {          /* do stuff needed for first */
                ol("code");
                ol("code");
                ol("org #0000"); /* assembler file. */
                ol("org #0000"); /* assembler file. */
                ot("ld hl,"); outdec(stackptr); nl();   /* set up stack */
                ot("ld hl,"); outdec(stackptr); nl();   /* set up stack */
                ol("ld sp,hl");
                ol("ld sp,hl");
                zcall("main");  /* call the code generated by small-c */
                zcall("main");  /* call the code generated by small-c */
        }
        }
}
}
/* Print any assembler stuff needed after all code */
/* Print any assembler stuff needed after all code */
trailer()
trailer()
{       /* ol("END"); */        /*...note: commented out! */
{       /* ol("END"); */        /*...note: commented out! */
 
 
        nl();                   /* 6 May 80 rj errorsummary() now goes to console */
        nl();                   /* 6 May 80 rj errorsummary() now goes to console */
        comment();
        comment();
        outstr(" --- End of Compilation ---");
        outstr(" --- End of Compilation ---");
        nl();
        nl();
}
}
/* Print out a name such that it won't annoy the assembler */
/* Print out a name such that it won't annoy the assembler */
/*      (by matching anything reserved, like opcodes.) */
/*      (by matching anything reserved, like opcodes.) */
/*      gtf 4/7/80 */
/*      gtf 4/7/80 */
outname(sname)
outname(sname)
char *sname;
char *sname;
{       int len, i,j;
{       int len, i,j;
 
 
        outasm("__");
        outasm("__");
        len = strlen(sname);
        len = strlen(sname);
        if (len>(asmpref+asmsuff)) {
        if (len>(asmpref+asmsuff)) {
                i = asmpref;
                i = asmpref;
                len = len-asmpref-asmsuff;
                len = len-asmpref-asmsuff;
                while(i-- > 0)
                while(i-- > 0)
                        outbyte(lower(*sname++));
                        outbyte(lower(*sname++));
                while(len-- > 0)
                while(len-- > 0)
                        sname++;
                        sname++;
                while(*sname)
                while(*sname)
                        outbyte(lower(*sname++));
                        outbyte(lower(*sname++));
                }
                }
        else    outasm(sname);
        else    outasm(sname);
/* end outname */}
/* end outname */}
/* Fetch a static memory cell into the primary register */
/* Fetch a static memory cell into the primary register */
getmem(sym)
getmem(sym)
        char *sym;
        char *sym;
{
{
int padr;
int padr;
 
 
        if ((sym[ident]!=pointer)&(sym[type]==cchar)) {
        if ((sym[ident]!=pointer)&(sym[type]==cchar)) {
                ot("ld a,(");
                ot("ld a,(");
                outname(sym+name);
                outname(sym+name);
                outasm(")");
                outasm(")");
                nl();
                nl();
                callrts("ccsxt");
                callrts("ccsxt");
        } else if (sym[type]==cport) {
        } else if (sym[type]==cport) {
                padr=sym[offset] & 0xff;
                padr=sym[offset] & 0xff;
                ot("in a,(");outdec(padr);outasm(")");nl();
                ot("in a,(");outdec(padr);outasm(")");nl();
                callrts("ccsxt");
                callrts("ccsxt");
        } else {
        } else {
                ot("ld hl,(");
                ot("ld hl,(");
                outname(sym+name);
                outname(sym+name);
                outasm(")");
                outasm(")");
                nl();
                nl();
        }
        }
}
}
/* Fetch the address of the specified symbol */
/* Fetch the address of the specified symbol */
/*      into the primary register */
/*      into the primary register */
getloc(sym)
getloc(sym)
        char *sym;
        char *sym;
{
{
int off_val;
int off_val;
 
 
        immed();
        immed();
        off_val = ((sym[offset]&255)+((sym[offset+1]&255)<<8))-Zsp;
        off_val = ((sym[offset]&255)+((sym[offset+1]&255)<<8))-Zsp;
        off_val &= 0xffff;
        off_val &= 0xffff;
        outdec(off_val);
        outdec(off_val);
        nl();
        nl();
        ol("add hl,sp");
        ol("add hl,sp");
}
}
/* Store the primary register into the specified */
/* Store the primary register into the specified */
/*      static memory cell */
/*      static memory cell */
putmem(sym)
putmem(sym)
        char *sym;
        char *sym;
{
{
int padr;
int padr;
 
 
        if((sym[ident]!=pointer)&(sym[type]==cchar)) {
        if((sym[ident]!=pointer)&(sym[type]==cchar)) {
                ol("ld a,l");
                ol("ld a,l");
                ot("ld (");
                ot("ld (");
                outname(sym+name);
                outname(sym+name);
                outasm("),a");
                outasm("),a");
        } else if (sym[type]==cport) {
        } else if (sym[type]==cport) {
                padr=sym[offset] & 0xff;
                padr=sym[offset] & 0xff;
                ol("ld a,l");
                ol("ld a,l");
                ot("out (");outdec(padr);outasm("),a");nl();
                ot("out (");outdec(padr);outasm("),a");nl();
        } else {
        } else {
                ot("ld (");
                ot("ld (");
                outname(sym+name);
                outname(sym+name);
                outasm("),hl");
                outasm("),hl");
        }
        }
 
 
        nl();
        nl();
        }
        }
/* Store the specified object type in the primary register */
/* Store the specified object type in the primary register */
/*      at the address on the top of the stack */
/*      at the address on the top of the stack */
putstk(typeobj)
putstk(typeobj)
char typeobj;
char typeobj;
{       zpop();
{       zpop();
        if(typeobj==cint)
        if(typeobj==cint)
                callrts("ccpint");
                callrts("ccpint");
        else {  ol("ld a,l");           /* per Ron Cain: gtf 9/25/80 */
        else {  ol("ld a,l");           /* per Ron Cain: gtf 9/25/80 */
                ol("ld (de),a");
                ol("ld (de),a");
                }
                }
        }
        }
/* Fetch the specified object type indirect through the */
/* Fetch the specified object type indirect through the */
/*      primary register into the primary register */
/*      primary register into the primary register */
indirect(typeobj)
indirect(typeobj)
        char typeobj;
        char typeobj;
{       if(typeobj==cchar)callrts("ccgchar");
{       if(typeobj==cchar)callrts("ccgchar");
                else callrts("ccgint");
                else callrts("ccgint");
}
}
/* Swap the primary and secondary registers */
/* Swap the primary and secondary registers */
swap()
swap()
{       ol("xchg");
{       ol("xchg");
}
}
/* Print partial instruction to get an immediate value */
/* Print partial instruction to get an immediate value */
/*      into the primary register */
/*      into the primary register */
immed()
immed()
{       ot("ld hl,");
{       ot("ld hl,");
}
}
/* Push the primary register onto the stack */
/* Push the primary register onto the stack */
zpush()
zpush()
{       ol("push hl");
{       ol("push hl");
        Zsp=Zsp-2;
        Zsp=Zsp-2;
}
}
/* Pop the top of the stack into the secondary register */
/* Pop the top of the stack into the secondary register */
zpop()
zpop()
{       ol("pop de");
{       ol("pop de");
        Zsp=Zsp+2;
        Zsp=Zsp+2;
}
}
/* Swap the primary register and the top of the stack */
/* Swap the primary register and the top of the stack */
swapstk()
swapstk()
{       ol("ex (sp),hl");
{       ol("ex (sp),hl");
}
}
/* Call the specified subroutine name */
/* Call the specified subroutine name */
zcall(sname)
zcall(sname)
        char *sname;
        char *sname;
{       ot("call ");
{       ot("call ");
        outname(sname);
        outname(sname);
        nl();
        nl();
}
}
/* Call a run-time library routine */
/* Call a run-time library routine */
callrts(sname)
callrts(sname)
char *sname;
char *sname;
{
{
        ot("call ");
        ot("call ");
        outasm(sname);
        outasm(sname);
        nl();
        nl();
/*end callrts*/}
/*end callrts*/}
 
 
/* Return from subroutine */
/* Return from subroutine */
zret()
zret()
{       ol("RET");
{       ol("ret");
}
}
/* Perform subroutine call to value on top of stack */
/* Perform subroutine call to value on top of stack */
callstk()
callstk()
{       immed();
{       immed();
        outasm("$+5");
        outasm("$+5");
        nl();
        nl();
        swapstk();
        swapstk();
        ol("jp (hl)");
        ol("jp (hl)");
        Zsp=Zsp+2; /* corrected 5 May 81 rj */
        Zsp=Zsp+2; /* corrected 5 May 81 rj */
        }
        }
/* Jump to specified internal label number */
/* Jump to specified internal label number */
jump(label)
jump(label)
        int label;
        int label;
{       ot("jp ");
{       ot("jp ");
        printlabel(label);
        printlabel(label);
        nl();
        nl();
        }
        }
/* Test the primary register and jump if false to label */
/* Test the primary register and jump if false to label */
testjump(label)
testjump(label)
        int label;
        int label;
{       ol("ld a,h");
{       ol("ld a,h");
        ol("or l");
        ol("or l");
        ot("jp z,");
        ot("jp z,");
        printlabel(label);
        printlabel(label);
        nl();
        nl();
        }
        }
/* Print pseudo-op to define a byte */
/* Print pseudo-op to define a byte */
defbyte()
defbyte()
{       ot("db ");
{       ot("db ");
}
}
/*Print pseudo-op to define storage */
/*Print pseudo-op to define storage */
defstorage()
defstorage()
{       ot("ds ");
{       ot("ds ");
}
}
/* Print pseudo-op to define a word */
/* Print pseudo-op to define a word */
defword()
defword()
{       ot("dw ");
{       ot("dw ");
}
}
/* Modify the stack pointer to the new value indicated */
/* Modify the stack pointer to the new value indicated */
modstk(newsp)
modstk(newsp)
        int newsp;
        int newsp;
 {      int k;
 {      int k;
        k=newsp-Zsp;
        k=newsp-Zsp;
        if(k==0)return newsp;
        if(k==0)return newsp;
        if(k>=0)
        if(k>=0)
                {if(k<7)
                {if(k<7)
                        {if(k&1)
                        {if(k&1)
                                {ol("inc sp");
                                {ol("inc sp");
                                k--;
                                k--;
                                }
                                }
                        while(k)
                        while(k)
                                {ol("pop bc");
                                {ol("pop bc");
                                k=k-2;
                                k=k-2;
                                }
                                }
                        return newsp;
                        return newsp;
                        }
                        }
                }
                }
        if(k<0)
        if(k<0)
                {if(k>-7)
                {if(k>-7)
                        {if(k&1)
                        {if(k&1)
                                {ol("dec sp");
                                {ol("dec sp");
                                k++;
                                k++;
                                }
                                }
                        while(k)
                        while(k)
                                {ol("push bc");
                                {ol("push bc");
                                k=k+2;
                                k=k+2;
                                }
                                }
                        return newsp;
                        return newsp;
                        }
                        }
                }
                }
        swap();
        swap();
        immed();outdec(k);nl();
        immed();outdec(k);nl();
        ol("add hl,sp");
        ol("add hl,sp");
        ol("ld sp,hl");
        ol("ld sp,hl");
        swap();
        swap();
        return newsp;
        return newsp;
}
}
/* Double the primary register */
/* Double the primary register */
doublereg()
doublereg()
{       ol("add hl,hl");
{       ol("add hl,hl");
}
}
/* Add the primary and secondary registers */
/* Add the primary and secondary registers */
/*      (results in primary) */
/*      (results in primary) */
zadd()
zadd()
{       ol("add hl,de");
{       ol("add hl,de");
}
}
/* Subtract the primary register from the secondary */
/* Subtract the primary register from the secondary */
/*      (results in primary) */
/*      (results in primary) */
zsub()
zsub()
{       callrts("ccsub");
{       callrts("ccsub");
}
}
/* Multiply the primary and secondary registers */
/* Multiply the primary and secondary registers */
/*      (results in primary */
/*      (results in primary */
mult()
mult()
{       callrts("ccmult");
{       callrts("ccmult");
}
}
/* Divide the secondary register by the primary */
/* Divide the secondary register by the primary */
/*      (quotient in primary, remainder in secondary) */
/*      (quotient in primary, remainder in secondary) */
div()
div()
{       callrts("ccdiv");
{       callrts("ccdiv");
}
}
/* Compute remainder (mod) of secondary register divided */
/* Compute remainder (mod) of secondary register divided */
/*      by the primary */
/*      by the primary */
/*      (remainder in primary, quotient in secondary) */
/*      (remainder in primary, quotient in secondary) */
zmod()
zmod()
{       div();
{       div();
        swap();
        swap();
        }
        }
/* Inclusive 'or' the primary and the secondary registers */
/* Inclusive 'or' the primary and the secondary registers */
/*      (results in primary) */
/*      (results in primary) */
zor()
zor()
        {callrts("ccor");}
        {callrts("ccor");}
/* Exclusive 'or' the primary and seconday registers */
/* Exclusive 'or' the primary and seconday registers */
/*      (results in primary) */
/*      (results in primary) */
zxor()
zxor()
        {callrts("ccxor");}
        {callrts("ccxor");}
/* 'And' the primary and secondary registers */
/* 'And' the primary and secondary registers */
/*      (results in primary) */
/*      (results in primary) */
zand()
zand()
        {callrts("ccand");}
        {callrts("ccand");}
/* Arithmetic shift right the secondary register number of */
/* Arithmetic shift right the secondary register number of */
/*      times in primary (results in primary) */
/*      times in primary (results in primary) */
asr()
asr()
        {callrts("ccasr");}
        {callrts("ccasr");}
/* Arithmetic left shift the secondary register number of */
/* Arithmetic left shift the secondary register number of */
/*      times in primary (results in primary) */
/*      times in primary (results in primary) */
asl()
asl()
        {callrts("ccasl");}
        {callrts("ccasl");}
/* Form two's complement of primary register */
/* Form two's complement of primary register */
neg()
neg()
        {callrts("ccneg");}
        {callrts("ccneg");}
/* Form one's complement of primary register */
/* Form one's complement of primary register */
com()
com()
        {callrts("cccom");}
        {callrts("cccom");}
/* Increment the primary register by one */
/* Increment the primary register by one */
inc()
inc()
        {ol("inc hl");}
        {ol("inc hl");}
/* Decrement the primary register by one */
/* Decrement the primary register by one */
dec()
dec()
        {ol("dec hl");}
        {ol("dec hl");}
 
 
/* Following are the conditional operators */
/* Following are the conditional operators */
/* They compare the secondary register against the primary */
/* They compare the secondary register against the primary */
/* and put a literal 1 in the primary if the condition is */
/* and put a literal 1 in the primary if the condition is */
/* true, otherwise they clear the primary register */
/* true, otherwise they clear the primary register */
 
 
/* Test for equal */
/* Test for equal */
zeq()
zeq()
        {callrts("cceq");}
        {callrts("cceq");}
/* Test for not equal */
/* Test for not equal */
zne()
zne()
        {callrts("ccne");}
        {callrts("ccne");}
/* Test for less than (signed) */
/* Test for less than (signed) */
zlt()
zlt()
        {callrts("cclt");}
        {callrts("cclt");}
/* Test for less than or equal to (signed) */
/* Test for less than or equal to (signed) */
zle()
zle()
        {callrts("ccle");}
        {callrts("ccle");}
/* Test for greater than (signed) */
/* Test for greater than (signed) */
zgt()
zgt()
        {callrts("ccgt");}
        {callrts("ccgt");}
/* Test for greater than or equal to (signed) */
/* Test for greater than or equal to (signed) */
zge()
zge()
        {callrts("ccge");}
        {callrts("ccge");}
/* Test for less than (unsigned) */
/* Test for less than (unsigned) */
ult()
ult()
        {callrts("ccult");}
        {callrts("ccult");}
/* Test for less than or equal to (unsigned) */
/* Test for less than or equal to (unsigned) */
ule()
ule()
        {callrts("ccule");}
        {callrts("ccule");}
/* Test for greater than (unsigned) */
/* Test for greater than (unsigned) */
ugt()
ugt()
        {callrts("ccugt");}
        {callrts("ccugt");}
/* Test for greater than or equal to (unsigned) */
/* Test for greater than or equal to (unsigned) */
uge()
uge()
        {callrts("ccuge");}
        {callrts("ccuge");}
 
 
/*      <<<<<  End of small-c compiler  >>>>>   */
/*      <<<<<  End of small-c compiler  >>>>>   */
 
 
 
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.