LEX 'NIDTLEX2' * A file to change LEX ID's & tokens CON(2) #EC * LEX ID=236 Jack Elhay, PPPM, 21/8/88. CON(2) #90 * Low Token CON(2) #92 * High Token CON(5) 0 * No link NIBHEX F * No speed table CON(4) (TxTbSt)+1-(*) Offset to TEXT Table CON(4) 0 * No message table CON(5) 0 * No poll handler CON(3) (TxEn02)-(TxTbSt) * offset into text table REL(5) NID * entry for NEWID NIBHEX D * a statement CON(3) (TxEn03)-(TxTbSt) * offset into text table REL(5) NTOK * entry for NEWTOKS NIBHEX D * a statement CON(3) (TxEn01)-(TxTbSt) * offset into text table REL(5) CONFIG * entry for CONF NIBHEX D * a statement TxTbSt * text table start TxEn01 CON(1) (TxEn02)-(*)-4 * nibble count nib= LEN(in bytes)*2-1 NIBASC 'CONF' * Syntax: CONF CON(2) #92 * token is 146 TxEn02 CON(1) (TxEn03)-(*)-4 NIBASC 'NEWID' * Syntax: NEWID ,[,] CON(2) #90 * token is 144 (default link# is 0 when omitted) TxEn03 CON(1) (TxTbEn)-(*)-4 NIBASC 'NEWTOKS' * Syntax: NEWTOKS ,[,link #>] CON(2) #91 * token is 145 (default link# as above) TxTbEn NIBHEX 1FF Text table terminator ARGERR EQU #0BF19 * invalid argument error exit BF2DSP EQU #01C0E * send a buffer of characters to the display COMCKO EQU #032AA * output next token & check that it is a comma CONF EQU #10212 * configure TITAN DISPDC EQU #05450 * display decompile EXPEX- EQU #0F178 * evaluate expression FILDC* EQU #05759 * filename decompile FINDF EQU #09F77 * find a file (set D1 to start of file header) FIXP EQU #02A6E * FIX parse FORSTK EQU #2F59E * FOR stack address kept here FSPECe EQU #02F02 * invalid file specifier error exit FSPECp EQU #03CC5 * file specifier parse FSPECx EQU #09F2D * like EXPEXC but for filenames OUTELA EQU #05303 * decompile for statements without parameters MFERR EQU #09393 * mainframe error driver NUMCK EQU #0369D * number check in parse routines NXTSTM EQU #08A48 * exit for statements RESPTR EQU #03172 * reset pointers after parse RNDAHX EQU #136CB * pop,round,test & convert to hex integer S-R0-0 EQU #2F871 * statement scratch area STMTD1 EQU #2F896 * temporary storage area for D1 SYNTXe EQU #02E2B * syntax error exit tCOMMA EQU #F1 * comma token IDTd GOSBVL FILDC* * NEWID & NEWTOKS common decompile GOVLNG DISPDC * (taken, in part, from MODIFY of SPLEX) IDTp GOSBVL FSPECp * NEWID & NEWTOKS common parse GONC comcko * (also helped by SPLEX as well as JPC) GOVLNG FSPECe * error in FSPECp return with carry clear comcko GOSBVL COMCKO * check that we have a comma next GOC numck * ok, we have one GOVLNG SYNTXe * no we don't, syntax error numck GOSBVL NUMCK * is a number next? LC(2) tCOMMA * load C(B) with comma token ?A=C B * NUMCK put the next token into A(B), is it a comma? GOYES fixp * exit through FIXP GOVLNG RESPTR * otherwise just reset the pointers (no 3rd param) fixp GOVLNG FIXP * FIXP takes care of 3rd parameter & resets pointers ARGS GOSBVL FSPECx * EXPEXC for a filename GOC ERR * ERRN in C(B) & carry is set if in error GOSBVL FINDF * set D1 to start of file GONC OK * carry set=file not found ERR GOVLNG MFERR * error exit assumes ERRN in C(B) OK D1=D1+ 16 * point to filetype nibs A=0 A * clear A(A) and C(A) C=0 A * for filetype tests A=DAT1 4 * read filetype LCHEX E208 * minimun value for LEX file ?AC A * is ours greater? GOYES Argerr * don't want it! R0=A * it's ok, save in R0 D1=(5) STMTD1 * recover D1's position in the file C=DAT1 A * read it D1=C * set D1 back to filetype nibs D1=D1+ 16 * and advance D1 a further 27 nibs D1=D1+ 11 * to point to offset to linked LEX table C=DAT1 A * read the offset A=R1 * recall the link# NXTLNK ?A=0 A * is it zero? RTNYES * we are pointing to the desired LEX table, return ?C#0 A * a non-zero offset? GOYES NOTZER * yes, we are ok GONC ArgerR * no, link# requested># links in the file NOTZER AD1EX * add the offset to D1 A=A+C A * to point to the next AD1EX * LEX table A=A-1 A * decrement link# counter D1=D1+ 6 * point to next link offset C=DAT1 A * read the offset GONC NXTLNK * loop back for more *BET* REL(5) IDTd REL(5) IDTp NID GOSUB ARGS * pop args, etc., new ID in R0, D1 @ link offset D1=D1- 6 * point to ID byte C=R0 * recall new ID DAT1=C B * poke in new ID GOTO CONFIG * exit via config ArgerR GOTO Argerr * jump extender REL(5) IDTd REL(5) IDTp NTOK GOSUB ARGS * pop etc., as above D1=D1- 4 * point to low token byte A=0 A * clear A & C for testing C=0 A * further the validity of new lotoken A=DAT1 B * read old lotoken R1=A * save it in R1 D1=D1+ 2 * now point to hitoken byte C=DAT1 B * and read it ?C#0 B * is hitoken#0? GOYES KWDS * yes, there are keywords GOTO NOKWDS * no, exit with "No Keywords" displayed KWDS R2=C * save hitoken byte in R2 C=C-A A * this is (hitoken-lotoken) difference R3=C * which we save in R3 A=R0 * recall new lotoken to A A=A+C A * new lotoken+difference=new hitoken LCHEX FF * check against 255 ?A>C A * is new hitoken>255? GOYES ArgerR * yes, not allowed, error. DAT1=A B * no, ok, so write new hitoken byte in D1=D1- 2 * now point to lotoken byte A=R0 * recall new lotoken DAT1=A B * write it in D1=D1+ 9 * point to [1st] speed table nib A=0 A A=DAT1 1 * read it ?A#0 A * not 0? GOYES NOSPD * yes, then there is no spdtble, step just 1 nib C=0 A * no, there is. Have to step 80 nibs LCHEX 4F * so step 79 nibs first AD1EX * in the usual way A=A+C A * as for adding an offset AD1EX * to D1 NOSPD D1=D1+ 1 * this makes it right (1 or 80) C=DAT1 4 * read the text table offset AD1EX * swap D1 into A A=A+C A * to add the offset AD1EX * D1 now @ text of 1st keyword in this text table D1=D1- 1 * step back to start of table LCHEX FF1 * load end-of-text table marker B=C X * into B(X) for loop exit test LOOP A=DAT1 3 * read 1st 3 nibs ?A=B X * end of text table? GOYES CONFIG * exit via config A=0 A * not end yet A=DAT1 1 * read nibble count nibble(=textlength*2-1 nibs) CD1EX * swap D1 into C to step past keyword C=C+A A * however, this will take us 2 nibs short CD1EX * so, after swapping back, D1=D1+ 2 * we have to advance D1 a further byte A=DAT1 B * we can now read this keyword's token C=R1 * C(B)=old lotoken A=A-C B * deduct old lotoken from this token C=R0 * recall new lotoken A=A+C B * and add it to get new token for this keyword DAT1=A B * poke in new value of token D1=D1+ 2 * move past the token byte (clears carry) GONC LOOP *BET* REL(5) CONFd REL(5) CONFp CONFIG CD0EX * save D0 RSTK=C * on the return stack ST=0 0 * power-up not coldstart configuration required GOSBVL CONF * configure (reconstructs bLEX amongst other things) C=RSTK * collect D0 fro return stack D0=C * and restore it nxtstm GOVLNG NXTSTM * before going on. NOKWDS GOSUB C=RSTK * collect return address NIBASC 'No ' * which points at this buffer of characters NIBASC 'Keywords' NIBHEX D0A0FF * CR/LF and end-of-buffer byte FF C=RSTK C=RSTK * pop return address off return stack D1=C * set D1 to point at the buffer GOSBVL BF2DSP * send the characters in the buffer to the display GOC nxtstm *BET* (BF2DSP returns with carry set) CONFd GOVLNG OUTELA * decompile for CONF CONFp RTNCC * parse for CONF GETRG CD1EX * save D1 in C(A) D1=(5) FORSTK * set D1 to FORSTK A=DAT1 A * read FOR stack address D1=C * restore D1 ?A=C A * is D1 pointing at FOR stack? RTNYES * yes, ie.,there are no params on mathstack, rtnsc GOSBVL RNDAHX * no, there is a parameter, pop it GOC POS * accept positive arguments A=0 A * zero negative arguments POS D1=D1+ 16 * step past the arg. on the stack (clears carry) RTN * return with carry clear END * Originally, this file took no account of links. There was also a bug in the * text table because of the late addition of CONF. Rewriting the LEX table * has fixed the bug (acknowledgement to Mike Markov for Writehead). * The learning process experienced with the extension of the keywords ID, * LOTOKEN and HITOKEN was certainly of value, but did not prevent me from * making stupid errors along the way (I shall not detail them!). * The parse routine is a blend of bits and pieces from MM's disassembly of * SPLEX, from JPC( La Decomparse, JPC 27, pp 26-34) and from my fevered * and tortured brain. The optional parameter is what makes life difficult. * Early efforts at handling the optional parameter demonstrated my ignorance * again. I finally understand the execution code for DELAY, and I was able * to adapt it to the needs of these statements. Correct me if I am wrong, when * you call EXPEXC, everything to EOL or equiv. is evaluated, notwithstanding * comma separators. * CONF was added as a afterthought, which is why the tokens are 'out of step'. * The addition involved very little extra code, and the benefit is this: * Purge your current FORTHRAM (unless yours is special), return to FORTH * do 3600 SHRINK, then the following definition - * : ASS ASSEMBLE " BEEP @ PUT "#43" @ CONF " BASICX BYE ; * then when you wish to assemble a source code, enter FORTH as usual and * key in " " ASS then endline. The standard PASS 1 & PASS 2 with * dots will appear, followed by a beep, the BASIC prompt will return and * the LEX file will be linked into the LEX buffer, ie it will be instantly * usable without turning off and on again. * Regards and Happy Programming, * Jack Elhay.