提交 9528c347 编写于 作者: B Brian Anderson 提交者: Graydon Hoare

Begin implementing #fmt in rustc

上级 e2d36e00
......@@ -185,7 +185,7 @@
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
......
/* 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:
//
......@@ -656,7 +656,10 @@ fn is_ident(token.token t) -> bool {
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 @@ fn is_ident(token.token t) -> bool {
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;
......
......@@ -5,6 +5,7 @@ use std;
mod front {
mod ast;
mod extfmt;
mod lexer;
mod parser;
mod token;
......
use std;
import std._str;
fn test(str actual, str expected) {
log actual;
log expected;
check (_str.eq(actual, expected));
}
fn main() {
auto s = #fmt("hello %d friends and %s things", 10, "formatted");
log s;
test(#fmt("hello %d friends and %s things", 10, "formatted"),
"hello 10 friends and formatted things");
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册