@@ -49,214 +49,217 @@ tag piece {
49
49
piece_conv ( conv) ;
50
50
}
51
51
52
- fn parse_fmt_string ( str s) -> vec[ piece ] {
53
- let vec[ piece] pieces = vec ( ) ;
54
- auto lim = _str. byte_len ( s) ;
55
- auto buf = "" ;
56
-
57
- fn flush_buf ( str buf, & vec[ piece] pieces ) -> str {
58
- if ( _str. byte_len ( buf) > 0 u) {
59
- auto piece = piece_string ( buf) ;
60
- pieces += vec ( piece) ;
52
+ // Functions used by the fmt extension at compile time
53
+ mod CT {
54
+ fn parse_fmt_string ( str s) -> vec[ piece ] {
55
+ let vec[ piece] pieces = vec ( ) ;
56
+ auto lim = _str. byte_len ( s) ;
57
+ auto buf = "" ;
58
+
59
+ fn flush_buf ( str buf, & vec[ piece] pieces ) -> str {
60
+ if ( _str. byte_len ( buf) > 0 u) {
61
+ auto piece = piece_string ( buf) ;
62
+ pieces += vec ( piece) ;
63
+ }
64
+ ret "" ;
61
65
}
62
- ret "" ;
63
- }
64
66
65
- auto i = 0 u;
66
- while ( i < lim) {
67
- auto curr = _str. substr ( s, i, 1 u) ;
68
- if ( _str. eq ( curr, "%" ) ) {
69
- i += 1 u;
70
- if ( i >= lim) {
71
- log "unterminated conversion at end of string" ;
72
- fail;
73
- }
74
- auto curr2 = _str. substr ( s, i, 1 u) ;
75
- if ( _str. eq ( curr2, "%" ) ) {
67
+ auto i = 0 u;
68
+ while ( i < lim) {
69
+ auto curr = _str. substr ( s, i, 1 u) ;
70
+ if ( _str. eq ( curr, "%" ) ) {
76
71
i += 1 u;
72
+ if ( i >= lim) {
73
+ log "unterminated conversion at end of string" ;
74
+ fail;
75
+ }
76
+ auto curr2 = _str. substr ( s, i, 1 u) ;
77
+ if ( _str. eq ( curr2, "%" ) ) {
78
+ i += 1 u;
79
+ } else {
80
+ buf = flush_buf ( buf, pieces) ;
81
+ auto res = parse_conversion ( s, i, lim) ;
82
+ pieces += vec ( res. _0 ) ;
83
+ i = res. _1 ;
84
+ }
77
85
} else {
78
- buf = flush_buf ( buf, pieces) ;
79
- auto res = parse_conversion ( s, i, lim) ;
80
- pieces += vec ( res. _0 ) ;
81
- i = res. _1 ;
86
+ buf += curr;
87
+ i += 1 u;
82
88
}
83
- } else {
84
- buf += curr;
85
- i += 1 u;
86
89
}
87
- }
88
- buf = flush_buf ( buf, pieces) ;
89
- ret pieces;
90
- }
91
-
92
- fn peek_num ( str s, uint i, uint lim) -> option. t[ tup ( uint , uint ) ] {
93
- if ( i >= lim) {
94
- ret none[ tup ( uint, uint) ] ;
95
- }
96
-
97
- auto c = s. ( i) ;
98
- if ( !( '0' as u8 <= c && c <= '9' as u8 ) ) {
99
- ret option. none [ tup ( uint, uint) ] ;
90
+ buf = flush_buf ( buf, pieces) ;
91
+ ret pieces;
100
92
}
101
93
102
- auto n = ( c - ( '0' as u8 ) ) as uint ;
103
- alt ( peek_num ( s, i + 1 u, lim) ) {
104
- case ( none[ tup ( uint, uint) ] ) {
105
- ret some[ tup ( uint, uint) ] ( tup ( n, i + 1 u) ) ;
94
+ fn peek_num ( str s, uint i, uint lim) -> option. t[ tup ( uint , uint ) ] {
95
+ if ( i >= lim) {
96
+ ret none[ tup ( uint, uint) ] ;
106
97
}
107
- case ( some [ tup ( uint , uint ) ] ( ?next ) ) {
108
- auto m = next . _0 ;
109
- auto j = next . _1 ;
110
- ret some [ tup ( uint, uint) ] ( tup ( n * 10 u + m , j ) ) ;
98
+
99
+ auto c = s . ( i ) ;
100
+ if ( ! ( '0' as u8 <= c && c <= '9' as u8 ) ) {
101
+ ret option . none [ tup ( uint, uint) ] ;
111
102
}
112
- }
113
103
114
- }
104
+ auto n = ( c - ( '0' as u8 ) ) as uint ;
105
+ alt ( peek_num ( s, i + 1 u, lim) ) {
106
+ case ( none[ tup ( uint, uint) ] ) {
107
+ ret some[ tup ( uint, uint) ] ( tup ( n, i + 1 u) ) ;
108
+ }
109
+ case ( some[ tup ( uint, uint) ] ( ?next) ) {
110
+ auto m = next. _0 ;
111
+ auto j = next. _1 ;
112
+ ret some[ tup ( uint, uint) ] ( tup ( n * 10 u + m, j) ) ;
113
+ }
114
+ }
115
115
116
- fn parse_conversion ( str s, uint i, uint lim) -> tup ( piece , uint ) {
117
- auto parm = parse_parameter ( s, i, lim) ;
118
- auto flags = parse_flags ( s, parm. _1 , lim) ;
119
- auto width = parse_count ( s, flags. _1 , lim) ;
120
- auto prec = parse_precision ( s, width. _1 , lim) ;
121
- auto ty = parse_type ( s, prec. _1 , lim) ;
122
- ret tup ( piece_conv ( rec ( param = parm. _0 ,
123
- flags = flags. _0 ,
124
- width = width. _0 ,
125
- precision = prec. _0 ,
126
- ty = ty. _0 ) ) ,
127
- ty. _1 ) ;
128
- }
116
+ }
129
117
130
- fn parse_parameter ( str s, uint i, uint lim) -> tup ( option. t[ int ] , uint ) {
131
- if ( i >= lim) {
132
- ret tup ( none[ int] , i) ;
118
+ fn parse_conversion ( str s, uint i, uint lim) -> tup ( piece , uint ) {
119
+ auto parm = parse_parameter ( s, i, lim) ;
120
+ auto flags = parse_flags ( s, parm. _1 , lim) ;
121
+ auto width = parse_count ( s, flags. _1 , lim) ;
122
+ auto prec = parse_precision ( s, width. _1 , lim) ;
123
+ auto ty = parse_type ( s, prec. _1 , lim) ;
124
+ ret tup ( piece_conv ( rec ( param = parm. _0 ,
125
+ flags = flags. _0 ,
126
+ width = width. _0 ,
127
+ precision = prec. _0 ,
128
+ ty = ty. _0 ) ) ,
129
+ ty. _1 ) ;
133
130
}
134
131
135
- auto num = peek_num ( s, i, lim) ;
136
- alt ( num) {
137
- case ( none[ tup ( uint, uint) ] ) {
132
+ fn parse_parameter ( str s, uint i, uint lim) -> tup ( option. t[ int ] , uint ) {
133
+ if ( i >= lim) {
138
134
ret tup ( none[ int] , i) ;
139
135
}
140
- case ( some[ tup ( uint, uint) ] ( ?t) ) {
141
- auto n = t. _0 ;
142
- auto j = t. _1 ;
143
- if ( j < lim && s. ( j) == '$' as u8 ) {
144
- ret tup ( some[ int] ( n as int ) , j + 1 u) ;
145
- }
146
- else {
136
+
137
+ auto num = peek_num ( s, i, lim) ;
138
+ alt ( num) {
139
+ case ( none[ tup ( uint, uint) ] ) {
147
140
ret tup ( none[ int] , i) ;
148
141
}
142
+ case ( some[ tup ( uint, uint) ] ( ?t) ) {
143
+ auto n = t. _0 ;
144
+ auto j = t. _1 ;
145
+ if ( j < lim && s. ( j) == '$' as u8 ) {
146
+ ret tup ( some[ int] ( n as int ) , j + 1 u) ;
147
+ }
148
+ else {
149
+ ret tup ( none[ int] , i) ;
150
+ }
151
+ }
149
152
}
150
153
}
151
- }
152
-
153
- fn parse_flags ( str s, uint i, uint lim) -> tup ( vec[ flag ] , uint ) {
154
- let vec[ flag] noflags = vec ( ) ;
155
154
156
- if ( i >= lim) {
157
- ret tup ( noflags, i) ;
158
- }
155
+ fn parse_flags ( str s, uint i, uint lim) -> tup ( vec[ flag ] , uint ) {
156
+ let vec[ flag] noflags = vec ( ) ;
159
157
160
- fn more_ ( flag f, str s, uint i, uint lim) -> tup ( vec[ flag ] , uint ) {
161
- auto next = parse_flags ( s, i + 1 u, lim) ;
162
- auto rest = next. _0 ;
163
- auto j = next. _1 ;
164
- let vec[ flag] curr = vec ( f) ;
165
- ret tup ( curr + rest, j) ;
166
- }
158
+ if ( i >= lim) {
159
+ ret tup ( noflags, i) ;
160
+ }
167
161
168
- auto more = bind more_ ( _, s, i, lim) ;
169
-
170
- auto f = s. ( i) ;
171
- if ( f == ( '-' as u8 ) ) {
172
- ret more ( flag_left_justify) ;
173
- } else if ( f == ( '0' as u8 ) ) {
174
- ret more ( flag_left_zero_pad) ;
175
- } else if ( f == ( ' ' as u8 ) ) {
176
- ret more ( flag_left_space_pad) ;
177
- } else if ( f == ( '+' as u8 ) ) {
178
- ret more ( flag_plus_if_positive) ;
179
- } else if ( f == ( '#' as u8 ) ) {
180
- ret more ( flag_alternate) ;
181
- } else {
182
- ret tup ( noflags, i) ;
183
- }
184
- }
162
+ fn more_ ( flag f, str s, uint i, uint lim) -> tup ( vec[ flag ] , uint ) {
163
+ auto next = parse_flags ( s, i + 1 u, lim) ;
164
+ auto rest = next. _0 ;
165
+ auto j = next. _1 ;
166
+ let vec[ flag] curr = vec ( f) ;
167
+ ret tup ( curr + rest, j) ;
168
+ }
185
169
186
- fn parse_count ( str s, uint i, uint lim) -> tup ( count , uint ) {
187
- if ( i >= lim) {
188
- ret tup ( count_implied, i) ;
170
+ auto more = bind more_ ( _, s, i, lim) ;
171
+
172
+ auto f = s. ( i) ;
173
+ if ( f == ( '-' as u8 ) ) {
174
+ ret more ( flag_left_justify) ;
175
+ } else if ( f == ( '0' as u8 ) ) {
176
+ ret more ( flag_left_zero_pad) ;
177
+ } else if ( f == ( ' ' as u8 ) ) {
178
+ ret more ( flag_left_space_pad) ;
179
+ } else if ( f == ( '+' as u8 ) ) {
180
+ ret more ( flag_plus_if_positive) ;
181
+ } else if ( f == ( '#' as u8 ) ) {
182
+ ret more ( flag_alternate) ;
183
+ } else {
184
+ ret tup ( noflags, i) ;
185
+ }
189
186
}
190
187
191
- if ( s. ( i) == ( '*' as u8 ) ) {
192
- auto param = parse_parameter ( s, i + 1 u, lim) ;
193
- auto j = param. _1 ;
194
- alt ( param. _0 ) {
195
- case ( none[ int] ) {
196
- ret tup ( count_is_next_param, j) ;
197
- }
198
- case ( some[ int] ( ?n) ) {
199
- ret tup ( count_is_param ( n) , j) ;
200
- }
188
+ fn parse_count ( str s, uint i, uint lim) -> tup ( count , uint ) {
189
+ if ( i >= lim) {
190
+ ret tup ( count_implied, i) ;
201
191
}
202
- } else {
203
- auto num = peek_num ( s, i, lim) ;
204
- alt ( num) {
205
- case ( none[ tup ( uint, uint) ] ) {
206
- ret tup ( count_implied, i) ;
192
+
193
+ if ( s. ( i) == ( '*' as u8 ) ) {
194
+ auto param = parse_parameter ( s, i + 1 u, lim) ;
195
+ auto j = param. _1 ;
196
+ alt ( param. _0 ) {
197
+ case ( none[ int] ) {
198
+ ret tup ( count_is_next_param, j) ;
199
+ }
200
+ case ( some[ int] ( ?n) ) {
201
+ ret tup ( count_is_param ( n) , j) ;
202
+ }
207
203
}
208
- case ( some[ tup ( uint, uint) ] ( ?num) ) {
209
- ret tup ( count_is ( num. _0 as int ) , num. _1 ) ;
204
+ } else {
205
+ auto num = peek_num ( s, i, lim) ;
206
+ alt ( num) {
207
+ case ( none[ tup ( uint, uint) ] ) {
208
+ ret tup ( count_implied, i) ;
209
+ }
210
+ case ( some[ tup ( uint, uint) ] ( ?num) ) {
211
+ ret tup ( count_is ( num. _0 as int ) , num. _1 ) ;
212
+ }
210
213
}
211
214
}
212
215
}
213
- }
214
216
215
- fn parse_precision ( str s, uint i, uint lim) -> tup ( count , uint ) {
216
- if ( i >= lim) {
217
- ret tup ( count_implied, i) ;
218
- }
217
+ fn parse_precision ( str s, uint i, uint lim) -> tup ( count , uint ) {
218
+ if ( i >= lim) {
219
+ ret tup ( count_implied, i) ;
220
+ }
219
221
220
- if ( s. ( i) == '.' as u8 ) {
221
- ret parse_count ( s, i + 1 u, lim) ;
222
- } else {
223
- ret tup ( count_implied, i) ;
222
+ if ( s. ( i) == '.' as u8 ) {
223
+ ret parse_count ( s, i + 1 u, lim) ;
224
+ } else {
225
+ ret tup ( count_implied, i) ;
226
+ }
224
227
}
225
- }
226
228
227
- fn parse_type ( str s, uint i, uint lim) -> tup ( ty , uint ) {
228
- if ( i >= lim) {
229
- log "missing type in conversion" ;
230
- fail;
231
- }
229
+ fn parse_type ( str s, uint i, uint lim) -> tup ( ty , uint ) {
230
+ if ( i >= lim) {
231
+ log "missing type in conversion" ;
232
+ fail;
233
+ }
232
234
233
- auto t;
234
- auto tstr = _str. substr ( s, i, 1 u) ;
235
- if ( _str. eq ( tstr, "b" ) ) {
236
- t = ty_bool;
237
- } else if ( _str. eq ( tstr, "s" ) ) {
238
- t = ty_str;
239
- } else if ( _str. eq ( tstr, "c" ) ) {
240
- t = ty_char;
241
- } else if ( _str. eq ( tstr, "d" )
242
- || _str. eq ( tstr, "i" ) ) {
243
- // TODO: Do we really want two signed types here?
244
- // How important is it to be printf compatible?
245
- t = ty_int ( signed) ;
246
- } else if ( _str. eq ( tstr, "u" ) ) {
247
- t = ty_int ( unsigned) ;
248
- } else if ( _str. eq ( tstr, "x" ) ) {
249
- t = ty_hex ( case_lower) ;
250
- } else if ( _str. eq ( tstr, "X" ) ) {
251
- t = ty_hex ( case_upper) ;
252
- } else if ( _str. eq ( tstr, "t" ) ) {
253
- t = ty_bits;
254
- } else {
255
- log "unknown type in conversion" ;
256
- fail;
257
- }
235
+ auto t;
236
+ auto tstr = _str. substr ( s, i, 1 u) ;
237
+ if ( _str. eq ( tstr, "b" ) ) {
238
+ t = ty_bool;
239
+ } else if ( _str. eq ( tstr, "s" ) ) {
240
+ t = ty_str;
241
+ } else if ( _str. eq ( tstr, "c" ) ) {
242
+ t = ty_char;
243
+ } else if ( _str. eq ( tstr, "d" )
244
+ || _str. eq ( tstr, "i" ) ) {
245
+ // TODO: Do we really want two signed types here?
246
+ // How important is it to be printf compatible?
247
+ t = ty_int ( signed) ;
248
+ } else if ( _str. eq ( tstr, "u" ) ) {
249
+ t = ty_int ( unsigned) ;
250
+ } else if ( _str. eq ( tstr, "x" ) ) {
251
+ t = ty_hex ( case_lower) ;
252
+ } else if ( _str. eq ( tstr, "X" ) ) {
253
+ t = ty_hex ( case_upper) ;
254
+ } else if ( _str. eq ( tstr, "t" ) ) {
255
+ t = ty_bits;
256
+ } else {
257
+ log "unknown type in conversion" ;
258
+ fail;
259
+ }
258
260
259
- ret tup( t, i + 1 u) ;
261
+ ret tup( t, i + 1 u) ;
262
+ }
260
263
}
261
264
262
265
// Functions used by the fmt extension at runtime
0 commit comments