//************************************************
|
//************************************************
|
//
|
//
|
// 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 >>>>> */
|
|
|
|
|