(******************************************************************) (* *) (* Copyright (c) l978 Regents of the University of California. *) (* Permission to copy or distribute this software or documen- *) (* tation in hard or soft copy granted only by written license *) (* obtained from the Institute for Information Systems. *) (* *) (******************************************************************) PROCEDURE ERROR(*ERRORNUM: INTEGER*); VAR CH: CHAR; ERRSTART: INTEGER; A: PACKED ARRAY [0..179] OF CHAR; BEGIN WITH USERINFO DO IF (ERRSYM <> SYMCURSOR) OR (ERRBLK <> SYMBLK) THEN BEGIN ERRBLK := SYMBLK; ERRSYM := SYMCURSOR; ERRNUM := ERRORNUM; IF STUPID THEN CH := 'E' ELSE BEGIN IF NOISY THEN WRITELN(OUTPUT) ELSE IF LIST AND (ERRORNUM <= 400) THEN EXIT(ERROR); IF LINESTART = 0 THEN WRITE(OUTPUT,SYMBUFP^:SYMCURSOR) ELSE BEGIN ERRSTART := SCAN(-(LINESTART-1),=CHR(EOL), SYMBUFP^[LINESTART-2])+LINESTART-1; MOVELEFT(SYMBUFP^[ERRSTART],A[0],SYMCURSOR-ERRSTART); WRITE(OUTPUT,A:SYMCURSOR-ERRSTART) END; WRITELN(OUTPUT,' <<<<'); WRITE(OUTPUT,'Line ',SCREENDOTS,', error ',ERRORNUM:0,':'); IF NOISY THEN WRITE(OUTPUT,' (continue), (terminate), E(dit'); WRITE(OUTPUT,CHR(7)); REPEAT READ(KEYBOARD,CH) UNTIL (CH = ' ') OR (CH = 'E') OR (CH = 'e') OR (CH = ALTMODE) END; IF (CH = 'E') OR (CH = 'e') THEN BEGIN ERRBLK := SYMBLK-2; EXIT(PASCALCOMPILER) END; IF (ERRORNUM > 400) OR (CH = CHR(27)) THEN BEGIN ERRBLK := 0; EXIT(PASCALCOMPILER) END; WRITELN(OUTPUT); IF NOISY THEN WRITE(OUTPUT,'<',SCREENDOTS:4,'>') END END (*ERROR*) ; PROCEDURE GETNEXTPAGE; BEGIN SYMCURSOR := 0; LINESTART := 0; IF USING THEN BEGIN IF USEFILE = WORKCODE THEN BEGIN IF BLOCKREAD(USERINFO.WORKCODE^,SYMBUFP^,2,SYMBLK) <> 2 THEN USING := FALSE END ELSE IF USEFILE = SYSLIBRARY THEN IF BLOCKREAD(LIBRARY,SYMBUFP^,2,SYMBLK) <> 2 THEN USING := FALSE; IF NOT USING THEN BEGIN SYMBLK := PREVSYMBLK; SYMCURSOR := PREVSYMCURSOR; LINESTART := PREVLINESTART END END; IF NOT USING THEN BEGIN IF INCLUDING THEN IF BLOCKREAD(INCLFILE,SYMBUFP^,2,SYMBLK) <> 2 THEN BEGIN CLOSE(INCLFILE); INCLUDING := FALSE; SYMBLK := OLDSYMBLK; SYMCURSOR := OLDSYMCURSOR; LINESTART := OLDLINESTART END END; IF NOT (INCLUDING OR USING) THEN IF BLOCKREAD(USERINFO.WORKSYM^,SYMBUFP^,2,SYMBLK) <> 2 THEN ERROR(401); IF SYMCURSOR = 0 THEN BEGIN IF INMODULE THEN IF ININTERFACE AND NOT USING THEN WRITETEXT; IF SYMBUFP^[0] = CHR(16(*DLE*)) THEN SYMCURSOR := 2 END; SYMBLK := SYMBLK+2 END (*GETNEXTPAGE*) ; (*$I+*) PROCEDURE PRINTLINE; VAR DORLEV,STARORC: CHAR; LENG: INTEGER; A: PACKED ARRAY [0..99] OF CHAR; BEGIN STARORC := ':'; IF DP THEN DORLEV := 'D' ELSE DORLEV := CHR((BEGSTMTLEV MOD 10) + ORD('0')); IF BPTONLINE THEN STARORC := '*'; WRITE(LP,SCREENDOTS:6,SEG:4,CURPROC:5, STARORC,DORLEV,LINEINFO:6,' '); LENG := SYMCURSOR-LINESTART; IF LENG > 100 THEN LENG := 100; MOVELEFT(SYMBUFP^[LINESTART],A,LENG); IF A[0] = CHR(16(*DLE*)) THEN BEGIN IF A[1] > ' ' THEN WRITE(LP,' ':ORD(A[1])-ORD(' ')); LENG := LENG-2; MOVELEFT(A[2],A,LENG) END; A[LENG-1] := CHR(EOL); (*JUST TO MAKE SURE*) WRITE(LP,A:LENG); WITH USERINFO DO IF (ERRBLK = SYMBLK) AND (ERRSYM > LINESTART) THEN WRITELN(LP,'>>>>>> Error # ',ERRNUM) END (*PRINTLINE*) ; (*$I-*) PROCEDURE ENTERID(*FCP: CTP*); VAR LCP,LCP1: CTP; I: INTEGER; BEGIN LCP := DISPLAY[TOP].FNAME; IF LCP = NIL THEN DISPLAY[TOP].FNAME := FCP ELSE BEGIN I := TREESEARCH(LCP,LCP1,FCP^.NAME); WHILE I = 0 DO BEGIN ERROR(101); IF LCP1^.RLINK = NIL THEN I := 1 ELSE I := TREESEARCH(LCP1^.RLINK,LCP1,FCP^.NAME) END; IF I = 1 THEN LCP1^.RLINK := FCP ELSE LCP1^.LLINK := FCP END; FCP^.LLINK := NIL; FCP^.RLINK := NIL END (*ENTERID*) ; PROCEDURE INSYMBOL; (* COMPILER VERSION 3.4 06-NOV-76 *) LABEL 1; VAR LVP: CSP; X: INTEGER; PROCEDURE CHECKEND; BEGIN (* CHECKS FOR THE END OF THE PAGE *) SCREENDOTS := SCREENDOTS+1; SYMCURSOR := SYMCURSOR + 1; IF NOISY THEN BEGIN WRITE(OUTPUT,'.'); IF (SCREENDOTS-STARTDOTS) MOD 50 = 0 THEN BEGIN WRITELN(OUTPUT); WRITE(OUTPUT,'<',SCREENDOTS:4,'>') END END; IF LIST THEN PRINTLINE; BPTONLINE := FALSE; IF SYMBUFP^[SYMCURSOR]=CHR(0) THEN GETNEXTPAGE ELSE LINESTART := SYMCURSOR; IF SYMBUFP^[SYMCURSOR] = CHR(12(*FF*)) THEN SYMCURSOR:=SYMCURSOR+1; IF SYMBUFP^[SYMCURSOR] = CHR(16(*DLE*)) THEN SYMCURSOR := SYMCURSOR+2 ELSE BEGIN SYMCURSOR := SYMCURSOR+SCAN(80,<>CHR(9),SYMBUFP^[SYMCURSOR]); SYMCURSOR := SYMCURSOR+SCAN(80,<>' ',SYMBUFP^[SYMCURSOR]) END; IF DP THEN LINEINFO := LC ELSE LINEINFO := IC END; PROCEDURE COMMENTER(STOPPER: CHAR); VAR CH,SW,DEL: CHAR; LTITLE: STRING[40]; PROCEDURE SCANSTRING(VAR STRG: STRING; MAXLENG: INTEGER); VAR LENG: INTEGER; BEGIN SYMCURSOR := SYMCURSOR+2; LENG := SCAN(MAXLENG,=STOPPER,SYMBUFP^[SYMCURSOR]); STRG[0] := CHR(LENG); MOVELEFT(SYMBUFP^[SYMCURSOR],STRG[1],LENG); SYMCURSOR := SYMCURSOR+LENG+1 END (*SCANSTRING*) ; BEGIN SYMCURSOR := SYMCURSOR+1; (* POINT TO THE FIRST CH PAST "(*" *) IF SYMBUFP^[SYMCURSOR]='$' THEN IF SYMBUFP^[SYMCURSOR+1] <> STOPPER THEN REPEAT CH := SYMBUFP^[SYMCURSOR+1]; SW := SYMBUFP^[SYMCURSOR+2]; DEL := SYMBUFP^[SYMCURSOR+3]; IF (SW = ',') OR (SW = STOPPER) THEN BEGIN DEL := SW; SW := '+'; SYMCURSOR := SYMCURSOR-1 END; CASE CH OF 'C': BEGIN IF LEVEL > 1 THEN ERROR(194); NEW(COMMENT); SCANSTRING(COMMENT^,80); EXIT(COMMENTER) END; 'D': DEBUGGING := (SW='+'); 'G': GOTOOK := (SW='+'); 'I': IF (SW='+') OR (SW='-') THEN IOCHECK := (SW='+') ELSE BEGIN SCANSTRING(LTITLE,40); IF STOPPER = '*' THEN SYMCURSOR := SYMCURSOR+1; IF LIST THEN BEGIN SYMCURSOR := SYMCURSOR + 1; PRINTLINE; SYMCURSOR := SYMCURSOR - 1; END; IF INCLUDING OR INMODULE AND ININTERFACE THEN BEGIN ERROR(406); EXIT(COMMENTER) END; OPENOLD(INCLFILE,LTITLE); IF IORESULT <> 0 THEN BEGIN OPENOLD(INCLFILE,CONCAT(LTITLE,'.TEXT')); IF IORESULT <> 0 THEN ERROR(403) END; INCLUDING := TRUE; OLDSYMCURSOR := SYMCURSOR; OLDLINESTART := LINESTART; OLDSYMBLK := SYMBLK-2; SYMBLK := 2; GETNEXTPAGE; INSYMBOL; EXIT(INSYMBOL) END; 'L': IF (SW='+') OR (SW='-') THEN BEGIN LIST := (SW='+'); IF LIST THEN OPENNEW(LP,'*SYSTEM.LST.TEXT') END ELSE BEGIN SCANSTRING(LTITLE,40); OPENNEW(LP,LTITLE); LIST := IORESULT = 0; EXIT(COMMENTER) END; 'Q': NOISY := (SW='-'); 'P': WRITE(LP,CHR(12(*FF*))); 'R': RANGECHECK := (SW='+'); 'S': NOSWAP:=(SW='-'); 'T': TINY := (SW='+'); 'U': IF (SW='+') OR (SW='-') THEN BEGIN SYSCOMP := (SW = '-'); RANGECHECK := NOT SYSCOMP; IOCHECK := RANGECHECK; GOTOOK := SYSCOMP END ELSE IF NOT USING THEN BEGIN SCANSTRING(SYSTEMLIB,40); CLOSE(LIBRARY); LIBNOTOPEN := TRUE; EXIT(COMMENTER) END END (*CASES*); SYMCURSOR := SYMCURSOR+3; UNTIL DEL <> ','; SYMCURSOR := SYMCURSOR-1; (* ADJUST *) REPEAT REPEAT SYMCURSOR := SYMCURSOR+1; WHILE SYMBUFP^[SYMCURSOR] = CHR(EOL) DO CHECKEND UNTIL SYMBUFP^[SYMCURSOR]=STOPPER; UNTIL (SYMBUFP^[SYMCURSOR+1]=')') OR (STOPPER='}'); SYMCURSOR := SYMCURSOR+1; END (*COMMENTER*); PROCEDURE STRING; LABEL 1; VAR T: PACKED ARRAY [1..80] OF CHAR; TP,NBLANKS,L: INTEGER; DUPLE: BOOLEAN; BEGIN DUPLE := FALSE; (* INDICATES WHEN '' IS PRESENT *) TP := 0; (* INDEX INTO TEMPORARY STRING *) REPEAT IF DUPLE THEN SYMCURSOR := SYMCURSOR+1; REPEAT SYMCURSOR := SYMCURSOR+1; TP := TP+1; IF SYMBUFP^[SYMCURSOR] = CHR(EOL) THEN BEGIN ERROR(202); CHECKEND; GOTO 1 END; T[TP] := SYMBUFP^[SYMCURSOR]; UNTIL SYMBUFP^[SYMCURSOR]=''''; DUPLE := TRUE; UNTIL SYMBUFP^[SYMCURSOR+1]<>''''; 1: TP := TP-1; (* ADJUST *) SY := STRINGCONST; OP := NOOP; LGTH := TP; (* GROSS *) IF TP=1 (* SINGLE CHARACTER CONSTANT *) THEN VAL.IVAL := ORD(T[1]) ELSE WITH SCONST^ DO BEGIN CCLASS := STRG; SLGTH := TP; MOVELEFT(T[1],SVAL[1],TP); VAL.VALP := SCONST END END(*STRING*); PROCEDURE NUMBER; VAR EXPONENT,ENDI,ENDF,ENDE,SIGN,IPART,FPART,EPART, ISUM: INTEGER; TIPE: (REALTIPE,INTEGERTIPE); RSUM: REAL; NOTLONG: BOOLEAN; K,J: INTEGER; BEGIN (* TAKES A NUMBER AND DECIDES WHETHER IT'S REAL OR INTEGER AND CONVERTS IT TO THE INTERNAL FORM. *) TIPE := INTEGERTIPE; ENDI := 0; ENDF := 0; ENDE := 0; SIGN := 1; NOTLONG := TRUE; EPART := 9999; (* OUT OF REACH *) IPART := SYMCURSOR; (* INTEGER PART STARTS HERE *) REPEAT SYMCURSOR := SYMCURSOR+1 UNTIL (SYMBUFP^[SYMCURSOR]<'0') OR (SYMBUFP^[SYMCURSOR]>'9'); (* SYMCURSOR NOW POINTS AT FIRST CHARACTER PAST INTEGER PART *) ENDI := SYMCURSOR-1; (* MARK THE END OF IPART *) IF SYMBUFP^[SYMCURSOR]='.' THEN IF SYMBUFP^[SYMCURSOR+1]<>'.' (* WATCH OUT FOR '..' *) THEN BEGIN TIPE := REALTIPE; SYMCURSOR := SYMCURSOR+1; FPART := SYMCURSOR; (* BEGINNING OF FPART *) WHILE (SYMBUFP^[SYMCURSOR] >= '0') AND (SYMBUFP^[SYMCURSOR] <= '9') DO SYMCURSOR := SYMCURSOR+1; IF SYMCURSOR = FPART THEN ERROR(201); ENDF := SYMCURSOR-1; END; IF SYMBUFP^[SYMCURSOR]='E' THEN BEGIN TIPE := REALTIPE; SYMCURSOR := SYMCURSOR+1; IF SYMBUFP^[SYMCURSOR]='-' THEN BEGIN SYMCURSOR := SYMCURSOR+1; SIGN := -1; END ELSE IF SYMBUFP^[SYMCURSOR]='+' THEN SYMCURSOR := SYMCURSOR+1; EPART := SYMCURSOR; (* BEGINNING OF EXPONENT *) WHILE (SYMBUFP^[SYMCURSOR]>='0') AND (SYMBUFP^[SYMCURSOR]<='9') DO SYMCURSOR := SYMCURSOR+1; ENDE := SYMCURSOR-1; IF ENDEMAXINT DIV 10) OR ((ISUM=MAXINT DIV 10) AND (ORD(SYMBUFP^[J]) - ORD('0') > MAXINT MOD 10)) THEN BEGIN NOTLONG := FALSE; K := J; J := ENDI END ELSE ISUM := ISUM*10+(ORD(SYMBUFP^[J])-ORD('0')); END; IF NOTLONG THEN BEGIN SY := INTCONST; OP := NOOP; VAL.IVAL := ISUM; END ELSE BEGIN IF ENDI - IPART >= MAXDEC THEN BEGIN ERROR(203); IPART := ENDI; K := ENDI END; NEW(LVP,LONG); WITH LVP^ DO BEGIN CCLASS := LONG; J := 4; LLENG := 0; WHILE K <= ENDI DO BEGIN IF J = 4 THEN BEGIN LLENG := LLENG + 1; LONGVAL[LLENG] := ISUM; ISUM := 0; J := 0 END; ISUM := ISUM * 10 + ORD(SYMBUFP^[K])-ORD('0'); K := K + 1; J := J + 1 END; LLAST := J; IF J > 0 THEN BEGIN LLENG := LLENG + 1; LONGVAL[LLENG] := ISUM END; END; SY := LONGCONST; OP := NOOP; LGTH := ENDI - IPART + 1; VAL.VALP := LVP END; END (*TIPE = INTEGERTIPE*) ELSE BEGIN (* REAL NUMBER HERE *) RSUM := 0; FOR J := IPART TO ENDI DO BEGIN RSUM := RSUM*10+(ORD(SYMBUFP^[J])-ORD('0')); END; FOR J := ENDF DOWNTO FPART DO RSUM := RSUM+(ORD(SYMBUFP^[J])-ORD('0'))/PWROFTEN(J-FPART+1); EXPONENT := 0; FOR J := EPART TO ENDE DO EXPONENT := EXPONENT*10+ORD(SYMBUFP^[J])-ORD('0'); IF SIGN=-1 THEN RSUM := RSUM/PWROFTEN(EXPONENT) ELSE RSUM := RSUM*PWROFTEN(EXPONENT); SY := REALCONST; OP := NOOP; NEW(LVP,REEL); LVP^.CCLASS := REEL; LVP^.RVAL := RSUM; VAL.VALP := LVP; END; SYMCURSOR := SYMCURSOR-1; (* ADJUST FOR POSTERITY *) END (*NUMBER*) ; BEGIN (* INSYMBOL *) IF GETSTMTLEV THEN BEGIN BEGSTMTLEV := STMTLEV; GETSTMTLEV := FALSE END; OP := NOOP; 1: SY := OTHERSY; (* IF NO CASES EXERCISED BLOW UP *) CASE SYMBUFP^[SYMCURSOR] OF '''':STRING; '0','1','2','3','4','5','6','7','8','9': NUMBER; 'A','B','C','D','E','F','G','H','I','J','K','L','M', 'N','O','P','Q','R','S','T','U','V','W','X','Y','Z', 'a','b','c','d','e','f','g','h','i','j','k','l','m', 'n','o','p','q','r','s','t','u','v','w','x','y','z': IDSEARCH(SYMCURSOR,SYMBUFP^); (* MAGIC PROC *) '{': BEGIN COMMENTER('}'); GOTO 1 END; '(': BEGIN IF SYMBUFP^[SYMCURSOR+1]='*' THEN BEGIN SYMCURSOR := SYMCURSOR+1; COMMENTER('*'); SYMCURSOR := SYMCURSOR+1; GOTO 1; (* GET ANOTHER TOKEN *) END ELSE SY := LPARENT; END; ')': SY := RPARENT; ',': SY := COMMA; ' ',' ': BEGIN SYMCURSOR := SYMCURSOR+1; GOTO 1; END; '.': BEGIN IF SYMBUFP^[SYMCURSOR+1]='.' THEN BEGIN SYMCURSOR := SYMCURSOR+1; SY := COLON END ELSE SY := PERIOD; END; ':': IF SYMBUFP^[SYMCURSOR+1]='=' THEN BEGIN SYMCURSOR := SYMCURSOR+1; SY := BECOMES; END ELSE SY := COLON; ';': SY := SEMICOLON; '^': SY := ARROW; '[': SY := LBRACK; ']': SY := RBRACK; '*': BEGIN SY := MULOP; OP := MUL END; '+': BEGIN SY := ADDOP; OP := PLUS END; '-': BEGIN SY := ADDOP; OP := MINUS END; '/': BEGIN SY := MULOP; OP := RDIV END; '<': BEGIN SY := RELOP; OP := LTOP; CASE SYMBUFP^[SYMCURSOR+1] OF '>': BEGIN OP := NEOP; SYMCURSOR := SYMCURSOR+1 END; '=': BEGIN OP := LEOP; SYMCURSOR := SYMCURSOR+1 END END; END; '=': BEGIN SY := RELOP; OP := EQOP END; '>': BEGIN SY := RELOP; IF SYMBUFP^[SYMCURSOR+1]='=' THEN BEGIN OP := GEOP; SYMCURSOR := SYMCURSOR+1; END ELSE OP := GTOP; END END (* CASE SYMBUFP^[SYMCURSOR] OF *); IF SY=OTHERSY THEN IF SYMBUFP^[SYMCURSOR] = CHR(EOL) THEN BEGIN CHECKEND; GETSTMTLEV := TRUE; GOTO 1 END ELSE ERROR(400); SYMCURSOR := SYMCURSOR+1; (* NEXT CALL TALKS ABOUT NEXT TOKEN *) END (*INSYMBOL*) ;