-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathSprintf.idr
58 lines (52 loc) · 2.24 KB
/
Sprintf.idr
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
module Sprintf
data Format = IntFormat Format |
StringFormat Format |
DoubleFormat Format |
CharFormat Format |
LiteralFormat String Format |
EndFormat
chars_to_format : List Char -> Format
chars_to_format Nil = EndFormat
chars_to_format ('%' :: 'i' :: tail) =
let tail_format = chars_to_format tail in
IntFormat tail_format
chars_to_format ('%' :: 's' :: tail) =
let tail_format = chars_to_format tail in
StringFormat tail_format
chars_to_format ('%' :: 'd' :: tail) =
let tail_format = chars_to_format tail in
DoubleFormat tail_format
chars_to_format ('%' :: 'c' :: tail) =
let tail_format = chars_to_format tail in
CharFormat tail_format
chars_to_format (cur_char :: tail) =
let tail_format = chars_to_format tail in
case tail_format of
LiteralFormat literal format => LiteralFormat (strCons cur_char literal) format
format => LiteralFormat (strCons cur_char "") format
string_to_format : String -> Format
string_to_format s = chars_to_format (unpack s)
SprintfType : Format -> Type
SprintfType (IntFormat format) = Int -> SprintfType format
SprintfType (StringFormat format) = String -> SprintfType format
SprintfType (DoubleFormat format) = Double -> SprintfType format
SprintfType (CharFormat format) = Char -> SprintfType format
SprintfType (LiteralFormat _ format) = SprintfType format
SprintfType EndFormat = String
sprintf_from_format : (format : Format) -> (acc : String) -> (SprintfType format)
sprintf_from_format (IntFormat format) acc = \cur_int =>
let cur_int_str = show cur_int in
sprintf_from_format format (acc ++ cur_int_str)
sprintf_from_format (StringFormat format) acc =
\cur_string => sprintf_from_format format (acc ++ cur_string)
sprintf_from_format (DoubleFormat format) acc = \cur_double =>
let cur_double_str = show cur_double in
sprintf_from_format format (acc ++ cur_double_str)
sprintf_from_format (CharFormat format) acc = \cur_char =>
let cur_char_str = show cur_char in
sprintf_from_format format (acc ++ cur_char_str)
sprintf_from_format (LiteralFormat literal format) acc =
sprintf_from_format format (acc ++ literal)
sprintf_from_format EndFormat acc = acc
sprintf : (format : String) -> (SprintfType (string_to_format format))
sprintf format = sprintf_from_format (string_to_format format) ""