aboutsummaryrefslogtreecommitdiff
path: root/src/comp
diff options
context:
space:
mode:
authorBrian Anderson <[email protected]>2011-02-23 23:48:01 -0500
committerGraydon Hoare <[email protected]>2011-03-02 10:28:14 -0800
commit9528c34774ff27b112c9e66afff6e10fa7021635 (patch)
tree4d5f9bde4c48eed1a188f6002e88daa93f4ea28b /src/comp
parentRemove parens from nullary tag constructors in docs (diff)
downloadrust-9528c34774ff27b112c9e66afff6e10fa7021635.tar.xz
rust-9528c34774ff27b112c9e66afff6e10fa7021635.zip
Begin implementing #fmt in rustc
Diffstat (limited to 'src/comp')
-rw-r--r--src/comp/front/ast.rs13
-rw-r--r--src/comp/front/extfmt.rs84
-rw-r--r--src/comp/front/parser.rs35
-rw-r--r--src/comp/rustc.rc1
4 files changed, 131 insertions, 2 deletions
diff --git a/src/comp/front/ast.rs b/src/comp/front/ast.rs
index 4ed513a3..18add3bd 100644
--- a/src/comp/front/ast.rs
+++ b/src/comp/front/ast.rs
@@ -185,7 +185,7 @@ tag expr_ {
expr_field(@expr, ident, ann);
expr_index(@expr, @expr, ann);
expr_path(path, option.t[def], ann);
- expr_ext(path, vec[@expr], option.t[@expr], ann);
+ expr_ext(path, vec[@expr], option.t[@expr], option.t[@expr], ann);
expr_fail;
expr_ret(option.t[@expr]);
expr_put(option.t[@expr]);
@@ -363,6 +363,17 @@ fn is_call_expr(@expr e) -> bool {
}
}
+fn is_ext_expr(@expr e) -> bool {
+ alt (e.node) {
+ case (expr_ext(_, _, _, _, _)) {
+ ret true;
+ }
+ case (_) {
+ ret false;
+ }
+ }
+}
+
//
// Local Variables:
// mode: rust
diff --git a/src/comp/front/extfmt.rs b/src/comp/front/extfmt.rs
new file mode 100644
index 00000000..cb70805a
--- /dev/null
+++ b/src/comp/front/extfmt.rs
@@ -0,0 +1,84 @@
+/* The 'fmt' extension is modeled on the posix printf system.
+ *
+ * A posix conversion ostensibly looks like this:
+ *
+ * %[parameter][flags][width][.precision][length]type
+ *
+ * Given the different numeric type bestiary we have, we omit the 'length'
+ * parameter and support slightly different conversions for 'type':
+ *
+ * %[parameter][flags][width][.precision]type
+ *
+ * we also only support translating-to-rust a tiny subset of the possible
+ * combinations at the moment.
+ */
+
+use std;
+
+import std.option;
+
+tag signedness {
+ signed;
+ unsigned;
+}
+
+tag caseness {
+ case_upper;
+ case_lower;
+}
+
+tag ty {
+ ty_bool;
+ ty_str;
+ ty_char;
+ ty_int(signedness);
+ ty_bits;
+ ty_hex(caseness);
+ // FIXME: More types
+}
+
+tag flag {
+ flag_left_justify;
+ flag_left_zero_pad;
+ flag_left_space_pad;
+ flag_plus_if_positive;
+ flag_alternate;
+}
+
+tag count {
+ count_is(int);
+ count_is_param(int);
+ count_is_next_param;
+ count_implied;
+}
+
+// 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);
+}
+
+// A fragment of the output sequence
+tag piece {
+ piece_string(str);
+ piece_conv(str);
+}
+
+fn expand_syntax_ext(vec[@ast.expr] args,
+ option.t[@ast.expr] body) -> @ast.expr {
+ fail;
+}
+
+//
+// Local Variables:
+// mode: rust
+// fill-column: 78;
+// indent-tabs-mode: nil
+// c-basic-offset: 4
+// buffer-file-coding-system: utf-8-unix
+// compile-command: "make -k -C ../.. 2>&1 | sed -e 's/\\/x\\//x:\\//g'";
+// End:
+//
diff --git a/src/comp/front/parser.rs b/src/comp/front/parser.rs
index f747c084..8f6db17d 100644
--- a/src/comp/front/parser.rs
+++ b/src/comp/front/parser.rs
@@ -656,7 +656,10 @@ impure fn parse_bottom_expr(parser p) -> @ast.expr {
some(token.COMMA),
pf, p);
hi = es.span;
- ex = ast.expr_ext(pth, es.node, none[@ast.expr], ast.ann_none);
+ ex = ast.expr_ext(pth, es.node, none[@ast.expr],
+ none[@ast.expr], ast.ann_none);
+ // FIXME: Here is probably not the right place for this
+ ex = expand_syntax_ext(p, @spanned(lo, hi, ex)).node;
}
case (token.FAIL) {
@@ -736,6 +739,36 @@ impure fn parse_bottom_expr(parser p) -> @ast.expr {
ret @spanned(lo, hi, ex);
}
+/*
+ * FIXME: This is a crude approximation of the syntax-extension system,
+ * for purposes of prototyping and/or hard-wiring any extensions we
+ * wish to use while bootstrapping. The eventual aim is to permit
+ * loading rust crates to process extensions, but this will likely
+ * require a rust-based frontend, or an ocaml-FFI-based connection to
+ * rust crates. At the moment we have neither.
+ */
+
+impure fn expand_syntax_ext(parser p, @ast.expr ext) -> @ast.expr {
+ check (ast.is_ext_expr(ext));
+ alt (ext.node) {
+ case (ast.expr_ext(?path, ?args, ?body, _, ?ann)) {
+ check (_vec.len[ast.ident](path.node.idents) > 0u);
+ 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);
+
+ ret @spanned(ext.span, ext.span, newexpr);
+ } else {
+ p.err("unknown syntax extension");
+ }
+ }
+ }
+ fail;
+}
+
impure fn extend_expr_by_ident(parser p, span lo, span hi,
@ast.expr e, ast.ident i) -> @ast.expr {
auto e_ = e.node;
diff --git a/src/comp/rustc.rc b/src/comp/rustc.rc
index bc4aaa52..16d24e9b 100644
--- a/src/comp/rustc.rc
+++ b/src/comp/rustc.rc
@@ -5,6 +5,7 @@ use std;
mod front {
mod ast;
+ mod extfmt;
mod lexer;
mod parser;
mod token;