다음은  대화형 모드(interactive mode)에서 진법 변환(radix conversion)하는 Common Lisp 소스 코드이다.


메뉴는 주메뉴 Command: (S)et radix, (A)bout, (Q)uit or E(x)it
와 부메뉴 SubCommand: 'main()' to goto Main menu, 'exit()' or 'quit()' to exit
로 구성되어 있으며, 진법 변환의 핵심은 아래 소스의 52째 줄과 53째 줄에 있는

       (setf val (parse-integer s :radix srcRdx))
        (setf ret (write-to-string val :base destRdx))

이다. 지원되는 진법은 2진법에서 36진법까지이다.


  1. ;;  Filename: convertRadix.lsp
  2. ;;            Convert radix in a interactive mode.
  3. ;;
  4. ;;  Execute: clisp convertRadix.lsp
  5. ;;
  6. ;;      Date:  2013. 9. 5.
  7. (defun printUsage()
  8.     (format t "Usage: clisp convertRadix.lsp~%")
  9.     (format t "Convert radix in a interactive mode, where the maximum radix is 36.~%") )
  10. (defun printAbout()
  11.     (format t "    About: Convert radix in a interactive mode.~%") )
  12. (defun printMainMenu()
  13.     (format t "  Command: (S)et radix, (A)bout, (Q)uit or E(x)it~%") )
  14. (defun printMainPrompt()
  15.     (format t "  Prompt> ") )
  16. (defun printSubMenu(srcRadix destRadix)
  17.     (format t "    Convert Radix_~D to Radix_~D~%" srcRadix destRadix)
  18.     (format t "    SubCommand: 'main()' to goto Main menu, 'exit()' or 'quit()' to exit~%") )
  19. (defun printSubPrompt()
  20.     (format t "    Input Value>> ") )
  21. (setf *BASE36* "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ")
  22. (defun join-string-list (string-list)
  23.     "Concatenates a list of strings and puts spaces between the elements."
  24.     (format nil "~{~A~^~}" string-list))
  25. (define-condition invalid-src-radix (error)
  26.   ((msg :reader msg :initarg :msg))
  27.   (:report (lambda (condition stream)
  28.              (format stream "Exception: ~A." (msg condition)))))
  29. (define-condition invalid-dest-radix (error)
  30.   ((msg :reader msg :initarg :msg))
  31.   (:report (lambda (condition stream)
  32.              (format stream "Exception: ~A." (msg condition)))))
  33. (defun convertRadix(s srcRdx destRdx)
  34.   (ignore-errors
  35.     (if (or (< srcRdx 2) (> srcRdx 36))
  36.         (error 'invalid-src-radix :msg (format nil "Invalid source radix: ~A" srcRdx)))
  37.     (if (or (< destRdx 2) (> destRdx 36))
  38.         (error 'invalid-dest-radix :msg (format nil "Invalid destination radix: ~A" destRdx)))
  39.     (let ((ret ""))
  40.         (setf val (parse-integer s :radix srcRdx))
  41.         (setf ret (write-to-string val :base destRdx))
  42.         (string-upcase ret)))
  43.   )
  44. (defun nonwhite-char-p (c)
  45.     (> (char-code c) (char-code #\Space)))
  46. (defun white-char-p (c)
  47.     (<= (char-code c) (char-code #\Space)))
  48. (defun safe-parse-integer (s)
  49.         (handler-case
  50.              (parse-integer s :radix 10)
  51.              (parse-error (c)
  52.                        (format t "예외상황 발생: ~A" c)
  53.                )
  54.         )
  55. )
  56. (defun get-token (s)
  57.   (let* ((i (if (find (elt s 0) "+-") 1 0))
  58.          (d (position-if 'nonwhite-char-p s :start i))
  59.          (f (position-if 'white-char-p s :start (1+ d))))
  60.     ; (format t "d = ~A~%" d)
  61.     ; (format t "f = ~A~%" f)
  62.     (substring s d f)))
  63. (defun get-two-tokens (s)
  64.   (let* ((i (if (find (elt s 0) "+-") 1 0))
  65.          (d (position-if 'nonwhite-char-p s :start i))
  66.          (f (position-if 'white-char-p s :start (1+ d)))
  67.          (d2 (position-if 'nonwhite-char-p s :start (1+ f)))
  68.          (f2 (position-if 'white-char-p s :start (1+ d2))))
  69.     (format t "d = ~A~%" d)
  70.     (format t "f = ~A~%" f)
  71.     (format t "d2 = ~A~%" d2)
  72.     (format t "f2 = ~A~%" f2)
  73.     (list (substring s d f) (substring s d2 f2)) ))
  74. (defun get-tokens (s)
  75.   (let ((arr (list))
  76.         (n (length s))
  77.         (x "")
  78.         (c #\Space))
  79.       (loop for i from 0 below n do
  80.           (setf c (aref s i))
  81.           (if (white-char-p c)
  82.               (if (> (length x) 0) (progn
  83.                    (push x arr)
  84.                    (setf x "") )))
  85.           (if (nonwhite-char-p c) (progn
  86.                    (setf x (concatenate 'string x (format nil "~A" c))) ))
  87.       )
  88.       (if (> (length x) 0)
  89.                    (push x arr))
  90.       (reverse arr) ))
  91. (defun doConvert(srcRadix destRadix)
  92.     (let ((line "")
  93.           (cmd "")
  94.           (innerLoop t)
  95.           (srcStr "")
  96.           (destStr ""))
  97.         (format t "~%")
  98.         (printSubMenu srcRadix destRadix)
  99.         (handler-case
  100.           (progn
  101.             (loop while innerLoop do
  102.                 (printSubPrompt)
  103.                 (setf cmd (read-line))
  104.                 (setf cmd (string-trim " " cmd))
  105.                 (if (equal (string-downcase cmd) "main()")
  106.                     (progn
  107.                         (setf innerLoop nil)
  108.                         (return nil) ))
  109.                 (if (or (equal (string-downcase cmd) "exit()") (equal (string-downcase cmd) "quit()"))
  110.                     (quit))
  111.                 (handler-case
  112.                   (progn
  113.                      (parse-integer cmd :radix srcRadix)
  114.                      (setf srcStr (string-upcase cmd))
  115.                      (setf destStr (convertRadix srcStr srcRadix destRadix))
                         (format t "        ( ~A )_~A   --->   ( ~A )_~A~%" srcStr srcRadix destStr destRadix)
  116.                      (format t "~%")
  117.                   )
  118.                  (parse-error (c)
  119.                        (format t "예외상황 발생: ~A" c)
  120.                        (format t "다시 입력하시오,~%~%") )
  121.                )
  122.             )
  123.         ))
  124.     t
  125.     ))
  126. (defun doStart()
  127.     (let ((line "")
  128.           (cmd "")
  129.           (outerLoop t)
  130.           (srcRadix 10)
  131.           (destRadix 10)
  132.           (srcStr "")
  133.           (destStr "")
  134.           (onlyOnce t))
  135.         (handler-case
  136.           (progn
  137.             (loop while outerLoop do
  138.                    (format t "~%")
  139.                    (if (equal onlyOnce t) (progn
  140.                         (format t "  The supported maximum radix is 36.~%")
  141.                         (setf onlyOnce nil)
  142.                         (printMainMenu)
  143.                         (printMainPrompt)
  144.                         (setf cmd (read-line))
  145.                         (setf cmd (string-trim " " cmd))
  146.                         (if (or (equal cmd "q") (equal cmd "Q") (equal cmd "x") (equal cmd "X")) (quit) )
  147.                         (if (or (equal cmd "a") (equal cmd "A")) (progn (printAbout) (setf onlyOnce t)) )
  148.                         (if (or (equal cmd "s") (equal cmd "S")) (progn
  149.                                (format t "  Input the source and target radices (say, 16 2): ")
  150.                                (setf line (read-line))
  151.                                (setf st (get-tokens line))
  152.                                (loop while (not (= (length st) 2)) do
  153.                                    (format t "  Input the source and target radices (say, 16 2): ")
  154.                                    (setf line (read-line))
  155.                                    (setf st (get-tokens line)) )
  156.                                ; (setf srcRadix (parse-integer (nth 0 st) :radix 10))
  157.                                ; (setf destRadix (parse-integer (nth 1 st) :radix 10))
  158.                                (setf srcRadix (safe-parse-integer (nth 0 st)))
  159.                                (setf destRadix (safe-parse-integer (nth 1 st)))
  160.                                (if (and (not (equal srcRadix nil)) (not (equal destRadix nil)))
  161.                                    (progn
  162.                                        (doConvert srcRadix destRadix)
  163.                                        (setf onlyOnce t)
  164.                                    )
  165.                                    (progn
  166.                                        (format t "두 수를 다시 입력하시오.~%")
  167.                                        (setf onlyOnce t)
  168.                                    )
  169.                                )
  170.                         ))
  171.             ))
  172.           )
  173.         ))
  174.     ))
  175. ;; Begin here
  176. (if (and (> (length ext:*args*) 0) (equal (nth 0 ext:*args*) "-h")) (progn
  177.     (printUsage)
  178.     (quit) ))
  179. (doStart)



실행> clisp convertRadix.lsp

  The supported maximum radix is 36.
  Command: (S)et radix, (A)bout, (Q)uit or E(x)it
  Prompt> s
  Input the source and target radices (say, 16 2): 10 8

    Convert Radix_10 to Radix_8
    SubCommand: 'main()' to goto Main menu, 'exit()' or 'quit()' to exit
    Input Value>> 200
        ( 200 )_10   --->   ( 310 )_8

    Input Value>> main()

  Command: (S)et radix, (A)bout, (Q)uit or E(x)it
  Prompt> S
  Input the source and target radices (say, 16 2): 8 10

    Convert Radix_8 to Radix_10
    SubCommand: 'main()' to goto Main menu, 'exit()' or 'quit()' to exit
    Input Value>> 2666
        ( 2666 )_8   --->   ( 1462 )_10

    Input Value>> main()

  Command: (S)et radix, (A)bout, (Q)uit or E(x)it
  Prompt> x




Posted by Scripter
,