### Pretty printer puzzle

This past week, I came across a Lisp challenge that turned out to be trickier than one might expect at first. I needed to pretty-print a Lisp form to a string and identify the positions of certain subforms. Here's an example:

In this, output the bounding indices of the`CL-USER> (with-output-to-string (*standard-output*) (pprint '(defun factorial (x) (if (zerop x) 1 (* x (factorial (1- x))))))) " (DEFUN FACTORIAL (X) (IF (ZEROP X) 1 (* X (FACTORIAL (1- X)))))"`

`IF`

form are 24 and 77. In other words:The challenge, then, is to write a function that, given a form and list of subforms, returns a string with the pretty-printed output and a list of bounding indices for each subform. E.g.`CL-USER> (subseq * 24 77) "(IF (ZEROP X) 1 (* X (FACTORIAL (1- X))))"`

I'll post my solution later. Have fun. :-)`CL-USER> (pprinted-bounds '(defun factorial (x) #1=(if (zerop x) 1 (* x #2=(factorial (1- x))))) (list '#1# '#2#)) " (DEFUN FACTORIAL (X) (IF (ZEROP X) 1 (* X (FACTORIAL (1- X)))))" ((24 77) (57 75))`

## 2 komentoj:

Does your solution handle things like "(" in strings and symbols, too?

Eg. for the input

(defun |())())| (one &key #1=(two 1))

"comment string ()()((("

(if (plusp two)

(|())())| (1- one) (1- two))

(print #2=(+ one two))))

do you get correct output?

The "cleaner" approach of counting parenthesis would need to have syntactic knowledge (strings, comments, symbols, etc.); the other approach I can think of would be to change a symbol in each sought list, and to find the change in the resulting string output - this actually sounds easier.

My solution does not get confused by non-syntactic ('s no. I rely on the pretty printer dispatch table to know what is what.

Your second solution seems close to what I've got, but why change a symbol? What if the form doesn't have symbols? (Also, changing the symbol will probably screw the pretty printing.)

Post a comment