Using the kid utility, we can make rotate single to be simpler too:
123456789101112131415
;; x y;; / \ / \;; y c => a x ;; / \ / \;; a b b c;;(defunrotate-s(rootdir)(let((x(cadrroot))(y(cadr(kid(notdir))))(a(kid(notdir)(notdir)))(b(kid(notdir)dir))(c(kiddir)))(ifdir(listay(listbxc))(list(listcxb)ya))))
Observe that the two return form is nested reversed. Why not write a macro that
generate this form? Then we only need to write the right case!
Reverse the tree
First we need to write a function that take a nested form and return it in
reversed order (also nested.) To achieve this, we use double recursion.
Now the insert-binary-r and rotate-s can be re-written only in right form!
12345678910111213141516171819202122
;; x y;; / \ / \;; y c => a x ;; / \ / \;; a b b c;;(defunrotate-s(rootdir)(let((x(cadrroot))(y(cadr(kid(notdir))))(a(kid(notdir)(notdir)))(b(kid(notdir)dir))(c(kiddir)))(mtree-expanddir(ay(bxc)))))(defuninsert-binary-r(rootdata)(cond((nullroot)`(nil,(make-rb:datadata)nil))((=data(node-dataroot))root)(T(let*((dir(>data(node-dataroot)))(x(cadrroot))(a(kidroot(notdir)))(b(binary-insert-r(kidrootdir)data)))(mtree-expanddir(axb))))))
Macro that simplify the input form
We also want to simplify that ugly let form, so we create this function and
macro:
See? We don’t need to write the comment to remind us the relative position of
variables. The code express itself! You can see what this code will expand
to by expanding the macro: