-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathAlanString.ml
More file actions
113 lines (105 loc) · 3.54 KB
/
AlanString.ml
File metadata and controls
113 lines (105 loc) · 3.54 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
open Error
(* Caml Inria explode - implode functions *)
let explode s =
let rec expl i l =
if i < 0 then l else
expl (i - 1) (s.[i] :: l) in
expl (String.length s - 1) []
let implode l =
let result = String.create (List.length l) in
let rec imp i = function
| [] -> result
| c :: l -> result.[i] <- c; imp (i + 1) l in
imp 0 l
(* Functions for parsing hex characters *)
let is_hex ch =
((ch >= '0' && ch <= '9') ||
(ch >= 'a' && ch <= 'f') ||
(ch >= 'A' && ch <= 'Z'))
let get_hex_value x =
if (x>='0' && x<='9')
then Char.code x - Char.code '0'
else if (x>='A' && x <= 'F')
then Char.code x - Char.code 'A' + 10
else Char.code x - Char.code 'a' + 10
let parse_hex str =
let h1 = get_hex_value str.[2] in
let h2 = get_hex_value str.[3] in
Char.chr (h1*16+h2)
(* Takes a string and returns it without escape characters *)
let de_escape str =
let length = String.length str in
let rec loop i acc=
if (i < length)
then (
match str.[i] with
|'\\' -> (
match str.[i+1] with
|'n' -> loop (i+2) ('\n'::acc)
|'r' -> loop (i+2) ('\r'::acc)
|'t' -> loop (i+2) ('\t'::acc)
|'0' -> loop (i+2) ((Char.chr 0)::acc)
|'\'' -> loop (i+2) ('\''::acc)
|'"' -> loop (i+2) ('"'::acc)
|'x' ->
if ((is_hex str.[i+2]) && (is_hex str.[i+3]))
then
let h1 = get_hex_value str.[i+2] in
let h2 = get_hex_value str.[i+3] in
loop (i+4) ((Char.chr (h1*16+h2))::acc)
else (
error "Invalid escape sequence";
loop (i+5) acc
)
|_ -> error "Invalid escape sequence";
loop (i+2) acc
)
|_ -> loop (i+1) (str.[i]::acc)
)
else implode (List.rev acc)
in loop 0 []
(* Handle escape sequences for Final Code Creation *)
let handle_escapes str =
let char_list = explode str in
let base = List.rev (explode "\tdb '") in
let rec delete_empty_strings char_list acc =
match char_list with
| [] -> implode acc
| ('\n'::'\''::'\''::' '::'b'::'d'::'\t'::t) ->
delete_empty_strings t acc
| (h::t) ->
delete_empty_strings t (h::acc) in
let rec parse_char_list acc lst =
match lst with
| [] ->
let tail_lst = List.rev (explode "'\n\tdb 0\n") in
delete_empty_strings (tail_lst@acc) []
| ('\\'::'t'::t) ->
let to_add = List.rev (explode "'\n\tdb 9\n\tdb '") in
parse_char_list (to_add @ acc) t
| ('\\'::'n'::t) ->
let to_add = List.rev (explode "'\n\tdb 10\n\tdb '") in
parse_char_list (to_add @ acc) t
| ('\\'::'r'::t) ->
let to_add = List.rev (explode "'\n\tdb 13\n\tdb '") in
parse_char_list (to_add @ acc) t
| ('\\'::'0'::t) ->
let to_add = List.rev (explode "'\n\tdb 0\n\tdb '") in
parse_char_list (to_add @ acc) t
| ('\\'::'\\'::t) ->
let to_add = List.rev (explode "'\n\tdb \\\n\tdb '") in
parse_char_list (to_add @ acc) t
| ('\\'::'\''::t) ->
let to_add = List.rev (explode "'\n\tdb 39\n\tdb '") in
parse_char_list (to_add @ acc) t
| ('\\'::'"'::t) ->
let to_add = List.rev (explode "'\n\tdb 34\n\tdb '") in
parse_char_list (to_add @ acc) t
| ('\\'::'x'::n1::n2::t) ->
let code = (get_hex_value n1 * 16 + get_hex_value n2) in
let to_add_str = Printf.sprintf "'\n\tdb %d\n\tdb '" code in
let to_add = List.rev (explode to_add_str) in
parse_char_list (to_add @ acc) t
| (h::t) ->
parse_char_list (h::acc) t in
parse_char_list base char_list