LnSOS BOOT 1.1 SOS.KERNEL SOS KRNLI/O ERRORFILE 'SOS.KERNEL' NOT FOUND%INVALID KERNEL FILE: xةw,@  ȱlmi8#)!)O^±6 !4-UTS.TEST.CODE&6!UTS.TEST.EXECl6!-UTS.TEST.TEXT(6!! (UTS.TEXT9p6!+III.PCL.14u' *UTS.1.TEXT 6!*UTS.2.TEXT9p6!*UTS.3.TEXTH)P6 !&(UTS.CODEq4f6 6UTS.EXEC!6 !:/UTS.SAMPLE.TEXT >dLԡm#i㰼m#iЕOLԡȱfg hi !dLԡ憦  Ljmkm l y`2 Lԡ8(Je稽)ʈ@L  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFO^±--------------------------------------------------------------- } VAR " v_IDList : t_IDList; { Internal Token ID List (Array ) } v_ExtIDListPtr : t_ID_Ptr; { External Token ID List (Linked List) } t_ExtID = RECORD { External token definition } ext_ID : t_ID; { The token ID name } next_ID : t_ID_Ptr; { Pointer to next list token } END; { ---------------- } TYPE " t_ID = STRING[k_IDLength]; { A token ID } $ t_IDList = ARRAY [0..k_IDLm1] OF t_ID; { Token ID list } t_ID_Ptr = ^t_ExtID; { Pointer to an external token } um character length } $ k_IDListLength = 212 {ORD(tk_Identifier)}; { Element count of ID list } { (Excludes tk_Identifier itself) } $k_IDLm1 = 211; { --------------------------------------------------------------------- * ************************************************************************** } CONST " k_Version = 99; { UNIT version number in format X.YZ [0.99] } k_IDLength = 8; { Token ID maxim { ************************************************************************** * * * P R I V A T E C O N S T A N T S / T Y P E S / V A R I A B L E S * * BEGIN index := LENGTH(p); REPEAT BEGIN IF p[index] IN ['a'..'z'] THEN p[index] := CHR(ORD(p[index]) - ORD('a') + ORD('A')); index := index - 1; END; ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| } PROCEDURE uppercase(VAR p : ts_Phrase); VAR index : INTEGER; BEGIN { ----- uppercase ----- } & &{$IFC F_BUG} BP('UPPERCASE'); {$ENDC} & IF (LENGTH(p) > 0) THEN |||||||||||||||||||||||||||||||||||||||||||||| | ROUTINE...: uppercase | PURPOSE...: Convert a string to all uppercase letters | INPUT.....: p - String phrase to uppercase | OUTPUT....: p - String with all the letters in uppercase |||||||||||||||id_count,PD1STRING); PD_WRITE('Total of '); *PD_WRITE(PD1STRING); *PD_WRITELN(' id(s) are present'); PD_WRITELN(''); END; END; { ----- BUG_Dump_External_Token_List ----- } {$ENDC} {^FF} { |||||||||||||||||||||||||||| FOR pad := 1 TO (k_IDLength - LENGTH(id_Ptr^.ext_ID)) DO PD_WRITE(' '); id_Ptr := id_Ptr^.next_ID; END; UNTIL (id_Ptr = NIL); PD_WRITELN(''); PD_WRITELN(''); *STR( 4PD1STRING := CONCAT(' ',PD1STRING); PD_WRITE(PD1STRING); END; PD_WRITE(CONCAT(' ',id_Ptr^.ext_ID)); IF (LENGTH(id_Ptr^.ext_ID) < k_IDLength) THEN id_Count := 0; REPEAT BEGIN id_Count := id_Count + 1; IF ((id_Count-1) MOD 5 = 0) THEN BEGIN PD_WRITELN(''); 2STR(id_Count-1,PD1STRING); 2WHILE LENGTH(PD1STRING) < 4 DOKEN TABLE ]'); PD_WRITELN(''); IF (v_ExtIDListPtr = NIL) THEN PD_WRITELN('*** External ID List is EMPTY') ELSE BEGIN PD_WRITELN(h_1); PD_WRITE (h_2); id_Ptr := v_ExtIDListPtr; h_2 = '---- -------- -------- -------- -------- --------'; VAR id_Ptr : t_ID_Ptr; id_Count : INTEGER; pad : INTEGER; BEGIN { ----- BUG_Dump_External_Token_List ----- } PD_WRITELN('[ EXTERNAL TO|||||||||||||||||||||||||||| } {$IFC F_BUG} PROCEDURE BUG_Dump_External_Token_List; CONST h_1 = 'ID # ID Name ID Name ID Name ID Name ID Name '; | PURPOSE...: Output the external token list to the debugger file. | INPUT.....: v_ExtIDListPtr - Pointer to external token list | OUTPUT....: Token list outputted to debugger file in nice column format |||||||||||||||||||||||||||||||||||||||||||||| * ************************************************************************** } { |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| | ROUTINE...: BUG_Dump_External_Token_List { ************************************************************************** * * * P R I V A T E R O U T I N E S * * UNTIL (index = 0); END; & &{$IFC F_BUG} EP('UPPERCASE'); {$ENDC} & END; { ----- uppercase ----- } {^FF} { |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| | ROUTINE...: init_TokenList | PURPOSE...: Initialize the internal token list array | INPUT.....: (none) | OUTPUT....: Internal token list array initialized |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| } PROCEDURE init_TokenList; VAR id : INTEGER; { -------- BEGIN { ----- init_1_SpecialWords ----- } & & {$IFC F_BUG} BP('INIT_1_SPECIALWORDS'); {$ENDC} ( set_IDList_Element (inc_id , '???'); { Start of special words } set_IDList_Element (inc_id , 'ABS' ); set_IDList_; { End of symbols } ( & {$IFC F_BUG} EP('INIT_SYMBOLS'); {$ENDC} ( END; { ----- init_Symbols ----- } { -------------------------------------------------------------------------- } PROCEDURE init_1_SpecialWords; List_Element (inc_id , '(*' ); set_IDList_Element (inc_id , '*)' ); set_IDList_Element (inc_id , '(.' ); { = '[' in MacPascal } set_IDList_Element (inc_id , '.)' ); { = ']' in MacPascal } set_IDList_Element (inc_id , '???')inc_id , '<>' ); set_IDList_Element (inc_id , '<=' ); set_IDList_Element (inc_id , '>=' ); set_IDList_Element (inc_id , ':=' ); set_IDList_Element (inc_id , '..' ); set_IDList_Element (inc_id , '**' ); set_ID set_IDList_Element (inc_id , '\' ); set_IDList_Element (inc_id , '?' ); set_IDList_Element (inc_id , '"' ); set_IDList_Element (inc_id , '!' ); set_IDList_Element (inc_id , '&' ); ( set_IDList_Element ( set_IDList_Element (inc_id , '#' ); set_IDList_Element (inc_id , '$' ); set_IDList_Element (inc_id , '%' ); set_IDList_Element (inc_id , '_' ); set_IDList_Element (inc_id , '|' ); t_Element (inc_id , '@' ); set_IDList_Element (inc_id , '{' ); set_IDList_Element (inc_id , '}' ); set_IDList_Element (inc_id , '~' ); set_IDList_Element (inc_id , '`' ); set_IDList_Element (inc_id , '''' ); _id , ',' ); set_IDList_Element (inc_id , '(' ); set_IDList_Element (inc_id , ')' ); set_IDList_Element (inc_id , ':' ); set_IDList_Element (inc_id , ';' ); set_IDList_Element (inc_id , '^' ); set_IDLis set_IDList_Element (inc_id , '<' ); set_IDList_Element (inc_id , '>' ); set_IDList_Element (inc_id , '[' ); set_IDList_Element (inc_id , ']' ); set_IDList_Element (inc_id , '.' ); set_IDList_Element (inc { Start of symbols } set_IDList_Element (inc_id , '+' ); set_IDList_Element (inc_id , '-' ); set_IDList_Element (inc_id , '*' ); set_IDList_Element (inc_id , '/' ); set_IDList_Element (inc_id , '=' ); ---------------------- } PROCEDURE init_Symbols; BEGIN { ----- init_Symbols ----- } & & {$IFC F_BUG} BP('INIT_SYMBOLS'); {$ENDC} ( set_IDList_Element (inc_id , '???'); { Unknown symbol } set_IDList_Element (inc_id , '???');----------------------------------------- } FUNCTION inc_id : INTEGER; BEGIN { ----- inc_id ----- } & id := id + 1; inc_id := id; ( END; { ----- inc_id ----- } { ---------------------------------------------------- IF (LENGTH(id_phrase) > k_IDLength) THEN v_IDList[id_number] := COPY(id_phrase,1,k_IDLength) ELSE v_IDList[id_number] := id_phrase; END; { ----- set_IDList_Element ----- } { --------------------------------------------------------------------------------------------------- } PROCEDURE set_IDList_Element(id_number : INTEGER; id_phrase : ts_Phrase); BEGIN { ----- set_IDList_Element ----- } Element (inc_id , 'AND' ); set_IDList_Element (inc_id , 'ATAN' ); set_IDList_Element (inc_id , 'ARCTAN' ); set_IDList_Element (inc_id , 'ARRAY' ); set_IDList_Element (inc_id , 'ATTACH' ); set_IDList_Element (inc_id , 'BEGIN' ); set_IDList_Element (inc_id , 'BLOCKREAD' ); set_IDList_Element (inc_id , 'BLOCKWRITE' ); set_IDList_Element (inc_id , 'BOOLEAN' ); s set_IDList_Element (inc_id , 'INTRINSIC' ); set_IDList_Element (inc_id , 'IORESULT' ); ( & {$IFC F_BUG} EP('INIT_2_SPECIALWORDS'); {$ENDC} ( END; { ----- init_2_SpecialWords ----- } { -------------------------------List_Element (inc_id , 'INSERT' ); set_IDList_Element (inc_id , 'INTEGER' ); set_IDList_Element (inc_id , 'INTERACTIVE' ); set_IDList_Element (inc_id , 'INTERFACE' ); ); set_IDList_Element (inc_id , 'IMPLEMENTATION' ); set_IDList_Element (inc_id , 'IN' ); set_IDList_Element (inc_id , 'INLINE' ); set_IDList_Element (inc_id , 'INPUT' ); set_IDnt (inc_id , 'GOTOXY' ); set_IDList_Element (inc_id , 'HALT' ); set_IDList_Element (inc_id , 'HEAPRESULT' ); set_IDList_Element (inc_id , 'IDSEARCH' ); set_IDList_Element (inc_id , 'IF' set_IDList_Element (inc_id , 'FORWARD' ); set_IDList_Element (inc_id , 'FUNCTION' ); set_IDList_Element (inc_id , 'GET' ); set_IDList_Element (inc_id , 'GOTO' ); set_IDList_Eleme 'EXTERNAL' ); set_IDList_Element (inc_id , 'FALSE' ); set_IDList_Element (inc_id , 'FILE' ); set_IDList_Element (inc_id , 'FILLCHAR' ); set_IDList_Element (inc_id , 'FOR' ); IDList_Element (inc_id , 'EOLN' ); set_IDList_Element (inc_id , 'EXIT' ); set_IDList_Element (inc_id , 'EXP' ); set_IDList_Element (inc_id , 'EXTENDED' ); set_IDList_Element (inc_id ,rds ----- } & & {$IFC F_BUG} BP('INIT_2_SPECIALWORDS'); {$ENDC} * set_IDList_Element (inc_id , 'ELSE' ); set_IDList_Element (inc_id , 'END' ); set_IDList_Element (inc_id , 'EOF' ); set_& {$IFC F_BUG} EP('INIT_1_SPECIALWORDS'); {$ENDC} ( END; { ----- init_1_SpecialWords ----- } { -------------------------------------------------------------------------- } PROCEDURE init_2_SpecialWords; BEGIN { ----- init_2_SpecialWoList_Element (inc_id , 'DIV' ); set_IDList_Element (inc_id , 'DO' ); set_IDList_Element (inc_id , 'DOUBLE' ); set_IDList_Element (inc_id , 'DOWNTO' ); ( ); set_IDList_Element (inc_id , 'CYCLE' ); set_IDList_Element (inc_id , 'DATA' ); set_IDList_Element (inc_id , 'DELETE' ); set_IDList_Element (inc_id , 'DISPOSE' ); set_IDnt (inc_id , 'CONST' ); set_IDList_Element (inc_id , 'COPY' ); set_IDList_Element (inc_id , 'COS' ); set_IDList_Element (inc_id , 'CREATION' ); set_IDList_Element (inc_id , 'CRUNCH' set_IDList_Element (inc_id , 'CLOSE' ); set_IDList_Element (inc_id , 'CODE' ); set_IDList_Element (inc_id , 'COMP' ); set_IDList_Element (inc_id , 'CONCAT' ); set_IDList_Elemeet_IDList_Element (inc_id , 'BYTESTREAM' ); set_IDList_Element (inc_id , 'CASE' ); set_IDList_Element (inc_id , 'CHAR' ); set_IDList_Element (inc_id , 'CHR' ); ------------------------------------------- } PROCEDURE init_3_SpecialWords; BEGIN { ----- init_3_SpecialWords ----- } & & {$IFC F_BUG} BP('INIT_3_SPECIALWORDS'); {$ENDC} ( set_IDList_Element (inc_id , 'KEYBOARD' ); set_IDList_Element (inc_id , 'KEYPRESS' ); set_IDList_Element (inc_id , 'LEAVE' ); set_IDList_Element (inc_id , 'LABEL' ); set_IDList_Element (inc_id , 'LENGTH' ); set_IDList_Element (inc_i set_IDList_Element (inc_id , 'SEEK' ); set_IDList_Element (inc_id , 'SEGMENT' ); set_IDList_Element (inc_id , 'SEMAPHORE' ); set_IDList_Element (inc_id , 'SEMINIT' ); set_IDList_Eleme 'REWRITE' ); set_IDList_Element (inc_id , 'ROUND' ); set_IDList_Element (inc_id , 'SCAN' ); set_IDList_Element (inc_id , 'SCANEQ' ); set_IDList_Element (inc_id , 'SCANNE' ); IDList_Element (inc_id , 'RECORD' ); set_IDList_Element (inc_id , 'RELEASE' ); set_IDList_Element (inc_id , 'REPEAT' ); set_IDList_Element (inc_id , 'RESET' ); set_IDList_Element (inc_id ,rds ----- } & & {$IFC F_BUG} BP('INIT_4_SPECIALWORDS'); {$ENDC} ( set_IDList_Element (inc_id , 'READ' ); set_IDList_Element (inc_id , 'READLN' ); set_IDList_Element (inc_id , 'REAL' ); set_& {$IFC F_BUG} EP('INIT_3_SPECIALWORDS'); {$ENDC} ( END; { ----- init_3_SpecialWords ----- } { -------------------------------------------------------------------------- } PROCEDURE init_4_SpecialWords; BEGIN { ----- init_4_SpecialWoList_Element (inc_id , 'PROGRAM' ); set_IDList_Element (inc_id , 'PURGE' ); set_IDList_Element (inc_id , 'PUT' ); set_IDList_Element (inc_id , 'PWROFTEN' ); ( ); set_IDList_Element (inc_id , 'PRED' ); set_IDList_Element (inc_id , 'PROCEDURE' ); set_IDList_Element (inc_id , 'PROCESS' ); set_IDList_Element (inc_id , 'PROCESSID' ); set_IDnt (inc_id , 'PACKED' ); set_IDList_Element (inc_id , 'PAGE' ); set_IDList_Element (inc_id , 'PMACHINE' ); set_IDList_Element (inc_id , 'POINTER' ); set_IDList_Element (inc_id , 'POS' set_IDList_Element (inc_id , 'ORD4' ); set_IDList_Element (inc_id , 'OTHERWISE' ); set_IDList_Element (inc_id , 'OUTPUT' ); set_IDList_Element (inc_id , 'PACK' ); set_IDList_ElemeList_Element (inc_id , 'ODD' ); set_IDList_Element (inc_id , 'OF' ); set_IDList_Element (inc_id , 'OR' ); set_IDList_Element (inc_id , 'ORD' ); ); set_IDList_Element (inc_id , 'NEW' ); set_IDList_Element (inc_id , 'NIL' ); set_IDList_Element (inc_id , 'NORMAL' ); set_IDList_Element (inc_id , 'NOT' ); set_IDnt (inc_id , 'MEMSWAP' ); set_IDList_Element (inc_id , 'METHODS' ); set_IDList_Element (inc_id , 'MOD' ); set_IDList_Element (inc_id , 'MOVELEFT' ); set_IDList_Element (inc_id , 'MOVERIGHT' set_IDList_Element (inc_id , 'MARK' ); set_IDList_Element (inc_id , 'MAXINT' ); set_IDList_Element (inc_id , 'MEMAVAIL' ); set_IDList_Element (inc_id , 'MEMLOCK' ); set_IDList_Elemed , 'LN' ); set_IDList_Element (inc_id , 'LOCK' ); set_IDList_Element (inc_id , 'LOG' ); set_IDList_Element (inc_id , 'LONGINT' ); nt (inc_id , 'SEPARATE' ); set_IDList_Element (inc_id , 'SET' ); set_IDList_Element (inc_id , 'SIGNAL' ); set_IDList_Element (inc_id , 'SIN' ); set_IDList_Element (inc_id , 'SINGLE' ); set_IDList_Element (inc_id , 'SIZEOF' ); set_IDList_Element (inc_id , 'SQR' ); set_IDList_Element (inc_id , 'SQRT' ); set_IDList_Element (inc_id , 'START' ); set_ID | INPUT.....: extID_file - Name of external token list file | OUTPUT....: External token list initialized with the word contents of | the external token file. | NOTE......: The words in the external file should occupy one word per | t_TokenList'); {$ENDC} & END; { ----- init_TokenList ----- } {^FF} { |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| | ROUTINE...: init_ExternalTokenList | PURPOSE...: Initialize the external token linked list init_Symbols; { Setup the symbols } init_1_SpecialWords; { and setup the special words... } init_2_SpecialWords; init_3_SpecialWords; init_4_SpecialWords; init_5_SpecialWords; & &{$IFC F_BUG} EP('ini { ----- init_5_SpecialWords ----- } { -------------------------------------------------------------------------- } BEGIN { ----- init_TokenList ----- } $ &{$IFC F_BUG} BP('init_TokenList'); {$ENDC} & id := -1; { Initialize id index } set_IDList_Element (inc_id , 'WRITE' ); set_IDList_Element (inc_id , 'WRITELN' ); set_IDList_Element (inc_id , '???'); { End of special words } ( & {$IFC F_BUG} EP('INIT_5_SPECIALWORDS'); {$ENDC} ( END; List_Element (inc_id , 'WHILE' ); set_IDList_Element (inc_id , 'WITH' ); set_IDList_Element (inc_id , 'WORDSTREAM' ); set_IDList_Element (inc_id , 'WPROTECT' ); ); set_IDList_Element (inc_id , 'VARAVAIL' ); set_IDList_Element (inc_id , 'VARDISPOSE' ); set_IDList_Element (inc_id , 'VARNEW' ); set_IDList_Element (inc_id , 'WAIT' ); set_IDnt (inc_id , 'UNITWAIT' ); set_IDList_Element (inc_id , 'UNITWRITE' ); set_IDList_Element (inc_id , 'UNTIL' ); set_IDList_Element (inc_id , 'USES' ); set_IDList_Element (inc_id , 'VAR' set_IDList_Element (inc_id , 'UNITBUSY' ); set_IDList_Element (inc_id , 'UNITCLEAR' ); set_IDList_Element (inc_id , 'UNITREAD' ); set_IDList_Element (inc_id , 'UNITSTATUS' ); set_IDList_ElemeECIALWORDS'); {$ENDC} ( set_IDList_Element (inc_id , 'UNIT' ); set_IDList_Element (inc_id , 'UNPACK' ); set_IDList_Element (inc_id , 'UNPROTECT' ); $ENDC} * END; { ----- init_4_SpecialWords ----- } { -------------------------------------------------------------------------- } PROCEDURE init_5_SpecialWords; BEGIN { ----- init_5_SpecialWords ----- } & & {$IFC F_BUG} BP('INIT_5_SPnt (inc_id , 'TREESEARCH' ); set_IDList_Element (inc_id , 'TRUE' ); set_IDList_Element (inc_id , 'TRUNC' ); set_IDList_Element (inc_id , 'TYPE' ); ( & {$IFC F_BUG} EP('INIT_4_SPECIALWORDS'); { set_IDList_Element (inc_id , 'TEXT' ); set_IDList_Element (inc_id , 'THEN' ); set_IDList_Element (inc_id , 'TIME' ); set_IDList_Element (inc_id , 'TO' ); set_IDList_ElemeList_Element (inc_id , 'STR' ); set_IDList_Element (inc_id , 'STRING' ); set_IDList_Element (inc_id , 'SUCC' ); set_IDList_Element (inc_id , 'TAN' ); line and these words should not contain any strange chars. | If a line is blank or starts with an '*', then the line is | ignored ('*' lines are useful for comments). | If a line starts with '<', then the following phrase is | used as the name of another external text token file whose | token words will be added to the external token list. | Note that only one level of included file names is allowed. | UNTIL (POS(' ',id) = 0); IF (LENGTH(id) > 0) THEN { Ignore blank lines } BEGIN IF (id[1] <> '*') THEN { Ignore comment lines } BEGIN {$ENDC} IF (inc_error = ts_k_NoError) THEN BEGIN REPEAT { Remove all blanks in identifier } IF (POS(' ',id) > 0) THEN DELETE(id,POS(' ',id),1); READLN(gv_IncFile,id); inc_error := IORESULT; {$IFC F_BUG} 0STR(inc_error,PD1STRING); IF (inc_error <> ts_k_NoError) THEN PD_WRITELN(CONCAT('INCLUDE file opening failed: ', DPD1STRING)); - } RESET(gv_IncFile,include_file); inc_error := IORESULT; { Open file } IF (inc_error = ts_k_NoError) THEN { Ignore all I/O errors } BEGIN REPEAT { Process INCLUDE file line by line } BEGIN { -------------------------------------------------------------------------- } PROCEDURE handle_INCLUDE_File(include_file : ts_Phrase); VAR {inc_File : TEXT;} inc_error : ts_Error; BEGIN { ----- handle_INCLUDE_File ----v_ExtIDListPtr; v_ExtIDListPtr := ext_id_info; END; END; add_ID_to_External_List := memory_error; { Return error to caller } END; { ----- add_ID_to_External_List ----- } THEN memory_error := 37 { Mem error ? } AELSE memory_error := ts_k_NoError; IF (memory_error = ts_k_NoError) THEN BEGIN ext_id_info^.ext_ID := the_ID; { Setup the entry } ext_id_info^.next_ID := entry } ext_id_info^.next_ID := NIL; END; END; END ELSE BEGIN { Non-empty list found, so insert new ID into the list } NEW(ext_id_info); , ,IF ext_id_info = NIL EELSE memory_error := ts_k_NoError; IF (memory_error = ts_k_NoError) THEN BEGIN v_ExtIDListPtr := ext_id_info; { Point at 1st entry } ext_id_info^.ext_ID := the_ID; { Setup 1st error ? } AELSE memory_error := ts_k_NoError; IF (memory_error = ts_k_NoError) THEN BEGIN NEW(ext_id_info); 0 0IF ext_id_info = NIL THEN memory_error := 37 { Mem error ? } } memory_error := ts_k_NoError; { Assume all is well } uppercase(the_ID); IF (v_ExtIDListPtr = NIL) THEN BEGIN { Empty list found } MARK(ext_id_info); , ,IF ext_id_info = NIL THEN memory_error := 37 { Mem-------------------------------------------------------- } FUNCTION add_ID_to_External_List(the_ID : ts_Phrase) : ts_Error; VAR memory_error : ts_Error; ext_id_info : t_ID_Ptr; BEGIN { ----- add_ID_to_External_List ----- |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| } FUNCTION init_ExternalTokenList(extID_file : ts_Phrase) : ts_Error; VAR error : ts_Error; &{ext_file : TEXT;} id : ts_Phrase; { ------------------ That is, if file extID_file contains an include file line | whose file name is other_tokens, then the file other_tokens | can not contain lines starting with '<'. IF (id[1] <> '<') THEN { Ignore another INCLUDE } BEGIN { Add id to external token list } IF (LENGTH(id) > k_IDLength) THEN id := COPY(id,1,k_IDLength); inc_error := add_ID_to_External_List(id); END; END; END; END; END; O^±k_NoError; END; init_ExternalTokenList := error; { Return error result to caller } & &{$IFC F_BUG} EP('init_ExternalTokenList'); {$ENDC} & END; { ----- init_ExternalTokenList ----- } IF (v_ExtIDListPtr <> NIL) AND (error <> ts_k_NoError) THEN BEGIN { Remove external token list data from memory } RELEASE(v_ExtIDListPtr); * *IF v_ExtIDListPtr = NIL THEN error := 37 { Mem error ? } BELSE error := ts_ END; END; END; UNTIL EOF(gv_ExtFile) OR (error <> ts_k_NoError); { Time to stop ? } CLOSE(gv_ExtFile); { Do NOT check for a CLOSE I/O error } END; IF (LENGTH(id) > k_IDLength) THEN id := COPY(id,1,k_IDLength); error := add_ID_to_External_List(id); END; END; NDC} handle_INCLUDE_File(id); { Process file } END ELSE BEGIN { Add id to external token list } BEGIN DELETE(id,1,1); { Remove leading '<' } {$IFC F_BUG} PD_WRITELN(CONCAT('INCLUDE file: "',id,'"')); {$E> 0) THEN { Ignore blank lines } BEGIN IF (id[1] <> '*') THEN { Ignore comment lines } BEGIN IF (id[1] = '<') THEN { Include another file } N BEGIN REPEAT { Remove all blanks in identifier } IF (POS(' ',id) > 0) THEN DELETE(id,POS(' ',id),1); UNTIL (POS(' ',id) = 0); IF (LENGTH(id) RESET(gv_ExtFile,extID_file); error := IORESULT; { I/O error ? } IF (error = ts_k_NoError) THEN BEGIN REPEAT BEGIN READLN(gv_ExtFile,id); error := IORESULT; IF (error = ts_k_NoError) THE{ -------------------------------------------------------------------------- } BEGIN { ----- init_ExternalTokenList ----- } & &{$IFC F_BUG} BP('init_ExternalTokenList'); {$ENDC} & v_ExtIDListPtr := NIL; { Assume external file is invalid } UNTIL EOF(gv_IncFile) OR (inc_error <> ts_k_NoError); CLOSE(gv_IncFile,LOCK); { Close up shop } END; END; { ----- handle_INCLUDE_File ----- } GIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnoION TS_TerminateTokenSearch {: ts_Error}; VAR error : ts_Error; { Termination error result } BEGIN { ----- TS_TerminateTokenSearch ----- } $ &{$IFC F_BUG} BP('TS_TerminateTokenSearch'); {$ENDC} & error := ts_k_NoError; { Assume allND; { ----- TS_InitializeTokenSearch ----- } {^FF} { |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| | ROUTINE...: TS_TerminateTokenSearch |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| } FUNCT IF (error = ts_k_NoError) THEN BUG_Dump_External_Token_List; {$ENDC} END; TS_InitializeTokenSearch := error; { Return error result to caller } & &{$IFC F_BUG} EP('TS_InitializeTokenSearch'); {$ENDC} & Ets } init_TokenList; IF (identifier_file = '') THEN v_ExtIDListPtr := NIL { No external ID file present } ELSE BEGIN error := init_ExternalTokenList(identifier_file); {$IFC F_BUG} ER ***'); PD_WRITELN(''); & &BP('TS_InitializeTokenSearch'); {$ENDC} & &{$IFC F_BUG} &STR(SIZEOF(t_IDList),PD1STRING); &PD_WRITELN(CONCAT('SIZEOF(t_IDList) = ',PD1STRING)); &{$ENDC} { Initialize the internal & external token liskenSearch ----- } & error := ts_k_NoError; { Assume all is well } { Initialize the Debugger (iff debugger flag is set) } {$IFC F_BUG} PD_InitDebugger; PD_WRITELN(''); PD_WRITELN('*** WELCOME TO THE TokenSearch DEBUGG |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| } FUNCTION TS_InitializeTokenSearch{(identifier_file: ts_Phrase): ts_Error}; VAR error : ts_Error; { Initialization error result } BEGIN { ----- TS_InitializeToEP('TS_VERSION'); {$ENDC} END; { ----- TS_Version ----- } {^FF} { |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| | ROUTINE...: TS_InitializeTokenSearch ||||||||||||||||||||||||||||||||||||||||||||||||||||||||| } FUNCTION TS_Version {: INTEGER}; BEGIN { ----- TS_Version ----- } &{$IFC F_BUG} BP('TS_VERSION'); {$ENDC} $ TS_Version := k_Version; { Tell the caller who I am } & &{$IFC F_BUG} * ************************************************************************** } { |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| | ROUTINE...: TS_Version ||||||||||||||||| { ************************************************************************** * * * P U B L I C R O U T I N E S * * is well } IF (v_ExtIDListPtr <> NIL) THEN BEGIN { Remove external token list data from memory } RELEASE(v_ExtIDListPtr); { Mem error ? } * *IF v_ExtIDListPtr = NIL THEN error := 37 BELSE error := ts_k_NoError; END; $ &{$IFC F_BUG} EP('TS_TerminateTokenSearch'); {$ENDC} { Terminate the Debugger (iff debugger flag is set) } {$IFC F_BUG} PD_WRITELN(''); PD_WRITELN('*** DEBUGGER IS TERMINATING ***'); PD_KillDebugger; offset := offset + 1; { Point at the next character } eoi := (offset > LENGTH(phrase)); { At End-of-Identifier ? } , IF NOT(eoi) THEN { No, so test current character } BEGIN eoi := NOT( { Extract ENTIRE identifier from phrase } id_1 := '?'; { Initialize these guys } c := '?'; id_1[1] := phrase[offset]; { Initialize identifier } REPEAT { Extract the identifier character by character } BEGIN END; END; { ----- search_External_ID_List ----- } { -------------------------------------------------------------------------- } BEGIN { ----- scan_identifier ----- } & & {$IFC F_BUG} BP('SCAN_IDENTIFIER'); {$ENDC} & d); END; UNTIL id_found OR (id_Ptr^.next_ID = NIL); { Stop ? } END; IF id_found THEN { ID match found in list ? } BEGIN token_kind := tk_ExtTOKEN; { External token found } ifiers } BEGIN REPEAT BEGIN id_Ptr := id_Ptr^.next_ID; { Get the ID from list } IF (id_Ptr <> NIL) THEN { Match found ? } id_found := (id_Ptr^.ext_ID = the_i:= tk_Identifier; { Assume undefined identifier } id_Ptr := v_ExtIDListPtr; { Start at the front of the list } id_found := (id_Ptr^.ext_ID = the_id); { Test 1st entry } IF NOT(id_found) THEN { Test remaining external ident PROCEDURE search_External_ID_List(the_id : t_ID); VAR id_Ptr : t_ID_Ptr; { Identifier pointer } id_found : BOOLEAN; { Identifier found flag } BEGIN { ----- search_External_ID_List ----- } token_kind oi : BOOLEAN; { End-of-Identifier flag } id_index : INTEGER; { Identifier list index } id_found : BOOLEAN; { Identifier found in list flag } { -------------------------------------------------------------------------- } tifier; { INPUT: offset points at non-symbol } VAR id_1 : ts_Phrase; { Modified identifier } id_2 : ts_Phrase; { Original identifier } c : STRING[1]; { A small string used in CONCAT() function } e BEGIN { ----- seperator_found ----- } seperator_found := (ch < min_symbol) OR (ch > max_symbol); END; { ----- seperator_found ----- } { -------------------------------------------------------------------------- } PROCEDURE scan_iden{ -------------------------------------------------------------------------- } FUNCTION seperator_found(ch : CHAR) : BOOLEAN; CONST min_symbol = '!'; { ASCII Exclamation [$21] } max_symbol = '~'; { ASCII Tilde [$7F] } CORD CASE BOOLEAN OF 4 FALSE : (t : ts_TokenType); 6TRUE : (i : INTEGER ); 4END; 4 VAR token_kind : ts_TokenType; { Token kind to return to caller } &trix_token : t_TokenTrix; { Special token trick record } |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| } FUNCTION TS_GetToken{( phrase : ts_Phrase; VAR offset : ts_Offset; VAR token : ts_Phrase) : ts_TokenType}; $TYPE &t_TokenTrix = RE{$ENDC} TS_TerminateTokenSearch := error; { Return error result to caller } END; { ----- TS_TerminateTokenSearch ----- } {^FF} { |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| | ROUTINE...: TS_GetToken ||||||||||phrase[offset] IN ['A'..'Z','a'..'z','0'..'9','_']); 0 IF NOT(eoi) THEN { Valid identifier character found ? } BEGIN { Yeah, so concatenate character to the identifier } c[1] := phrase[offset]; { Get the next character } id_1 := CONCAT(id_1,c); { Do the addition } END; END; END; UNTIL eoi; { Stop ? } { Search for the extracte : token_kind := tk_Times; * * ORD(tk_Slash) : token_kind := tk_Slash; * * ORD(tk_Equal) : token_kind := tk_Equal; * * ORD(tk_LessThan) : token_kind :CASE sym_index OF * * ORD(tk_Plus) : token_kind := tk_Plus; * * ORD(tk_Minus) : token_kind := tk_Minus; * * ORD(tk_Times) * IF YOUR PASCAL COMPILER DOES NOT SUPPORT TYPE CONVERSION * * THEN REPLACE THE NEXT CODE LINE WITH THE FOLLOWING CODE: * * * * ND)); IF NOT(sym_found) THEN token_kind := tk_SymUNKNOWN { Unknown symbol } ELSE BEGIN { **************************** NOTE **************************** Start at symbol start } REPEAT BEGIN sym_found := (token = v_IDList[sym_index]); 0 0IF NOT(sym_found) THEN 2sym_index := sym_index + 1; END; UNTIL sym_found OR (sym_index = ORD(tk_SymEN BEGIN { Last symbol character scanner } token := '?'; token[1] := phrase[offset]; offset := offset + 1; { Search for token in symbol list } sym_index := ORD(tk_SymSTART) + 1; { new_char : CHAR; { Next character in phrase } BEGIN { ----- scan_symbol ----- } & & {$IFC F_BUG} BP('SCAN_SYMBOL'); {$ENDC} & { Test if the last phrase character is being scanned } IF (offset = LENGTH(phrase)) THEOCEDURE scan_symbol; { INPUT: offset points at non-seperator } VAR sym_index : INTEGER; { Symbol list index } sym_found : BOOLEAN; { Symbol found in list flag } old_char : CHAR; { Current character in phrase } token_kind := trix_token.t; { TYPE CONVERSION } END; ( & {$IFC F_BUG} EP('SCAN_IDENTIFIER'); {$ENDC} ( END; { ----- scan_identifier ----- } { -------------------------------------------------------------------------- } PRLSE BEGIN { *********************************************** *** SEE NOTE IN ROUTINE scan_symbol BELOW *** *********************************************** }  trix_token.i := id_index; IF (v_ExtIDListPtr <> NIL) THEN { External list alive ? } search_External_ID_List(id_2) { Yeah, so search it } ELSE token_kind := tk_Identifier; { No , so return IDENTIFIER } END END; UNTIL id_found OR (id_index = ORD(tk_SpecEND)); { Stop ? } token := id_1; { Setup token phrase for caller's use } ( IF NOT(id_found) THEN { Match found ? } BEGIN { No, so search external identifier list } th); id_index := ORD(tk_SpecSTART) + 1; { Start the search } REPEAT BEGIN id_found := (id_2 = v_IDList[id_index]); { Match found ? } , ,IF NOT(id_found) THEN .id_index := id_index + 1; { Bump index } Ed identifier in the identifier list } id_2 := id_1; { Save the identifier & convert it to uppercase } uppercase(id_2); IF (LENGTH(id_2) > k_IDLength) THEN { Identifiers have FIXED length } id_2 := COPY(id_2,1,k_IDLeng= tk_LessThan; * * ORD(tk_GreaterThan) : token_kind := tk_GreaterThan; * * ORD(tk_LBraket) : token_kind := tk_LBraket; * * ORD(tk_RBraket) : token_kind := tk_RBraket; * * ORD(tk_Period) : token_kind := tk_Period; * * ORD(tk_Comma) : token_kind := tk_Comma; * * * * THUS, THE CODE THAT REPLACES THE ABOVE LARGE CASE * * STATEMENT WOULD BE: * * ONE (1) WORD OF MEMORY. HOW THIS WORD IS MANIPULATED IN * * MEMORY IS TOTALLY UP TO THE COMPILER AND ITS CONTENTS * * HAVE NO IMPLIED MEANING. * * * NOW trix.i REFERS TO A VALUE OF TYPE INTEGER, AND trix.t * * REFERS TO A VALUE OF TYPE ts_TokenType. THIS TRICK WORKS * * BECAUSE INTEGERS AND ENUMERATED TYPES IN PASCAL OCCUPY * * _TokenType); * * END; * * * * * VAR trix : RECORD CASE BOOLEAN OF * * FALSE : (i : INTEGER); * * TRUE : (t : ts * * YOU CAN AVOID THE ABOVE MESS BY USING A PASCAL TYPE * * CONVERSION TRICK KNOWN AS A "FREE UNION VARIANT RECORD": * * * END; * * * * --------------------------------------------------------- * * = tk_Quote; * * ORD(tk_Exclamation) : token_kind := tk_Exclamation; * * ORD(tk_Ampersand) : token_kind := tk_Ampersand; * r) : token_kind := tk_VerticalBar; * * ORD(tk_BackwardSlash) : token_kind := tk_BackwardSlash; * * ORD(tk_Question) : token_kind := tk_Question; * * ORD(tk_Quote) : token_kind : ORD(tk_Dollar) : token_kind := tk_Dollar; * * ORD(tk_Percent) : token_kind := tk_Percent; * * ORD(tk_Underscore) : token_kind := tk_Underscore; * * ORD(tk_VerticalBa * ORD(tk_LTick) : token_kind := tk_LTick; * * ORD(tk_STick) : token_kind := tk_STick; * * ORD(tk_Pound) : token_kind := tk_Pound; * * = tk_LBrace; * * ORD(tk_RBrace) : token_kind := tk_RBrace; * * ORD(tk_Tilde) : token_kind := tk_Tilde; * : token_kind := tk_SemiColon; * * ORD(tk_Carrot) : token_kind := tk_Carrot; * * ORD(tk_At) : token_kind := tk_At; * * ORD(tk_LBrace) : token_kind : ORD(tk_LParenthesis) : token_kind := tk_LParenthesis; * * ORD(tk_RParenthesis) : token_kind := tk_RParenthesis * * ORD(tk_Colon) : token_kind := tk_Colon; * * ORD(tk_SemiColon) * * trix.i := sym_index; * * token_kind := trix.t; * * * **************************** NOTE **************************** }  trix_token.i := sym_index; token_kind := trix_token.t; { TY tk_SymUNKNOWN; { Unknown symbol } END ELSE { Non-seperator found, so process it further } BEGIN IF (phrase[offset] IN ['A'..'Z','a'..'z']) THEN scan_identifier { Process identifiers (Eg: 'PACKED') } et as a seperator } IF seperator_found(phrase[offset]) THEN BEGIN { Seperator character found so return it to caller } token := '?'; token[1] := phrase[offset]; offset := offset +1; token_kind := END; { ----- scan_symbol ----- } { -------------------------------------------------------------------------- } BEGIN { ----- TS_GetToken ----- } $ &{$IFC F_BUG} BP('TS_GetToken'); {$ENDC} & { Test the character pointed to by the offs*********************************************** }  trix_token.i := sym_index; token_kind := trix_token.t; { TYPE CONVERSION } END; END; ( & {$IFC F_BUG} EP('SCAN_SYMBOL'); {$ENDC} ( token_kind := tk_SymUNKNOWN { Unknown SINGLE length token } ELSE BEGIN { *********************************************** *** SEE NOTE IN ROUTINE scan_symbol ABOVE *** BEGIN sym_found := (token = v_IDList[sym_index]); 0 0IF NOT(sym_found) THEN 2sym_index := sym_index + 1; END; UNTIL sym_found OR (sym_index = ORD(tk_SymEND)); IF NOT(sym_found) THEN offset := offset + 2; { Point after new_char } END; END; { Search for SINGLE or DOUBLE length token in symbol list } sym_index := ORD(tk_SymSTART) + 1; REPEAT fset := offset + 1; { Point at new_char } END ELSE { token = '??' } BEGIN { DOUBLE length symbol } token[1] := old_char; token[2] := new_char; = '.') THEN token := '??'; IF (old_char = '.') AND (new_char = ')') THEN token := '??'; IF (token = '?') THEN BEGIN { SINGLE length symbol } token[1] := old_char; ofhar = '.') AND (new_char = '.') THEN token := '??'; IF (old_char = '(') AND (new_char = '*') THEN token := '??'; IF (old_char = '*') AND (new_char = ')') THEN token := '??'; IF (old_char = '(') AND (new_char IF (old_char = '<') AND (new_char = '>') THEN token := '??'; IF (old_char = '>') AND (new_char = '=') THEN token := '??'; IF (old_char = ':') AND (new_char = '=') THEN token := '??'; IF (old_c + 1; { Point at new_char } END ELSE { Handle the (possible) DOUBLE symbol } BEGIN token := '?'; { Assume SINGLE length symbol } { Attempt DOUBLE length symbol match } the new character is a seperator (i.e., non-symbol) } IF seperator_found(new_char) THEN BEGIN { Handle the SINGLE symbol } token := '?'; token[1] := old_char; offset := offsetPE CONVERSION } END; END ELSE { Non-last symbol character scanner } BEGIN old_char := phrase[offset ]; { Get the next 2 characters } new_char := phrase[offset + 1]; { Test if ELSE scan_symbol; { Process special symbols (Eg: ':=' ) } END; TS_GetToken := token_kind; & &{$IFC F_BUG} EP('TS_GetToken'); {$ENDC} & END; { ----- TS_GetToken ----- } ( UTOKENSE (* { *) tk_RBrace, (* } *) tk_Tilde, { ~ } tk_LTick, { ` } tk_STick, { ' } tk_Pound, } tk_Colon, { : } tk_SemiColon, { ; } tk_Carrot, { ^ } tk_At, { @ } tk_LBrace, tk_RBraket, { ] } tk_Period, { . } tk_Comma, { , } tk_LParenthesis, { ( } tk_RParenthesis, { ) { / } tk_Equal, { = } tk_LessThan, { < } tk_GreaterThan, { > } tk_LBraket, { [ } tk_SymSTART, { Start of symbols } tk_Plus, { + } tk_Minus, { - } tk_Times, { * } tk_Slash, STRING[ts_k_MaxPhLength]; { Phrase line } ts_Offset = 1..ts_k_MaxPhLength; { Phrase line offset } { Pascal Symbols, Reserved words, and Predefined words } ts_TokenType = (tk_SymUNKNOWN, { Unknown symbol } ts_k_MaxPhLength = 131; { Maximum length of a phrase line in characters } $ { -------------------------------------------------------------------------- } TYPE ts_Error = INTEGER; { Error result } ts_Phrase =:'')PBBINTEGER xtiREAL toCHAR OSBOOLEAN vthSTRING 0 5TEXT :$emINTERACT*hiINPUT &$ * * * ************************************************************************** } CONST ts_k_NoError = 0; { No error result [///] } F runtime string checking }  { ************************************************************************** * * * P U B L I C C O N S T A N T S / T Y P E S / V A R I A B L E S  "{$SETC F_BUG := FALSE} { Enable/Disable runtime debugger } " "{$IFC F_BUG} ${ Load the Debugger if needed } $ " USES {$USING .D2/UDEBUG.CODE} U_PDebugger; "{$ENDC} " "{$IOCHECK- } { Turn OFF runtime I/O checking } "{$VARSTRING-} { Turn OFprstuvwxyz{|}~ { # } tk_Dollar, { $ } tk_Percent, { % } tk_Underscore, { _ } tk_VerticalBar, { | } tk_BackwardSlash, { \ } tk_Question, { ? } tk_Quote, { " } tk_Exclamation, { ! } tk_Ampersand, { & tk_FILE, { FILE } tk_FILLCHAR, { FILLCHAR } tk_FOR, { FOR } tk_FORWARD, { FORWARD } tk_EXP, { EXP } tk_EXTENDED, { EXTENDED } tk_EXTERNAL, { EXTERNAL } tk_FALSE, { FALSE } tk_END, { END } tk_EOF, { EOF } tk_EOLN, { EOLN } tk_EXIT, { EXIT } tk_DO, { DO } tk_DOUBLE, { DOUBLE } tk_DOWNTO, { DOWNTO } tk_ELSE, { ELSE } tk_DATA, { DATA } tk_DELETE, { DELETE } tk_DISPOSE, { DISPOSE } tk_DIV, { DIV } tk_COS, { COS } tk_CREATION, { CREATION } tk_CRUNCH, { CRUNCH } tk_CYCLE, { CYCLE } tk_COMP, { COMP } tk_CONCAT, { CONCAT } tk_CONST, { CONST } tk_COPY, { COPY } tk_CHAR, { CHAR } tk_CHR, { CHR } tk_CLOSE, { CLOSE } tk_CODE, { CODE } tk_BLKWRITE, { BLOCKWRITE } tk_BOOLEAN, { BOOLEAN } tk_BYTESTREAM, { BYTESTREAM } tk_CASE, { CASE } tk_ARRAY, { ARRAY } tk_ATTACH, { ATTACH } tk_BEGIN, { BEGIN } tk_BLKREAD, { BLOCKREAD } tk_ABS, { ABS } tk_AND, { AND } tk_ATAN, { ATAN } tk_ARCTAN, { ARCTAN } tk_R2Braket, { .) } { = ']' in MacPascal } tk_SymEND, { End of symbols } tk_SpecSTART, { Start of special words } { .. } tk_Power, { ** } tk_LComment, { (* } tk_RComment, { *) } tk_L2Braket, { (. } { = '[' in MacPascal } } tk_NotEqual, { <> } tk_LE, { <= } tk_GE, { >= } tk_Assignment, { := } tk_Ellipse, tk_FUNCTION, { FUNCTION } tk_GET, { GET } tk_GOTO, { GOTO } tk_GOTOXY, { GOTOXY } tk_HALT, { HALT } tk_HEAPRESULT, { HEAPRESULT } tk_IDSEARCH, { IDSEARCH } tk_IF, { IF } tk_PWROFTEN, { PWROFTEN } tk_READ, { READ } tk_READLN, { READLN } tk_REAL, { REAL } tk_PRUCESSID, { PROCESSID } tk_PROGRAM, { PROGRAM } tk_PURGE, { PURGE } tk_PUT, { PUT } tk_POS, { POS } tk_PRED, { PRED } tk_PROCEDURE, { PROCEDURE } tk_PRACESS, { PROCESS } tk_PACKED, { PACKED } tk_PAGE, { PAGE } tk_PMACHINE, { PMACHINE } tk_POINTER, { POINTER } tk_ORD4, { ORD4 } tk_OTHERWISE, { OTHERWISE } tk_OUTPUT, { OUTPUT } tk_PACK, { PACK } tk_ODD, { ODD } tk_OF, { OF } tk_OR, { OR } tk_ORD, { ORD } tk_NEW, { NEW } tk_NIL, { NIL } tk_NORMAL, { NORMAL } tk_NOT, { NOT } tk_METHODS, { METHODS } tk_MOD, { MOD } tk_MOVELEFT, { MOVELEFT } tk_MOVERIGHT, { MOVERIGHT } tk_MAXINT, { MAXINT } tk_MEMAVAIL, { MEMAVAIL } tk_MEMLOCK, { MEMLOCK } tk_MEMSWAP, { MEMSWAP } tk_LOCK, { LOCK } tk_LOG, { LOG } tk_LONGINT, { LONGINT } tk_MARK, { MARK } tk_LABEL, { LABEL } tk_LEAVE, { LEAVE } tk_LENGTH, { LENGTH } tk_LN, { LN } tk_INTRINSIC, { INTRINSIC } tk_IORESULT, { IORESULT } tk_KEYBOARD, { KEYBOARD } tk_KEYPRESS, { KEYPRESS } tk_INSERT, { INSERT } tk_INTEGER, { INTEGER } tk_INTERACTIVE, { INTERACTIVE } tk_INTURFACE, { INTERFACE } tk_IMPLEMENTATION, { IMPLEMENTATION } tk_IN, { IN } tk_INLINE, { INLINE } tk_INPUT, { INPUT } tk_RECORD, { RECORD } tk_RELEASE, { RELEASE } tk_REPEAT, { REPEAT } tk_RESET, { RESET } tk_REWRITE, { REWRITE } tk_ROUND, { ROUND } tk_SCAN, { SCAN } tk_SCANEQ, { SCANEQ } last in this list *** *********************************************** } tk_Identifier); { User-defined identifier } "VAR gv_ExtFile : TEXT; { External ID list file } &gv_IncFile : TEXT; { External tk_SpecEND, { End of special words } tk_ExtTOKEN, { External token } { *********************************************** *** tk_Identifier MUST be tk_WORDSTREAM, { WORDSTREAM } tk_WPROTECT, { WPROTECT } tk_WRITE, { WRITE } tk_WRYTELN, { WRITELN } tk_VARNEW, { VARNEW } tk_WAIT, { WAIT } tk_WHILE, { WHILE } tk_WITH, { WITH } tk_USES, { USES } tk_VAR, { VAR } tk_VARAVAIL, { VARAVAIL } tk_VARDISPOSE, { VARDISPOSE } tk_UNTSTATUS, { UNITSTATUS } tk_UNTWAIT, { UNITWAIT } tk_UNTWRITE, { UNITWRITE } tk_UNTIL, { UNTIL } tk_UNPROTECT, { UNPROTECT } tk_UNTBUSY, { UNITBUSY } tk_UNTCLEAR, { UNITCLEAR } tk_UNTREAD, { UNITREAD } tk_TRUNC, { TRUNC } tk_TYPE, { TYPE } tk_UNIT, { UNIT } tk_UNPACK, { UNPACK } tk_TIME, { TIME } tk_TO, { TO } tk_TREESEARCH, { TREESEARCH } tk_TRUE, { TRUE } tk_SUCC, { SUCC } tk_TAN, { TAN } tk_TEXT, { TEXT } tk_THEN, { THEN } tk_SQRT, { SQRT } tk_START, { START } tk_STR, { STR } tk_STRING, { STRING } tk_SIN, { SIN } tk_SINGLE, { SINGLE } tk_SIZEOF, { SIZEOF } tk_SQR, { SQR } tk_SEMINIT, { SEMINIT } tk_SEPARATE, { SEPARATE } tk_SET, { SET } tk_SIGNAL, { SIGNAL } tk_SCANNE, { SCANNE } tk_SEEK, { SEEK } tk_SEGMENT, { SEGMENT } tk_SEMAPHORE, { SEMAPHORE } ID list INCLUDE file } {^FF} { ************************************************************************** * * * P U B L I C R O U T I N E S * * * ************************************************************************** } { ||||||||||||||||||||mment tokens and quote tokens are | tested correctly. |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| } FUNCTION TS_GetToken( phrase : ts_Phrase; VAR offset : ts_Offset; This routine ONLY processes primitive tokens; processing of | comments and quoted string constants must be done by other | routines. But this other processing is not difficult if | the standard Pascal co | tk_LBrace : handle_left_comment | tk_WHILE : handle_WHILE_keyword | etc... | END | UNTIL offset > LENGTH(phrase) (* Stop when all is scanned *) | | (* Initialize the character offset *) | | (* Scan the source line token by token *) | | REPEAT | token_kind := TS_GetToken(phrase,offset,token) | CASE token_kind OF the external identifier list last if | this list exists. | | A typical algorithm using TS_GetToken is as follows: | | READLN(phrase) (* Read an entire source line *) | | offset := 1 S.....: This is the MAIN routine for this unit. The method used to | scan the source line consists of searching the symbol tokens | first, searching the internal special words (identifiers) | second, and searching | offset - Character index into the line (starts at 1) | OUTPUT....: offset - Index to character immediately following the token | token - Token phrase that was found. | Type of token found is returned. | NOTEF} { |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| | ROUTINE...: TS_GetToken | PURPOSE...: Scan a source phrase line for Pascal tokens. | INPUT.....: phrase - Source phrase line to scan en list exists, then it is removed. | Error result returned. | NOTES.....: This routine MUST be called last ! |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| } FUNCTION TS_TerminateTokenSearch : ts_Error; {^Fch(identifier_file : ts_Phrase) : ts_Error; { |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| | ROUTINE...: TS_TerminateTokenSearch | PURPOSE...: Terminate this unit. | INPUT.....: (none) | OUTPUT....: If an external tok | token list. | Error result returned. | NOTES.....: This routine MUST be called before calling below routines ! |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| } FUNCTION TS_InitializeTokenSeartialize this unit. | INPUT.....: identifier_file - Name of external TEXT identifier file name | OUTPUT....: Internal token list initialized and if identifier_file exists | then the tokens listed in it are loaded into the external one) |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| } FUNCTION TS_Version : INTEGER; { |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| | ROUTINE...: TS_InitializeTokenSearch | PURPOSE...: Ini|||||||||||||||||||||||||||||||||||||||||||||||||||||| | ROUTINE...: TS_Version | PURPOSE...: Specify the version number of this unit. | INPUT.....: (none) | OUTPUT....: Version number returned with format X.YZ (Eg; 145 --> 1.45) | NOTES.....: (n VAR token : ts_Phrase) : ts_TokenType; {^FF} { [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][] [] [] [] I M P L E M E N T A T I O N [] [] [] [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][] } IMPLEMENTATION áDG Gá%FFFá*GGá%FFFáGGG,GGá%FFFáGGGFت"DDáGǃ"DDás ײGšGצ Gצ GáGš7G צUNTIL צUSES VAR׮ VARAVAIL׮ צ VARDISPOSE VARNEW׮ צWAIT WHILE׮ WITH׮ צ WORDSTREAM WPROTECT׮ צWRITE צWRITELN צ???p ڪFHEN׮ צTIME TO׮ צ TREESEARCH TRUE׮ צTRUNC צTYPE צUNIT UNPACK׮ צ UNPROTECT צUNITBUSY UNITCLEAR׮ UNITREAD׮ צ UNITSTATUS UNITWAIT׮ צ UNITWRITEצSEEK SEGMENT׮ SEMAPHORE׮ SEMINIT׮ SEPARATE׮ צSET צSIGNAL SIN׮ SINGLE׮ צSIZEOF SQR׮ SQRT׮ צSTART צSTR צSTRING SUCC׮ צTAN צTEXT TSSID׮ PROGRAM׮ PURGE׮ PUT׮ PWROFTEN׮v  צREAD READLN׮ צREAL RECORD׮ צRELEASE צREPEAT RESET׮ REWRITE׮ ROUND׮ SCAN׮ צSCANEQ SCANNE׮ ORMAL׮ צNOT צODD צOF OR׮ צORD צORD4 OTHERWISE׮ OUTPUT׮ צPACK PACKED׮ צPAGE PMACHINE׮ צPOINTER צPOS צPRED PROCEDURE׮ PROCESS׮ PROCEVE צLABEL צLENGTH LN׮ צLOCK LOG׮ LONGINT׮ MARK׮ צMAXINT MEMAVAIL׮ צMEMLOCK צMEMSWAP צMETHODS צMOD צMOVELEFT MOVERIGHT׮ NEW׮ NIL׮ NT׮ צIDSEARCH IF׮ צIMPLEMENTATION IN׮ צINLINE INPUT׮ INSERT׮ צINTEGER צ INTERACTIVE צ INTERFACE צ INTRINSIC צIORESULT  צKEYBOARD KEYPRESS׮ צLEAE END׮ EOF׮ EOLN׮ צEXIT EXP׮ EXTENDED׮ צEXTERNAL FALSE׮ FILE׮ צFILLCHAR FOR׮ FORWARD׮ FUNCTION׮ צGET צGOTO GOTOXY׮ צHALT HEAPRESUL CLOSE׮ CODE׮ צCOMP CONCAT׮ צCONST צCOPY COS׮ CREATION׮ צCRUNCH CYCLE׮ DATA׮ צDELETE DISPOSE׮ DIV׮ DO׮ צDOUBLE DOWNTO׮  צELS .)׮ צ???z  צ??? צABS צAND צATAN ARCTAN׮ צARRAY צATTACH BEGIN׮ BLOCKREAD׮ BLOCKWRITE׮ צBOOLEAN צ BYTESTREAM CASE׮ צCHAR CHR׮ . , ( ) : ; ^ @ { } ~ ` ' # $ % _ | \ ? " ! & צ<> <=׮ צ>= :=׮ צ.. **׮ צ(* *)׮ צ(.š5ٛ ٛٛaAá2FتšEE>  צ??? צ??? + - * / = < > [ ]E VAR token : ts_Phrase) : ts_TokenType; {^FF} { [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][] [] [] *ˡ-G<ˡ#GšGGEEGD Dˍ  ڪ"FFáGǃ"FFáwצ GšG Gצ GáGš@G*ˡ7G<á GG!GšGGƀƀGF FˍF˄!á%FFF' c ڪFצFF.ˡ!á%*!~ōتHߓޟˡO^±%FR.D3/UTS.CODE YQC.D3/UTS $ %% ?<>Ä צ??>=Ä ??ת:=Ä צ??..Ä ??ת(*Ä צ??*)Ä ??ת(.Ä צ??.)Ä ??ת?ڿǃڿۿǃٓ,ÍGVEXTFILd x GVINCFIL 3 B VIDLIST $XrVEXTIDLI = q w a ,1{$ #NB\  (n0&Z,?ڿǃ?<>Ä צ??>=Ä ??ת:=Ä צ??..Ä ??ת(*Ä צ??*)Ä ??ת(.Ä צ??.)Ä ??ת?ڿǃڿۿǃٓ,ÍٓH ظIIH:Aܪ?ǃH#H ^ptHFNB\  (n0&Z,?ڿǃ?<>Ä צ??>=Ä ??ת:=Ä צ??..Ä ??ת(*Ä צ??*)Ä ??ת(.Ä צ??.)Ä ??ת?ڿǃڿۿǃٓ,Íʀ̀ʀʀÍʀˡCH ʀIIH_  *áa?ǃٓ,ÍٓH ظIIH?ڿǃÍߡH#F?ƀ?ǃ̀ʀX̀ʀ1ƀ̀ƀǃƀƀDŽƀʀCCCšCCƀƀ-̀Cʀ̀ʀ program uts_test_file; "const a = 1; (b = 1.2345; (c = 'david'; " "type paoc = packed array [0..15] of char; (trix = record case boolean of 1false : (i : integer); 1true : (b : packed array [0..15] of 0..1); /end; " "var trixy : trix; (VE צLABEL צLENGTH LN׮ צLOCK LOG׮ LONGINT׮ MARK׮ צMAXINT MEMAVAIL׮ צMEMLOCK צMEMSWAP צMETHODS צMOD צMOVELEFT MOVERIGHT׮ NEW׮ NIL׮ NT׮ צIDSEARCH IF׮ צIMPLEMENTATION IN׮ צINLINE INPUT׮ INSERT׮ צINTEGER צ INTERACTIVE צ INTERFACE צ INTRINSIC צIORESULT  צKEYBOARD KEYPRESS׮ צLEAE END׮ EOF׮ EOLN׮ צEXIT EXP׮ EXTENDED׮ צEXTERNAL FALSE׮ FILE׮ צFILLCHAR FOR׮ FORWARD׮ FUNCTION׮ צGET צGOTO GOTOXY׮ צHALT HEAPRESUL CLOSE׮ CODE׮ צCOMP CONCAT׮ צCONST צCOPY COS׮ CREATION׮ צCRUNCH CYCLE׮ DATA׮ צDELETE DISPOSE׮ DIV׮ DO׮ צDOUBLE DOWNTO׮  צELS .)׮ צ???z  צ??? צABS צAND צATAN ARCTAN׮ צARRAY צATTACH BEGIN׮ BLOCKREAD׮ BLOCKWRITE׮ צBOOLEAN צ BYTESTREAM CASE׮ צCHAR CHR׮ . , ( ) : ; ^ @ { } ~ ` ' # $ % _ | \ ? " ! & צ<> <=׮ צ>= :=׮ צ.. **׮ צ(* *)׮ צ(.š5ٛ ٛٛaAá2Fتš|EE|>  צ??? צ??? + - * / = < > [ ]    \TOKENSEAUTOKENSEALPHA OMEGA INTRODUCFETCHPASPROCESSPSHOWERRO int : integer;  "begin $int := 5 * 4 div (3 + 7) mod 31415 - 27172; "end. " "(* the end *)  ORMAL׮ צNOT צODD צOF OR׮ צORD צORD4 OTHERWISE׮ OUTPUT׮ צPACK PACKED׮ צPAGE PMACHINE׮ צPOINTER צPOS צPRED PROCEDURE׮ PROCESS׮ PROCESSID׮ PROGRAM׮ PURGE׮ PUT׮ PWROFTEN׮v  צREAD READLN׮ צREAL RECORD׮ צRELEASE צREPEAT RESET׮ REWRITE׮ ROUND׮ SCAN׮ צSCANEQ SCANNE׮  RK.CODE[*]WH%HCompile what text? oG Compiling... ^^YYY#9:UTS.TEST.CODE[*]t\JJNz^to^EDJjnt|t+|l@;Y;#9:UTS.TEST.CODElLY8LKEXEC//K{KExecute what file? #9:UTS.TEST.TEXTfr*t|t+|  tt#94ytx2JJ:>r]tJJJN]t] ^^YYW ^5WECommand: E(dit, R(un, F(ile, C(omp, L(ink, X(ecute, A(ssem, ئRK.CODE[*]WH%HCompile what text? oG Compiling... ^^YYY#9:UTS.TEST.CODE[*]t\JJNz^to^EDJjnt|t+|l@;Y;#9:UTS.TEST.CODElLY8LKEXEC//K{KExecute what file? ?<>Ä צ??>=Ä ??ת:=Ä צ??..Ä ??ת(*Ä צ??*)Ä ??ת(.Ä צ??.)Ä ??ת?ڿǃڿۿǃٓ,ÍٓH ظIIH:Aܪ?ǃH#H ^ptHFNB\  (n0&Z,?ڿǃ?<>Ä צ??>=Ä ??ת:=Ä צ??..Ä ??ת(*Ä צ??*)Ä ??ת(.Ä צ??.)Ä ??ת?ڿǃڿۿǃ|ٓ,Íʀ̀ʀʀÍʀˡCH ʀIIH_  *áa?ǃ|ٓ,ÍٓH ظIIH?ڿǃÍߡH#F?ƀ?ǃ̀ʀX̀ʀ1ƀ̀ƀǃƀƀDŽƀʀCCCšCCƀƀ-̀C|ʀ̀ʀGF FˍF˄!á%FFF' c ڪFצFF.ˡ!á%*!~ōتHߓޟˡ*ˡ-G<ˡ#GšGGEEGD* Dˍ*  ڪ"FFáGǃ"FFáwצ GšG Gצ GáGš@G*ˡ7G<á GG!GšGGƀƀáDG Gá%FFFá*GGá%FFFáGGG,GGá%FFFáGGGFت*"DDá*Gǃ*"DDás ײGšGצ Gצ GáGš7G צUNTIL צUSES VAR׮ VARAVAIL׮ צ VARDISPOSE VARNEW׮ צWAIT WHILE׮ WITH׮ צ WORDSTREAM WPROTECT׮ צWRITE צWRITELN צ???p ڪFHEN׮ צTIME TO׮ צ TREESEARCH TRUE׮ צTRUNC צTYPE צUNIT UNPACK׮ צ UNPROTECT צUNITBUSY UNITCLEAR׮ UNITREAD׮ צ UNITSTATUS UNITWAIT׮ צ UNITWRITEצSEEK SEGMENT׮ SEMAPHORE׮ SEMINIT׮ SEPARATE׮ צSET צSIGNAL SIN׮ SINGLE׮ צSIZEOF SQR׮ SQRT׮ צSTART צSTR צSTRING SUCC׮ צTAN צTEXT T #9:UTS.TEST.TEXTfr*t|t+|  tt#94ytx2JJ:>r]tJJJN]t] ^^YYW ^5WECommand: E(dit, R(un, F(ile, C(omp, L(ink, X(ecute, A(ssem, 0Token Search UNIT Tester [by David Craig - 1987]T YYY#9:UTS.TEST.CODE[*]t\JJNz^to^EDJjnt|t+|l@;Y;#9:UTS.TEST.CODElLY8LKEXEC//K{KExecute what file? O^±$% FR.D3/UTS.TEST.CODE YQ C.D3/UTS.TEST $ L.D3/UTS.TEST .D1/UDEBUG .D3/UTS .D3/UTS.TEST X.D3/UTS.TEST %% ,ȄƂ٦ SYMBOL תʂ-ʂȄƂצ RESERVED ʂáƂ٦ EXT. TOKENתʂáƂצ IDENTIFIERצType: [ʂ ] Ƃ | צName: "Ƃ"ʂƂSš, ˍ,, *P)QQˡalphaשQ C R{ { RQ Qˡprocess_Pascal_FileשQ {Q QˡomegaשQ צThat's all, Folks...* <#NOWN ʂʂ,ȄƂ٦ SYMBOL תʂ-ʂȄƂצ RESERVED ʂáƂ٦ EXT. TOKENתʂáƂצ IDENTIFIERצType: [ʂ ] Ƃ | צName: "Ƃ"ʂƂSš, ˍ,, ٪Pצ *** ERROR : צ Routine "צ" failed with error #  Rz ,؞"áƂSšǃ̂ƂSʂ؛ áʂǃ̂عƂSƂƂ̂Ƃ٦ ??????????תʂáƂצ UNKNOWN ʂʂ,ȄƂ٦ SYMBOL תʂ-ʂȄƂצ RESERVED ʂáƂ٦ EXT. TOKENתʂáƂצ IDENTIFIERצType: [ʂ ] Ƃ | צName: "Ƃ"ʂƂSš, ˍ,, !#d2 צScanning Pascal program file "" ...,؞"á,ƂSǃ,؞"áƂSšǃ̂ƂSʂ؛ áʂǃ̂عƂSƂƂ̂Ƃ٦ ??????????תʂáƂצ UNKNOWN ʂʂ,ȄƂ٦ SYMBOL תʂ-ʂȄƂצ RESERVED ʂáƂ٦ EXT. TOKENתʂáƂצ IDENTIFIERצType: [ʂ ] Ƃ | צName: "Ƃ"ʂƂSš, ˍ,, ٪P,ƂRצScanning Pascal program file "" ...,؞"á,ƂSǃ,؞"áƂSšǃ̂ƂSʂ؛ áʂǃ̂عƂSƂƂ̂Ƃ٦ ??????????תʂáƂצ UNKNOWN ʂʂV TEST.TEXTfr*t|t+|  tt#94ytx2JJ:>r]tJJJN]t] ^^YYW ^5WECommand: E(dit, R(un, F(ile, C(omp, L(ink, X(ecute, A(ssem, š5ٛ ٛٛaAá2F/Pascal file to scan (Press to Quit) ? PáU.á >.TEXTצ.TEXTÍPצ.TEXTUP #9:UTS.TEST.TEXTfr*t|t+|  tt#94ytx2JJ:>r]tJJJN]t] ^^YYW ^5WECommand: E(dit, R(un, F(ile, C(omp, L(ink, X(ecute, A(ssem, L_FILE'); {$ENDC} & WRITELN; WRITE('Pascal file to scan (Press to Quit) ? '); READLN(file_name); & &IF (LENGTH(file_name) = 0) THEN quit := TRUE AELSE quit := FALSE; IF NOT(quit) THEN BEGIN ( *{$IFC F_BUG} PDindex := index - 1; END; UNTIL (index = 0); END; END; { uppercase } { ------------------------------------------------------------------------- } BEGIN { fetch_Pascal_File } $ &{$IFC F_BUG} BP('FETCH_PASCA IF (LENGTH(s) > 0) THEN BEGIN index := LENGTH(s); REPEAT BEGIN IF s[index] IN ['a'..'z'] THEN s[index] := CHR(ORD(s[index]) - ORD('a') + ORD('A')); t : BOOLEAN); CONST suffix = '.TEXT'; { ------------------------------------------------------------------------- } PROCEDURE uppercase(VAR s : t_String); VAR index : INTEGER; BEGIN { uppercase } C F_BUG} EP('INTRODUCTION'); {$ENDC} & END; { introduction } { ------------------------------------------------------------------------- } SEGMENT PROCEDURE fetch_Pascal_File(VAR file_name : t_String; VAR qui----------------------------------- } SEGMENT PROCEDURE introduction; BEGIN { introduction } $ &{$IFC F_BUG} BP('INTRODUCTION'); {$ENDC} & WRITELN; WRITELN('Token Search UNIT Tester [by David Craig - 1987]'); WRITELN; & &{$IF{ ------------------------------------------------------------------------- } SEGMENT PROCEDURE omega(VAR error : ts_Error); BEGIN { omega } & error := TS_TerminateTokenSearch; & END; { omega } { --------------------------------------ng; g_Quit : BOOLEAN; { ------------------------------------------------------------------------- } SEGMENT PROCEDURE alpha(VAR error : ts_Error); BEGIN { alpha } & error := TS_InitializeTokenSearch(''); & END; { alpha } ES " {$IFC F_BUG} ${$USING UDEBUG.CODE} U_PDebugger, ${$ENDC} $ " {$U .D3/UTS.CODE} U_TokenSearch; { The Token Search UNIT } "{$IOCHECK-} {$VARSTRING-} " TYPE t_String = STRING[80]; VAR g_Error : ts_Error; g_FileName : t_Stri [] [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][] } PROGRAM TokenSearch_Tester; { Written in Apple /// Pascal 1.1 } "{$SETC F_BUG := FALSE} { Enable/Disable runtime Debugger }  US { [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][] [] [] [] TOKEN SEARCHER UNIT TEST PROGRAM [] [] _WRITELN(CONCAT('file_name = ',file_name)); {$ENDC} * uppercase(file_name); { Convert to all uppercase characters } { If the file name ends with a period (.) then remove the period } { and use the new name as the file name. } IF (file_name[LENGTH(file_name)] = '.') THEN DELETE(file_name,LENGTH(file_name),1) ELSE BEGIN { Test for the presence of END; END; UNTIL (p_offset > LENGTH(p_line)); END; END; END; UNTIL EOF(p_file) OR (error <> ts_k_NoError); CLOSE(p_file); END; { CASE } > >***********) WRITELN('Type: [',ORD(p_tokenType):3,'] ', kind,' | ', 'Name: "',p_tokenPhrase,'"'); tk_SpecSTART..tk_SpecEND : kind := 'RESERVED '; tk_ExtTOKEN : kind := 'EXT. TOKEN'; tk_Identifier : kind := 'IDENTIFIER'; NTIFIER'; > >(*********** Lisa can handle this CASE @ >CASE p_tokenType OF tk_SymUNKNOWN : kind := 'UNKNOWN '; tk_SymSTART..tk_SymEND : kind := 'SYMBOL '; ) THEN @kind := 'SYMBOL '; @ >IF (p_tokenType >= tk_SpecSTART) AND @ (p_tokenType <= tk_SpecEND ) THEN > kind := 'RESERVED '; > >IF p_tokenType = tk_ExtTOKEN THEN @kind := 'EXT. TOKEN'; > >IF p_tokenType = tk_Identifier THEN @kind := 'IDE p_tokenPhrase); kind := '??????????'; > >IF p_tokenType = tk_SymUNKNOWN THEN > kind := 'UNKNOWN '; @ >IF (p_tokenType >= tk_SymSTART) AND A(p_tokenType <= tk_SymEND p_offset := p_offset + 1 ELSE BEGIN p_tokenType := TS_GetToken(p_line, p_offset, t the beginning of the phrase } { Process each non-space character using TS_GetToken } REPEAT BEGIN IF (p_line[p_offset] = ascii_SPACE) THEN BEGIN READLN(p_file,p_line); error := IORESULT; IF (error = ts_k_NoError) THEN BEGIN IF (LENGTH(p_line) > 0) THEN BEGIN p_offset := 1; { Start aPROCESS_PASCAL_FILE'); {$ENDC} & WRITELN; WRITELN('Scanning Pascal program file "',file_name,'" ...'); WRITELN; RESET(p_file,file_name); error := IORESULT; IF (error = ts_k_NoError) THEN BEGIN REPEAT p_file : TEXT; p_line : ts_Phrase; p_tokenType : ts_TokenType; p_tokenPhrase : ts_Phrase; p_offset : ts_Offset; kind : STRING[31]; BEGIN { process_Pascal_File } $ &{$IFC F_BUG} BP('----------------------------------------- } SEGMENT PROCEDURE process_Pascal_File( file_name : t_String; VAR error : ts_Error); CONST ascii_SPACE = ' '; { ASCII = 32 [$20] } VAR (POS(suffix,file_name) = 0) THEN file_name := CONCAT(file_name,suffix); END; END; ( &{$IFC F_BUG} EP('FETCH_PASCAL_FILE'); {$ENDC} ( END; { fetch_Pascal_File } { -------------------------------- the standard suffix on the name } { and if the suffix is not present then concatenate the suffix } { to the end of the current file name. } IF (LENGTH(file_name) <= LENGTH(suffix)) OR END; ( &{$IFC F_BUG} EP('PROCESS_PASCAL_FILE'); {$ENDC} ( END; { process_Pascal_File } { ------------------------------------------------------------------------- } SEGMENT PROCEDURE show_Error(proc_name : t_String; error : ts_Error); BEGIN { show_Error } WRITELN; WRITELN('*** ERROR : ', 'Routine "',proc_name,'" failed with error # ',error:1); WRITELN; END; { show_Error } { ------------------------- { [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][] [] [] [] -------------------------------------------------------------------- [] [] P A S C A L  O^± END. { TokenSearch_Tester } { the end } < show_Error('process_Pascal_File',g_Error); END; UNTIL g_Quit; END; omega(g_Error); IF (g_Error <> ts_k_NoError) THEN show_Error('omega',g_Error); WRITELN; WRITELN('That''s all, Folks...'); ; {$ENDC} ( introduction; REPEAT BEGIN fetch_Pascal_File(g_FileName,g_Quit); IF NOT(g_Quit) THEN process_Pascal_File(g_FileName,g_Error); IF (g_Error <> ts_k_NoError) THEN ------------------------------------------------ } BEGIN { TokenSearch_Tester } alpha(g_Error); IF (g_Error <> ts_k_NoError) THEN show_Error('alpha',g_Error) ELSE BEGIN & ({$IFC F_BUG} PD_WRITELN('Welcome to the UTS TESTER !') T O K E N S E A R C H E R U N I T [] [] -------------------------------------------------------------------- [] [] [] [] Author : David T. Craig ( 736 Edgewater, Wichita KS 67230 ) [] [] Date : 1987 [] [] Language : Apple /// Pascal 1.1 [] [] Computer : Apple /// [] A NOTE ABOUT (UCSD) PASCAL SOURCE FILE TOKENS [] [] [] [] Pascal source programs consist of the letters 'A'..'Z', 'a'..'z', [] [] the digits '0'..'9',] } { Pretty Printer form feed command comment ---> } {^FF} { [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][] [] [] D BY THE AUTHOR * [] [] ****************************************************************** [] [] [] [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][ [] [] ****************************************************************** [] [] * THIS PROGRAM IS PLACED INTO THE PUBLIC DOMAIN, * [] [] * BUT ALL COMMERCIAL RIGHTS ARE RESERVE [] compiler built-in routine IDSEARCH. For more information see [] [] [] [] Apple /// Pascal Programmer's Manual, Volume 1 (Pages 226-229) [] [] ] [] [] [] REFERENCE [] [] This collection of routines is based on the Apple /// Pascal [] [] [] The token list elements were extracted from UCSD Pascal and [] [] the Pascal compilers made by Apple Computer for its Apple //, [] [] Apple ///, Macintosh, and Lisa computers. [ of the format of the external token files see [] [] routine init_ExternalTokenList. [] [] [] [] NOTES [] checked first, the built-in words next, and then the words in the [] [] linked list. On termination, the linked list memory storage is [] [] deallocated and returned to the general memory pool. [] [] For a description] [] is initialized the file whose name is referenced by the routine [] [] TS_InitializeTokenSearch will have its words read into a linked [] [] list. When TS_GetToken scans a source line the symbols are [] [] [] [] [] If the provided tokens are not suitable, then external tokens [] [] can be included in an external disk TEXT file. When this unit [ction consists of four (4) routines of which [] [] routine TS_GetToken is the most important since it performs the [] [] actual scanning. Each of the routines is described in full in the [] [] INTERFACE part of this source file. [] source lines for symbols, reserved words, and the predefined [] [] identifiers. The found token's name & type are returned. [] [] [] [] The routine colle[] [] [] [] PURPOSE [] [] This code is a collection of routines which scan Pascal language [] and all the other printable characters of the [] [] standard ASCII alphabet (E.g., '(',':','[','+', etc...). [] [] [] [] Blanks (ASCII 32) and carriage returns (ASCII 13) delimit tokens [] [] and format the source file into a legible manner. [] [] [] [] Tokens are the smallest meaningful units of text in a Pascal program [ ts_k_MaxPhLength = 131; { Maximum length of a phrase line in characters } $ { -------------------------------------------------------------------------- } TYPE ts_Error = INTEGER; { Error result } ts_Phrase = * ************************************************************************** } CONST ts_k_NoError = 0; { No error result [///] } ing checking }  { ************************************************************************** * * * P U B L I C C O N S T A N T S / T Y P E S / V A R I A B L E S * * F_BUG := FALSE} { Enable/Disable runtime debugger } " "{$IFC F_BUG} ${ Load the Debugger if needed } $ " USES {$USING .D2/UDEBUG.CODE} U_PDebugger; "{$ENDC} " "{$IOCHECK- } { Turn OFF runtime I/O checking } "{$VARSTRING-} { Turn OFF runtime str [] I N T E R F A C E [] [] [] [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][] } INTERFACE  "{$SETC ] } {^FF} UNIT U_TokenSearch; { [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][] [] [] file, but it can [] [] be changed to any name appropriate for your system. [] [] [] [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][ebugger by setting this constant to FALSE. When [] [] enabled all debugging output will be sent to the file whose name is [] [] contained in the private IMPLEMENTATION constant k_BUG_FILE. [] [] Currently this file name refers to a generic [] This unit contains a primitive run-time debugger which outputs data [] [] to an external file while the unit is running. The debugger is [] [] enabled by setting the private IMPLEMENTATION constant f_DEBUGGER to [] [] TRUE. Disable the d[][] [] [] [] A NOTE ABOUT THE DEBUGGER [] [] [] [] [] [] [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][] } { [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]user, or are new words defined by the user. [] [] Numbers are numeric sequences, labels are special digit-sequences, & [] [] quoted string constants are character sequences delimited by the [] [] quote symbol ('). [] Special symbols are single or double character sequences. Reserved [] [] words are words which are defined by the compiler and can not be [] [] redefined by the user. Identifiers are predefined words which may [] [] be redefined by the ] [] & are classified into special symbols, reserved words, identifiers, [] [] numbers, labels, and quoted string constants. [] [] [] STRING[ts_k_MaxPhLength]; { Phrase line } ts_Offset = 1..ts_k_MaxPhLength; { Phrase line offset } { Pascal Symbols, Reserved words, and Predefined words } ts_TokenType = (tk_SymUNKNOWN, { Unknown symbol } tk_SymSTART, { Start of symbols } tk_Plus, { + } tk_Minus, { - } tk_Times, { * } tk_Slash, tk_COMP, { COMP } tk_CONCAT, { CONCAT } tk_CONST, { CONST } tk_COPY, { COPY } tk_CHAR, { CHAR } tk_CHR, { CHR } tk_CLOSE, { CLOSE } tk_CODE, { CODE } tk_BLKWRITE, { BLOCKWRITE } tk_BOOLEAN, { BOOLEAN } tk_BYTESTREAM, { BYTESTREAM } tk_CASE, { CASE } tk_ARRAY, { ARRAY } tk_ATTACH, { ATTACH } tk_BEGIN, { BEGIN } tk_BLKREAD, { BLOCKREAD } tk_ABS, { ABS } tk_AND, { AND } tk_ATAN, { ATAN } tk_ARCTAN, { ARCTAN } tk_R2Braket, { .) } { = ']' in MacPascal } tk_SymEND, { End of symbols } tk_SpecSTART, { Start of special words } { .. } tk_Power, { ** } tk_LComment, { (* } tk_RComment, { *) } tk_L2Braket, { (. } { = '[' in MacPascal } } tk_NotEqual, { <> } tk_LE, { <= } tk_GE, { >= } tk_Assignment, { := } tk_Ellipse, tk_BackwardSlash, { \ } tk_Question, { ? } tk_Quote, { " } tk_Exclamation, { ! } tk_Ampersand, { & { # } tk_Dollar, { $ } tk_Percent, { % } tk_Underscore, { _ } tk_VerticalBar, { | } (* { *) tk_RBrace, (* } *) tk_Tilde, { ~ } tk_LTick, { ` } tk_STick, { ' } tk_Pound, } tk_Colon, { : } tk_SemiColon, { ; } tk_Carrot, { ^ } tk_At, { @ } tk_LBrace, tk_RBraket, { ] } tk_Period, { . } tk_Comma, { , } tk_LParenthesis, { ( } tk_RParenthesis, { ) { / } tk_Equal, { = } tk_LessThan, { < } tk_GreaterThan, { > } tk_LBraket, { [ } tk_COS, { COS } tk_CREATION, { CREATION } tk_CRUNCH, { CRUNCH } tk_CYCLE, { CYCLE } tk_DATA, { DATA } tk_DELETE, { DELETE } tk_DISPOSE, { DISPOSE } tk_DIV, { DIV } tk_NEW, { NEW } tk_NIL, { NIL } tk_NORMAL, { NORMAL } tk_NOT, { NOT } tk_METHODS, { METHODS } tk_MOD, { MOD } tk_MOVELEFT, { MOVELEFT } tk_MOVERIGHT, { MOVERIGHT } tk_MAXINT, { MAXINT } tk_MEMAVAIL, { MEMAVAIL } tk_MEMLOCK, { MEMLOCK } tk_MEMSWAP, { MEMSWAP } tk_LOCK, { LOCK } tk_LOG, { LOG } tk_LONGINT, { LONGINT } tk_MARK, { MARK } tk_LABEL, { LABEL } tk_LEAVE, { LEAVE } tk_LENGTH, { LENGTH } tk_LN, { LN } tk_INTRINSIC, { INTRINSIC } tk_IORESULT, { IORESULT } tk_KEYBOARD, { KEYBOARD } tk_KEYPRESS, { KEYPRESS } tk_INSERT, { INSERT } tk_INTEGER, { INTEGER } tk_INTERACTIVE, { INTERACTIVE } tk_INTURFACE, { INTERFACE } tk_IMPLEMENTATION, { IMPLEMENTATION } tk_IN, { IN } tk_INLINE, { INLINE } tk_INPUT, { INPUT } tk_HALT, { HALT } tk_HEAPRESULT, { HEAPRESULT } tk_IDSEARCH, { IDSEARCH } tk_IF, { IF } tk_FUNCTION, { FUNCTION } tk_GET, { GET } tk_GOTO, { GOTO } tk_GOTOXY, { GOTOXY } tk_FILE, { FILE } tk_FILLCHAR, { FILLCHAR } tk_FOR, { FOR } tk_FORWARD, { FORWARD } tk_EXP, { EXP } tk_EXTENDED, { EXTENDED } tk_EXTERNAL, { EXTERNAL } tk_FALSE, { FALSE } tk_END, { END } tk_EOF, { EOF } tk_EOLN, { EOLN } tk_EXIT, { EXIT } tk_DO, { DO } tk_DOUBLE, { DOUBLE } tk_DOWNTO, { DOWNTO } tk_ELSE, { ELSE } tk_ODD, { ODD } tk_OF, { OF } tk_OR, { OR } tk_ORD, { ORD } tk_ORD4, { ORD4 } tk_OTHERWISE, { OTHERWISE } tk_OUTPUT, { OUTPUT } tk_PACK, { PACK } tk_UNPROTECT, { UNPROTECT } tk_UNTBUSY, { UNITBUSY } tk_UNTCLEAR, { UNITCLEAR } tk_UNTREAD, { UNITREAD } tk_TRUNC, { TRUNC } tk_TYPE, { TYPE } tk_UNIT, { UNIT } tk_UNPACK, { UNPACK } tk_TIME, { TIME } tk_TO, { TO } tk_TREESEARCH, { TREESEARCH } tk_TRUE, { TRUE } tk_SUCC, { SUCC } tk_TAN, { TAN } tk_TEXT, { TEXT } tk_THEN, { THEN } tk_SQRT, { SQRT } tk_START, { START } tk_STR, { STR } tk_STRING, { STRING } tk_SIN, { SIN } tk_SINGLE, { SINGLE } tk_SIZEOF, { SIZEOF } tk_SQR, { SQR } tk_SEMINIT, { SEMINIT } tk_SEPARATE, { SEPARATE } tk_SET, { SET } tk_SIGNAL, { SIGNAL } tk_SCANNE, { SCANNE } tk_SEEK, { SEEK } tk_SEGMENT, { SEGMENT } tk_SEMAPHORE, { SEMAPHORE } tk_REWRITE, { REWRITE } tk_ROUND, { ROUND } tk_SCAN, { SCAN } tk_SCANEQ, { SCANEQ } tk_RECORD, { RECORD } tk_RELEASE, { RELEASE } tk_REPEAT, { REPEAT } tk_RESET, { RESET } tk_PWROFTEN, { PWROFTEN } tk_READ, { READ } tk_READLN, { READLN } tk_REAL, { REAL } tk_PRUCESSID, { PROCESSID } tk_PROGRAM, { PROGRAM } tk_PURGE, { PURGE } tk_PUT, { PUT } tk_POS, { POS } tk_PRED, { PRED } tk_PROCEDURE, { PROCEDURE } tk_PRACESS, { PROCESS } tk_PACKED, { PACKED } tk_PAGE, { PAGE } tk_PMACHINE, { PMACHINE } tk_POINTER, { POINTER } tk_UNTSTATUS, { UNITSTATUS } tk_UNTWAIT, { UNITWAIT } tk_UNTWRITE, { UNITWRITE } tk_UNTIL, { UNTIL } tk_USES, { USES } tk_VAR, { VAR } tk_VARAVAIL, { VARAVAIL } tk_VARDISPOSE, { VARDISPOSE } | offset - Character index into the line (starts at 1) | OUTPUT....: offset - Index to character immediately following the token | token - Token phrase that was found. | Type of token found is returned. | NOTEF} { |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| | ROUTINE...: TS_GetToken | PURPOSE...: Scan a source phrase line for Pascal tokens. | INPUT.....: phrase - Source phrase line to scan en list exists, then it is removed. | Error result returned. | NOTES.....: This routine MUST be called last ! |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| } FUNCTION TS_TerminateTokenSearch : ts_Error; {^Fch(identifier_file : ts_Phrase) : ts_Error; { |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| | ROUTINE...: TS_TerminateTokenSearch | PURPOSE...: Terminate this unit. | INPUT.....: (none) | OUTPUT....: If an external tok | token list. | Error result returned. | NOTES.....: This routine MUST be called before calling below routines ! |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| } FUNCTION TS_InitializeTokenSeartialize this unit. | INPUT.....: identifier_file - Name of external TEXT identifier file name | OUTPUT....: Internal token list initialized and if identifier_file exists | then the tokens listed in it are loaded into the external one) |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| } FUNCTION TS_Version : INTEGER; { |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| | ROUTINE...: TS_InitializeTokenSearch | PURPOSE...: Ini|||||||||||||||||||||||||||||||||||||||||||||||||||||| | ROUTINE...: TS_Version | PURPOSE...: Specify the version number of this unit. | INPUT.....: (none) | OUTPUT....: Version number returned with format X.YZ (Eg; 145 --> 1.45) | NOTES.....: (n * P U B L I C R O U T I N E S * * * ************************************************************************** } { ||||||||||||||||||||ID list INCLUDE file } {^FF} { ************************************************************************** * * last in this list *** *********************************************** } tk_Identifier); { User-defined identifier } "VAR gv_ExtFile : TEXT; { External ID list file } &gv_IncFile : TEXT; { External tk_SpecEND, { End of special words } tk_ExtTOKEN, { External token } { *********************************************** *** tk_Identifier MUST be tk_WORDSTREAM, { WORDSTREAM } tk_WPROTECT, { WPROTECT } tk_WRITE, { WRITE } tk_WRYTELN, { WRITELN } tk_VARNEW, { VARNEW } tk_WAIT, { WAIT } tk_WHILE, { WHILE } tk_WITH, { WITH } S.....: This is the MAIN routine for this unit. The method used to | scan the source line consists of searching the symbol tokens | first, searching the internal special words (identifiers) | second, and searching the external identifier list last if | this list exists. | | A typical algorithm using TS_GetToken is as follows: | | READLN(phrase) (* Read an entire source line *) | | offset := 1 [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][] } ][][][][][][][][][][][] [] [] [] F I N I S [] [] [] CHECK-} "{$VARSTRING-}  "{$INCLUDE .D3/UTS.1.TEXT } "{$INCLUDE .D3/UTS.2.TEXT } "{$INCLUDE .D3/UTS.3.TEXT } BEGIN { Apple /// Unit initialization routine (unused here) } END. { IMPLEMENTATION } { [][][][][][][][][][][][][][][][][][][][][][][][][][ [] I M P L E M E N T A T I O N [] [] [] [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][] } IMPLEMENTATION "{$IO VAR token : ts_Phrase) : ts_TokenType; {^FF} { [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][] [] [] mment tokens and quote tokens are | tested correctly. |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| } FUNCTION TS_GetToken( phrase : ts_Phrase; VAR offset : ts_Offset; This routine ONLY processes primitive tokens; processing of | comments and quoted string constants must be done by other | routines. But this other processing is not difficult if | the standard Pascal co | tk_LBrace : handle_left_comment | tk_WHILE : handle_WHILE_keyword | etc... | END | UNTIL offset > LENGTH(phrase) (* Stop when all is scanned *) | | (* Initialize the character offset *) | | (* Scan the source line token by token *) | | REPEAT | token_kind := TS_GetToken(phrase,offset,token) | CASE token_kind OF