다음은 대화형 모드(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진법까지이다.
- ;; Filename: convertRadix.lsp
- ;; Convert radix in a interactive mode.
- ;;
- ;; Execute: clisp convertRadix.lsp
- ;;
- ;; Date: 2013. 9. 5.
- (defun printUsage()
- (format t "Usage: clisp convertRadix.lsp~%")
- (format t "Convert radix in a interactive mode, where the maximum radix is 36.~%") )
- (defun printAbout()
- (format t " About: Convert radix in a interactive mode.~%") )
- (defun printMainMenu()
- (format t " Command: (S)et radix, (A)bout, (Q)uit or E(x)it~%") )
- (defun printMainPrompt()
- (format t " Prompt> ") )
- (defun printSubMenu(srcRadix destRadix)
- (format t " Convert Radix_~D to Radix_~D~%" srcRadix destRadix)
- (format t " SubCommand: 'main()' to goto Main menu, 'exit()' or 'quit()' to exit~%") )
- (defun printSubPrompt()
- (format t " Input Value>> ") )
- (setf *BASE36* "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ")
- (defun join-string-list (string-list)
- "Concatenates a list of strings and puts spaces between the elements."
- (format nil "~{~A~^~}" string-list))
- (define-condition invalid-src-radix (error)
- ((msg :reader msg :initarg :msg))
- (:report (lambda (condition stream)
- (format stream "Exception: ~A." (msg condition)))))
- (define-condition invalid-dest-radix (error)
- ((msg :reader msg :initarg :msg))
- (:report (lambda (condition stream)
- (format stream "Exception: ~A." (msg condition)))))
- (defun convertRadix(s srcRdx destRdx)
- (ignore-errors
- (if (or (< srcRdx 2) (> srcRdx 36))
- (error 'invalid-src-radix :msg (format nil "Invalid source radix: ~A" srcRdx)))
- (if (or (< destRdx 2) (> destRdx 36))
- (error 'invalid-dest-radix :msg (format nil "Invalid destination radix: ~A" destRdx)))
- (let ((ret ""))
- (setf val (parse-integer s :radix srcRdx))
- (setf ret (write-to-string val :base destRdx))
- (string-upcase ret)))
- )
- (defun nonwhite-char-p (c)
- (> (char-code c) (char-code #\Space)))
- (defun white-char-p (c)
- (<= (char-code c) (char-code #\Space)))
- (defun safe-parse-integer (s)
- (handler-case
- (parse-integer s :radix 10)
- (parse-error (c)
- (format t "예외상황 발생: ~A" c)
- )
- )
- )
- (defun get-token (s)
- (let* ((i (if (find (elt s 0) "+-") 1 0))
- (d (position-if 'nonwhite-char-p s :start i))
- (f (position-if 'white-char-p s :start (1+ d))))
- ; (format t "d = ~A~%" d)
- ; (format t "f = ~A~%" f)
- (substring s d f)))
- (defun get-two-tokens (s)
- (let* ((i (if (find (elt s 0) "+-") 1 0))
- (d (position-if 'nonwhite-char-p s :start i))
- (f (position-if 'white-char-p s :start (1+ d)))
- (d2 (position-if 'nonwhite-char-p s :start (1+ f)))
- (f2 (position-if 'white-char-p s :start (1+ d2))))
- (format t "d = ~A~%" d)
- (format t "f = ~A~%" f)
- (format t "d2 = ~A~%" d2)
- (format t "f2 = ~A~%" f2)
- (list (substring s d f) (substring s d2 f2)) ))
- (defun get-tokens (s)
- (let ((arr (list))
- (n (length s))
- (x "")
- (c #\Space))
- (loop for i from 0 below n do
- (setf c (aref s i))
- (if (white-char-p c)
- (if (> (length x) 0) (progn
- (push x arr)
- (setf x "") )))
- (if (nonwhite-char-p c) (progn
- (setf x (concatenate 'string x (format nil "~A" c))) ))
- )
- (if (> (length x) 0)
- (push x arr))
- (reverse arr) ))
- (defun doConvert(srcRadix destRadix)
- (let ((line "")
- (cmd "")
- (innerLoop t)
- (srcStr "")
- (destStr ""))
- (format t "~%")
- (printSubMenu srcRadix destRadix)
- (handler-case
- (progn
- (loop while innerLoop do
- (printSubPrompt)
- (setf cmd (read-line))
- (setf cmd (string-trim " " cmd))
- (if (equal (string-downcase cmd) "main()")
- (progn
- (setf innerLoop nil)
- (return nil) ))
- (if (or (equal (string-downcase cmd) "exit()") (equal (string-downcase cmd) "quit()"))
- (quit))
- (handler-case
- (progn
- (parse-integer cmd :radix srcRadix)
- (setf srcStr (string-upcase cmd))
- (setf destStr (convertRadix srcStr srcRadix destRadix))
(format t " ( ~A )_~A ---> ( ~A )_~A~%" srcStr srcRadix destStr destRadix) - (format t "~%")
- )
- (parse-error (c)
- (format t "예외상황 발생: ~A" c)
- (format t "다시 입력하시오,~%~%") )
- )
- )
- ))
- t
- ))
- (defun doStart()
- (let ((line "")
- (cmd "")
- (outerLoop t)
- (srcRadix 10)
- (destRadix 10)
- (srcStr "")
- (destStr "")
- (onlyOnce t))
- (handler-case
- (progn
- (loop while outerLoop do
- (format t "~%")
- (if (equal onlyOnce t) (progn
- (format t " The supported maximum radix is 36.~%")
- (setf onlyOnce nil)
- (printMainMenu)
- (printMainPrompt)
- (setf cmd (read-line))
- (setf cmd (string-trim " " cmd))
- (if (or (equal cmd "q") (equal cmd "Q") (equal cmd "x") (equal cmd "X")) (quit) )
- (if (or (equal cmd "a") (equal cmd "A")) (progn (printAbout) (setf onlyOnce t)) )
- (if (or (equal cmd "s") (equal cmd "S")) (progn
- (format t " Input the source and target radices (say, 16 2): ")
- (setf line (read-line))
- (setf st (get-tokens line))
- (loop while (not (= (length st) 2)) do
- (format t " Input the source and target radices (say, 16 2): ")
- (setf line (read-line))
- (setf st (get-tokens line)) )
- ; (setf srcRadix (parse-integer (nth 0 st) :radix 10))
- ; (setf destRadix (parse-integer (nth 1 st) :radix 10))
- (setf srcRadix (safe-parse-integer (nth 0 st)))
- (setf destRadix (safe-parse-integer (nth 1 st)))
- (if (and (not (equal srcRadix nil)) (not (equal destRadix nil)))
- (progn
- (doConvert srcRadix destRadix)
- (setf onlyOnce t)
- )
- (progn
- (format t "두 수를 다시 입력하시오.~%")
- (setf onlyOnce t)
- )
- )
- ))
- ))
- )
- ))
- ))
- ;; Begin here
- (if (and (> (length ext:*args*) 0) (equal (nth 0 ext:*args*) "-h")) (progn
- (printUsage)
- (quit) ))
- (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
'프로그래밍 > Common Lisp' 카테고리의 다른 글
7비트 ASCII 코드표 만들기 예제 with Common Lisp (0) | 2013.09.05 |
---|---|
진법(radix) 표 만들기 예제 with Common Lisp (0) | 2013.09.04 |
황금비율(golden ratio) 구하기 with Common Lisp (0) | 2013.09.01 |
현재 시각 알아내기 for Common Lisp (0) | 2013.08.31 |
조립제법(Horner의 방법) 예제 for Common Lisp (0) | 2013.08.30 |