-
Notifications
You must be signed in to change notification settings - Fork 0
/
printf.mana
58 lines (43 loc) · 2.28 KB
/
printf.mana
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
------------------------------------------------------------------------------
--
-- Printf
--
------------------------------------------------------------------------------
namespace Printf
import Core
------------------------------------------------------------------------------
-- Format
------------------------------------------------------------------------------
type Format = FNil | FLiteral String Format | FString Format | FInt Format
formatType : Format -> Type -> Type
formatType (FNil ) t = t
formatType (FLiteral s f) t = formatType f t
formatType (FString f) t = String -> formatType f t
formatType (FInt f) t = Int -> formatType f t
parseFormat : List Char -> Format
parseFormat (Nil ) = FNil
parseFormat (Cons '%' (Cons 'd' cs)) = FInt (parseFormat cs)
parseFormat (Cons '%' (Cons 's' cs)) = FString (parseFormat cs)
parseFormat (Cons c cs ) = pushChar c (parseFormat cs)
pushChar : Char -> Format -> Format
pushChar c (FLiteral string f) = FLiteral (singleton c + string) f
pushChar c f = FLiteral (pack (Cons c Nil)) f
------------------------------------------------------------------------------
-- Format string
------------------------------------------------------------------------------
stringToFormat : String -> Format
stringToFormat = parseFormat . unpack
formatStringToType : String -> Type -> Type
formatStringToType s = formatType (stringToFormat s)
------------------------------------------------------------------------------
-- printf
------------------------------------------------------------------------------
printf : (s : String) -> formatStringToType s (IO ())
printf s = printfImpl (IO ()) printString (stringToFormat s)
sprintf : (s : String) -> formatStringToType s String
sprintf s = printfImpl String id (stringToFormat s)
printfImpl : (t : Type) -> (String -> t) -> (f : Format) -> formatType f t
printfImpl t k (FNil ) = k ""
printfImpl t k (FLiteral s f) = printfImpl t (k . (s +)) f
printfImpl t k (FString f) = \s -> printfImpl t (k . (s +)) f
printfImpl t k (FInt f) = \n -> printfImpl t (k . (show n +)) f