(FILECREATED " 3-Jun-88 17:03:38" {QV}<DICT>TOOLS>ANALYZER.;119 62229 changes to: (VARS ANALYZERCOMS Analyzer.DefaultStream) (FNS AnalyzerForStream TEdit.SetAnalyzer) previous date: " 4-Feb-88 08:58:45" {QV}<DICT>TOOLS>ANALYZER.;117) (* Copyright (c) 1985, 1986, 1987, 1988 by Xerox Corporation. All rights reserved.) (PRETTYCOMPRINT ANALYZERCOMS) (RPAQQ ANALYZERCOMS [(COMS (* * THE ANALYZER CLASS) (RECORDS Morphalyzer) (* renamed record to avoid a conflict.) (MACROS Analyzer.Open Analyzer.Close Analyzer.Corrections Analyzer.Proofread Analyzer.Analyze Analyzer.Lookup Analyzer.FindWord Analyzer.AddEntry) (* MACROS that call apply the methods of the analyzer class.) (FNS AnalyzerFromName Analyzer.CountWords Analyzer.DefaultCorrections Analyzer.DefaultNextWord Analyzer.Name Analyzer.DefaultAddEntry Analyzer.DefaultAnalyze Analyzer.DefaultProofread) (* Functions implementing the default case for various methods of the analyzer class.) (FNS Analyzer.DefaultLoadWordList Analyzer.DefaultStoreWordList Analyzer.ReadWordList Analyzer.WriteWordList CREATEWORDLISTRDTBL) (INITVARS WORDLISTRDTBL) (FNS Analyzer.Prop Analyzer.PushProp) (MACROS Analyzer.AlphaCharP \Analyzer.TestCorruption Analyzer.Capitalization Analyzer.UCaseP) (* Service MACROS.) (FNS STREAM.FETCHSTRING) (MACROS Stream.Init Stream.NextChar) (FNS Analyzer.CorruptWord) (GLOBALVARS WORDLISTRDTBL)) [COMS (* * TEDIT interface to analyzer.) (FNS Analyzer.Establish AnalyzerForStream Analyzer.QuitFn Analyzer.BeforeLogout) (FNS TEdit.ProofreadMenu WITH-TEDIT TEdit.Correct TEdit.CountWords TEdit.AddEntry TEdit.Proofread TEdit.SetAnalyzer TEdit.LoadWordList TEdit.StoreWordList Analyzer.TEditMenuItems) (INITVARS Analyzer.List Proofreader.AutoCorrect Analyzer.DefaultStream (Proofreader.AutoDelete T) (Proofreader.MenuEdge (QUOTE LEFT)) Analyzer.TimeProofreader Proofreader.UserFns) (GLOBALVARS Analyzer.List Proofreader.AutoCorrect Analyzer.DefaultStream Proofreader.AutoDelete Proofreader.MenuEdge Analyzer.TimeProofreader Proofreader.UserFns) (P (Analyzer.TEditMenuItems) (push BEFORELOGOUTFORMS (QUOTE (Analyzer.BeforeLogout] (COMS (* * THE Dict CLASS) (RECORDS Dict) (MACROS Dict.Open Dict.Close Dict.GetEntry Dict.PutEntry Dict.PrintEntry Dict.MapEntries) (* * utility functions) (FNS DictFromName Dict.Establish Dict.Prop Dict.Name) (INITVARS Dict.DictionaryList) (GLOBALVARS Dict.DictionaryList) (* * a simple dictionary.) (FNS SimpleDict.New SimpleDict.PutEntry SimpleDict.Lookup SimpleDict.MapEntries SimpleDict.PrintEntries SimpleDict.Test) (RECORDS SimpleDict.Node)) (COMS (* * the INVERTEDDICT class) (RECORDS INVERTEDDICT) (FNS InvertedDictFromName InvertedDict.Establish InvertedDict.Prop InvertedDict.Name InvertedDict.Open) (INITVARS InvertedDict.List) (GLOBALVARS InvertedDict.List)) (DECLARE: DONTEVAL@LOAD DOEVAL@COMPILE DONTCOPY COMPILERVARS (ADDVARS (NLAMA) (NLAML) (LAMA InvertedDict.Prop Dict.Prop Analyzer.Prop]) (* * THE ANALYZER CLASS) [DECLARE: EVAL@COMPILE (DATATYPE Morphalyzer (analyzerName grammar index analyzerProps openFn closeFn proofreadFn analyzeFn lookupFn correctionsFn generateFn conjugateFn findWordFn addEntryFn) openFn ←(FUNCTION NILL) closeFn ←(FUNCTION NILL) proofreadFn ←(FUNCTION Analyzer.DefaultProofread) analyzeFn ←(FUNCTION Analyzer.DefaultAnalyze) lookupFn ←(FUNCTION NILL) correctionsFn ←(FUNCTION Analyzer.DefaultCorrections) generateFn ←(FUNCTION NILL) conjugateFn ←(FUNCTION NILL) findWordFn ←(FUNCTION NILL) addEntryFn ←(FUNCTION Analyzer.DefaultAddEntry)) ] (/DECLAREDATATYPE (QUOTE Morphalyzer) (QUOTE (POINTER POINTER POINTER POINTER POINTER POINTER POINTER POINTER POINTER POINTER POINTER POINTER POINTER POINTER)) (QUOTE ((Morphalyzer 0 POINTER) (Morphalyzer 2 POINTER) (Morphalyzer 4 POINTER) (Morphalyzer 6 POINTER) (Morphalyzer 8 POINTER) (Morphalyzer 10 POINTER) (Morphalyzer 12 POINTER) (Morphalyzer 14 POINTER) (Morphalyzer 16 POINTER) (Morphalyzer 18 POINTER) (Morphalyzer 20 POINTER) (Morphalyzer 22 POINTER) (Morphalyzer 24 POINTER) (Morphalyzer 26 POINTER))) (QUOTE 28)) (* renamed record to avoid a conflict.) (DECLARE: EVAL@COMPILE (PUTPROPS Analyzer.Open MACRO ((analyzer) (APPLY* (fetch (Morphalyzer openFn) of analyzer) analyzer))) (PUTPROPS Analyzer.Close MACRO ((analyzer) (APPLY* (fetch (Morphalyzer closeFn) of analyzer)))) (PUTPROPS Analyzer.Corrections MACRO ((analyzer stream loc len) (* * returns a list of possible corrections for the string starting at "loc" that is "len" characters long.) (APPLY* (fetch (Morphalyzer correctionsFn) of analyzer) analyzer stream loc len))) (PUTPROPS Analyzer.Proofread MACRO ((analyzer stream start length prFn) (* * The user interface to Analyzer.Analyze.) (APPLY* (fetch (Morphalyzer proofreadFn) of analyzer) analyzer stream start length prFn))) (PUTPROPS Analyzer.Analyze MACRO ((analyzer stream fromLoc toLoc analFn) (* * break up the stream into legal lexical items. call analFn (analyzer stream start len entries) on each item, where "entries" is the analysis of that item. If "entries" is NIL, then the item could not be analyzed.) (APPLY* (fetch (Morphalyzer analyzeFn) of analyzer) analyzer stream fromLoc toLoc analFn))) (PUTPROPS Analyzer.Lookup MACRO ((analyzer stream fromLoc toLoc) (* * Look up the substring of stream between fromLoc and toLoc in dict. "stream" can be a stream, a string, or a list of characters.) (APPLY* (fetch (Morphalyzer lookupFn) of analyzer) analyzer stream fromLoc toLoc))) (PUTPROPS Analyzer.FindWord MACRO ((analyzer word stream start length) (APPLY* (fetch (Morphalyzer findWordFn) of analyzer) analyzer word stream start length))) (PUTPROPS Analyzer.AddEntry MACRO ((analyzer lemma entry dontRecord errorStream) (* * add lemma to the dictionary with entry "entry". If dontRecord is non-NIL, don't worry about keeping track of this word for the word list.) (APPLY* (fetch (Morphalyzer addEntryFn) of analyzer) analyzer lemma entry dontRecord errorStream))) ) (* MACROS that call apply the methods of the analyzer class.) (DEFINEQ (AnalyzerFromName [LAMBDA (dictName remoteName) (* jtm: "13-Oct-87 10:44") (* * find the analyzer corresponding to the dictionary.) (PROG (analyzer) [COND ((NULL dictName) (SETQ analyzer (CAR Analyzer.List))) ((for i in Analyzer.List do (COND ([AND (EQ dictName (fetch (Morphalyzer analyzerName) of i)) (EQ remoteName (Analyzer.Prop i (QUOTE RemoteDict] (SETQ analyzer i) (RETURN T] (RETURN analyzer]) (Analyzer.CountWords [LAMBDA (analyzer stream start length) (* jtm: "13-Nov-86 13:32") (LET [(n 0) (FN (Analyzer.Prop analyzer (QUOTE CountWords] (COND (FN (APPLY* FN analyzer stream start length)) (T (Analyzer.Analyze analyzer stream start length (FUNCTION [LAMBDA (analyzer stream start length entries) (add n 1) NIL])) n]) (Analyzer.DefaultCorrections [LAMBDA (analyzer stream start length) (* jtm: " 7-Apr-87 08:23") (* * returns a list of possible spelling corrections for the given word.) (PROG [form word wordList caps periods (userDict (Analyzer.Prop analyzer (QUOTE UserDict] [COND [(STREAMP stream) (SETFILEPTR stream start) (SETQ word (for i from 1 to length collect (BIN stream] ((STRINGP stream) (SETQ word (for i from 1 to (NCHARS stream) collect (NTHCHARCODE stream i] (SETQ caps (Analyzer.Capitalization word)) (SETQ periods (FMEMB (CHARCODE %.) word)) (* * first try transpositions) (for tail temp on word while (CDR tail) do (SETQ temp (CAR tail)) (RPLACA tail (CADR tail)) (RPLACA (CDR tail) temp) (COND ((AND (EQ caps (QUOTE FIRST)) (EQ tail word)) (* don't transpose the first letters of a capitalized word.) NIL) (T (\Analyzer.TestCorruption analyzer word wordList userDict))) (RPLACA (CDR tail) (CAR tail)) (RPLACA tail temp)) (* * next try deletions) (COND ((CDR word) (\Analyzer.TestCorruption analyzer (CDR word) wordList userDict))) (for tail temp on word while (CDR tail) do (SETQ temp (CDR tail)) (RPLACD tail (CDDR tail)) (\Analyzer.TestCorruption analyzer word wordList userDict) (RPLACD tail temp)) (* * prepend a character.) (SETQ word (CONS (CHARCODE A) word)) (SELECTQ caps (FIRST (* don't prepend a character before a capitalized word.) NIL) (ALL (* prepend a capital letter.) (for c from (CHARCODE A) to (CHARCODE Z) do (RPLACA word c) (\Analyzer.TestCorruption analyzer word wordList userDict))) (for c from (CHARCODE a) to (CHARCODE z) do (RPLACA word c) (\Analyzer.TestCorruption analyzer word wordList userDict))) (SETQ word (CDR word)) (* * insert characters.) (for tail on word do (RPLACD tail (CONS (CHARCODE A) (CDR tail))) [COND ((EQ caps (QUOTE ALL)) (for c from (CHARCODE A) to (CHARCODE Z) do (RPLACA (CDR tail) c) (\Analyzer.TestCorruption analyzer word wordList userDict))) (T (for c from (CHARCODE a) to (CHARCODE z) do (RPLACA (CDR tail) c) (\Analyzer.TestCorruption analyzer word wordList userDict] (COND (periods (RPLACA (CDR tail) (CHARCODE %.)) (\Analyzer.TestCorruption analyzer word wordList userDict))) (RPLACD tail (CDDR tail))) (* * replace characters) (for tail temp on word do (SETQ temp (CAR tail)) [COND ((OR (EQ caps (QUOTE ALL)) (AND (EQ caps (QUOTE FIRST)) (EQ tail word))) (for c from (CHARCODE A) to (CHARCODE Z) do (COND ((NEQ temp c) (RPLACA tail c) (\Analyzer.TestCorruption analyzer word wordList userDict] [COND ((OR (EQ caps NIL) (NOT (ALPHACHARP (CHCON1 temp))) (AND (EQ caps (QUOTE FIRST)) (NEQ tail word))) (for c from (CHARCODE a) to (CHARCODE z) do (COND ((NEQ temp c) (RPLACA tail c) (\Analyzer.TestCorruption analyzer word wordList userDict] (COND (periods (RPLACA tail (CHARCODE %.)) (\Analyzer.TestCorruption analyzer word wordList userDict))) (RPLACA tail temp)) (SETQ wordList (SORT wordList)) [for i on wordList do (while (STREQUAL (CAR i) (CADR i)) do (RPLACD i (CDDR i] (RETURN wordList]) (Analyzer.DefaultNextWord [LAMBDA (analyzer stream startPtr searchLength NWFn) (* jtm: "29-Oct-85 15:23") (* * Scans the stream looking for a word, i.e. a sequence of alphabetic charqacters. If the file ptr is already in the middle of such a sequence, it backs up to the beginning of that sequence. The function applies NWFn to (stream start stop) for each such word.) (SETFILEPTR stream (OR startPtr (SETQ startPtr 0))) (bind char end endPtr word length start value quote (filePtr ←(GETFILEPTR stream)) (EOFPtr ←(GETEOFPTR stream)) first (SETQ endPtr (COND (searchLength (IPLUS startPtr searchLength)) (T EOFPtr))) (OR (ILEQ endPtr EOFPtr) (SETQ endPtr EOFPtr)) do (SETQ char (AND (ILESSP (GETFILEPTR stream) endPtr) (BIN stream))) (COND [(AND char (AND (NUMBERP char) (ILESSP char 128) (Analyzer.AlphaCharP char))) (OR start (SETQ start (SUB1 (GETFILEPTR stream] (start (SETQ end (GETFILEPTR stream)) (SETQ length (IDIFFERENCE end start)) (AND char (add length -1)) (* back up to the last legal char.) [COND (NWFn (SETQ value (APPLY* NWFn analyzer stream start length] (COND ((OR (NULL NWFn) (EQ value T)) (RETURN (CONS start length))) (value (RETURN value))) (SETFILEPTR stream end) (SETQ start NIL))) (OR char (RETURN]) (Analyzer.Name [LAMBDA (analyzer) (* jtm: "13-Oct-87 10:44") (COND [(Analyzer.Prop analyzer (QUOTE RemoteDict)) (MKATOM (CONCAT (fetch (Morphalyzer analyzerName) of analyzer) ": " (Analyzer.Prop analyzer (QUOTE RemoteDict] (T (fetch (Morphalyzer analyzerName) of analyzer]) (Analyzer.DefaultAddEntry [LAMBDA (analyzer lemma entry dontRecord errorStream) (* jtm: " 7-Apr-87 07:57") (LET [(userDict (Analyzer.Prop analyzer (QUOTE UserDict] (COND ((NULL userDict) (SETQ userDict (SimpleDict.New)) (Analyzer.Prop analyzer (QUOTE UserDict) userDict))) (Dict.PutEntry userDict lemma entry) (COND ((NOT dontRecord) (Analyzer.PushProp analyzer (QUOTE WordList) lemma))) lemma]) (Analyzer.DefaultAnalyze [LAMBDA (analyzer stream startPtr searchLength NWFn) (* jtm: "15-Apr-87 10:55") (* * Scans the stream looking for a word, i.e. a sequence of alphabetic charqacters. If the file ptr is already in the middle of such a sequence, it backs up to the beginning of that sequence. The function applies NWFn to (stream start stop) for each such word.) [COND ((STRINGP stream) (SETQ stream (OPENSTRINGSTREAM stream] (SETFILEPTR stream (OR startPtr (SETQ startPtr 0))) (bind char end endPtr length start lookup number initialQuote seprs (userDict ←(Analyzer.Prop analyzer (QUOTE UserDict))) [optSeprCodes ←(OR (Analyzer.Prop analyzer (QUOTE OPT-SEPR-CODES)) (QUOTE (39 46 45 47] (addAlphaCharCodes ←(Analyzer.Prop analyzer (QUOTE ADD-ALPHA-CHAR-CODES))) (word ←(ALLOCSTRING 100 32)) (i ← startPtr) first (DECLARE (LOCALVARS . T)) [SETQ endPtr (COND (searchLength (IMIN (GETEOFPTR stream) (IPLUS startPtr searchLength))) (T (GETEOFPTR stream] do (SETQ char (AND (add i 1) (ILEQ i endPtr) (BIN stream))) (COND ((AND start (NUMBERP char) (ILESSP char 128)) (RPLCHARCODE word (IDIFFERENCE i start) char))) [COND [(AND char (OR (AND (NUMBERP char) (ILESSP char 128) (Analyzer.AlphaCharP char)) (FMEMB char addAlphaCharCodes))) (COND ((NULL start) [COND (number (SETQ start (IDIFFERENCE i 2)) (* we have a number followed by some characters. (e.g. 7th, 21st, etc.) Take in the last digit of the number.) (RPLCHARCODE word 1 number) (SETQ number NIL)) (T (SETQ start (SUB1 i] (RPLCHARCODE word (IDIFFERENCE i start) char] [(AND char (NUMBERP char) (IGEQ char 48) (ILEQ char 57)) (* a number) (COND ((NULL start) (SETQ number char) (SETQ initialQuote NIL)) (T (RPLCHARCODE word (IDIFFERENCE i start) char] ((AND start char (FMEMB char optSeprCodes)) (* optSeprCodes may or may not be a part of the word.) (push seprs i)) [start (* AND char (add length -1)) (* back up to the last legal char.) (* * find the longest string of characters seperated by seprs that the analyzer accepts.) (COND ((NULL seprs) (SETQ seprs i)) (T (push seprs i))) [for stop inside seprs do (SETQ length (SUB1 (IDIFFERENCE stop start))) (COND ([SETQ lookup (OR (Analyzer.Lookup analyzer word 0 length) (AND userDict (SimpleDict.Lookup userDict word length] (RETURN)) ((AND initialQuote (EQP length 1) (EQ (NTHCHARCODE word 1) (CHARCODE s))) (SETQ lookup (QUOTE possessive)) (RETURN] (* * apply NWFn and return its value if non-NIL.) (COND ((AND (NULL NWFn) (NEQ lookup (QUOTE possessive))) (RETURN (CONS start length))) ((AND (NEQ lookup (QUOTE possessive)) (SETQ lookup (APPLY* NWFn analyzer stream start length lookup))) (RETURN lookup)) (T (COND ((NEQ i (IPLUS start length 1)) (* we regressed.) (SETQ i (IPLUS start length)) (* don't add 1 so that we will see the quote and initialQuote will get set ("time's")) (SETFILEPTR stream i) (* set char to T to prevent the RETURN at the end of the loop.) (SETQ char T))) (SETQ start NIL) (SETQ seprs NIL) (SETQ initialQuote NIL] (T (SETQ number NIL) (SETQ initialQuote (EQ char (CHARCODE '] (OR char (RETURN]) (Analyzer.DefaultProofread [LAMBDA (analyzer stream begin length) (* jtm: "16-Dec-87 13:07") (PROG (start.length correction startTime stopTime char (n 0)) (TEDIT.PROMPTPRINT stream "Proofreading . . . " T) (* * initialize and back up to the beginning of a word.) (SETQ startTime (CLOCK 0)) (Stream.Init stream begin length) [COND ((NEQ length 0) (while (AND (NUMBERP (SETQ char (BIN stream))) (ALPHACHARP char)) do (COND ((EQUAL begin 0) (RETURN)) (T (add begin -1) (add length 1) (SETFILEPTR stream begin] (* * look for the next spelling error.) [while [SETQ start.length (Analyzer.Analyze analyzer stream begin length (FUNCTION (LAMBDA (analyzer stream start length entries) (add n 1) (COND ((NULL entries) (CONS start length] do (* * start.length is a CONS pair of locations delimiting an unrecognizable word. Set the selection to it and display it.) [COND ((AND Proofreader.UserFns (for fn (word ←(STREAM.FETCHSTRING stream (CAR start.length) (CDR start.length))) inside Proofreader.UserFns thereis (APPLY* fn word))) (SETQ correction (QUOTE *SKIP*))) (T (TEDIT.SETSEL stream (ADD1 (CAR start.length)) (CDR start.length) (QUOTE RIGHT) T) (TEDIT.SHOWSEL stream NIL) (TEDIT.NORMALIZECARET stream) (TEDIT.SHOWSEL stream T) (COND ([NOT (AND Proofreader.AutoCorrect (SETQ correction (TEdit.Correct stream analyzer T] (RETURN] (COND [(FMEMB correction (QUOTE (*SKIP* *INSERT*))) [add length (IDIFFERENCE begin (IPLUS (CAR start.length) (CDR start.length] (SETQ begin (IPLUS (CAR start.length) (CDR start.length] ((STRINGP correction) (add length (IDIFFERENCE begin (CAR start.length))) (* move start point.) (add length (IDIFFERENCE (NCHARS correction) (CDR start.length))) (* adjust for correction.) (SETQ begin (CAR start.length))) (T (SHOULDNT] (SETQ stopTime (CLOCK 0)) (COND (Analyzer.TimeProofreader (TEDIT.PROMPTPRINT stream (CONCAT "Elapsed Time: " (QUOTIENT (DIFFERENCE stopTime startTime) 1000.0) " seconds."))) (start.length (TEDIT.PROMPTPRINT stream "Error found.")) (T (* (ADD1 (GETEOFPTR stream))) (TEDIT.SETSEL stream (IPLUS begin length 1) 0 (QUOTE RIGHT)) (TEDIT.SHOWSEL stream NIL) (TEDIT.NORMALIZECARET stream) (TEDIT.SHOWSEL stream T) (TEDIT.PROMPTPRINT stream (COND ((EQUAL n 0) "No Errors.") (T (CONCAT n " words proofread."))) T]) ) (* Functions implementing the default case for various methods of the analyzer class.) (DEFINEQ (Analyzer.DefaultLoadWordList [LAMBDA (analyzer file) (* jtm: "17-Sep-86 09:39") (* * adds a word list to the given analyzer.) (PROG (wordList) (SETQ wordList (Analyzer.ReadWordList file)) (for i in wordList do (Analyzer.AddEntry analyzer i T T)) (Analyzer.PushProp analyzer (QUOTE WordListFile) file]) (Analyzer.DefaultStoreWordList [LAMBDA (analyzer file) (* jtm: "23-Sep-86 09:08") (* * adds the current word list to the remote file.) (PROG (wordList) (SETQ wordList (Analyzer.Prop analyzer (QUOTE WordList))) [COND ((DIRECTORY file) (SETQ wordList (APPEND wordList (Analyzer.ReadWordList file] (Analyzer.WriteWordList wordList file) (Analyzer.PushProp analyzer (QUOTE WordListFile) file) (Analyzer.Prop analyzer (QUOTE WordList) NIL]) (Analyzer.ReadWordList [LAMBDA (file) (* jtm: "17-Sep-86 10:56") (PROG (firstWord words stream) (SETQ stream (OPENSTREAM file (QUOTE INPUT))) (SETFILEPTR stream 0) (SETQ firstWord (READ stream)) (SETFILEPTR stream 0) (COND [(LISTP firstWord) (* old style format.) (RETURN (CDR (READFILE stream] (T (* new style format) [COND ((NULL WORDLISTRDTBL) (SETQ WORDLISTRDTBL (CREATEWORDLISTRDTBL] (while (SKIPSEPRCODES stream WORDLISTRDTBL) do (push words (RSTRING stream WORDLISTRDTBL))) (CLOSEF stream) (RETURN words]) (Analyzer.WriteWordList [LAMBDA (wordList file) (* jtm: "17-Sep-86 10:11") (PROG (stream) (SETQ stream (OPENSTREAM file (QUOTE OUTPUT))) (SETFILEPTR stream 0) (for word in wordList do (printout stream word T)) (CLOSEF stream]) (CREATEWORDLISTRDTBL [LAMBDA NIL (* jtm: "17-Sep-86 10:55") (LET (RDTBL) (SETQ RDTBL (COPYREADTABLE (QUOTE ORIG))) (for SEPR in (GETSEPR RDTBL) do (SETSYNTAX (CHARACTER SEPR) (QUOTE OTHER) RDTBL)) (for BREAK in (GETBRK RDTBL) do (SETSYNTAX (CHARACTER BREAK) (QUOTE OTHER) RDTBL)) (SETSYNTAX (CHARACTER (CHARCODE CR)) (QUOTE SEPR) RDTBL) RDTBL]) ) (RPAQ? WORDLISTRDTBL NIL) (DEFINEQ (Analyzer.Prop [LAMBDA a (* jtm: "13-Oct-87 11:54") (LET (p (analyzer (ARG a 1)) (prop (ARG a 2))) (SETQ p (FASSOC prop (fetch (Morphalyzer analyzerProps) of analyzer))) (COND ((ILEQ a 2) (CDR p)) [p (PROG1 (CDR p) (RPLACD p (ARG a 3] (T (CDAR (push (fetch (Morphalyzer analyzerProps) of analyzer) (CONS prop (ARG a 3]) (Analyzer.PushProp [LAMBDA (analyzer prop value) (* jtm: "13-Oct-87 10:59") (* * pushes value onto a list of values stored at prop.) (LET [(prop.values (FASSOC prop (fetch (Morphalyzer analyzerProps) of analyzer] (COND [(NULL prop.values) (push (fetch (Morphalyzer analyzerProps) of analyzer) (CONS prop (LIST value] ((NOT (for i in (CDR prop.values) thereis (EQUAL i value))) (push (CDR prop.values) value))) value]) ) (DECLARE: EVAL@COMPILE (PUTPROPS Analyzer.AlphaCharP MACRO [(CHAR) (OR (EQ (LRSH CHAR 8) 241) ([LAMBDA (UCHAR) (DECLARE (LOCALVARS UCHAR)) (OR (EQ (LRSH UCHAR 8) 241) (AND (IGEQ UCHAR (CHARCODE A)) (ILEQ UCHAR (CHARCODE Z] (LOGAND CHAR 95]) (PUTPROPS \Analyzer.TestCorruption MACRO [(analyzer word wordList userDict) (COND ((OR (Analyzer.Lookup analyzer word) (AND userDict (SimpleDict.Lookup userDict word))) (push wordList (CONCATCODES word]) (PUTPROPS Analyzer.Capitalization MACRO [(word) (* * returns NIL, ALL or FIRST) (COND ((AND (CAR word) (Analyzer.UCaseP (CAR word))) (COND ((AND (CADR word) (Analyzer.UCaseP (CADR word))) (QUOTE ALL)) (T (QUOTE FIRST]) (PUTPROPS Analyzer.UCaseP MACRO [(UCHAR) (OR (AND (IGEQ UCHAR (CHARCODE 361,041)) (ILEQ UCHAR (CHARCODE 361,160))) (AND (IGEQ UCHAR (CHARCODE A)) (ILEQ UCHAR (CHARCODE Z]) ) (* Service MACROS.) (DEFINEQ (STREAM.FETCHSTRING [LAMBDA (stream start length buffer restorePtr) (* jtm: " 3-Apr-87 11:28") (LET (pos) [COND (restorePtr (SETQ pos (GETFILEPTR stream] [COND ((OR (NULL buffer) (IGREATERP length (NCHARS buffer))) (SETQ buffer (ALLOCSTRING length] (SETFILEPTR stream start) (for i from 1 to length do (RPLCHARCODE buffer i (BIN stream))) (COND (restorePtr (SETFILEPTR stream pos))) (SUBSTRING buffer 1 length]) ) (DECLARE: EVAL@COMPILE (PUTPROPS Stream.Init MACRO [(stream start length) (COND [(STRINGP stream) (OR start (SETQ start 0)) (OR length (SETQ length (NCHARS stream] ((NOT (LISTP stream)) (COND ((NULL start) (SETQ start 0))) [COND ((NULL length) (SETQ length (IDIFFERENCE (GETEOFPTR stream) start] (SETFILEPTR stream start]) (PUTPROPS Stream.NextChar MACRO [(stream length index) (COND ((LISTP stream) (pop stream)) ((OR (NULL stream) (ILEQ length 0)) NIL) ((STRINGP stream) (add length -1) (add index 1) (NTHCHARCODE stream index)) (T (add length -1) (BIN stream]) ) (DEFINEQ (Analyzer.CorruptWord [LAMBDA (analyzer stream start length) (* jtm: " 5-Feb-87 11:23") (* * returns a list of possible spelling corrections for the given word.) (PROG (form word wordList caps) (SETQ word (for i from 1 to length collect (BIN stream))) (SETQ caps (Analyzer.Capitalization word)) (* * first try transpositions) (for tail temp on word while (CDR tail) do (SETQ temp (CAR tail)) (RPLACA tail (CADR tail)) (RPLACA (CDR tail) temp) (COND ((AND (EQ caps (QUOTE FIRST)) (EQ tail word)) (* don't transpose the first letters of a capitalized word.) NIL) (T (\Analyzer.TestCorruption analyzer word wordList))) (RPLACA (CDR tail) (CAR tail)) (RPLACA tail temp)) (* * next try deletions) (COND ((CDR word) (\Analyzer.TestCorruption analyzer (CDR word) wordList))) (for tail temp on word while (CDR tail) do (SETQ temp (CDR tail)) (RPLACD tail (CDDR tail)) (\Analyzer.TestCorruption analyzer word wordList) (RPLACD tail temp)) (* * prepend a character.) (SETQ word (CONS (QUOTE A) word)) (SELECTQ caps (FIRST (* don't prepend a character before a capitalized word.) NIL) (ALL (* prepend a capital letter.) (for c from (CHARCODE A) to (CHARCODE Z) do (RPLACA word c) (\Analyzer.TestCorruption analyzer word wordList))) (for c from (CHARCODE a) to (CHARCODE z) do (RPLACA word c) (\Analyzer.TestCorruption analyzer word wordList))) (SETQ word (CDR word)) (* * insert characters.) (for tail on word do (RPLACD tail (CONS (QUOTE A) (CDR tail))) [COND ((EQ caps (QUOTE ALL)) (for c from (CHARCODE A) to (CHARCODE Z) do (RPLACA (CDR tail) c) (\Analyzer.TestCorruption analyzer word wordList))) (T (for c from (CHARCODE a) to (CHARCODE z) do (RPLACA (CDR tail) c) (\Analyzer.TestCorruption analyzer word wordList] (RPLACD tail (CDDR tail))) (* * replace characters) (for tail temp on word do (SETQ temp (CAR tail)) [COND ((OR (EQ caps (QUOTE ALL)) (AND (EQ caps (QUOTE FIRST)) (EQ tail word))) (for c from (CHARCODE A) to (CHARCODE Z) do (RPLACA tail c) (COND ((EQ temp c)) (T (\Analyzer.TestCorruption analyzer word wordList] [COND ((OR (EQ caps NIL) (NOT (ALPHACHARP temp)) (AND (EQ caps (QUOTE FIRST)) (NEQ tail word))) (for c from (CHARCODE a) to (CHARCODE z) do (RPLACA tail c) (COND ((EQ temp (CHARACTER c))) (T (\Analyzer.TestCorruption analyzer word wordList] (RPLACA tail temp)) (SETQ wordList (SORT wordList)) [for i on wordList do (while (STREQUAL (CAR i) (CADR i)) do (RPLACD i (CDR i] (RETURN wordList]) ) (DECLARE: DOEVAL@COMPILE DONTCOPY (GLOBALVARS WORDLISTRDTBL) ) (* * TEDIT interface to analyzer.) (DEFINEQ (Analyzer.Establish [LAMBDA (analyzer) (* jtm: "13-Oct-87 10:44") (AND analyzer (OR (AND (BOUNDP (QUOTE Analyzer.List)) (bind (analyzerName ←(fetch (Morphalyzer analyzerName) of analyzer)) for tail on Analyzer.List when (EQUAL analyzerName (fetch (Morphalyzer analyzerName) of (CAR tail))) do (RPLACA tail analyzer) (RETURN T))) (push Analyzer.List analyzer]) (AnalyzerForStream [LAMBDA (stream) (* jtm: " 3-Jun-88 16:53") (* * comment) (COND ((STREAMPROP stream (QUOTE analyzer))) ((STREAMPROP (OR Analyzer.DefaultStream (SETQ Analyzer.DefaultStream (OPENTEXTSTREAM))) (QUOTE analyzer))) (T (TEdit.SetAnalyzer Analyzer.DefaultStream]) (Analyzer.QuitFn [LAMBDA (window stream textObj) (* jtm: "14-Jan-86 15:58") (* * ask the user if he wants to save the word list.) (PROG ((analyzer (AnalyzerForStream stream))) (COND ((AND analyzer (Analyzer.Prop analyzer (QUOTE WordList)) (STREQUAL "yes" (TEDIT.GETINPUT stream "Do you want to save the word list? " "yes"))) (TEdit.StoreWordList stream]) (Analyzer.BeforeLogout [LAMBDA NIL (* jtm: "13-Oct-87 10:45") (for analyzer file in Analyzer.List do (COND ([AND (Analyzer.Prop analyzer (QUOTE WordList)) (EQ (QUOTE Y) (ASKUSER 10 (QUOTE N) (CONCAT "Do you want to save the word list for " (fetch (Morphalyzer analyzerName) of analyzer) "? "] (COND ([NULL (SETQ file (PROMPTFORWORD "Store word list on file:" (CAR (Analyzer.Prop analyzer (QUOTE WordListFile] (printout T "Aborted.")) (T [RESETLST (printout T (CONCAT "Storing word list on " file "...")) (Analyzer.DefaultStoreWordList analyzer file) (printout T "Deleting old version...") (RESETSAVE (TTYDISPLAYSTREAM (OPENTEXTSTREAM))) (* to swallow up the output of DIRECTORY) (DIRECTORY file (QUOTE (DELVER] (printout T "done."]) ) (DEFINEQ (TEdit.ProofreadMenu [LAMBDA (stream) (* jtm: "30-Mar-87 14:07") (* * TEDIT interface to the current analyzer.) (PROG (menuWindow menu analyzer W) (* COND ((WINDOWPROP W (QUOTE DEFWINDOW)) (* so they don't interfere.) (CLOSEW (WINDOWPROP W (QUOTE DEFWINDOW))))) [SETQ W (CAR (fetch \WINDOW of (TEXTOBJ stream] (SETQ menuWindow (WINDOWPROP W (QUOTE Proofreader.Menu))) (COND ((NULL menuWindow) (SETQ menu (create MENU ITEMS ←(LIST (LIST (QUOTE Proofread) (BQUOTE (WITH-TEDIT , W (FUNCTION TEdit.Proofread))) "looks for the next spelling error starting from the caret.") (LIST (QUOTE Correct) (BQUOTE (WITH-TEDIT , W (FUNCTION TEdit.Correct))) "generates a list of possible corrections for the current selection.") (LIST (QUOTE Insert) (BQUOTE (WITH-TEDIT , W (FUNCTION TEdit.AddEntry))) "inserts the selected word into the analyzer's word list.") (LIST (QUOTE CountWords) (BQUOTE (WITH-TEDIT , W (FUNCTION TEdit.CountWords))) "counts the words in the current selection.")) CENTERFLG ← T)) (SETQ menuWindow (CREATEW (CREATEREGION -100 -100 (IPLUS 8 (fetch (MENU IMAGEWIDTH) of menu)) (IPLUS 8 (fetch (MENU IMAGEHEIGHT) of menu))) NIL NIL T)) (* WINDOWPROP menuWindow (QUOTE RESHAPEFN) (QUOTE DON'T)) (ADDMENU menu menuWindow) (WINDOWPROP W (QUOTE Proofreader.Menu) menuWindow) (CLOSEW menuWindow))) (COND ((NOT (OPENWP menuWindow)) (ATTACHWINDOW menuWindow W Proofreader.MenuEdge (QUOTE TOP) (QUOTE LOCALCLOSE)) (* (CAR (WINDOWPROP W (QUOTE PROMPTWINDOW)))) (* if you attach the menuWindow to W, then it gets attached to the top-most TEdit menu.) (OPENW menuWindow))) [COND ((SETQ analyzer (AnalyzerForStream stream)) (Analyzer.Proofread analyzer stream (SUB1 (TEDIT.GETPOINT stream] (RETURN menuWindow]) (WITH-TEDIT [LAMBDA (TEXTOBJ FUNCTION) (* jtm: "30-Mar-87 14:07") (LET (EDITOP) [COND ((WINDOWP TEXTOBJ) (SETQ TEXTOBJ (TEXTOBJ TEXTOBJ] (COND ((SETQ EDITOP (fetch EDITOPACTIVE of TEXTOBJ)) (TEDIT.PROMPTPRINT TEXTOBJ (CONCAT (COND ((EQ EDITOP T) "Edit operation") (T EDITOP)) " in progress; please wait."))) (T (RESETLST [RESETSAVE (\TEDIT.MARKACTIVE TEXTOBJ) (QUOTE (AND (\TEDIT.MARKINACTIVE OLDVALUE] (replace EDITOPACTIVE of TEXTOBJ with FUNCTION) (APPLY* FUNCTION TEXTOBJ]) (TEdit.Correct [LAMBDA (stream analyzer autoCorrect) (* jtm: "30-Mar-87 14:09") (PROG (selection correction start length items menuWindow) [COND ((WINDOWP stream) (SETQ menuWindow (WINDOWPROP stream (QUOTE Proofreader.Menu))) (SETQ stream (TEXTSTREAM stream))) ((type? TEXTOBJ stream) (SETQ stream (TEXTSTREAM stream))) (T (SETQ menuWindow (WINDOWPROP (CAR (fetch \WINDOW of (TEXTOBJ stream))) (QUOTE Proofreader.Menu] (COND ([AND (NULL analyzer) (NULL (SETQ analyzer (AnalyzerForStream stream] (TEDIT.PROMPTPRINT stream "No analyzer selected." T) (RETURN))) (SETQ selection (TEDIT.GETSEL stream)) (SETQ start (fetch (SELECTION CH#) of selection)) (SETQ length (IDIFFERENCE (fetch (SELECTION CHLIM) of selection) start)) (TEDIT.PROMPTPRINT stream (CONCAT "Looking for corrections for %"" (STREAM.FETCHSTRING stream (SUB1 start) length) "%" . . . ") T) (SETQ items (Analyzer.Corrections analyzer stream (SUB1 start) length)) [AND autoCorrect (SETQ items (APPEND items (QUOTE (*INSERT* *SKIP*] (COND (items [SELECTQ (SETQ correction (MENU (create MENU ITEMS ← items CENTERFLG ← T MENUOFFSET ←(create POSITION XCOORD ← 6 YCOORD ← 6) TITLE ← "corrections"))) (*INSERT* (TEdit.AddEntry stream analyzer)) (*SKIP* NIL) (COND (correction (TEDIT.DELETE stream) (TEDIT.INSERT stream correction] (TEDIT.PROMPTPRINT stream "" T)) (T (TEDIT.PROMPTPRINT stream (CONCAT "No corrections for the word %"" (STREAM.FETCHSTRING stream (SUB1 start) length) "%".") T))) (RETURN correction]) (TEdit.CountWords [LAMBDA (stream) (* jtm: "30-Mar-87 14:11") (LET (selection n) [COND ((OR (WINDOWP stream) (type? TEXTOBJ stream)) (SETQ stream (TEXTSTREAM stream] (SETQ selection (TEDIT.GETSEL stream)) (TEDIT.PROMPTPRINT stream "Counting words in selection . . . " T) [SETQ n (Analyzer.CountWords (AnalyzerForStream stream) stream (SUB1 (fetch (SELECTION CH#) of selection)) (IDIFFERENCE (fetch (SELECTION CHLIM) of selection) (fetch (SELECTION CH#) of selection] [COND ((STRINGP n) (TEDIT.PROMPTPRINT stream n T)) (T (TEDIT.PROMPTPRINT stream (CONCAT n " words counted."] n]) (TEdit.AddEntry [LAMBDA (stream analyzer) (* jtm: "30-Mar-87 14:11") (PROG (word) [COND ((OR (WINDOWP stream) (type? TEXTOBJ stream)) (SETQ stream (TEXTSTREAM stream] [COND ((NULL analyzer) (SETQ analyzer (AnalyzerForStream stream] (SETQ word (TEDIT.SEL.AS.STRING stream)) (COND [analyzer (COND ((Analyzer.AddEntry analyzer word T NIL stream) (TEDIT.PROMPTPRINT stream (CONCAT "%"" word "%"" " inserted into local word list.") T)) (T (TEDIT.PROMPTPRINT stream "Insert not implemented for this analyzer." T] (T (TEDIT.PROMPTPRINT stream "No analyzer selected." T]) (TEdit.Proofread [LAMBDA (W) (* jtm: "16-Dec-87 13:06") (LET (sel string (stream (TEXTSTREAM W))) (SETQ sel (TEDIT.GETSEL stream)) (SETQ string (STREAM.FETCHSTRING stream (SUB1 (fetch (SELECTION CH#) of sel)) (fetch (SELECTION DCH) of sel))) (COND ((STRPOS " " string) (* just analyze the selection.) (Analyzer.Proofread (AnalyzerForStream stream) stream (SUB1 (fetch (SELECTION CH#) of sel)) (fetch (SELECTION DCH) of sel))) (T (Analyzer.Proofread (AnalyzerForStream stream) stream (SUB1 (TEDIT.GETPOINT stream]) (TEdit.SetAnalyzer [LAMBDA (stream analyzer) (* jtm: "28-Aug-86 09:15") (* * sets the analyzer property for the window) (PROG (quitFn menuItems) [COND ((NULL analyzer) [SETQ menuItems (for i in Analyzer.List collect (LIST (Analyzer.Name i) (LIST (QUOTE QUOTE) i) (if (Analyzer.Prop i (QUOTE RemoteDict)) then "Calls the remote dictionary server"] [COND ((NULL menuItems)) ((EQ 1 (LENGTH menuItems)) (SETQ analyzer (CAR Analyzer.List))) (T (SETQ analyzer (MENU (create MENU ITEMS ← menuItems TITLE ← "analyzers" CENTERFLG ← T] (COND ((NULL analyzer) (SETQ analyzer (STREAMPROP stream (QUOTE analyzer))) (TEDIT.PROMPTPRINT stream (CONCAT "Proofreader is " (AND analyzer (Analyzer.Name analyzer)) ".") T) (RETURN] (TEDIT.PROMPTPRINT stream (CONCAT "Setting proofreader to " (Analyzer.Name analyzer) "...") T) (Analyzer.Open analyzer) (STREAMPROP stream (QUOTE analyzer) analyzer) (SETQ quitFn (TEXTPROP stream (QUOTE QUITFN))) [COND ((OR (EQ quitFn (QUOTE Analyzer.QuitFn)) (FMEMB (QUOTE Analyzer.QuitFn) quitFn)) NIL) ((NULL quitFn) (TEXTPROP stream (QUOTE QUITFN) (QUOTE Analyzer.QuitFn))) (T (TEXTPROP stream (QUOTE QUITFN) (CONS (QUOTE Analyzer.QuitFn) quitFn] (* push the function onto the list.) (TEDIT.PROMPTPRINT stream "done.")) analyzer]) (TEdit.LoadWordList [LAMBDA (stream) (* jtm: " 9-Oct-85 10:39") (* * reads a word list from a remote file and adds it to the given analyzer.) (PROG (file (analyzer (AnalyzerForStream stream))) (COND ((NULL analyzer) (TEDIT.PROMPTPRINT stream "Please select a proofreader." T)) ((NULL (SETQ file (TEDIT.GETINPUT stream "Fetch word list on file: "))) (TEDIT.PROMPTPRINT stream "Aborted." T)) (T (TEDIT.PROMPTPRINT stream (CONCAT "Reading " file "...") T) (Analyzer.DefaultLoadWordList analyzer file) (TEDIT.PROMPTPRINT stream "done."]) (TEdit.StoreWordList [LAMBDA (stream) (* jtm: " 4-Feb-88 08:57") (* * stores the word list for the given analyzer on a remote file.) (PROG (file (analyzer (AnalyzerForStream stream))) (COND ((NULL analyzer) (TEDIT.PROMPTPRINT stream "Please select a proofreader." T)) ((NULL (Analyzer.Prop analyzer (QUOTE WordList))) (TEDIT.PROMPTPRINT stream "No words to be stored." T)) ([NULL (SETQ file (TEDIT.GETINPUT stream "Store word list on file: " (CAR (Analyzer.Prop analyzer (QUOTE WordListFile] (TEDIT.PROMPTPRINT stream "Aborted." T)) (T (TEDIT.PROMPTPRINT stream (CONCAT "Storing word list on " file "...") T) (Analyzer.DefaultStoreWordList analyzer file) [COND (Proofreader.AutoDelete (TEDIT.PROMPTPRINT stream "Deleting old version..." T) (DIRECTORY file (QUOTE ((OLDVERSIONS DELETE) OUT {NULL}] (TEDIT.PROMPTPRINT stream "done."]) (Analyzer.TEditMenuItems [LAMBDA NIL (* jtm: "23-Oct-87 08:58") (AND (BOUNDP (QUOTE TEDIT.DEFAULT.MENU)) (TEDIT.ADD.MENUITEM TEDIT.DEFAULT.MENU (QUOTE (Proofread (FUNCTION TEdit.ProofreadMenu) "Looks for the next spelling error after the caret." (SUBITEMS (Proofread (FUNCTION TEdit.ProofreadMenu) "Looks for the next spelling error after the caret." (SUBITEMS (SetProofreader (FUNCTION TEdit.SetAnalyzer) "Gives a menu of possible proofreaders to use.") (LoadWordList (FUNCTION TEdit.LoadWordList) "Loads a file of words into the proofreader.") (StoreWordList (FUNCTION TEdit.StoreWordList) "Stores the words added to the proofreader by the user on a remote file.") (AutoCorrect (FUNCTION [LAMBDA (stream) (SETQ Proofreader.AutoCorrect T) (TEDIT.PROMPTPRINT stream "AutoCorrection is ON." T]) "The proofreader automatically generates a menu of corrections for the user.") (ManualCorrect (FUNCTION [LAMBDA (stream) (SETQ Proofreader.AutoCorrect) (TEDIT.PROMPTPRINT stream "AutoCorrection is OFF." T]) "The user must ask for a menu of corrections from the proofreader if he wants one."))) (Correct (FUNCTION TEdit.Correct) "generates a list of possible corrections for the current selection.") (Insert (FUNCTION TEdit.AddEntry) "inserts the selected word into the analyzer's word list.") (CountWords (FUNCTION TEdit.CountWords) "Counts the number of words in the currect selection."]) ) (RPAQ? Analyzer.List NIL) (RPAQ? Proofreader.AutoCorrect NIL) (RPAQ? Analyzer.DefaultStream NIL) (RPAQ? Proofreader.AutoDelete T) (RPAQ? Proofreader.MenuEdge (QUOTE LEFT)) (RPAQ? Analyzer.TimeProofreader NIL) (RPAQ? Proofreader.UserFns NIL) (DECLARE: DOEVAL@COMPILE DONTCOPY (GLOBALVARS Analyzer.List Proofreader.AutoCorrect Analyzer.DefaultStream Proofreader.AutoDelete Proofreader.MenuEdge Analyzer.TimeProofreader Proofreader.UserFns) ) (Analyzer.TEditMenuItems) (push BEFORELOGOUTFORMS (QUOTE (Analyzer.BeforeLogout))) (* * THE Dict CLASS) [DECLARE: EVAL@COMPILE (DATATYPE Dict (dictName contents analyzer dictProps subDictionaries openFn closeFn getEntryFn putEntryFn mapFn printEntryFn) openFn ←(FUNCTION NILL) closeFn ←(FUNCTION NILL) getEntryFn ←(FUNCTION NILL) putEntryFn ←(FUNCTION NILL) mapFn ←(FUNCTION NILL) printEntryFn ←(FUNCTION NILL)) ] (/DECLAREDATATYPE (QUOTE Dict) (QUOTE (POINTER POINTER POINTER POINTER POINTER POINTER POINTER POINTER POINTER POINTER POINTER)) (QUOTE ((Dict 0 POINTER) (Dict 2 POINTER) (Dict 4 POINTER) (Dict 6 POINTER) (Dict 8 POINTER) (Dict 10 POINTER) (Dict 12 POINTER) (Dict 14 POINTER) (Dict 16 POINTER) (Dict 18 POINTER) (Dict 20 POINTER))) (QUOTE 22)) (DECLARE: EVAL@COMPILE (PUTPROPS Dict.Open MACRO ((dict messageStream) (APPLY* (fetch (Dict openFn) of dict) dict messageStream))) (PUTPROPS Dict.Close MACRO ((dict) (APPLY* (fetch (Dict closeFn) of dict)))) (PUTPROPS Dict.GetEntry MACRO ((dict uniqueID prop) (APPLY* (fetch (Dict getEntryFn) of dict) dict uniqueID prop))) (PUTPROPS Dict.PutEntry MACRO ((dict uniqueID entry prop) (APPLY* (fetch putEntryFn of dict) dict uniqueID entry prop))) (PUTPROPS Dict.PrintEntry MACRO ((dict entry stream) (APPLY* [COND ((type? Dict dict) (fetch (Dict printEntryFn) of dict)) ((type? INVERTEDDICT dict) (InvertedDict.Prop dict (QUOTE PRINTENTRYFN] dict entry stream))) (PUTPROPS Dict.MapEntries MACRO ((dict MpFn prop topOnly) (* MpFn (dict uniqueId entry prop)) (APPLY* (fetch (Dict mapFn) of dict) dict MpFn prop topOnly))) ) (* * utility functions) (DEFINEQ (DictFromName [LAMBDA (dictName remoteName) (* jtm: "14-Oct-87 14:02") (PROG (dict) [COND ((NULL dictName) (SETQ dict (CAR Dict.DictionaryList))) [(for i in Dict.DictionaryList do (COND ([AND (EQ dictName (fetch (Dict dictName) of i)) (EQ remoteName (Dict.Prop i (QUOTE RemoteDict] (SETQ dict i) (RETURN T] ((for i in InvertedDict.List do (COND ([AND (EQ dictName (fetch (INVERTEDDICT INVERTEDDICTNAME) of i)) (EQ remoteName (InvertedDict.Prop i (QUOTE RemoteDict))) (SETQ dict (InvertedDict.Prop i (QUOTE DICTIONARY] (RETURN T] (RETURN dict]) (Dict.Establish [LAMBDA (dict) (* jtm: "13-Oct-87 10:45") (OR (AND (BOUNDP (QUOTE Dict.DictionaryList)) (bind (dictName ←(fetch (Dict dictName) of dict)) for tail on Dict.DictionaryList when (EQUAL dictName (fetch (Dict dictName) of (CAR tail))) do (RPLACA tail dict) (RETURN T))) (push Dict.DictionaryList dict]) (Dict.Prop [LAMBDA a (* jtm: "13-Oct-87 11:54") (LET (p (dict (ARG a 1)) (prop (ARG a 2))) (SETQ p (FASSOC prop (fetch (Dict dictProps) of dict))) (COND ((ILEQ a 2) (CDR p)) [p (PROG1 (CDR p) (RPLACD p (ARG a 3] (T (CDAR (push (fetch (Dict dictProps) of dict) (CONS prop (ARG a 3]) (Dict.Name [LAMBDA (dict) (* jtm: "13-Oct-87 10:45") (COND [(Dict.Prop dict (QUOTE RemoteDict)) (MKATOM (CONCAT (fetch (Dict dictName) of dict) ": " (Dict.Prop dict (QUOTE RemoteDict] (T (fetch (Dict dictName) of dict]) ) (RPAQ? Dict.DictionaryList NIL) (DECLARE: DOEVAL@COMPILE DONTCOPY (GLOBALVARS Dict.DictionaryList) ) (* * a simple dictionary.) (DEFINEQ (SimpleDict.New [LAMBDA (name) (* jtm: "13-Oct-87 10:40") (create Dict dictName ← name getEntryFn ←(FUNCTION SimpleDict.Lookup) putEntryFn ←(FUNCTION SimpleDict.PutEntry) mapFn ←(FUNCTION SimpleDict.MapEntries) contents ←(create SimpleDict.Node]) (SimpleDict.PutEntry [LAMBDA (dict entry value) (* jtm: " 5-Feb-87 11:29") (* * adds the value to dict under entry.) (LET (subNode (node (fetch (Dict contents) of dict))) [COND ((LITATOM entry) (SETQ entry (MKSTRING entry] (COND ((STRINGP entry) (for i char from 1 to (NCHARS entry) do (SETQ char (NTHCHAR entry i)) (COND ([NOT (SETQ subNode (FASSOC char (fetch (SimpleDict.Node subnodes) of node] (SETQ subNode (create SimpleDict.Node char ← char)) (push (fetch (SimpleDict.Node subnodes) of node) subNode))) (SETQ node subNode)) (replace (SimpleDict.Node value) of node with value)) ((LISTP entry) (for char in entry do (COND ([NOT (SETQ subNode (FASSOC char (fetch (SimpleDict.Node subnodes) of node] (SETQ subNode (create SimpleDict.Node char ← char)) (push (fetch (SimpleDict.Node subnodes) of node) subNode))) (SETQ node subNode)) (replace (SimpleDict.Node value) of node with value))) value]) (SimpleDict.Lookup [LAMBDA (dict entry length) (* jtm: " 7-Apr-87 08:28") (* * looks up entry in the dictionary) (PROG ((node (fetch (Dict contents) of dict))) (COND [(OR (STRINGP entry) (LITATOM entry)) [for i from 1 to (OR length (NCHARS entry)) do (COND ([NOT (SETQ node (FASSOC (NTHCHAR entry i) (fetch (SimpleDict.Node subnodes) of node] (RETURN] (AND node (RETURN (fetch (SimpleDict.Node value) of node] ((LISTP entry) [for i in entry do (COND [(AND (NUMBERP i) (IGREATERP i 9)) (* a character code.) (COND ([NOT (SETQ node (FASSOC (CHARACTER i) (fetch ( SimpleDict.Node subnodes) of node] (RETURN] ([NOT (SETQ node (FASSOC i (fetch (SimpleDict.Node subnodes) of node] (RETURN] (AND node (RETURN (fetch (SimpleDict.Node value) of node]) (SimpleDict.MapEntries [LAMBDA (dict fn node path) (* jtm: "11-Apr-86 15:45") (* * maps all of the entries in the dictionary in arbitrary order.) [COND ((NULL node) (SETQ node (fetch (Dict contents) of dict] [COND ((fetch (SimpleDict.Node value) of node) (APPLY* fn dict path (fetch (SimpleDict.Node value) of node] (for i in (fetch (SimpleDict.Node subnodes) of node) do (SimpleDict.MapEntries dict fn i (APPEND path (LIST (fetch (SimpleDict.Node char) of i]) (SimpleDict.PrintEntries [LAMBDA (dict stream noValues) (* jtm: "31-Mar-87 07:37") [Dict.MapEntries dict (FUNCTION (LAMBDA (dict entry value) (COND (noValues (printout stream (CONCATLIST entry) T)) (T (printout stream (CONCATLIST entry) , value T] dict]) (SimpleDict.Test [LAMBDA NIL (* jtm: "11-Apr-86 15:49") (* * tests the SimpleDict implementation.) (LET [(dict (SimpleDict.New (QUOTE test] (for i in (QUOTE (asdf asd asdfg asde bfdas)) do (Dict.PutEntry dict i i)) [Dict.MapEntries dict (FUNCTION (LAMBDA (dict entry value) (printout T entry , value T] dict]) ) [DECLARE: EVAL@COMPILE (RECORD SimpleDict.Node (char value . subnodes)) ] (* * the INVERTEDDICT class) [DECLARE: EVAL@COMPILE (TYPERECORD INVERTEDDICT (INVERTEDDICTNAME HEADERINDEX KEYINDEX INDEXFILE FILEDIR FILENAME FILEEXT FILEARRAY INVERTEDDICTPROPS)) ] (DEFINEQ (InvertedDictFromName [LAMBDA (dictName remoteName) (* jtm: "13-Oct-87 10:32") (PROG (dict) [COND ((NULL dictName) (SETQ dict (CAR InvertedDict.List))) ((for i in InvertedDict.List do (COND ([AND (EQ dictName (fetch (INVERTEDDICT INVERTEDDICTNAME) of i)) (EQ remoteName (InvertedDict.Prop i (QUOTE RemoteDict] (SETQ dict i) (RETURN T] (RETURN dict]) (InvertedDict.Establish [LAMBDA (dict) (* jtm: "13-Oct-87 10:32") (OR (bind (name ←(fetch (INVERTEDDICT INVERTEDDICTNAME) of dict)) for tail on InvertedDict.List when (EQUAL name (fetch (INVERTEDDICT INVERTEDDICTNAME) of (CAR tail))) do (RPLACA tail dict) (RETURN T)) (push InvertedDict.List dict]) (InvertedDict.Prop [LAMBDA a (* jtm: "13-Oct-87 11:54") (LET (p (dict (ARG a 1)) (prop (ARG a 2))) (SETQ p (FASSOC prop (fetch (INVERTEDDICT INVERTEDDICTPROPS) of dict))) (COND ((ILEQ a 2) (CDR p)) [p (PROG1 (CDR p) (RPLACD p (ARG a 3] (T (CDAR (push (fetch (INVERTEDDICT INVERTEDDICTPROPS) of dict) (CONS prop (ARG a 3]) (InvertedDict.Name [LAMBDA (dict) (* jtm: "13-Oct-87 10:33") (COND [(InvertedDict.Prop dict (QUOTE RemoteDict)) (MKATOM (CONCAT (fetch (INVERTEDDICT INVERTEDDICTNAME) of dict) ": " (InvertedDict.Prop dict (QUOTE RemoteDict] (T (fetch (INVERTEDDICT INVERTEDDICTNAME) of dict]) (InvertedDict.Open [LAMBDA (invertedDict) (* jtm: " 7-Apr-87 09:01") (LET [(OPENFN (InvertedDict.Prop invertedDict (QUOTE OPENFN] (AND OPENFN (APPLY* OPENFN invertedDict]) ) (RPAQ? InvertedDict.List NIL) (DECLARE: DOEVAL@COMPILE DONTCOPY (GLOBALVARS InvertedDict.List) ) (DECLARE: DONTEVAL@LOAD DOEVAL@COMPILE DONTCOPY COMPILERVARS (ADDTOVAR NLAMA ) (ADDTOVAR NLAML ) (ADDTOVAR LAMA InvertedDict.Prop Dict.Prop Analyzer.Prop) ) (PUTPROPS ANALYZER COPYRIGHT ("Xerox Corporation" 1985 1986 1987 1988)) (DECLARE: DONTCOPY (FILEMAP (NIL (7023 23325 (AnalyzerFromName 7033 . 7682) (Analyzer.CountWords 7684 . 8154) ( Analyzer.DefaultCorrections 8156 . 12659) (Analyzer.DefaultNextWord 12661 . 14321) (Analyzer.Name 14323 . 14721) (Analyzer.DefaultAddEntry 14723 . 15258) (Analyzer.DefaultAnalyze 15260 . 19877) ( Analyzer.DefaultProofread 19879 . 23323)) (23421 26218 (Analyzer.DefaultLoadWordList 23431 . 23851) ( Analyzer.DefaultStoreWordList 23853 . 24457) (Analyzer.ReadWordList 24459 . 25283) ( Analyzer.WriteWordList 25285 . 25616) (CREATEWORDLISTRDTBL 25618 . 26216)) (26250 27378 (Analyzer.Prop 26260 . 26777) (Analyzer.PushProp 26779 . 27376)) (28571 29175 (STREAM.FETCHSTRING 28581 . 29173)) ( 29966 33729 (Analyzer.CorruptWord 29976 . 33727)) (33835 36443 (Analyzer.Establish 33845 . 34431) ( AnalyzerForStream 34433 . 34842) (Analyzer.QuitFn 34844 . 35333) (Analyzer.BeforeLogout 35335 . 36441) ) (36444 50028 (TEdit.ProofreadMenu 36454 . 39147) (WITH-TEDIT 39149 . 39866) (TEdit.Correct 39868 . 41930) (TEdit.CountWords 41932 . 42774) (TEdit.AddEntry 42776 . 43563) (TEdit.Proofread 43565 . 44333) (TEdit.SetAnalyzer 44335 . 46209) (TEdit.LoadWordList 46211 . 46915) (TEdit.StoreWordList 46917 . 48020) (Analyzer.TEditMenuItems 48022 . 50026)) (52503 54786 (DictFromName 52513 . 53470) ( Dict.Establish 53472 . 53953) (Dict.Prop 53955 . 54434) (Dict.Name 54436 . 54784)) (54927 59343 ( SimpleDict.New 54937 . 55296) (SimpleDict.PutEntry 55298 . 56626) (SimpleDict.Lookup 56628 . 57883) ( SimpleDict.MapEntries 57885 . 58541) (SimpleDict.PrintEntries 58543 . 58892) (SimpleDict.Test 58894 . 59341)) (59630 61859 (InvertedDictFromName 59640 . 60234) (InvertedDict.Establish 60236 . 60682) ( InvertedDict.Prop 60684 . 61203) (InvertedDict.Name 61205 . 61609) (InvertedDict.Open 61611 . 61857))) )) STOP