-- CreateLookupImpl.mesa -- ryu 27-Jun-84 19:48:39 DIRECTORY CESDictDataDefs USING [DictBytesPerEntry, Entry], JLispLookupFile USING [MaxKanaPerEntry, MaxKanjiPerEntry, LEntry, DictPtr], CharDefs USING [Char, Code], PhonicDefs USING [Phonics], CreateLookupDictDefs, Heap USING [Create, Delete], Put USING [Text, Line, Decimal], Stream USING [Block, CompletionCode, Handle, PutByte, PutWord, GetBlock, SetPosition], Space USING [PageCount], Window USING [Handle]; CreateLookupImpl: PROGRAM IMPORTS Stream, Heap, Put EXPORTS CreateLookupDictDefs = BEGIN -- Constants Onesbyte: CARDINAL = 377B; nullPhonic: CharDefs.Code = PhonicDefs.Phonics[nullPhonic].ORD; MaxEntries : CARDINAL = 134; -- Variables mEntry: CESDictDataDefs.Entry; nullPtr: JLispLookupFile.DictPtr _ [0, , 0]; pMEntry: LONG POINTER TO CESDictDataDefs.Entry _ @mEntry; inBlock: Stream.Block _ [LOOPHOLE [LONG[@mEntry]], 0, CESDictDataDefs.DictBytesPerEntry]; nBytes: CARDINAL _ 0; kana0, kana1: CharDefs.Code _ nullPhonic; currentDictPtr, oldDictPtr: JLispLookupFile.DictPtr; kanjiArray: ARRAY [0..JLispLookupFile.MaxKanjiPerEntry) OF CharDefs.Char; nKanjis: CARDINAL _ 0; recsize : CARDINAL _ 0; nKanaCodes : CARDINAL _ 0; KanaCode : PACKED ARRAY [0..JLispLookupFile.MaxKanaPerEntry) OF CharDefs.Code; nOldKana: CARDINAL _ 0; oldKana: PACKED ARRAY [0..JLispLookupFile.MaxKanaPerEntry) OF CharDefs.Code; nLEntries : CARDINAL _ 0; pLEntry : ARRAY [0 .. MaxEntries] OF LONG POINTER TO JLispLookupFile.LEntry; myZone: UNCOUNTED ZONE; zoneSize: Space.PageCount = 200; firstTime: BOOLEAN; why: Stream.CompletionCode; -- Create is the Main Line of this module CreateLookupDict: PUBLIC PROCEDURE [masterStrH: Stream.Handle, lookupStrH: Stream.Handle, indexStrH: Stream.Handle, msgSW, logSW: Window.Handle] RETURNS [nEntry, ctSkipped: LONG CARDINAL] = BEGIN -- Initialize initializes the index table (first part) of the lookup dictionary Initialize: PROCEDURE[] = BEGIN myZone _ Heap.Create[initial: zoneSize, increment: 10, threshold: 16, checking: TRUE]; KanaCode _ ALL [nullPhonic]; -- KanaCode[0] _ PhonicDefs.Phonics[hirSmallA].ORD; kana0 _ nullPhonic; kana1 _ nullPhonic; nLEntries _ 0; pLEntry _ ALL [NIL]; recsize _ 0; currentDictPtr.dictPageNo _ 0; currentDictPtr.relAddr _ 1; oldDictPtr _ currentDictPtr; InitIndex[]; Stream.SetPosition[indexStrH, LONG[0] ]; Stream.PutWord[lookupStrH, 0]; firstTime _ TRUE; END; -- InitIndex InitIndex: PROCEDURE[] = BEGIN i, j: LONG CARDINAL; Stream.SetPosition[indexStrH, LONG[0]]; FOR i IN [PhonicDefs.Phonics[hirSmallA].ORD .. PhonicDefs.Phonics[hirN].ORD] DO FOR j IN [nullPhonic .. PhonicDefs.Phonics[hirN].ORD] DO OutputDictPtr[indexStrH, nullPtr]; ENDLOOP; ENDLOOP; END; -- AddEntry AddEntry: PROCEDURE [pMEntry: LONG POINTER TO CESDictDataDefs.Entry] = BEGIN ConvertNullPhonic[pMEntry]; IF EqKana[KanaCode, pMEntry.kana] THEN SameRecord[pMEntry] ELSE DifferentRecord[pMEntry]; END; -- ConvertNullPhonic ConvertNullPhonic: PROCEDURE [pMEntry: LONG POINTER TO CESDictDataDefs.Entry] = BEGIN i: CARDINAL; FOR i IN [0..JLispLookupFile.MaxKanaPerEntry) DO IF pMEntry.kana[i] = Onesbyte THEN pMEntry.kana[i] _ nullPhonic; ENDLOOP; END; -- EqKana EqKana: PROCEDURE[kana1, kana2: PACKED ARRAY [0..JLispLookupFile.MaxKanaPerEntry) OF CharDefs.Code] RETURNS[BOOLEAN] = BEGIN i: CARDINAL; FOR i IN [0..JLispLookupFile.MaxKanaPerEntry) DO IF kana1[i] # kana2[i] THEN RETURN[FALSE]; IF kana1[i] = nullPhonic THEN RETURN[TRUE]; ENDLOOP; RETURN[TRUE] END; -- SameRecord SameRecord: PROCEDURE [pMEntry: LONG POINTER TO CESDictDataDefs.Entry] = BEGIN nWords, i: CARDINAL; IF nLEntries >= MaxEntries THEN { Put.Text[logSW, "Entry table overflow: "L]; FOR i IN [0 .. nKanaCodes-1) DO Put.Decimal[logSW, KanaCode[i]]; Put.Text[logSW, ", "] ENDLOOP; Put.Decimal[logSW, KanaCode[nKanaCodes-1]]; Put.Line[logSW, " "L] } ELSE { [nWords, pLEntry[nLEntries]] _ ConvertEntry[pMEntry]; nLEntries _ nLEntries + 1; recsize _ recsize + nWords; nEntry _ nEntry + 1 }; END; -- ConvertEntry ConvertEntry: PROCEDURE [pMEntry: LONG POINTER TO CESDictDataDefs.Entry] RETURNS [nWords: CARDINAL, pLEntry: LONG POINTER TO JLispLookupFile.LEntry] = BEGIN i: CARDINAL; nKanjis _ 0; FOR i IN [0..JLispLookupFile.MaxKanjiPerEntry) DO kanjiArray[i] _ pMEntry.kanji[i]; IF kanjiArray[i].code # Onesbyte THEN nKanjis _ i + 1; ENDLOOP; pLEntry _ myZone.NEW[JLispLookupFile.LEntry[nKanjis]]; pLEntry^.nKanjis _ nKanjis; pLEntry^.pos _ pMEntry^.pos; pLEntry^.pre _ 1; pLEntry^.freq _ pMEntry^.freq; FOR i IN [0..nKanjis) DO pLEntry^.kanji[i] _ pMEntry.kanji[i] ENDLOOP; nWords _ nKanjis + 3; RETURN [nWords, pLEntry]; END; -- DifferentRecord DifferentRecord: PROCEDURE [pMEntry: LONG POINTER TO CESDictDataDefs.Entry] = BEGIN nWords: CARDINAL; IF firstTime THEN firstTime _ FALSE ELSE OutputPrevRecord[]; SetupKanaCodes[pMEntry]; ClearAllLEntries[]; nLEntries _ 1; [nWords, pLEntry[0]] _ ConvertEntry[pMEntry]; recsize _ nWords + CeilQuotient[nKanaCodes, 2] + 3; -- for recsize(1), nKanaCodes(1), and nLEntries(1) nEntry _ nEntry + 1; END; -- OutputPrevRecord OutputPrevRecord: PROCEDURE = BEGIN i: CARDINAL; Stream.PutWord[lookupStrH, recsize]; Stream.PutWord[lookupStrH, nKanaCodes]; FOR i IN [0..nKanaCodes) DO Stream.PutByte[lookupStrH, KanaCode[i]] ENDLOOP; IF nKanaCodes MOD 2 # 0 THEN Stream.PutByte[lookupStrH, nullPhonic]; Stream.PutWord[lookupStrH, nLEntries]; FOR i IN [0..nLEntries) DO OutputEntry[ pLEntry[i] ]; ENDLOOP; -- OutputDictPtr[lookupStrH, nullPtr]; AdvancePtr[recsize]; END; -- OutputEntry OutputEntry: PROCEDURE[pLEntry: LONG POINTER TO JLispLookupFile.LEntry] = BEGIN i: CARDINAL; Stream.PutWord[lookupStrH, pLEntry.nKanjis]; FOR i IN [0..pLEntry.nKanjis) DO Stream.PutByte[lookupStrH, pLEntry.kanji[i].chset]; Stream.PutByte[lookupStrH, pLEntry.kanji[i].code] ENDLOOP; Stream.PutByte[lookupStrH, pLEntry.pos]; Stream.PutByte[lookupStrH, pLEntry.pre]; Stream.PutByte[lookupStrH, pLEntry.freq]; Stream.PutByte[lookupStrH, pLEntry.reserved]; END; -- OutputDictPtr OutputDictPtr: PROCEDURE [strH: Stream.Handle, aDictPtr: JLispLookupFile.DictPtr] = BEGIN Stream.PutWord[strH, aDictPtr.dictPageNo]; Stream.PutByte[strH, aDictPtr.padding]; Stream.PutByte[strH, aDictPtr.relAddr]; END; -- AdvancePtr AdvancePtr: PROCEDURE[adv: CARDINAL] = BEGIN temp: CARDINAL; temp _ CARDINAL[currentDictPtr.relAddr] + adv; currentDictPtr.dictPageNo _ currentDictPtr.dictPageNo + temp/256; currentDictPtr.relAddr _ temp MOD 256; END; -- ClearAllLEntries ClearAllLEntries: PROCEDURE = BEGIN i: CARDINAL; FOR i IN [0.. nLEntries) DO myZone.FREE[ @pLEntry[i] ]; ENDLOOP; END; -- SetupKanaCodes SetupKanaCodes: PROCEDURE [pMEntry: LONG POINTER TO CESDictDataDefs.Entry] = BEGIN i: CARDINAL; nOldKana _ nKanaCodes; FOR i IN [0..JLispLookupFile.MaxKanaPerEntry) DO oldKana[i] _ KanaCode[i] ENDLOOP; FOR i IN [0..JLispLookupFile.MaxKanaPerEntry) DO KanaCode[i] _ pMEntry.kana[i]; IF KanaCode[i] # nullPhonic THEN nKanaCodes _ i + 1 ENDLOOP; IF KanaCode[0] # kana0 OR KanaCode[1] # kana1 THEN { NewIndex[KanaCode[0], KanaCode[1]]; oldDictPtr _ currentDictPtr; kana0 _ KanaCode[0]; kana1 _ KanaCode[1]} END; -- NewIndex NewIndex: PROCEDURE [kana0, kana1: CharDefs.Code] = BEGIN position: LONG CARDINAL; IF kana0 = nullPhonic AND kana1 = nullPhonic THEN RETURN; position _ ((kana0-1)*(PhonicDefs.Phonics[hirN].ORD + 1) + kana1)*4; -- position _ ((kana0-1)*84 + kana1)*4; Stream.SetPosition[indexStrH, position]; OutputDictPtr[indexStrH, currentDictPtr]; END; LastEntry: PROCEDURE [pMEntry: LONG POINTER TO CESDictDataDefs.Entry] = BEGIN OutputPrevRecord[]; -- NewIndex[kana0, kana1]; ClearAllLEntries[]; END; -- CeilQuotient CeilQuotient: PROCEDURE [x, y: CARDINAL] RETURNS[CARDINAL] = BEGIN IF x MOD y = 0 THEN RETURN[x/y] ELSE RETURN[x/y+1] END; -- main line of Create Initialize[]; nEntry _ 1; DO [nBytes, why] _ Stream.GetBlock[masterStrH, inBlock]; IF why = endOfStream THEN { LastEntry[pMEntry]; EXIT }; IF pMEntry.pos >= 1 AND pMEntry.pos <= 60B AND (pMEntry.kanji[1].code.ORD = Onesbyte OR pMEntry.freq >= 4) THEN AddEntry[pMEntry]; ENDLOOP; Heap.Delete[myZone,TRUE]; RETURN[nEntry, 0]; END; -- of Create END.