USADACS@wsmr-simtel20.army.mil (Al McIntosh) (12/11/88)
21-May-86 10:30:44-MDT,54751;000000000001 Return-Path: <unix-sources-request@BRL.ARPA> Received: from BRL-SMOKE.ARPA by SIMTEL20.ARPA with TCP; Wed 21 May 86 10:25:39-MDT Received: from USENET by SMOKE.BRL.ARPA id a015507; 20 May 86 19:37 EDT From: sources-request@panda.uucp Newsgroups: mod.sources Subject: Small C compiler version C3.0R1.1 (part 2 of 3) Message-ID: <1893@panda.UUCP> Date: 19 May 86 22:47:44 GMT Sender: jpn@panda.uucp Approved: jpn@panda.UUCP To: unix-sources@brl-smoke.arpa Mod.sources: Volume 5, Issue 8 Submitted by: genrad!linus!mnetor!clewis (Chris Lewis) #! /bin/sh # This is a shell archive, meaning: # 1. Remove everything above the #! /bin/sh line. # 2. Save the resulting text in a file. # 3. Execute the file with /bin/sh (not csh) to create the files: # defs.h # error.c # expr.c # function.c # gen.c # io.c # lex.c # main.c # preproc.c # primary.c # stmt.c # sym.c # while.c # This archive created: Sun May 18 18:17:13 1986 export PATH; PATH=/bin:$PATH echo shar: extracting "'defs.h'" '(1982 characters)' if test -f 'defs.h' then echo shar: will not over-write existing file "'defs.h'" else cat << \SHAR_EOF > 'defs.h' /* File defs.h: 2.1 (83/03/21,02:07:20) */ #define FOREVER for(;;) #define FALSE 0 #define TRUE 1 #define NO 0 #define YES 1 /* miscellaneous */ #define EOS 0 #define EOL 10 #define BKSP 8 #define CR 13 #define FFEED 12 #define TAB 9 /* symbol table parameters */ #define SYMSIZ 14 #define SYMTBSZ 2800 #define NUMGLBS 150 #define STARTGLB symtab #define ENDGLB (STARTGLB+NUMGLBS*SYMSIZ) #define STARTLOC (ENDGLB+SYMSIZ) #define ENDLOC (symtab+SYMTBSZ-SYMSIZ) /* symbol table entry format */ #define NAME 0 #define IDENT 9 #define TYPE 10 #define STORAGE 11 #define OFFSET 12 /* system-wide name size (for symbols) */ #define NAMESIZE 9 #define NAMEMAX 8 /* possible entries for "ident" */ #define VARIABLE 1 #define ARRAY 2 #define POINTER 3 #define FUNCTION 4 /* possible entries for "type" */ #define CCHAR 1 #define CINT 2 /* possible entries for storage */ #define PUBLIC 1 #define AUTO 2 #define EXTERN 3 #define STATIC 4 #define LSTATIC 5 #define DEFAUTO 6 /* "do"/"for"/"while"/"switch" statement stack */ #define WSTABSZ 100 #define WSSIZ 7 #define WSMAX ws+WSTABSZ-WSSIZ /* entry offsets in "do"/"for"/"while"/"switch" stack */ #define WSSYM 0 #define WSSP 1 #define WSTYP 2 #define WSCASEP 3 #define WSTEST 3 #define WSINCR 4 #define WSDEF 4 #define WSBODY 5 #define WSTAB 5 #define WSEXIT 6 /* possible entries for "wstyp" */ #define WSWHILE 0 #define WSFOR 1 #define WSDO 2 #define WSSWITCH 3 /* "switch" label stack */ #define SWSTSZ 100 /* literal pool */ #define LITABSZ 2000 #define LITMAX LITABSZ-1 /* input line */ #define LINESIZE 150 #define LINEMAX (LINESIZE-1) #define MPMAX LINEMAX /* macro (define) pool */ #define MACQSIZE 1000 #define MACMAX (MACQSIZE-1) /* "include" stack */ #define INCLSIZ 3 /* statement types (tokens) */ #define STIF 1 #define STWHILE 2 #define STRETURN 3 #define STBREAK 4 #define STCONT 5 #define STASM 6 #define STEXP 7 #define STDO 8 #define STFOR 9 #define STSWITCH 10 #define DEFLIB inclib() SHAR_EOF if test 1982 -ne "`wc -c < 'defs.h'`" then echo shar: error transmitting "'defs.h'" '(should have been 1982 characters)' fi fi echo shar: extracting "'error.c'" '(552 characters)' if test -f 'error.c' then echo shar: will not over-write existing file "'error.c'" else cat << \SHAR_EOF > 'error.c' /* File error.c: 2.1 (83/03/20,16:02:00) */ /*% cc -O -c % * */ #include <stdio.h> #include "defs.h" #include "data.h" error (ptr) char ptr[]; { FILE *tempfile; tempfile = output; output = stdout; doerror(ptr); output = tempfile; doerror(ptr); errcnt++; } doerror(ptr) char *ptr; { int k; comment (); outstr (line); nl (); comment (); k = 0; while (k < lptr) { if (line[k] == 9) tab (); else outbyte (' '); k++; } outbyte ('^'); nl (); comment (); outstr ("****** "); outstr (ptr); outstr (" ******"); nl (); } SHAR_EOF if test 552 -ne "`wc -c < 'error.c'`" then echo shar: error transmitting "'error.c'" '(should have been 552 characters)' fi fi echo shar: extracting "'expr.c'" '(10028 characters)' if test -f 'expr.c' then echo shar: will not over-write existing file "'expr.c'" else cat << \SHAR_EOF > 'expr.c' /* File expr.c: 2.2 (83/06/21,11:24:26) */ /*% cc -O -c % * */ #include <stdio.h> #include "defs.h" #include "data.h" /* * lval[0] - symbol table address, else 0 for constant * lval[1] - type indirect object to fetch, else 0 for static object * lval[2] - type pointer or array, else 0 */ expression (comma) int comma; { int lval[3]; do { if (heir1 (lval)) rvalue (lval); if (!comma) return; } while (match (",")); } heir1 (lval) int lval[]; { int k, lval2[3]; char fc; k = heir1a (lval); if (match ("=")) { if (k == 0) { needlval (); return (0); } if (lval[1]) gpush (); if (heir1 (lval2)) rvalue (lval2); store (lval); return (0); } else { fc = ch(); if (match ("-=") || match ("+=") || match ("*=") || match ("/=") || match ("%=") || match (">>=") || match ("<<=") || match ("&=") || match ("^=") || match ("|=")) { if (k == 0) { needlval (); return (0); } if (lval[1]) gpush (); rvalue (lval); gpush (); if (heir1 (lval2)) rvalue (lval2); switch (fc) { case '-': { if (dbltest(lval,lval2)) gaslint(); gsub(); result (lval, lval2); break; } case '+': { if (dbltest(lval,lval2)) gaslint(); gadd (lval,lval2); result(lval,lval2); break; } case '*': gmult (); break; case '/': gdiv (); break; case '%': gmod (); break; case '>': gasr (); break; case '<': gasl (); break; case '&': gand (); break; case '^': gxor (); break; case '|': gor (); break; } store (lval); return (0); } else return (k); } } heir1a (lval) int lval[]; { int k, lval2[3], lab1, lab2; k = heir1b (lval); blanks (); if (ch () != '?') return (k); if (k) rvalue (lval); FOREVER if (match ("?")) { testjump (lab1 = getlabel (), FALSE); if (heir1b (lval2)) rvalue (lval2); jump (lab2 = getlabel ()); printlabel (lab1); col (); nl (); blanks (); if (!match (":")) { error ("missing colon"); return (0); } if (heir1b (lval2)) rvalue (lval2); printlabel (lab2); col (); nl (); } else return (0); } heir1b (lval) int lval[]; { int k, lval2[3], lab; k = heir1c (lval); blanks (); if (!sstreq ("||")) return (k); if (k) rvalue (lval); FOREVER if (match ("||")) { testjump (lab = getlabel (), TRUE); if (heir1c (lval2)) rvalue (lval2); printlabel (lab); col (); nl (); gbool(); } else return (0); } heir1c (lval) int lval[]; { int k, lval2[3], lab; k = heir2 (lval); blanks (); if (!sstreq ("&&")) return (k); if (k) rvalue (lval); FOREVER if (match ("&&")) { testjump (lab = getlabel (), FALSE); if (heir2 (lval2)) rvalue (lval2); printlabel (lab); col (); nl (); gbool(); } else return (0); } heir2 (lval) int lval[]; { int k, lval2[3]; k = heir3 (lval); blanks (); if ((ch() != '|') | (nch() == '|') | (nch() == '=')) return (k); if (k) rvalue (lval); FOREVER { if ((ch() == '|') & (nch() != '|') & (nch() != '=')) { inbyte (); gpush (); if (heir3 (lval2)) rvalue (lval2); gor (); blanks(); } else return (0); } } heir3 (lval) int lval[]; { int k, lval2[3]; k = heir4 (lval); blanks (); if ((ch () != '^') | (nch() == '=')) return (k); if (k) rvalue (lval); FOREVER { if ((ch() == '^') & (nch() != '=')){ inbyte (); gpush (); if (heir4 (lval2)) rvalue (lval2); gxor (); blanks(); } else return (0); } } heir4 (lval) int lval[]; { int k, lval2[3]; k = heir5 (lval); blanks (); if ((ch() != '&') | (nch() == '|') | (nch() == '=')) return (k); if (k) rvalue (lval); FOREVER { if ((ch() == '&') & (nch() != '&') & (nch() != '=')) { inbyte (); gpush (); if (heir5 (lval2)) rvalue (lval2); gand (); blanks(); } else return (0); } } heir5 (lval) int lval[]; { int k, lval2[3]; k = heir6 (lval); blanks (); if (!sstreq ("==") & !sstreq ("!=")) return (k); if (k) rvalue (lval); FOREVER { if (match ("==")) { gpush (); if (heir6 (lval2)) rvalue (lval2); geq (); } else if (match ("!=")) { gpush (); if (heir6 (lval2)) rvalue (lval2); gne (); } else return (0); } } heir6 (lval) int lval[]; { int k, lval2[3]; k = heir7 (lval); blanks (); if (!sstreq ("<") && !sstreq ("<=") && !sstreq (">=") && !sstreq (">")) return (k); if (sstreq ("<<") || sstreq (">>")) return (k); if (k) rvalue (lval); FOREVER { if (match ("<=")) { gpush (); if (heir7 (lval2)) rvalue (lval2); if (lval[2] || lval2[2]) { gule (); continue; } gle (); } else if (match (">=")) { gpush (); if (heir7 (lval2)) rvalue (lval2); if (lval[2] || lval2[2]) { guge (); continue; } gge (); } else if ((sstreq ("<")) && !sstreq ("<<")) { inbyte (); gpush (); if (heir7 (lval2)) rvalue (lval2); if (lval[2] || lval2[2]) { gult (); continue; } glt (); } else if ((sstreq (">")) && !sstreq (">>")) { inbyte (); gpush (); if (heir7 (lval2)) rvalue (lval2); if (lval[2] || lval2[2]) { gugt (); continue; } ggt (); } else return (0); blanks (); } } heir7 (lval) int lval[]; { int k, lval2[3]; k = heir8 (lval); blanks (); if (!sstreq (">>") && !sstreq ("<<") || sstreq(">>=") || sstreq("<<=")) return (k); if (k) rvalue (lval); FOREVER { if (sstreq(">>") && ! sstreq(">>=")) { inbyte(); inbyte(); gpush (); if (heir8 (lval2)) rvalue (lval2); gasr (); } else if (sstreq("<<") && ! sstreq("<<=")) { inbyte(); inbyte(); gpush (); if (heir8 (lval2)) rvalue (lval2); gasl (); } else return (0); blanks(); } } heir8 (lval) int lval[]; { int k, lval2[3]; k = heir9 (lval); blanks (); if ((ch () != '+') & (ch () != '-') | nch() == '=') return (k); if (k) rvalue (lval); FOREVER { if (match ("+")) { gpush (); if (heir9 (lval2)) rvalue (lval2); /* if left is pointer and right is int, scale right */ if (dbltest (lval, lval2)) gaslint (); /* will scale left if right int pointer and left int */ gadd (lval,lval2); result (lval, lval2); } else if (match ("-")) { gpush (); if (heir9 (lval2)) rvalue (lval2); /* if dbl, can only be: pointer - int, or pointer - pointer, thus, in first case, int is scaled up, in second, result is scaled down. */ if (dbltest (lval, lval2)) gaslint (); gsub (); /* if both pointers, scale result */ if ((lval[2] == CINT) && (lval2[2] == CINT)) { gasrint(); /* divide by intsize */ } result (lval, lval2); } else return (0); } } heir9 (lval) int lval[]; { int k, lval2[3]; k = heir10 (lval); blanks (); if (((ch () != '*') && (ch () != '/') && (ch () != '%')) || (nch() == '=')) return (k); if (k) rvalue (lval); FOREVER { if (match ("*")) { gpush (); if (heir10 (lval2)) rvalue (lval2); gmult (); } else if (match ("/")) { gpush (); if (heir10 (lval2)) rvalue (lval2); gdiv (); } else if (match ("%")) { gpush (); if (heir10 (lval2)) rvalue (lval2); gmod (); } else return (0); } } heir10 (lval) int lval[]; { int k; char *ptr; if (match ("++")) { if ((k = heir10 (lval)) == 0) { needlval (); return (0); } if (lval[1]) gpush (); rvalue (lval); ginc (lval); store (lval); return (0); } else if (match ("--")) { if ((k = heir10 (lval)) == 0) { needlval (); return (0); } if (lval[1]) gpush (); rvalue (lval); gdec (lval); store (lval); return (0); } else if (match ("-")) { k = heir10 (lval); if (k) rvalue (lval); gneg (); return (0); } else if (match ("~")) { k = heir10 (lval); if (k) rvalue (lval); gcom (); return (0); } else if (match ("!")) { k = heir10 (lval); if (k) rvalue (lval); glneg (); return (0); } else if (ch()=='*' && nch() != '=') { inbyte(); k = heir10 (lval); if (k) rvalue (lval); if (ptr = lval[0]) lval[1] = ptr[TYPE]; else lval[1] = CINT; lval[2] = 0; /* flag as not pointer or array */ return (1); } else if (ch()=='&' && nch()!='&' && nch()!='=') { inbyte(); k = heir10 (lval); if (k == 0) { error ("illegal address"); return (0); } ptr = lval[0]; lval[2] = ptr[TYPE]; if (lval[1]) return (0); /* global and non-array */ immed (); prefix (); outstr (ptr = lval[0]); nl (); lval[1] = ptr[TYPE]; return (0); } else { k = heir11 (lval); if (match ("++")) { if (k == 0) { needlval (); return (0); } if (lval[1]) gpush (); rvalue (lval); ginc (lval); store (lval); gdec (lval); return (0); } else if (match ("--")) { if (k == 0) { needlval (); return (0); } if (lval[1]) gpush (); rvalue (lval); gdec (lval); store (lval); ginc (lval); return (0); } else return (k); } } heir11 (lval) int *lval; { int k; char *ptr; k = primary (lval); ptr = lval[0]; blanks (); if ((ch () == '[') | (ch () == '(')) FOREVER { if (match ("[")) { if (ptr == 0) { error ("can't subscript"); junk (); needbrack ("]"); return (0); } else if (ptr[IDENT] == POINTER) rvalue (lval); else if (ptr[IDENT] != ARRAY) { error ("can't subscript"); k = 0; } gpush (); expression (YES); needbrack ("]"); if (ptr[TYPE] == CINT) gaslint (); gadd (NULL,NULL); lval[0] = 0; lval[1] = ptr[TYPE]; k = 1; } else if (match ("(")) { if (ptr == 0) callfunction (0); else if (ptr[IDENT] != FUNCTION) { rvalue (lval); callfunction (0); } else callfunction (ptr); k = lval[0] = 0; } else return (k); } if (ptr == 0) return (k); if (ptr[IDENT] == FUNCTION) { immed (); prefix (); outstr (ptr); nl (); return (0); } return (k); } SHAR_EOF if test 10028 -ne "`wc -c < 'expr.c'`" then echo shar: error transmitting "'expr.c'" '(should have been 10028 characters)' fi fi echo shar: extracting "'function.c'" '(2643 characters)' if test -f 'function.c' then echo shar: will not over-write existing file "'function.c'" else cat << \SHAR_EOF > 'function.c' /* File function.c: 2.1 (83/03/20,16:02:04) */ /*% cc -O -c % * */ #include <stdio.h> #include "defs.h" #include "data.h" /* * begin a function * * called from "parse", this routine tries to make a function out * of what follows * modified version. p.l. woods * */ int argtop; newfunc () { char n[NAMESIZE], *ptr; fexitlab = getlabel(); if (!symname (n) ) { error ("illegal function or declaration"); kill (); return; } if (ptr = findglb (n)) { if (ptr[IDENT] != FUNCTION) multidef (n); else if (ptr[OFFSET] == FUNCTION) multidef (n); else ptr[OFFSET] = FUNCTION; } else addglb (n, FUNCTION, CINT, FUNCTION, PUBLIC); prologue (); if (!match ("(")) error ("missing open paren"); prefix (); outstr (n); col (); nl (); locptr = STARTLOC; argstk = 0; while (!match (")")) { if (symname (n)) { if (findloc (n)) multidef (n); else { addloc (n, 0, 0, argstk, AUTO); argstk = argstk + intsize(); } } else { error ("illegal argument name"); junk (); } blanks (); if (!streq (line + lptr, ")")) { if (!match (",")) error ("expected comma"); } if (endst ()) break; } stkp = 0; argtop = argstk; while (argstk) { if (amatch ("register", 8)) { if (amatch("char", 4)) getarg(CCHAR); else if (amatch ("int", 3)) getarg(CINT); else getarg(CINT); ns(); } else if (amatch ("char", 4)) { getarg (CCHAR); ns (); } else if (amatch ("int", 3)) { getarg (CINT); ns (); } else { error ("wrong number args"); break; } } statement(YES); printlabel(fexitlab); col(); nl(); modstk (0); gret (); stkp = 0; locptr = STARTLOC; } /* * declare argument types * * called from "newfunc", this routine add an entry in the local * symbol table for each named argument * completely rewritten version. p.l. woods * */ getarg (t) int t; { int j, legalname, address; char n[NAMESIZE], c, *argptr; FOREVER { if (argstk == 0) return; if (match ("*")) j = POINTER; else j = VARIABLE; if (!(legalname = symname (n))) illname (); if (match ("[")) { while (inbyte () != ']') if (endst ()) break; j = POINTER; } if (legalname) { if (argptr = findloc (n)) { argptr[IDENT] = j; argptr[TYPE] = t; address = argtop - glint(argptr); if (t == CCHAR && j == VARIABLE) address = address + byteoff(); argptr[OFFSET] = (address) & 0xff; argptr[OFFSET + 1] = (address >> 8) & 0xff; } else error ("expecting argument name"); } argstk = argstk - intsize(); if (endst ()) return; if (!match (",")) error ("expected comma"); } } SHAR_EOF if test 2643 -ne "`wc -c < 'function.c'`" then echo shar: error transmitting "'function.c'" '(should have been 2643 characters)' fi fi echo shar: extracting "'gen.c'" '(1495 characters)' if test -f 'gen.c' then echo shar: will not over-write existing file "'gen.c'" else cat << \SHAR_EOF > 'gen.c' /* File gen.c: 2.1 (83/03/20,16:02:06) */ /*% cc -O -c % * */ #include <stdio.h> #include "defs.h" #include "data.h" /* * return next available internal label number * */ getlabel () { return (nxtlab++); } /* * print specified number as label */ printlabel (label) int label; { olprfix (); outdec (label); } /* * glabel - generate label */ glabel (lab) char *lab; { prefix (); outstr (lab); col (); nl (); } /* * gnlabel - generate numeric label */ gnlabel (nlab) int nlab; { printlabel (nlab); col (); nl (); } outbyte (c) char c; { if (c == 0) return (0); fputc (c, output); return (c); } outstr (ptr) char ptr[]; { int k; k = 0; while (outbyte (ptr[k++])); } tab () { outbyte (9); } ol (ptr) char ptr[]; { ot (ptr); nl (); } ot (ptr) char ptr[]; { tab (); outstr (ptr); } outdec (number) int number; { int k, zs; char c; if (number == -32768) { outstr ("-32768"); return; } zs = 0; k = 10000; if (number < 0) { number = (-number); outbyte ('-'); } while (k >= 1) { c = number / k + '0'; if ((c != '0' | (k == 1) | zs)) { zs = 1; outbyte (c); } number = number % k; k = k / 10; } } store (lval) int *lval; { if (lval[1] == 0) putmem (lval[0]); else putstk (lval[1]); } rvalue (lval) int *lval; { if ((lval[0] != 0) & (lval[1] == 0)) getmem (lval[0]); else indirect (lval[1]); } test (label, ft) int label, ft; { needbrack ("("); expression (YES); needbrack (")"); testjump (label, ft); } SHAR_EOF if test 1495 -ne "`wc -c < 'gen.c'`" then echo shar: error transmitting "'gen.c'" '(should have been 1495 characters)' fi fi echo shar: extracting "'io.c'" '(2032 characters)' if test -f 'io.c' then echo shar: will not over-write existing file "'io.c'" else cat << \SHAR_EOF > 'io.c' /* File io.c: 2.1 (83/03/20,16:02:07) */ /*% cc -O -c % * */ #include <stdio.h> #include "defs.h" #include "data.h" /* * open input file */ openin (p) char *p; { strcpy(fname, p); fixname (fname); if (!checkname (fname)) return (NO); if ((input = fopen (fname, "r")) == NULL) { pl ("Open failure\n"); return (NO); } kill (); return (YES); } /* * open output file */ openout () { outfname (fname); if ((output = fopen (fname, "w")) == NULL) { pl ("Open failure"); return (NO); } kill (); return (YES); } /* * change input filename to output filename */ outfname (s) char *s; { while (*s) s++; *--s = 's'; } /* * remove NL from filenames * */ fixname (s) char *s; { while (*s && *s++ != EOL); if (!*s) return; *(--s) = 0; } /* * check that filename is "*.c" */ checkname (s) char *s; { while (*s) s++; if (*--s != 'c') return (NO); if (*--s != '.') return (NO); return (YES); } kill () { lptr = 0; line[lptr] = 0; } inline () { int k; FILE *unit; FOREVER { if (feof (input)) return; if ((unit = input2) == NULL) unit = input; kill (); while ((k = fgetc (unit)) != EOF) { if ((k == EOL) | (lptr >= LINEMAX)) break; line[lptr++] = k; } line[lptr] = 0; if (k <= 0) if (input2 != NULL) { input2 = inclstk[--inclsp]; fclose (unit); } if (lptr) { if ((ctext) & (cmode)) { comment (); outstr (line); nl (); } lptr = 0; return; } } } inbyte () { while (ch () == 0) { if (feof (input)) return (0); preprocess (); } return (gch ()); } inchar () { if (ch () == 0) inline (); if (feof (input)) return (0); return (gch ()); } gch () { if (ch () == 0) return (0); else return (line[lptr++] & 127); } nch () { if (ch () == 0) return (0); else return (line[lptr + 1] & 127); } ch () { return (line[lptr] & 127); } /* * print a carriage return and a string only to console * */ pl (str) char *str; { int k; k = 0; putchar (EOL); while (str[k]) putchar (str[k++]); } SHAR_EOF if test 2032 -ne "`wc -c < 'io.c'`" then echo shar: error transmitting "'io.c'" '(should have been 2032 characters)' fi fi echo shar: extracting "'lex.c'" '(2029 characters)' if test -f 'lex.c' then echo shar: will not over-write existing file "'lex.c'" else cat << \SHAR_EOF > 'lex.c' /* File lex.c: 2.1 (83/03/20,16:02:09) */ /*% cc -O -c % * */ #include <stdio.h> #include "defs.h" #include "data.h" /* * semicolon enforcer * * called whenever syntax requires a semicolon * */ ns () { if (!match (";")) error ("missing semicolon"); } junk () { if (an (inbyte ())) while (an (ch ())) gch (); else while (an (ch ())) { if (ch () == 0) break; gch (); } blanks (); } endst () { blanks (); return ((streq (line + lptr, ";") | (ch () == 0))); } needbrack (str) char *str; { if (!match (str)) { error ("missing bracket"); comment (); outstr (str); nl (); } } /* * test if given character is alpha * */ alpha (c) char c; { c = c & 127; return (((c >= 'a') & (c <= 'z')) | ((c >= 'A') & (c <= 'Z')) | (c == '_')); } /* * test if given character is numeric * */ numeric (c) char c; { c = c & 127; return ((c >= '0') & (c <= '9')); } /* * test if given character is alphanumeric * */ an (c) char c; { return ((alpha (c)) | (numeric (c))); } sstreq (str1) char *str1; { return (streq(line + lptr, str1)); } streq (str1, str2) char str1[], str2[]; { int k; k = 0; while (str2[k]) { if ((str1[k] != str2[k])) return (0); k++; } return (k); } astreq (str1, str2, len) char str1[], str2[]; int len; { int k; k = 0; while (k < len) { if ((str1[k] != str2[k])) break; if (str1[k] == 0) break; if (str2[k] == 0) break; k++; } if (an (str1[k])) return (0); if (an (str2[k])) return (0); return (k); } match (lit) char *lit; { int k; blanks (); if (k = streq (line + lptr, lit)) { lptr = lptr + k; return (1); } return (0); } amatch (lit, len) char *lit; int len; { int k; blanks (); if (k = astreq (line + lptr, lit, len)) { lptr = lptr + k; while (an (ch ())) inbyte (); return (1); } return (0); } blanks () { FOREVER { while (ch () == 0) { preprocess (); if (feof (input)) break; } if (ch () == ' ') gch (); else if (ch () == 9) gch (); else return; } } SHAR_EOF if test 2029 -ne "`wc -c < 'lex.c'`" then echo shar: error transmitting "'lex.c'" '(should have been 2029 characters)' fi fi echo shar: extracting "'main.c'" '(4283 characters)' if test -f 'main.c' then echo shar: will not over-write existing file "'main.c'" else cat << \SHAR_EOF > 'main.c' /* File main.c: 2.7 (84/11/28,10:14:56) */ /*% cc -O -c % * */ #include <stdio.h> #include "defs.h" #include "data.h" main (argc, argv) int argc, *argv; { char *p,*bp; int smacptr; macptr = 0; ctext = 0; argc--; argv++; errs = 0; aflag = 1; while (p = *argv++) if (*p == '-') while (*++p) switch(*p) { case 't': case 'T': ctext = 1; break; case 's': case 'S': sflag = 1; break; case 'c': case 'C': cflag = 1; break; case 'a': case 'A': aflag = 0; break; case 'd': case 'D': bp = ++p; if (!*p) usage(); while (*p && *p != '=') p++; if (*p == '=') *p = '\t'; while (*p) p++; p--; defmac(bp); break; default: usage(); } else break; smacptr = macptr; if (!p) usage(); while (p) { errfile = 0; if (typeof(p) == 'c') { glbptr = STARTGLB; locptr = STARTLOC; wsptr = ws; inclsp = iflevel = skiplevel = swstp = litptr = stkp = errcnt = ncmp = lastst = quote[1] = 0; macptr = smacptr; input2 = NULL; quote[0] = '"'; cmode = 1; glbflag = 1; nxtlab = 0; litlab = getlabel (); defmac("end\tmemory"); addglb("memory", ARRAY, CCHAR, 0, EXTERN); addglb("stack", ARRAY, CCHAR, 0, EXTERN); rglbptr = glbptr; addglb ("etext", ARRAY, CCHAR, 0, EXTERN); addglb ("edata", ARRAY, CCHAR, 0, EXTERN); defmac("short\tint"); initmac(); /* * compiler body */ if (!openin (p)) return; if (!openout ()) return; header (); gtext (); parse (); fclose (input); gdata (); dumplits (); dumpglbs (); errorsummary (); trailer (); fclose (output); pl (""); errs = errs || errfile; #ifndef NOASLD } if (!errfile && !sflag) errs = errs || assemble(p); #else } else { fputs("Don't understand file ", stderr); fputs(p, stderr); errs = 1; } #endif p = *argv++; } #ifndef NOASLD if (!errs && !sflag && !cflag) errs = errs || link(); #endif exit(errs != 0); } FEvers() { outstr("\tFront End (2.7,84/11/28)"); } usage() { fputs("usage: sccXXXX [-tcsa] [-dSYM[=VALUE]] files\n", stderr); exit(1); } /* * process all input text * * at this level, only static declarations, defines, includes, * and function definitions are legal. * */ parse () { while (!feof (input)) { if (amatch ("extern", 6)) dodcls(EXTERN); else if (amatch ("static",6)) dodcls(STATIC); else if (dodcls(PUBLIC)) ; else if (match ("#asm")) doasm (); else if (match ("#include")) doinclude (); else if (match ("#define")) dodefine(); else if (match ("#undef")) doundef(); else newfunc (); blanks (); } } /* * parse top level declarations */ dodcls(stclass) int stclass; { blanks(); if (amatch("char", 4)) declglb(CCHAR, stclass); else if (amatch("int", 3)) declglb(CINT, stclass); else if (stclass == PUBLIC) return(0); else declglb(CINT, stclass); ns (); return(1); } /* * dump the literal pool */ dumplits () { int j, k; if (litptr == 0) return; printlabel (litlab); col (); k = 0; while (k < litptr) { defbyte (); j = 8; while (j--) { onum (litq[k++] & 127); if ((j == 0) | (k >= litptr)) { nl (); break; } outbyte (','); } } } /* * dump all static variables */ dumpglbs () { int j; if (!glbflag) return; cptr = rglbptr; while (cptr < glbptr) { if (cptr[IDENT] != FUNCTION) { ppubext(cptr); if (cptr[STORAGE] != EXTERN) { prefix (); outstr (cptr); col (); defstorage (); j = glint(cptr); if ((cptr[TYPE] == CINT) || (cptr[IDENT] == POINTER)) j = j * intsize(); onum (j); nl (); } } else { fpubext(cptr); } cptr = cptr + SYMSIZ; } } /* * report errors */ errorsummary () { if (ncmp) error ("missing closing bracket"); nl (); comment (); outdec (errcnt); if (errcnt) errfile = YES; outstr (" error(s) in compilation"); nl (); comment(); ot("literal pool:"); outdec(litptr); nl(); comment(); ot("global pool:"); outdec(glbptr-rglbptr); nl(); comment(); ot("Macro pool:"); outdec(macptr); nl(); pl (errcnt ? "Error(s)" : "No errors"); } typeof(s) char *s; { s += strlen(s) - 2; if (*s == '.') return(*(s+1)); return(' '); } SHAR_EOF if test 4283 -ne "`wc -c < 'main.c'`" then echo shar: error transmitting "'main.c'" '(should have been 4283 characters)' fi fi echo shar: extracting "'preproc.c'" '(5137 characters)' if test -f 'preproc.c' then echo shar: will not over-write existing file "'preproc.c'" else cat << \SHAR_EOF > 'preproc.c' /* File preproc.c: 2.3 (84/11/27,11:47:40) */ /*% cc -O -c % * */ #include <stdio.h> #include "defs.h" #include "data.h" /* * open an include file */ doinclude () { char *p; FILE *inp2; blanks (); if (inp2 = fixiname ()) if (inclsp < INCLSIZ) { inclstk[inclsp++] = input2; input2 = inp2; } else { fclose (inp2); error ("too many nested includes"); } else { error ("Could not open include file"); } kill (); } /* * fixiname - remove "brackets" around include file name */ fixiname () { char c1, c2, *p, *ibp; char buf[20]; FILE *fp; char buf2[100]; ibp = &buf[0]; if ((c1 = gch ()) != '"' && c1 != '<') return (NULL); for (p = line + lptr; *p ;) *ibp++ = *p++; c2 = *(--p); if (c1 == '"' ? (c2 != '"') : (c2 != '>')) { error ("incorrect delimiter"); return (NULL); } *(--ibp) = 0; fp = NULL; if (c1 == '<' || !(fp = fopen(buf, "r"))) { strcpy(buf2, DEFLIB); strcat(buf2, buf); fp = fopen(buf2, "r"); } return(fp); } /* * "asm" pseudo-statement * * enters mode where assembly language statements are passed * intact through parser * */ doasm () { cmode = 0; FOREVER { inline (); if (match ("#endasm")) break; if (feof (input)) break; outstr (line); nl (); } kill (); cmode = 1; } dodefine () { addmac(); } doundef () { int mp; char sname[NAMESIZE]; if (!symname(sname)) { illname(); kill(); return; } if (mp = findmac(sname)) delmac(mp); kill(); } preprocess () { if (ifline()) return; while (cpp()); } doifdef (ifdef) int ifdef; { char sname[NAMESIZE]; int k; blanks(); ++iflevel; if (skiplevel) return; k = symname(sname) && findmac(sname); if (k != ifdef) skiplevel = iflevel; } ifline() { FOREVER { inline(); if (feof(input)) return(1); if (match("#ifdef")) { doifdef(YES); continue; } else if (match("#ifndef")) { doifdef(NO); continue; } else if (match("#else")) { if (iflevel) { if (skiplevel == iflevel) skiplevel = 0; else if (skiplevel == 0) skiplevel = iflevel; } else noiferr(); continue; } else if (match("#endif")) { if (iflevel) { if (skiplevel == iflevel) skiplevel = 0; --iflevel; } else noiferr(); continue; } if (!skiplevel) return(0); } } noiferr() { error("no matching #if..."); } cpp () { int k; char c, sname[NAMESIZE]; int tog; int cpped; /* non-zero if something expanded */ cpped = 0; /* don't expand lines with preprocessor commands in them */ if (!cmode || line[0] == '#') return(0); mptr = lptr = 0; while (ch ()) { if ((ch () == ' ') | (ch () == 9)) { keepch (' '); while ((ch () == ' ') | (ch () == 9)) gch (); } else if (ch () == '"') { keepch (ch ()); gch (); while (ch () != '"') { if (ch () == 0) { error ("missing quote"); break; } if (ch() == '\\') keepch(gch()); keepch (gch ()); } gch (); keepch ('"'); } else if (ch () == 39) { keepch (39); gch (); while (ch () != 39) { if (ch () == 0) { error ("missing apostrophe"); break; } if (ch() == '\\') keepch(gch()); keepch (gch ()); } gch (); keepch (39); } else if ((ch () == '/') & (nch () == '*')) { inchar (); inchar (); while ((((c = ch ()) == '*') & (nch () == '/')) == 0) if (c == '$') { inchar (); tog = TRUE; if (ch () == '-') { tog = FALSE; inchar (); } if (alpha (c = ch ())) { inchar (); toggle (c, tog); } } else { if (ch () == 0) inline (); else inchar (); if (feof (input)) break; } inchar (); inchar (); } else if (an (ch ())) { k = 0; while (an (ch ())) { if (k < NAMEMAX) sname[k++] = ch (); gch (); } sname[k] = 0; if (k = findmac (sname)) { cpped = 1; while (c = macq[k++]) keepch (c); } else { k = 0; while (c = sname[k++]) keepch (c); } } else keepch (gch ()); } keepch (0); if (mptr >= MPMAX) error ("line too long"); lptr = mptr = 0; while (line[lptr++] = mline[mptr++]); lptr = 0; return(cpped); } keepch (c) char c; { mline[mptr] = c; if (mptr < MPMAX) mptr++; return (c); } defmac(s) char *s; { kill(); strcpy(line, s); addmac(); } addmac () { char sname[NAMESIZE]; int k; int mp; if (!symname (sname)) { illname (); kill (); return; } if (mp = findmac(sname)) { error("Duplicate define"); delmac(mp); } k = 0; while (putmac (sname[k++])); while (ch () == ' ' | ch () == 9) gch (); while (putmac (gch ())); if (macptr >= MACMAX) error ("macro table full"); } delmac(mp) int mp; { --mp; --mp; /* step over previous null */ while (mp >= 0 && macq[mp]) macq[mp--] = '%'; } putmac (c) char c; { macq[macptr] = c; if (macptr < MACMAX) macptr++; return (c); } findmac (sname) char *sname; { int k; k = 0; while (k < macptr) { if (astreq (sname, macq + k, NAMEMAX)) { while (macq[k++]); return (k); } while (macq[k++]); while (macq[k++]); } return (0); } toggle (name, onoff) char name; int onoff; { switch (name) { case 'C': ctext = onoff; break; } } SHAR_EOF if test 5137 -ne "`wc -c < 'preproc.c'`" then echo shar: error transmitting "'preproc.c'" '(should have been 5137 characters)' fi fi echo shar: extracting "'primary.c'" '(4818 characters)' if test -f 'primary.c' then echo shar: will not over-write existing file "'primary.c'" else cat << \SHAR_EOF > 'primary.c' /* File primary.c: 2.4 (84/11/27,16:26:07) */ /*% cc -O -c % * */ #include <stdio.h> #include "defs.h" #include "data.h" primary (lval) int *lval; { char *ptr, sname[NAMESIZE]; int num[1]; int k; lval[2] = 0; /* clear pointer/array type */ if (match ("(")) { k = heir1 (lval); needbrack (")"); return (k); } if (amatch("sizeof", 6)) { needbrack("("); immed(); if (amatch("int", 3)) onum(intsize()); else if (amatch("char", 4)) onum(1); else if (symname(sname)) { if ((ptr = findloc(sname)) || (ptr = findglb(sname))) { if (ptr[STORAGE] == LSTATIC) error("sizeof local static"); k = glint(ptr); if ((ptr[TYPE] == CINT) || (ptr[IDENT] == POINTER)) k *= intsize(); onum(k); } else { error("sizeof undeclared variable"); onum(0); } } else { error("sizeof only on type or variable"); } needbrack(")"); nl(); return(lval[0] = lval[1] = 0); } if (symname (sname)) { if (ptr = findloc (sname)) { getloc (ptr); lval[0] = ptr; lval[1] = ptr[TYPE]; if (ptr[IDENT] == POINTER) { lval[1] = CINT; lval[2] = ptr[TYPE]; } if (ptr[IDENT] == ARRAY) { lval[2] = ptr[TYPE]; lval[2] = 0; return (0); } else return (1); } if (ptr = findglb (sname)) if (ptr[IDENT] != FUNCTION) { lval[0] = ptr; lval[1] = 0; if (ptr[IDENT] != ARRAY) { if (ptr[IDENT] == POINTER) lval[2] = ptr[TYPE]; return (1); } immed (); prefix (); outstr (ptr); nl (); lval[1] = lval[2] = ptr[TYPE]; lval[2] = 0; return (0); } blanks (); if (ch() != '(') error("undeclared variable"); ptr = addglb (sname, FUNCTION, CINT, 0, PUBLIC); lval[0] = ptr; lval[1] = 0; return (0); } if (constant (num)) return (lval[0] = lval[1] = 0); else { error ("invalid expression"); immed (); onum (0); nl (); junk (); return (0); } } /* * true if val1 -> int pointer or int array and val2 not pointer or array */ dbltest (val1, val2) int val1[], val2[]; { if (val1 == NULL) return (FALSE); if (val1[2] != CINT) return (FALSE); if (val2[2]) return (FALSE); return (TRUE); } /* * determine type of binary operation */ result (lval, lval2) int lval[], lval2[]; { if (lval[2] && lval2[2]) lval[2] = 0; else if (lval2[2]) { lval[0] = lval2[0]; lval[1] = lval2[1]; lval[2] = lval2[2]; } } constant (val) int val[]; { if (number (val)) immed (); else if (pstr (val)) immed (); else if (qstr (val)) { immed (); printlabel (litlab); outbyte ('+'); } else return (0); onum (val[0]); nl (); return (1); } number (val) int val[]; { int k, minus, base; char c; k = minus = 1; while (k) { k = 0; if (match ("+")) k = 1; if (match ("-")) { minus = (-minus); k = 1; } } if (!numeric (c = ch ())) return (0); if (match ("0x") || match ("0X")) while (numeric (c = ch ()) || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F')) { inbyte (); k = k * 16 + (numeric (c) ? (c - '0') : ((c & 07) + 9)); } else { base = (c == '0') ? 8 : 10; while (numeric (ch ())) { c = inbyte (); k = k * base + (c - '0'); } } if (minus < 0) k = (-k); val[0] = k; return (1); } pstr (val) int val[]; { int k; char c; k = 0; if (!match ("'")) return (0); while ((c = gch ()) != 39) { c = (c == '\\') ? spechar(): c; k = (k & 255) * 256 + (c & 255); } val[0] = k; return (1); } qstr (val) int val[]; { char c; if (!match (quote)) return (0); val[0] = litptr; while (ch () != '"') { if (ch () == 0) break; if (litptr >= LITMAX) { error ("string space exhausted"); while (!match (quote)) if (gch () == 0) break; return (1); } c = gch(); litq[litptr++] = (c == '\\') ? spechar(): c; } gch (); litq[litptr++] = 0; return (1); } /* * decode special characters (preceeded by back slashes) */ spechar() { char c; c = ch(); if (c == 'n') c = EOL; else if (c == 't') c = TAB; else if (c == 'r') c = CR; else if (c == 'f') c = FFEED; else if (c == 'b') c = BKSP; else if (c == '0') c = EOS; else if (c == EOS) return; gch(); return (c); } /* * perform a function call * * called from "heir11", this routine will either call the named * function, or if the supplied ptr is zero, will call the contents * of HL * */ callfunction (ptr) char *ptr; { int nargs; nargs = 0; blanks (); if (ptr == 0) gpush (); while (!streq (line + lptr, ")")) { if (endst ()) break; expression (NO); if (ptr == 0) swapstk (); gpush (); nargs = nargs + intsize(); if (!match (",")) break; } needbrack (")"); if (aflag) gnargs(nargs / intsize()); if (ptr) gcall (ptr); else callstk (); stkp = modstk (stkp + nargs); } needlval () { error ("must be lvalue"); } SHAR_EOF if test 4818 -ne "`wc -c < 'primary.c'`" then echo shar: error transmitting "'primary.c'" '(should have been 4818 characters)' fi fi echo shar: extracting "'stmt.c'" '(6668 characters)' if test -f 'stmt.c' then echo shar: will not over-write existing file "'stmt.c'" else cat << \SHAR_EOF > 'stmt.c' /* File stmt.c: 2.1 (83/03/20,16:02:17) */ /*% cc -O -c % * */ #include <stdio.h> #include "defs.h" #include "data.h" /* * statement parser * * called whenever syntax requires a statement. this routine * performs that statement and returns a number telling which one * * 'func' is true if we require a "function_statement", which * must be compound, and must contain "statement_list" (even if * "declaration_list" is omitted) */ statement (func) int func; { if ((ch () == 0) & feof (input)) return (0); lastst = 0; if (func) if (match ("{")) { compound (YES); return (lastst); } else error ("function requires compound statement"); if (match ("{")) compound (NO); else stst (); return (lastst); } /* * declaration */ stdecl () { if (amatch("register", 8)) doldcls(DEFAUTO); else if (amatch("auto", 4)) doldcls(DEFAUTO); else if (amatch("static", 6)) doldcls(LSTATIC); else if (doldcls(AUTO)) ; else return (NO); return (YES); } doldcls(stclass) int stclass; { blanks(); if (amatch("char", 4)) declloc(CCHAR, stclass); else if (amatch("int", 3)) declloc(CINT, stclass); else if (stclass == LSTATIC || stclass == DEFAUTO) declloc(CINT, stclass); else return(0); ns(); return(1); } /* * non-declaration statement */ stst () { if (amatch ("if", 2)) { doif (); lastst = STIF; } else if (amatch ("while", 5)) { dowhile (); lastst = STWHILE; } else if (amatch ("switch", 6)) { doswitch (); lastst = STSWITCH; } else if (amatch ("do", 2)) { dodo (); ns (); lastst = STDO; } else if (amatch ("for", 3)) { dofor (); lastst = STFOR; } else if (amatch ("return", 6)) { doreturn (); ns (); lastst = STRETURN; } else if (amatch ("break", 5)) { dobreak (); ns (); lastst = STBREAK; } else if (amatch ("continue", 8)) { docont (); ns (); lastst = STCONT; } else if (match (";")) ; else if (amatch ("case", 4)) { docase (); lastst = statement (NO); } else if (amatch ("default", 7)) { dodefault (); lastst = statement (NO); } else if (match ("#asm")) { doasm (); lastst = STASM; } else if (match ("{")) compound (NO); else { expression (YES); /* if (match (":")) { dolabel (); lastst = statement (NO); } else { */ ns (); lastst = STEXP; /* } */ } } /* * compound statement * * allow any number of statements to fall between "{" and "}" * * 'func' is true if we are in a "function_statement", which * must contain "statement_list" */ compound (func) int func; { int decls; decls = YES; ncmp++; while (!match ("}")) { if (feof (input)) return; if (decls) { if (!stdecl ()) decls = NO; } else stst (); } ncmp--; } /* * "if" statement */ doif () { int fstkp, flab1, flab2; char *flev; flev = locptr; fstkp = stkp; flab1 = getlabel (); test (flab1, FALSE); statement (NO); stkp = modstk (fstkp); locptr = flev; if (!amatch ("else", 4)) { gnlabel (flab1); return; } jump (flab2 = getlabel ()); gnlabel (flab1); statement (NO); stkp = modstk (fstkp); locptr = flev; gnlabel (flab2); } /* * "while" statement */ dowhile () { int ws[7]; ws[WSSYM] = locptr; ws[WSSP] = stkp; ws[WSTYP] = WSWHILE; ws[WSTEST] = getlabel (); ws[WSEXIT] = getlabel (); addwhile (ws); gnlabel (ws[WSTEST]); test (ws[WSEXIT], FALSE); statement (NO); jump (ws[WSTEST]); gnlabel (ws[WSEXIT]); locptr = ws[WSSYM]; stkp = modstk (ws[WSSP]); delwhile (); } /* * "do" statement */ dodo () { int ws[7]; ws[WSSYM] = locptr; ws[WSSP] = stkp; ws[WSTYP] = WSDO; ws[WSBODY] = getlabel (); ws[WSTEST] = getlabel (); ws[WSEXIT] = getlabel (); addwhile (ws); gnlabel (ws[WSBODY]); statement (NO); if (!match ("while")) { error ("missing while"); return; } gnlabel (ws[WSTEST]); test (ws[WSBODY], TRUE); gnlabel (ws[WSEXIT]); locptr = ws[WSSYM]; stkp = modstk (ws[WSSP]); delwhile (); } /* * "for" statement */ dofor () { int ws[7], *pws; ws[WSSYM] = locptr; ws[WSSP] = stkp; ws[WSTYP] = WSFOR; ws[WSTEST] = getlabel (); ws[WSINCR] = getlabel (); ws[WSBODY] = getlabel (); ws[WSEXIT] = getlabel (); addwhile (ws); pws = readwhile (); needbrack ("("); if (!match (";")) { expression (YES); ns (); } gnlabel (pws[WSTEST]); if (!match (";")) { expression (YES); testjump (pws[WSBODY], TRUE); jump (pws[WSEXIT]); ns (); } else pws[WSTEST] = pws[WSBODY]; gnlabel (pws[WSINCR]); if (!match (")")) { expression (YES); needbrack (")"); jump (pws[WSTEST]); } else pws[WSINCR] = pws[WSTEST]; gnlabel (pws[WSBODY]); statement (NO); jump (pws[WSINCR]); gnlabel (pws[WSEXIT]); locptr = pws[WSSYM]; stkp = modstk (pws[WSSP]); delwhile (); } /* * "switch" statement */ doswitch () { int ws[7]; int *ptr; ws[WSSYM] = locptr; ws[WSSP] = stkp; ws[WSTYP] = WSSWITCH; ws[WSCASEP] = swstp; ws[WSTAB] = getlabel (); ws[WSDEF] = ws[WSEXIT] = getlabel (); addwhile (ws); immed (); printlabel (ws[WSTAB]); nl (); gpush (); needbrack ("("); expression (YES); needbrack (")"); stkp = stkp + intsize(); /* '?case' will adjust the stack */ gjcase (); statement (NO); ptr = readswitch (); jump (ptr[WSEXIT]); dumpsw (ptr); gnlabel (ptr[WSEXIT]); locptr = ptr[WSSYM]; stkp = modstk (ptr[WSSP]); swstp = ptr[WSCASEP]; delwhile (); } /* * "case" label */ docase () { int val; val = 0; if (readswitch ()) { if (!number (&val)) if (!pstr (&val)) error ("bad case label"); addcase (val); if (!match (":")) error ("missing colon"); } else error ("no active switch"); } /* * "default" label */ dodefault () { int *ptr, lab; if (ptr = readswitch ()) { ptr[WSDEF] = lab = getlabel (); gnlabel (lab); if (!match (":")) error ("missing colon"); } else error ("no active switch"); } /* * "return" statement */ doreturn () { if (endst () == 0) expression (YES); jump(fexitlab); } /* * "break" statement */ dobreak () { int *ptr; if ((ptr = readwhile ()) == 0) return; modstk (ptr[WSSP]); jump (ptr[WSEXIT]); } /* * "continue" statement */ docont () { int *ptr; if ((ptr = findwhile ()) == 0) return; modstk (ptr[WSSP]); if (ptr[WSTYP] == WSFOR) jump (ptr[WSINCR]); else jump (ptr[WSTEST]); } /* * dump switch table */ dumpsw (ws) int ws[]; { int i,j; gdata (); gnlabel (ws[WSTAB]); if (ws[WSCASEP] != swstp) { j = ws[WSCASEP]; while (j < swstp) { defword (); i = 4; while (i--) { onum (swstcase[j]); outbyte (','); printlabel (swstlab[j++]); if ((i == 0) | (j >= swstp)) { nl (); break; } outbyte (','); } } } defword (); printlabel (ws[WSDEF]); outstr (",0"); nl (); gtext (); } SHAR_EOF if test 6668 -ne "`wc -c < 'stmt.c'`" then echo shar: error transmitting "'stmt.c'" '(should have been 6668 characters)' fi fi echo shar: extracting "'sym.c'" '(3849 characters)' if test -f 'sym.c' then echo shar: will not over-write existing file "'sym.c'" else cat << \SHAR_EOF > 'sym.c' /* File sym.c: 2.1 (83/03/20,16:02:19) */ /*% cc -O -c % * */ #include <stdio.h> #include "defs.h" #include "data.h" /* * declare a static variable */ declglb (typ, stor) int typ, stor; { int k, j; char sname[NAMESIZE]; FOREVER { FOREVER { if (endst ()) return; k = 1; if (match ("*")) j = POINTER; else j = VARIABLE; if (!symname (sname)) illname (); if (findglb (sname)) multidef (sname); if (match ("[")) { k = needsub (); if (k || stor == EXTERN) j = ARRAY; else j = POINTER; } addglb (sname, j, typ, k, stor); break; } if (!match (",")) return; } } /* * declare local variables * * works just like "declglb", but modifies machine stack and adds * symbol table entry with appropriate stack offset to find it again */ declloc (typ, stclass) int typ, stclass; { int k, j; char sname[NAMESIZE]; FOREVER { FOREVER { if (endst ()) return; if (match ("*")) j = POINTER; else j = VARIABLE; if (!symname (sname)) illname (); if (findloc (sname)) multidef (sname); if (match ("[")) { k = needsub (); if (k) { j = ARRAY; if (typ == CINT) k = k * intsize(); } else { j = POINTER; k = intsize(); } } else if ((typ == CCHAR) & (j != POINTER)) k = 1; else k = intsize(); if (stclass != LSTATIC) { k = galign(k); stkp = modstk (stkp - k); addloc (sname, j, typ, stkp, AUTO); } else addloc( sname, j, typ, k, LSTATIC); break; } if (!match (",")) return; } } /* * get required array size */ needsub () { int num[1]; if (match ("]")) return (0); if (!number (num)) { error ("must be constant"); num[0] = 1; } if (num[0] < 0) { error ("negative size illegal"); num[0] = (-num[0]); } needbrack ("]"); return (num[0]); } findglb (sname) char *sname; { char *ptr; ptr = STARTGLB; while (ptr != glbptr) { if (astreq (sname, ptr, NAMEMAX)) return (ptr); ptr = ptr + SYMSIZ; } return (0); } findloc (sname) char *sname; { char *ptr; ptr = locptr; while (ptr != STARTLOC) { ptr = ptr - SYMSIZ; if (astreq (sname, ptr, NAMEMAX)) return (ptr); } return (0); } addglb (sname, id, typ, value, stor) char *sname, id, typ; int value, stor; { char *ptr; if (cptr = findglb (sname)) return (cptr); if (glbptr >= ENDGLB) { error ("global symbol table overflow"); return (0); } cptr = ptr = glbptr; while (an (*ptr++ = *sname++)); cptr[IDENT] = id; cptr[TYPE] = typ; cptr[STORAGE] = stor; cptr[OFFSET] = value & 0xff; cptr[OFFSET+1] = (value >> 8) & 0xff; glbptr = glbptr + SYMSIZ; return (cptr); } addloc (sname, id, typ, value, stclass) char *sname, id, typ; int value, stclass; { char *ptr; int k; if (cptr = findloc (sname)) return (cptr); if (locptr >= ENDLOC) { error ("local symbol table overflow"); return (0); } cptr = ptr = locptr; while (an (*ptr++ = *sname++)); cptr[IDENT] = id; cptr[TYPE] = typ; cptr[STORAGE] = stclass; if (stclass == LSTATIC) { gdata(); printlabel(k = getlabel()); col(); defstorage(); onum(value); nl(); gtext(); value = k; } else value = galign(value); cptr[OFFSET] = value & 0xff; cptr[OFFSET+1] = (value >> 8) & 0xff; locptr = locptr + SYMSIZ; return (cptr); } /* * test if next input string is legal symbol name * */ symname (sname) char *sname; { int k; char c; blanks (); if (!alpha (ch ())) return (0); k = 0; while (an (ch ())) sname[k++] = gch (); sname[k] = 0; return (1); } illname () { error ("illegal symbol name"); } multidef (sname) char *sname; { error ("already defined"); comment (); outstr (sname); nl (); } glint(syment) char *syment; { int l,u,r; l = syment[OFFSET]; u = syment[OFFSET+1]; r = (l & 0xff) + ((u << 8) & ~0x00ff); return (r); } SHAR_EOF if test 3849 -ne "`wc -c < 'sym.c'`" then echo shar: error transmitting "'sym.c'" '(should have been 3849 characters)' fi fi echo shar: extracting "'while.c'" '(980 characters)' if test -f 'while.c' then echo shar: will not over-write existing file "'while.c'" else cat << \SHAR_EOF > 'while.c' /* File while.c: 2.1 (83/03/20,16:02:22) */ /*% cc -O -c % * */ #include <stdio.h> #include "defs.h" #include "data.h" addwhile (ptr) int ptr[]; { int k; if (wsptr == WSMAX) { error ("too many active whiles"); return; } k = 0; while (k < WSSIZ) *wsptr++ = ptr[k++]; } delwhile () { if (readwhile ()) wsptr = wsptr - WSSIZ; } readwhile () { if (wsptr == ws) { error ("no active do/for/while/switch"); return (0); } else return (wsptr-WSSIZ); } findwhile () { int *ptr; for (ptr = wsptr; ptr != ws;) { ptr = ptr - WSSIZ; if (ptr[WSTYP] != WSSWITCH) return (ptr); } error ("no active do/for/while"); return (0); } readswitch () { int *ptr; if (ptr = readwhile ()) if (ptr[WSTYP] == WSSWITCH) return (ptr); return (0); } addcase (val) int val; { int lab; if (swstp == SWSTSZ) error ("too many case labels"); else { swstcase[swstp] = val; swstlab[swstp++] = lab = getlabel (); printlabel (lab); col (); nl (); } } SHAR_EOF if test 980 -ne "`wc -c < 'while.c'`" then echo shar: error transmitting "'while.c'" '(should have been 980 characters)' fi fi exit 0 # End of shell archive -------