Saturday, November 17, 2007

program



































































Arnold A. Flores





































































































#include
#include "cc.h"

extern char
*symtab, *macn, *macq, *pline, *mline, optimize,
alarm, *glbptr, *line, *lptr, *cptr, *cptr2, *cptr3,
*locptr, msname[NAMESIZE], pause, quote[2];

extern int
*wq, ccode, ch, csp, eof, errflag, iflevel,
input, input2, listfp, macptr, nch,
nxtlab, op[16], opindex, opsize, output, pptr,
skiplevel, *wqptr;

/********************** input functions **********************/

preprocess() {
int k;
char c;
if(ccode) {
line = mline;
ifline();
if(eof) return;
}
else {
inline();
return;
}
pptr = -1;
while(ch != NEWLINE && ch) {
if(white()) {
keepch(' ');
while(white()) gch();
}
else if(ch == '"') {
keepch(ch);
gch();
while(ch != '"' (*(lptr-1) == 92 && *(lptr-2) != 92)) {
if(ch == NULL) {
error("no quote");
break;
}
keepch(gch());
}
gch();
keepch('"');
}
else if(ch == 39) {
keepch(39);
gch();
while(ch != 39 (*(lptr-1) == 92 && *(lptr-2) != 92)) {
if(ch == NULL) {
error("no apostrophe");
break;
}
keepch(gch());
}
gch();
keepch(39);
}
else if(ch == '/' && nch == '*') {
bump(2);
while((ch == '*' && nch == '/') == 0) {
if(ch) bump(1);
else {
ifline();
if(eof) break;
}
}
bump(2);
}
else if(an(ch)) {
k = 0;
while(an(ch) && k < k =" getint(cptr+NAMESIZE," c =" macq[k++])" k =" 0;" c =" msname[k++])">= LINEMAX) error("line too long");
keepch(NULL);
line = pline;
bump(0);
}

keepch(c) char c; {
if(pptr < skiplevel =" iflevel;" skiplevel =" iflevel;" skiplevel ="=" skiplevel =" 0;" skiplevel ="=" skiplevel =" iflevel;" skiplevel ="=" skiplevel =" 0;" ch ="=" input ="=" unit =" input2)" unit =" input;" input2 =" EOF;" input =" EOF;" line =" NULL;" listfp ="=" ch ="=" sname =" 0);" k =" 0;" errflag =" 0;" k =" streq(lptr," k =" 0;" k =" astreq(lptr," k =" 0;" opindex =" 0;" opsize =" 0;"> ' ') op[opsize++] = *list++;
op[opsize] = 0;
if(opsize = streq(lptr, op))
if(*(lptr+opsize) != '=' &&
*(lptr+opsize) != *(lptr+opsize-1))
return 1;
if(*list) {
++list;
++opindex;
}
else return 0;
}
}

blanks() {
while(1) {
while(ch) {
if(white()) gch();
else return;
}
if(line == mline) return;
preprocess();
if(eof) break;
}
}

white() {
avail(YES); /* abort on stack/symbol table overflow */
return (*lptr <= ' ' && *lptr); } gch() { int c; if(c = ch) bump(1); return c; } bump(n) int n; { if(n) lptr += n; else lptr = line; if(ch = nch = *lptr) nch = *(lptr+1); } kill() { *line = 0; bump(0); } skip() { if(an(inbyte())) while(an(ch)) gch(); else while(an(ch) == 0) { if(ch == 0) break; gch(); } blanks(); } endst() { blanks(); return (streq(lptr, ";") ch == 0); } /*********** symbol table management functions ***********/ addsym(sname, id, type, size, value, lgpp, class) char *sname, id, type; int size, value, *lgpp, class; { if(lgpp == &glbptr) { if(cptr2 = findglb(sname)) return cptr2; if(cptr == 0) { error("global symbol table overflow"); return 0; } } else { if(locptr > (ENDLOC-SYMMAX)) {
error("local symbol table overflow");
abort(ERRCODE);
}
cptr = *lgpp;
}
cptr[IDENT] = id;
cptr[TYPE] = type;
cptr[CLASS] = class;
putint(size, cptr + SIZE, 2);
putint(value, cptr + OFFSET, 2);
cptr3 = cptr2 = cptr + NAME;
while(an(*sname)) *cptr2++ = *sname++;
if(lgpp == &locptr) {
*cptr2 = cptr2 - cptr3; /* set length */
*lgpp = ++cptr2;
}
return cptr;
}

/*
** search for symbol match
** on return cptr points to slot found or empty slot
*/
search(sname, buf, len, end, max, off)
char *sname, *buf, *end; int len, max, off; {
cptr =
cptr2 = buf+((hash(sname)%(max-1))*len);
while(*cptr != NULL) {
if(astreq(sname, cptr+off, NAMEMAX)) return 1;
if((cptr = cptr+len) >= end) cptr = buf;
if(cptr == cptr2) return (cptr = 0);
}
return 0;
}

hash(sname) char *sname; {
int i, c;
i = 0;
while(c = *sname++) i = (i << cptr =" locptr"> STARTLOC) {
cptr = cptr - *cptr;
if(astreq(sname, cptr, NAMEMAX)) return (cptr - NAME);
cptr = cptr - NAME - 1;
}
return 0;
}

nextsym(entry) char *entry; {
entry = entry + NAME;
while(*entry++ >= ' '); /* find length byte */
return entry;
}

/******** while queue management functions *********/

addwhile(ptr) int ptr[]; {
int k;
ptr[WQSP] = csp; /* and stk ptr */
ptr[WQLOOP] = getlabel(); /* and looping label */
ptr[WQEXIT] = getlabel(); /* and exit label */
if(wqptr == WQMAX) {
error("control statement nesting limit");
abort(ERRCODE);
}
k = 0;
while (k <> wq) wqptr -= WQSIZ;
}

/****************** utility functions ********************/

/*
** test if c is alphabetic
*/
alpha(c) char c; {
return (isalpha(c) c == '_');
}

/*
** test if given character is alphanumeric
*/
an(c) char c; {
return (alpha(c) isdigit(c));
}

/*
** return next avail internal label number
*/
getlabel() {
return(++nxtlab);
}

/*
** get integer of length len from address addr
** (byte sequence set by "putint")
*/
getint(addr, len) char *addr; int len; {
int i;
i = *(addr + --len); /* high order byte sign extended */
while(len--) i = (i << i =" i">> 8;
}
}

lout(line, fd) char *line; int fd; {
fputs(line, fd);
fputc(NEWLINE, fd);
}

/******************* error functions *********************/

illname() {
error("illegal symbol");
skip();
}

multidef(sname) char *sname; {
error("already defined");
}

needlval() {
error("must be lvalue");
}

noiferr() {
error("no matching #if...");
errflag = 0;
}

error(msg) char msg[]; {
if(errflag) return;
else errflag = 1;
lout(line, stderr);
errout(msg, stderr);
if(alarm) fputc(7, stderr);
if(pause) while(fgetc(stderr) != NEWLINE);
if(listfp > 0) errout(msg, listfp);
}

errout(msg, fp) char msg[]; int fp; {
int k;
k = line+2;
while(k++ <= lptr) fputc(' ', fp); lout("/\\", fp); fputs("**** ", fp); lout(msg, fp); }