ASCII(애스키)란 American Standard Code for Information Interchange의 줄임글로서, 영문자에 기초한 문자 인코딩이다. 이 문자 인코딩에는 C0 제어문자(C0 control character)도 포함되어 있다. ( 참고: ASCII - Wikipedia, the free encyclopedia )
다음은 7bit ASCII 코드표를 만들어 보여주는 OCaml 소스 코드이다. 소스 코드 중에 진법변환에 필요한 함수
atoi string radix
itoa number radix
를 OCaml 코드로 자체 작성하여 사용하였다.
(아래의 소스는 Python 소스를 F# 소스로 일대일 변환 수정하고, 또 F# 소스를 OCaml 소스로 바꾼 것이라서 명령형 언어 특징을 위주로 작성되어 있다. 그래서 함수형 언어의 관점으로 보면 사이드 이팩트가 많아 난잡하게 보이는 소스이다.)
- (*
- * Filename: makeAsciiTable.ml
- * Make a table of ascii codes.
- *
- * Execute: ocaml makeAsciiTable.ml
- *
- * Or
- *
- * Compile: ocamlc -o makeAsciiTable.exe makeAsciiTable.ml
- * Execute: makeAsciiTable
- *
- * Date: 20013. 1. 29.
- * Author: pkim __AT__ scripts.pe.kr
- *)
- open Printf;;
- exception RuntimeError of string
- exception ValueError of string
- let println s = printf "%s\n" s ;;
- let print s = printf "%s" s ;;
- let printUsage() =
- println "Usage: makeAsciiTable" ;
- println "Make a table of ascii codes." ;;
- let split_char sep str =
- let rec indices acc i =
- try
- let i = succ(String.index_from str i sep) in
- indices (i::acc) i
- with Not_found ->
- (String.length str + 1) :: acc
- in
- let is = indices [0] 0 in
- let rec aux acc = function
- | last::start::tl ->
- let w = String.sub str start (last-start-1) in
- aux (w::acc) (start::tl)
- | _ -> acc
- in
- aux [] is ;;
- let sBASE36 = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ" ;;
- let rec sdup str n =
- match n with
- | 0 -> ""
- | k when k > 0 -> str ^ (sdup str (n - 1))
- | _ -> ""
- let contains s1 s2 =
- try
- let len = String.length s2 in
- for i = 0 to (String.length s1) - len do
- if String.sub s1 i len = s2 then raise Exit
- done;
- false
- with Exit -> true ;;
- let join list sep =
- let rec join' list acc =
- match list with
- | [] -> ""
- | [single] -> single
- | one::[two] ->
- if acc = "" then one ^ sep ^ two
- else acc ^ one ^ sep ^ two
- | first::others -> join' others (acc ^ first ^ ", ")
- in
- join' list "" ;;
- let str_reverse str =
- let len = String.length str in
- let res = String.create len in
- for i = 0 to pred len do
- let j = pred len - i in
- res.[i] <- str.[j]
- done;
- res ;;
- let itoa num radix =
- let isNegative = ref false in
- let num1 = num + 0 in
- let numx = ref num1 in
- if num < 0 then begin
- isNegative := true ;
- numx := (-num)
- end ;
- let nnumx = !numx in
- let q1 = nnumx in
- let q = ref q1 in
- let r = ref 0 in
- let slen = ref 1 in
- while (!q >= radix) do
- r := !q mod radix ;
- q := !q / radix ;
- slen := !slen + 1
- done ;
- let sslen = !slen in
- let str = String.create sslen in
- let p1 = nnumx in
- let p = ref p1 in
- for i = 0 to sslen - 1 do
- r := !p mod radix ;
- p := !p / radix ;
- str.[i] <- sBASE36.[!r]
- done ;
- let str2 = str_reverse str in
- str2;;
- let atoi s radix =
- let ret = ref 0 in
- let isNegative = ref false in
- let len = String.length s in
- let valx = ref 0 in
- let c1 = s.[0] in
- let c = ref c1 in
- if !c = '-' then
- isNegative := true
- else if (!c >= '0' && !c <= '9') then
- ret := (int_of_char !c) - (int_of_char '0')
- else if (!c >= 'A' && !c <= 'Z') then
- ret := (int_of_char !c) - (int_of_char 'A') + 10
- else if (!c >= 'a' && !c <= 'z') then
- ret := (int_of_char !c) - (int_of_char 'a') + 10 ;
- if (!ret >= radix) then
- raise (ValueError (sprintf "Can not read \"%s\" (as radix %d): '%c' is invalid." s radix !c ) ) ;
- for i = 1 to len - 1 do
- c := s.[i] ;
- ret := (!ret)*radix ;
- if (!c >= '0' && !c <= '9') then
- valx := int_of_char !c - int_of_char '0'
- else if (!c >= 'A' && !c <= 'Z') then
- valx := int_of_char !c - int_of_char 'A' + 10
- else if (!c >= 'a' && !c <= 'z') then
- valx := int_of_char !c - int_of_char 'a' + 10 ;
- if (!valx >= radix) then
- raise (ValueError (sprintf "Can not read \"%s\" (as radix %d): '%c' is invalid." s radix !c ) ) ;
- ret := (!ret) + (!valx)
- done;
- if (!isNegative) then
- ret := (-(!ret) ) ;
- !ret ;;
- let asc = [|
- "NUL"; "SOH"; "STX"; "ETX"; "EOT";
- "ENQ"; "ACK"; "BEL"; "BS"; "HT";
- "LF"; "VT"; "FF"; "CR"; "SO";
- "SI"; "DLE"; "DC1"; "DC2"; "DC3";
- "DC4"; "NAK"; "SYN"; "ETB"; "CAN";
- "EM"; "SUB"; "ESC"; "FS"; "GS";
- "RS"; "US"; "Spc" |] ;;
- let control = [|
- "NUL (null)";
- "SOH (start of heading)";
- "STX (start of text)";
- "ETX (end of text)";
- "EOT (end of transmission)";
- "ENQ (enquiry)";
- "ACK (acknowledge)";
- "BEL (bell)";
- "BS (backspace)";
- "TAB (horizontal tab)";
- "LF (line feed, NL new line)";
- "VT (vertical tab)";
- "FF (form feed, NP new page)";
- "CR (carriage return)";
- "SO (shift out)";
- "SI (shift in)";
- "DLE (data link escape)";
- "DC1 (device control 1)";
- "DC2 (device control 2)";
- "DC3 (device control 3)";
- "DC4 (device control 4)";
- "NAK (negative acknowledge)";
- "SYN (synchronous idle)";
- "ETB (end of trans. block)";
- "CAN (cancel)";
- "EM (end of medium)";
- "SUB (substitute, EOF end of file)";
- "ESC (escape)";
- "FS (file separator)";
- "GS (group separator)";
- "RS (record separator)";
- "US (unit separator)" |] ;;
- let makeTable() =
- let sbuf = " " in
- let sbuf = sbuf ^ (sdup "+----" 8) in
- let sbuf = sbuf ^ "+" in
- println sbuf ;
- let sbuf = " " in
- let sbuf = sbuf ^ "| 0- " in
- let sbuf = sbuf ^ "| 1- " in
- let sbuf = sbuf ^ "| 2- " in
- let sbuf = sbuf ^ "| 3- " in
- let sbuf = sbuf ^ "| 4- " in
- let sbuf = sbuf ^ "| 5- " in
- let sbuf = sbuf ^ "| 6- " in
- let sbuf = sbuf ^ "| 7- " in
- let sbuf = sbuf ^ "|" in
- println sbuf ;
- let sbuf = "+---" in
- let sbuf = sbuf ^ (sdup "+----" 8) in
- let sbuf = sbuf ^ "+" in
- println sbuf ;
- let aa = Array.make_matrix 16 8 "" in
- for i = 0 to (16-1) do
- let sbuf = (itoa i 16) in
- let tbuf = "| " ^ sbuf ^ " " in
- print tbuf ;
- for j = 0 to (8-1) do
- if j*16 + i <= 32 then
- aa.(i).(j) <- sprintf "| %-3s" asc.(j*16 + i)
- else if j*16 + i = 127 then
- aa.(i).(j) <- sprintf "| %-3s" "DEL"
- else begin
- let c = char_of_int (j*16 + i) in
- aa.(i).(j) <- sprintf "| %1c " c
- end ;
- print aa.(i).(j)
- done;
- println "|"
- done ;
- let sbuf = "+---" in
- let sbuf = sbuf ^ (sdup "+----" 8) in
- let sbuf = sbuf ^ "+" in
- println sbuf ;
- println "" ;
- for i = 0 to (16-1) do
- let tbuf = sprintf "%-30s %-34s" control.(i) control.(i+16) in
- println tbuf
- done ;
- "" ;;
- (* Begin here *)
- let main() =
- let cmdArgs = Sys.argv in
- if (Array.length cmdArgs > 1 && "-h" = cmdArgs.(1)) then begin
- printUsage() ;
- exit(1)
- end ;
- makeTable() ;;
- main() ;;
컴파일> ocamlc -o makeAsciiTable.exe makeAsciiTable.ml
실행> makeAsciiTable
+----+----+----+----+----+----+----+----+ | 0- | 1- | 2- | 3- | 4- | 5- | 6- | 7- | +---+----+----+----+----+----+----+----+----+ | 0 | NUL| DLE| Spc| 0 | @ | P | ` | p | | 1 | SOH| DC1| ! | 1 | A | Q | a | q | | 2 | STX| DC2| " | 2 | B | R | b | r | | 3 | ETX| DC3| # | 3 | C | S | c | s | | 4 | EOT| DC4| $ | 4 | D | T | d | t | | 5 | ENQ| NAK| % | 5 | E | U | e | u | | 6 | ACK| SYN| & | 6 | F | V | f | v | | 7 | BEL| ETB| ' | 7 | G | W | g | w | | 8 | BS | CAN| ( | 8 | H | X | h | x | | 9 | HT | EM | ) | 9 | I | Y | i | y | | A | LF | SUB| * | : | J | Z | j | z | | B | VT | ESC| + | ; | K | [ | k | { | | C | FF | FS | , | < | L | \ | l | | | | D | CR | GS | - | = | M | ] | m | } | | E | SO | RS | . | > | N | ^ | n | ~ | | F | SI | US | / | ? | O | _ | o | DEL| +---+----+----+----+----+----+----+----+----+ NUL (null) DLE (data link escape) SOH (start of heading) DC1 (device control 1) STX (start of text) DC2 (device control 2) ETX (end of text) DC3 (device control 3) EOT (end of transmission) DC4 (device control 4) ENQ (enquiry) NAK (negative acknowledge) ACK (acknowledge) SYN (synchronous idle) BEL (bell) ETB (end of trans. block) BS (backspace) CAN (cancel) TAB (horizontal tab) EM (end of medium) LF (line feed, NL new line) SUB (substitute, EOF end of file) VT (vertical tab) ESC (escape) FF (form feed, NP new page) FS (file separator) CR (carriage return) GS (group separator) SO (shift out) RS (record separator) SI (shift in) US (unit separator)
'프로그래밍 > OCaml' 카테고리의 다른 글
손으로 만드는 나눗셈 계산표 with OCaml (0) | 2013.02.01 |
---|---|
OCaml 언어로 큰 정수(big integer) 계산하기 (0) | 2013.01.30 |
OCaml 에 Extlib 설치하고 사용하는 예 (0) | 2013.01.29 |
진법(radix) 표 만들기 예제 with OCaml (0) | 2013.01.28 |
대화형 모드의 진법(radix) 변환 예제 with OCaml (0) | 2013.01.27 |