GET "SY:BCPLIB" MANIFEST $( TREEMAX=6000 $) STATIC $( REPORTCOUNT=0 BCPL=0 OCODE=0 LIST=0 LINE=0 LINEP=0 LINELENGTH=0 LINECOUNT=0 DATASET=0 CSIBLOCK=0 GETCSI=0 DEFAULTERROR=0 ENDC.P=0 ENDC.L=0 OUTPUTTING=0 INPUTOPEN=0 LISTBCPL=0 $) GLOBAL $( //OPTIONS PRINTINGNAMES=61 PRINTINGTREE=60 LISTGET=62 // GETTING:70 PERFORMGET:71 CONSOLE:72 REPORTERROR:73 REPORTMAX:74 RCH:75 CH:76 MARKERROR:77 FORMTREE:78 PRINTTREE:79 PRINTNAMES:80 COMPILEAE:81 LISTING:82 $) LET MOREINPUT() = VALOF $( IF INPUTOPEN $( CLOSE(INPUT); INPUTOPEN := FALSE $) UNLESS GETTING $( ERROR := SWERR DATASET := PARSEINPUT(CSIBLOCK,0) ERROR := DEFAULTERROR IF DATASET = 0 RESULTIS FALSE ERROR := IOPERR BCPL := OPENINPUT(DATASET,IDFNB(),120) ERROR := DEFAULTERROR $) INPUT := BCPL INPUTOPEN := TRUE GETTING := FALSE LISTING := LISTBCPL RESULTIS TRUE $) AND RDLINE() BE $( READREC(INPUT,LINE) TEST ENDOFFILE(INPUT) THEN TEST MOREINPUT() THEN RDLINE() OR ENDJOB(0) OR $( LINELENGTH := LINE%0 IF LISTING $( IF LINECOUNT REM 60 = 0 WRITES("*P*N") LINECOUNT := LINECOUNT+1 WRITED(LINECOUNT,3) WRITES(" ") WRITES(LINE) NEWLINE() $) UNPACKSTRING(LINE, LINE) LINEP := 1 $) $) AND RCH() BE $( IF LINEP=0 RDLINE() TEST LINEP>LINELENGTH THEN $( CH := '*N'; LINEP := 0 $) OR $( CH := LINE%LINEP; LINEP := LINEP+1 $) $) AND MARKERROR() BE $( TEST LISTING THEN FOR I=1 TO 5 WRITEC('*S') OR $( FOR I=1 TO LINELENGTH WRITEC(LINE%I) NEWLINE() $) FOR I=2 TO LINEP WRITEC('*S') WRITES("^*N") $) AND PERFORMGET(S) BE $( ERROR := GETERR GETCSI := ANALYZE(S) DATASET := PARSEOUTPUT(GETCSI,0) INPUT := OPENINPUT(DATASET,GDFNB(),120) UNHEAP(GETCSI) GETTING := TRUE IF LISTING LISTING := LISTGET LISTGET := FALSE ERROR := DEFAULTERROR RDLINE() RCH() $) AND DUMMY() BE $( CODE " .MCALL NMBLK$" CODE "IDFN: NMBLK$ INPUT,BCL" CODE "ODFN: NMBLK$ OUTPUT,OCO" CODE "LDFN: NMBLK$ OUTPUT,LST" CODE "GDFN: NMBLK$ BCPLIB,GET" CODE " .MCALL CSI$SW,CSI$ND" CODE "SWTB: CSI$SW TR,-1,GV+120." CODE " CSI$SW NA,-1,GV+122." CODE " CSI$SW GE,-1,GV+124." CODE " CSI$ND" $) AND IDFNB() BE CODE " MOV #IDFN/2,R0" AND ODFNB() BE CODE " MOV #ODFN/2,R0" AND LDFNB() BE CODE " MOV #LDFN/2,R0" AND GDFNB() BE CODE " MOV #GDFN/2,R0" AND SWITCH() BE CODE " MOV #SWTB/2,R0" AND CMLERR() BE $( WRITES("COMMAND LINE ERROR*N") ENDWRITE(CONSOLE) FINISH $) AND SYNERR() BE ENDJOB("SYNTAX ERROR") AND SWERR() BE ENDJOB("ILLEGAL SWITCH") AND OOPERR() BE ENDJOB("OPEN FAIL ON OUTPUT FILE") AND LOPERR() BE ENDJOB("OPEN FAIL ON LIST FILE") AND IOPERR() BE ENDJOB("OPEN FAIL ON INPUT FILE") AND GETERR() BE $( UNHEAP(GETCSI) ENDJOB("FAILURE IN 'GET'") $) AND REPORTERROR(S,M) BE $( WRITES(S) WRITES(M) NEWLINE() REPORTCOUNT := REPORTCOUNT+1 IF REPORTCOUNT GE REPORTMAX ENDJOB(0) $) AND ENDJOB(S) BE $( OUTPUT := CONSOLE TEST S=0 THEN IF REPORTCOUNT>0 $( WRITES("COMPILATION ") WRITES(REPORTCOUNT GE REPORTMAX -> "ABORTED", "FAILED") WRITES(" - ") WRITEN(REPORTCOUNT) WRITES(" ERROR") UNLESS REPORTCOUNT=1 WRITEC('S') NEWLINE() $) OR $( WRITES("BCPL -- "); WRITES(S); NEWLINE() $) LONGJUMP(ENDC.P, ENDC.L) $) START: $(S LET OB = VEC 120 LET LB = VEC 120 LET IB = VEC 120 LET CB = VEC 41 LET OS = VEC STREAMSIZE LET TS = VEC STREAMSIZE LET T = VEC TREEMAX LET COMMAND = 0 LINE := IB OCODE := OS OCODE%BUFFER := OB OCODE%ENDOF := ENDOFFILE OCODE%TRANSFER := WRITEREC LIST := TS LIST%BUFFER := LB LIST%ENDOF := ENDOFFILE LIST%TRANSFER := WRITEREC INITIALIZEIO() CONSOLE := CREATEOUTPUT("TI:") ENDC.P, ENDC.L := LEVEL(), ENDC DEFAULTERROR := ERROR NEXT: OUTPUT := CONSOLE REPORTCOUNT, REPORTMAX := 0, 6 LISTING, OUTPUTTING := FALSE, FALSE GETTING, INPUTOPEN := FALSE, FALSE PRINTINGNAMES, PRINTINGTREE := FALSE, FALSE LISTGET, LISTBCPL := FALSE, FALSE ERROR := CMLERR COMMAND := READCOMMAND("BCPL>", CB) IF COMMAND=0 GOTO EXIT ERROR := SYNERR CSIBLOCK := ANALYZE(COMMAND) UNLESS MOREINPUT() SYNERR() ERROR := SWERR DATASET := PARSEOUTPUT(CSIBLOCK,0) UNLESS DATASET=0 $( ERROR := OOPERR OCODE%FILE := OPENOUTPUT(DATASET,ODFNB(),120) OCODE%POINTER := 0 OUTPUTTING := TRUE $) ERROR := SWERR DATASET := PARSEOUTPUT(CSIBLOCK,SWITCH()) UNLESS DATASET=0 $( ERROR := LOPERR LIST%FILE := OPENOUTPUT(DATASET,LDFNB(),120) LIST%POINTER := 0 LISTBCPL := TRUE LISTING := TRUE $) ERROR := DEFAULTERROR $( LET A = 0 OUTPUT := LISTING -> LIST, CONSOLE LINECOUNT, LINEP := 0, 0 A := FORMTREE(T) IF PRINTINGTREE PRINTTREE(A) IF PRINTINGNAMES PRINTNAMES() OUTPUT := OCODE IF OUTPUTTING COMPILEAE(A) $) REPEAT ENDC: IF LISTBCPL CLOSE(LIST%FILE) IF OUTPUTTING CLOSE(OCODE%FILE) IF GETTING CLOSE(INPUT) IF INPUTOPEN CLOSE(BCPL) UNHEAP(CSIBLOCK) GOTO NEXT EXIT: ENDWRITE(CONSOLE) FINISH $)S . //\* /DGIM/TPP1 15.7 6/5 GET "SY:TSYN.GET" LET NEXTSYMB() BE $(1 NLPENDING := FALSE NEXT: SWITCHON CH INTO $( CASE '*P': CASE '*N': NLPENDING := TRUE // IGNORABLE CHARACTERS CASE '*T': CASE 0: CASE #15: // CARRIAGE RETURN CASE '*S': RCH() REPEATWHILE CH='*S' GOTO NEXT CASE '0':CASE '1':CASE '2':CASE '3':CASE '4': CASE '5':CASE '6':CASE '7':CASE '8':CASE '9': DECVAL := CH - '0' OCTVAL := DECVAL SYMB := S.NUMBER $( RCH() UNLESS '0' LE CH LE '9' RETURN DECVAL := DECVAL*10 + CH - '0' OCTVAL := (OCTVAL<<3) + CH - '0' $) REPEAT CASE 'A':CASE 'B':CASE 'C':CASE 'D':CASE 'E': CASE 'F':CASE 'G':CASE 'H':CASE 'I':CASE 'J': CASE 'K':CASE 'L':CASE 'M':CASE 'N':CASE 'O': CASE 'P':CASE 'Q':CASE 'R':CASE 'S':CASE 'T': CASE 'U':CASE 'V':CASE 'W':CASE 'X':CASE 'Y': CASE 'Z': CASE #141:CASE #142:CASE #143:CASE #144: CASE #145:CASE #146:CASE #147:CASE #150: CASE #151:CASE #152:CASE #153:CASE #154: CASE #155:CASE #156:CASE #157:CASE #160: CASE #161:CASE #162:CASE #163:CASE #164: CASE #165:CASE #166:CASE #167:CASE #170: CASE #171:CASE #172: RDTAG() SYMB := LOOKUPWORD() IF SYMB=S.GET DO $( NEXTSYMB() UNLESS SYMB=S.STRING $( REPORT(97); GOTO NEXT $) TEST GETTING THEN REPORT(93) OR PERFORMGET(WORDV) GOTO NEXT $) RETURN CASE '$': RCH() IF CH='8' DO $( SYMB := S.OCT; GOTO L $) IF CH='(' \/ CH=')' DO $( SYMB := CH='(' -> S.LSECT, S.RSECT CH := '$' RDTAG() LOOKUPWORD() RETURN $) REPORT(91) RCH() GOTO NEXT CASE #173: CASE #175: SYMB := CH=#173 -> S.LSECT, S.RSECT CH := '$' RDTAG() LOOKUPWORD() RETURN CASE '[': CASE '(': SYMB := S.LPAREN; GOTO L CASE ']': CASE ')': RCH() IF CH='.' DO $( RCH() REPEATUNTIL CH='(' \/ CH='[' SYMB := S.COMMA GOTO L $) SYMB := S.RPAREN RETURN CASE '#': SYMB := S.OCT; GOTO L CASE #176: SYMB := S.NOT; GOTO L CASE '+': SYMB := S.PLUS; GOTO L CASE ',': SYMB := S.COMMA; GOTO L CASE '!': SYMB := S.INFIX; GOTO L CASE '@': SYMB := S.LV; GOTO L CASE '&': SYMB := S.LOGAND; GOTO L CASE '=': SYMB := S.EQ; GOTO L CASE '|': CASE '%': SYMB := S.VECAP; GOTO L CASE '**': SYMB := S.MULT; GOTO L CASE ';': RCH() IF CH=';' DO $( SYMB := S.SEQ; GOTO L $) SYMB := S.SEMICOLON RETURN CASE '/': RCH() IF CH='\' DO $( SYMB := S.LOGAND; GOTO L $) IF CH='**' DO $( $( RCH() REPEATUNTIL CH='**' RCH(); IF CH='/' BREAK $) REPEAT RCH(); GOTO NEXT $) UNLESS CH='/' DO $( SYMB := S.DIV; RETURN $) RCH() REPEATUNTIL CH='*N' GOTO NEXT CASE '\': RCH() IF CH='/' DO $( SYMB := S.LOGOR; GOTO L $) IF CH='=' DO $( SYMB := S.NE; GOTO L $) SYMB := S.NOT RETURN CASE '<': RCH() IF CH='=' DO $( SYMB := S.LE; GOTO L $) IF CH='<' DO $( SYMB := S.LSHIFT; GOTO L $) IF CH='>' DO $( SYMB := S.SEQ; GOTO L $) SYMB := S.LS RETURN CASE '>': RCH() IF CH='=' DO $( SYMB := S.GE; GOTO L $) IF CH='>' DO $( SYMB := S.RSHIFT; GOTO L $) SYMB := S.GR RETURN CASE '-': RCH() IF CH='>' DO $( SYMB := S.COND; GOTO L $) SYMB := S.MINUS RETURN CASE ':': RCH() IF CH='=' DO $( SYMB := S.ASS; GOTO L $) SYMB := S.COLON RETURN CASE '*'':CASE '*"': $(1 LET QUOTE = CH LET LENGTH = 0 $( RCH() IF CH=QUOTE \/ LENGTH=255 DO $( UNLESS CH=QUOTE DO REPORT(95) TEST LENGTH=1 & CH='*'' THEN SYMB := S.CHAR OR $( WORDV%0 := LENGTH PACKSTRING(WORDV, WORDV) WORDLENGTH := (LENGTH+3)/2 SYMB := S.STRING $) GOTO L $) IF CH='**' DO $( RCH() CH := CH='N' -> 10, CH='S' -> 32, CH='T' -> 9, CH='P' -> 12, CH='E' -> 26, CH='C' -> 13, CH='L' -> 10, CH='^' -> VALOF $( RCH(); RESULTIS CH&31 $), CH $) DECVAL := CH LENGTH := LENGTH+1 WORDV%LENGTH := CH $) REPEAT $)1 CASE '.': SYMB := S.END RETURN DEFAULT: CH := '*S' REPORT(94) GOTO NEXT L: RCH() $)1 . //\* /DGIM/TPP2 20.13 5/5 GET "SY:TSYN.GET" LET DECLSYSWORDS() BE $( LET V = WORDV LET D(S, ITEM) BE $( LET LENGTH = S%0 WORDLENGTH := (LENGTH+3)/2 WORDV := S LOOKUPWORD() WORDNODE%0 := ITEM $) D('AND', S.AND) D('BE', S.BE) D('BREAK', S.BREAK) D('BY', S.BY) D('CASE', S.CASE) D('CODE', S.CODE) D('DO', S.DO) D('DEFAULT', S.DEFAULT) D('EQ', S.EQ) D('EQV', S.EQV) D('ENDCASE', S.ENDCASE) D('FALSE', S.FALSE) D('FOR', S.FOR) D('FINISH', S.FINISH) D('GOTO', S.GOTO) D('GE', S.GE) D('GR', S.GR) D('GLOBAL', S.GLOBAL) D('GET', S.GET) D('IF', S.IF) D('INTO', S.INTO) D('IS', S.BE) D('LET', S.LET) D('LV', S.LV) D('LE', S.LE) D('LS', S.LS) D('LOGOR', S.LOGOR) D('LOGAND', S.LOGAND) D('LOOP', S.LOOP) D('LSHIFT', S.LSHIFT) D('MANIFEST', S.MANIFEST) D('NE', S.NE) D('NOT', S.NOT) D('NEQV', S.NEQV) D('OR', S.OR) D('RESULTIS', S.RESULTIS) D('RETURN', S.RETURN) D('REM', S.REM) D('RSHIFT', S.RSHIFT) D('RV', S.RV) D('REPEAT', S.REPEAT) D('REPEATWHILE', S.REPEATWHILE) D('REPEATUNTIL', S.REPEATUNTIL) D('SWITCHON', S.SWITCHON) D('STATIC', S.STATIC) D('TO', S.TO) D('TEST', S.TEST) D('TRUE', S.TRUE) D('THEN', S.DO) D('TABLE', S.TABLE) D('UNTIL', S.UNTIL) D('UNLESS', S.UNLESS) D('VEC', S.VEC) D('VALOF', S.VALOF) D('WHERE', S.WHERE) D('WHILE', S.WHILE) D('$', 0); NULLTAG := WORDNODE WORDV := V $) AND LOOKUPWORD() = VALOF $(1 LET M = LV NAMETREE NEXT: WORDNODE := RV M IF WORDNODE NE 0 DO $(2 LET P = WORDNODE+3 FOR I = 0 TO WORDLENGTH-1 DO $( LET X, Y = P%I, WORDV%I IF X>Y DO $( M := WORDNODE+1; GOTO NEXT $) IF X") RETURN $) SWITCHON H1%X INTO $( CASE S.NUMBER: WRITEN(H2%X) WRITEC('>') RETURN CASE S.NAME: WRITES(X+3) WRITEC('>') RETURN CASE S.STRING: WRITEC('"') WRITES(X+1) WRITES('">') RETURN CASE S.FOR: SIZE := SIZE + 2 CASE S.COND:CASE S.FNDEF:CASE S.RTDEF: CASE S.TEST:CASE S.CONSTDEF: SIZE := SIZE + 1 CASE S.VECAP:CASE S.FNAP: CASE S.MULT:CASE S.DIV:CASE S.REM:CASE S.PLUS:CASE S.MINUS: CASE S.EQ:CASE S.NE:CASE S.LS:CASE S.GR:CASE S.LE:CASE S.GE: CASE S.LSHIFT:CASE S.RSHIFT:CASE S.LOGAND:CASE S.LOGOR: CASE S.EQV:CASE S.NEQV:CASE S.COMMA: CASE S.AND:CASE S.VALDEF:CASE S.VECDEF: CASE S.ASS:CASE S.RTAP:CASE S.COLON:CASE S.IF:CASE S.UNLESS: CASE S.WHILE:CASE S.UNTIL:CASE S.REPEATWHILE: CASE S.REPEATUNTIL: CASE S.SWITCHON:CASE S.CASE:CASE S.SEQ:CASE S.LET: CASE S.MANIFEST:CASE S.STATIC:CASE S.GLOBAL: SIZE := SIZE + 1 CASE S.VALOF:CASE S.LV:CASE S.RV:CASE S.NEG:CASE S.NOT: CASE S.TABLE:CASE S.GOTO:CASE S.RESULTIS:CASE S.REPEAT: CASE S.CODE: SIZE := SIZE + 1 CASE S.BREAK:CASE S.RETURN:CASE S.FINISH:CASE S.ENDCASE: CASE S.TRUE:CASE S.FALSE:CASE S.LOOP: DEFAULT: SIZE := SIZE + 1 IF N=D DO $( WRITES("ETC>") RETURN $) WRITES(VALOF SWITCHON H1%X INTO $( CASE S.FNDEF: RESULTIS "FNDEF" CASE S.RTDEF: RESULTIS "RTDEF" CASE S.CONSTDEF:RESULTIS "CONSTDEF" CASE S.VECDEF: RESULTIS "VECDEF" CASE S.VALDEF: RESULTIS "VALDEF" CASE S.FNAP: RESULTIS "FNAP" CASE S.RTAP: RESULTIS "RTAP" CASE S.SEQ: RESULTIS "SEQ" CASE S.COND: RESULTIS "->" CASE S.ASS: RESULTIS ":=" CASE S.MULT: RESULTIS "**" CASE S.DIV: RESULTIS "/" CASE S.VECAP: RESULTIS "%" CASE S.PLUS: RESULTIS "+" CASE S.MINUS: RESULTIS "-" CASE S.COLON: RESULTIS ":" CASE S.COMMA: RESULTIS "," DEFAULT: IF IN(NAMETREE,H1%X) RESULTIS S WRITEN(H1%X); RESULTIS "-OP" $) ) WRITEC('>') FOR I = 2 TO SIZE DO $( NEWLINE() V%N := I=SIZE -> " `", " |" FOR J=0 TO N DO WRITES(V%J) WRITES("-<") V%N := I=SIZE->" "," |" PLIST(H1%(X+I-1), N+1, D) $) RETURN $)1 AND IN(T,X) = VALOF $( IF T=0 RESULTIS FALSE IF T%0=S.NAME RESULTIS FALSE IF T%0=X $( S := T+3; RESULTIS TRUE $) RESULTIS IN(T%1,X) \/ IN(T%2,X) $) .