// BSAE2.bcpl - BCPL Compiler -- SAE part 2 - More Declaration handling // Copyright Xerox Corporation 1980 // Last modified on Sun 29 Oct 72 0350.42 by jec. // last modified by Butterfield, February 12, 1979 10:53 AM // - DeclExt, if not SWNoExtExts (/-E), allow EXTERNAL & EXTERNAL - 2/12/79 // DeclareLet // *DeclNames // *DeclValues // DeclLocal // DeclStatic // DeclExt // DeclStruct // CellWithName // NewName // StructWithName // NewStructName // CheckDistinct // OutputStatic // * local to this file. get "bsaex" let DeclareLet(x) be [ let DE, DS = DvecE, DvecS let Def = H2!x while H1!Def eq LINE do [ Curline = H2!Def; Def = H3!Def ] DeclNames(Def) CheckDistinct(DS, DvecS) DvecE = DvecS Decllabels(H3!x) DeclValues(Def) Declvars(H3!x) DvecE, DvecS = DE, DS ] and DeclNames(Def) be [ if Def eq 0 return while H1!Def eq LINE do [ Curline = H2!Def; Def = H3!Def; if Def eq 0 return ] switchon H1!Def into [ case AND: DeclNames(H2!Def) DeclNames(H3!Def) return case VALDEF: DeclLocal(H2!Def) return case RTDEF: case FNDEF: [ H5!Def = Nextentry() H2!(H2!Def) = H5!Def let d = DeclStatic(H2!Def, ENTRY) H6!Def = d!1 return ] default: SAEreport(-3) return ] ] and DeclValues(Def) be [ if Def eq 0 return while H1!Def eq LINE do [ Curline = H2!Def; Def = H3!Def; if Def eq 0 return ] switchon H1!Def into [ case AND: DeclValues(H2!Def) DeclValues(H3!Def) return case VALDEF: Lookat (H3+Def) return case RTDEF: case FNDEF: [ let DE, DS = DvecE, DvecS and DP = DvecP DvecP = DvecS DeclLocal(H3!Def) if H7!Def ne 0 do DeclLocal(H7!Def) CheckDistinct(DS, DvecS) DvecE = DvecS test H1!Def eq RTDEF then [ Decllabels(H4!Def) Declvars(H4!Def) ] or [ Lookat(H4+Def) ] DvecE, DvecS = DE, DS DvecP = DP return ] default: return ] ] and DeclLocal(x) be [ if x eq 0 return if (H1!x & TypeMask) eq LOCAL do [ NewName(x) return ] if H1!x eq COMMA do [ DeclLocal(H2!x) DeclLocal(H3!x) return ] if H1!x eq NIL return SAEreport(-4) ] and DeclStatic(x, valtype) = valof [ let xname = x!0 & NameMask let xtype = x!0 & TypeMask let xvalue = x!1 let d = CellWithName(xname) let dtype = d!0 & TypeMask test d ne 0 ifnot [ NewName(x) d = x ] ifso switchon dtype into [ case LOCAL: case CONSTANT: case LABEL: case ZLABEL: NewName(x) d = x endcase case EXTLABEL: case ZEXTLABEL: if d!1 ne 0 do SAEreport(2, xname) test dtype eq ZEXTLABEL % xtype eq ZLABEL then d!0 = (d!0 & NameMask) + ZINTLABEL or d!0 = (d!0 & NameMask) + INTLABEL endcase case INTLABEL: case ZINTLABEL: SAEreport(1, xname) resultis d default: SAEreport(-9) ] d!1 = Nextstatic() OutputStatic(d, xvalue, valtype) resultis d ] and DeclExt(x) be [ let xname = x!0 & NameMask let xtype = x!0 & TypeMask let d = CellWithName(xname) let dtype = d!0 & TypeMask test d ne 0 ifnot [ NewName(x) return ] ifso switchon dtype into [ case LOCAL: case CONSTANT: NewName(x) return case EXTLABEL: case ZEXTLABEL: if SWNoExtExts then SAEreport(3, xname) return case INTLABEL: case ZINTLABEL: SAEreport(4, xname) return case LABEL: case ZLABEL: SAEreport(5, xname) return default: SAEreport(-8) ] ] and DeclStruct(lvx, defnode, newstruct) be [ let x = rv lvx if x eq 0 return let y, z = nil, nil if (H1!x & NameBit) ne 0 do [ Curname = H1!x unless defnode eq 0 do [ NewStructName(x, defnode); DvecE = DvecS ] ] test (H1!x & NameBit) ne 0 % H1!x eq BLANK then DeclStruct(lv H2!x, 0, newstruct) or switchon H1!x into [ case UPLUMP: DeclStruct(lv H2!x, defnode, newstruct) if newstruct do [ H3!x = H3!x eq 0 ? 0, EvalConst(H3+x) H4!x = EvalConst(H4+x) ] endcase case FIELDLIST: case OVERLAYLIST: for i = 1 to H2!x do DeclStruct(lv (H2+i)!x, defnode, newstruct) endcase case RV: unless newstruct do SAEreport(-21) y = StructWithName(H2!x) test y eq 0 then [ SAEreport(11, H2!x); rv lvx = 0 ] or [ z = H2!y switchon H1!z into [ case BIT: case BYTE: case WORD: case UPLUMP: case FIELDLIST: case OVERLAYLIST: endcase default: SAEreport(-23) ] DeclStruct(lv H2!y, (defnode eq 0 ? 0, H2!y), false) rv lvx = H2!y endcase ] case BIT: case BYTE: case WORD: if newstruct do H2!x = H2!x eq 0 ? 1, EvalConst(H2+x) endcase default: SAEreport(-22) ] ] and NewName(namenode) be [ if DvecS + DvecN ge DvecT do [ SAEreport(6, namenode!0); return ] DVec!DvecS = (namenode!0 & NameMask) + NameBit DVec!(DvecS+1) = namenode DvecS = DvecS + DvecN ] and CellWithName(n) = valof [ n = (n & NameMask) + NameBit DvecLoc = DvecE - DvecN while DvecLoc gr 0 do [ if DVec!DvecLoc eq n resultis DVec!(DvecLoc+1) DvecLoc = DvecLoc - DvecN ] resultis 0 ] and NewStructName(namenode, defnode) be [ if DvecS + DvecN ge DvecT do [ SAEreport(6, namenode!0); return ] DVec!DvecS = namenode DVec!(DvecS+1) = defnode DvecS = DvecS + DvecN ] and StructWithName(n) = valof [ n = (n & NameMask) + NameBit DvecLoc = DvecE - DvecN while DvecLoc gr 0 do [ let namenode = DVec!DvecLoc if (namenode & NameBit) eq 0 do if namenode!0 eq n resultis namenode DvecLoc = DvecLoc - DvecN ] resultis 0 ] and CheckDistinct(DE, DS) be [ for q = DE step DvecN to DS - DvecN do [ let n = DVec!q test (n & NameBit) ne 0 then for p = q + DvecN step DvecN to DS - DvecN do if DVec!p eq n do SAEreport(7, n) or for p = q + DvecN step DvecN to DS - DvecN do [ let namenode = DVec!p if (namenode & NameBit) eq 0 do if H1!namenode eq H1!n do SAEreport(13, H1!n) ] ] ] and OutputStatic(d, val, valtype) be [ let op = selecton d!0 & TypeMask into [ case EXTLABEL: EXT case ZEXTLABEL: ZEXT case INTLABEL: INT case ZINTLABEL: ZINT case LABEL: LOC case ZLABEL: ZLOC default: 0 ] Writech(OcodeStream, op) Writeaddr(OcodeStream, d!0 & NameMask) switchon d!0 & TypeMask into [ case EXTLABEL: case ZEXTLABEL: return case INTLABEL: case ZINTLABEL: case LABEL: case ZLABEL: Writech(OcodeStream, valtype) [ Writeword(OcodeStream, val) ] return default: SAEreport(-2) ] ]