// BCAE0.bcpl - BCPL Compiler -- CAE Main Program. // Copyright Xerox Corporation 1980 // Swinehart, 5-10-77: docase exp // last modified by Butterfield, January 25, 1979 2:09 PM // - Nextsymb, add END - 1/25/79 // ConstructTree Construct the AE-tree. // Nextsymb Read the LEX file for the next lexeme // CAEskip Skip over command after an error // LinePtr Get the last line pointer read by Nextsymb // CAEreport Error report for CAE. get "bcaex" external InitToRead static // Scalars used in CAE. [ TRUENODE = nil // Tree node to hold (TRUE, true). FALSENODE = nil // ditto false NILNODE = nil // ditto nil ERRORNAME = nil // Dummy name used to recover from errors. ERRORNODE = nil // Dummy node for undefined names ZERONODE = nil // A useful node consisting of (NUMBER,0) NULLQUALNODE = nil // For qualname errors TempV = nil // Temp vector for EXT, etc. in Readblockbody ] let ConstructTree() be // Translate the source code [ if SWDebug do WriteS("CAE*n") let v = vec Vmax; V = v // Nextsymb reads names and numbers and strings here. let v = vec TempT; TempV = v Tree = Newvec(0) // The initial tree location TRUENODE = List2(TRUE, true) // Various useful nodes FALSENODE = List2(FALSE, false) NILNODE = List2(NIL, 0) ZERONODE = List2(NUMBER,0) ERRORNAME = 0 ERRORNODE = List2(ERRORNAME + LABEL, 0) NULLQUALNODE = List3(0, WordSizeOb, 0) ResetStream(LexStream, $l) // Reopen the LEX file for reading InitToRead(LexStream) Curline = 0 Nextsymb() rv Tree = Readblockbody() // DO THE WORK. unless Symb eq END do CAEreport(0) CloseTemp(LexStream, $l) // Close the LEX file ] and CAEreport(n) be [ Ostream = ErrorStream WW($*n) let w = WriteLines(Curline, -1, 2) if not w do unless SWHelp % SWDebug return let m = selecton n into [ default: 0 case 0: "END OF SOURCE TEXT NOT REACHED*n*t(POSSIBLY DUE TO PREVIOUS ERROR)" case 1: "ILLEGAL EXPRESSION IN DECLARATION" case 2: "ILLEGAL EXPRESSION" case 3: "TOO MANY NAMES IN DECLARATION" case 4: "DECLARATION IMPROPERLY TERMINATED" case 5: "TABLE NOT FOLLOWED BY [ " case 6: "END OF SOURCE TEXT REACHED -- CLOSING ] EXPECTED" case 7: "CLOSING ] EXPECTED" case 8: "NAME EXPECTED" case 9: "MISSING COMMA" case 10: "ILLEGAL STATEMENT" case 11: "ILLEGAL EXPRESSION IN SWITCH" case 12: "SWITCH NOT FOLLOWED BY [ " case 13: "ILLEGAL ARGUMENT LIST" case 14: "ILLEGAL CONDITIONAL EXPRESSION" case 15: "ILLEGAL PROCEDURE DECLARATION" case 16: "PROCEDURE BODY EXPECTED" case 17: "ILLEGAL DECLARATION" case 18: "ILLEGAL LABEL" case 19: "ILLEGAL STATEMENT" case 20: "CONDITIONAL CLAUSE IMPROPERLY TERMINATED" case 21: "ILLEGAL FOR CLAUSE" case 22: "FOR CLAUSE IMPROPERLY TERMINATED" case 23: "CASE LABEL IMPROPERLY TERMINATED" case 24: "NEXT CASE EXPECTED IN SELECTON EXPRESSION" case 25: "DO, THEN, IFSO, IFNOT, INTO OUT OF CONTEXT" case 26: "AND OUT OF CONTEXT" case 27: "TABLE TOO BIG" case 28: "OPENING [ EXPECTED" ] BCPLreport(n, m) if SWHelp do Help("CAE REPORT") if n le 0 goto Abort Ostream = OutputStream ] and Nextsymb() be // Read the next lexeme from the LEX file [ let n = nil L: if SWCaeTrace do [ WriteS("*t*******s") ] Readch(LexStream, lv Symb) // The lexeme symbol switchon Symb into [ case NAME: Readaddr(LexStream, lv V!0) if SWCaeTrace do [ WriteS("NAME "); WriteO(V!0) ] endcase case LINE: Readaddr(LexStream, lv Curline) if SWCaeTrace do [ WriteS("LINE "); WriteO(Curline); if SWList do WW($*n) ] if SWList do [ if not SWCaeTrace do [ WriteO(Curline); WW($*s) ] WriteLine(Curline) ] goto L case END: Readaddr(LexStream, lv V!0) if SWCaeTrace do [ WriteS("END "); WriteO(V!0) ] endcase case NUMBER: case CHARCONST: Readword(LexStream, lv V!0) if SWCaeTrace do [ WriteN(Symb); WW($*s); WriteO(V!0) ] endcase case NAMEBRA: case NAMEKET: case STRINGCONST: Readword(LexStream, lv V!0) for i = 1 to Length(V)/Bytesperword do Readword(LexStream, lv V!i) test Symb eq NAMEBRA then Symb = SECTBRA or if Symb eq NAMEKET then Symb = SECTKET if SWCaeTrace do [ WriteN(Symb); WW($*s); WriteS(V) ] endcase case SECTBRA: case SECTKET: V!0 = 0 if SWCaeTrace do [ WriteN(Symb) ] endcase default: if SWCaeTrace do [ WriteN(Symb) ] endcase ] if SWCaeTrace do WW($*n) ] and CAEskip(n) = valof [ CAEreport(n) switchon Symb into [ case SEMICOLON: case SECTKET: case END: resultis true // We are at the end of a command case SECTBRA: case LET: case AND: case STATIC: case EXT: case MANIFEST: case IF: case UNLESS: case WHILE: case UNTIL: case TEST: case FOR: case GOTO: case SWITCHON: case CASE: case DEFAULT: case BREAK: case LOOP: case ENDCASE: case RETURN: case RESULTIS: case FINISH: case ABORT: case DOCASE: resultis false // We are at the beginning of a command default: Nextsymb() ] repeat ] and LinePtr() = Curline // Retrieve the last line pointer seen by Nextsymb