diff options
| author | Brian Anderson <[email protected]> | 2011-02-24 23:22:36 -0500 |
|---|---|---|
| committer | Graydon Hoare <[email protected]> | 2011-03-02 10:28:14 -0800 |
| commit | 1c60399257cde71fc265eb10cae1f398a0ac2516 (patch) | |
| tree | 6cbe2270a9553e1686505ba6684cab0c8f51795a /src/comp/front | |
| parent | Begin implementing #fmt in rustc (diff) | |
| download | rust-1c60399257cde71fc265eb10cae1f398a0ac2516.tar.xz rust-1c60399257cde71fc265eb10cae1f398a0ac2516.zip | |
Begin work on #fmt parsing
Diffstat (limited to 'src/comp/front')
| -rw-r--r-- | src/comp/front/extfmt.rs | 100 | ||||
| -rw-r--r-- | src/comp/front/parser.rs | 1 |
2 files changed, 98 insertions, 3 deletions
diff --git a/src/comp/front/extfmt.rs b/src/comp/front/extfmt.rs index cb70805a..7018ef14 100644 --- a/src/comp/front/extfmt.rs +++ b/src/comp/front/extfmt.rs @@ -13,8 +13,10 @@ * combinations at the moment. */ -use std; +import front.parser; +import std._str; +import std._vec; import std.option; tag signedness { @@ -64,14 +66,108 @@ tag conv { // A fragment of the output sequence tag piece { piece_string(str); - piece_conv(str); + piece_conv(conv); +} + +fn bad_fmt_call() { + log "malformed #fmt call"; + fail; } fn expand_syntax_ext(vec[@ast.expr] args, option.t[@ast.expr] body) -> @ast.expr { + + if (_vec.len[@ast.expr](args) == 0u) { + bad_fmt_call(); + } + + auto fmt = expr_to_str(args.(0)); + log fmt; + auto pieces = parse_fmt_string(fmt); + ret pieces_to_expr(pieces, args); +} + +fn expr_to_str(@ast.expr expr) -> str { + alt (expr.node) { + case (ast.expr_lit(?l, _)) { + alt (l.node) { + case (ast.lit_str(?s)) { + ret s; + } + } + } + } + bad_fmt_call(); fail; } +fn parse_fmt_string(str s) -> vec[piece] { + let vec[piece] pieces = vec(); + // FIXME: Should be counting codepoints instead of bytes + auto lim = _str.byte_len(s); + auto buf = ""; + + // TODO: This is super ugly + fn flush_buf(str buf, vec[piece] pieces) -> str { + log "flushing"; + if (_str.byte_len(buf) > 0u) { + auto piece = piece_string(buf); + pieces += piece; + } + log "buf:"; + log buf; + log "pieces:"; + for (piece p in pieces) { + alt (p) { + case (piece_string(?s)) { + log s; + } + case (piece_conv(_)) { + log "conv"; + } + } + } + ret ""; + } + + auto i = 0u; + while (i < lim) { + log "step:"; + log i; + auto curr = _str.substr(s, i, 1u); + if (_str.eq(curr, "%")) { + i += 1u; + if (i >= lim) { + log "unterminated conversion at end of string"; + fail; + } + auto curr2 = _str.substr(s, i, 1u); + if (_str.eq(curr2, "%")) { + i += 1u; + } else { + buf = flush_buf(buf, pieces); + } + } else { + buf += curr; + log "buf:"; + log buf; + i += 1u; + } + } + + ret pieces; +} + +fn pieces_to_expr(vec[piece] pieces, vec[@ast.expr] args) -> @ast.expr { + auto lo = args.(0).span; + auto hi = args.(0).span; + auto strlit = ast.lit_str("TODO"); + auto spstrlit = @parser.spanned[ast.lit_](lo, hi, strlit); + auto expr = ast.expr_lit(spstrlit, ast.ann_none); + auto spexpr = @parser.spanned[ast.expr_](lo, hi, expr); + ret spexpr; +} + // // Local Variables: // mode: rust diff --git a/src/comp/front/parser.rs b/src/comp/front/parser.rs index 8f6db17d..e5f68033 100644 --- a/src/comp/front/parser.rs +++ b/src/comp/front/parser.rs @@ -756,7 +756,6 @@ impure fn expand_syntax_ext(parser p, @ast.expr ext) -> @ast.expr { auto extname = path.node.idents.(0); if (_str.eq(extname, "fmt")) { auto expanded = extfmt.expand_syntax_ext(args, body); - check (ast.is_ext_expr(expanded)); auto newexpr = ast.expr_ext(path, args, body, some[@ast.expr](expanded), ann); |