Here’s a simple program editor that you can add to uLisp. It lets you step through a function definition, editing it a bit at a time, using a set of simple single-key editing commands you type at the keyboard.
(defun e (l)
(loop
(let ((c (read)))
(when (eq c 'b) (return l))
(setq l
(cond
((eq c 'r) (read))
((eq c '?) (princ l) (terpri) l)
((eq c 'c) (cons (read) l))
((atom l) (princ '*) l)
((eq c 'd) (cons (car l) (e (cdr l))))
((eq c 'a) (cons (e (car l)) (cdr l)))
((eq c 'x) (cdr l))
(t (princ '!) (terpri) l))))))
(defun edit (l) (set l (e (eval l))))
Commands
Here is a summary of the commands:
- Enter Prints the current form.
- a (car) Takes the car of the current form.
- d (cdr) Takes the cdr of the current form.
- r (replace) Replaces the current form with what you type in.
- c (cons) Conses what you type in onto the front of the current form.
- x (delete) Deletes the car of the current form.
- b (back) Backs up the tree.
You run the editor by typing:
(edit 'fun)
where fun is the name of the function, or variable, you want to edit.
To edit the function you type a series of a or d commands to step through the function to the part you want to edit, use r, c, or x to make changes, and type b repeatedly to go back until you exit from the editor.
At any stage you can press Enter to print the current part of the function you’ve reached.
If you type an invalid key the editor prints ?, and if you reach the end of the tree with a or d the editor prints !.
Example
As an example of using the program editor, enter the following program b that blinks the LED on pin 13 once a second:
(defun b (x) (pinmode 13 t) (digitalwrite 13 x) (delay 500) (b (not x)))
Suppose we now want to change the delay parameter to 250 to make it blink twice as quickly. First give the command:
(edit 'b)
The editor prints the current context:
(lambda (x) (pinmode 13 t) (digitalwrite 13 x) (delay 500) (b (not x)))
Get to the delay command by typing:
dddd
The editor prints:
((delay 500) (b (not x)))
Now get to the 500 by typing:
ada
The editor responds:
500
Replace this with 250 by typing:
r250
The editor responds:
250
We can confirm that we’ve changed the correct value by backing up with:
bb
The editor responds:
(delay 250)
Quit from the editor with:
bbbb
Finally run the program to confirm that the change has been made:
(b nil)