This file is stored on VLISP.COM It is used as a comment file for generating the listing of the vlisp initialization vlile (VLISP.INI) Note: the first 10 lines of this file are ignored by the saveall routine STORED ON: VLISP.INI AUTHOR: PAUL MENNEN DATE: 6-NOV-80 The programs in this file are loaded when vlisp is started This file contains the pretty printer. Loading this file uses up the following resources: Atom space = 600 List space = 1151 ISLIST return T if B is a list, otherwise return nil LEN return the number of characters required to print the expression L. .NULL nil requires two characters: "()" .ATOM atoms require the length of their pname .QUOTE quote only needs one character "'" .LIST the function list is abreviated [...] .ISLIST if its a list, add the length of its elements + 2 + intervening spaces .S initialize S for summing lengths of list elements .S sum the lenghts of each element .S return S .5 must be a s-expression (dotted pair);thus add in the 5 characters "( . )" TO-BIG return T if the expression L is to big to fit on one line cpos (comment position) is the right hand limit for the line INSER inserts x into the sorted list L and returns a new sorted list L is a list of lists arranged in increasing order according to the 2nd element of each list PTLIST pretty prints the cdr of list L1. (note car of L1 allready printed) if mlines (multiple lines) is false, print a blank between each element of the list. if mlines is true, terp is called whenever it is desired to advance to the next line. for multiple line lists, there is 3 different formats: format 1 - print 3 elements on first line and 2 elements on succeeding lines (SETQ) format 2 - print 2 elements on first line and 1 on all others (IF, IFN, WHILE, UNTIL, LAMBDA) format nil - print each element on a seperate line .NOT this line prints a list on a single line .1 is this format 1? .SETQ determine if format is 1,2,or nil .WHILE .WHILE *** come here for format 1 (SETQ), print remaining elements in 2 columns .OUTPOS position for column 1 (variable name) .PT print variable (i.e. quoted argument) .LMARGIN set left margin for column 2 .IF move to left margin if its forward, otherwise skip one space .PT print expression to be set to variable in column 1 .LMARGIN restore original margin .TERP go to next line if there are more terms in the setq list .2 *** come here for format 2 .PRINCH print a blank between first and 2nd elements of list .SETQ save present margin .LMARGIN present position is new margin .PT print second element .LEFTSV restore margin .L1 print rest of list one element per line .T *** come here for format nil - each element of the list will appear on a seperate line PT pretty prints the expression L. pnm is the label for the pair of parentheses that encloses this expression call with mlines=true if the expression requires multiple lines to be printed if brak is false, lists are printed normally - ( ... ) if brak is true, lists are printed with brackets - [ ... ] .MLINES if we are printing L on multiple lines, its time to recompute to see if this is necessary .NULL print nil as the 2 characters "()" .PRIN if L is atomic, just print it, then check for comments .QUOTE is L a 2 element list of the form (quote j) .PRINCH if yes, abrieviate (quote j) by 'j .EQ abrieviate the list function by using [...] .T L is non atomic and therefore must be a list or dotted pair .96 the printing of the first left paren is inhibited if pt is called with pnm=96, this is used by pret since the first left paren has allready been printed before the de,df, or dm .LRP save this left paren in the sorted list lrp. it's sorted in increasing order relative to outpos (paren position) .BRAK print the paren or the bracket .CHANGEP move on to the next paren label .MLINES if there are multiple lines needed to print the list, indent succeding lines .CAR pretty print the first element of the list or dotted pair .PTLIST if list, print the rest of the elements .PROGN for dotted pairs print " . " followed by the second part of the dotted pair .96 also save the right paren in the list lrp .BRAK and then print the right paren or bracket .MLINES discontinue the indentation after the list is printed TERP this routine is called whenever a line of pretty printing is to be completed. this routine then prints the parenthesis matching information if requested (i.e. if par = t) and also prints any comments that are associated with this line if the comment flag (comt) is true. .COMT advance to next line, if any comments first print the first line of them .PAR is paren matching selected with a non-empty lrp .RINNER2 yes, first remove deepest level parens from lrp .LRP was there only that one level? .-1 yes, it's not worth printing, discard one label .RINNER2 no, extract level 2 (second deepest level) from lrp .LRP were there only 2 levels on this line? .PROGN no, there were at least 3 levels, so do this .A4 save level 2 in A4 .RINNER2 extract level 3 parens from lrp into A3 .TERP2 print paren matching for level 3 .A4 print paren matching for level 2 .LRP are there any level 4 parens or higher? .-3 no, discard some unneeded labels .MAPC now print paren matching characters for all levels higher than 3 by using paren labels .SETQ must leave this routine with lrp empty .TERP4 print the next comment line (if any) following the paren matching characters .-2 yes, there were only 2 levels, no paren labels will be needed .IF dont print paren matching characters for level 2 unless there are more than one pair or unless the single paren pair spans at least 30 characters between the left and right paren .TERP2 print paren matching for level 2 and a comment line (if any are remaining) .COMT if comt = true, print any remaining comment lines and restore the print status TERPRA advance to the next line, linecnt will contain the number of lines used to pretty print the function TERP2 inserts paren matching characters for the parens contained in list A3 .SETQ save left margin position .0 move left margin to position zero .OUTPOS move output position to right margin so that outbuf will accept the characters .0 signify to vlisp when this file in used as input, that this is the start of a comment line .A3 insert paren matching to parens in A3 TERP3 L contains a collection of parentheses of a single level to be matched on a single line by using a !......! notation or a ?::::::? notation. terp3 inserts these characters into the output buffer. the structure of L is: ((lp1 rp1) (lp2 rp2) ... (lpn rpn)) where lpi is the buffer position of the ith left hand paren and rpi is the buffer position of the ith right hand paren .LAMBDA do this function for each paren pair in L .I I and J are the left and right print positons of the pair .EQ are we inside another matched pair of parens? .SYM1 yes, use ?::::? to indicate the innermost level .SYM1 no, use !.......! .I print ? or ! for left hand paren .J print ? or ! for right hand paren .WHILE print a . or : in all positions between the right and left paren pair TERP4 if there are any more comments, print the next comment line attached to the paren matching characters otherwise just advance to the next line .NEQ move output position to rightmost non-blank character .LMARGIN restore left margin to position encountered before terp was called .AND are there any comments to print? .PRINL1 yes, print them .JPOS no, jpos will be the end of the comment line .ADD1 move output position so next command will work .JPOS indicate that this is the end of the comment .TERPRA advance to the next line RINNER2 removes inner set of parentheses (deepest level) from lrp. A1 is used to collect the remaining parens, and A3 will contain the parens that are removed. lrp is eventually restored with its desired contents (the remaining parens in original order) from A1. the structure used for lrp is: ((L1 P1) (L2 P2) ... (Ln Pn)) where Li is the paren label (PNUM) and Pi is the paren position. note that both left and right parens are stored in lrp but they are not identified as left or right. the structure for list A1 is the same as for lrp. for the structure of A3, see the comments given for terp3 RINNER this routine is called iteratively to do the work for rinner2 .LRP are we done yet (is lrp empty)? .A1 yes, restore lrp with remaining parens .EQ no, not done yet. do the first two parens in lrp have the same label? .A1 no, put the first paren of lrp into A1 .A3 yes, these two parens must be an inner pair, save just the positions into A3 .LRP remove first paren from lrp .LRP remove first paren from lrp .RINNER continue the process CHANGEP this routine steps pnum forward or backword by n positions where n= -3, -2, -1, 0, or 1 pnum contains the ascii code of the character currently being used as a label for a right-left parentheses pair. the 52 valid characters for pnum are a thru z and A thru Z .123 jump to A after z .65 if we have decremented beyond the upper case, jump back to lower case .91 jump to a after Z .96 if we have decremented beyond the lower case, jump back to upper case PRETTY PRETTY does exactly the same thing as PRET PRET this routine pretty prints a function and returns # of lines printed. (PRET ABC) pretty prints the function ABC without parenthesis matching. (PRET ABC T) pretty prints the function ABC with parenthesis matching. the atom CPOS may be used to define the output linelength if pret is called by save with a comment file then right margin = 127 and cpos indicates the position where the comment lines begin. (i.e. cpos is the max # of characters in a line not counting comments) .BOUNDP if cpos is undefined use default value of 68 .RMARGIN save the current value of the margins .NAME extract function name and paren matching flag from parameter list, clear line count .SETQ set xtype to DE, DF, or DM (or nil if NAME isnt a function) .0 use full line width available, skip a line to start .XTYPE don't pretty print it if it isnt a function .1 dont insert spaces before each print arguement .3 indent the next line .XTYPE now start to print the first line .PRIN now print the argument list and some spaces to seperate the function discripter comments .AND do we have a comment file? .PRIN yes, begin to print the function discripter .READLN get first function discripter comment line .SETQ put all lines at current position (thispos) .WHILE do this until we hit a blank line (LIN=nil), means end of function discripter comments .LIN print the line and read the next one .LIN advance to next line except for last time .PRIN close the comment .READLN read the next line for PT .TERPRA advance to next line to begin function body .7 no blanks, use " around literals .96 initialize paren label (PNUM) and others for PT .PT pretty print the function body .0 restore print status and original margins .LIN this helps the save routine .LINECNT return number of lines printed SAVEINI this routine saves all of the routines on this file (VLISP.INI)