Skip to content

Commit 37f8716

Browse files
committed
Move ExtFmt compile-time functions into their own module
1 parent c41796f commit 37f8716

File tree

2 files changed

+174
-171
lines changed

2 files changed

+174
-171
lines changed

src/comp/front/extfmt.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ import std.ExtFmt.conv;
5050
import std.ExtFmt.piece;
5151
import std.ExtFmt.piece_string;
5252
import std.ExtFmt.piece_conv;
53-
import std.ExtFmt.parse_fmt_string;
53+
import std.ExtFmt.CT.parse_fmt_string;
5454

5555
export expand_syntax_ext;
5656

src/lib/ExtFmt.rs

Lines changed: 173 additions & 170 deletions
Original file line numberDiff line numberDiff line change
@@ -49,214 +49,217 @@ tag piece {
4949
piece_conv(conv);
5050
}
5151

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) > 0u) {
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) > 0u) {
61+
auto piece = piece_string(buf);
62+
pieces += vec(piece);
63+
}
64+
ret "";
6165
}
62-
ret "";
63-
}
6466

65-
auto i = 0u;
66-
while (i < lim) {
67-
auto curr = _str.substr(s, i, 1u);
68-
if (_str.eq(curr, "%")) {
69-
i += 1u;
70-
if (i >= lim) {
71-
log "unterminated conversion at end of string";
72-
fail;
73-
}
74-
auto curr2 = _str.substr(s, i, 1u);
75-
if (_str.eq(curr2, "%")) {
67+
auto i = 0u;
68+
while (i < lim) {
69+
auto curr = _str.substr(s, i, 1u);
70+
if (_str.eq(curr, "%")) {
7671
i += 1u;
72+
if (i >= lim) {
73+
log "unterminated conversion at end of string";
74+
fail;
75+
}
76+
auto curr2 = _str.substr(s, i, 1u);
77+
if (_str.eq(curr2, "%")) {
78+
i += 1u;
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+
}
7785
} 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 += 1u;
8288
}
83-
} else {
84-
buf += curr;
85-
i += 1u;
8689
}
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;
10092
}
10193

102-
auto n = (c - ('0' as u8)) as uint;
103-
alt (peek_num(s, i + 1u, lim)) {
104-
case (none[tup(uint, uint)]) {
105-
ret some[tup(uint, uint)](tup(n, i + 1u));
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)];
10697
}
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 * 10u + 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)];
111102
}
112-
}
113103

114-
}
104+
auto n = (c - ('0' as u8)) as uint;
105+
alt (peek_num(s, i + 1u, lim)) {
106+
case (none[tup(uint, uint)]) {
107+
ret some[tup(uint, uint)](tup(n, i + 1u));
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 * 10u + m, j));
113+
}
114+
}
115115

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+
}
129117

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);
133130
}
134131

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) {
138134
ret tup(none[int], i);
139135
}
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 + 1u);
145-
}
146-
else {
136+
137+
auto num = peek_num(s, i, lim);
138+
alt (num) {
139+
case (none[tup(uint, uint)]) {
147140
ret tup(none[int], i);
148141
}
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 + 1u);
147+
}
148+
else {
149+
ret tup(none[int], i);
150+
}
151+
}
149152
}
150153
}
151-
}
152-
153-
fn parse_flags(str s, uint i, uint lim) -> tup(vec[flag], uint) {
154-
let vec[flag] noflags = vec();
155154

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();
159157

160-
fn more_(flag f, str s, uint i, uint lim) -> tup(vec[flag], uint) {
161-
auto next = parse_flags(s, i + 1u, 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+
}
167161

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 + 1u, 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+
}
185169

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+
}
189186
}
190187

191-
if (s.(i) == ('*' as u8)) {
192-
auto param = parse_parameter(s, i + 1u, 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);
201191
}
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 + 1u, 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+
}
207203
}
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+
}
210213
}
211214
}
212215
}
213-
}
214216

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+
}
219221

220-
if (s.(i) == '.' as u8) {
221-
ret parse_count(s, i + 1u, lim);
222-
} else {
223-
ret tup(count_implied, i);
222+
if (s.(i) == '.' as u8) {
223+
ret parse_count(s, i + 1u, lim);
224+
} else {
225+
ret tup(count_implied, i);
226+
}
224227
}
225-
}
226228

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+
}
232234

233-
auto t;
234-
auto tstr = _str.substr(s, i, 1u);
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, 1u);
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+
}
258260

259-
ret tup(t, i + 1u);
261+
ret tup(t, i + 1u);
262+
}
260263
}
261264

262265
// Functions used by the fmt extension at runtime

0 commit comments

Comments
 (0)