@@ -50,6 +50,7 @@ import std.ExtFmt.conv;
50
50
import std. ExtFmt . piece ;
51
51
import std. ExtFmt . piece_string ;
52
52
import std. ExtFmt . piece_conv ;
53
+ import std. ExtFmt . parse_fmt_string ;
53
54
54
55
export expand_syntax_ext;
55
56
@@ -87,216 +88,6 @@ fn expr_to_str(@ast.expr expr) -> str {
87
88
fail;
88
89
}
89
90
90
- fn parse_fmt_string ( str s) -> vec[ piece ] {
91
- let vec[ piece] pieces = vec ( ) ;
92
- auto lim = _str. byte_len ( s) ;
93
- auto buf = "" ;
94
-
95
- fn flush_buf ( str buf, & vec[ piece] pieces ) -> str {
96
- if ( _str. byte_len ( buf) > 0 u) {
97
- auto piece = piece_string ( buf) ;
98
- pieces += vec ( piece) ;
99
- }
100
- ret "" ;
101
- }
102
-
103
- auto i = 0 u;
104
- while ( i < lim) {
105
- auto curr = _str. substr ( s, i, 1 u) ;
106
- if ( _str. eq ( curr, "%" ) ) {
107
- i += 1 u;
108
- if ( i >= lim) {
109
- log "unterminated conversion at end of string" ;
110
- fail;
111
- }
112
- auto curr2 = _str. substr ( s, i, 1 u) ;
113
- if ( _str. eq ( curr2, "%" ) ) {
114
- i += 1 u;
115
- } else {
116
- buf = flush_buf ( buf, pieces) ;
117
- auto res = parse_conversion ( s, i, lim) ;
118
- pieces += vec ( res. _0 ) ;
119
- i = res. _1 ;
120
- }
121
- } else {
122
- buf += curr;
123
- i += 1 u;
124
- }
125
- }
126
- buf = flush_buf ( buf, pieces) ;
127
- ret pieces;
128
- }
129
-
130
- fn peek_num ( str s, uint i, uint lim) -> option. t[ tup ( uint , uint ) ] {
131
- if ( i >= lim) {
132
- ret none[ tup ( uint, uint) ] ;
133
- }
134
-
135
- auto c = s. ( i) ;
136
- if ( !( '0' as u8 <= c && c <= '9' as u8 ) ) {
137
- ret option. none [ tup ( uint, uint) ] ;
138
- }
139
-
140
- auto n = ( c - ( '0' as u8 ) ) as uint ;
141
- alt ( peek_num ( s, i + 1 u, lim) ) {
142
- case ( none[ tup ( uint, uint) ] ) {
143
- ret some[ tup ( uint, uint) ] ( tup ( n, i + 1 u) ) ;
144
- }
145
- case ( some[ tup ( uint, uint) ] ( ?next) ) {
146
- auto m = next. _0 ;
147
- auto j = next. _1 ;
148
- ret some[ tup ( uint, uint) ] ( tup ( n * 10 u + m, j) ) ;
149
- }
150
- }
151
-
152
- }
153
-
154
- fn parse_conversion ( str s, uint i, uint lim) -> tup ( piece , uint ) {
155
- auto parm = parse_parameter ( s, i, lim) ;
156
- auto flags = parse_flags ( s, parm. _1 , lim) ;
157
- auto width = parse_count ( s, flags. _1 , lim) ;
158
- auto prec = parse_precision ( s, width. _1 , lim) ;
159
- auto ty = parse_type ( s, prec. _1 , lim) ;
160
- ret tup ( piece_conv ( rec ( param = parm. _0 ,
161
- flags = flags. _0 ,
162
- width = width. _0 ,
163
- precision = prec. _0 ,
164
- ty = ty. _0 ) ) ,
165
- ty. _1 ) ;
166
- }
167
-
168
- fn parse_parameter ( str s, uint i, uint lim) -> tup ( option. t[ int ] , uint ) {
169
- if ( i >= lim) {
170
- ret tup ( none[ int] , i) ;
171
- }
172
-
173
- auto num = peek_num ( s, i, lim) ;
174
- alt ( num) {
175
- case ( none[ tup ( uint, uint) ] ) {
176
- ret tup ( none[ int] , i) ;
177
- }
178
- case ( some[ tup ( uint, uint) ] ( ?t) ) {
179
- auto n = t. _0 ;
180
- auto j = t. _1 ;
181
- if ( j < lim && s. ( j) == '$' as u8 ) {
182
- ret tup ( some[ int] ( n as int ) , j + 1 u) ;
183
- }
184
- else {
185
- ret tup ( none[ int] , i) ;
186
- }
187
- }
188
- }
189
- }
190
-
191
- fn parse_flags ( str s, uint i, uint lim) -> tup ( vec[ flag ] , uint ) {
192
- let vec[ flag] noflags = vec ( ) ;
193
-
194
- if ( i >= lim) {
195
- ret tup ( noflags, i) ;
196
- }
197
-
198
- fn more_ ( flag f, str s, uint i, uint lim) -> tup ( vec[ flag ] , uint ) {
199
- auto next = parse_flags ( s, i + 1 u, lim) ;
200
- auto rest = next. _0 ;
201
- auto j = next. _1 ;
202
- let vec[ flag] curr = vec ( f) ;
203
- ret tup ( curr + rest, j) ;
204
- }
205
-
206
- auto more = bind more_ ( _, s, i, lim) ;
207
-
208
- auto f = s. ( i) ;
209
- if ( f == ( '-' as u8 ) ) {
210
- ret more ( flag_left_justify) ;
211
- } else if ( f == ( '0' as u8 ) ) {
212
- ret more ( flag_left_zero_pad) ;
213
- } else if ( f == ( ' ' as u8 ) ) {
214
- ret more ( flag_left_space_pad) ;
215
- } else if ( f == ( '+' as u8 ) ) {
216
- ret more ( flag_plus_if_positive) ;
217
- } else if ( f == ( '#' as u8 ) ) {
218
- ret more ( flag_alternate) ;
219
- } else {
220
- ret tup ( noflags, i) ;
221
- }
222
- }
223
-
224
- fn parse_count ( str s, uint i, uint lim) -> tup ( count , uint ) {
225
- if ( i >= lim) {
226
- ret tup ( count_implied, i) ;
227
- }
228
-
229
- if ( s. ( i) == ( '*' as u8 ) ) {
230
- auto param = parse_parameter ( s, i + 1 u, lim) ;
231
- auto j = param. _1 ;
232
- alt ( param. _0 ) {
233
- case ( none[ int] ) {
234
- ret tup ( count_is_next_param, j) ;
235
- }
236
- case ( some[ int] ( ?n) ) {
237
- ret tup ( count_is_param ( n) , j) ;
238
- }
239
- }
240
- } else {
241
- auto num = peek_num ( s, i, lim) ;
242
- alt ( num) {
243
- case ( none[ tup ( uint, uint) ] ) {
244
- ret tup ( count_implied, i) ;
245
- }
246
- case ( some[ tup ( uint, uint) ] ( ?num) ) {
247
- ret tup ( count_is ( num. _0 as int ) , num. _1 ) ;
248
- }
249
- }
250
- }
251
- }
252
-
253
- fn parse_precision ( str s, uint i, uint lim) -> tup ( count , uint ) {
254
- if ( i >= lim) {
255
- ret tup ( count_implied, i) ;
256
- }
257
-
258
- if ( s. ( i) == '.' as u8 ) {
259
- ret parse_count ( s, i + 1 u, lim) ;
260
- } else {
261
- ret tup ( count_implied, i) ;
262
- }
263
- }
264
-
265
- fn parse_type ( str s, uint i, uint lim) -> tup ( ty , uint ) {
266
- if ( i >= lim) {
267
- log "missing type in conversion" ;
268
- fail;
269
- }
270
-
271
- auto t;
272
- auto tstr = _str. substr ( s, i, 1 u) ;
273
- if ( _str. eq ( tstr, "b" ) ) {
274
- t = ty_bool;
275
- } else if ( _str. eq ( tstr, "s" ) ) {
276
- t = ty_str;
277
- } else if ( _str. eq ( tstr, "c" ) ) {
278
- t = ty_char;
279
- } else if ( _str. eq ( tstr, "d" )
280
- || _str. eq ( tstr, "i" ) ) {
281
- // TODO: Do we really want two signed types here?
282
- // How important is it to be printf compatible?
283
- t = ty_int ( signed) ;
284
- } else if ( _str. eq ( tstr, "u" ) ) {
285
- t = ty_int ( unsigned) ;
286
- } else if ( _str. eq ( tstr, "x" ) ) {
287
- t = ty_hex ( case_lower) ;
288
- } else if ( _str. eq ( tstr, "X" ) ) {
289
- t = ty_hex ( case_upper) ;
290
- } else if ( _str. eq ( tstr, "t" ) ) {
291
- t = ty_bits;
292
- } else {
293
- log "unknown type in conversion" ;
294
- fail;
295
- }
296
-
297
- ret tup( t, i + 1 u) ;
298
- }
299
-
300
91
fn pieces_to_expr ( vec[ piece] pieces , vec[ @ast. expr] args) -> @ast . expr {
301
92
302
93
fn make_new_lit ( common . span sp, ast. lit_ lit ) -> @ast . expr {
0 commit comments