@@ -18,6 +18,8 @@ import front.parser;
18
18
import std. _str ;
19
19
import std. _vec ;
20
20
import std. option ;
21
+ import std. option . none ;
22
+ import std. option . some ;
21
23
22
24
tag signedness {
23
25
signed;
@@ -55,13 +57,11 @@ tag count {
55
57
}
56
58
57
59
// A formatted conversion from an expression to a string
58
- tag conv {
59
- conv_param( option. t [ int] ) ;
60
- conv_flags ( vec[ flag] ) ;
61
- conv_width ( count) ;
62
- conv_precision ( count) ;
63
- conv_ty ( ty) ;
64
- }
60
+ type conv = rec ( option. t[ int] param ,
61
+ vec[ flag] flags ,
62
+ count width,
63
+ count precision ,
64
+ ty typ ) ;
65
65
66
66
// A fragment of the output sequence
67
67
tag piece {
@@ -84,6 +84,18 @@ fn expand_syntax_ext(vec[@ast.expr] args,
84
84
auto fmt = expr_to_str ( args. ( 0 ) ) ;
85
85
log fmt;
86
86
auto pieces = parse_fmt_string ( fmt) ;
87
+ log "printing all pieces" ;
88
+ for ( piece p in pieces) {
89
+ alt ( p) {
90
+ case ( piece_string( ?s) ) {
91
+ log s;
92
+ }
93
+ case ( piece_conv( _) ) {
94
+ log "conv" ;
95
+ }
96
+ }
97
+ }
98
+ log "done printing all pieces" ;
87
99
ret pieces_to_expr( pieces, args) ;
88
100
}
89
101
@@ -107,33 +119,16 @@ fn parse_fmt_string(str s) -> vec[piece] {
107
119
auto lim = _str. byte_len( s) ;
108
120
auto buf = "" ;
109
121
110
- // TODO: This is super ugly
111
- fn flush_buf( str buf, vec[ piece] pieces ) -> str {
112
- log "flushing" ;
122
+ fn flush_buf( str buf, & vec[ piece] pieces) -> str {
113
123
if ( _str. byte_len( buf) > 0 u) {
114
124
auto piece = piece_string( buf) ;
115
125
pieces += piece;
116
126
}
117
- log "buf:" ;
118
- log buf;
119
- log "pieces:" ;
120
- for ( piece p in pieces) {
121
- alt ( p) {
122
- case ( piece_string( ?s) ) {
123
- log s;
124
- }
125
- case ( piece_conv( _) ) {
126
- log "conv" ;
127
- }
128
- }
129
- }
130
127
ret "" ;
131
128
}
132
129
133
130
auto i = 0 u;
134
131
while ( i < lim) {
135
- log "step:" ;
136
- log i;
137
132
auto curr = _str. substr ( s, i, 1 u) ;
138
133
if ( _str. eq ( curr, "%" ) ) {
139
134
i += 1 u;
@@ -146,18 +141,115 @@ fn parse_fmt_string(str s) -> vec[piece] {
146
141
i += 1 u;
147
142
} else {
148
143
buf = flush_buf ( buf, pieces) ;
144
+ auto res = parse_conversion ( s, i, lim) ;
145
+ pieces += res. _0 ;
146
+ i = res. _1 ;
149
147
}
150
148
} else {
151
149
buf += curr;
152
- log "buf:" ;
153
- log buf;
154
150
i += 1 u;
155
151
}
156
152
}
157
-
153
+ buf = flush_buf ( buf , pieces ) ;
158
154
ret pieces;
159
155
}
160
156
157
+ fn peek_num ( str s, uint i, uint lim) -> option. t[ tup ( int , int ) ] {
158
+ if ( i >= lim) {
159
+ ret none[ tup ( int, int) ] ;
160
+ } else {
161
+ ret none[ tup ( int, int) ] ;
162
+ /*if ('0' <= c && c <= '9') {
163
+ log c;
164
+ fail;
165
+ } else {
166
+ ret option.none[tup(int, int)];
167
+ }
168
+ */
169
+ }
170
+ }
171
+
172
+ fn parse_conversion ( str s, uint i, uint lim) -> tup ( piece , uint ) {
173
+ auto parm = parse_parameter ( s, i, lim) ;
174
+ auto flags = parse_flags ( s, parm. _1 , lim) ;
175
+ auto width = parse_width ( s, flags. _1 , lim) ;
176
+ auto prec = parse_precision ( s, width. _1 , lim) ;
177
+ auto ty = parse_type ( s, prec. _1 , lim) ;
178
+ ret tup ( piece_conv ( rec ( param = parm. _0 ,
179
+ flags = flags. _0 ,
180
+ width = width. _0 ,
181
+ precision = prec. _0 ,
182
+ typ = ty. _0 ) ) ,
183
+ ty. _1 ) ;
184
+ }
185
+
186
+ fn parse_parameter ( str s, uint i, uint lim) -> tup ( option. t[ int ] , uint ) {
187
+ if ( i >= lim) {
188
+ ret tup ( none[ int] , i) ;
189
+ }
190
+
191
+ auto num = peek_num ( s, i, lim) ;
192
+ alt ( num) {
193
+ case ( none[ tup ( int, int) ] ) {
194
+ ret tup ( none[ int] , i) ;
195
+ }
196
+ case ( some[ tup ( int, int) ] ( ?t) ) {
197
+ fail;
198
+ }
199
+ }
200
+ }
201
+
202
+ fn parse_flags ( str s, uint i, uint lim) -> tup ( vec[ flag ] , uint ) {
203
+ let vec[ flag] flags = vec ( ) ;
204
+ ret tup( flags, i) ;
205
+ }
206
+
207
+ fn parse_width ( str s, uint i, uint lim) -> tup ( count , uint ) {
208
+ ret tup ( count_implied, i) ;
209
+ }
210
+
211
+ fn parse_precision ( str s, uint i, uint lim) -> tup ( count , uint ) {
212
+ ret tup ( count_implied, i) ;
213
+ }
214
+
215
+ fn parse_type ( str s, uint i, uint lim) -> tup ( ty , uint ) {
216
+ if ( i >= lim) {
217
+ log "missing type in conversion" ;
218
+ fail;
219
+ }
220
+
221
+ auto t;
222
+ auto tstr = _str. substr ( s, i, 1 u) ;
223
+ if ( _str. eq ( tstr, "b" ) ) {
224
+ t = ty_bool;
225
+ } else if ( _str. eq ( tstr, "s" ) ) {
226
+ t = ty_str;
227
+ } else if ( _str. eq ( tstr, "c" ) ) {
228
+ t = ty_char;
229
+ } else if ( _str. eq ( tstr, "d" )
230
+ || _str. eq ( tstr, "i" ) ) {
231
+ // TODO: Do we really want two signed types here?
232
+ // How important is it to be printf compatible?
233
+ t = ty_int ( signed) ;
234
+ } else if ( _str. eq ( tstr, "u" ) ) {
235
+ t = ty_int ( unsigned) ;
236
+ } else if ( _str. eq ( tstr, "x" ) ) {
237
+ t = ty_hex ( case_lower) ;
238
+ } else if ( _str. eq ( tstr, "X" ) ) {
239
+ t = ty_hex ( case_upper) ;
240
+ } else if ( _str. eq ( tstr, "t" ) ) {
241
+ t = ty_bits;
242
+ } else {
243
+ // FIXME: This is a hack to avoid 'unsatisfied precondition
244
+ // constraint' on uninitialized variable t below
245
+ t = ty_bool;
246
+ log "unknown type in conversion" ;
247
+ fail;
248
+ }
249
+
250
+ ret tup( t, i + 1 u) ;
251
+ }
252
+
161
253
fn pieces_to_expr ( vec[ piece] pieces , vec[ @ast. expr] args) -> @ast . expr {
162
254
auto lo = args. ( 0 ) . span ;
163
255
auto hi = args. ( 0 ) . span ;
0 commit comments