aboutsummaryrefslogtreecommitdiff
path: root/src/comp/front
diff options
context:
space:
mode:
authorBrian Anderson <[email protected]>2011-02-24 23:22:36 -0500
committerGraydon Hoare <[email protected]>2011-03-02 10:28:14 -0800
commit1c60399257cde71fc265eb10cae1f398a0ac2516 (patch)
tree6cbe2270a9553e1686505ba6684cab0c8f51795a /src/comp/front
parentBegin implementing #fmt in rustc (diff)
downloadrust-1c60399257cde71fc265eb10cae1f398a0ac2516.tar.xz
rust-1c60399257cde71fc265eb10cae1f398a0ac2516.zip
Begin work on #fmt parsing
Diffstat (limited to 'src/comp/front')
-rw-r--r--src/comp/front/extfmt.rs100
-rw-r--r--src/comp/front/parser.rs1
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);