// BLEX0A.bcpl -  BCPL Compiler
//*DCS* Precompiled Declaration Files -- Read, Write Utilities
// Copyright Xerox Corporation 1980

   get "blexx"
   get "bcpliox"
   
   external
      [
      syscall
      openfile
      ]
      
// Code

   let ReadDecl() be
      [
      ///* DictStream file contains statics needed to re-initialize
      ///* LEX, some tables chronicling the file reading events which
      ///*  occurred during precompilation, and the dictionary as
      ///*  normally written by LEX for other passes.
      ///* First, Read random statics
      let InStream = openfile(DICTName)
      InStream>>STREAM.action = readact
      let nv = GetnameV!0
      LexLength = ReadWord(InStream)
      Chline = ReadWord(InStream)
      LastItem = ReadWord(InStream)
      NewLineptr = ReadWord(InStream)
      NLPending = ReadWord(InStream)
      ///* Read File Table Pointers, the Tables Themselves
      GetnameP = ReadWord(InStream)
      ReadSequential(InStream,
         GetnameV, (GetnameP+GetnameN))
      // Each file name is FileNameLength bytes long.  There are
      // GetnameP/GetnameN+1 of them.
      ReadSequential(InStream, (GetnameV!0),
         (FileNameLength/2+1)*(GetnameP/GetnameN+1))
      GetlineP = ReadWord(InStream)
      if GetlineP gr GetlineT then [ LEXreport(1) ]
      ReadSequential(InStream,
         GetlineV,GetlineP)
      ///* Dictionary Related Statics
      RealSymCount = ReadWord(InStream)
      RealSymSize = ReadWord(InStream)
      DictLength = ReadWord(InStream)
      Dictionary!0 = DictLength
      ///* The Partial Dictionary
      ReadSequential(InStream,(Dictionary+1),
         (DictLength-1) )
      CloseInput(InStream)
        ///* relocate pointers if addresses differ
      nv = nv - GetnameV!0
      if nv ne 0 then
         for i = 0 to GetnameT by GetnameN do
            GetnameV!i = GetnameV!i + nv
      ]
   
   and ReadLex() be
      [
      let InStream = openfile(DECLName)
      InStream>>STREAM.action = readact
      let buf = vec 510 ///* two DOS buffers.
      for i = LexLength/2 to 0 by -510 do
         if i ne 0 then 
            [
            let ct = i ls 510? i,510
            ReadSequential(InStream,buf,ct)
            WriteSequential(LexStream,buf,ct)
            ]
      CloseInput(InStream)
      ]
   
   and WriteDecl() be
      [
      ///* See ReadDecl for description of DictStream contents
      ///* First, Write random statics
      WriteWord(DictStream, LexLength)
      WriteWord(DictStream, Chline)
      WriteWord(DictStream, LastItem)
      WriteWord(DictStream, NewLineptr)
      WriteWord(DictStream, NLPending)
      ///* Write File Table Pointers, the Tables Themselves
      WriteWord(DictStream, GetnameP)
      WriteSequential(DictStream,
         GetnameV, (GetnameP+GetnameN))
      WriteSequential(DictStream, (GetnameV!0),
         (FileNameLength/2+1)*(GetnameP/GetnameN+1))
      WriteWord(DictStream, GetlineP)
      WriteSequential(DictStream,
         GetlineV,GetlineP)
      ///* Dictionary Related Statics
      WriteWord(DictStream,RealSymCount)
      WriteWord(DictStream,RealSymSize)
      ///* Partial Dictionary itself written by lex0
      ]