@@ -21,6 +21,8 @@ import std.option;
21
21
import std. option . none ;
22
22
import std. option . some ;
23
23
24
+ export expand_syntax_ext;
25
+
24
26
tag signedness {
25
27
signed;
26
28
unsigned;
@@ -61,7 +63,7 @@ type conv = rec(option.t[int] param,
61
63
vec[ flag] flags ,
62
64
count width,
63
65
count precision ,
64
- ty typ ) ;
66
+ ty ty ) ;
65
67
66
68
// A fragment of the output sequence
67
69
tag piece {
@@ -74,6 +76,7 @@ fn bad_fmt_call() {
74
76
fail;
75
77
}
76
78
79
+ // TODO: Need to thread parser through here to handle errors correctly
77
80
fn expand_syntax_ext( vec[ @ast. expr] args,
78
81
option. t[ @ast. expr] body) -> @ast . expr {
79
82
@@ -96,6 +99,8 @@ fn expand_syntax_ext(vec[@ast.expr] args,
96
99
}
97
100
}
98
101
log "done printing all pieces" ;
102
+ auto args_len = _vec. len[ @ast. expr] ( args) ;
103
+ auto fmt_args = _vec. slice[ @ast. expr] ( args, 1 u, args_len - 1 u) ;
99
104
ret pieces_to_expr( pieces, args) ;
100
105
}
101
106
@@ -179,7 +184,7 @@ fn parse_conversion(str s, uint i, uint lim) -> tup(piece, uint) {
179
184
flags = flags. _0 ,
180
185
width = width. _0 ,
181
186
precision = prec. _0 ,
182
- typ = ty. _0 ) ) ,
187
+ ty = ty. _0 ) ) ,
183
188
ty. _1 ) ;
184
189
}
185
190
@@ -252,22 +257,107 @@ fn parse_type(str s, uint i, uint lim) -> tup(ty, uint) {
252
257
253
258
fn pieces_to_expr ( vec[ piece] pieces , vec[ @ast. expr] args) -> @ast . expr {
254
259
255
- fn make_new_str ( common . span sp, str s) -> @ast . expr {
256
- auto strlit = ast. lit_str ( s) ;
257
- auto spstrlit = @parser. spanned [ ast. lit_ ] ( sp, sp, strlit) ;
258
- auto expr = ast. expr_lit ( spstrlit, ast. ann_none ) ;
260
+ fn make_new_lit ( common . span sp, ast. lit_ lit ) -> @ast . expr {
261
+ auto sp_lit = @parser. spanned [ ast. lit_ ] ( sp, sp, lit) ;
262
+ auto expr = ast. expr_lit ( sp_lit, ast. ann_none ) ;
259
263
ret @parser. spanned [ ast. expr_ ] ( sp, sp, expr) ;
260
264
}
261
265
266
+ fn make_new_str ( common . span sp, str s) -> @ast . expr {
267
+ auto lit = ast. lit_str ( s) ;
268
+ ret make_new_lit ( sp, lit) ;
269
+ }
270
+
271
+ fn make_new_uint ( common . span sp, uint u) -> @ast . expr {
272
+ auto lit = ast. lit_uint ( u) ;
273
+ ret make_new_lit ( sp, lit) ;
274
+ }
275
+
262
276
fn make_add_expr ( common . span sp,
263
277
@ast. expr lhs , @ast. expr rhs ) -> @ast . expr {
264
278
auto binexpr = ast. expr_binary ( ast. add , lhs, rhs, ast. ann_none ) ;
265
279
ret @parser. spanned [ ast. expr_ ] ( sp, sp, binexpr) ;
266
280
}
267
281
282
+ fn make_call ( common . span sp, vec[ ast. ident] fn_path ,
283
+ vec[ @ast. expr] args) -> @ast . expr {
284
+ let vec[ ast. ident ] path_idents = fn_path;
285
+ let vec[ @ast. ty] path_types = vec ( ) ;
286
+ auto path = rec ( idents = path_idents, types = path_types) ;
287
+ auto sp_path = parser. spanned [ ast. path_ ] ( sp, sp, path) ;
288
+ auto pathexpr = ast. expr_path ( sp_path, none[ ast. def ] , ast. ann_none ) ;
289
+ auto sp_pathexpr = @parser. spanned [ ast. expr_ ] ( sp, sp, pathexpr) ;
290
+ auto callexpr = ast. expr_call ( sp_pathexpr, args, ast. ann_none ) ;
291
+ auto sp_callexpr = @parser. spanned [ ast. expr_ ] ( sp, sp, callexpr) ;
292
+ ret sp_callexpr;
293
+ }
294
+
295
+ fn make_new_conv ( conv cnv, @ast. expr arg ) -> @ast . expr {
296
+
297
+ auto unsupported = "conversion not supported in #fmt string" ;
298
+
299
+ alt ( cnv. param ) {
300
+ case ( option. none [ int] ) {
301
+ }
302
+ case ( _) {
303
+ log unsupported;
304
+ fail;
305
+ }
306
+ }
307
+
308
+ if ( _vec. len [ flag] ( cnv. flags ) != 0 u) {
309
+ log unsupported;
310
+ fail;
311
+ }
312
+
313
+ alt ( cnv. width ) {
314
+ case ( count_implied) {
315
+ }
316
+ case ( _) {
317
+ log unsupported;
318
+ fail;
319
+ }
320
+ }
321
+
322
+ alt ( cnv. precision ) {
323
+ case ( count_implied) {
324
+ }
325
+ case ( _) {
326
+ log unsupported;
327
+ fail;
328
+ }
329
+ }
330
+
331
+ alt ( cnv. ty ) {
332
+ case ( ty_str) {
333
+ ret arg;
334
+ }
335
+ case ( ty_int ( ?sign) ) {
336
+ alt ( sign) {
337
+ case ( signed) {
338
+ let vec[ str] path = vec ( "std" , "_int" , "to_str" ) ;
339
+ auto radix_expr = make_new_uint ( arg. span , 10 u) ;
340
+ let vec[ @ast. expr] args = vec ( arg, radix_expr) ;
341
+ ret make_call( arg. span , path, args) ;
342
+ }
343
+ case ( unsigned) {
344
+ let vec[ str] path = vec ( "std" , "_uint" , "to_str" ) ;
345
+ auto radix_expr = make_new_uint ( arg. span , 10 u) ;
346
+ let vec[ @ast. expr] args = vec ( arg, radix_expr) ;
347
+ ret make_call( arg. span , path, args) ;
348
+ }
349
+ }
350
+ }
351
+ case ( _) {
352
+ log unsupported;
353
+ fail;
354
+ }
355
+ }
356
+ }
357
+
268
358
auto sp = args. ( 0 ) . span;
269
- auto n = 0 ;
270
- auto tmp_expr = make_new_str ( sp, "whatever " ) ;
359
+ auto n = 0 u ;
360
+ auto tmp_expr = make_new_str( sp, "" ) ;
271
361
272
362
for ( piece p in pieces ) {
273
363
alt ( p) {
@@ -276,6 +366,15 @@ fn pieces_to_expr(vec[piece] pieces, vec[@ast.expr] args) -> @ast.expr {
276
366
tmp_expr = make_add_expr ( sp, tmp_expr, s_expr) ;
277
367
}
278
368
case ( piece_conv ( ?conv) ) {
369
+ if ( n >= _vec. len [ @ast. expr ] ( args) ) {
370
+ log "too many conversions in #fmt string" ;
371
+ fail;
372
+ }
373
+
374
+ n += 1 u;
375
+ auto arg_expr = args. ( n) ;
376
+ auto c_expr = make_new_conv ( conv, arg_expr) ;
377
+ tmp_expr = make_add_expr ( sp, tmp_expr, c_expr) ;
279
378
}
280
379
}
281
380
}
0 commit comments