// BSAE0.bcpl - BCPL Compiler -- SAE Main Program.
// Copyright Xerox Corporation 1980
// Last modified on 15 sept 74 by GMcD.
// DeclareNames Scan the tree and process all declarations
// SAEreport
// PrintName Print a name for SAE errors
get "bsaex"
external InitToRead
static // Scalars used in CAE.
[ Curname = -1
DVec = nil // Stack of identifiers currently declared.
DvecS = DvecN+DvecN // Next free location in Dvec.
DvecE = DvecN+DvecN // Last Dvec location currently declared.
DvecP = DvecN+DvecN // Base in Dvec of current block body.
DvecLoc = 0 // Output of CellWithName
Uvec = nil
UvecP = 0
]
let DeclareNames() be
[ if SWDebug do WriteS("SAE*n")
ResetStream(DictStream, $d)
InitToRead(DictStream)
let v = vec DvecT; DVec = v
DVec!0, DVec!1 = 0, 0 // An unused entry, for error return from CellWithName.
DVec!DvecN, DVec!(DvecN+1) = ERRORNAME, ERRORNODE // Declare "?".
Uvec = Newvec(UvecT)
Uvec!0, Uvec!1 = ERRORNAME + LABEL, 0
OcodeStream = OpenTemp($c, false) // output only
Decllabels(rv Tree); Declvars(rv Tree)
Writech(OcodeStream, ENDSTATIC)
TreeOffset = Newvec(0); rv TreeOffset =-1 // The last tree location
if UvecP eq 0 return
Ostream = ErrorStream
WW($*n)
if UvecP ge UvecT do WriteS("MORE THAN ")
WriteN(UvecP/UvecN); WriteS(" UNDEFINED NAME")
unless UvecP/UvecN eq 1 do WW($S); WW($*n)
for p = UvecN to UvecP by UvecN do
[ PrintName(Uvec!p); WW($*t); WriteN(Uvec!(p+1)); WW($*n) ]
Ostream = OutputStream
]
and SAEreport(n, name) be
[ Ostream = ErrorStream
WW($*n)
WriteLine(Curline)
let m = selecton n into
[ default: 0
case 1: "MULTIPLE DEFINITION -- EXTERNAL+STATIC & STATIC"
case 2: "EXTERNAL NAME USED BEFORE STATIC DECLARATION"
case 3: "MULTIPLE DEFINITION -- EXTERNAL & EXTERNAL"
case 4: "MULTIPLE DEFINITION -- EXTERNAL+STATIC & EXTERNAL"
case 5: "MULTIPLE DEFINITION -- STATIC & EXTERNAL"
case 6: "TOO MANY NAMES DEFINED IN THE SAME SCOPE"
case 7: "MULTIPLE DEFINITION"
case 8: "DYNAMIC NAME REFERENCED OUTSIDE ITS DEFINING PROCEDURE"
case 9: "EXPRESSION MUST BE CONSTANT"
case 10: "UNDEFINED NAME"
case 11: "UNDEFINED NAME AFTER @ "
case 12: "IMPROPER NAME AFTER @ "
case 13: "MULTIPLE STRUCTURE NAME DEFINITION"
case 14: "UNDEFINED STRUCTURE NAME"
case 15: "TOO MANY SUBSCRIPTS AFTER NAME"
case 16: "NOT ENOUGH SUBSCRIPTS ON NAME"
case 17: "SUBSCRIPT LESS THEN LOWER LIMIT"
case 18: "SUBSCRIPT GREATER THAN UPPER LIMIT"
case 19: "WORD FIELD IS NOT ON A WORD BOUNDARY"
case 20: "BYTE FIELD IS NOT ON A BYTE BOUNDARY"
case 21: "BIT FIELD OVERLAPS A WORD BOUNDARY"
]
BCPLreport(n, m)
if n ls 0 do name = -1
unless name eq -1 do
[ WriteS(" *""); PrintName(name); WriteS("*"*n") ]
unless Curname eq -1 do
[ WriteS(" LAST NAME DECLARED WAS *"")
PrintName(Curname); WriteS("*"*n")
Curname = -1
]
if SWHelp do Help("SAE REPORT")
if n le 0 goto Abort
Ostream = OutputStream
]
and PrintName(name) be
[ name = name & NameMask
if name eq 0 % name eq NameMask do [ WriteS("??"); return ]
Reposition(DictStream, name*Bytesperword)
let v = vec NAMELENGTH/Bytesperword
Readword(DictStream, lv v!0)
for i = 1 to Length(v)/Bytesperword do Readword(DictStream, lv v!i)
WW($*s); WriteS(v); WW($*s)
]