// KeywordInit.bcpl -- initialization for keyword table package, // containing primitives for creating keyword tables // and inserting and deleting keyword table entries. // Copyright Xerox Corporation 1979, 1982 // Last modified May 12, 1982 5:24 PM by Taft get "Keyword.decl" external [ // outgoing procedures CreateKeywordTable; DestroyKeywordTable; EnumerateKeywordTable LookupKeyword; InsertKeyword; DeleteKeyword // for OEP declaration only KTInsert; KTDelete // incoming procedures KTLookup; KTEnumerate; KTDestroy BinarySearch; CompareKey; ExtractSubstring DefaultArgs; Allocate; Free; MoveBlock; Zero; SysErr Call0; Call1; Call2; Call3; Call4 // incoming statics sysZone ] static [ DestroyKeywordTable; EnumerateKeywordTable LookupKeyword; InsertKeyword; DeleteKeyword ] structure String: [ length byte; char↑1,255 byte ] //--------------------------------------------------------------------------- let CreateKeywordTable(maxEntries, lenEntry, zone; numargs na) = valof //--------------------------------------------------------------------------- // Creates and returns a keyword table capable of holding a maximum of // maxEntries entries of lenEntry words each [ DefaultArgs(lv na, -1, 1, sysZone) let lenKTE = offset KTE.entry/16 + lenEntry let kt = Allocate(zone, (offset KT.kte↑0)/16 + maxEntries*lenKTE) kt>>KT.Insert = KTInsert kt>>KT.Delete = KTDelete kt>>KT.Lookup = KTLookup kt>>KT.Enumerate = KTEnumerate kt>>KT.Destroy = KTDestroy kt>>KT.zone = zone kt>>KT.numEntries = 0 kt>>KT.maxEntries = maxEntries kt>>KT.lenKTE = lenKTE InsertKeyword = Call0 DeleteKeyword = Call1 LookupKeyword = Call2 EnumerateKeywordTable = Call3 DestroyKeywordTable = Call4 resultis kt ] //--------------------------------------------------------------------------- and KTInsert(kt, key) = valof //--------------------------------------------------------------------------- // Inserts a copy of the supplied key string into the table kt // and returns a pointer to the new entry (which has been zeroed). [ let i = not BinarySearch(key, kt, kt>>KT.numEntries, CompareKey) if i ls 0 then SysErr(kt, ecKeyAlreadyExists) if kt>>KT.numEntries eq kt>>KT.maxEntries then SysErr(kt, ecKeyTableFull) let kte = GetKTE(kt, i) let p = GetKTE(kt, kt>>KT.numEntries)-1 while p ge kte do [ p!(kt>>KT.lenKTE) = p!0; p = p-1 ] kt>>KT.numEntries = kt>>KT.numEntries+1 Zero(kte, kt>>KT.lenKTE) kte>>KTE.key = ExtractSubstring(key, 0, 0, kt>>KT.zone) resultis lv kte>>KTE.entry ] //--------------------------------------------------------------------------- and KTDelete(kt, key) be //--------------------------------------------------------------------------- // Deletes the entry matching key from the table. [ let i = BinarySearch(key, kt, kt>>KT.numEntries, CompareKey) if i ls 0 then SysErr(kt, ecKeyDoesntExist) let kte = GetKTE(kt, i) Free(kt>>KT.zone, kte>>KTE.key) kt>>KT.numEntries = kt>>KT.numEntries-1 // this may move zero words, but that's supposed to be ok MoveBlock(kte, kte+kt>>KT.lenKTE, (kt>>KT.numEntries-i)*kt>>KT.lenKTE) ] //--------------------------------------------------------------------------- and GetKTE(kt, i) = lv kt>>KT.kte↑0 + i * kt>>KT.lenKTE //---------------------------------------------------------------------------