~eda-qa/leaflang/cpp

« back to all changes in this revision

Viewing changes to share/std_library/std/utf8.leaf

  • Committer: edA-qa mort-ora-y
  • Date: 2017-08-19 06:03:00 UTC
  • mfrom: (100.1.22 misc)
  • Revision ID: eda-qa@disemia.com-20170819060300-209dwd5884343mi0
merging miscelaneous changes, mainly platform improvements

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/**
 
2
        @param c the character to encode in utf-8
 
3
        @param o the callback for each octet in the sequence
 
4
*/
 
5
defn u8_encode_char = ( c : char, o : (c:octet)->() ) -> {
 
6
        //FEATURE: shouldn't need lossy, code_val could return integer with range?
 
7
        var v : binary = lossy( code_val(c) )
 
8
        
 
9
        //FEATURE: a suffix marker for binary might be nice
 
10
        literal c_imask : binary =  0b0011_1111
 
11
        literal c_val : binary = 0b1000_0000
 
12
 
 
13
        defn lo = ( c : binary ) -> {
 
14
                o( lossy(c) )
 
15
        }
 
16
        //FEATURE: A binary formatting function/op
 
17
        do select(
 
18
                v <= 0b0111_1111 ? {
 
19
                        lo( v )
 
20
                }, v <= 0b0111_1111_1111 ? {
 
21
                        lo( bit_shr(v,6) or 0b1100_0000 )
 
22
                        lo( (v and c_imask) or c_val )
 
23
                }, v <= 0b1111_1111_1111_1111 ? {
 
24
                        lo( bit_shr(v,12) or 0b1110_0000 )
 
25
                        lo( ( bit_shr(v,6) and c_imask ) or c_val )
 
26
                        lo( ( v and c_imask ) or c_val )
 
27
                }, v <= 0b0001_1111_1111_1111_1111_1111 ? {
 
28
                        lo( bit_shr(v,18) or 0b1111_0000 )
 
29
                        lo( ( bit_shr(v,12) and c_imask ) or c_val )
 
30
                        lo( ( bit_shr(v,6) and c_imask ) or c_val )
 
31
                        lo( ( v and c_imask ) or c_val )
 
32
                }, {
 
33
                        fail
 
34
                }
 
35
        )
 
36
}
 
37
 
 
38
/**
 
39
        @return the number of octects for character `c` in utf-8
 
40
*/
 
41
defn u8_octet_len = ( c : char ) -> {
 
42
        var v : binary = lossy( code_val(c) )
 
43
        do select(
 
44
                v <= 0b0111_1111 ? {
 
45
                        return 1
 
46
                }, v <= 0b0111_1111_1111 ? {
 
47
                        return 2
 
48
                }, v <= 0b1111_1111_1111_1111 ? {
 
49
                        return 3
 
50
                }, v <= 0b0001_1111_1111_1111_1111_1111 ? {
 
51
                        return 4
 
52
                }, {
 
53
                        fail
 
54
                }
 
55
        )
 
56
}
 
57
 
 
58
defn u8_octet_len = ( s : array「char」 ) -> {
 
59
        var c = 0
 
60
        for i in range(0,s.size) {
 
61
                c = c + u8_octet_len(s#i)
 
62
        }
 
63
        return c
 
64
}
 
65
 
 
66
@export
 
67
defn u8_encode = ( s : array「char」 ) -> ( t : array「octet」 ) {
 
68
        var len = u8_octet_len( s )
 
69
        var r = type「 array「abi_char」 」(len+1)
 
70
        var at = 0
 
71
        
 
72
        for i in range(0,s.size) {
 
73
                u8_encode_char( s#i, (c)-> {
 
74
                        r#at = c
 
75
                        at = at + 1
 
76
                } )
 
77
        }
 
78
                
 
79
        r#at = 0
 
80
        t = r
 
81
}
 
82
 
 
83
//TODO: these should all be "literal" instead
 
84
//these are marked `binary` to be large enough for bitops, not 8bit.
 
85
//TODO: I'd prefer they are octet and there be a simple way to mark a large region of bit os as 32bit
 
86
var b_mask_1 : binary = 0b1000_0000
 
87
var b_val_1 : binary = 0b0000_0000
 
88
var b_mask_2 : binary = 0b1110_0000
 
89
var b_val_2 : binary = 0b1100_0000
 
90
var b_mask_3 : binary = 0b1111_0000
 
91
var b_val_3 : binary = 0b1110_0000
 
92
var b_mask_4 : binary = 0b1111_1000
 
93
var b_val_4 : binary = 0b1111_0000
 
94
var c_mask : binary = 0b1100_0000
 
95
var c_val : binary = 0b1000_0000
 
96
 
 
97
defn u8_len = ( s : array「octet」, max : integer ) -> {
 
98
        var len = 0
 
99
        var at = 0
 
100
        loop at < max ? {
 
101
                var c = s#at
 
102
                do select(
 
103
                        (c and b_mask_1) == b_val_1 ? {
 
104
                                at = at + 1
 
105
                        }, (c and b_mask_2) == b_val_2 ? {
 
106
                                at = at + 2
 
107
                        }, (c and b_mask_3) == b_val_3 ? {
 
108
                                at = at + 3
 
109
                        }, (c and b_mask_4) == b_val_4 ? {
 
110
                                at = at + 4
 
111
                        }, {
 
112
                                fail
 
113
                        }
 
114
                )
 
115
                
 
116
                len = len + 1
 
117
        }
 
118
        
 
119
        return len
 
120
}
 
121
 
 
122
@export
 
123
defn u8_decode = ( u : array「octet」, max : integer ) -> ( s : array「char」 ) {
 
124
        var clen = u8_len(u,max)
 
125
        
 
126
        s = type「 array「char」 」(clen)
 
127
        var sat = 0
 
128
        var at = 0
 
129
        loop sat < clen ? {
 
130
                var c : binary = u#at
 
131
                var step : integer
 
132
                var cp : binary
 
133
                
 
134
                do select(
 
135
                        (c and b_mask_1) == b_val_1 ? {
 
136
                                cp = c
 
137
                                step = 1
 
138
                        }, (c and b_mask_2) == b_val_2 ? {
 
139
                                cp = (bit_shl(c and not b_mask_2,6) or
 
140
                                        (u#(at+1) and not c_mask))
 
141
                                step = 2
 
142
                        }, (c and b_mask_3) == b_val_3 ? {
 
143
                                cp = (bit_shl((c and not b_mask_3),12) or
 
144
                                        bit_shl((u#(at+1) and not c_mask),6) or
 
145
                                        (u#(at+2) and not c_mask))
 
146
                                step = 3
 
147
                        }, (c and b_mask_4) == b_val_4 ? {
 
148
                                cp = (bit_shl(c and not b_mask_4,18) or
 
149
                                        bit_shl(u#(at+1) and not c_mask,12) or
 
150
                                        bit_shl(u#(at+2) and not c_mask,6) or
 
151
                                        (u#(at+3) and not c_mask))
 
152
                                step = 4
 
153
                        }, {
 
154
                                fail
 
155
                        }
 
156
                )
 
157
                
 
158
                s#sat = char_val(lossy(cp))
 
159
                at = at + step
 
160
                sat = sat + 1
 
161
                
 
162
        }
 
163
        
 
164
}
 
 
b'\\ No newline at end of file'