// BCAE2.bcpl - BCPL Compiler -- Part 2 of CAE. // Copyright Xerox Corporation 1980 // Last modified on Sat 28 Oct 72 0028.04 by jec. // Paxton, 9-14-78: unsigned compares // Rexp The main expression reader. get "bcaex" let Rexp(n) = valof [ let A, B, C, Op = nil, nil, nil, nil if Symb eq NAME do // This is the usual case, so give it fast service. [ A = V!0 + NameBit; Nextsymb() goto L ] // Read the next operand, and store it into A. switchon Symb into // Branch on the leading operand of the expression. [ default: CAEskip(2) resultis List2(NUMBER, 0) case STRINGCONST: A = Newvec(1 + Length(V)/Bytesperword) A!0 = STRINGCONST for k = 0 to Length(V)/Bytesperword do A!(k+1) = V!k Nextsymb() endcase case CHARCONST: A = List2(CHARCONST, V!0) Nextsymb() endcase case NUMBER: A = List2(NUMBER, V!0) Nextsymb() endcase case NIL: A = NILNODE; Nextsymb(); endcase case TRUE: A = TRUENODE; Nextsymb(); endcase case FALSE: A = FALSENODE; Nextsymb(); endcase case RBRA: Nextsymb() A = Rexp(0) test Symb eq RKET then Nextsymb() or [ CAEskip(2) resultis A ] endcase case VALOF: Nextsymb() A = Rcom(Rcom) A = List2(VALOF, A) endcase case TABLE: [ Nextsymb() A = Rtable() endcase ] case SELECTON: [ Nextsymb() A = Rexp(0) while Symb eq SEMICOLON do Nextsymb() test Symb eq INTO then Nextsymb() or CAEskip(11) let V1 = 0 while Symb eq SEMICOLON do Nextsymb() test Symb eq SECTBRA ifnot CAEskip(12) ifso [ if V!0 ne 0 do [ V1 = Newvec(Length(V)/Bytesperword) for k = 0 to Length(V)/Bytesperword do V1!k = V!k ] Nextsymb() ] B = Rselect(false) test Symb eq SECTKET ifso if EqVec(V1) do Nextsymb() ifnot CAEskip(7) A = List3(SWITCHON, A, B) A = List2(VALOF, A) endcase ] case SIZE: // Size of a structure item. case OFFSET: // Offset of a structure item Op = Symb A = Rqualname(2) H1!A = Op H2!A = 0 endcase case LV: case RV: Op = Symb Nextsymb() A = Rexp(35) A = List2(Op, A) endcase case PLUS: Nextsymb() A = Rexp(35) endcase case MINUS: Nextsymb() A = Rexp(35) A = List2(NEG, A) endcase case VEC: Nextsymb() A = Rexp(12) A = List2(VEC, A) endcase case NOT: Nextsymb() A = Rexp(25) A = List2(NOT, A) endcase ] L: // An operand has been read. Now look at the next operator. switchon Symb into [ default: resultis A case RBRA: Nextsymb() test Symb eq RKET // Have empty parentheses been scanned? ifso [ B = 0; Nextsymb() ] // Yes. ifnot [ B = Rexp(0) test Symb eq RKET then Nextsymb() or [ CAEskip(13) resultis List3(FNAP, A, B) ] ] A = List3(FNAP, A, B) goto L case VECAP: if n ge 40 resultis A Nextsymb() B = Rexp(40) A = List3(VECAP, A, B) goto L case HEFALUMP: A = List2(RV, A) Symb = RIGHTLUMP case LEFTLUMP: case RIGHTLUMP: if n ge 38 resultis A Op = Symb B = Rqualname(3) H1!B = Op H2!B = A H3!B = 0 A = B goto L case DIV: case REM: case MULT: case LSHIFT: case RSHIFT: if n ge 35 resultis A Op = Symb Nextsymb() B = Rexp(34) A = List3(Op, A, B) goto L case PLUS: case MINUS: if n ge 34 resultis A Op = Symb Nextsymb() B = Rexp(34) A = List3(Op, A, B) goto L case EQ: case NE: case LS: case LE: case GR: case GE: case ULS: case ULE: case UGR: case UGE: if n ge 30 resultis A Op = Symb Nextsymb() B = Rexp(30) A = List3(Op, A, B) goto L case LOGAND: if n ge 24 resultis A Nextsymb() B = Rexp(23) A = List3(LOGAND, A, B) goto L case LOGOR: if n ge 23 resultis A Nextsymb() B = Rexp(22) A = List3(LOGOR, A, B) goto L case EQV: case NEQV: if n ge 22 resultis A Op = Symb Nextsymb() B = Rexp(22) A = List3(Op, A, B) goto L case COND: if n ge 13 resultis A Nextsymb() B = Rexp(12) test Symb eq COMMA then Nextsymb() or [ CAEskip(14) resultis A ] C = Rexp(12) A = List4(COND, A, B, C) goto L case COMMA: if n ge 12 resultis A Nextsymb() B = Rexp(11) A = List3(COMMA, A, B) goto L ] ]