* Whenever we get new LEX files, sure as Murphy's Law, some will be assembled * and undocumented. Various means have been used to work them out; for * example LISTLEX and Graham Fraser's LEXINFO. For a quick look, LISTLEX is * useful, if rather inadequate. LEXLEX will give high and low tokens, and ID * for a file, KEYWORD gives the keywords and SCANLEX helps to determine the * keyword types. LEXINFO gives all these details, but we need to know the * position of the file in the LEX file chain, and moreover, it occupies some * 7k. Short of full and correct disassembly, there is not much we can do. * As a partial solution to this problem I offer the following LEX file. * A large part of the code is taken straight from SCANLEX (JPC - thanks * PPC PC). Given a keyword, NIBHEX$ returns a null string if it is a * statement, while functions yield the NIBHEX which precedes the entry * for that function. For example, we have in this file, the entry 'nibhex'. * The line immediately preceding it reads NIBHEX 8412. * This could also be written: * NIBHEX 8 * NIBHEX 4 * NIBHEX 1 * NIBHEX 2 * TITAN reads all that backwards because it begins looking from the entry * point, which is the execution address. * It reads first that there can be no more than 2 parameters, no less than 1, * the 1st parameter being a string(4) and the [optional] 2nd being a number. * HORNER has NIBHEX 888888888888888 * and NIBHEX 3F. * So it has at most 15 parameters, at least 3 and all are numbers. * Here is how the parameter types are defined: * string = 4 and number = 8 ; add 2 if it is an array, * ie. string array = 6 and numeric array = A (10 in hex) * if it can be a string or a number, add the string's 4 and the number's 8 * to get C (12 in hex), and add 2 if string or numeric array, ie E (14 in hex) * Thus ADPEEK$ from UTILEX (aka PEEKUTIL) has this nibhex:88A23, that is, * the 1st param can be either a number or a string, the 2nd is a number, while * the 3rd, which is optional, is another number. * MDIM, one of my early efforts, has a nibhex of 8E22 * What all this is leading to, is the LEX file below. * * Examples: NIBHEX$("MDIM")="8E22" and NIBHEX$("HORNER")="8888888888888883F" * * One final note: since the the early portion of the file comes from SCANLEX, * the optional numeric parameter is available to this function. For instance, * we can ask for NIBHEX$("REV$",2), and it will look for the 2nd occurence of * REV$ and return "411". LEX 'NIBHEX' * An aid to receivers of LEX files ID #EC * Jack Elhay, 15/6/88. MSG 0 * see notes above POLL 0 ENTRY nibhex CHAR #F KEY 'NIBHEX$' * Syntax: NIBHEX$([,n]) TOKEN 143 * see notes above for valid parameters values ENDTXT REV$ EQU #1B38E * reverse a string on the MATH STACK EXPR EQU #0F23C * evaluate exprn on stack; general purpose func exit RNDAHX EQU #136CB * pop,round,test & conv to hex integer REVPOP EQU #0BD31 * REV$ then pop a string CSLW5 EQU #0ED3D * 5 full word left shifts of C register NTOKEN EQU #0493B * output ID and token for a keyword ARGERR EQU #0BF19 * invalid argument error exit RESPTR EQU #03172 * reset input pointer prior to NTOKEN call RESCAN EQU #04A4C * lexical analyser restart after undesired match D1C=R3 EQU #03047 * restore D1 and C(A) from R3 FNRTN2 EQU #0F219 * function return, PC in A(A) D=AVMS EQU #1A460 * needed by ADHEAD ADHEAD EQU #181B7 * add header to string on stack NIBHEX 8412 * WHAT THIS IS ALL ABOUT! nibhex P=C 15 * put parameter count in P A=0 A * clear A (ensures a 0 if no 2nd parameter passed) ?P= 1 * was it 1 parameter? GOYES Find1 * yes, skip the pop GOSBVL RNDAHX * no, pop the number GONC Argerr * no negatives D1=D1+ 16 * D1 past the number, point to string header A=A-1 A * don't want a 0 popped GOC Argerr * error if it was 0 Find1 R1=A * save number (less 1 for use as a counter) P= 0 * restore P GOSBVL REVPOP * reverse and pop the string CD1EX * now we have to save D1 and D0 in R3 D1=C C=C+A A * end of string D=C A * save in D - as end of output buffer (FORSTK) GOSBVL CSLW5 CD0EX D0=C R3=C * saved ST=1 0 * set ST0 since we need to know keyword type GOSBVL NTOKEN * A(?-0)=TOKEN, B(A)=execution addr. if it exists Findx ?ST=1 11 * if true, we have tokenised a variable GOYES Argerr * no good, error ?A#0 A * A(A)=0 means GO, no go! GOYES Find2 * ok, no error Argerr GOVLNG ARGERR Find2 AR1EX * pick up the counter A=A-1 A * decrement AR1EX * save in case needed again GOC found * the case we want, leave the loop GOSBVL RESPTR * reset D1 ST=1 0 * see above A=C A * info necessary to NTOKEN was in A GOSBVL RESCAN * this is similar to NTOKEN GOTO Findx * loop back found A=0 A * clear A C=ST * type of keyword A=C P * put into A(A) ?A=0 A * is it a function? GOYES FN * yes GOSBVL D1C=R3 * no, restore D1, put PC into A(A) C=0 W * clear C(W) to make a simple header LCHEX F * F0 means a string - this one has length 0 GOVLNG FNRTN2 * send it out as a null string FN GOSBVL D1C=R3 * restore D1, PC into A(A) R3=C * put D0 into R3 R1=A * put D1 into R1 (will be used by ADHEAD) A=B A * transfer execution address to A(A) A=A-1 A * point to max # of parameters nib D0=A * set D0 to this C=0 A * want C(A) clean C=DAT0 1 * read the nib (m=max #) C=C+1 A * m+1 for counter because ther are m+2 nibs D=C A * use D(A) as loop counter P= 0 * precautionary CONV A=0 A * my alternative to HP's HEXASC A=DAT0 1 * combined with reading & writing the required nibs ST=0 4 * ST4 clear for: 0<=nib<=9 C=0 A LCHEX A * load 10(hex) for comparison ?A