The Convoluted Logic of ROT13 in CCL
Playing with CCL, the Mule Code Conversion Language, I decided to write a simple ROT13 algorithm. This turned out to be tougher than expected since CCL has no concept of the logical and and or operators; what is && and || in C derived languages.
(define-ccl-program my-ccl-rot13
'(1
((loop
(read r0)
;; The convoluted logic of rot13 in CCL.
(if (r0 >= 110) ; n
(if (r0 <= 122) ; z
((r0 -= 13))) ;; If we are between n-z
(if (r0 >= 97) ; a
(if (r0 <= 109) ; m
((r0 += 13))) ;; If we are between a-m
(if (r0 >= 78) ; N
(if (r0 <= 90) ; Z
((r0 -= 13))) ;; If we are between N-Z
(if (r0 >= 65) ; A
(if (r0 <= 77); ; M
((r0 += 13))))))) ;; If we are between A-M
(write r0)
(repeat)))))
One method to tackle this, as demonstrated above, is to use the if-else construct and carefully order the comparisons.
Now, in order to do something useful with this, we define the function my-rot13-word-at-point.
(defun my-rot13-word-at-point ()
(interactive)
(let ((word (word-at-point)))
(if (stringp word)
(message (ccl-execute-on-string 'my-ccl-rot13 [0 0 0 0 0 0 0 0 nil]
word)))))
And now we can do M-x my-rot13-word-at-point and we will see the word (de)cyphered in the echo area.
There is one “bug” so to speak, and that it will potentially display garbage when applied to non-ascii text, such as Japanese.
Finally, these code snippets are GPL 2 or 3 at your convenience.
Good start! A couple of comments; you can use character literals, so (if (r0 > ?n) …) is fine, rather than typing the numeric ASCII code and commenting what it represents. And for most use cases for CCL, it’s quite a big deal that non-ASCII is trashed. See lisp/mule/make-coding-system.el in 21.5 for CCL examples that take non-ASCII more seriously.