-- 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.