// BSAE1.bcpl - BCPL Compiler -- SAE part 1 - Declaration handling // Copyright Xerox Corporation 1980 // Last modified on Sun 29 Oct 72 0345.20 by jec. // Swinehart, 5-10-77: docase exp, merge Declvars activities // last modified by Butterfield, January 31, 1979 12:59 PM // - Scanlabels and Declvars, ThinDVec on END - 1/25/79 // Decllabels Declare all the labels at the top level in a block. // *ScanLabels Do the work for Decllabels. // Declvars Declare all the rest of the names in a block. // *ThinDVec Squeeze out names with excessive Dictionary indexes. // * local to this file. get "bsaex" // This routine is called for all blocks to declare all labels reachable at the top level // in the block. It uses ScanLabels to do the work. let Decllabels(x) be [ let DS = DvecS let L = Curline ScanLabels(x) CheckDistinct(DS, DvecS) Curline = L DvecE = DvecS ] // This routine does the work for Decllabels just above. All labels are declared. and ScanLabels(x) be [ if x eq 0 return switchon H1!x into [ default: return case COLON: [ H5!x = Nextentry() H2!(H2!x) = H5!x let d = DeclStatic(H2!x, LENTRY) H4!x = d!1 ScanLabels(H3!x) return ] case IF: case UNLESS: case UNTIL: case WHILE: ScanLabels(H3!x) return case REPEAT: case REPEATWHILE: case REPEATUNTIL: ScanLabels(H2!x) return case TEST: ScanLabels(H3!x) ScanLabels(H4!x) return case LINE: Curline = H2!x if SWList do WriteLine(Curline) ScanLabels(H3!x) return case END: ThinDVec(H2!x) ScanLabels(H3!x) return case SWITCHON: case CASE: ScanLabels(H3!x) return case CASETO: ScanLabels(H4!x) return case DEFAULT: ScanLabels(H2!x) return case SEQ: ScanLabels(H2!x) ScanLabels(H3!x) return ///*DCS* conditional compilation, choose one case COMPILEIF: [ H1!x = COMPILETEST let B = EvalConst(H3+x) /// 0 => want ifnot (no code if COMPILEIF) let res = B? H4!x, H5!x if res then [ let rest = H2!x H2!x = res Compileifsplice(x,H2+x,rest) ] ScanLabels(H2!x) // rest of block body return ] ] ] and Declvars(x) be [ if x eq 0 return switchon H1!x into [ case LET: DeclareLet(x) return case EXT: case MANIFEST: case STATIC: case STRUCTURE: [ let DE, DS = DvecE, DvecS L: test H1!x eq STRUCTURE then [struct DeclStruct(lv H3!x, H3!x, true) let err = CheckStruct(H3!x, 0) unless err eq 0 do SAEreport(err, -1) ]struct or [var let p = lv H4!x until p ge lv H4!x + H3!x do [scan Curname = p!0 switchon H1!x into [ case EXT: DeclExt(p) endcase case STATIC: p!1 = EvalConst(lv p!1) DeclStatic(p, STATIC) endcase case MANIFEST: p!1 = EvalConst(lv p!1) NewName(p) endcase ] DvecE = DvecS p = p + 2 ]scan ]var Curname = -1 let t = x x = H2!x M: switchon H1!x into [ case LINE: Curline = H2!x if SWList do WriteLine(Curline) x = H3!x goto M case END: ThinDVec(H2!x) x = H3!x goto M case EXT: case MANIFEST: case STATIC: case STRUCTURE: goto L default: endcase ] x = t CheckDistinct(DS, DvecS) DvecE = DvecS Decllabels(H2!x) Declvars(H2!x) DvecE, DvecS = DE, DS return ] case LINE: Curline = H2!x if SWList do WriteLine(Curline) Declvars(H3!x) return case END: ThinDVec(H2!x) Declvars(H3!x) return case ASS: case RTAP: Lookat(H2+x); Lookat(H3+x) return case GOTO: case RESULTIS: case DOCASE: Lookat(H2+x) return case IF: case UNLESS: case WHILE: case UNTIL: case CASE: case SWITCHON: Lookat(H2+x) case COLON: Declvars(H3!x) return case TEST: Lookat(H2+x) Declvars(H3!x) Declvars(H4!x) return case REPEATWHILE: case REPEATUNTIL: Lookat(H3+x) case REPEAT: case DEFAULT: case COMPILETEST: Declvars(H2!x) return case CASETO: // Case label with limits. Lookat(H2+x); Lookat(H3+x) Declvars(H4!x) return case FOR: [ Lookat(H3+x) Lookat(H4+x) unless H5!x eq 0 do Lookat(H5+x) let DE, DS = DvecE, DvecS DeclLocal(H2!x) DvecE = DvecS Decllabels(H6!x) Declvars(H6!x) DvecE, DvecS = DE, DS return ] case SEQ: Declvars(H2!x) Declvars(H3!x) return case COMPILEIF: SAEreport(-20) // Conditional compilation out of place case BREAK: case LOOP: case RETURN: case FINISH: case ABORT: case ENDCASE: return default: SAEreport(-1) // Error report. ] ] and Compileifsplice(x,lvsome,rest) be [ let some = @lvsome unless some do [ @lvsome = rest return ] let idx = selecton H1!some into [ case MANIFEST: case EXT: case STATIC: case COMPILEIF: case STRUCTURE: H2 case LINE: case AND: case LET: case SEQ: H3 default: -1 ] test idx < 0 ifso [ H3!x = SEQ H4!x = some H5!x = rest @lvsome = H3+x ] ifnot Compileifsplice(x,idx+some,rest) ] //---------------------------------------------------------------------------- and ThinDVec(newEnd) be //---------------------------------------------------------------------------- [ manifest [ signBit = #100000; goodSign = signBit; badSign = 0; ] let NextName(index, sign, newEnd) = valof [ if index ge DvecS resultis DvecS //don't let index go beyond DvecS let nameword = DVec!index; let name = NameMask & (((nameword & NameBit) ne 0)? nameword, @nameword) if (name - newEnd & signBit) eq sign resultis index; index = index + DvecN; ] repeat; let new = NextName(DvecN + DvecN, badSign, newEnd); let bad = new; //(skip CellWithName's unused error entry and ERRORNAME entry; cf. BSAE0) while bad ls DvecS do [ let good = NextName(bad + DvecN, goodSign, newEnd); bad = NextName(good + DvecN, badSign, newEnd); for i = 0 to bad - good - 1 do DVec!(new+i) = DVec!(good+i); new = new + bad - good; ] DvecS = new; ]