about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorBrian Anderson <andersrb@gmail.com>2011-02-27 14:30:44 -0500
committerGraydon Hoare <graydon@mozilla.com>2011-03-02 10:28:14 -0800
commitfe5de6bfffee3c277f540517b5766547f34e81c7 (patch)
tree0c93def17b39f88ac2dca3e83fe5fb7416cfd058 /src
parentf1500e5872d03e3ec3b140060641136a2ff5a15a (diff)
Parse parameter types for fmt extension
Diffstat (limited to 'src')
-rw-r--r--src/comp/front/extfmt.rs148
-rw-r--r--src/comp/middle/trans.rs4
-rw-r--r--src/rt/memory_region.cpp2
-rw-r--r--src/test/run-pass/syntax-extension-fmt.rs11
4 files changed, 126 insertions, 39 deletions
diff --git a/src/comp/front/extfmt.rs b/src/comp/front/extfmt.rs
index 7018ef146f0..998bfa4de43 100644
--- a/src/comp/front/extfmt.rs
+++ b/src/comp/front/extfmt.rs
@@ -18,6 +18,8 @@ import front.parser;
 import std._str;
 import std._vec;
 import std.option;
+import std.option.none;
+import std.option.some;
 
 tag signedness {
     signed;
@@ -55,13 +57,11 @@ tag count {
 }
 
 // A formatted conversion from an expression to a string
-tag conv {
-    conv_param(option.t[int]);
-    conv_flags(vec[flag]);
-    conv_width(count);
-    conv_precision(count);
-    conv_ty(ty);
-}
+type conv = rec(option.t[int] param,
+                vec[flag] flags,
+                count width,
+                count precision,
+                ty typ);
 
 // A fragment of the output sequence
 tag piece {
@@ -84,6 +84,18 @@ fn expand_syntax_ext(vec[@ast.expr] args,
     auto fmt = expr_to_str(args.(0));
     log fmt;
     auto pieces = parse_fmt_string(fmt);
+    log "printing all pieces";
+    for (piece p in pieces) {
+        alt (p) {
+            case (piece_string(?s)) {
+                log s;
+            }
+            case (piece_conv(_)) {
+                log "conv";
+            }
+        }
+    }
+    log "done printing all pieces";
     ret pieces_to_expr(pieces, args);
 }
 
@@ -107,33 +119,16 @@ fn parse_fmt_string(str s) -> vec[piece] {
     auto lim = _str.byte_len(s);
     auto buf = "";
 
-    // TODO: This is super ugly
-    fn flush_buf(str buf, vec[piece] pieces) -> str {
-        log "flushing";
+    fn flush_buf(str buf, &vec[piece] pieces) -> str {
         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;
@@ -146,18 +141,115 @@ fn parse_fmt_string(str s) -> vec[piece] {
                 i += 1u;
             } else {
                 buf = flush_buf(buf, pieces);
+                auto res = parse_conversion(s, i, lim);
+                pieces += res._0;
+                i = res._1;
             }
         } else {
             buf += curr;
-            log "buf:";
-            log buf;
             i += 1u;
         }
     }
-
+    buf = flush_buf(buf, pieces);
     ret pieces;
 }
 
+fn peek_num(str s, uint i, uint lim) -> option.t[tup(int, int)] {
+    if (i >= lim) {
+        ret none[tup(int, int)];
+    } else {
+        ret none[tup(int, int)];
+        /*if ('0' <= c && c <= '9') {
+            log c;
+            fail;
+        } else {
+            ret option.none[tup(int, int)];
+        }
+        */
+    }
+}
+
+fn parse_conversion(str s, uint i, uint lim) -> tup(piece, uint) {
+    auto parm = parse_parameter(s, i, lim);
+    auto flags = parse_flags(s, parm._1, lim);
+    auto width = parse_width(s, flags._1, lim);
+    auto prec = parse_precision(s, width._1, lim);
+    auto ty = parse_type(s, prec._1, lim);
+    ret tup(piece_conv(rec(param = parm._0,
+                           flags = flags._0,
+                           width = width._0,
+                           precision = prec._0,
+                           typ = ty._0)),
+            ty._1);
+}
+
+fn parse_parameter(str s, uint i, uint lim) -> tup(option.t[int], uint) {
+    if (i >= lim) {
+        ret tup(none[int], i);
+    }
+
+    auto num = peek_num(s, i, lim);
+    alt (num) {
+        case (none[tup(int, int)]) {
+            ret tup(none[int], i);
+        }
+        case (some[tup(int, int)](?t)) {
+            fail;
+        }
+    }
+}
+
+fn parse_flags(str s, uint i, uint lim) -> tup(vec[flag], uint) {
+    let vec[flag] flags = vec();
+    ret tup(flags, i);
+}
+
+fn parse_width(str s, uint i, uint lim) -> tup(count, uint) {
+    ret tup(count_implied, i);
+}
+
+fn parse_precision(str s, uint i, uint lim) -> tup(count, uint) {
+    ret tup(count_implied, i);
+}
+
+fn parse_type(str s, uint i, uint lim) -> tup(ty, uint) {
+    if (i >= lim) {
+        log "missing type in conversion";
+        fail;
+    }
+
+    auto t;
+    auto tstr = _str.substr(s, i, 1u);
+    if (_str.eq(tstr, "b")) {
+        t = ty_bool;
+    } else if (_str.eq(tstr, "s")) {
+        t = ty_str;
+    } else if (_str.eq(tstr, "c")) {
+        t = ty_char;
+    } else if (_str.eq(tstr, "d")
+               || _str.eq(tstr, "i")) {
+        // TODO: Do we really want two signed types here?
+        // How important is it to be printf compatible?
+        t = ty_int(signed);
+    } else if (_str.eq(tstr, "u")) {
+        t = ty_int(unsigned);
+    } else if (_str.eq(tstr, "x")) {
+        t = ty_hex(case_lower);
+    } else if (_str.eq(tstr, "X")) {
+        t = ty_hex(case_upper);
+    } else if (_str.eq(tstr, "t")) {
+        t = ty_bits;
+    } else {
+        // FIXME: This is a hack to avoid 'unsatisfied precondition
+        // constraint' on uninitialized variable t below
+        t = ty_bool;
+        log "unknown type in conversion";
+        fail;
+    }
+
+    ret tup(t, i + 1u);
+}
+
 fn pieces_to_expr(vec[piece] pieces, vec[@ast.expr] args) -> @ast.expr {
     auto lo = args.(0).span;
     auto hi = args.(0).span;
diff --git a/src/comp/middle/trans.rs b/src/comp/middle/trans.rs
index f8c3fd61d46..9fee3dab4a0 100644
--- a/src/comp/middle/trans.rs
+++ b/src/comp/middle/trans.rs
@@ -1957,8 +1957,6 @@ fn trans_lit(@crate_ctxt cx, &ast.lit lit, &ast.ann ann) -> ValueRef {
             ret C_nil();
         }
         case (ast.lit_str(?s)) {
-            log "translating literal:";
-            log s;
             ret C_str(cx, s);
         }
     }
@@ -3601,7 +3599,6 @@ fn trans_rec(@block_ctxt cx, vec[ast.field] fields,
 fn trans_expr(@block_ctxt cx, @ast.expr e) -> result {
     alt (e.node) {
         case (ast.expr_lit(?lit, ?ann)) {
-            log "translating literal";
             ret res(cx, trans_lit(cx.fcx.ccx, *lit, ann));
         }
 
@@ -3697,7 +3694,6 @@ fn trans_expr(@block_ctxt cx, @ast.expr e) -> result {
         }
 
         case (ast.expr_ext(_, _, _, ?expanded, _)) {
-            log "translating extension";
             ret trans_expr(cx, option.get[@ast.expr](expanded));
         }
 
diff --git a/src/rt/memory_region.cpp b/src/rt/memory_region.cpp
index 7ede3761e9a..fb19620f8b9 100644
--- a/src/rt/memory_region.cpp
+++ b/src/rt/memory_region.cpp
@@ -1,7 +1,7 @@
 #include "rust_internal.h"
 #include "memory_region.h"
 
-// #define TRACK_ALLOCATIONS
+#define TRACK_ALLOCATIONS
 
 memory_region::memory_region(rust_srv *srv, bool synchronized) :
     _srv(srv), _parent(NULL), _live_allocations(0),
diff --git a/src/test/run-pass/syntax-extension-fmt.rs b/src/test/run-pass/syntax-extension-fmt.rs
index 0d1d708297f..b7076c8176d 100644
--- a/src/test/run-pass/syntax-extension-fmt.rs
+++ b/src/test/run-pass/syntax-extension-fmt.rs
@@ -1,14 +1,13 @@
-//use std;
-//import std._str;
+use std;
+import std._str;
 
 fn test(str actual, str expected) {
   log actual;
   log expected;
-  //check (_str.eq(actual, expected));
+  check (_str.eq(actual, expected));
 }
 
 fn main() {
-  /*test(#fmt("hello %d friends and %s things", 10, "formatted"),
-    "hello 10 friends and formatted things");*/
-  log #fmt("test");
+  test(#fmt("hello %d friends and %s things", 10, "formatted"),
+    "hello 10 friends and formatted things");
 }