// BSAE4.bcpl - BCPL Compiler -- SAE part 4 -- Structure reference handling // Copyright Xerox Corporation 1980 // LookatQual // TraceStructName // StructSize // CheckStruct get "bsaex" let LookatQual(x) = valof [ let S = NULLQUALNODE if x!0 eq 0 resultis S let def = StructWithName(x!1) if def eq 0 do [ SAEreport(14, x!1); x!(-1) = S; resultis S ] def = DVec!(DvecLoc+1) //the top-level node containing the name let u = vec QualMax * 4 u!0 = 0 let q = 1 u!q = 0 let p = 1 for k = 1 to x!0 do [nextname let v = vec QualMax*2 v!0 = 0 v!1 = 0 let d = TraceStructName(x!p, def, v) if d eq 0 do [ SAEreport(14, x!p); x!(-1) = S; resultis S ] let m = x!(p+1) let n = v!0 test m gr n then [ SAEreport(15, x!p); x!(-1) = S; resultis S ] or if m ls n unless k eq x!0 then [ SAEreport(16, x!p); x!(-1) = S; resultis S ] let r = 1 for l = 1 to x!(p+1) do [nextsubscr u!q = u!q + v!r let subdef = v!(r+1) let lvsub = Lookat(lv x!((p+1)+l)) test lvsub gr 0 then [ let sub = rv lvsub unless sub ge H3!subdef do SAEreport(17, x!p) unless sub le H4!subdef do SAEreport(18, x!p) u!q = u!q + (sub - H3!subdef) * StructSize(H2!subdef) ] or [ u!(q+1) = x!((p+1)+l) u!(q+2) = lv H3!subdef u!(q+3) = StructSize(H2!subdef) u!0 = u!0 + 1 q = q + 4 u!q = 0 ] r = r + 2 ]nextsubscr u!q = u!q + v!r u!(q+1) = StructSize(v!(r+1)) p = (p+1) + x!(p+1) +1 def = d ]nextname S = Newvec(q+1) H1!S = u!q H2!S = u!(q+1) for i = 0 to q-1 do (H3+i)!S = u!i x!(-1) = S resultis S ] and TraceStructName(name, def, v) = valof [ if (H1!def & NameBit) ne 0 do [ test (H1!def & NameMask) eq (name & NameMask) then [ v!(v!0*2+2) = H2!def; resultis H2!def ] or resultis 0 ] switchon H1!def into [ case UPLUMP: [uplump let m = v!0 let n = m*2+1 v!(n+1) = def v!0 = v!0 + 1 n = n + 2 v!n = 0 let s = TraceStructName(name, H2!def, v) if s eq 0 do v!0 = m resultis s ]uplump case FIELDLIST: case OVERLAYLIST: [list let m = v!0 let n = m*2+1 let l = v!n for i = 1 to H2!def do [ let y = (H2+i)!def let s = TraceStructName(name, y, v) if s ne 0 resultis s if H1!def eq FIELDLIST do v!n = v!n + StructSize(y) ] v!n = l ]list case BLANK: resultis 0 case BIT: case BYTE: case WORD: resultis 0 default: SAEreport(-25) ] ] and StructSize(def) = valof [ if (H1!def & NameBit) ne 0 resultis StructSize(H2!def) switchon H1!def into [ case UPLUMP: resultis (H4!def - H3!def + 1) * StructSize(H2!def) case FIELDLIST: [ let s = 0 for i = 1 to H2!def do s = s + StructSize((H2+i)!def) resultis s ] case OVERLAYLIST: [ let s = 0 for i = 1 to H2!def do [ let t = StructSize((H2+i)!def) if t gr s do s = t ] resultis s ] case BLANK: resultis StructSize(H2!def) case BIT: resultis H2!def case BYTE: resultis H2!def * ByteSizeOb case WORD: resultis H2!def * WordSizeOb default: SAEreport(-26) ] ] and CheckStruct(def, B) = valof [ if def eq 0 resultis 0 let err = 0 test (H1!def & NameBit) ne 0 then [ Curname = H1!def err = CheckStruct(H2!def, B) ] or switchon H1!def into [ case FIELDLIST: for i = 1 to H2!def do [ err = CheckStruct((H2+i)!def, B) unless err eq 0 resultis err B = B + StructSize((H2+i)!def) ] endcase case OVERLAYLIST: for i = 1 to H2!def do [ err = CheckStruct((H2+i)!def, B) unless err eq 0 resultis err ] endcase case UPLUMP: for i = H3!def to H4!def do [ err = CheckStruct(H2!def, B) unless err eq 0 resultis err B = B + StructSize(H2!def) ] endcase case BLANK: endcase case WORD: unless B rem WordSizeOb eq 0 do err = 19 endcase case BYTE: unless B rem ByteSizeOb eq 0 do err = 20 endcase case BIT: unless (B+StructSize(def)-1)/WordSizeOb eq B/WordSizeOb do err = 21 endcase default: SAEreport(-27) ] resultis err ]