auto merge of #6611 : huonw/rust/syntax-ext-no-dup, r=jbclements
Fixes https://github.com/mozilla/rust/issues/6578 by merging the 3 different ways to build an AST into a single `AstBuilder` trait, creating a more uniform and briefer interface. Also, converts the `ext_ctxt` trait-object to be a plain struct, as well as renaming it to `ExtCtxt`. Seems to make expansion slightly faster for the normal case (e.g. `libcore` and `libstd`), but slower for `librustc` (slightly) and `libsyntax` (0.3s -> 0.8s! I'm investigating this, but I'd prefer this patch to land relatively quickly.). `git blame` suggests maybe @graydon or @erickt are familiar with this area of the code. r?
This commit is contained in:
commit
64963d6cba
36 changed files with 1719 additions and 2302 deletions
|
|
@ -17,7 +17,7 @@ use syntax::ast_util::*;
|
|||
use syntax::attr;
|
||||
use syntax::codemap::{dummy_sp, span, ExpandedFrom, CallInfo, NameAndSpan};
|
||||
use syntax::codemap;
|
||||
use syntax::ext::base::{mk_ctxt, ext_ctxt};
|
||||
use syntax::ext::base::ExtCtxt;
|
||||
use syntax::fold;
|
||||
use syntax::print::pprust;
|
||||
use syntax::{ast, ast_util};
|
||||
|
|
@ -36,7 +36,7 @@ struct TestCtxt {
|
|||
sess: session::Session,
|
||||
crate: @ast::crate,
|
||||
path: ~[ast::ident],
|
||||
ext_cx: @ext_ctxt,
|
||||
ext_cx: @ExtCtxt,
|
||||
testfns: ~[Test]
|
||||
}
|
||||
|
||||
|
|
@ -64,7 +64,7 @@ fn generate_test_harness(sess: session::Session,
|
|||
let cx: @mut TestCtxt = @mut TestCtxt {
|
||||
sess: sess,
|
||||
crate: crate,
|
||||
ext_cx: mk_ctxt(sess.parse_sess, copy sess.opts.cfg),
|
||||
ext_cx: ExtCtxt::new(sess.parse_sess, copy sess.opts.cfg),
|
||||
path: ~[],
|
||||
testfns: ~[]
|
||||
};
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ use std::semver;
|
|||
use std::term;
|
||||
use syntax::ast_util::*;
|
||||
use syntax::codemap::{dummy_sp, spanned, dummy_spanned};
|
||||
use syntax::ext::base::{mk_ctxt, ext_ctxt};
|
||||
use syntax::ext::base::ExtCtxt;
|
||||
use syntax::{ast, attr, codemap, diagnostic, fold};
|
||||
use syntax::ast::{meta_name_value, meta_list};
|
||||
use syntax::attr::{mk_attr};
|
||||
|
|
@ -178,7 +178,7 @@ struct ListenerFn {
|
|||
struct ReadyCtx {
|
||||
sess: session::Session,
|
||||
crate: @ast::crate,
|
||||
ext_cx: @ext_ctxt,
|
||||
ext_cx: @ExtCtxt,
|
||||
path: ~[ast::ident],
|
||||
fns: ~[ListenerFn]
|
||||
}
|
||||
|
|
@ -247,7 +247,7 @@ pub fn ready_crate(sess: session::Session,
|
|||
let ctx = @mut ReadyCtx {
|
||||
sess: sess,
|
||||
crate: crate,
|
||||
ext_cx: mk_ctxt(sess.parse_sess, copy sess.opts.cfg),
|
||||
ext_cx: ExtCtxt::new(sess.parse_sess, copy sess.opts.cfg),
|
||||
path: ~[],
|
||||
fns: ~[]
|
||||
};
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ fn next_state(s: State) -> Option<State> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn expand_asm(cx: @ext_ctxt, sp: span, tts: &[ast::token_tree])
|
||||
pub fn expand_asm(cx: @ExtCtxt, sp: span, tts: &[ast::token_tree])
|
||||
-> base::MacResult {
|
||||
let p = parse::new_parser_from_tts(cx.parse_sess(),
|
||||
cx.cfg(),
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ use codemap::span;
|
|||
use ext::base::*;
|
||||
|
||||
pub fn expand_auto_encode(
|
||||
cx: @ext_ctxt,
|
||||
cx: @ExtCtxt,
|
||||
span: span,
|
||||
_mitem: @ast::meta_item,
|
||||
in_items: ~[@ast::item]
|
||||
|
|
@ -25,7 +25,7 @@ pub fn expand_auto_encode(
|
|||
}
|
||||
|
||||
pub fn expand_auto_decode(
|
||||
cx: @ext_ctxt,
|
||||
cx: @ExtCtxt,
|
||||
span: span,
|
||||
_mitem: @ast::meta_item,
|
||||
in_items: ~[@ast::item]
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ pub struct MacroDef {
|
|||
ext: SyntaxExtension
|
||||
}
|
||||
|
||||
pub type ItemDecorator = @fn(@ext_ctxt,
|
||||
pub type ItemDecorator = @fn(@ExtCtxt,
|
||||
span,
|
||||
@ast::meta_item,
|
||||
~[@ast::item])
|
||||
|
|
@ -44,7 +44,7 @@ pub struct SyntaxExpanderTT {
|
|||
span: Option<span>
|
||||
}
|
||||
|
||||
pub type SyntaxExpanderTTFun = @fn(@ext_ctxt,
|
||||
pub type SyntaxExpanderTTFun = @fn(@ExtCtxt,
|
||||
span,
|
||||
&[ast::token_tree])
|
||||
-> MacResult;
|
||||
|
|
@ -54,7 +54,7 @@ pub struct SyntaxExpanderTTItem {
|
|||
span: Option<span>
|
||||
}
|
||||
|
||||
pub type SyntaxExpanderTTItemFun = @fn(@ext_ctxt,
|
||||
pub type SyntaxExpanderTTItemFun = @fn(@ExtCtxt,
|
||||
span,
|
||||
ast::ident,
|
||||
~[ast::token_tree])
|
||||
|
|
@ -202,134 +202,109 @@ pub fn syntax_expander_table() -> SyntaxEnv {
|
|||
// One of these is made during expansion and incrementally updated as we go;
|
||||
// when a macro expansion occurs, the resulting nodes have the backtrace()
|
||||
// -> expn_info of their expansion context stored into their span.
|
||||
pub trait ext_ctxt {
|
||||
fn codemap(&self) -> @CodeMap;
|
||||
fn parse_sess(&self) -> @mut parse::ParseSess;
|
||||
fn cfg(&self) -> ast::crate_cfg;
|
||||
fn call_site(&self) -> span;
|
||||
fn print_backtrace(&self);
|
||||
fn backtrace(&self) -> Option<@ExpnInfo>;
|
||||
fn mod_push(&self, mod_name: ast::ident);
|
||||
fn mod_pop(&self);
|
||||
fn mod_path(&self) -> ~[ast::ident];
|
||||
fn bt_push(&self, ei: codemap::ExpnInfo);
|
||||
fn bt_pop(&self);
|
||||
fn span_fatal(&self, sp: span, msg: &str) -> !;
|
||||
fn span_err(&self, sp: span, msg: &str);
|
||||
fn span_warn(&self, sp: span, msg: &str);
|
||||
fn span_unimpl(&self, sp: span, msg: &str) -> !;
|
||||
fn span_bug(&self, sp: span, msg: &str) -> !;
|
||||
fn bug(&self, msg: &str) -> !;
|
||||
fn next_id(&self) -> ast::node_id;
|
||||
fn trace_macros(&self) -> bool;
|
||||
fn set_trace_macros(&self, x: bool);
|
||||
/* for unhygienic identifier transformation */
|
||||
fn str_of(&self, id: ast::ident) -> ~str;
|
||||
fn ident_of(&self, st: &str) -> ast::ident;
|
||||
pub struct ExtCtxt {
|
||||
parse_sess: @mut parse::ParseSess,
|
||||
cfg: ast::crate_cfg,
|
||||
backtrace: @mut Option<@ExpnInfo>,
|
||||
|
||||
// These two @mut's should really not be here,
|
||||
// but the self types for CtxtRepr are all wrong
|
||||
// and there are bugs in the code for object
|
||||
// types that make this hard to get right at the
|
||||
// moment. - nmatsakis
|
||||
mod_path: @mut ~[ast::ident],
|
||||
trace_mac: @mut bool
|
||||
}
|
||||
|
||||
pub fn mk_ctxt(parse_sess: @mut parse::ParseSess, cfg: ast::crate_cfg)
|
||||
-> @ext_ctxt {
|
||||
struct CtxtRepr {
|
||||
parse_sess: @mut parse::ParseSess,
|
||||
cfg: ast::crate_cfg,
|
||||
backtrace: @mut Option<@ExpnInfo>,
|
||||
|
||||
// These two @mut's should really not be here,
|
||||
// but the self types for CtxtRepr are all wrong
|
||||
// and there are bugs in the code for object
|
||||
// types that make this hard to get right at the
|
||||
// moment. - nmatsakis
|
||||
mod_path: @mut ~[ast::ident],
|
||||
trace_mac: @mut bool
|
||||
}
|
||||
impl ext_ctxt for CtxtRepr {
|
||||
fn codemap(&self) -> @CodeMap { self.parse_sess.cm }
|
||||
fn parse_sess(&self) -> @mut parse::ParseSess { self.parse_sess }
|
||||
fn cfg(&self) -> ast::crate_cfg { copy self.cfg }
|
||||
fn call_site(&self) -> span {
|
||||
match *self.backtrace {
|
||||
Some(@ExpandedFrom(CallInfo {call_site: cs, _})) => cs,
|
||||
None => self.bug("missing top span")
|
||||
}
|
||||
pub impl ExtCtxt {
|
||||
fn new(parse_sess: @mut parse::ParseSess, cfg: ast::crate_cfg) -> @ExtCtxt {
|
||||
@ExtCtxt {
|
||||
parse_sess: parse_sess,
|
||||
cfg: cfg,
|
||||
backtrace: @mut None,
|
||||
mod_path: @mut ~[],
|
||||
trace_mac: @mut false
|
||||
}
|
||||
fn print_backtrace(&self) { }
|
||||
fn backtrace(&self) -> Option<@ExpnInfo> { *self.backtrace }
|
||||
fn mod_push(&self, i: ast::ident) { self.mod_path.push(i); }
|
||||
fn mod_pop(&self) { self.mod_path.pop(); }
|
||||
fn mod_path(&self) -> ~[ast::ident] { copy *self.mod_path }
|
||||
fn bt_push(&self, ei: codemap::ExpnInfo) {
|
||||
match ei {
|
||||
ExpandedFrom(CallInfo {call_site: cs, callee: ref callee}) => {
|
||||
}
|
||||
|
||||
fn codemap(&self) -> @CodeMap { self.parse_sess.cm }
|
||||
fn parse_sess(&self) -> @mut parse::ParseSess { self.parse_sess }
|
||||
fn cfg(&self) -> ast::crate_cfg { copy self.cfg }
|
||||
fn call_site(&self) -> span {
|
||||
match *self.backtrace {
|
||||
Some(@ExpandedFrom(CallInfo {call_site: cs, _})) => cs,
|
||||
None => self.bug("missing top span")
|
||||
}
|
||||
}
|
||||
fn print_backtrace(&self) { }
|
||||
fn backtrace(&self) -> Option<@ExpnInfo> { *self.backtrace }
|
||||
fn mod_push(&self, i: ast::ident) { self.mod_path.push(i); }
|
||||
fn mod_pop(&self) { self.mod_path.pop(); }
|
||||
fn mod_path(&self) -> ~[ast::ident] { copy *self.mod_path }
|
||||
fn bt_push(&self, ei: codemap::ExpnInfo) {
|
||||
match ei {
|
||||
ExpandedFrom(CallInfo {call_site: cs, callee: ref callee}) => {
|
||||
*self.backtrace =
|
||||
Some(@ExpandedFrom(CallInfo {
|
||||
call_site: span {lo: cs.lo, hi: cs.hi,
|
||||
expn_info: *self.backtrace},
|
||||
callee: copy *callee}));
|
||||
}
|
||||
}
|
||||
}
|
||||
fn bt_pop(&self) {
|
||||
match *self.backtrace {
|
||||
Some(@ExpandedFrom(CallInfo {
|
||||
call_site: span {expn_info: prev, _}, _
|
||||
})) => {
|
||||
*self.backtrace = prev
|
||||
}
|
||||
_ => self.bug("tried to pop without a push")
|
||||
}
|
||||
}
|
||||
fn span_fatal(&self, sp: span, msg: &str) -> ! {
|
||||
self.print_backtrace();
|
||||
self.parse_sess.span_diagnostic.span_fatal(sp, msg);
|
||||
}
|
||||
fn span_err(&self, sp: span, msg: &str) {
|
||||
self.print_backtrace();
|
||||
self.parse_sess.span_diagnostic.span_err(sp, msg);
|
||||
}
|
||||
fn span_warn(&self, sp: span, msg: &str) {
|
||||
self.print_backtrace();
|
||||
self.parse_sess.span_diagnostic.span_warn(sp, msg);
|
||||
}
|
||||
fn span_unimpl(&self, sp: span, msg: &str) -> ! {
|
||||
self.print_backtrace();
|
||||
self.parse_sess.span_diagnostic.span_unimpl(sp, msg);
|
||||
}
|
||||
fn span_bug(&self, sp: span, msg: &str) -> ! {
|
||||
self.print_backtrace();
|
||||
self.parse_sess.span_diagnostic.span_bug(sp, msg);
|
||||
}
|
||||
fn bug(&self, msg: &str) -> ! {
|
||||
self.print_backtrace();
|
||||
self.parse_sess.span_diagnostic.handler().bug(msg);
|
||||
}
|
||||
fn next_id(&self) -> ast::node_id {
|
||||
return parse::next_node_id(self.parse_sess);
|
||||
}
|
||||
fn trace_macros(&self) -> bool {
|
||||
*self.trace_mac
|
||||
}
|
||||
fn set_trace_macros(&self, x: bool) {
|
||||
*self.trace_mac = x
|
||||
}
|
||||
fn str_of(&self, id: ast::ident) -> ~str {
|
||||
copy *self.parse_sess.interner.get(id)
|
||||
}
|
||||
fn ident_of(&self, st: &str) -> ast::ident {
|
||||
self.parse_sess.interner.intern(st)
|
||||
}
|
||||
}
|
||||
let imp: @CtxtRepr = @CtxtRepr {
|
||||
parse_sess: parse_sess,
|
||||
cfg: cfg,
|
||||
backtrace: @mut None,
|
||||
mod_path: @mut ~[],
|
||||
trace_mac: @mut false
|
||||
};
|
||||
((imp) as @ext_ctxt)
|
||||
fn bt_pop(&self) {
|
||||
match *self.backtrace {
|
||||
Some(@ExpandedFrom(
|
||||
CallInfo {
|
||||
call_site: span {expn_info: prev, _}, _
|
||||
})) => {
|
||||
*self.backtrace = prev
|
||||
}
|
||||
_ => self.bug("tried to pop without a push")
|
||||
}
|
||||
}
|
||||
fn span_fatal(&self, sp: span, msg: &str) -> ! {
|
||||
self.print_backtrace();
|
||||
self.parse_sess.span_diagnostic.span_fatal(sp, msg);
|
||||
}
|
||||
fn span_err(&self, sp: span, msg: &str) {
|
||||
self.print_backtrace();
|
||||
self.parse_sess.span_diagnostic.span_err(sp, msg);
|
||||
}
|
||||
fn span_warn(&self, sp: span, msg: &str) {
|
||||
self.print_backtrace();
|
||||
self.parse_sess.span_diagnostic.span_warn(sp, msg);
|
||||
}
|
||||
fn span_unimpl(&self, sp: span, msg: &str) -> ! {
|
||||
self.print_backtrace();
|
||||
self.parse_sess.span_diagnostic.span_unimpl(sp, msg);
|
||||
}
|
||||
fn span_bug(&self, sp: span, msg: &str) -> ! {
|
||||
self.print_backtrace();
|
||||
self.parse_sess.span_diagnostic.span_bug(sp, msg);
|
||||
}
|
||||
fn bug(&self, msg: &str) -> ! {
|
||||
self.print_backtrace();
|
||||
self.parse_sess.span_diagnostic.handler().bug(msg);
|
||||
}
|
||||
fn next_id(&self) -> ast::node_id {
|
||||
parse::next_node_id(self.parse_sess)
|
||||
}
|
||||
fn trace_macros(&self) -> bool {
|
||||
*self.trace_mac
|
||||
}
|
||||
fn set_trace_macros(&self, x: bool) {
|
||||
*self.trace_mac = x
|
||||
}
|
||||
fn str_of(&self, id: ast::ident) -> ~str {
|
||||
copy *self.parse_sess.interner.get(id)
|
||||
}
|
||||
fn ident_of(&self, st: &str) -> ast::ident {
|
||||
self.parse_sess.interner.intern(st)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn expr_to_str(cx: @ext_ctxt, expr: @ast::expr, err_msg: ~str) -> ~str {
|
||||
pub fn expr_to_str(cx: @ExtCtxt, expr: @ast::expr, err_msg: ~str) -> ~str {
|
||||
match expr.node {
|
||||
ast::expr_lit(l) => match l.node {
|
||||
ast::lit_str(s) => copy *s,
|
||||
|
|
@ -339,7 +314,7 @@ pub fn expr_to_str(cx: @ext_ctxt, expr: @ast::expr, err_msg: ~str) -> ~str {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn expr_to_ident(cx: @ext_ctxt,
|
||||
pub fn expr_to_ident(cx: @ExtCtxt,
|
||||
expr: @ast::expr,
|
||||
err_msg: &str) -> ast::ident {
|
||||
match expr.node {
|
||||
|
|
@ -353,14 +328,14 @@ pub fn expr_to_ident(cx: @ext_ctxt,
|
|||
}
|
||||
}
|
||||
|
||||
pub fn check_zero_tts(cx: @ext_ctxt, sp: span, tts: &[ast::token_tree],
|
||||
pub fn check_zero_tts(cx: @ExtCtxt, sp: span, tts: &[ast::token_tree],
|
||||
name: &str) {
|
||||
if tts.len() != 0 {
|
||||
cx.span_fatal(sp, fmt!("%s takes no arguments", name));
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_single_str_from_tts(cx: @ext_ctxt,
|
||||
pub fn get_single_str_from_tts(cx: @ExtCtxt,
|
||||
sp: span,
|
||||
tts: &[ast::token_tree],
|
||||
name: &str) -> ~str {
|
||||
|
|
@ -375,7 +350,7 @@ pub fn get_single_str_from_tts(cx: @ext_ctxt,
|
|||
}
|
||||
}
|
||||
|
||||
pub fn get_exprs_from_tts(cx: @ext_ctxt, tts: &[ast::token_tree])
|
||||
pub fn get_exprs_from_tts(cx: @ExtCtxt, tts: &[ast::token_tree])
|
||||
-> ~[@ast::expr] {
|
||||
let p = parse::new_parser_from_tts(cx.parse_sess(),
|
||||
cx.cfg(),
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -14,9 +14,9 @@ use ast;
|
|||
use codemap::span;
|
||||
use ext::base::*;
|
||||
use ext::base;
|
||||
use ext::build::{mk_u8, mk_slice_vec_e};
|
||||
use ext::build::AstBuilder;
|
||||
|
||||
pub fn expand_syntax_ext(cx: @ext_ctxt, sp: span, tts: &[ast::token_tree]) -> base::MacResult {
|
||||
pub fn expand_syntax_ext(cx: @ExtCtxt, sp: span, tts: &[ast::token_tree]) -> base::MacResult {
|
||||
// Gather all argument expressions
|
||||
let exprs = get_exprs_from_tts(cx, tts);
|
||||
let mut bytes = ~[];
|
||||
|
|
@ -28,7 +28,7 @@ pub fn expand_syntax_ext(cx: @ext_ctxt, sp: span, tts: &[ast::token_tree]) -> ba
|
|||
// string literal, push each byte to vector expression
|
||||
ast::lit_str(s) => {
|
||||
for s.each |byte| {
|
||||
bytes.push(mk_u8(cx, sp, byte));
|
||||
bytes.push(cx.expr_u8(sp, byte));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -37,7 +37,7 @@ pub fn expand_syntax_ext(cx: @ext_ctxt, sp: span, tts: &[ast::token_tree]) -> ba
|
|||
if v > 0xFF {
|
||||
cx.span_err(sp, "Too large u8 literal in bytes!")
|
||||
} else {
|
||||
bytes.push(mk_u8(cx, sp, v as u8));
|
||||
bytes.push(cx.expr_u8(sp, v as u8));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -48,14 +48,14 @@ pub fn expand_syntax_ext(cx: @ext_ctxt, sp: span, tts: &[ast::token_tree]) -> ba
|
|||
} else if v < 0 {
|
||||
cx.span_err(sp, "Negative integer literal in bytes!")
|
||||
} else {
|
||||
bytes.push(mk_u8(cx, sp, v as u8));
|
||||
bytes.push(cx.expr_u8(sp, v as u8));
|
||||
}
|
||||
}
|
||||
|
||||
// char literal, push to vector expression
|
||||
ast::lit_int(v, ast::ty_char) => {
|
||||
if (v as char).is_ascii() {
|
||||
bytes.push(mk_u8(cx, sp, v as u8));
|
||||
bytes.push(cx.expr_u8(sp, v as u8));
|
||||
} else {
|
||||
cx.span_err(sp, "Non-ascii char literal in bytes!")
|
||||
}
|
||||
|
|
@ -68,6 +68,6 @@ pub fn expand_syntax_ext(cx: @ext_ctxt, sp: span, tts: &[ast::token_tree]) -> ba
|
|||
}
|
||||
}
|
||||
|
||||
let e = mk_slice_vec_e(cx, sp, bytes);
|
||||
let e = cx.expr_vec_slice(sp, bytes);
|
||||
MRExpr(e)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ use ext::base::*;
|
|||
use ext::base;
|
||||
use parse::token;
|
||||
|
||||
pub fn expand_syntax_ext(cx: @ext_ctxt, sp: span, tts: &[ast::token_tree])
|
||||
pub fn expand_syntax_ext(cx: @ExtCtxt, sp: span, tts: &[ast::token_tree])
|
||||
-> base::MacResult {
|
||||
let mut res_str = ~"";
|
||||
for tts.eachi |i, e| {
|
||||
|
|
|
|||
|
|
@ -10,23 +10,23 @@
|
|||
|
||||
use ast::{meta_item, item, expr};
|
||||
use codemap::span;
|
||||
use ext::base::ext_ctxt;
|
||||
use ext::build;
|
||||
use ext::base::ExtCtxt;
|
||||
use ext::build::AstBuilder;
|
||||
use ext::deriving::generic::*;
|
||||
|
||||
|
||||
pub fn expand_deriving_clone(cx: @ext_ctxt,
|
||||
pub fn expand_deriving_clone(cx: @ExtCtxt,
|
||||
span: span,
|
||||
mitem: @meta_item,
|
||||
in_items: ~[@item])
|
||||
-> ~[@item] {
|
||||
let trait_def = TraitDef {
|
||||
path: Path::new(~[~"core", ~"clone", ~"Clone"]),
|
||||
path: Path::new(~["core", "clone", "Clone"]),
|
||||
additional_bounds: ~[],
|
||||
generics: LifetimeBounds::empty(),
|
||||
methods: ~[
|
||||
MethodDef {
|
||||
name: ~"clone",
|
||||
name: "clone",
|
||||
generics: LifetimeBounds::empty(),
|
||||
explicit_self: borrowed_explicit_self(),
|
||||
args: ~[],
|
||||
|
|
@ -42,18 +42,18 @@ pub fn expand_deriving_clone(cx: @ext_ctxt,
|
|||
&trait_def)
|
||||
}
|
||||
|
||||
pub fn expand_deriving_deep_clone(cx: @ext_ctxt,
|
||||
pub fn expand_deriving_deep_clone(cx: @ExtCtxt,
|
||||
span: span,
|
||||
mitem: @meta_item,
|
||||
in_items: ~[@item])
|
||||
-> ~[@item] {
|
||||
let trait_def = TraitDef {
|
||||
path: Path::new(~[~"core", ~"clone", ~"DeepClone"]),
|
||||
path: Path::new(~["core", "clone", "DeepClone"]),
|
||||
additional_bounds: ~[],
|
||||
generics: LifetimeBounds::empty(),
|
||||
methods: ~[
|
||||
MethodDef {
|
||||
name: ~"deep_clone",
|
||||
name: "deep_clone",
|
||||
generics: LifetimeBounds::empty(),
|
||||
explicit_self: borrowed_explicit_self(),
|
||||
args: ~[],
|
||||
|
|
@ -73,21 +73,21 @@ pub fn expand_deriving_deep_clone(cx: @ext_ctxt,
|
|||
|
||||
fn cs_clone(
|
||||
name: &str,
|
||||
cx: @ext_ctxt, span: span,
|
||||
cx: @ExtCtxt, span: span,
|
||||
substr: &Substructure) -> @expr {
|
||||
let clone_ident = substr.method_ident;
|
||||
let ctor_ident;
|
||||
let all_fields;
|
||||
let subcall = |field|
|
||||
build::mk_method_call(cx, span, field, clone_ident, ~[]);
|
||||
cx.expr_method_call(span, field, clone_ident, ~[]);
|
||||
|
||||
match *substr.fields {
|
||||
Struct(ref af) => {
|
||||
ctor_ident = ~[ substr.type_ident ];
|
||||
ctor_ident = substr.type_ident;
|
||||
all_fields = af;
|
||||
}
|
||||
EnumMatching(_, variant, ref af) => {
|
||||
ctor_ident = ~[ variant.node.name ];
|
||||
ctor_ident = variant.node.name;
|
||||
all_fields = af;
|
||||
},
|
||||
EnumNonMatching(*) => cx.span_bug(span,
|
||||
|
|
@ -102,7 +102,7 @@ fn cs_clone(
|
|||
[(None, _, _), .. _] => {
|
||||
// enum-like
|
||||
let subcalls = all_fields.map(|&(_, self_f, _)| subcall(self_f));
|
||||
build::mk_call(cx, span, ctor_ident, subcalls)
|
||||
cx.expr_call_ident(span, ctor_ident, subcalls)
|
||||
},
|
||||
_ => {
|
||||
// struct-like
|
||||
|
|
@ -113,16 +113,14 @@ fn cs_clone(
|
|||
fmt!("unnamed field in normal struct in `deriving(%s)`",
|
||||
name))
|
||||
};
|
||||
build::Field { ident: ident, ex: subcall(self_f) }
|
||||
cx.field_imm(span, ident, subcall(self_f))
|
||||
};
|
||||
|
||||
if fields.is_empty() {
|
||||
// no fields, so construct like `None`
|
||||
build::mk_path(cx, span, ctor_ident)
|
||||
cx.expr_ident(span, ctor_ident)
|
||||
} else {
|
||||
build::mk_struct_e(cx, span,
|
||||
ctor_ident,
|
||||
fields)
|
||||
cx.expr_struct_ident(span, ctor_ident, fields)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,22 +10,22 @@
|
|||
|
||||
use ast::{meta_item, item, expr};
|
||||
use codemap::span;
|
||||
use ext::base::ext_ctxt;
|
||||
use ext::build;
|
||||
use ext::base::ExtCtxt;
|
||||
use ext::build::AstBuilder;
|
||||
use ext::deriving::generic::*;
|
||||
|
||||
pub fn expand_deriving_eq(cx: @ext_ctxt,
|
||||
pub fn expand_deriving_eq(cx: @ExtCtxt,
|
||||
span: span,
|
||||
mitem: @meta_item,
|
||||
in_items: ~[@item]) -> ~[@item] {
|
||||
// structures are equal if all fields are equal, and non equal, if
|
||||
// any fields are not equal or if the enum variants are different
|
||||
fn cs_eq(cx: @ext_ctxt, span: span, substr: &Substructure) -> @expr {
|
||||
cs_and(|cx, span, _, _| build::mk_bool(cx, span, false),
|
||||
fn cs_eq(cx: @ExtCtxt, span: span, substr: &Substructure) -> @expr {
|
||||
cs_and(|cx, span, _, _| cx.expr_bool(span, false),
|
||||
cx, span, substr)
|
||||
}
|
||||
fn cs_ne(cx: @ext_ctxt, span: span, substr: &Substructure) -> @expr {
|
||||
cs_or(|cx, span, _, _| build::mk_bool(cx, span, true),
|
||||
fn cs_ne(cx: @ExtCtxt, span: span, substr: &Substructure) -> @expr {
|
||||
cs_or(|cx, span, _, _| cx.expr_bool(span, true),
|
||||
cx, span, substr)
|
||||
}
|
||||
|
||||
|
|
@ -36,7 +36,7 @@ pub fn expand_deriving_eq(cx: @ext_ctxt,
|
|||
generics: LifetimeBounds::empty(),
|
||||
explicit_self: borrowed_explicit_self(),
|
||||
args: ~[borrowed_self()],
|
||||
ret_ty: Literal(Path::new(~[~"bool"])),
|
||||
ret_ty: Literal(Path::new(~["bool"])),
|
||||
const_nonmatching: true,
|
||||
combine_substructure: $f
|
||||
},
|
||||
|
|
@ -44,12 +44,12 @@ pub fn expand_deriving_eq(cx: @ext_ctxt,
|
|||
);
|
||||
|
||||
let trait_def = TraitDef {
|
||||
path: Path::new(~[~"core", ~"cmp", ~"Eq"]),
|
||||
path: Path::new(~["core", "cmp", "Eq"]),
|
||||
additional_bounds: ~[],
|
||||
generics: LifetimeBounds::empty(),
|
||||
methods: ~[
|
||||
md!(~"eq", cs_eq),
|
||||
md!(~"ne", cs_ne)
|
||||
md!("eq", cs_eq),
|
||||
md!("ne", cs_ne)
|
||||
]
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -9,13 +9,13 @@
|
|||
// except according to those terms.
|
||||
|
||||
|
||||
use ast::{meta_item, item, expr_if, expr};
|
||||
use ast::{meta_item, item, expr};
|
||||
use codemap::span;
|
||||
use ext::base::ext_ctxt;
|
||||
use ext::build;
|
||||
use ext::base::ExtCtxt;
|
||||
use ext::build::AstBuilder;
|
||||
use ext::deriving::generic::*;
|
||||
|
||||
pub fn expand_deriving_ord(cx: @ext_ctxt,
|
||||
pub fn expand_deriving_ord(cx: @ExtCtxt,
|
||||
span: span,
|
||||
mitem: @meta_item,
|
||||
in_items: ~[@item]) -> ~[@item] {
|
||||
|
|
@ -26,7 +26,7 @@ pub fn expand_deriving_ord(cx: @ext_ctxt,
|
|||
generics: LifetimeBounds::empty(),
|
||||
explicit_self: borrowed_explicit_self(),
|
||||
args: ~[borrowed_self()],
|
||||
ret_ty: Literal(Path::new(~[~"bool"])),
|
||||
ret_ty: Literal(Path::new(~["bool"])),
|
||||
const_nonmatching: false,
|
||||
combine_substructure: |cx, span, substr|
|
||||
cs_ord($less, $equal, cx, span, substr)
|
||||
|
|
@ -37,15 +37,15 @@ pub fn expand_deriving_ord(cx: @ext_ctxt,
|
|||
|
||||
|
||||
let trait_def = TraitDef {
|
||||
path: Path::new(~[~"core", ~"cmp", ~"Ord"]),
|
||||
path: Path::new(~["core", "cmp", "Ord"]),
|
||||
// XXX: Ord doesn't imply Eq yet
|
||||
additional_bounds: ~[Literal(Path::new(~[~"core", ~"cmp", ~"Eq"]))],
|
||||
additional_bounds: ~[Literal(Path::new(~["core", "cmp", "Eq"]))],
|
||||
generics: LifetimeBounds::empty(),
|
||||
methods: ~[
|
||||
md!(~"lt", true, false),
|
||||
md!(~"le", true, true),
|
||||
md!(~"gt", false, false),
|
||||
md!(~"ge", false, true)
|
||||
md!("lt", true, false),
|
||||
md!("le", true, true),
|
||||
md!("gt", false, false),
|
||||
md!("ge", false, true)
|
||||
]
|
||||
};
|
||||
|
||||
|
|
@ -55,17 +55,14 @@ pub fn expand_deriving_ord(cx: @ext_ctxt,
|
|||
|
||||
/// `less`: is this `lt` or `le`? `equal`: is this `le` or `ge`?
|
||||
fn cs_ord(less: bool, equal: bool,
|
||||
cx: @ext_ctxt, span: span,
|
||||
cx: @ExtCtxt, span: span,
|
||||
substr: &Substructure) -> @expr {
|
||||
let binop = if less {
|
||||
cx.ident_of("lt")
|
||||
} else {
|
||||
cx.ident_of("gt")
|
||||
};
|
||||
let false_blk_expr = build::mk_block(cx, span,
|
||||
~[], ~[],
|
||||
Some(build::mk_bool(cx, span, false)));
|
||||
let base = build::mk_bool(cx, span, equal);
|
||||
let base = cx.expr_bool(span, equal);
|
||||
|
||||
cs_fold(
|
||||
false, // need foldr,
|
||||
|
|
@ -98,19 +95,15 @@ fn cs_ord(less: bool, equal: bool,
|
|||
cx.span_bug(span, "Not exactly 2 arguments in `deriving(Ord)`");
|
||||
}
|
||||
|
||||
let cmp = build::mk_method_call(cx, span,
|
||||
self_f, cx.ident_of("eq"), other_fs.to_owned());
|
||||
let subexpr = build::mk_simple_block(cx, span, subexpr);
|
||||
let elseif = expr_if(cmp, subexpr, Some(false_blk_expr));
|
||||
let elseif = build::mk_expr(cx, span, elseif);
|
||||
let cmp = cx.expr_method_call(span,
|
||||
self_f, cx.ident_of("eq"), other_fs.to_owned());
|
||||
let elseif = cx.expr_if(span, cmp,
|
||||
subexpr, Some(cx.expr_bool(span, false)));
|
||||
|
||||
let cmp = build::mk_method_call(cx, span,
|
||||
self_f, binop, other_fs.to_owned());
|
||||
let true_blk = build::mk_simple_block(cx, span,
|
||||
build::mk_bool(cx, span, true));
|
||||
let if_ = expr_if(cmp, true_blk, Some(elseif));
|
||||
|
||||
build::mk_expr(cx, span, if_)
|
||||
let cmp = cx.expr_method_call(span,
|
||||
self_f, binop, other_fs.to_owned());
|
||||
cx.expr_if(span, cmp,
|
||||
cx.expr_bool(span, true), Some(elseif))
|
||||
},
|
||||
base,
|
||||
|cx, span, args, _| {
|
||||
|
|
@ -119,7 +112,7 @@ fn cs_ord(less: bool, equal: bool,
|
|||
match args {
|
||||
[(self_var, _, _),
|
||||
(other_var, _, _)] =>
|
||||
build::mk_bool(cx, span,
|
||||
cx.expr_bool(span,
|
||||
if less {
|
||||
self_var < other_var
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -11,31 +11,31 @@
|
|||
|
||||
use ast::{meta_item, item, expr};
|
||||
use codemap::span;
|
||||
use ext::base::ext_ctxt;
|
||||
use ext::build;
|
||||
use ext::base::ExtCtxt;
|
||||
use ext::build::AstBuilder;
|
||||
use ext::deriving::generic::*;
|
||||
|
||||
pub fn expand_deriving_totaleq(cx: @ext_ctxt,
|
||||
pub fn expand_deriving_totaleq(cx: @ExtCtxt,
|
||||
span: span,
|
||||
mitem: @meta_item,
|
||||
in_items: ~[@item]) -> ~[@item] {
|
||||
|
||||
fn cs_equals(cx: @ext_ctxt, span: span, substr: &Substructure) -> @expr {
|
||||
cs_and(|cx, span, _, _| build::mk_bool(cx, span, false),
|
||||
fn cs_equals(cx: @ExtCtxt, span: span, substr: &Substructure) -> @expr {
|
||||
cs_and(|cx, span, _, _| cx.expr_bool(span, false),
|
||||
cx, span, substr)
|
||||
}
|
||||
|
||||
let trait_def = TraitDef {
|
||||
path: Path::new(~[~"core", ~"cmp", ~"TotalEq"]),
|
||||
path: Path::new(~["core", "cmp", "TotalEq"]),
|
||||
additional_bounds: ~[],
|
||||
generics: LifetimeBounds::empty(),
|
||||
methods: ~[
|
||||
MethodDef {
|
||||
name: ~"equals",
|
||||
name: "equals",
|
||||
generics: LifetimeBounds::empty(),
|
||||
explicit_self: borrowed_explicit_self(),
|
||||
args: ~[borrowed_self()],
|
||||
ret_ty: Literal(Path::new(~[~"bool"])),
|
||||
ret_ty: Literal(Path::new(~["bool"])),
|
||||
const_nonmatching: true,
|
||||
combine_substructure: cs_equals
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,26 +10,26 @@
|
|||
|
||||
use ast::{meta_item, item, expr};
|
||||
use codemap::span;
|
||||
use ext::base::ext_ctxt;
|
||||
use ext::build;
|
||||
use ext::base::ExtCtxt;
|
||||
use ext::build::AstBuilder;
|
||||
use ext::deriving::generic::*;
|
||||
use core::cmp::{Ordering, Equal, Less, Greater};
|
||||
|
||||
pub fn expand_deriving_totalord(cx: @ext_ctxt,
|
||||
pub fn expand_deriving_totalord(cx: @ExtCtxt,
|
||||
span: span,
|
||||
mitem: @meta_item,
|
||||
in_items: ~[@item]) -> ~[@item] {
|
||||
let trait_def = TraitDef {
|
||||
path: Path::new(~[~"core", ~"cmp", ~"TotalOrd"]),
|
||||
path: Path::new(~["core", "cmp", "TotalOrd"]),
|
||||
additional_bounds: ~[],
|
||||
generics: LifetimeBounds::empty(),
|
||||
methods: ~[
|
||||
MethodDef {
|
||||
name: ~"cmp",
|
||||
name: "cmp",
|
||||
generics: LifetimeBounds::empty(),
|
||||
explicit_self: borrowed_explicit_self(),
|
||||
args: ~[borrowed_self()],
|
||||
ret_ty: Literal(Path::new(~[~"core", ~"cmp", ~"Ordering"])),
|
||||
ret_ty: Literal(Path::new(~["core", "cmp", "Ordering"])),
|
||||
const_nonmatching: false,
|
||||
combine_substructure: cs_cmp
|
||||
}
|
||||
|
|
@ -41,30 +41,31 @@ pub fn expand_deriving_totalord(cx: @ext_ctxt,
|
|||
}
|
||||
|
||||
|
||||
pub fn ordering_const(cx: @ext_ctxt, span: span, cnst: Ordering) -> @expr {
|
||||
pub fn ordering_const(cx: @ExtCtxt, span: span, cnst: Ordering) -> @expr {
|
||||
let cnst = match cnst {
|
||||
Less => "Less",
|
||||
Equal => "Equal",
|
||||
Greater => "Greater"
|
||||
};
|
||||
build::mk_path_global(cx, span,
|
||||
~[cx.ident_of("core"),
|
||||
cx.ident_of("cmp"),
|
||||
cx.ident_of(cnst)])
|
||||
cx.expr_path(
|
||||
cx.path_global(span,
|
||||
~[cx.ident_of("core"),
|
||||
cx.ident_of("cmp"),
|
||||
cx.ident_of(cnst)]))
|
||||
}
|
||||
|
||||
pub fn cs_cmp(cx: @ext_ctxt, span: span,
|
||||
pub fn cs_cmp(cx: @ExtCtxt, span: span,
|
||||
substr: &Substructure) -> @expr {
|
||||
|
||||
cs_same_method_fold(
|
||||
// foldr (possibly) nests the matches in lexical_ordering better
|
||||
false,
|
||||
|cx, span, old, new| {
|
||||
build::mk_call_global(cx, span,
|
||||
~[cx.ident_of("core"),
|
||||
cx.ident_of("cmp"),
|
||||
cx.ident_of("lexical_ordering")],
|
||||
~[old, new])
|
||||
cx.expr_call_global(span,
|
||||
~[cx.ident_of("core"),
|
||||
cx.ident_of("cmp"),
|
||||
cx.ident_of("lexical_ordering")],
|
||||
~[old, new])
|
||||
},
|
||||
ordering_const(cx, span, Equal),
|
||||
|cx, span, list, _| {
|
||||
|
|
|
|||
|
|
@ -15,15 +15,15 @@ encodable.rs for more.
|
|||
|
||||
use ast;
|
||||
use ast::*;
|
||||
use ext::base::ext_ctxt;
|
||||
use ext::build;
|
||||
use ext::base::ExtCtxt;
|
||||
use ext::build::AstBuilder;
|
||||
use ext::deriving::*;
|
||||
use codemap::{span, spanned};
|
||||
use ast_util;
|
||||
use opt_vec;
|
||||
|
||||
pub fn expand_deriving_decodable(
|
||||
cx: @ext_ctxt,
|
||||
cx: @ExtCtxt,
|
||||
span: span,
|
||||
_mitem: @meta_item,
|
||||
in_items: ~[@item]
|
||||
|
|
@ -38,34 +38,31 @@ pub fn expand_deriving_decodable(
|
|||
}
|
||||
|
||||
fn create_derived_decodable_impl(
|
||||
cx: @ext_ctxt,
|
||||
cx: @ExtCtxt,
|
||||
span: span,
|
||||
type_ident: ident,
|
||||
generics: &Generics,
|
||||
method: @method
|
||||
) -> @item {
|
||||
let decoder_ty_param = build::mk_ty_param(
|
||||
cx,
|
||||
let decoder_ty_param = cx.typaram(
|
||||
cx.ident_of("__D"),
|
||||
@opt_vec::with(
|
||||
build::mk_trait_ty_param_bound_global(
|
||||
cx,
|
||||
span,
|
||||
~[
|
||||
cx.ident_of("std"),
|
||||
cx.ident_of("serialize"),
|
||||
cx.ident_of("Decoder"),
|
||||
]
|
||||
)
|
||||
)
|
||||
);
|
||||
cx.typarambound(
|
||||
cx.path_global(
|
||||
span,
|
||||
~[
|
||||
cx.ident_of("std"),
|
||||
cx.ident_of("serialize"),
|
||||
cx.ident_of("Decoder"),
|
||||
]))));
|
||||
|
||||
// All the type parameters need to bound to the trait.
|
||||
let generic_ty_params = opt_vec::with(decoder_ty_param);
|
||||
|
||||
let methods = [method];
|
||||
let trait_path = build::mk_raw_path_global_(
|
||||
let trait_path = cx.path_all(
|
||||
span,
|
||||
true,
|
||||
~[
|
||||
cx.ident_of("std"),
|
||||
cx.ident_of("serialize"),
|
||||
|
|
@ -73,7 +70,7 @@ fn create_derived_decodable_impl(
|
|||
],
|
||||
None,
|
||||
~[
|
||||
build::mk_simple_ty_path(cx, span, cx.ident_of("__D"))
|
||||
cx.ty_ident(span, cx.ident_of("__D"))
|
||||
]
|
||||
);
|
||||
create_derived_impl(
|
||||
|
|
@ -91,22 +88,21 @@ fn create_derived_decodable_impl(
|
|||
// Creates a method from the given set of statements conforming to the
|
||||
// signature of the `decodable` method.
|
||||
fn create_decode_method(
|
||||
cx: @ext_ctxt,
|
||||
cx: @ExtCtxt,
|
||||
span: span,
|
||||
type_ident: ast::ident,
|
||||
generics: &Generics,
|
||||
expr: @ast::expr
|
||||
) -> @method {
|
||||
// Create the `e` parameter.
|
||||
let d_arg_type = build::mk_ty_rptr(
|
||||
cx,
|
||||
let d_arg_type = cx.ty_rptr(
|
||||
span,
|
||||
build::mk_simple_ty_path(cx, span, cx.ident_of("__D")),
|
||||
cx.ty_ident(span, cx.ident_of("__D")),
|
||||
None,
|
||||
ast::m_mutbl
|
||||
);
|
||||
let d_ident = cx.ident_of("__d");
|
||||
let d_arg = build::mk_arg(cx, span, d_ident, d_arg_type);
|
||||
let d_arg = cx.arg(span, d_ident, d_arg_type);
|
||||
|
||||
// Create the type of the return value.
|
||||
let output_type = create_self_type_with_params(
|
||||
|
|
@ -118,10 +114,10 @@ fn create_decode_method(
|
|||
|
||||
// Create the function declaration.
|
||||
let inputs = ~[d_arg];
|
||||
let fn_decl = build::mk_fn_decl(inputs, output_type);
|
||||
let fn_decl = cx.fn_decl(inputs, output_type);
|
||||
|
||||
// Create the body block.
|
||||
let body_block = build::mk_simple_block(cx, span, expr);
|
||||
let body_block = cx.blk_expr(expr);
|
||||
|
||||
// Create the method.
|
||||
let explicit_self = spanned { node: sty_static, span: span };
|
||||
|
|
@ -142,31 +138,31 @@ fn create_decode_method(
|
|||
}
|
||||
|
||||
fn call_substructure_decode_method(
|
||||
cx: @ext_ctxt,
|
||||
cx: @ExtCtxt,
|
||||
span: span
|
||||
) -> @ast::expr {
|
||||
// Call the substructure method.
|
||||
build::mk_call_(
|
||||
cx,
|
||||
cx.expr_call(
|
||||
span,
|
||||
build::mk_path_global(
|
||||
cx,
|
||||
span,
|
||||
~[
|
||||
cx.ident_of("std"),
|
||||
cx.ident_of("serialize"),
|
||||
cx.ident_of("Decodable"),
|
||||
cx.ident_of("decode"),
|
||||
]
|
||||
cx.expr_path(
|
||||
cx.path_global(
|
||||
span,
|
||||
~[
|
||||
cx.ident_of("std"),
|
||||
cx.ident_of("serialize"),
|
||||
cx.ident_of("Decodable"),
|
||||
cx.ident_of("decode"),
|
||||
]
|
||||
)
|
||||
),
|
||||
~[
|
||||
build::mk_path(cx, span, ~[cx.ident_of("__d")])
|
||||
cx.expr_ident(span, cx.ident_of("__d"))
|
||||
]
|
||||
)
|
||||
}
|
||||
|
||||
fn expand_deriving_decodable_struct_def(
|
||||
cx: @ext_ctxt,
|
||||
cx: @ExtCtxt,
|
||||
span: span,
|
||||
struct_def: &struct_def,
|
||||
type_ident: ident,
|
||||
|
|
@ -192,7 +188,7 @@ fn expand_deriving_decodable_struct_def(
|
|||
}
|
||||
|
||||
fn expand_deriving_decodable_enum_def(
|
||||
cx: @ext_ctxt,
|
||||
cx: @ExtCtxt,
|
||||
span: span,
|
||||
enum_definition: &enum_def,
|
||||
type_ident: ident,
|
||||
|
|
@ -218,63 +214,54 @@ fn expand_deriving_decodable_enum_def(
|
|||
}
|
||||
|
||||
fn create_read_struct_field(
|
||||
cx: @ext_ctxt,
|
||||
cx: @ExtCtxt,
|
||||
span: span,
|
||||
idx: uint,
|
||||
ident: ident
|
||||
) -> build::Field {
|
||||
) -> ast::field {
|
||||
// Call the substructure method.
|
||||
let decode_expr = call_substructure_decode_method(cx, span);
|
||||
|
||||
let d_arg = build::mk_arg(cx,
|
||||
span,
|
||||
cx.ident_of("__d"),
|
||||
build::mk_ty_infer(cx, span));
|
||||
let d_id = cx.ident_of("__d");
|
||||
|
||||
let call_expr = build::mk_method_call(
|
||||
cx,
|
||||
let call_expr = cx.expr_method_call(
|
||||
span,
|
||||
build::mk_path(cx, span, ~[cx.ident_of("__d")]),
|
||||
cx.expr_ident(span, d_id),
|
||||
cx.ident_of("read_struct_field"),
|
||||
~[
|
||||
build::mk_base_str(cx, span, cx.str_of(ident)),
|
||||
build::mk_uint(cx, span, idx),
|
||||
build::mk_lambda(cx,
|
||||
span,
|
||||
build::mk_fn_decl(~[d_arg],
|
||||
build::mk_ty_infer(cx, span)),
|
||||
decode_expr),
|
||||
cx.expr_str(span, cx.str_of(ident)),
|
||||
cx.expr_uint(span, idx),
|
||||
cx.lambda_expr_1(span, decode_expr, d_id)
|
||||
]
|
||||
);
|
||||
|
||||
build::Field { ident: ident, ex: call_expr }
|
||||
cx.field_imm(span, ident, call_expr)
|
||||
}
|
||||
|
||||
fn create_read_struct_arg(
|
||||
cx: @ext_ctxt,
|
||||
cx: @ExtCtxt,
|
||||
span: span,
|
||||
idx: uint,
|
||||
ident: ident
|
||||
) -> build::Field {
|
||||
) -> ast::field {
|
||||
// Call the substructure method.
|
||||
let decode_expr = call_substructure_decode_method(cx, span);
|
||||
|
||||
let call_expr = build::mk_method_call(
|
||||
cx,
|
||||
let call_expr = cx.expr_method_call(
|
||||
span,
|
||||
build::mk_path(cx, span, ~[cx.ident_of("__d")]),
|
||||
cx.expr_ident(span, cx.ident_of("__d")),
|
||||
cx.ident_of("read_struct_arg"),
|
||||
~[
|
||||
build::mk_uint(cx, span, idx),
|
||||
build::mk_lambda_no_args(cx, span, decode_expr),
|
||||
cx.expr_uint(span, idx),
|
||||
cx.lambda_expr_0(span, decode_expr),
|
||||
]
|
||||
);
|
||||
|
||||
build::Field { ident: ident, ex: call_expr }
|
||||
cx.field_imm(span, ident, call_expr)
|
||||
}
|
||||
|
||||
fn expand_deriving_decodable_struct_method(
|
||||
cx: @ext_ctxt,
|
||||
cx: @ExtCtxt,
|
||||
span: span,
|
||||
struct_def: &struct_def,
|
||||
type_ident: ident,
|
||||
|
|
@ -298,34 +285,19 @@ fn expand_deriving_decodable_struct_method(
|
|||
i += 1;
|
||||
}
|
||||
|
||||
let d_arg = build::mk_arg(cx,
|
||||
span,
|
||||
cx.ident_of("__d"),
|
||||
build::mk_ty_infer(cx, span));
|
||||
let d_id = cx.ident_of("__d");
|
||||
|
||||
let read_struct_expr = build::mk_method_call(
|
||||
cx,
|
||||
let read_struct_expr = cx.expr_method_call(
|
||||
span,
|
||||
build::mk_path(
|
||||
cx,
|
||||
span,
|
||||
~[cx.ident_of("__d")]
|
||||
),
|
||||
cx.expr_ident(span, d_id),
|
||||
cx.ident_of("read_struct"),
|
||||
~[
|
||||
build::mk_base_str(cx, span, cx.str_of(type_ident)),
|
||||
build::mk_uint(cx, span, fields.len()),
|
||||
build::mk_lambda(
|
||||
cx,
|
||||
cx.expr_str(span, cx.str_of(type_ident)),
|
||||
cx.expr_uint(span, fields.len()),
|
||||
cx.lambda_expr_1(
|
||||
span,
|
||||
build::mk_fn_decl(~[d_arg], build::mk_ty_infer(cx, span)),
|
||||
build::mk_struct_e(
|
||||
cx,
|
||||
span,
|
||||
~[type_ident],
|
||||
fields
|
||||
)
|
||||
),
|
||||
cx.expr_struct_ident(span, type_ident, fields),
|
||||
d_id)
|
||||
]
|
||||
);
|
||||
|
||||
|
|
@ -334,20 +306,20 @@ fn expand_deriving_decodable_struct_method(
|
|||
}
|
||||
|
||||
fn create_read_variant_arg(
|
||||
cx: @ext_ctxt,
|
||||
cx: @ExtCtxt,
|
||||
span: span,
|
||||
idx: uint,
|
||||
variant: &ast::variant
|
||||
) -> ast::arm {
|
||||
// Create the matching pattern.
|
||||
let pat = build::mk_pat_lit(cx, span, build::mk_uint(cx, span, idx));
|
||||
let pat = cx.pat_lit(span, cx.expr_uint(span, idx));
|
||||
|
||||
// Feed each argument in this variant to the decode function
|
||||
// as well.
|
||||
let variant_arg_len = variant_arg_count(cx, span, variant);
|
||||
|
||||
let expr = if variant_arg_len == 0 {
|
||||
build::mk_path(cx, span, ~[variant.node.name])
|
||||
cx.expr_ident(span, variant.node.name)
|
||||
} else {
|
||||
// Feed the discriminant to the decode function.
|
||||
let mut args = ~[];
|
||||
|
|
@ -356,53 +328,38 @@ fn create_read_variant_arg(
|
|||
// Call the substructure method.
|
||||
let expr = call_substructure_decode_method(cx, span);
|
||||
|
||||
let d_arg = build::mk_arg(cx,
|
||||
span,
|
||||
cx.ident_of("__d"),
|
||||
build::mk_ty_infer(cx, span));
|
||||
let t_infer = build::mk_ty_infer(cx, span);
|
||||
let d_id = cx.ident_of("__d");
|
||||
|
||||
let call_expr = build::mk_method_call(
|
||||
cx,
|
||||
let call_expr = cx.expr_method_call(
|
||||
span,
|
||||
build::mk_path(cx, span, ~[cx.ident_of("__d")]),
|
||||
cx.expr_ident(span, d_id),
|
||||
cx.ident_of("read_enum_variant_arg"),
|
||||
~[
|
||||
build::mk_uint(cx, span, j),
|
||||
build::mk_lambda(cx,
|
||||
span,
|
||||
build::mk_fn_decl(~[d_arg], t_infer),
|
||||
expr),
|
||||
cx.expr_uint(span, j),
|
||||
cx.lambda_expr_1(span, expr, d_id),
|
||||
]
|
||||
);
|
||||
|
||||
args.push(call_expr);
|
||||
}
|
||||
|
||||
build::mk_call(
|
||||
cx,
|
||||
span,
|
||||
~[variant.node.name],
|
||||
args
|
||||
)
|
||||
cx.expr_call_ident(span, variant.node.name, args)
|
||||
};
|
||||
|
||||
// Create the arm.
|
||||
build::mk_arm(cx, span, ~[pat], expr)
|
||||
cx.arm(span, ~[pat], expr)
|
||||
}
|
||||
|
||||
fn create_read_enum_variant(
|
||||
cx: @ext_ctxt,
|
||||
cx: @ExtCtxt,
|
||||
span: span,
|
||||
enum_definition: &enum_def
|
||||
) -> @expr {
|
||||
// Create a vector that contains all the variant names.
|
||||
let expr_arm_names = build::mk_base_vec_e(
|
||||
cx,
|
||||
let expr_arm_names = cx.expr_vec(
|
||||
span,
|
||||
do enum_definition.variants.map |variant| {
|
||||
build::mk_base_str(
|
||||
cx,
|
||||
cx.expr_str(
|
||||
span,
|
||||
cx.str_of(variant.node.name)
|
||||
)
|
||||
|
|
@ -415,51 +372,24 @@ fn create_read_enum_variant(
|
|||
};
|
||||
|
||||
// Add the impossible case arm.
|
||||
arms.push(build::mk_unreachable_arm(cx, span));
|
||||
arms.push(cx.arm_unreachable(span));
|
||||
|
||||
// Create the read_enum_variant expression.
|
||||
build::mk_method_call(
|
||||
cx,
|
||||
cx.expr_method_call(
|
||||
span,
|
||||
build::mk_path(cx, span, ~[cx.ident_of("__d")]),
|
||||
cx.expr_ident(span, cx.ident_of("__d")),
|
||||
cx.ident_of("read_enum_variant"),
|
||||
~[
|
||||
expr_arm_names,
|
||||
build::mk_lambda(
|
||||
cx,
|
||||
span,
|
||||
build::mk_fn_decl(
|
||||
~[
|
||||
build::mk_arg(
|
||||
cx,
|
||||
span,
|
||||
cx.ident_of("__d"),
|
||||
build::mk_ty_infer(cx, span)
|
||||
),
|
||||
build::mk_arg(
|
||||
cx,
|
||||
span,
|
||||
cx.ident_of("__i"),
|
||||
build::mk_ty_infer(cx, span)
|
||||
)
|
||||
],
|
||||
build::mk_ty_infer(cx, span)
|
||||
),
|
||||
build::mk_expr(
|
||||
cx,
|
||||
span,
|
||||
ast::expr_match(
|
||||
build::mk_path(cx, span, ~[cx.ident_of("__i")]),
|
||||
arms
|
||||
)
|
||||
)
|
||||
)
|
||||
cx.lambda_expr(span,
|
||||
~[cx.ident_of("__d"), cx.ident_of("__i")],
|
||||
cx.expr_match(span, cx.expr_ident(span, cx.ident_of("__i")), arms))
|
||||
]
|
||||
)
|
||||
}
|
||||
|
||||
fn expand_deriving_decodable_enum_method(
|
||||
cx: @ext_ctxt,
|
||||
cx: @ExtCtxt,
|
||||
span: span,
|
||||
enum_definition: &enum_def,
|
||||
type_ident: ast::ident,
|
||||
|
|
@ -471,24 +401,16 @@ fn expand_deriving_decodable_enum_method(
|
|||
enum_definition
|
||||
);
|
||||
|
||||
let d_arg = build::mk_arg(cx,
|
||||
span,
|
||||
cx.ident_of("__d"),
|
||||
build::mk_ty_infer(cx, span));
|
||||
let d_id = cx.ident_of("__d");
|
||||
|
||||
// Create the read_enum expression
|
||||
let read_enum_expr = build::mk_method_call(
|
||||
cx,
|
||||
let read_enum_expr = cx.expr_method_call(
|
||||
span,
|
||||
build::mk_path(cx, span, ~[cx.ident_of("__d")]),
|
||||
cx.expr_ident(span, d_id),
|
||||
cx.ident_of("read_enum"),
|
||||
~[
|
||||
build::mk_base_str(cx, span, cx.str_of(type_ident)),
|
||||
build::mk_lambda(cx,
|
||||
span,
|
||||
build::mk_fn_decl(~[d_arg],
|
||||
build::mk_ty_infer(cx, span)),
|
||||
read_enum_variant_expr),
|
||||
cx.expr_str(span, cx.str_of(type_ident)),
|
||||
cx.lambda_expr_1(span, read_enum_variant_expr, d_id)
|
||||
]
|
||||
);
|
||||
|
||||
|
|
|
|||
|
|
@ -78,15 +78,15 @@ would yield functions like:
|
|||
|
||||
use ast;
|
||||
use ast::*;
|
||||
use ext::base::ext_ctxt;
|
||||
use ext::build;
|
||||
use ext::base::ExtCtxt;
|
||||
use ext::build::AstBuilder;
|
||||
use ext::deriving::*;
|
||||
use codemap::{span, spanned};
|
||||
use ast_util;
|
||||
use opt_vec;
|
||||
|
||||
pub fn expand_deriving_encodable(
|
||||
cx: @ext_ctxt,
|
||||
cx: @ExtCtxt,
|
||||
span: span,
|
||||
_mitem: @meta_item,
|
||||
in_items: ~[@item]
|
||||
|
|
@ -101,34 +101,31 @@ pub fn expand_deriving_encodable(
|
|||
}
|
||||
|
||||
fn create_derived_encodable_impl(
|
||||
cx: @ext_ctxt,
|
||||
cx: @ExtCtxt,
|
||||
span: span,
|
||||
type_ident: ident,
|
||||
generics: &Generics,
|
||||
method: @method
|
||||
) -> @item {
|
||||
let encoder_ty_param = build::mk_ty_param(
|
||||
cx,
|
||||
let encoder_ty_param = cx.typaram(
|
||||
cx.ident_of("__E"),
|
||||
@opt_vec::with(
|
||||
build::mk_trait_ty_param_bound_global(
|
||||
cx,
|
||||
span,
|
||||
~[
|
||||
cx.ident_of("std"),
|
||||
cx.ident_of("serialize"),
|
||||
cx.ident_of("Encoder"),
|
||||
]
|
||||
)
|
||||
)
|
||||
);
|
||||
cx.typarambound(
|
||||
cx.path_global(
|
||||
span,
|
||||
~[
|
||||
cx.ident_of("std"),
|
||||
cx.ident_of("serialize"),
|
||||
cx.ident_of("Encoder"),
|
||||
]))));
|
||||
|
||||
// All the type parameters need to bound to the trait.
|
||||
let generic_ty_params = opt_vec::with(encoder_ty_param);
|
||||
|
||||
let methods = [method];
|
||||
let trait_path = build::mk_raw_path_global_(
|
||||
let trait_path = cx.path_all(
|
||||
span,
|
||||
true,
|
||||
~[
|
||||
cx.ident_of("std"),
|
||||
cx.ident_of("serialize"),
|
||||
|
|
@ -136,7 +133,7 @@ fn create_derived_encodable_impl(
|
|||
],
|
||||
None,
|
||||
~[
|
||||
build::mk_simple_ty_path(cx, span, cx.ident_of("__E"))
|
||||
cx.ty_ident(span, cx.ident_of("__E"))
|
||||
]
|
||||
);
|
||||
create_derived_impl(
|
||||
|
|
@ -154,29 +151,28 @@ fn create_derived_encodable_impl(
|
|||
// Creates a method from the given set of statements conforming to the
|
||||
// signature of the `encodable` method.
|
||||
fn create_encode_method(
|
||||
cx: @ext_ctxt,
|
||||
cx: @ExtCtxt,
|
||||
span: span,
|
||||
statements: ~[@stmt]
|
||||
) -> @method {
|
||||
// Create the `e` parameter.
|
||||
let e_arg_type = build::mk_ty_rptr(
|
||||
cx,
|
||||
let e_arg_type = cx.ty_rptr(
|
||||
span,
|
||||
build::mk_simple_ty_path(cx, span, cx.ident_of("__E")),
|
||||
cx.ty_ident(span, cx.ident_of("__E")),
|
||||
None,
|
||||
ast::m_mutbl
|
||||
);
|
||||
let e_arg = build::mk_arg(cx, span, cx.ident_of("__e"), e_arg_type);
|
||||
let e_arg = cx.arg(span, cx.ident_of("__e"), e_arg_type);
|
||||
|
||||
// Create the type of the return value.
|
||||
let output_type = @ast::Ty { id: cx.next_id(), node: ty_nil, span: span };
|
||||
let output_type = cx.ty_nil();
|
||||
|
||||
// Create the function declaration.
|
||||
let inputs = ~[e_arg];
|
||||
let fn_decl = build::mk_fn_decl(inputs, output_type);
|
||||
let fn_decl = cx.fn_decl(inputs, output_type);
|
||||
|
||||
// Create the body block.
|
||||
let body_block = build::mk_block_(cx, span, statements);
|
||||
let body_block = cx.blk(span, statements, None);
|
||||
|
||||
// Create the method.
|
||||
let explicit_self = spanned { node: sty_region(None, m_imm), span: span };
|
||||
|
|
@ -197,18 +193,17 @@ fn create_encode_method(
|
|||
}
|
||||
|
||||
fn call_substructure_encode_method(
|
||||
cx: @ext_ctxt,
|
||||
cx: @ExtCtxt,
|
||||
span: span,
|
||||
self_field: @expr
|
||||
) -> @ast::expr {
|
||||
// Gather up the parameters we want to chain along.
|
||||
let e_ident = cx.ident_of("__e");
|
||||
let e_expr = build::mk_path(cx, span, ~[e_ident]);
|
||||
let e_expr = cx.expr_ident(span, e_ident);
|
||||
|
||||
// Call the substructure method.
|
||||
let encode_ident = cx.ident_of("encode");
|
||||
build::mk_method_call(
|
||||
cx,
|
||||
cx.expr_method_call(
|
||||
span,
|
||||
self_field,
|
||||
encode_ident,
|
||||
|
|
@ -217,7 +212,7 @@ fn call_substructure_encode_method(
|
|||
}
|
||||
|
||||
fn expand_deriving_encodable_struct_def(
|
||||
cx: @ext_ctxt,
|
||||
cx: @ExtCtxt,
|
||||
span: span,
|
||||
struct_def: &struct_def,
|
||||
type_ident: ident,
|
||||
|
|
@ -242,7 +237,7 @@ fn expand_deriving_encodable_struct_def(
|
|||
}
|
||||
|
||||
fn expand_deriving_encodable_enum_def(
|
||||
cx: @ext_ctxt,
|
||||
cx: @ExtCtxt,
|
||||
span: span,
|
||||
enum_definition: &enum_def,
|
||||
type_ident: ident,
|
||||
|
|
@ -267,7 +262,7 @@ fn expand_deriving_encodable_enum_def(
|
|||
}
|
||||
|
||||
fn expand_deriving_encodable_struct_method(
|
||||
cx: @ext_ctxt,
|
||||
cx: @ExtCtxt,
|
||||
span: span,
|
||||
type_ident: ident,
|
||||
struct_def: &struct_def
|
||||
|
|
@ -279,10 +274,9 @@ fn expand_deriving_encodable_struct_method(
|
|||
match struct_field.node.kind {
|
||||
named_field(ident, _) => {
|
||||
// Create the accessor for this field.
|
||||
let self_field = build::mk_access_(cx,
|
||||
span,
|
||||
build::make_self(cx, span),
|
||||
ident);
|
||||
let self_field = cx.expr_field_access(span,
|
||||
cx.expr_self(span),
|
||||
ident);
|
||||
|
||||
// Call the substructure method.
|
||||
let encode_expr = call_substructure_encode_method(
|
||||
|
|
@ -292,31 +286,19 @@ fn expand_deriving_encodable_struct_method(
|
|||
);
|
||||
|
||||
let e_ident = cx.ident_of("__e");
|
||||
let e_arg = build::mk_arg(cx,
|
||||
span,
|
||||
e_ident,
|
||||
build::mk_ty_infer(cx, span));
|
||||
|
||||
let blk_expr = build::mk_lambda(
|
||||
cx,
|
||||
let call_expr = cx.expr_method_call(
|
||||
span,
|
||||
build::mk_fn_decl(~[e_arg], build::mk_ty_infer(cx, span)),
|
||||
encode_expr
|
||||
);
|
||||
|
||||
let call_expr = build::mk_method_call(
|
||||
cx,
|
||||
span,
|
||||
build::mk_path(cx, span, ~[cx.ident_of("__e")]),
|
||||
cx.expr_ident(span, e_ident),
|
||||
cx.ident_of("emit_struct_field"),
|
||||
~[
|
||||
build::mk_base_str(cx, span, cx.str_of(ident)),
|
||||
build::mk_uint(cx, span, idx),
|
||||
blk_expr
|
||||
cx.expr_str(span, cx.str_of(ident)),
|
||||
cx.expr_uint(span, idx),
|
||||
cx.lambda_expr_1(span, encode_expr, e_ident)
|
||||
]
|
||||
);
|
||||
|
||||
statements.push(build::mk_stmt(cx, span, call_expr));
|
||||
statements.push(cx.stmt_expr(call_expr));
|
||||
}
|
||||
unnamed_field => {
|
||||
cx.span_unimpl(
|
||||
|
|
@ -328,40 +310,26 @@ fn expand_deriving_encodable_struct_method(
|
|||
idx += 1;
|
||||
}
|
||||
|
||||
let e_arg = build::mk_arg(cx,
|
||||
span,
|
||||
cx.ident_of("__e"),
|
||||
build::mk_ty_infer(cx, span));
|
||||
|
||||
let emit_struct_stmt = build::mk_method_call(
|
||||
cx,
|
||||
let e_id = cx.ident_of("__e");
|
||||
let emit_struct_stmt = cx.expr_method_call(
|
||||
span,
|
||||
build::mk_path(
|
||||
cx,
|
||||
span,
|
||||
~[cx.ident_of("__e")]
|
||||
),
|
||||
cx.expr_ident(span, e_id),
|
||||
cx.ident_of("emit_struct"),
|
||||
~[
|
||||
build::mk_base_str(cx, span, cx.str_of(type_ident)),
|
||||
build::mk_uint(cx, span, statements.len()),
|
||||
build::mk_lambda_stmts(
|
||||
cx,
|
||||
span,
|
||||
build::mk_fn_decl(~[e_arg], build::mk_ty_infer(cx, span)),
|
||||
statements
|
||||
),
|
||||
cx.expr_str(span, cx.str_of(type_ident)),
|
||||
cx.expr_uint(span, statements.len()),
|
||||
cx.lambda_stmts_1(span, statements, e_id),
|
||||
]
|
||||
);
|
||||
|
||||
let statements = ~[build::mk_stmt(cx, span, emit_struct_stmt)];
|
||||
let statements = ~[cx.stmt_expr(emit_struct_stmt)];
|
||||
|
||||
// Create the method itself.
|
||||
return create_encode_method(cx, span, statements);
|
||||
}
|
||||
|
||||
fn expand_deriving_encodable_enum_method(
|
||||
cx: @ext_ctxt,
|
||||
cx: @ExtCtxt,
|
||||
span: span,
|
||||
type_ident: ast::ident,
|
||||
enum_definition: &enum_def
|
||||
|
|
@ -382,91 +350,59 @@ fn expand_deriving_encodable_enum_method(
|
|||
let expr = call_substructure_encode_method(cx, span, field);
|
||||
|
||||
let e_ident = cx.ident_of("__e");
|
||||
let e_arg = build::mk_arg(cx,
|
||||
span,
|
||||
e_ident,
|
||||
build::mk_ty_infer(cx, span));
|
||||
|
||||
let blk_expr = build::mk_lambda(
|
||||
cx,
|
||||
let call_expr = cx.expr_method_call(
|
||||
span,
|
||||
build::mk_fn_decl(~[e_arg], build::mk_ty_infer(cx, span)),
|
||||
expr
|
||||
);
|
||||
|
||||
let call_expr = build::mk_method_call(
|
||||
cx,
|
||||
span,
|
||||
build::mk_path(cx, span, ~[cx.ident_of("__e")]),
|
||||
cx.expr_ident(span, e_ident),
|
||||
cx.ident_of("emit_enum_variant_arg"),
|
||||
~[
|
||||
build::mk_uint(cx, span, j),
|
||||
blk_expr,
|
||||
cx.expr_uint(span, j),
|
||||
cx.lambda_expr_1(span, expr, e_ident),
|
||||
]
|
||||
);
|
||||
|
||||
stmts.push(build::mk_stmt(cx, span, call_expr));
|
||||
stmts.push(cx.stmt_expr(call_expr));
|
||||
}
|
||||
|
||||
// Create the pattern body.
|
||||
let e_arg = build::mk_arg(cx,
|
||||
span,
|
||||
cx.ident_of("__e"),
|
||||
build::mk_ty_infer(cx, span));
|
||||
let call_expr = build::mk_method_call(
|
||||
cx,
|
||||
let e_id = cx.ident_of("__e");
|
||||
|
||||
let call_expr = cx.expr_method_call(
|
||||
span,
|
||||
build::mk_path(cx, span, ~[cx.ident_of("__e")]),
|
||||
cx.expr_ident(span, e_id),
|
||||
cx.ident_of("emit_enum_variant"),
|
||||
~[
|
||||
build::mk_base_str(cx, span, cx.str_of(variant.node.name)),
|
||||
build::mk_uint(cx, span, i),
|
||||
build::mk_uint(cx, span, variant_arg_len),
|
||||
build::mk_lambda_stmts(
|
||||
cx,
|
||||
span,
|
||||
build::mk_fn_decl(~[e_arg], build::mk_ty_infer(cx, span)),
|
||||
stmts
|
||||
)
|
||||
cx.expr_str(span, cx.str_of(variant.node.name)),
|
||||
cx.expr_uint(span, i),
|
||||
cx.expr_uint(span, variant_arg_len),
|
||||
cx.lambda_stmts_1(span, stmts, e_id)
|
||||
]
|
||||
);
|
||||
|
||||
let match_body_block = build::mk_simple_block(cx, span, call_expr);
|
||||
//let match_body_block = cx.blk_expr(call_expr);
|
||||
|
||||
// Create the arm.
|
||||
ast::arm {
|
||||
pats: ~[pat],
|
||||
guard: None,
|
||||
body: match_body_block,
|
||||
}
|
||||
cx.arm(span, ~[pat], call_expr) //match_body_block)
|
||||
};
|
||||
|
||||
let e_ident = cx.ident_of("__e");
|
||||
let e_arg = build::mk_arg(cx,
|
||||
span,
|
||||
e_ident,
|
||||
build::mk_ty_infer(cx, span));
|
||||
|
||||
// Create the method body.
|
||||
let lambda_expr = build::mk_lambda(
|
||||
cx,
|
||||
let lambda_expr = cx.lambda_expr_1(
|
||||
span,
|
||||
build::mk_fn_decl(~[e_arg], build::mk_ty_infer(cx, span)),
|
||||
expand_enum_or_struct_match(cx, span, arms)
|
||||
);
|
||||
expand_enum_or_struct_match(cx, span, arms),
|
||||
e_ident);
|
||||
|
||||
let call_expr = build::mk_method_call(
|
||||
cx,
|
||||
let call_expr = cx.expr_method_call(
|
||||
span,
|
||||
build::mk_path(cx, span, ~[cx.ident_of("__e")]),
|
||||
cx.expr_ident(span, e_ident),
|
||||
cx.ident_of("emit_enum"),
|
||||
~[
|
||||
build::mk_base_str(cx, span, cx.str_of(type_ident)),
|
||||
cx.expr_str(span, cx.str_of(type_ident)),
|
||||
lambda_expr,
|
||||
]
|
||||
);
|
||||
|
||||
let stmt = build::mk_stmt(cx, span, call_expr);
|
||||
let stmt = cx.stmt_expr(call_expr);
|
||||
|
||||
// Create the method.
|
||||
create_encode_method(cx, span, ~[stmt])
|
||||
|
|
|
|||
|
|
@ -165,8 +165,8 @@ StaticEnum(<ast::enum_def of C>, ~[(<ident of C0>, Left(1)),
|
|||
use ast;
|
||||
use ast::{enum_def, expr, ident, Generics, struct_def};
|
||||
|
||||
use ext::base::ext_ctxt;
|
||||
use ext::build;
|
||||
use ext::base::ExtCtxt;
|
||||
use ext::build::AstBuilder;
|
||||
use ext::deriving::*;
|
||||
use codemap::{span,respan};
|
||||
use opt_vec;
|
||||
|
|
@ -174,7 +174,7 @@ use opt_vec;
|
|||
pub use self::ty::*;
|
||||
mod ty;
|
||||
|
||||
pub fn expand_deriving_generic(cx: @ext_ctxt,
|
||||
pub fn expand_deriving_generic(cx: @ExtCtxt,
|
||||
span: span,
|
||||
_mitem: @ast::meta_item,
|
||||
in_items: ~[@ast::item],
|
||||
|
|
@ -195,13 +195,13 @@ pub fn expand_deriving_generic(cx: @ext_ctxt,
|
|||
|
||||
pub struct TraitDef<'self> {
|
||||
/// Path of the trait, including any type parameters
|
||||
path: Path,
|
||||
path: Path<'self>,
|
||||
/// Additional bounds required of any type parameters of the type,
|
||||
/// other than the current trait
|
||||
additional_bounds: ~[Ty],
|
||||
additional_bounds: ~[Ty<'self>],
|
||||
|
||||
/// Any extra lifetimes and/or bounds, e.g. `D: std::serialize::Decoder`
|
||||
generics: LifetimeBounds,
|
||||
generics: LifetimeBounds<'self>,
|
||||
|
||||
methods: ~[MethodDef<'self>]
|
||||
}
|
||||
|
|
@ -209,20 +209,20 @@ pub struct TraitDef<'self> {
|
|||
|
||||
pub struct MethodDef<'self> {
|
||||
/// name of the method
|
||||
name: ~str,
|
||||
name: &'self str,
|
||||
/// List of generics, e.g. `R: core::rand::Rng`
|
||||
generics: LifetimeBounds,
|
||||
generics: LifetimeBounds<'self>,
|
||||
|
||||
/// Whether there is a self argument (outer Option) i.e. whether
|
||||
/// this is a static function, and whether it is a pointer (inner
|
||||
/// Option)
|
||||
explicit_self: Option<Option<PtrTy>>,
|
||||
explicit_self: Option<Option<PtrTy<'self>>>,
|
||||
|
||||
/// Arguments other than the self argument
|
||||
args: ~[Ty],
|
||||
args: ~[Ty<'self>],
|
||||
|
||||
/// Return type
|
||||
ret_ty: Ty,
|
||||
ret_ty: Ty<'self>,
|
||||
|
||||
/// if the value of the nonmatching enums is independent of the
|
||||
/// actual enum variants, i.e. can use _ => .. match.
|
||||
|
|
@ -281,7 +281,7 @@ Combine the values of all the fields together. The last argument is
|
|||
all the fields of all the structures, see above for details.
|
||||
*/
|
||||
pub type CombineSubstructureFunc<'self> =
|
||||
&'self fn(@ext_ctxt, span, &Substructure) -> @expr;
|
||||
&'self fn(@ExtCtxt, span, &Substructure) -> @expr;
|
||||
|
||||
/**
|
||||
Deal with non-matching enum variants, the arguments are a list
|
||||
|
|
@ -289,14 +289,14 @@ representing each variant: (variant index, ast::variant instance,
|
|||
[variant fields]), and a list of the nonself args of the type
|
||||
*/
|
||||
pub type EnumNonMatchFunc<'self> =
|
||||
&'self fn(@ext_ctxt, span,
|
||||
&'self fn(@ExtCtxt, span,
|
||||
&[(uint, ast::variant,
|
||||
~[(Option<ident>, @expr)])],
|
||||
&[@expr]) -> @expr;
|
||||
|
||||
|
||||
impl<'self> TraitDef<'self> {
|
||||
fn create_derived_impl(&self, cx: @ext_ctxt, span: span,
|
||||
fn create_derived_impl(&self, cx: @ExtCtxt, span: span,
|
||||
type_ident: ident, generics: &Generics,
|
||||
methods: ~[@ast::method]) -> @ast::item {
|
||||
let trait_path = self.path.to_path(cx, span, type_ident, generics);
|
||||
|
|
@ -315,7 +315,7 @@ impl<'self> TraitDef<'self> {
|
|||
additional_bounds)
|
||||
}
|
||||
|
||||
fn expand_struct_def(&self, cx: @ext_ctxt,
|
||||
fn expand_struct_def(&self, cx: @ExtCtxt,
|
||||
span: span,
|
||||
struct_def: &struct_def,
|
||||
type_ident: ident,
|
||||
|
|
@ -347,7 +347,7 @@ impl<'self> TraitDef<'self> {
|
|||
}
|
||||
|
||||
fn expand_enum_def(&self,
|
||||
cx: @ext_ctxt, span: span,
|
||||
cx: @ExtCtxt, span: span,
|
||||
enum_def: &enum_def,
|
||||
type_ident: ident,
|
||||
generics: &Generics) -> @ast::item {
|
||||
|
|
@ -380,7 +380,7 @@ impl<'self> TraitDef<'self> {
|
|||
|
||||
impl<'self> MethodDef<'self> {
|
||||
fn call_substructure_method(&self,
|
||||
cx: @ext_ctxt,
|
||||
cx: @ExtCtxt,
|
||||
span: span,
|
||||
type_ident: ident,
|
||||
self_args: &[@expr],
|
||||
|
|
@ -398,7 +398,7 @@ impl<'self> MethodDef<'self> {
|
|||
&substructure)
|
||||
}
|
||||
|
||||
fn get_ret_ty(&self, cx: @ext_ctxt, span: span,
|
||||
fn get_ret_ty(&self, cx: @ExtCtxt, span: span,
|
||||
generics: &Generics, type_ident: ident) -> @ast::Ty {
|
||||
self.ret_ty.to_ty(cx, span, type_ident, generics)
|
||||
}
|
||||
|
|
@ -407,7 +407,7 @@ impl<'self> MethodDef<'self> {
|
|||
self.explicit_self.is_none()
|
||||
}
|
||||
|
||||
fn split_self_nonself_args(&self, cx: @ext_ctxt, span: span,
|
||||
fn split_self_nonself_args(&self, cx: @ExtCtxt, span: span,
|
||||
type_ident: ident, generics: &Generics)
|
||||
-> (ast::explicit_self, ~[@expr], ~[@expr], ~[(ident, @ast::Ty)]) {
|
||||
|
||||
|
|
@ -431,7 +431,7 @@ impl<'self> MethodDef<'self> {
|
|||
let ident = cx.ident_of(fmt!("__arg_%u", i));
|
||||
arg_tys.push((ident, ast_ty));
|
||||
|
||||
let arg_expr = build::mk_path(cx, span, ~[ident]);
|
||||
let arg_expr = cx.expr_ident(span, ident);
|
||||
|
||||
match *ty {
|
||||
// for static methods, just treat any Self
|
||||
|
|
@ -440,7 +440,7 @@ impl<'self> MethodDef<'self> {
|
|||
self_args.push(arg_expr);
|
||||
}
|
||||
Ptr(~Self, _) if nonstatic => {
|
||||
self_args.push(build::mk_deref(cx, span, arg_expr))
|
||||
self_args.push(cx.expr_deref(span, arg_expr))
|
||||
}
|
||||
_ => {
|
||||
nonself_args.push(arg_expr);
|
||||
|
|
@ -451,7 +451,7 @@ impl<'self> MethodDef<'self> {
|
|||
(ast_explicit_self, self_args, nonself_args, arg_tys)
|
||||
}
|
||||
|
||||
fn create_method(&self, cx: @ext_ctxt, span: span,
|
||||
fn create_method(&self, cx: @ExtCtxt, span: span,
|
||||
type_ident: ident,
|
||||
generics: &Generics,
|
||||
explicit_self: ast::explicit_self,
|
||||
|
|
@ -461,14 +461,14 @@ impl<'self> MethodDef<'self> {
|
|||
let fn_generics = self.generics.to_generics(cx, span, type_ident, generics);
|
||||
|
||||
let args = do arg_types.map |&(id, ty)| {
|
||||
build::mk_arg(cx, span, id, ty)
|
||||
cx.arg(span, id, ty)
|
||||
};
|
||||
|
||||
let ret_type = self.get_ret_ty(cx, span, generics, type_ident);
|
||||
|
||||
let method_ident = cx.ident_of(self.name);
|
||||
let fn_decl = build::mk_fn_decl(args, ret_type);
|
||||
let body_block = build::mk_simple_block(cx, span, body);
|
||||
let fn_decl = cx.fn_decl(args, ret_type);
|
||||
let body_block = cx.blk_expr(body);
|
||||
|
||||
|
||||
// Create the method.
|
||||
|
|
@ -509,7 +509,7 @@ impl<'self> MethodDef<'self> {
|
|||
~~~
|
||||
*/
|
||||
fn expand_struct_method_body(&self,
|
||||
cx: @ext_ctxt,
|
||||
cx: @ExtCtxt,
|
||||
span: span,
|
||||
struct_def: &struct_def,
|
||||
type_ident: ident,
|
||||
|
|
@ -555,19 +555,14 @@ impl<'self> MethodDef<'self> {
|
|||
// structs. This is actually right-to-left, but it shoudn't
|
||||
// matter.
|
||||
for vec::each2(self_args, patterns) |&arg_expr, &pat| {
|
||||
let match_arm = ast::arm {
|
||||
pats: ~[ pat ],
|
||||
guard: None,
|
||||
body: build::mk_simple_block(cx, span, body)
|
||||
};
|
||||
|
||||
body = build::mk_expr(cx, span, ast::expr_match(arg_expr, ~[match_arm]))
|
||||
body = cx.expr_match(span, arg_expr,
|
||||
~[ cx.arm(span, ~[pat], body) ])
|
||||
}
|
||||
body
|
||||
}
|
||||
|
||||
fn expand_static_struct_method_body(&self,
|
||||
cx: @ext_ctxt,
|
||||
cx: @ExtCtxt,
|
||||
span: span,
|
||||
struct_def: &struct_def,
|
||||
type_ident: ident,
|
||||
|
|
@ -609,7 +604,7 @@ impl<'self> MethodDef<'self> {
|
|||
~~~
|
||||
*/
|
||||
fn expand_enum_method_body(&self,
|
||||
cx: @ext_ctxt,
|
||||
cx: @ExtCtxt,
|
||||
span: span,
|
||||
enum_def: &enum_def,
|
||||
type_ident: ident,
|
||||
|
|
@ -645,7 +640,7 @@ impl<'self> MethodDef<'self> {
|
|||
the first call).
|
||||
*/
|
||||
fn build_enum_match(&self,
|
||||
cx: @ext_ctxt, span: span,
|
||||
cx: @ExtCtxt, span: span,
|
||||
enum_def: &enum_def,
|
||||
type_ident: ident,
|
||||
self_args: &[@expr],
|
||||
|
|
@ -690,7 +685,7 @@ impl<'self> MethodDef<'self> {
|
|||
}
|
||||
let field_tuples =
|
||||
do vec::map_zip(*self_vec,
|
||||
enum_matching_fields) |&(id, self_f), &other| {
|
||||
enum_matching_fields) |&(id, self_f), &other| {
|
||||
(id, self_f, other)
|
||||
};
|
||||
substructure = EnumMatching(variant_index, variant, field_tuples);
|
||||
|
|
@ -738,16 +733,16 @@ impl<'self> MethodDef<'self> {
|
|||
matches_so_far,
|
||||
match_count + 1);
|
||||
matches_so_far.pop();
|
||||
arms.push(build::mk_arm(cx, span, ~[ pattern ], arm_expr));
|
||||
arms.push(cx.arm(span, ~[ pattern ], arm_expr));
|
||||
|
||||
if enum_def.variants.len() > 1 {
|
||||
let e = &EnumNonMatching(&[]);
|
||||
let wild_expr = self.call_substructure_method(cx, span, type_ident,
|
||||
self_args, nonself_args,
|
||||
e);
|
||||
let wild_arm = build::mk_arm(cx, span,
|
||||
~[ build::mk_pat_wild(cx, span) ],
|
||||
wild_expr);
|
||||
let wild_arm = cx.arm(span,
|
||||
~[ cx.pat_wild(span) ],
|
||||
wild_expr);
|
||||
arms.push(wild_arm);
|
||||
}
|
||||
} else {
|
||||
|
|
@ -774,19 +769,18 @@ impl<'self> MethodDef<'self> {
|
|||
match_count + 1);
|
||||
matches_so_far.pop();
|
||||
|
||||
let arm = build::mk_arm(cx, span, ~[ pattern ], arm_expr);
|
||||
let arm = cx.arm(span, ~[ pattern ], arm_expr);
|
||||
arms.push(arm);
|
||||
}
|
||||
}
|
||||
|
||||
// match foo { arm, arm, arm, ... }
|
||||
build::mk_expr(cx, span,
|
||||
ast::expr_match(self_args[match_count], arms))
|
||||
cx.expr_match(span, self_args[match_count], arms)
|
||||
}
|
||||
}
|
||||
|
||||
fn expand_static_enum_method_body(&self,
|
||||
cx: @ext_ctxt,
|
||||
cx: @ExtCtxt,
|
||||
span: span,
|
||||
enum_def: &enum_def,
|
||||
type_ident: ident,
|
||||
|
|
@ -810,7 +804,7 @@ impl<'self> MethodDef<'self> {
|
|||
}
|
||||
}
|
||||
|
||||
fn summarise_struct(cx: @ext_ctxt, span: span,
|
||||
fn summarise_struct(cx: @ExtCtxt, span: span,
|
||||
struct_def: &struct_def) -> Either<uint, ~[ident]> {
|
||||
let mut named_idents = ~[];
|
||||
let mut unnamed_count = 0;
|
||||
|
|
@ -840,12 +834,12 @@ Fold the fields. `use_foldl` controls whether this is done
|
|||
left-to-right (`true`) or right-to-left (`false`).
|
||||
*/
|
||||
pub fn cs_fold(use_foldl: bool,
|
||||
f: &fn(@ext_ctxt, span,
|
||||
f: &fn(@ExtCtxt, span,
|
||||
old: @expr,
|
||||
self_f: @expr, other_fs: &[@expr]) -> @expr,
|
||||
base: @expr,
|
||||
enum_nonmatch_f: EnumNonMatchFunc,
|
||||
cx: @ext_ctxt, span: span,
|
||||
cx: @ExtCtxt, span: span,
|
||||
substructure: &Substructure) -> @expr {
|
||||
match *substructure.fields {
|
||||
EnumMatching(_, _, ref all_fields) | Struct(ref all_fields) => {
|
||||
|
|
@ -879,18 +873,18 @@ f(cx, span, ~[self_1.method(__arg_1_1, __arg_2_1),
|
|||
~~~
|
||||
*/
|
||||
#[inline(always)]
|
||||
pub fn cs_same_method(f: &fn(@ext_ctxt, span, ~[@expr]) -> @expr,
|
||||
pub fn cs_same_method(f: &fn(@ExtCtxt, span, ~[@expr]) -> @expr,
|
||||
enum_nonmatch_f: EnumNonMatchFunc,
|
||||
cx: @ext_ctxt, span: span,
|
||||
cx: @ExtCtxt, span: span,
|
||||
substructure: &Substructure) -> @expr {
|
||||
match *substructure.fields {
|
||||
EnumMatching(_, _, ref all_fields) | Struct(ref all_fields) => {
|
||||
// call self_n.method(other_1_n, other_2_n, ...)
|
||||
let called = do all_fields.map |&(_, self_field, other_fields)| {
|
||||
build::mk_method_call(cx, span,
|
||||
self_field,
|
||||
substructure.method_ident,
|
||||
other_fields)
|
||||
cx.expr_method_call(span,
|
||||
self_field,
|
||||
substructure.method_ident,
|
||||
other_fields)
|
||||
};
|
||||
|
||||
f(cx, span, called)
|
||||
|
|
@ -911,10 +905,10 @@ fields. `use_foldl` controls whether this is done left-to-right
|
|||
*/
|
||||
#[inline(always)]
|
||||
pub fn cs_same_method_fold(use_foldl: bool,
|
||||
f: &fn(@ext_ctxt, span, @expr, @expr) -> @expr,
|
||||
f: &fn(@ExtCtxt, span, @expr, @expr) -> @expr,
|
||||
base: @expr,
|
||||
enum_nonmatch_f: EnumNonMatchFunc,
|
||||
cx: @ext_ctxt, span: span,
|
||||
cx: @ExtCtxt, span: span,
|
||||
substructure: &Substructure) -> @expr {
|
||||
cs_same_method(
|
||||
|cx, span, vals| {
|
||||
|
|
@ -940,14 +934,14 @@ on all the fields.
|
|||
#[inline(always)]
|
||||
pub fn cs_binop(binop: ast::binop, base: @expr,
|
||||
enum_nonmatch_f: EnumNonMatchFunc,
|
||||
cx: @ext_ctxt, span: span,
|
||||
cx: @ExtCtxt, span: span,
|
||||
substructure: &Substructure) -> @expr {
|
||||
cs_same_method_fold(
|
||||
true, // foldl is good enough
|
||||
|cx, span, old, new| {
|
||||
build::mk_binary(cx, span,
|
||||
binop,
|
||||
old, new)
|
||||
cx.expr_binary(span,
|
||||
binop,
|
||||
old, new)
|
||||
|
||||
},
|
||||
base,
|
||||
|
|
@ -958,18 +952,18 @@ pub fn cs_binop(binop: ast::binop, base: @expr,
|
|||
/// cs_binop with binop == or
|
||||
#[inline(always)]
|
||||
pub fn cs_or(enum_nonmatch_f: EnumNonMatchFunc,
|
||||
cx: @ext_ctxt, span: span,
|
||||
cx: @ExtCtxt, span: span,
|
||||
substructure: &Substructure) -> @expr {
|
||||
cs_binop(ast::or, build::mk_bool(cx, span, false),
|
||||
cs_binop(ast::or, cx.expr_bool(span, false),
|
||||
enum_nonmatch_f,
|
||||
cx, span, substructure)
|
||||
}
|
||||
/// cs_binop with binop == and
|
||||
#[inline(always)]
|
||||
pub fn cs_and(enum_nonmatch_f: EnumNonMatchFunc,
|
||||
cx: @ext_ctxt, span: span,
|
||||
cx: @ExtCtxt, span: span,
|
||||
substructure: &Substructure) -> @expr {
|
||||
cs_binop(ast::and, build::mk_bool(cx, span, true),
|
||||
cs_binop(ast::and, cx.expr_bool(span, true),
|
||||
enum_nonmatch_f,
|
||||
cx, span, substructure)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,28 +10,28 @@
|
|||
|
||||
use ast::{meta_item, item, expr, and};
|
||||
use codemap::span;
|
||||
use ext::base::ext_ctxt;
|
||||
use ext::build;
|
||||
use ext::base::ExtCtxt;
|
||||
use ext::build::AstBuilder;
|
||||
use ext::deriving::generic::*;
|
||||
|
||||
pub fn expand_deriving_iter_bytes(cx: @ext_ctxt,
|
||||
pub fn expand_deriving_iter_bytes(cx: @ExtCtxt,
|
||||
span: span,
|
||||
mitem: @meta_item,
|
||||
in_items: ~[@item]) -> ~[@item] {
|
||||
let trait_def = TraitDef {
|
||||
path: Path::new(~[~"core", ~"to_bytes", ~"IterBytes"]),
|
||||
path: Path::new(~["core", "to_bytes", "IterBytes"]),
|
||||
additional_bounds: ~[],
|
||||
generics: LifetimeBounds::empty(),
|
||||
methods: ~[
|
||||
MethodDef {
|
||||
name: ~"iter_bytes",
|
||||
name: "iter_bytes",
|
||||
generics: LifetimeBounds::empty(),
|
||||
explicit_self: borrowed_explicit_self(),
|
||||
args: ~[
|
||||
Literal(Path::new(~[~"bool"])),
|
||||
Literal(Path::new(~[~"core", ~"to_bytes", ~"Cb"]))
|
||||
Literal(Path::new(~["bool"])),
|
||||
Literal(Path::new(~["core", "to_bytes", "Cb"]))
|
||||
],
|
||||
ret_ty: Literal(Path::new(~[~"bool"])),
|
||||
ret_ty: Literal(Path::new(~["bool"])),
|
||||
const_nonmatching: false,
|
||||
combine_substructure: iter_bytes_substructure
|
||||
}
|
||||
|
|
@ -41,14 +41,14 @@ pub fn expand_deriving_iter_bytes(cx: @ext_ctxt,
|
|||
expand_deriving_generic(cx, span, mitem, in_items, &trait_def)
|
||||
}
|
||||
|
||||
fn iter_bytes_substructure(cx: @ext_ctxt, span: span, substr: &Substructure) -> @expr {
|
||||
fn iter_bytes_substructure(cx: @ExtCtxt, span: span, substr: &Substructure) -> @expr {
|
||||
let lsb0_f = match substr.nonself_args {
|
||||
[l, f] => ~[l, f],
|
||||
_ => cx.span_bug(span, "Incorrect number of arguments in `deriving(IterBytes)`")
|
||||
};
|
||||
let iter_bytes_ident = substr.method_ident;
|
||||
let call_iterbytes = |thing_expr| {
|
||||
build::mk_method_call(cx, span,
|
||||
cx.expr_method_call(span,
|
||||
thing_expr, iter_bytes_ident,
|
||||
copy lsb0_f)
|
||||
};
|
||||
|
|
@ -63,7 +63,7 @@ fn iter_bytes_substructure(cx: @ext_ctxt, span: span, substr: &Substructure) ->
|
|||
// iteration function.
|
||||
let discriminant = match variant.node.disr_expr {
|
||||
Some(copy d)=> d,
|
||||
None => build::mk_uint(cx, span, index)
|
||||
None => cx.expr_uint(span, index)
|
||||
};
|
||||
|
||||
exprs.push(call_iterbytes(discriminant));
|
||||
|
|
@ -82,6 +82,6 @@ fn iter_bytes_substructure(cx: @ext_ctxt, span: span, substr: &Substructure) ->
|
|||
}
|
||||
|
||||
do vec::foldl(exprs[0], exprs.slice(1, exprs.len())) |prev, me| {
|
||||
build::mk_binary(cx, span, and, prev, *me)
|
||||
cx.expr_binary(span, and, prev, *me)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,9 +20,9 @@ library.
|
|||
|
||||
use ast;
|
||||
use ast::{Ty, enum_def, expr, ident, item, Generics, meta_item, struct_def};
|
||||
use ext::base::ext_ctxt;
|
||||
use ext::build;
|
||||
use codemap::{span, respan};
|
||||
use ext::base::ExtCtxt;
|
||||
use ext::build::AstBuilder;
|
||||
use codemap::span;
|
||||
use parse::token::special_idents::clownshoes_extensions;
|
||||
use opt_vec;
|
||||
|
||||
|
|
@ -45,20 +45,20 @@ pub mod totalord;
|
|||
|
||||
pub mod generic;
|
||||
|
||||
pub type ExpandDerivingStructDefFn<'self> = &'self fn(@ext_ctxt,
|
||||
pub type ExpandDerivingStructDefFn<'self> = &'self fn(@ExtCtxt,
|
||||
span,
|
||||
x: &struct_def,
|
||||
ident,
|
||||
y: &Generics)
|
||||
-> @item;
|
||||
pub type ExpandDerivingEnumDefFn<'self> = &'self fn(@ext_ctxt,
|
||||
pub type ExpandDerivingEnumDefFn<'self> = &'self fn(@ExtCtxt,
|
||||
span,
|
||||
x: &enum_def,
|
||||
ident,
|
||||
y: &Generics)
|
||||
-> @item;
|
||||
|
||||
pub fn expand_meta_deriving(cx: @ext_ctxt,
|
||||
pub fn expand_meta_deriving(cx: @ExtCtxt,
|
||||
_span: span,
|
||||
mitem: @meta_item,
|
||||
in_items: ~[@item])
|
||||
|
|
@ -113,7 +113,7 @@ pub fn expand_meta_deriving(cx: @ext_ctxt,
|
|||
}
|
||||
}
|
||||
|
||||
pub fn expand_deriving(cx: @ext_ctxt,
|
||||
pub fn expand_deriving(cx: @ExtCtxt,
|
||||
span: span,
|
||||
in_items: ~[@item],
|
||||
expand_deriving_struct_def: ExpandDerivingStructDefFn,
|
||||
|
|
@ -143,38 +143,15 @@ pub fn expand_deriving(cx: @ext_ctxt,
|
|||
result
|
||||
}
|
||||
|
||||
fn create_impl_item(cx: @ext_ctxt, span: span, item: ast::item_) -> @item {
|
||||
let doc_attr = respan(span,
|
||||
ast::lit_str(@~"Automatically derived."));
|
||||
let doc_attr = respan(span, ast::meta_name_value(@~"doc", doc_attr));
|
||||
let doc_attr = ast::attribute_ {
|
||||
style: ast::attr_outer,
|
||||
value: @doc_attr,
|
||||
is_sugared_doc: false
|
||||
};
|
||||
let doc_attr = respan(span, doc_attr);
|
||||
|
||||
@ast::item {
|
||||
ident: clownshoes_extensions,
|
||||
attrs: ~[doc_attr],
|
||||
id: cx.next_id(),
|
||||
node: item,
|
||||
vis: ast::public,
|
||||
span: span,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn create_self_type_with_params(cx: @ext_ctxt,
|
||||
span: span,
|
||||
type_ident: ident,
|
||||
generics: &Generics)
|
||||
-> @Ty {
|
||||
pub fn create_self_type_with_params(cx: @ExtCtxt,
|
||||
span: span,
|
||||
type_ident: ident,
|
||||
generics: &Generics)
|
||||
-> @Ty {
|
||||
// Create the type parameters on the `self` path.
|
||||
let mut self_ty_params = ~[];
|
||||
for generics.ty_params.each |ty_param| {
|
||||
let self_ty_param = build::mk_simple_ty_path(cx,
|
||||
span,
|
||||
ty_param.ident);
|
||||
let self_ty_param = cx.ty_ident(span, ty_param.ident);
|
||||
self_ty_params.push(self_ty_param);
|
||||
}
|
||||
|
||||
|
|
@ -186,14 +163,10 @@ pub fn create_self_type_with_params(cx: @ext_ctxt,
|
|||
|
||||
|
||||
// Create the type of `self`.
|
||||
let self_type = build::mk_raw_path_(span,
|
||||
~[ type_ident ],
|
||||
lifetime,
|
||||
self_ty_params);
|
||||
build::mk_ty_path_path(cx, span, self_type)
|
||||
cx.ty_path(cx.path_all(span, false, ~[ type_ident ], lifetime, self_ty_params))
|
||||
}
|
||||
|
||||
pub fn create_derived_impl(cx: @ext_ctxt,
|
||||
pub fn create_derived_impl(cx: @ExtCtxt,
|
||||
span: span,
|
||||
type_ident: ident,
|
||||
generics: &Generics,
|
||||
|
|
@ -222,18 +195,17 @@ pub fn create_derived_impl(cx: @ext_ctxt,
|
|||
for generics.ty_params.each |ty_param| {
|
||||
// extra restrictions on the generics parameters to the type being derived upon
|
||||
let mut bounds = do bounds_paths.map |&bound_path| {
|
||||
build::mk_trait_ty_param_bound_(cx, bound_path)
|
||||
cx.typarambound(bound_path)
|
||||
};
|
||||
|
||||
let this_trait_bound =
|
||||
build::mk_trait_ty_param_bound_(cx, trait_path);
|
||||
let this_trait_bound = cx.typarambound(trait_path);
|
||||
bounds.push(this_trait_bound);
|
||||
|
||||
impl_generics.ty_params.push(build::mk_ty_param(cx, ty_param.ident, @bounds));
|
||||
impl_generics.ty_params.push(cx.typaram(ty_param.ident, @bounds));
|
||||
}
|
||||
|
||||
// Create the reference to the trait.
|
||||
let trait_ref = build::mk_trait_ref_(cx, trait_path);
|
||||
let trait_ref = cx.trait_ref(trait_path);
|
||||
|
||||
// Create the type of `self`.
|
||||
let self_type = create_self_type_with_params(cx,
|
||||
|
|
@ -241,21 +213,27 @@ pub fn create_derived_impl(cx: @ext_ctxt,
|
|||
type_ident,
|
||||
generics);
|
||||
|
||||
// Create the impl item.
|
||||
let impl_item = ast::item_impl(impl_generics,
|
||||
Some(trait_ref),
|
||||
self_type,
|
||||
methods.map(|x| *x));
|
||||
return create_impl_item(cx, span, impl_item);
|
||||
let doc_attr = cx.attribute(
|
||||
span,
|
||||
cx.meta_name_value(span,
|
||||
~"doc", ast::lit_str(@~"Automatically derived.")));
|
||||
cx.item(
|
||||
span,
|
||||
clownshoes_extensions,
|
||||
~[doc_attr],
|
||||
ast::item_impl(impl_generics,
|
||||
Some(trait_ref),
|
||||
self_type,
|
||||
methods.map(|x| *x)))
|
||||
}
|
||||
|
||||
pub fn create_subpatterns(cx: @ext_ctxt,
|
||||
pub fn create_subpatterns(cx: @ExtCtxt,
|
||||
span: span,
|
||||
field_paths: ~[@ast::Path],
|
||||
mutbl: ast::mutability)
|
||||
-> ~[@ast::pat] {
|
||||
do field_paths.map |&path| {
|
||||
build::mk_pat(cx, span,
|
||||
cx.pat(span,
|
||||
ast::pat_ident(ast::bind_by_ref(mutbl), path, None))
|
||||
}
|
||||
}
|
||||
|
|
@ -265,7 +243,7 @@ enum StructType {
|
|||
Unknown, Record, Tuple
|
||||
}
|
||||
|
||||
pub fn create_struct_pattern(cx: @ext_ctxt,
|
||||
pub fn create_struct_pattern(cx: @ExtCtxt,
|
||||
span: span,
|
||||
struct_ident: ident,
|
||||
struct_def: &struct_def,
|
||||
|
|
@ -274,12 +252,12 @@ pub fn create_struct_pattern(cx: @ext_ctxt,
|
|||
-> (@ast::pat, ~[(Option<ident>, @expr)]) {
|
||||
if struct_def.fields.is_empty() {
|
||||
return (
|
||||
build::mk_pat_ident_with_binding_mode(
|
||||
cx, span, struct_ident, ast::bind_infer),
|
||||
cx.pat_ident_binding_mode(
|
||||
span, struct_ident, ast::bind_infer),
|
||||
~[]);
|
||||
}
|
||||
|
||||
let matching_path = build::mk_raw_path(span, ~[ struct_ident ]);
|
||||
let matching_path = cx.path(span, ~[ struct_ident ]);
|
||||
|
||||
let mut paths = ~[], ident_expr = ~[];
|
||||
|
||||
|
|
@ -301,10 +279,10 @@ pub fn create_struct_pattern(cx: @ext_ctxt,
|
|||
cx.span_bug(span, "A struct with named and unnamed fields in `deriving`");
|
||||
}
|
||||
};
|
||||
let path = build::mk_raw_path(span,
|
||||
~[ cx.ident_of(fmt!("%s_%u", prefix, i)) ]);
|
||||
let path = cx.path_ident(span,
|
||||
cx.ident_of(fmt!("%s_%u", prefix, i)));
|
||||
paths.push(path);
|
||||
ident_expr.push((opt_id, build::mk_path_raw(cx, span, path)));
|
||||
ident_expr.push((opt_id, cx.expr_path(path)));
|
||||
}
|
||||
|
||||
let subpats = create_subpatterns(cx, span, paths, mutbl);
|
||||
|
|
@ -318,15 +296,15 @@ pub fn create_struct_pattern(cx: @ext_ctxt,
|
|||
push(ast::field_pat { ident: id.get(), pat: pat })
|
||||
}
|
||||
};
|
||||
build::mk_pat_struct(cx, span, matching_path, field_pats)
|
||||
cx.pat_struct(span, matching_path, field_pats)
|
||||
} else {
|
||||
build::mk_pat_enum(cx, span, matching_path, subpats)
|
||||
cx.pat_enum(span, matching_path, subpats)
|
||||
};
|
||||
|
||||
(pattern, ident_expr)
|
||||
}
|
||||
|
||||
pub fn create_enum_variant_pattern(cx: @ext_ctxt,
|
||||
pub fn create_enum_variant_pattern(cx: @ExtCtxt,
|
||||
span: span,
|
||||
variant: &ast::variant,
|
||||
prefix: &str,
|
||||
|
|
@ -337,24 +315,24 @@ pub fn create_enum_variant_pattern(cx: @ext_ctxt,
|
|||
match variant.node.kind {
|
||||
ast::tuple_variant_kind(ref variant_args) => {
|
||||
if variant_args.is_empty() {
|
||||
return (build::mk_pat_ident_with_binding_mode(
|
||||
cx, span, variant_ident, ast::bind_infer), ~[]);
|
||||
return (cx.pat_ident_binding_mode(
|
||||
span, variant_ident, ast::bind_infer), ~[]);
|
||||
}
|
||||
|
||||
let matching_path = build::mk_raw_path(span, ~[ variant_ident ]);
|
||||
let matching_path = cx.path_ident(span, variant_ident);
|
||||
|
||||
let mut paths = ~[], ident_expr = ~[];
|
||||
for uint::range(0, variant_args.len()) |i| {
|
||||
let path = build::mk_raw_path(span,
|
||||
~[ cx.ident_of(fmt!("%s_%u", prefix, i)) ]);
|
||||
let path = cx.path_ident(span,
|
||||
cx.ident_of(fmt!("%s_%u", prefix, i)));
|
||||
|
||||
paths.push(path);
|
||||
ident_expr.push((None, build::mk_path_raw(cx, span, path)));
|
||||
ident_expr.push((None, cx.expr_path(path)));
|
||||
}
|
||||
|
||||
let subpats = create_subpatterns(cx, span, paths, mutbl);
|
||||
|
||||
(build::mk_pat_enum(cx, span, matching_path, subpats),
|
||||
(cx.pat_enum(span, matching_path, subpats),
|
||||
ident_expr)
|
||||
}
|
||||
ast::struct_variant_kind(struct_def) => {
|
||||
|
|
@ -366,19 +344,17 @@ pub fn create_enum_variant_pattern(cx: @ext_ctxt,
|
|||
}
|
||||
}
|
||||
|
||||
pub fn variant_arg_count(_cx: @ext_ctxt, _span: span, variant: &ast::variant) -> uint {
|
||||
pub fn variant_arg_count(_cx: @ExtCtxt, _span: span, variant: &ast::variant) -> uint {
|
||||
match variant.node.kind {
|
||||
ast::tuple_variant_kind(ref args) => args.len(),
|
||||
ast::struct_variant_kind(ref struct_def) => struct_def.fields.len(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn expand_enum_or_struct_match(cx: @ext_ctxt,
|
||||
pub fn expand_enum_or_struct_match(cx: @ExtCtxt,
|
||||
span: span,
|
||||
arms: ~[ ast::arm ])
|
||||
-> @expr {
|
||||
let self_expr = build::make_self(cx, span);
|
||||
let self_expr = build::mk_unary(cx, span, ast::deref, self_expr);
|
||||
let self_match_expr = ast::expr_match(self_expr, arms);
|
||||
build::mk_expr(cx, span, self_match_expr)
|
||||
let self_expr = cx.expr_deref(span, cx.expr_self(span));
|
||||
cx.expr_match(span, self_expr, arms)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,30 +11,30 @@
|
|||
use ast;
|
||||
use ast::{meta_item, item, expr, ident};
|
||||
use codemap::span;
|
||||
use ext::base::ext_ctxt;
|
||||
use ext::build;
|
||||
use ext::base::ExtCtxt;
|
||||
use ext::build::{AstBuilder, Duplicate};
|
||||
use ext::deriving::generic::*;
|
||||
|
||||
pub fn expand_deriving_rand(cx: @ext_ctxt,
|
||||
pub fn expand_deriving_rand(cx: @ExtCtxt,
|
||||
span: span,
|
||||
mitem: @meta_item,
|
||||
in_items: ~[@item])
|
||||
-> ~[@item] {
|
||||
let trait_def = TraitDef {
|
||||
path: Path::new(~[~"core", ~"rand", ~"Rand"]),
|
||||
path: Path::new(~["core", "rand", "Rand"]),
|
||||
additional_bounds: ~[],
|
||||
generics: LifetimeBounds::empty(),
|
||||
methods: ~[
|
||||
MethodDef {
|
||||
name: ~"rand",
|
||||
name: "rand",
|
||||
generics: LifetimeBounds {
|
||||
lifetimes: ~[],
|
||||
bounds: ~[(~"R",
|
||||
~[ Path::new(~[~"core", ~"rand", ~"Rng"]) ])]
|
||||
bounds: ~[("R",
|
||||
~[ Path::new(~["core", "rand", "Rng"]) ])]
|
||||
},
|
||||
explicit_self: None,
|
||||
args: ~[
|
||||
Ptr(~Literal(Path::new_local(~"R")),
|
||||
Ptr(~Literal(Path::new_local("R")),
|
||||
Borrowed(None, ast::m_mutbl))
|
||||
],
|
||||
ret_ty: Self,
|
||||
|
|
@ -47,7 +47,7 @@ pub fn expand_deriving_rand(cx: @ext_ctxt,
|
|||
expand_deriving_generic(cx, span, mitem, in_items, &trait_def)
|
||||
}
|
||||
|
||||
fn rand_substructure(cx: @ext_ctxt, span: span, substr: &Substructure) -> @expr {
|
||||
fn rand_substructure(cx: @ExtCtxt, span: span, substr: &Substructure) -> @expr {
|
||||
let rng = match substr.nonself_args {
|
||||
[rng] => ~[ rng ],
|
||||
_ => cx.bug("Incorrect number of arguments to `rand` in `deriving(Rand)`")
|
||||
|
|
@ -59,10 +59,9 @@ fn rand_substructure(cx: @ext_ctxt, span: span, substr: &Substructure) -> @expr
|
|||
cx.ident_of("rand")
|
||||
];
|
||||
let rand_call = || {
|
||||
build::mk_call_global(cx,
|
||||
span,
|
||||
copy rand_ident,
|
||||
~[ build::duplicate_expr(cx, rng[0]) ])
|
||||
cx.expr_call_global(span,
|
||||
copy rand_ident,
|
||||
~[ rng[0].duplicate(cx) ])
|
||||
};
|
||||
|
||||
return match *substr.fields {
|
||||
|
|
@ -74,67 +73,61 @@ fn rand_substructure(cx: @ext_ctxt, span: span, substr: &Substructure) -> @expr
|
|||
cx.span_fatal(span, "`Rand` cannot be derived for enums with no variants");
|
||||
}
|
||||
|
||||
let variant_count = build::mk_uint(cx, span, variants.len());
|
||||
let variant_count = cx.expr_uint(span, variants.len());
|
||||
|
||||
// need to specify the uint-ness of the random number
|
||||
let u32_ty = build::mk_ty_path(cx, span, ~[cx.ident_of("uint")]);
|
||||
let r_ty = build::mk_ty_path(cx, span, ~[cx.ident_of("R")]);
|
||||
let rand_name = build::mk_raw_path_(span, copy rand_ident, None, ~[ u32_ty, r_ty ]);
|
||||
let rand_name = build::mk_path_raw(cx, span, rand_name);
|
||||
let u32_ty = cx.ty_ident(span, cx.ident_of("uint"));
|
||||
let r_ty = cx.ty_ident(span, cx.ident_of("R"));
|
||||
let rand_name = cx.path_all(span, false, copy rand_ident, None, ~[ u32_ty, r_ty ]);
|
||||
let rand_name = cx.expr_path(rand_name);
|
||||
|
||||
let rv_call = build::mk_call_(cx,
|
||||
span,
|
||||
rand_name,
|
||||
~[ build::duplicate_expr(cx, rng[0]) ]);
|
||||
let rv_call = cx.expr_call(span,
|
||||
rand_name,
|
||||
~[ rng[0].duplicate(cx) ]);
|
||||
|
||||
// rand() % variants.len()
|
||||
let rand_variant = build::mk_binary(cx, span, ast::rem,
|
||||
let rand_variant = cx.expr_binary(span, ast::rem,
|
||||
rv_call, variant_count);
|
||||
|
||||
let mut arms = do variants.mapi |i, id_sum| {
|
||||
let i_expr = build::mk_uint(cx, span, i);
|
||||
let pat = build::mk_pat_lit(cx, span, i_expr);
|
||||
let i_expr = cx.expr_uint(span, i);
|
||||
let pat = cx.pat_lit(span, i_expr);
|
||||
|
||||
match *id_sum {
|
||||
(ident, ref summary) => {
|
||||
build::mk_arm(cx, span,
|
||||
~[ pat ],
|
||||
rand_thing(cx, span, ident, summary, rand_call))
|
||||
cx.arm(span,
|
||||
~[ pat ],
|
||||
rand_thing(cx, span, ident, summary, rand_call))
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// _ => {} at the end. Should never occur
|
||||
arms.push(build::mk_unreachable_arm(cx, span));
|
||||
arms.push(cx.arm_unreachable(span));
|
||||
|
||||
build::mk_expr(cx, span,
|
||||
ast::expr_match(rand_variant, arms))
|
||||
cx.expr_match(span, rand_variant, arms)
|
||||
}
|
||||
_ => cx.bug("Non-static method in `deriving(Rand)`")
|
||||
};
|
||||
|
||||
fn rand_thing(cx: @ext_ctxt, span: span,
|
||||
fn rand_thing(cx: @ExtCtxt, span: span,
|
||||
ctor_ident: ident,
|
||||
summary: &Either<uint, ~[ident]>,
|
||||
rand_call: &fn() -> @expr) -> @expr {
|
||||
let ctor_ident = ~[ ctor_ident ];
|
||||
match *summary {
|
||||
Left(copy count) => {
|
||||
if count == 0 {
|
||||
build::mk_path(cx, span, ctor_ident)
|
||||
cx.expr_ident(span, ctor_ident)
|
||||
} else {
|
||||
let exprs = vec::from_fn(count, |_| rand_call());
|
||||
build::mk_call(cx, span, ctor_ident, exprs)
|
||||
cx.expr_call_ident(span, ctor_ident, exprs)
|
||||
}
|
||||
}
|
||||
Right(ref fields) => {
|
||||
let rand_fields = do fields.map |ident| {
|
||||
build::Field {
|
||||
ident: *ident,
|
||||
ex: rand_call()
|
||||
}
|
||||
cx.field_imm(span, *ident, rand_call())
|
||||
};
|
||||
build::mk_struct_e(cx, span, ctor_ident, rand_fields)
|
||||
cx.expr_struct_ident(span, ctor_ident, rand_fields)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,26 +10,26 @@
|
|||
|
||||
use ast::{meta_item, item, expr};
|
||||
use codemap::span;
|
||||
use ext::base::ext_ctxt;
|
||||
use ext::build;
|
||||
use ext::base::ExtCtxt;
|
||||
use ext::build::AstBuilder;
|
||||
use ext::deriving::generic::*;
|
||||
|
||||
pub fn expand_deriving_to_str(cx: @ext_ctxt,
|
||||
pub fn expand_deriving_to_str(cx: @ExtCtxt,
|
||||
span: span,
|
||||
mitem: @meta_item,
|
||||
in_items: ~[@item])
|
||||
-> ~[@item] {
|
||||
let trait_def = TraitDef {
|
||||
path: Path::new(~[~"core", ~"to_str", ~"ToStr"]),
|
||||
path: Path::new(~["core", "to_str", "ToStr"]),
|
||||
additional_bounds: ~[],
|
||||
generics: LifetimeBounds::empty(),
|
||||
methods: ~[
|
||||
MethodDef {
|
||||
name: ~"to_str",
|
||||
name: "to_str",
|
||||
generics: LifetimeBounds::empty(),
|
||||
explicit_self: borrowed_explicit_self(),
|
||||
args: ~[],
|
||||
ret_ty: Ptr(~Literal(Path::new_local(~"str")), Owned),
|
||||
ret_ty: Ptr(~Literal(Path::new_local("str")), Owned),
|
||||
const_nonmatching: false,
|
||||
combine_substructure: to_str_substructure
|
||||
}
|
||||
|
|
@ -39,15 +39,15 @@ pub fn expand_deriving_to_str(cx: @ext_ctxt,
|
|||
expand_deriving_generic(cx, span, mitem, in_items, &trait_def)
|
||||
}
|
||||
|
||||
fn to_str_substructure(cx: @ext_ctxt, span: span, substr: &Substructure) -> @expr {
|
||||
fn to_str_substructure(cx: @ExtCtxt, span: span, substr: &Substructure) -> @expr {
|
||||
match substr.self_args {
|
||||
[self_obj] => {
|
||||
let self_addr = build::mk_addr_of(cx, span, self_obj);
|
||||
build::mk_call_global(cx, span,
|
||||
~[cx.ident_of("core"),
|
||||
cx.ident_of("sys"),
|
||||
cx.ident_of("log_str")],
|
||||
~[self_addr])
|
||||
let self_addr = cx.expr_addr_of(span, self_obj);
|
||||
cx.expr_call_global(span,
|
||||
~[cx.ident_of("core"),
|
||||
cx.ident_of("sys"),
|
||||
cx.ident_of("log_str")],
|
||||
~[self_addr])
|
||||
}
|
||||
_ => cx.span_bug(span, "Invalid number of arguments in `deriving(ToStr)`")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,37 +15,36 @@ explicit `Self` type to use when specifying impls to be derived.
|
|||
|
||||
use ast;
|
||||
use ast::{expr,Generics,ident};
|
||||
use ext::base::ext_ctxt;
|
||||
use ext::build;
|
||||
use ext::base::ExtCtxt;
|
||||
use ext::build::AstBuilder;
|
||||
use codemap::{span,respan};
|
||||
use opt_vec;
|
||||
|
||||
/// The types of pointers
|
||||
#[deriving(Eq)]
|
||||
pub enum PtrTy {
|
||||
pub enum PtrTy<'self> {
|
||||
Owned, // ~
|
||||
Managed(ast::mutability), // @[mut]
|
||||
Borrowed(Option<~str>, ast::mutability), // &['lifetime] [mut]
|
||||
Borrowed(Option<&'self str>, ast::mutability), // &['lifetime] [mut]
|
||||
}
|
||||
|
||||
/// A path, e.g. `::core::option::Option::<int>` (global). Has support
|
||||
/// for type parameters and a lifetime.
|
||||
#[deriving(Eq)]
|
||||
pub struct Path {
|
||||
path: ~[~str],
|
||||
lifetime: Option<~str>,
|
||||
params: ~[~Ty],
|
||||
pub struct Path<'self> {
|
||||
path: ~[&'self str],
|
||||
lifetime: Option<&'self str>,
|
||||
params: ~[~Ty<'self>],
|
||||
global: bool
|
||||
}
|
||||
|
||||
pub impl Path {
|
||||
fn new(path: ~[~str]) -> Path {
|
||||
pub impl<'self> Path<'self> {
|
||||
fn new<'r>(path: ~[&'r str]) -> Path<'r> {
|
||||
Path::new_(path, None, ~[], true)
|
||||
}
|
||||
fn new_local(path: ~str) -> Path {
|
||||
fn new_local<'r>(path: &'r str) -> Path<'r> {
|
||||
Path::new_(~[ path ], None, ~[], false)
|
||||
}
|
||||
fn new_(path: ~[~str], lifetime: Option<~str>, params: ~[~Ty], global: bool) -> Path {
|
||||
fn new_<'r>(path: ~[&'r str], lifetime: Option<&'r str>, params: ~[~Ty<'r>], global: bool)
|
||||
-> Path<'r> {
|
||||
Path {
|
||||
path: path,
|
||||
lifetime: lifetime,
|
||||
|
|
@ -54,87 +53,81 @@ pub impl Path {
|
|||
}
|
||||
}
|
||||
|
||||
fn to_ty(&self, cx: @ext_ctxt, span: span,
|
||||
fn to_ty(&self, cx: @ExtCtxt, span: span,
|
||||
self_ty: ident, self_generics: &Generics) -> @ast::Ty {
|
||||
build::mk_ty_path_path(cx, span,
|
||||
self.to_path(cx, span,
|
||||
self_ty, self_generics))
|
||||
cx.ty_path(self.to_path(cx, span,
|
||||
self_ty, self_generics))
|
||||
}
|
||||
fn to_path(&self, cx: @ext_ctxt, span: span,
|
||||
fn to_path(&self, cx: @ExtCtxt, span: span,
|
||||
self_ty: ident, self_generics: &Generics) -> @ast::Path {
|
||||
let idents = self.path.map(|s| cx.ident_of(*s) );
|
||||
let lt = mk_lifetime(cx, span, &self.lifetime);
|
||||
let tys = self.params.map(|t| t.to_ty(cx, span, self_ty, self_generics));
|
||||
|
||||
if self.global {
|
||||
build::mk_raw_path_global_(span, idents, lt, tys)
|
||||
} else {
|
||||
build::mk_raw_path_(span, idents, lt, tys)
|
||||
}
|
||||
cx.path_all(span, self.global, idents, lt, tys)
|
||||
}
|
||||
}
|
||||
|
||||
/// A type. Supports pointers (except for *), Self, and literals
|
||||
#[deriving(Eq)]
|
||||
pub enum Ty {
|
||||
pub enum Ty<'self> {
|
||||
Self,
|
||||
// &/~/@ Ty
|
||||
Ptr(~Ty, PtrTy),
|
||||
Ptr(~Ty<'self>, PtrTy<'self>),
|
||||
// mod::mod::Type<[lifetime], [Params...]>, including a plain type
|
||||
// parameter, and things like `int`
|
||||
Literal(Path),
|
||||
Literal(Path<'self>),
|
||||
// includes nil
|
||||
Tuple(~[Ty])
|
||||
Tuple(~[Ty<'self>])
|
||||
}
|
||||
|
||||
pub fn borrowed_ptrty() -> PtrTy {
|
||||
pub fn borrowed_ptrty<'r>() -> PtrTy<'r> {
|
||||
Borrowed(None, ast::m_imm)
|
||||
}
|
||||
pub fn borrowed(ty: ~Ty) -> Ty {
|
||||
pub fn borrowed<'r>(ty: ~Ty<'r>) -> Ty<'r> {
|
||||
Ptr(ty, borrowed_ptrty())
|
||||
}
|
||||
|
||||
pub fn borrowed_explicit_self() -> Option<Option<PtrTy>> {
|
||||
pub fn borrowed_explicit_self<'r>() -> Option<Option<PtrTy<'r>>> {
|
||||
Some(Some(borrowed_ptrty()))
|
||||
}
|
||||
|
||||
pub fn borrowed_self() -> Ty {
|
||||
pub fn borrowed_self<'r>() -> Ty<'r> {
|
||||
borrowed(~Self)
|
||||
}
|
||||
|
||||
pub fn nil_ty() -> Ty {
|
||||
pub fn nil_ty() -> Ty<'static> {
|
||||
Tuple(~[])
|
||||
}
|
||||
|
||||
fn mk_lifetime(cx: @ext_ctxt, span: span, lt: &Option<~str>) -> Option<@ast::Lifetime> {
|
||||
fn mk_lifetime(cx: @ExtCtxt, span: span, lt: &Option<&str>) -> Option<@ast::Lifetime> {
|
||||
match *lt {
|
||||
Some(ref s) => Some(@build::mk_lifetime(cx, span, cx.ident_of(*s))),
|
||||
Some(ref s) => Some(@cx.lifetime(span, cx.ident_of(*s))),
|
||||
None => None
|
||||
}
|
||||
}
|
||||
|
||||
pub impl Ty {
|
||||
fn to_ty(&self, cx: @ext_ctxt, span: span,
|
||||
pub impl<'self> Ty<'self> {
|
||||
fn to_ty(&self, cx: @ExtCtxt, span: span,
|
||||
self_ty: ident, self_generics: &Generics) -> @ast::Ty {
|
||||
match *self {
|
||||
Ptr(ref ty, ref ptr) => {
|
||||
let raw_ty = ty.to_ty(cx, span, self_ty, self_generics);
|
||||
match *ptr {
|
||||
Owned => {
|
||||
build::mk_ty_uniq(cx, span, raw_ty)
|
||||
cx.ty_uniq(span, raw_ty)
|
||||
}
|
||||
Managed(mutbl) => {
|
||||
build::mk_ty_box(cx, span, raw_ty, mutbl)
|
||||
cx.ty_box(span, raw_ty, mutbl)
|
||||
}
|
||||
Borrowed(ref lt, mutbl) => {
|
||||
let lt = mk_lifetime(cx, span, lt);
|
||||
build::mk_ty_rptr(cx, span, raw_ty, lt, mutbl)
|
||||
cx.ty_rptr(span, raw_ty, lt, mutbl)
|
||||
}
|
||||
}
|
||||
}
|
||||
Literal(ref p) => { p.to_ty(cx, span, self_ty, self_generics) }
|
||||
Self => {
|
||||
build::mk_ty_path_path(cx, span, self.to_path(cx, span, self_ty, self_generics))
|
||||
cx.ty_path(self.to_path(cx, span, self_ty, self_generics))
|
||||
}
|
||||
Tuple(ref fields) => {
|
||||
let ty = if fields.is_empty() {
|
||||
|
|
@ -143,17 +136,17 @@ pub impl Ty {
|
|||
ast::ty_tup(fields.map(|f| f.to_ty(cx, span, self_ty, self_generics)))
|
||||
};
|
||||
|
||||
build::mk_ty(cx, span, ty)
|
||||
cx.ty(span, ty)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn to_path(&self, cx: @ext_ctxt, span: span,
|
||||
fn to_path(&self, cx: @ExtCtxt, span: span,
|
||||
self_ty: ident, self_generics: &Generics) -> @ast::Path {
|
||||
match *self {
|
||||
Self => {
|
||||
let self_params = do self_generics.ty_params.map |ty_param| {
|
||||
build::mk_ty_path(cx, span, ~[ ty_param.ident ])
|
||||
cx.ty_ident(span, ty_param.ident)
|
||||
};
|
||||
let lifetime = if self_generics.lifetimes.is_empty() {
|
||||
None
|
||||
|
|
@ -161,8 +154,8 @@ pub impl Ty {
|
|||
Some(@*self_generics.lifetimes.get(0))
|
||||
};
|
||||
|
||||
build::mk_raw_path_(span, ~[self_ty], lifetime,
|
||||
opt_vec::take_vec(self_params))
|
||||
cx.path_all(span, false, ~[self_ty], lifetime,
|
||||
opt_vec::take_vec(self_params))
|
||||
}
|
||||
Literal(ref p) => {
|
||||
p.to_path(cx, span, self_ty, self_generics)
|
||||
|
|
@ -174,14 +167,14 @@ pub impl Ty {
|
|||
}
|
||||
|
||||
|
||||
fn mk_ty_param(cx: @ext_ctxt, span: span, name: ~str, bounds: ~[Path],
|
||||
fn mk_ty_param(cx: @ExtCtxt, span: span, name: &str, bounds: &[Path],
|
||||
self_ident: ident, self_generics: &Generics) -> ast::TyParam {
|
||||
let bounds = opt_vec::from(
|
||||
do bounds.map |b| {
|
||||
let path = b.to_path(cx, span, self_ident, self_generics);
|
||||
build::mk_trait_ty_param_bound_(cx, path)
|
||||
cx.typarambound(path)
|
||||
});
|
||||
build::mk_ty_param(cx, cx.ident_of(name), @bounds)
|
||||
cx.typaram(cx.ident_of(name), @bounds)
|
||||
}
|
||||
|
||||
fn mk_generics(lifetimes: ~[ast::Lifetime], ty_params: ~[ast::TyParam]) -> Generics {
|
||||
|
|
@ -192,33 +185,37 @@ fn mk_generics(lifetimes: ~[ast::Lifetime], ty_params: ~[ast::TyParam]) -> Gene
|
|||
}
|
||||
|
||||
/// Lifetimes and bounds on type parameters
|
||||
pub struct LifetimeBounds {
|
||||
lifetimes: ~[~str],
|
||||
bounds: ~[(~str, ~[Path])]
|
||||
pub struct LifetimeBounds<'self> {
|
||||
lifetimes: ~[&'self str],
|
||||
bounds: ~[(&'self str, ~[Path<'self>])]
|
||||
}
|
||||
|
||||
pub impl LifetimeBounds {
|
||||
fn empty() -> LifetimeBounds {
|
||||
pub impl<'self> LifetimeBounds<'self> {
|
||||
fn empty() -> LifetimeBounds<'static> {
|
||||
LifetimeBounds {
|
||||
lifetimes: ~[], bounds: ~[]
|
||||
}
|
||||
}
|
||||
fn to_generics(&self, cx: @ext_ctxt, span: span,
|
||||
fn to_generics(&self, cx: @ExtCtxt, span: span,
|
||||
self_ty: ident, self_generics: &Generics) -> Generics {
|
||||
let lifetimes = do self.lifetimes.map |<| {
|
||||
build::mk_lifetime(cx, span, cx.ident_of(lt))
|
||||
let lifetimes = do self.lifetimes.map |lt| {
|
||||
cx.lifetime(span, cx.ident_of(*lt))
|
||||
};
|
||||
let ty_params = do self.bounds.map |&(name, bounds)| {
|
||||
mk_ty_param(cx, span, name, bounds, self_ty, self_generics)
|
||||
let ty_params = do self.bounds.map |t| {
|
||||
match t {
|
||||
&(ref name, ref bounds) => {
|
||||
mk_ty_param(cx, span, *name, *bounds, self_ty, self_generics)
|
||||
}
|
||||
}
|
||||
};
|
||||
mk_generics(lifetimes, ty_params)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
pub fn get_explicit_self(cx: @ext_ctxt, span: span, self_ptr: &Option<PtrTy>)
|
||||
pub fn get_explicit_self(cx: @ExtCtxt, span: span, self_ptr: &Option<PtrTy>)
|
||||
-> (@expr, ast::explicit_self) {
|
||||
let self_path = build::make_self(cx, span);
|
||||
let self_path = cx.expr_self(span);
|
||||
match *self_ptr {
|
||||
None => {
|
||||
(self_path, respan(span, ast::sty_value))
|
||||
|
|
@ -230,12 +227,12 @@ pub fn get_explicit_self(cx: @ext_ctxt, span: span, self_ptr: &Option<PtrTy>)
|
|||
Owned => ast::sty_uniq(ast::m_imm),
|
||||
Managed(mutbl) => ast::sty_box(mutbl),
|
||||
Borrowed(ref lt, mutbl) => {
|
||||
let lt = lt.map(|s| @build::mk_lifetime(cx, span,
|
||||
cx.ident_of(*s)));
|
||||
let lt = lt.map(|s| @cx.lifetime(span,
|
||||
cx.ident_of(*s)));
|
||||
ast::sty_region(lt, mutbl)
|
||||
}
|
||||
});
|
||||
let self_expr = build::mk_deref(cx, span, self_path);
|
||||
let self_expr = cx.expr_deref(span, self_path);
|
||||
(self_expr, self_ty)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,9 +18,9 @@ use ast;
|
|||
use codemap::span;
|
||||
use ext::base::*;
|
||||
use ext::base;
|
||||
use ext::build::mk_base_str;
|
||||
use ext::build::AstBuilder;
|
||||
|
||||
pub fn expand_syntax_ext(cx: @ext_ctxt, sp: span, tts: &[ast::token_tree])
|
||||
pub fn expand_syntax_ext(cx: @ExtCtxt, sp: span, tts: &[ast::token_tree])
|
||||
-> base::MacResult {
|
||||
|
||||
let var = get_single_str_from_tts(cx, sp, tts, "env!");
|
||||
|
|
@ -29,8 +29,8 @@ pub fn expand_syntax_ext(cx: @ext_ctxt, sp: span, tts: &[ast::token_tree])
|
|||
// Option<str> rather than just an maybe-empty string.
|
||||
|
||||
let e = match os::getenv(var) {
|
||||
None => mk_base_str(cx, sp, ~""),
|
||||
Some(ref s) => mk_base_str(cx, sp, copy *s)
|
||||
None => cx.expr_str(sp, ~""),
|
||||
Some(ref s) => cx.expr_str(sp, copy *s)
|
||||
};
|
||||
MRExpr(e)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ use parse;
|
|||
use parse::{parse_item_from_source_str};
|
||||
|
||||
pub fn expand_expr(extsbox: @mut SyntaxEnv,
|
||||
cx: @ext_ctxt,
|
||||
cx: @ExtCtxt,
|
||||
e: &expr_,
|
||||
s: span,
|
||||
fld: @ast_fold,
|
||||
|
|
@ -109,7 +109,7 @@ pub fn expand_expr(extsbox: @mut SyntaxEnv,
|
|||
// NB: there is some redundancy between this and expand_item, below, and
|
||||
// they might benefit from some amount of semantic and language-UI merger.
|
||||
pub fn expand_mod_items(extsbox: @mut SyntaxEnv,
|
||||
cx: @ext_ctxt,
|
||||
cx: @ExtCtxt,
|
||||
module_: &ast::_mod,
|
||||
fld: @ast_fold,
|
||||
orig: @fn(&ast::_mod, @ast_fold) -> ast::_mod)
|
||||
|
|
@ -161,7 +161,7 @@ macro_rules! with_exts_frame (
|
|||
|
||||
// When we enter a module, record it, for the sake of `module!`
|
||||
pub fn expand_item(extsbox: @mut SyntaxEnv,
|
||||
cx: @ext_ctxt,
|
||||
cx: @ExtCtxt,
|
||||
it: @ast::item,
|
||||
fld: @ast_fold,
|
||||
orig: @fn(@ast::item, @ast_fold) -> Option<@ast::item>)
|
||||
|
|
@ -227,7 +227,7 @@ macro_rules! without_macro_scoping(
|
|||
// Support for item-position macro invocations, exactly the same
|
||||
// logic as for expression-position macro invocations.
|
||||
pub fn expand_item_mac(extsbox: @mut SyntaxEnv,
|
||||
cx: @ext_ctxt, it: @ast::item,
|
||||
cx: @ExtCtxt, it: @ast::item,
|
||||
fld: @ast_fold)
|
||||
-> Option<@ast::item> {
|
||||
let (pth, tts) = match it.node {
|
||||
|
|
@ -294,7 +294,7 @@ pub fn expand_item_mac(extsbox: @mut SyntaxEnv,
|
|||
|
||||
// expand a stmt
|
||||
pub fn expand_stmt(extsbox: @mut SyntaxEnv,
|
||||
cx: @ext_ctxt,
|
||||
cx: @ExtCtxt,
|
||||
s: &stmt_,
|
||||
sp: span,
|
||||
fld: @ast_fold,
|
||||
|
|
@ -360,7 +360,7 @@ pub fn expand_stmt(extsbox: @mut SyntaxEnv,
|
|||
|
||||
|
||||
pub fn expand_block(extsbox: @mut SyntaxEnv,
|
||||
cx: @ext_ctxt,
|
||||
cx: @ExtCtxt,
|
||||
blk: &blk_,
|
||||
sp: span,
|
||||
fld: @ast_fold,
|
||||
|
|
@ -381,7 +381,7 @@ pub fn expand_block(extsbox: @mut SyntaxEnv,
|
|||
}
|
||||
}
|
||||
|
||||
pub fn new_span(cx: @ext_ctxt, sp: span) -> span {
|
||||
pub fn new_span(cx: @ExtCtxt, sp: span) -> span {
|
||||
/* this discards information in the case of macro-defining macros */
|
||||
return span {lo: sp.lo, hi: sp.hi, expn_info: cx.backtrace()};
|
||||
}
|
||||
|
|
@ -590,7 +590,7 @@ pub fn expand_crate(parse_sess: @mut parse::ParseSess,
|
|||
// every method/element of AstFoldFns in fold.rs.
|
||||
let extsbox = @mut syntax_expander_table();
|
||||
let afp = default_ast_fold();
|
||||
let cx: @ext_ctxt = mk_ctxt(parse_sess, copy cfg);
|
||||
let cx = ExtCtxt::new(parse_sess, copy cfg);
|
||||
let f_pre = @AstFoldFns {
|
||||
fold_expr: |expr,span,recur|
|
||||
expand_expr(extsbox, cx, expr, span, recur, afp.fold_expr),
|
||||
|
|
|
|||
|
|
@ -18,12 +18,11 @@ use ast;
|
|||
use codemap::span;
|
||||
use ext::base::*;
|
||||
use ext::base;
|
||||
use ext::build;
|
||||
use ext::build::*;
|
||||
use ext::build::AstBuilder;
|
||||
|
||||
use core::unstable::extfmt::ct::*;
|
||||
|
||||
pub fn expand_syntax_ext(cx: @ext_ctxt, sp: span, tts: &[ast::token_tree])
|
||||
pub fn expand_syntax_ext(cx: @ExtCtxt, sp: span, tts: &[ast::token_tree])
|
||||
-> base::MacResult {
|
||||
let args = get_exprs_from_tts(cx, tts);
|
||||
if args.len() == 0 {
|
||||
|
|
@ -34,7 +33,7 @@ pub fn expand_syntax_ext(cx: @ext_ctxt, sp: span, tts: &[ast::token_tree])
|
|||
~"first argument to fmt! must be a string literal.");
|
||||
let fmtspan = args[0].span;
|
||||
debug!("Format string: %s", fmt);
|
||||
fn parse_fmt_err_(cx: @ext_ctxt, sp: span, msg: &str) -> ! {
|
||||
fn parse_fmt_err_(cx: @ExtCtxt, sp: span, msg: &str) -> ! {
|
||||
cx.span_fatal(sp, msg);
|
||||
}
|
||||
let parse_fmt_err: @fn(&str) -> ! = |s| parse_fmt_err_(cx, fmtspan, s);
|
||||
|
|
@ -46,23 +45,23 @@ pub fn expand_syntax_ext(cx: @ext_ctxt, sp: span, tts: &[ast::token_tree])
|
|||
// probably be factored out in common with other code that builds
|
||||
// expressions. Also: Cleanup the naming of these functions.
|
||||
// Note: Moved many of the common ones to build.rs --kevina
|
||||
fn pieces_to_expr(cx: @ext_ctxt, sp: span,
|
||||
fn pieces_to_expr(cx: @ExtCtxt, sp: span,
|
||||
pieces: ~[Piece], args: ~[@ast::expr])
|
||||
-> @ast::expr {
|
||||
fn make_path_vec(cx: @ext_ctxt, ident: &str) -> ~[ast::ident] {
|
||||
fn make_path_vec(cx: @ExtCtxt, ident: &str) -> ~[ast::ident] {
|
||||
let intr = cx.parse_sess().interner;
|
||||
return ~[intr.intern("unstable"), intr.intern("extfmt"),
|
||||
intr.intern("rt"), intr.intern(ident)];
|
||||
}
|
||||
fn make_rt_path_expr(cx: @ext_ctxt, sp: span, nm: &str) -> @ast::expr {
|
||||
fn make_rt_path_expr(cx: @ExtCtxt, sp: span, nm: &str) -> @ast::expr {
|
||||
let path = make_path_vec(cx, nm);
|
||||
return mk_path_global(cx, sp, path);
|
||||
cx.expr_path(cx.path_global(sp, path))
|
||||
}
|
||||
// Produces an AST expression that represents a RT::conv record,
|
||||
// which tells the RT::conv* functions how to perform the conversion
|
||||
|
||||
fn make_rt_conv_expr(cx: @ext_ctxt, sp: span, cnv: &Conv) -> @ast::expr {
|
||||
fn make_flags(cx: @ext_ctxt, sp: span, flags: &[Flag]) -> @ast::expr {
|
||||
fn make_rt_conv_expr(cx: @ExtCtxt, sp: span, cnv: &Conv) -> @ast::expr {
|
||||
fn make_flags(cx: @ExtCtxt, sp: span, flags: &[Flag]) -> @ast::expr {
|
||||
let mut tmp_expr = make_rt_path_expr(cx, sp, "flag_none");
|
||||
for flags.each |f| {
|
||||
let fstr = match *f {
|
||||
|
|
@ -72,26 +71,26 @@ fn pieces_to_expr(cx: @ext_ctxt, sp: span,
|
|||
FlagSignAlways => "flag_sign_always",
|
||||
FlagAlternate => "flag_alternate"
|
||||
};
|
||||
tmp_expr = mk_binary(cx, sp, ast::bitor, tmp_expr,
|
||||
make_rt_path_expr(cx, sp, fstr));
|
||||
tmp_expr = cx.expr_binary(sp, ast::bitor, tmp_expr,
|
||||
make_rt_path_expr(cx, sp, fstr));
|
||||
}
|
||||
return tmp_expr;
|
||||
}
|
||||
fn make_count(cx: @ext_ctxt, sp: span, cnt: Count) -> @ast::expr {
|
||||
fn make_count(cx: @ExtCtxt, sp: span, cnt: Count) -> @ast::expr {
|
||||
match cnt {
|
||||
CountImplied => {
|
||||
return make_rt_path_expr(cx, sp, "CountImplied");
|
||||
}
|
||||
CountIs(c) => {
|
||||
let count_lit = mk_uint(cx, sp, c as uint);
|
||||
let count_lit = cx.expr_uint(sp, c as uint);
|
||||
let count_is_path = make_path_vec(cx, "CountIs");
|
||||
let count_is_args = ~[count_lit];
|
||||
return mk_call_global(cx, sp, count_is_path, count_is_args);
|
||||
return cx.expr_call_global(sp, count_is_path, count_is_args);
|
||||
}
|
||||
_ => cx.span_unimpl(sp, "unimplemented fmt! conversion")
|
||||
}
|
||||
}
|
||||
fn make_ty(cx: @ext_ctxt, sp: span, t: Ty) -> @ast::expr {
|
||||
fn make_ty(cx: @ExtCtxt, sp: span, t: Ty) -> @ast::expr {
|
||||
let rt_type = match t {
|
||||
TyHex(c) => match c {
|
||||
CaseUpper => "TyHexUpper",
|
||||
|
|
@ -103,27 +102,18 @@ fn pieces_to_expr(cx: @ext_ctxt, sp: span,
|
|||
};
|
||||
return make_rt_path_expr(cx, sp, rt_type);
|
||||
}
|
||||
fn make_conv_struct(cx: @ext_ctxt, sp: span, flags_expr: @ast::expr,
|
||||
fn make_conv_struct(cx: @ExtCtxt, sp: span, flags_expr: @ast::expr,
|
||||
width_expr: @ast::expr, precision_expr: @ast::expr,
|
||||
ty_expr: @ast::expr) -> @ast::expr {
|
||||
let intr = cx.parse_sess().interner;
|
||||
mk_global_struct_e(
|
||||
cx,
|
||||
cx.expr_struct(
|
||||
sp,
|
||||
make_path_vec(cx, "Conv"),
|
||||
cx.path_global(sp, make_path_vec(cx, "Conv")),
|
||||
~[
|
||||
build::Field {
|
||||
ident: intr.intern("flags"), ex: flags_expr
|
||||
},
|
||||
build::Field {
|
||||
ident: intr.intern("width"), ex: width_expr
|
||||
},
|
||||
build::Field {
|
||||
ident: intr.intern("precision"), ex: precision_expr
|
||||
},
|
||||
build::Field {
|
||||
ident: intr.intern("ty"), ex: ty_expr
|
||||
},
|
||||
cx.field_imm(sp, intr.intern("flags"), flags_expr),
|
||||
cx.field_imm(sp, intr.intern("width"), width_expr),
|
||||
cx.field_imm(sp, intr.intern("precision"), precision_expr),
|
||||
cx.field_imm(sp, intr.intern("ty"), ty_expr)
|
||||
]
|
||||
)
|
||||
}
|
||||
|
|
@ -134,16 +124,16 @@ fn pieces_to_expr(cx: @ext_ctxt, sp: span,
|
|||
make_conv_struct(cx, sp, rt_conv_flags, rt_conv_width,
|
||||
rt_conv_precision, rt_conv_ty)
|
||||
}
|
||||
fn make_conv_call(cx: @ext_ctxt, sp: span, conv_type: &str, cnv: &Conv,
|
||||
fn make_conv_call(cx: @ExtCtxt, sp: span, conv_type: &str, cnv: &Conv,
|
||||
arg: @ast::expr, buf: @ast::expr) -> @ast::expr {
|
||||
let fname = ~"conv_" + conv_type;
|
||||
let path = make_path_vec(cx, fname);
|
||||
let cnv_expr = make_rt_conv_expr(cx, sp, cnv);
|
||||
let args = ~[cnv_expr, arg, buf];
|
||||
return mk_call_global(cx, arg.span, path, args);
|
||||
cx.expr_call_global(arg.span, path, args)
|
||||
}
|
||||
|
||||
fn make_new_conv(cx: @ext_ctxt, sp: span, cnv: &Conv,
|
||||
fn make_new_conv(cx: @ExtCtxt, sp: span, cnv: &Conv,
|
||||
arg: @ast::expr, buf: @ast::expr) -> @ast::expr {
|
||||
fn is_signed_type(cnv: &Conv) -> bool {
|
||||
match cnv.ty {
|
||||
|
|
@ -198,10 +188,10 @@ fn pieces_to_expr(cx: @ext_ctxt, sp: span,
|
|||
TyChar => ("char", arg),
|
||||
TyBits | TyOctal | TyHex(_) | TyInt(Unsigned) => ("uint", arg),
|
||||
TyFloat => ("float", arg),
|
||||
TyPoly => ("poly", mk_addr_of(cx, sp, arg))
|
||||
TyPoly => ("poly", cx.expr_addr_of(sp, arg))
|
||||
};
|
||||
return make_conv_call(cx, arg.span, name, cnv, actual_arg,
|
||||
mk_mut_addr_of(cx, arg.span, buf));
|
||||
cx.expr_mut_addr_of(arg.span, buf));
|
||||
}
|
||||
fn log_conv(c: &Conv) {
|
||||
debug!("Building conversion:");
|
||||
|
|
@ -259,7 +249,7 @@ fn pieces_to_expr(cx: @ext_ctxt, sp: span,
|
|||
|
||||
/* 'ident' is the local buffer building up the result of fmt! */
|
||||
let ident = cx.parse_sess().interner.intern("__fmtbuf");
|
||||
let buf = || mk_path(cx, fmt_sp, ~[ident]);
|
||||
let buf = || cx.expr_ident(fmt_sp, ident);
|
||||
let str_ident = cx.parse_sess().interner.intern("str");
|
||||
let push_ident = cx.parse_sess().interner.intern("push_str");
|
||||
let mut stms = ~[];
|
||||
|
|
@ -276,14 +266,14 @@ fn pieces_to_expr(cx: @ext_ctxt, sp: span,
|
|||
buffer with it directly. If it's actually the only piece,
|
||||
then there's no need for it to be mutable */
|
||||
if i == 0 {
|
||||
stms.push(mk_local(cx, fmt_sp, npieces > 1, ident, mk_uniq_str(cx, fmt_sp, s)));
|
||||
stms.push(cx.stmt_let(fmt_sp, npieces > 1,
|
||||
ident, cx.expr_str_uniq(fmt_sp, s)));
|
||||
} else {
|
||||
let args = ~[mk_mut_addr_of(cx, fmt_sp, buf()), mk_base_str(cx, fmt_sp, s)];
|
||||
let call = mk_call_global(cx,
|
||||
fmt_sp,
|
||||
~[str_ident, push_ident],
|
||||
args);
|
||||
stms.push(mk_stmt(cx, fmt_sp, call));
|
||||
let args = ~[cx.expr_mut_addr_of(fmt_sp, buf()), cx.expr_str(fmt_sp, s)];
|
||||
let call = cx.expr_call_global(fmt_sp,
|
||||
~[str_ident, push_ident],
|
||||
args);
|
||||
stms.push(cx.stmt_expr(call));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -300,12 +290,11 @@ fn pieces_to_expr(cx: @ext_ctxt, sp: span,
|
|||
/* If the first portion is a conversion, then the local buffer
|
||||
must be initialized as an empty string */
|
||||
if i == 0 {
|
||||
stms.push(mk_local(cx, fmt_sp, true, ident,
|
||||
mk_uniq_str(cx, fmt_sp, ~"")));
|
||||
stms.push(cx.stmt_let(fmt_sp, true, ident,
|
||||
cx.expr_str_uniq(fmt_sp, ~"")));
|
||||
}
|
||||
stms.push(mk_stmt(cx, fmt_sp,
|
||||
make_new_conv(cx, fmt_sp, conv,
|
||||
args[n], buf())));
|
||||
stms.push(cx.stmt_expr(make_new_conv(cx, fmt_sp, conv,
|
||||
args[n], buf())));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -317,5 +306,5 @@ fn pieces_to_expr(cx: @ext_ctxt, sp: span,
|
|||
nargs, expected_nargs));
|
||||
}
|
||||
|
||||
return mk_block(cx, fmt_sp, ~[], stms, Some(buf()));
|
||||
cx.expr_blk(cx.blk(fmt_sp, stms, Some(buf())))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ use ext::base::*;
|
|||
use ext::base;
|
||||
use print;
|
||||
|
||||
pub fn expand_syntax_ext(cx: @ext_ctxt,
|
||||
pub fn expand_syntax_ext(cx: @ExtCtxt,
|
||||
sp: codemap::span,
|
||||
tt: &[ast::token_tree])
|
||||
-> base::MacResult {
|
||||
|
|
|
|||
|
|
@ -13,16 +13,10 @@
|
|||
// To start with, it will be use dummy spans, but it might someday do
|
||||
// something smarter.
|
||||
|
||||
use abi::AbiSet;
|
||||
use ast::ident;
|
||||
use ast;
|
||||
use ast_util;
|
||||
use codemap::{span, respan, dummy_sp, spanned};
|
||||
use codemap;
|
||||
use ext::base::ext_ctxt;
|
||||
use ext::quote::rt::*;
|
||||
use opt_vec;
|
||||
use opt_vec::OptVec;
|
||||
use codemap::span;
|
||||
// use ext::quote::rt::*;
|
||||
|
||||
// Transitional reexports so qquote can find the paths it is looking for
|
||||
mod syntax {
|
||||
|
|
@ -66,377 +60,3 @@ impl append_types for @ast::Path {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub trait ext_ctxt_ast_builder {
|
||||
fn ty_param(&self, id: ast::ident, bounds: @OptVec<ast::TyParamBound>)
|
||||
-> ast::TyParam;
|
||||
fn arg(&self, name: ident, ty: @ast::Ty) -> ast::arg;
|
||||
fn expr_block(&self, e: @ast::expr) -> ast::blk;
|
||||
fn fn_decl(&self, inputs: ~[ast::arg], output: @ast::Ty) -> ast::fn_decl;
|
||||
fn item(&self, name: ident, span: span, node: ast::item_) -> @ast::item;
|
||||
fn item_fn_poly(&self,
|
||||
ame: ident,
|
||||
inputs: ~[ast::arg],
|
||||
output: @ast::Ty,
|
||||
generics: Generics,
|
||||
body: ast::blk) -> @ast::item;
|
||||
fn item_fn(&self,
|
||||
name: ident,
|
||||
inputs: ~[ast::arg],
|
||||
output: @ast::Ty,
|
||||
body: ast::blk) -> @ast::item;
|
||||
fn item_enum_poly(&self,
|
||||
name: ident,
|
||||
span: span,
|
||||
enum_definition: ast::enum_def,
|
||||
generics: Generics) -> @ast::item;
|
||||
fn item_enum(&self,
|
||||
name: ident,
|
||||
span: span,
|
||||
enum_definition: ast::enum_def) -> @ast::item;
|
||||
fn item_struct_poly(&self,
|
||||
name: ident,
|
||||
span: span,
|
||||
struct_def: ast::struct_def,
|
||||
generics: Generics) -> @ast::item;
|
||||
fn item_struct(&self,
|
||||
name: ident,
|
||||
span: span,
|
||||
struct_def: ast::struct_def) -> @ast::item;
|
||||
fn struct_expr(&self,
|
||||
path: @ast::Path,
|
||||
fields: ~[ast::field]) -> @ast::expr;
|
||||
fn variant(&self,
|
||||
name: ident,
|
||||
span: span,
|
||||
tys: ~[@ast::Ty]) -> ast::variant;
|
||||
fn item_mod(&self,
|
||||
name: ident,
|
||||
span: span,
|
||||
items: ~[@ast::item]) -> @ast::item;
|
||||
fn ty_path_ast_builder(&self, path: @ast::Path) -> @ast::Ty;
|
||||
fn item_ty_poly(&self,
|
||||
name: ident,
|
||||
span: span,
|
||||
ty: @ast::Ty,
|
||||
generics: Generics) -> @ast::item;
|
||||
fn item_ty(&self, name: ident, span: span, ty: @ast::Ty) -> @ast::item;
|
||||
fn ty_vars(&self, ty_params: &OptVec<ast::TyParam>) -> ~[@ast::Ty];
|
||||
fn ty_vars_global(&self, ty_params: &OptVec<ast::TyParam>) -> ~[@ast::Ty];
|
||||
fn ty_field_imm(&self, name: ident, ty: @ast::Ty) -> ast::ty_field;
|
||||
fn field_imm(&self, name: ident, e: @ast::expr) -> ast::field;
|
||||
fn block(&self, stmts: ~[@ast::stmt], e: @ast::expr) -> ast::blk;
|
||||
fn stmt_let(&self, ident: ident, e: @ast::expr) -> @ast::stmt;
|
||||
fn stmt_expr(&self, e: @ast::expr) -> @ast::stmt;
|
||||
fn block_expr(&self, b: ast::blk) -> @ast::expr;
|
||||
fn ty_option(&self, ty: @ast::Ty) -> @ast::Ty;
|
||||
fn ty_infer(&self) -> @ast::Ty;
|
||||
fn ty_nil_ast_builder(&self) -> @ast::Ty;
|
||||
fn strip_bounds(&self, bounds: &Generics) -> Generics;
|
||||
}
|
||||
|
||||
impl ext_ctxt_ast_builder for @ext_ctxt {
|
||||
fn ty_option(&self, ty: @ast::Ty) -> @ast::Ty {
|
||||
self.ty_path_ast_builder(path_global(~[
|
||||
self.ident_of("core"),
|
||||
self.ident_of("option"),
|
||||
self.ident_of("Option")
|
||||
], dummy_sp()).add_ty(ty))
|
||||
}
|
||||
|
||||
fn block_expr(&self, b: ast::blk) -> @ast::expr {
|
||||
@expr {
|
||||
id: self.next_id(),
|
||||
callee_id: self.next_id(),
|
||||
node: ast::expr_block(b),
|
||||
span: dummy_sp(),
|
||||
}
|
||||
}
|
||||
|
||||
fn stmt_expr(&self, e: @ast::expr) -> @ast::stmt {
|
||||
@spanned { node: ast::stmt_expr(e, self.next_id()),
|
||||
span: dummy_sp()}
|
||||
}
|
||||
|
||||
fn stmt_let(&self, ident: ident, e: @ast::expr) -> @ast::stmt {
|
||||
let ext_cx = *self;
|
||||
quote_stmt!( let $ident = $e; )
|
||||
}
|
||||
|
||||
fn field_imm(&self, name: ident, e: @ast::expr) -> ast::field {
|
||||
spanned {
|
||||
node: ast::field_ { mutbl: ast::m_imm, ident: name, expr: e },
|
||||
span: dummy_sp(),
|
||||
}
|
||||
}
|
||||
|
||||
fn ty_field_imm(&self, name: ident, ty: @ast::Ty) -> ast::ty_field {
|
||||
spanned {
|
||||
node: ast::ty_field_ {
|
||||
ident: name,
|
||||
mt: ast::mt { ty: ty, mutbl: ast::m_imm },
|
||||
},
|
||||
span: dummy_sp(),
|
||||
}
|
||||
}
|
||||
|
||||
fn ty_infer(&self) -> @ast::Ty {
|
||||
@ast::Ty {
|
||||
id: self.next_id(),
|
||||
node: ast::ty_infer,
|
||||
span: dummy_sp(),
|
||||
}
|
||||
}
|
||||
|
||||
fn ty_param(&self, id: ast::ident, bounds: @OptVec<ast::TyParamBound>)
|
||||
-> ast::TyParam
|
||||
{
|
||||
ast::TyParam { ident: id, id: self.next_id(), bounds: bounds }
|
||||
}
|
||||
|
||||
fn arg(&self, name: ident, ty: @ast::Ty) -> ast::arg {
|
||||
ast::arg {
|
||||
is_mutbl: false,
|
||||
ty: ty,
|
||||
pat: @ast::pat {
|
||||
id: self.next_id(),
|
||||
node: ast::pat_ident(
|
||||
ast::bind_by_copy,
|
||||
ast_util::ident_to_path(dummy_sp(), name),
|
||||
None),
|
||||
span: dummy_sp(),
|
||||
},
|
||||
id: self.next_id(),
|
||||
}
|
||||
}
|
||||
|
||||
fn block(&self, stmts: ~[@ast::stmt], e: @ast::expr) -> ast::blk {
|
||||
let blk = ast::blk_ {
|
||||
view_items: ~[],
|
||||
stmts: stmts,
|
||||
expr: Some(e),
|
||||
id: self.next_id(),
|
||||
rules: ast::default_blk,
|
||||
};
|
||||
|
||||
spanned { node: blk, span: dummy_sp() }
|
||||
}
|
||||
|
||||
fn expr_block(&self, e: @ast::expr) -> ast::blk {
|
||||
self.block(~[], e)
|
||||
}
|
||||
|
||||
fn fn_decl(&self, inputs: ~[ast::arg],
|
||||
output: @ast::Ty) -> ast::fn_decl {
|
||||
ast::fn_decl {
|
||||
inputs: inputs,
|
||||
output: output,
|
||||
cf: ast::return_val,
|
||||
}
|
||||
}
|
||||
|
||||
fn item(&self, name: ident, span: span,
|
||||
node: ast::item_) -> @ast::item {
|
||||
|
||||
// XXX: Would be nice if our generated code didn't violate
|
||||
// Rust coding conventions
|
||||
let non_camel_case_attribute = respan(dummy_sp(), ast::attribute_ {
|
||||
style: ast::attr_outer,
|
||||
value: @respan(dummy_sp(),
|
||||
ast::meta_list(@~"allow", ~[
|
||||
@respan(dummy_sp(),
|
||||
ast::meta_word(
|
||||
@~"non_camel_case_types"))
|
||||
])),
|
||||
is_sugared_doc: false
|
||||
});
|
||||
|
||||
@ast::item { ident: name,
|
||||
attrs: ~[non_camel_case_attribute],
|
||||
id: self.next_id(),
|
||||
node: node,
|
||||
vis: ast::public,
|
||||
span: span }
|
||||
}
|
||||
|
||||
fn item_fn_poly(&self, name: ident,
|
||||
inputs: ~[ast::arg],
|
||||
output: @ast::Ty,
|
||||
generics: Generics,
|
||||
body: ast::blk) -> @ast::item {
|
||||
self.item(name,
|
||||
dummy_sp(),
|
||||
ast::item_fn(self.fn_decl(inputs, output),
|
||||
ast::impure_fn,
|
||||
AbiSet::Rust(),
|
||||
generics,
|
||||
body))
|
||||
}
|
||||
|
||||
fn item_fn(&self,
|
||||
name: ident,
|
||||
inputs: ~[ast::arg],
|
||||
output: @ast::Ty,
|
||||
body: ast::blk
|
||||
) -> @ast::item {
|
||||
self.item_fn_poly(
|
||||
name,
|
||||
inputs,
|
||||
output,
|
||||
ast_util::empty_generics(),
|
||||
body
|
||||
)
|
||||
}
|
||||
|
||||
fn item_enum_poly(&self, name: ident, span: span,
|
||||
enum_definition: ast::enum_def,
|
||||
generics: Generics) -> @ast::item {
|
||||
self.item(name, span, ast::item_enum(enum_definition, generics))
|
||||
}
|
||||
|
||||
fn item_enum(&self, name: ident, span: span,
|
||||
enum_definition: ast::enum_def) -> @ast::item {
|
||||
self.item_enum_poly(name, span, enum_definition,
|
||||
ast_util::empty_generics())
|
||||
}
|
||||
|
||||
fn item_struct(
|
||||
&self, name: ident,
|
||||
span: span,
|
||||
struct_def: ast::struct_def
|
||||
) -> @ast::item {
|
||||
self.item_struct_poly(
|
||||
name,
|
||||
span,
|
||||
struct_def,
|
||||
ast_util::empty_generics()
|
||||
)
|
||||
}
|
||||
|
||||
fn item_struct_poly(
|
||||
&self,
|
||||
name: ident,
|
||||
span: span,
|
||||
struct_def: ast::struct_def,
|
||||
generics: Generics
|
||||
) -> @ast::item {
|
||||
self.item(name, span, ast::item_struct(@struct_def, generics))
|
||||
}
|
||||
|
||||
fn struct_expr(&self, path: @ast::Path,
|
||||
fields: ~[ast::field]) -> @ast::expr {
|
||||
@ast::expr {
|
||||
id: self.next_id(),
|
||||
callee_id: self.next_id(),
|
||||
node: ast::expr_struct(path, fields, None),
|
||||
span: dummy_sp()
|
||||
}
|
||||
}
|
||||
|
||||
fn variant(&self, name: ident, span: span,
|
||||
tys: ~[@ast::Ty]) -> ast::variant {
|
||||
let args = do tys.map |ty| {
|
||||
ast::variant_arg { ty: *ty, id: self.next_id() }
|
||||
};
|
||||
|
||||
spanned {
|
||||
node: ast::variant_ {
|
||||
name: name,
|
||||
attrs: ~[],
|
||||
kind: ast::tuple_variant_kind(args),
|
||||
id: self.next_id(),
|
||||
disr_expr: None,
|
||||
vis: ast::public
|
||||
},
|
||||
span: span,
|
||||
}
|
||||
}
|
||||
|
||||
fn item_mod(&self, name: ident, span: span,
|
||||
items: ~[@ast::item]) -> @ast::item {
|
||||
|
||||
// XXX: Total hack: import `core::kinds::Owned` to work around a
|
||||
// parser bug whereby `fn f<T:::kinds::Owned>` doesn't parse.
|
||||
let vi = ast::view_item_use(~[
|
||||
@codemap::spanned {
|
||||
node: ast::view_path_simple(
|
||||
self.ident_of("Owned"),
|
||||
path(
|
||||
~[
|
||||
self.ident_of("core"),
|
||||
self.ident_of("kinds"),
|
||||
self.ident_of("Owned")
|
||||
],
|
||||
codemap::dummy_sp()
|
||||
),
|
||||
self.next_id()
|
||||
),
|
||||
span: codemap::dummy_sp()
|
||||
}
|
||||
]);
|
||||
let vi = @ast::view_item {
|
||||
node: vi,
|
||||
attrs: ~[],
|
||||
vis: ast::private,
|
||||
span: codemap::dummy_sp()
|
||||
};
|
||||
|
||||
self.item(
|
||||
name,
|
||||
span,
|
||||
ast::item_mod(ast::_mod {
|
||||
view_items: ~[vi],
|
||||
items: items,
|
||||
})
|
||||
)
|
||||
}
|
||||
|
||||
fn ty_path_ast_builder(&self, path: @ast::Path) -> @ast::Ty {
|
||||
@ast::Ty {
|
||||
id: self.next_id(),
|
||||
node: ast::ty_path(path, self.next_id()),
|
||||
span: path.span,
|
||||
}
|
||||
}
|
||||
|
||||
fn ty_nil_ast_builder(&self) -> @ast::Ty {
|
||||
@ast::Ty {
|
||||
id: self.next_id(),
|
||||
node: ast::ty_nil,
|
||||
span: dummy_sp(),
|
||||
}
|
||||
}
|
||||
|
||||
fn strip_bounds(&self, generics: &Generics) -> Generics {
|
||||
let no_bounds = @opt_vec::Empty;
|
||||
let new_params = do generics.ty_params.map |ty_param| {
|
||||
ast::TyParam { bounds: no_bounds, ..copy *ty_param }
|
||||
};
|
||||
Generics {
|
||||
ty_params: new_params,
|
||||
.. copy *generics
|
||||
}
|
||||
}
|
||||
|
||||
fn item_ty_poly(&self, name: ident, span: span, ty: @ast::Ty,
|
||||
generics: Generics) -> @ast::item {
|
||||
self.item(name, span, ast::item_ty(ty, generics))
|
||||
}
|
||||
|
||||
fn item_ty(&self, name: ident, span: span, ty: @ast::Ty) -> @ast::item {
|
||||
self.item_ty_poly(name, span, ty, ast_util::empty_generics())
|
||||
}
|
||||
|
||||
fn ty_vars(&self, ty_params: &OptVec<ast::TyParam>) -> ~[@ast::Ty] {
|
||||
opt_vec::take_vec(
|
||||
ty_params.map(|p| self.ty_path_ast_builder(
|
||||
path(~[p.ident], dummy_sp()))))
|
||||
}
|
||||
|
||||
fn ty_vars_global(&self,
|
||||
ty_params: &OptVec<ast::TyParam>) -> ~[@ast::Ty] {
|
||||
opt_vec::take_vec(
|
||||
ty_params.map(|p| self.ty_path_ast_builder(
|
||||
path(~[p.ident], dummy_sp()))))
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,11 +31,11 @@ that.
|
|||
|
||||
use ast;
|
||||
use codemap::span;
|
||||
use ext::base::ext_ctxt;
|
||||
use ext::base::ExtCtxt;
|
||||
use ext::pipes::proto::{state, protocol, next_state};
|
||||
use ext::pipes::proto;
|
||||
|
||||
impl proto::visitor<(), (), ()> for @ext_ctxt {
|
||||
impl proto::visitor<(), (), ()> for @ExtCtxt {
|
||||
fn visit_proto(&self, _proto: protocol, _states: &[()]) { }
|
||||
|
||||
fn visit_state(&self, state: state, _m: &[()]) {
|
||||
|
|
|
|||
|
|
@ -37,12 +37,12 @@ updating the states using rule (2) until there are no changes.
|
|||
|
||||
*/
|
||||
|
||||
use ext::base::ext_ctxt;
|
||||
use ext::base::ExtCtxt;
|
||||
use ext::pipes::proto::{protocol_};
|
||||
|
||||
use std::bitv::Bitv;
|
||||
|
||||
pub fn analyze(proto: @mut protocol_, _cx: @ext_ctxt) {
|
||||
pub fn analyze(proto: @mut protocol_, _cx: @ExtCtxt) {
|
||||
debug!("initializing colive analysis");
|
||||
let num_states = proto.num_states();
|
||||
let mut colive = do (copy proto.states).map_to_vec |state| {
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ FIXME (#3072) - This is still incomplete.
|
|||
use ast;
|
||||
use codemap::span;
|
||||
use ext::base;
|
||||
use ext::base::ext_ctxt;
|
||||
use ext::base::ExtCtxt;
|
||||
use ext::pipes::parse_proto::proto_parser;
|
||||
use ext::pipes::pipec::gen_init;
|
||||
use ext::pipes::proto::visit;
|
||||
|
|
@ -63,7 +63,7 @@ pub mod check;
|
|||
pub mod liveness;
|
||||
|
||||
|
||||
pub fn expand_proto(cx: @ext_ctxt, _sp: span, id: ast::ident,
|
||||
pub fn expand_proto(cx: @ExtCtxt, _sp: span, id: ast::ident,
|
||||
tt: ~[ast::token_tree]) -> base::MacResult {
|
||||
let sess = cx.parse_sess();
|
||||
let cfg = cx.cfg();
|
||||
|
|
|
|||
|
|
@ -12,8 +12,9 @@
|
|||
|
||||
use ast;
|
||||
use codemap::{dummy_sp, spanned};
|
||||
use ext::base::ext_ctxt;
|
||||
use ext::pipes::ast_builder::{append_types, ext_ctxt_ast_builder, path};
|
||||
use ext::base::ExtCtxt;
|
||||
use ext::build::AstBuilder;
|
||||
use ext::pipes::ast_builder::{append_types, path};
|
||||
use ext::pipes::ast_builder::{path_global};
|
||||
use ext::pipes::proto::*;
|
||||
use ext::quote::rt::*;
|
||||
|
|
@ -21,27 +22,27 @@ use opt_vec;
|
|||
use opt_vec::OptVec;
|
||||
|
||||
pub trait gen_send {
|
||||
fn gen_send(&mut self, cx: @ext_ctxt, try: bool) -> @ast::item;
|
||||
fn to_ty(&mut self, cx: @ext_ctxt) -> @ast::Ty;
|
||||
fn gen_send(&mut self, cx: @ExtCtxt, try: bool) -> @ast::item;
|
||||
fn to_ty(&mut self, cx: @ExtCtxt) -> @ast::Ty;
|
||||
}
|
||||
|
||||
pub trait to_type_decls {
|
||||
fn to_type_decls(&self, cx: @ext_ctxt) -> ~[@ast::item];
|
||||
fn to_endpoint_decls(&self, cx: @ext_ctxt,
|
||||
fn to_type_decls(&self, cx: @ExtCtxt) -> ~[@ast::item];
|
||||
fn to_endpoint_decls(&self, cx: @ExtCtxt,
|
||||
dir: direction) -> ~[@ast::item];
|
||||
}
|
||||
|
||||
pub trait gen_init {
|
||||
fn gen_init(&self, cx: @ext_ctxt) -> @ast::item;
|
||||
fn compile(&self, cx: @ext_ctxt) -> @ast::item;
|
||||
fn buffer_ty_path(&self, cx: @ext_ctxt) -> @ast::Ty;
|
||||
fn gen_buffer_type(&self, cx: @ext_ctxt) -> @ast::item;
|
||||
fn gen_buffer_init(&self, ext_cx: @ext_ctxt) -> @ast::expr;
|
||||
fn gen_init_bounded(&self, ext_cx: @ext_ctxt) -> @ast::expr;
|
||||
fn gen_init(&self, cx: @ExtCtxt) -> @ast::item;
|
||||
fn compile(&self, cx: @ExtCtxt) -> @ast::item;
|
||||
fn buffer_ty_path(&self, cx: @ExtCtxt) -> @ast::Ty;
|
||||
fn gen_buffer_type(&self, cx: @ExtCtxt) -> @ast::item;
|
||||
fn gen_buffer_init(&self, ext_cx: @ExtCtxt) -> @ast::expr;
|
||||
fn gen_init_bounded(&self, ext_cx: @ExtCtxt) -> @ast::expr;
|
||||
}
|
||||
|
||||
impl gen_send for message {
|
||||
fn gen_send(&mut self, cx: @ext_ctxt, try: bool) -> @ast::item {
|
||||
fn gen_send(&mut self, cx: @ExtCtxt, try: bool) -> @ast::item {
|
||||
debug!("pipec: gen_send");
|
||||
let name = self.name();
|
||||
|
||||
|
|
@ -52,14 +53,13 @@ impl gen_send for message {
|
|||
assert!(next_state.tys.len() ==
|
||||
next.generics.ty_params.len());
|
||||
let arg_names = tys.mapi(|i, _ty| cx.ident_of(~"x_"+i.to_str()));
|
||||
let args_ast = vec::map_zip(arg_names, *tys, |n, t| cx.arg(*n, *t));
|
||||
let args_ast = vec::map_zip(arg_names, *tys, |n, t| cx.arg(span, *n, *t));
|
||||
|
||||
let pipe_ty = cx.ty_path_ast_builder(
|
||||
let pipe_ty = cx.ty_path(
|
||||
path(~[this.data_name()], span)
|
||||
.add_tys(cx.ty_vars_global(&this.generics.ty_params)));
|
||||
.add_tys(cx.ty_vars(&this.generics.ty_params)));
|
||||
let args_ast = vec::append(
|
||||
~[cx.arg(cx.ident_of("pipe"),
|
||||
pipe_ty)],
|
||||
~[cx.arg(span, cx.ident_of("pipe"), pipe_ty)],
|
||||
args_ast);
|
||||
|
||||
let mut body = ~"{\n";
|
||||
|
|
@ -111,20 +111,21 @@ impl gen_send for message {
|
|||
|
||||
let body = cx.parse_expr(body);
|
||||
|
||||
let mut rty = cx.ty_path_ast_builder(path(~[next.data_name()],
|
||||
span)
|
||||
.add_tys(copy next_state.tys));
|
||||
let mut rty = cx.ty_path(path(~[next.data_name()],
|
||||
span)
|
||||
.add_tys(copy next_state.tys));
|
||||
if try {
|
||||
rty = cx.ty_option(rty);
|
||||
}
|
||||
|
||||
let name = cx.ident_of(if try { ~"try_" + name } else { name } );
|
||||
|
||||
cx.item_fn_poly(name,
|
||||
cx.item_fn_poly(dummy_sp(),
|
||||
name,
|
||||
args_ast,
|
||||
rty,
|
||||
self.get_generics(),
|
||||
cx.expr_block(body))
|
||||
cx.blk_expr(body))
|
||||
}
|
||||
|
||||
message(ref _id, span, ref tys, this, None) => {
|
||||
|
|
@ -132,14 +133,15 @@ impl gen_send for message {
|
|||
let arg_names = tys.mapi(|i, _ty| (~"x_" + i.to_str()));
|
||||
|
||||
let args_ast = do vec::map_zip(arg_names, *tys) |n, t| {
|
||||
cx.arg(cx.ident_of(*n), *t)
|
||||
cx.arg(span, cx.ident_of(*n), *t)
|
||||
};
|
||||
|
||||
let args_ast = vec::append(
|
||||
~[cx.arg(cx.ident_of("pipe"),
|
||||
cx.ty_path_ast_builder(
|
||||
~[cx.arg(span,
|
||||
cx.ident_of("pipe"),
|
||||
cx.ty_path(
|
||||
path(~[this.data_name()], span)
|
||||
.add_tys(cx.ty_vars_global(
|
||||
.add_tys(cx.ty_vars(
|
||||
&this.generics.ty_params))))],
|
||||
args_ast);
|
||||
|
||||
|
|
@ -171,27 +173,28 @@ impl gen_send for message {
|
|||
|
||||
let name = if try { ~"try_" + name } else { name };
|
||||
|
||||
cx.item_fn_poly(cx.ident_of(name),
|
||||
cx.item_fn_poly(dummy_sp(),
|
||||
cx.ident_of(name),
|
||||
args_ast,
|
||||
if try {
|
||||
cx.ty_option(cx.ty_nil_ast_builder())
|
||||
cx.ty_option(cx.ty_nil())
|
||||
} else {
|
||||
cx.ty_nil_ast_builder()
|
||||
cx.ty_nil()
|
||||
},
|
||||
self.get_generics(),
|
||||
cx.expr_block(body))
|
||||
cx.blk_expr(body))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn to_ty(&mut self, cx: @ext_ctxt) -> @ast::Ty {
|
||||
cx.ty_path_ast_builder(path(~[cx.ident_of(self.name())], self.span())
|
||||
.add_tys(cx.ty_vars_global(&self.get_generics().ty_params)))
|
||||
fn to_ty(&mut self, cx: @ExtCtxt) -> @ast::Ty {
|
||||
cx.ty_path(path(~[cx.ident_of(self.name())], self.span())
|
||||
.add_tys(cx.ty_vars(&self.get_generics().ty_params)))
|
||||
}
|
||||
}
|
||||
|
||||
impl to_type_decls for state {
|
||||
fn to_type_decls(&self, cx: @ext_ctxt) -> ~[@ast::item] {
|
||||
fn to_type_decls(&self, cx: @ExtCtxt) -> ~[@ast::item] {
|
||||
debug!("pipec: to_type_decls");
|
||||
// This compiles into two different type declarations. Say the
|
||||
// state is called ping. This will generate both `ping` and
|
||||
|
|
@ -217,7 +220,7 @@ impl to_type_decls for state {
|
|||
};
|
||||
|
||||
vec::append_one(tys,
|
||||
cx.ty_path_ast_builder(
|
||||
cx.ty_path(
|
||||
path(~[cx.ident_of(dir),
|
||||
cx.ident_of(next_name)], span)
|
||||
.add_tys(copy next_state.tys)))
|
||||
|
|
@ -225,22 +228,22 @@ impl to_type_decls for state {
|
|||
None => tys
|
||||
};
|
||||
|
||||
let v = cx.variant(cx.ident_of(name), span, tys);
|
||||
let v = cx.variant(span, cx.ident_of(name), tys);
|
||||
|
||||
items_msg.push(v);
|
||||
}
|
||||
|
||||
~[
|
||||
cx.item_enum_poly(
|
||||
name,
|
||||
self.span,
|
||||
name,
|
||||
ast::enum_def { variants: items_msg },
|
||||
cx.strip_bounds(&self.generics)
|
||||
)
|
||||
]
|
||||
}
|
||||
|
||||
fn to_endpoint_decls(&self, cx: @ext_ctxt,
|
||||
fn to_endpoint_decls(&self, cx: @ExtCtxt,
|
||||
dir: direction) -> ~[@ast::item] {
|
||||
debug!("pipec: to_endpoint_decls");
|
||||
let dir = match dir {
|
||||
|
|
@ -262,33 +265,33 @@ impl to_type_decls for state {
|
|||
if !self.proto.is_bounded() {
|
||||
items.push(
|
||||
cx.item_ty_poly(
|
||||
self.data_name(),
|
||||
self.span,
|
||||
cx.ty_path_ast_builder(
|
||||
self.data_name(),
|
||||
cx.ty_path(
|
||||
path_global(~[cx.ident_of("core"),
|
||||
cx.ident_of("pipes"),
|
||||
cx.ident_of(dir.to_str() + "Packet")],
|
||||
dummy_sp())
|
||||
.add_ty(cx.ty_path_ast_builder(
|
||||
.add_ty(cx.ty_path(
|
||||
path(~[cx.ident_of("super"),
|
||||
self.data_name()],
|
||||
dummy_sp())
|
||||
.add_tys(cx.ty_vars_global(
|
||||
.add_tys(cx.ty_vars(
|
||||
&self.generics.ty_params))))),
|
||||
cx.strip_bounds(&self.generics)));
|
||||
}
|
||||
else {
|
||||
items.push(
|
||||
cx.item_ty_poly(
|
||||
self.data_name(),
|
||||
self.span,
|
||||
cx.ty_path_ast_builder(
|
||||
self.data_name(),
|
||||
cx.ty_path(
|
||||
path_global(~[cx.ident_of("core"),
|
||||
cx.ident_of("pipes"),
|
||||
cx.ident_of(dir.to_str()
|
||||
+ "PacketBuffered")],
|
||||
dummy_sp())
|
||||
.add_tys(~[cx.ty_path_ast_builder(
|
||||
.add_tys(~[cx.ty_path(
|
||||
path(~[cx.ident_of("super"),
|
||||
self.data_name()],
|
||||
dummy_sp())
|
||||
|
|
@ -302,7 +305,7 @@ impl to_type_decls for state {
|
|||
}
|
||||
|
||||
impl gen_init for protocol {
|
||||
fn gen_init(&self, cx: @ext_ctxt) -> @ast::item {
|
||||
fn gen_init(&self, cx: @ExtCtxt) -> @ast::item {
|
||||
let ext_cx = cx;
|
||||
|
||||
debug!("gen_init");
|
||||
|
|
@ -340,19 +343,22 @@ impl gen_init for protocol {
|
|||
body.to_source(cx)))
|
||||
}
|
||||
|
||||
fn gen_buffer_init(&self, ext_cx: @ext_ctxt) -> @ast::expr {
|
||||
ext_cx.struct_expr(path(~[ext_cx.ident_of("__Buffer")],
|
||||
dummy_sp()),
|
||||
self.states.map_to_vec(|s| {
|
||||
let fty = s.to_ty(ext_cx);
|
||||
ext_cx.field_imm(ext_cx.ident_of(s.name),
|
||||
quote_expr!(
|
||||
::core::pipes::mk_packet::<$fty>()
|
||||
))
|
||||
}))
|
||||
fn gen_buffer_init(&self, ext_cx: @ExtCtxt) -> @ast::expr {
|
||||
ext_cx.expr_struct(
|
||||
dummy_sp(),
|
||||
path(~[ext_cx.ident_of("__Buffer")],
|
||||
dummy_sp()),
|
||||
self.states.map_to_vec(|s| {
|
||||
let fty = s.to_ty(ext_cx);
|
||||
ext_cx.field_imm(dummy_sp(),
|
||||
ext_cx.ident_of(s.name),
|
||||
quote_expr!(
|
||||
::core::pipes::mk_packet::<$fty>()
|
||||
))
|
||||
}))
|
||||
}
|
||||
|
||||
fn gen_init_bounded(&self, ext_cx: @ext_ctxt) -> @ast::expr {
|
||||
fn gen_init_bounded(&self, ext_cx: @ExtCtxt) -> @ast::expr {
|
||||
debug!("gen_init_bounded");
|
||||
let buffer_fields = self.gen_buffer_init(ext_cx);
|
||||
let buffer = quote_expr!(~::core::pipes::Buffer {
|
||||
|
|
@ -360,15 +366,16 @@ impl gen_init for protocol {
|
|||
data: $buffer_fields,
|
||||
});
|
||||
|
||||
let entangle_body = ext_cx.block_expr(
|
||||
ext_cx.block(
|
||||
let entangle_body = ext_cx.expr_blk(
|
||||
ext_cx.blk(
|
||||
dummy_sp(),
|
||||
self.states.map_to_vec(
|
||||
|s| ext_cx.parse_stmt(
|
||||
fmt!("data.%s.set_buffer(buffer)",
|
||||
s.name))),
|
||||
ext_cx.parse_expr(fmt!(
|
||||
Some(ext_cx.parse_expr(fmt!(
|
||||
"::core::ptr::to_mut_unsafe_ptr(&mut (data.%s))",
|
||||
self.states[0].name))));
|
||||
self.states[0].name)))));
|
||||
|
||||
quote_expr!({
|
||||
let buffer = $buffer;
|
||||
|
|
@ -378,7 +385,7 @@ impl gen_init for protocol {
|
|||
})
|
||||
}
|
||||
|
||||
fn buffer_ty_path(&self, cx: @ext_ctxt) -> @ast::Ty {
|
||||
fn buffer_ty_path(&self, cx: @ExtCtxt) -> @ast::Ty {
|
||||
let mut params: OptVec<ast::TyParam> = opt_vec::Empty;
|
||||
for (copy self.states).each |s| {
|
||||
for s.generics.ty_params.each |tp| {
|
||||
|
|
@ -389,13 +396,13 @@ impl gen_init for protocol {
|
|||
}
|
||||
}
|
||||
|
||||
cx.ty_path_ast_builder(path(~[cx.ident_of("super"),
|
||||
cx.ident_of("__Buffer")],
|
||||
copy self.span)
|
||||
.add_tys(cx.ty_vars_global(¶ms)))
|
||||
cx.ty_path(path(~[cx.ident_of("super"),
|
||||
cx.ident_of("__Buffer")],
|
||||
copy self.span)
|
||||
.add_tys(cx.ty_vars_global(¶ms)))
|
||||
}
|
||||
|
||||
fn gen_buffer_type(&self, cx: @ext_ctxt) -> @ast::item {
|
||||
fn gen_buffer_type(&self, cx: @ExtCtxt) -> @ast::item {
|
||||
let ext_cx = cx;
|
||||
let mut params: OptVec<ast::TyParam> = opt_vec::Empty;
|
||||
let fields = do (copy self.states).map_to_vec |s| {
|
||||
|
|
@ -427,8 +434,8 @@ impl gen_init for protocol {
|
|||
};
|
||||
|
||||
cx.item_struct_poly(
|
||||
cx.ident_of("__Buffer"),
|
||||
dummy_sp(),
|
||||
cx.ident_of("__Buffer"),
|
||||
ast::struct_def {
|
||||
fields: fields,
|
||||
ctor_id: None
|
||||
|
|
@ -436,7 +443,7 @@ impl gen_init for protocol {
|
|||
cx.strip_bounds(&generics))
|
||||
}
|
||||
|
||||
fn compile(&self, cx: @ext_ctxt) -> @ast::item {
|
||||
fn compile(&self, cx: @ExtCtxt) -> @ast::item {
|
||||
let mut items = ~[self.gen_init(cx)];
|
||||
let mut client_states = ~[];
|
||||
let mut server_states = ~[];
|
||||
|
|
@ -452,13 +459,24 @@ impl gen_init for protocol {
|
|||
items.push(self.gen_buffer_type(cx))
|
||||
}
|
||||
|
||||
items.push(cx.item_mod(cx.ident_of("client"),
|
||||
copy self.span,
|
||||
items.push(cx.item_mod(copy self.span,
|
||||
cx.ident_of("client"),
|
||||
~[], ~[],
|
||||
client_states));
|
||||
items.push(cx.item_mod(cx.ident_of("server"),
|
||||
copy self.span,
|
||||
items.push(cx.item_mod(copy self.span,
|
||||
cx.ident_of("server"),
|
||||
~[], ~[],
|
||||
server_states));
|
||||
|
||||
cx.item_mod(cx.ident_of(copy self.name), copy self.span, items)
|
||||
// XXX: Would be nice if our generated code didn't violate
|
||||
// Rust coding conventions
|
||||
let allows = cx.attribute(
|
||||
copy self.span,
|
||||
cx.meta_list(copy self.span,
|
||||
~"allow",
|
||||
~[cx.meta_word(copy self.span, ~"non_camel_case_types"),
|
||||
cx.meta_word(copy self.span, ~"unused_mut")]));
|
||||
cx.item_mod(copy self.span, cx.ident_of(copy self.name),
|
||||
~[allows], ~[], items)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,8 +10,9 @@
|
|||
|
||||
use ast;
|
||||
use codemap::span;
|
||||
use ext::base::ext_ctxt;
|
||||
use ext::pipes::ast_builder::{append_types, ext_ctxt_ast_builder, path};
|
||||
use ext::base::ExtCtxt;
|
||||
use ext::build::AstBuilder;
|
||||
use ext::pipes::ast_builder::{append_types, path};
|
||||
|
||||
#[deriving(Eq)]
|
||||
pub enum direction { send, recv }
|
||||
|
|
@ -92,8 +93,8 @@ pub impl state_ {
|
|||
}
|
||||
|
||||
/// Returns the type that is used for the messages.
|
||||
fn to_ty(&self, cx: @ext_ctxt) -> @ast::Ty {
|
||||
cx.ty_path_ast_builder
|
||||
fn to_ty(&self, cx: @ExtCtxt) -> @ast::Ty {
|
||||
cx.ty_path
|
||||
(path(~[cx.ident_of(self.name)],self.span).add_tys(
|
||||
cx.ty_vars(&self.generics.ty_params)))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,9 +10,9 @@
|
|||
|
||||
use ast;
|
||||
use codemap::{BytePos, Pos, span};
|
||||
use ext::base::ext_ctxt;
|
||||
use ext::base::ExtCtxt;
|
||||
use ext::base;
|
||||
use ext::build;
|
||||
use ext::build::AstBuilder;
|
||||
use parse::token::*;
|
||||
use parse::token;
|
||||
use parse;
|
||||
|
|
@ -30,7 +30,7 @@ use parse;
|
|||
|
||||
pub mod rt {
|
||||
use ast;
|
||||
use ext::base::ext_ctxt;
|
||||
use ext::base::ExtCtxt;
|
||||
use parse;
|
||||
use print::pprust;
|
||||
|
||||
|
|
@ -44,11 +44,11 @@ pub mod rt {
|
|||
use print::pprust::{item_to_str, ty_to_str};
|
||||
|
||||
pub trait ToTokens {
|
||||
pub fn to_tokens(&self, _cx: @ext_ctxt) -> ~[token_tree];
|
||||
pub fn to_tokens(&self, _cx: @ExtCtxt) -> ~[token_tree];
|
||||
}
|
||||
|
||||
impl ToTokens for ~[token_tree] {
|
||||
pub fn to_tokens(&self, _cx: @ext_ctxt) -> ~[token_tree] {
|
||||
pub fn to_tokens(&self, _cx: @ExtCtxt) -> ~[token_tree] {
|
||||
copy *self
|
||||
}
|
||||
}
|
||||
|
|
@ -57,10 +57,10 @@ pub mod rt {
|
|||
|
||||
trait ToSource : ToTokens {
|
||||
// Takes a thing and generates a string containing rust code for it.
|
||||
pub fn to_source(cx: @ext_ctxt) -> ~str;
|
||||
pub fn to_source(cx: @ExtCtxt) -> ~str;
|
||||
|
||||
// If you can make source, you can definitely make tokens.
|
||||
pub fn to_tokens(cx: @ext_ctxt) -> ~[token_tree] {
|
||||
pub fn to_tokens(cx: @ExtCtxt) -> ~[token_tree] {
|
||||
cx.parse_tts(self.to_source(cx))
|
||||
}
|
||||
}
|
||||
|
|
@ -69,80 +69,80 @@ pub mod rt {
|
|||
|
||||
pub trait ToSource {
|
||||
// Takes a thing and generates a string containing rust code for it.
|
||||
pub fn to_source(&self, cx: @ext_ctxt) -> ~str;
|
||||
pub fn to_source(&self, cx: @ExtCtxt) -> ~str;
|
||||
}
|
||||
|
||||
impl ToSource for ast::ident {
|
||||
fn to_source(&self, cx: @ext_ctxt) -> ~str {
|
||||
fn to_source(&self, cx: @ExtCtxt) -> ~str {
|
||||
copy *cx.parse_sess().interner.get(*self)
|
||||
}
|
||||
}
|
||||
|
||||
impl ToSource for @ast::item {
|
||||
fn to_source(&self, cx: @ext_ctxt) -> ~str {
|
||||
fn to_source(&self, cx: @ExtCtxt) -> ~str {
|
||||
item_to_str(*self, cx.parse_sess().interner)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'self> ToSource for &'self [@ast::item] {
|
||||
fn to_source(&self, cx: @ext_ctxt) -> ~str {
|
||||
fn to_source(&self, cx: @ExtCtxt) -> ~str {
|
||||
str::connect(self.map(|i| i.to_source(cx)), "\n\n")
|
||||
}
|
||||
}
|
||||
|
||||
impl ToSource for @ast::Ty {
|
||||
fn to_source(&self, cx: @ext_ctxt) -> ~str {
|
||||
fn to_source(&self, cx: @ExtCtxt) -> ~str {
|
||||
ty_to_str(*self, cx.parse_sess().interner)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'self> ToSource for &'self [@ast::Ty] {
|
||||
fn to_source(&self, cx: @ext_ctxt) -> ~str {
|
||||
fn to_source(&self, cx: @ExtCtxt) -> ~str {
|
||||
str::connect(self.map(|i| i.to_source(cx)), ", ")
|
||||
}
|
||||
}
|
||||
|
||||
impl ToSource for Generics {
|
||||
fn to_source(&self, cx: @ext_ctxt) -> ~str {
|
||||
fn to_source(&self, cx: @ExtCtxt) -> ~str {
|
||||
pprust::generics_to_str(self, cx.parse_sess().interner)
|
||||
}
|
||||
}
|
||||
|
||||
impl ToSource for @ast::expr {
|
||||
fn to_source(&self, cx: @ext_ctxt) -> ~str {
|
||||
fn to_source(&self, cx: @ExtCtxt) -> ~str {
|
||||
pprust::expr_to_str(*self, cx.parse_sess().interner)
|
||||
}
|
||||
}
|
||||
|
||||
impl ToSource for ast::blk {
|
||||
fn to_source(&self, cx: @ext_ctxt) -> ~str {
|
||||
fn to_source(&self, cx: @ExtCtxt) -> ~str {
|
||||
pprust::block_to_str(self, cx.parse_sess().interner)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'self> ToSource for &'self str {
|
||||
fn to_source(&self, _cx: @ext_ctxt) -> ~str {
|
||||
fn to_source(&self, _cx: @ExtCtxt) -> ~str {
|
||||
let lit = dummy_spanned(ast::lit_str(@str::to_owned(*self)));
|
||||
pprust::lit_to_str(@lit)
|
||||
}
|
||||
}
|
||||
|
||||
impl ToSource for int {
|
||||
fn to_source(&self, _cx: @ext_ctxt) -> ~str {
|
||||
fn to_source(&self, _cx: @ExtCtxt) -> ~str {
|
||||
let lit = dummy_spanned(ast::lit_int(*self as i64, ast::ty_i));
|
||||
pprust::lit_to_str(@lit)
|
||||
}
|
||||
}
|
||||
|
||||
impl ToSource for i8 {
|
||||
fn to_source(&self, _cx: @ext_ctxt) -> ~str {
|
||||
fn to_source(&self, _cx: @ExtCtxt) -> ~str {
|
||||
let lit = dummy_spanned(ast::lit_int(*self as i64, ast::ty_i8));
|
||||
pprust::lit_to_str(@lit)
|
||||
}
|
||||
}
|
||||
|
||||
impl ToSource for i16 {
|
||||
fn to_source(&self, _cx: @ext_ctxt) -> ~str {
|
||||
fn to_source(&self, _cx: @ExtCtxt) -> ~str {
|
||||
let lit = dummy_spanned(ast::lit_int(*self as i64, ast::ty_i16));
|
||||
pprust::lit_to_str(@lit)
|
||||
}
|
||||
|
|
@ -150,49 +150,49 @@ pub mod rt {
|
|||
|
||||
|
||||
impl ToSource for i32 {
|
||||
fn to_source(&self, _cx: @ext_ctxt) -> ~str {
|
||||
fn to_source(&self, _cx: @ExtCtxt) -> ~str {
|
||||
let lit = dummy_spanned(ast::lit_int(*self as i64, ast::ty_i32));
|
||||
pprust::lit_to_str(@lit)
|
||||
}
|
||||
}
|
||||
|
||||
impl ToSource for i64 {
|
||||
fn to_source(&self, _cx: @ext_ctxt) -> ~str {
|
||||
fn to_source(&self, _cx: @ExtCtxt) -> ~str {
|
||||
let lit = dummy_spanned(ast::lit_int(*self as i64, ast::ty_i64));
|
||||
pprust::lit_to_str(@lit)
|
||||
}
|
||||
}
|
||||
|
||||
impl ToSource for uint {
|
||||
fn to_source(&self, _cx: @ext_ctxt) -> ~str {
|
||||
fn to_source(&self, _cx: @ExtCtxt) -> ~str {
|
||||
let lit = dummy_spanned(ast::lit_uint(*self as u64, ast::ty_u));
|
||||
pprust::lit_to_str(@lit)
|
||||
}
|
||||
}
|
||||
|
||||
impl ToSource for u8 {
|
||||
fn to_source(&self, _cx: @ext_ctxt) -> ~str {
|
||||
fn to_source(&self, _cx: @ExtCtxt) -> ~str {
|
||||
let lit = dummy_spanned(ast::lit_uint(*self as u64, ast::ty_u8));
|
||||
pprust::lit_to_str(@lit)
|
||||
}
|
||||
}
|
||||
|
||||
impl ToSource for u16 {
|
||||
fn to_source(&self, _cx: @ext_ctxt) -> ~str {
|
||||
fn to_source(&self, _cx: @ExtCtxt) -> ~str {
|
||||
let lit = dummy_spanned(ast::lit_uint(*self as u64, ast::ty_u16));
|
||||
pprust::lit_to_str(@lit)
|
||||
}
|
||||
}
|
||||
|
||||
impl ToSource for u32 {
|
||||
fn to_source(&self, _cx: @ext_ctxt) -> ~str {
|
||||
fn to_source(&self, _cx: @ExtCtxt) -> ~str {
|
||||
let lit = dummy_spanned(ast::lit_uint(*self as u64, ast::ty_u32));
|
||||
pprust::lit_to_str(@lit)
|
||||
}
|
||||
}
|
||||
|
||||
impl ToSource for u64 {
|
||||
fn to_source(&self, _cx: @ext_ctxt) -> ~str {
|
||||
fn to_source(&self, _cx: @ExtCtxt) -> ~str {
|
||||
let lit = dummy_spanned(ast::lit_uint(*self as u64, ast::ty_u64));
|
||||
pprust::lit_to_str(@lit)
|
||||
}
|
||||
|
|
@ -201,115 +201,115 @@ pub mod rt {
|
|||
// Alas ... we write these out instead. All redundant.
|
||||
|
||||
impl ToTokens for ast::ident {
|
||||
fn to_tokens(&self, cx: @ext_ctxt) -> ~[token_tree] {
|
||||
fn to_tokens(&self, cx: @ExtCtxt) -> ~[token_tree] {
|
||||
cx.parse_tts(self.to_source(cx))
|
||||
}
|
||||
}
|
||||
|
||||
impl ToTokens for @ast::item {
|
||||
fn to_tokens(&self, cx: @ext_ctxt) -> ~[token_tree] {
|
||||
fn to_tokens(&self, cx: @ExtCtxt) -> ~[token_tree] {
|
||||
cx.parse_tts(self.to_source(cx))
|
||||
}
|
||||
}
|
||||
|
||||
impl<'self> ToTokens for &'self [@ast::item] {
|
||||
fn to_tokens(&self, cx: @ext_ctxt) -> ~[token_tree] {
|
||||
fn to_tokens(&self, cx: @ExtCtxt) -> ~[token_tree] {
|
||||
cx.parse_tts(self.to_source(cx))
|
||||
}
|
||||
}
|
||||
|
||||
impl ToTokens for @ast::Ty {
|
||||
fn to_tokens(&self, cx: @ext_ctxt) -> ~[token_tree] {
|
||||
fn to_tokens(&self, cx: @ExtCtxt) -> ~[token_tree] {
|
||||
cx.parse_tts(self.to_source(cx))
|
||||
}
|
||||
}
|
||||
|
||||
impl<'self> ToTokens for &'self [@ast::Ty] {
|
||||
fn to_tokens(&self, cx: @ext_ctxt) -> ~[token_tree] {
|
||||
fn to_tokens(&self, cx: @ExtCtxt) -> ~[token_tree] {
|
||||
cx.parse_tts(self.to_source(cx))
|
||||
}
|
||||
}
|
||||
|
||||
impl ToTokens for Generics {
|
||||
fn to_tokens(&self, cx: @ext_ctxt) -> ~[token_tree] {
|
||||
fn to_tokens(&self, cx: @ExtCtxt) -> ~[token_tree] {
|
||||
cx.parse_tts(self.to_source(cx))
|
||||
}
|
||||
}
|
||||
|
||||
impl ToTokens for @ast::expr {
|
||||
fn to_tokens(&self, cx: @ext_ctxt) -> ~[token_tree] {
|
||||
fn to_tokens(&self, cx: @ExtCtxt) -> ~[token_tree] {
|
||||
cx.parse_tts(self.to_source(cx))
|
||||
}
|
||||
}
|
||||
|
||||
impl ToTokens for ast::blk {
|
||||
fn to_tokens(&self, cx: @ext_ctxt) -> ~[token_tree] {
|
||||
fn to_tokens(&self, cx: @ExtCtxt) -> ~[token_tree] {
|
||||
cx.parse_tts(self.to_source(cx))
|
||||
}
|
||||
}
|
||||
|
||||
impl<'self> ToTokens for &'self str {
|
||||
fn to_tokens(&self, cx: @ext_ctxt) -> ~[token_tree] {
|
||||
fn to_tokens(&self, cx: @ExtCtxt) -> ~[token_tree] {
|
||||
cx.parse_tts(self.to_source(cx))
|
||||
}
|
||||
}
|
||||
|
||||
impl ToTokens for int {
|
||||
fn to_tokens(&self, cx: @ext_ctxt) -> ~[token_tree] {
|
||||
fn to_tokens(&self, cx: @ExtCtxt) -> ~[token_tree] {
|
||||
cx.parse_tts(self.to_source(cx))
|
||||
}
|
||||
}
|
||||
|
||||
impl ToTokens for i8 {
|
||||
fn to_tokens(&self, cx: @ext_ctxt) -> ~[token_tree] {
|
||||
fn to_tokens(&self, cx: @ExtCtxt) -> ~[token_tree] {
|
||||
cx.parse_tts(self.to_source(cx))
|
||||
}
|
||||
}
|
||||
|
||||
impl ToTokens for i16 {
|
||||
fn to_tokens(&self, cx: @ext_ctxt) -> ~[token_tree] {
|
||||
fn to_tokens(&self, cx: @ExtCtxt) -> ~[token_tree] {
|
||||
cx.parse_tts(self.to_source(cx))
|
||||
}
|
||||
}
|
||||
|
||||
impl ToTokens for i32 {
|
||||
fn to_tokens(&self, cx: @ext_ctxt) -> ~[token_tree] {
|
||||
fn to_tokens(&self, cx: @ExtCtxt) -> ~[token_tree] {
|
||||
cx.parse_tts(self.to_source(cx))
|
||||
}
|
||||
}
|
||||
|
||||
impl ToTokens for i64 {
|
||||
fn to_tokens(&self, cx: @ext_ctxt) -> ~[token_tree] {
|
||||
fn to_tokens(&self, cx: @ExtCtxt) -> ~[token_tree] {
|
||||
cx.parse_tts(self.to_source(cx))
|
||||
}
|
||||
}
|
||||
|
||||
impl ToTokens for uint {
|
||||
fn to_tokens(&self, cx: @ext_ctxt) -> ~[token_tree] {
|
||||
fn to_tokens(&self, cx: @ExtCtxt) -> ~[token_tree] {
|
||||
cx.parse_tts(self.to_source(cx))
|
||||
}
|
||||
}
|
||||
|
||||
impl ToTokens for u8 {
|
||||
fn to_tokens(&self, cx: @ext_ctxt) -> ~[token_tree] {
|
||||
fn to_tokens(&self, cx: @ExtCtxt) -> ~[token_tree] {
|
||||
cx.parse_tts(self.to_source(cx))
|
||||
}
|
||||
}
|
||||
|
||||
impl ToTokens for u16 {
|
||||
fn to_tokens(&self, cx: @ext_ctxt) -> ~[token_tree] {
|
||||
fn to_tokens(&self, cx: @ExtCtxt) -> ~[token_tree] {
|
||||
cx.parse_tts(self.to_source(cx))
|
||||
}
|
||||
}
|
||||
|
||||
impl ToTokens for u32 {
|
||||
fn to_tokens(&self, cx: @ext_ctxt) -> ~[token_tree] {
|
||||
fn to_tokens(&self, cx: @ExtCtxt) -> ~[token_tree] {
|
||||
cx.parse_tts(self.to_source(cx))
|
||||
}
|
||||
}
|
||||
|
||||
impl ToTokens for u64 {
|
||||
fn to_tokens(&self, cx: @ext_ctxt) -> ~[token_tree] {
|
||||
fn to_tokens(&self, cx: @ExtCtxt) -> ~[token_tree] {
|
||||
cx.parse_tts(self.to_source(cx))
|
||||
}
|
||||
}
|
||||
|
|
@ -321,7 +321,7 @@ pub mod rt {
|
|||
fn parse_tts(&self, s: ~str) -> ~[ast::token_tree];
|
||||
}
|
||||
|
||||
impl ExtParseUtils for @ext_ctxt {
|
||||
impl ExtParseUtils for ExtCtxt {
|
||||
|
||||
fn parse_item(&self, s: ~str) -> @ast::item {
|
||||
let res = parse::parse_item_from_source_str(
|
||||
|
|
@ -367,74 +367,74 @@ pub mod rt {
|
|||
|
||||
}
|
||||
|
||||
pub fn expand_quote_tokens(cx: @ext_ctxt,
|
||||
pub fn expand_quote_tokens(cx: @ExtCtxt,
|
||||
sp: span,
|
||||
tts: &[ast::token_tree]) -> base::MacResult {
|
||||
base::MRExpr(expand_tts(cx, sp, tts))
|
||||
}
|
||||
|
||||
pub fn expand_quote_expr(cx: @ext_ctxt,
|
||||
pub fn expand_quote_expr(cx: @ExtCtxt,
|
||||
sp: span,
|
||||
tts: &[ast::token_tree]) -> base::MacResult {
|
||||
base::MRExpr(expand_parse_call(cx, sp, "parse_expr", ~[], tts))
|
||||
}
|
||||
|
||||
pub fn expand_quote_item(cx: @ext_ctxt,
|
||||
pub fn expand_quote_item(cx: @ExtCtxt,
|
||||
sp: span,
|
||||
tts: &[ast::token_tree]) -> base::MacResult {
|
||||
let e_attrs = build::mk_uniq_vec_e(cx, sp, ~[]);
|
||||
let e_attrs = cx.expr_vec_uniq(sp, ~[]);
|
||||
base::MRExpr(expand_parse_call(cx, sp, "parse_item",
|
||||
~[e_attrs], tts))
|
||||
}
|
||||
|
||||
pub fn expand_quote_pat(cx: @ext_ctxt,
|
||||
pub fn expand_quote_pat(cx: @ExtCtxt,
|
||||
sp: span,
|
||||
tts: &[ast::token_tree]) -> base::MacResult {
|
||||
let e_refutable = build::mk_lit(cx, sp, ast::lit_bool(true));
|
||||
let e_refutable = cx.expr_lit(sp, ast::lit_bool(true));
|
||||
base::MRExpr(expand_parse_call(cx, sp, "parse_pat",
|
||||
~[e_refutable], tts))
|
||||
}
|
||||
|
||||
pub fn expand_quote_ty(cx: @ext_ctxt,
|
||||
pub fn expand_quote_ty(cx: @ExtCtxt,
|
||||
sp: span,
|
||||
tts: &[ast::token_tree]) -> base::MacResult {
|
||||
let e_param_colons = build::mk_lit(cx, sp, ast::lit_bool(false));
|
||||
let e_param_colons = cx.expr_lit(sp, ast::lit_bool(false));
|
||||
base::MRExpr(expand_parse_call(cx, sp, "parse_ty",
|
||||
~[e_param_colons], tts))
|
||||
}
|
||||
|
||||
pub fn expand_quote_stmt(cx: @ext_ctxt,
|
||||
pub fn expand_quote_stmt(cx: @ExtCtxt,
|
||||
sp: span,
|
||||
tts: &[ast::token_tree]) -> base::MacResult {
|
||||
let e_attrs = build::mk_uniq_vec_e(cx, sp, ~[]);
|
||||
let e_attrs = cx.expr_vec_uniq(sp, ~[]);
|
||||
base::MRExpr(expand_parse_call(cx, sp, "parse_stmt",
|
||||
~[e_attrs], tts))
|
||||
}
|
||||
|
||||
fn ids_ext(cx: @ext_ctxt, strs: ~[~str]) -> ~[ast::ident] {
|
||||
fn ids_ext(cx: @ExtCtxt, strs: ~[~str]) -> ~[ast::ident] {
|
||||
strs.map(|str| cx.parse_sess().interner.intern(*str))
|
||||
}
|
||||
|
||||
fn id_ext(cx: @ext_ctxt, str: &str) -> ast::ident {
|
||||
fn id_ext(cx: @ExtCtxt, str: &str) -> ast::ident {
|
||||
cx.parse_sess().interner.intern(str)
|
||||
}
|
||||
|
||||
// Lift an ident to the expr that evaluates to that ident.
|
||||
fn mk_ident(cx: @ext_ctxt, sp: span, ident: ast::ident) -> @ast::expr {
|
||||
let e_str = build::mk_base_str(cx, sp, cx.str_of(ident));
|
||||
build::mk_method_call(cx, sp,
|
||||
build::mk_path(cx, sp, ids_ext(cx, ~[~"ext_cx"])),
|
||||
id_ext(cx, "ident_of"),
|
||||
~[e_str])
|
||||
fn mk_ident(cx: @ExtCtxt, sp: span, ident: ast::ident) -> @ast::expr {
|
||||
let e_str = cx.expr_str(sp, cx.str_of(ident));
|
||||
cx.expr_method_call(sp,
|
||||
cx.expr_ident(sp, id_ext(cx, "ext_cx")),
|
||||
id_ext(cx, "ident_of"),
|
||||
~[e_str])
|
||||
}
|
||||
|
||||
fn mk_bytepos(cx: @ext_ctxt, sp: span, bpos: BytePos) -> @ast::expr {
|
||||
let path = ids_ext(cx, ~[~"BytePos"]);
|
||||
let arg = build::mk_uint(cx, sp, bpos.to_uint());
|
||||
build::mk_call(cx, sp, path, ~[arg])
|
||||
fn mk_bytepos(cx: @ExtCtxt, sp: span, bpos: BytePos) -> @ast::expr {
|
||||
let path = id_ext(cx, "BytePos");
|
||||
let arg = cx.expr_uint(sp, bpos.to_uint());
|
||||
cx.expr_call_ident(sp, path, ~[arg])
|
||||
}
|
||||
|
||||
fn mk_binop(cx: @ext_ctxt, sp: span, bop: token::binop) -> @ast::expr {
|
||||
fn mk_binop(cx: @ExtCtxt, sp: span, bop: token::binop) -> @ast::expr {
|
||||
let name = match bop {
|
||||
PLUS => "PLUS",
|
||||
MINUS => "MINUS",
|
||||
|
|
@ -447,22 +447,21 @@ fn mk_binop(cx: @ext_ctxt, sp: span, bop: token::binop) -> @ast::expr {
|
|||
SHL => "SHL",
|
||||
SHR => "SHR"
|
||||
};
|
||||
build::mk_path(cx, sp,
|
||||
ids_ext(cx, ~[name.to_owned()]))
|
||||
cx.expr_ident(sp, id_ext(cx, name))
|
||||
}
|
||||
|
||||
fn mk_token(cx: @ext_ctxt, sp: span, tok: &token::Token) -> @ast::expr {
|
||||
fn mk_token(cx: @ExtCtxt, sp: span, tok: &token::Token) -> @ast::expr {
|
||||
|
||||
match *tok {
|
||||
BINOP(binop) => {
|
||||
return build::mk_call(cx, sp,
|
||||
ids_ext(cx, ~[~"BINOP"]),
|
||||
~[mk_binop(cx, sp, binop)]);
|
||||
return cx.expr_call_ident(sp,
|
||||
id_ext(cx, "BINOP"),
|
||||
~[mk_binop(cx, sp, binop)]);
|
||||
}
|
||||
BINOPEQ(binop) => {
|
||||
return build::mk_call(cx, sp,
|
||||
ids_ext(cx, ~[~"BINOPEQ"]),
|
||||
~[mk_binop(cx, sp, binop)]);
|
||||
return cx.expr_call_ident(sp,
|
||||
id_ext(cx, "BINOPEQ"),
|
||||
~[mk_binop(cx, sp, binop)]);
|
||||
}
|
||||
|
||||
LIT_INT(i, ity) => {
|
||||
|
|
@ -474,15 +473,13 @@ fn mk_token(cx: @ext_ctxt, sp: span, tok: &token::Token) -> @ast::expr {
|
|||
ast::ty_i32 => ~"ty_i32",
|
||||
ast::ty_i64 => ~"ty_i64"
|
||||
};
|
||||
let e_ity =
|
||||
build::mk_path(cx, sp,
|
||||
ids_ext(cx, ~[s_ity]));
|
||||
let e_ity = cx.expr_ident(sp, id_ext(cx, s_ity));
|
||||
|
||||
let e_i64 = build::mk_lit(cx, sp, ast::lit_int(i, ast::ty_i64));
|
||||
let e_i64 = cx.expr_lit(sp, ast::lit_int(i, ast::ty_i64));
|
||||
|
||||
return build::mk_call(cx, sp,
|
||||
ids_ext(cx, ~[~"LIT_INT"]),
|
||||
~[e_i64, e_ity]);
|
||||
return cx.expr_call_ident(sp,
|
||||
id_ext(cx, "LIT_INT"),
|
||||
~[e_i64, e_ity]);
|
||||
}
|
||||
|
||||
LIT_UINT(u, uty) => {
|
||||
|
|
@ -493,24 +490,21 @@ fn mk_token(cx: @ext_ctxt, sp: span, tok: &token::Token) -> @ast::expr {
|
|||
ast::ty_u32 => ~"ty_u32",
|
||||
ast::ty_u64 => ~"ty_u64"
|
||||
};
|
||||
let e_uty =
|
||||
build::mk_path(cx, sp,
|
||||
ids_ext(cx, ~[s_uty]));
|
||||
let e_uty = cx.expr_ident(sp, id_ext(cx, s_uty));
|
||||
|
||||
let e_u64 = build::mk_lit(cx, sp, ast::lit_uint(u, ast::ty_u64));
|
||||
let e_u64 = cx.expr_lit(sp, ast::lit_uint(u, ast::ty_u64));
|
||||
|
||||
return build::mk_call(cx, sp,
|
||||
ids_ext(cx, ~[~"LIT_UINT"]),
|
||||
~[e_u64, e_uty]);
|
||||
return cx.expr_call_ident(sp,
|
||||
id_ext(cx, "LIT_UINT"),
|
||||
~[e_u64, e_uty]);
|
||||
}
|
||||
|
||||
LIT_INT_UNSUFFIXED(i) => {
|
||||
let e_i64 = build::mk_lit(cx, sp,
|
||||
ast::lit_int(i, ast::ty_i64));
|
||||
let e_i64 = cx.expr_lit(sp, ast::lit_int(i, ast::ty_i64));
|
||||
|
||||
return build::mk_call(cx, sp,
|
||||
ids_ext(cx, ~[~"LIT_INT_UNSUFFIXED"]),
|
||||
~[e_i64]);
|
||||
return cx.expr_call_ident(sp,
|
||||
id_ext(cx, "LIT_INT_UNSUFFIXED"),
|
||||
~[e_i64]);
|
||||
}
|
||||
|
||||
LIT_FLOAT(fident, fty) => {
|
||||
|
|
@ -519,40 +513,38 @@ fn mk_token(cx: @ext_ctxt, sp: span, tok: &token::Token) -> @ast::expr {
|
|||
ast::ty_f32 => ~"ty_f32",
|
||||
ast::ty_f64 => ~"ty_f64"
|
||||
};
|
||||
let e_fty =
|
||||
build::mk_path(cx, sp,
|
||||
ids_ext(cx, ~[s_fty]));
|
||||
let e_fty = cx.expr_ident(sp, id_ext(cx, s_fty));
|
||||
|
||||
let e_fident = mk_ident(cx, sp, fident);
|
||||
|
||||
return build::mk_call(cx, sp,
|
||||
ids_ext(cx, ~[~"LIT_FLOAT"]),
|
||||
~[e_fident, e_fty]);
|
||||
return cx.expr_call_ident(sp,
|
||||
id_ext(cx, "LIT_FLOAT"),
|
||||
~[e_fident, e_fty]);
|
||||
}
|
||||
|
||||
LIT_STR(ident) => {
|
||||
return build::mk_call(cx, sp,
|
||||
ids_ext(cx, ~[~"LIT_STR"]),
|
||||
~[mk_ident(cx, sp, ident)]);
|
||||
return cx.expr_call_ident(sp,
|
||||
id_ext(cx, "LIT_STR"),
|
||||
~[mk_ident(cx, sp, ident)]);
|
||||
}
|
||||
|
||||
IDENT(ident, b) => {
|
||||
return build::mk_call(cx, sp,
|
||||
ids_ext(cx, ~[~"IDENT"]),
|
||||
~[mk_ident(cx, sp, ident),
|
||||
build::mk_lit(cx, sp, ast::lit_bool(b))]);
|
||||
return cx.expr_call_ident(sp,
|
||||
id_ext(cx, "IDENT"),
|
||||
~[mk_ident(cx, sp, ident),
|
||||
cx.expr_bool(sp, b)]);
|
||||
}
|
||||
|
||||
LIFETIME(ident) => {
|
||||
return build::mk_call(cx, sp,
|
||||
ids_ext(cx, ~[~"LIFETIME"]),
|
||||
~[mk_ident(cx, sp, ident)]);
|
||||
return cx.expr_call_ident(sp,
|
||||
id_ext(cx, "LIFETIME"),
|
||||
~[mk_ident(cx, sp, ident)]);
|
||||
}
|
||||
|
||||
DOC_COMMENT(ident) => {
|
||||
return build::mk_call(cx, sp,
|
||||
ids_ext(cx, ~[~"DOC_COMMENT"]),
|
||||
~[mk_ident(cx, sp, ident)]);
|
||||
return cx.expr_call_ident(sp,
|
||||
id_ext(cx, "DOC_COMMENT"),
|
||||
~[mk_ident(cx, sp, ident)]);
|
||||
}
|
||||
|
||||
INTERPOLATED(_) => fail!("quote! with interpolated token"),
|
||||
|
|
@ -595,30 +587,26 @@ fn mk_token(cx: @ext_ctxt, sp: span, tok: &token::Token) -> @ast::expr {
|
|||
EOF => "EOF",
|
||||
_ => fail!()
|
||||
};
|
||||
build::mk_path(cx, sp,
|
||||
ids_ext(cx, ~[name.to_owned()]))
|
||||
cx.expr_ident(sp, id_ext(cx, name))
|
||||
}
|
||||
|
||||
|
||||
fn mk_tt(cx: @ext_ctxt, sp: span, tt: &ast::token_tree)
|
||||
fn mk_tt(cx: @ExtCtxt, sp: span, tt: &ast::token_tree)
|
||||
-> ~[@ast::stmt] {
|
||||
|
||||
match *tt {
|
||||
|
||||
ast::tt_tok(sp, ref tok) => {
|
||||
let e_sp = build::mk_path(cx, sp,
|
||||
ids_ext(cx, ~[~"sp"]));
|
||||
let e_tok =
|
||||
build::mk_call(cx, sp,
|
||||
ids_ext(cx, ~[~"tt_tok"]),
|
||||
~[e_sp, mk_token(cx, sp, tok)]);
|
||||
let e_sp = cx.expr_ident(sp, id_ext(cx, "sp"));
|
||||
let e_tok = cx.expr_call_ident(sp,
|
||||
id_ext(cx, "tt_tok"),
|
||||
~[e_sp, mk_token(cx, sp, tok)]);
|
||||
let e_push =
|
||||
build::mk_method_call(cx, sp,
|
||||
build::mk_path(cx, sp, ids_ext(cx, ~[~"tt"])),
|
||||
id_ext(cx, "push"),
|
||||
~[e_tok]);
|
||||
~[build::mk_stmt(cx, sp, e_push)]
|
||||
|
||||
cx.expr_method_call(sp,
|
||||
cx.expr_ident(sp, id_ext(cx, "tt")),
|
||||
id_ext(cx, "push"),
|
||||
~[e_tok]);
|
||||
~[cx.stmt_expr(e_push)]
|
||||
}
|
||||
|
||||
ast::tt_delim(ref tts) => mk_tts(cx, sp, *tts),
|
||||
|
|
@ -629,24 +617,23 @@ fn mk_tt(cx: @ext_ctxt, sp: span, tt: &ast::token_tree)
|
|||
// tt.push_all_move($ident.to_tokens(ext_cx))
|
||||
|
||||
let e_to_toks =
|
||||
build::mk_method_call(cx, sp,
|
||||
build::mk_path(cx, sp, ~[ident]),
|
||||
id_ext(cx, "to_tokens"),
|
||||
~[build::mk_path(cx, sp,
|
||||
ids_ext(cx, ~[~"ext_cx"]))]);
|
||||
cx.expr_method_call(sp,
|
||||
cx.expr_ident(sp, ident),
|
||||
id_ext(cx, "to_tokens"),
|
||||
~[cx.expr_ident(sp, id_ext(cx, "ext_cx"))]);
|
||||
|
||||
let e_push =
|
||||
build::mk_method_call(cx, sp,
|
||||
build::mk_path(cx, sp, ids_ext(cx, ~[~"tt"])),
|
||||
id_ext(cx, "push_all_move"),
|
||||
~[e_to_toks]);
|
||||
cx.expr_method_call(sp,
|
||||
cx.expr_ident(sp, id_ext(cx, "tt")),
|
||||
id_ext(cx, "push_all_move"),
|
||||
~[e_to_toks]);
|
||||
|
||||
~[build::mk_stmt(cx, sp, e_push)]
|
||||
~[cx.stmt_expr(e_push)]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn mk_tts(cx: @ext_ctxt, sp: span, tts: &[ast::token_tree])
|
||||
fn mk_tts(cx: @ExtCtxt, sp: span, tts: &[ast::token_tree])
|
||||
-> ~[@ast::stmt] {
|
||||
let mut ss = ~[];
|
||||
for tts.each |tt| {
|
||||
|
|
@ -655,7 +642,7 @@ fn mk_tts(cx: @ext_ctxt, sp: span, tts: &[ast::token_tree])
|
|||
ss
|
||||
}
|
||||
|
||||
fn expand_tts(cx: @ext_ctxt,
|
||||
fn expand_tts(cx: @ExtCtxt,
|
||||
sp: span,
|
||||
tts: &[ast::token_tree]) -> @ast::expr {
|
||||
|
||||
|
|
@ -677,11 +664,11 @@ fn expand_tts(cx: @ext_ctxt,
|
|||
// We want to emit a block expression that does a sequence of 'use's to
|
||||
// import the runtime module, followed by a tt-building expression.
|
||||
|
||||
let uses = ~[ build::mk_glob_use(cx, sp, ast::public,
|
||||
ids_ext(cx, ~[~"syntax",
|
||||
~"ext",
|
||||
~"quote",
|
||||
~"rt"])) ];
|
||||
let uses = ~[ cx.view_use_glob(sp, ast::public,
|
||||
ids_ext(cx, ~[~"syntax",
|
||||
~"ext",
|
||||
~"quote",
|
||||
~"rt"])) ];
|
||||
|
||||
// We also bind a single value, sp, to ext_cx.call_site()
|
||||
//
|
||||
|
|
@ -709,54 +696,53 @@ fn expand_tts(cx: @ext_ctxt,
|
|||
// of quotes, for example) but at this point it seems not likely to be
|
||||
// worth the hassle.
|
||||
|
||||
let e_sp = build::mk_method_call(cx, sp,
|
||||
build::mk_path(cx, sp, ids_ext(cx, ~[~"ext_cx"])),
|
||||
id_ext(cx, "call_site"),
|
||||
~[]);
|
||||
let e_sp = cx.expr_method_call(sp,
|
||||
cx.expr_ident(sp, id_ext(cx, "ext_cx")),
|
||||
id_ext(cx, "call_site"),
|
||||
~[]);
|
||||
|
||||
let stmt_let_sp = build::mk_local(cx, sp, false,
|
||||
id_ext(cx, "sp"),
|
||||
e_sp);
|
||||
let stmt_let_sp = cx.stmt_let(sp, false,
|
||||
id_ext(cx, "sp"),
|
||||
e_sp);
|
||||
|
||||
let stmt_let_tt = build::mk_local(cx, sp, true,
|
||||
id_ext(cx, "tt"),
|
||||
build::mk_uniq_vec_e(cx, sp, ~[]));
|
||||
let stmt_let_tt = cx.stmt_let(sp, true,
|
||||
id_ext(cx, "tt"),
|
||||
cx.expr_vec_uniq(sp, ~[]));
|
||||
|
||||
build::mk_block(cx, sp, uses,
|
||||
~[stmt_let_sp,
|
||||
stmt_let_tt] + mk_tts(cx, sp, tts),
|
||||
Some(build::mk_path(cx, sp,
|
||||
ids_ext(cx, ~[~"tt"]))))
|
||||
cx.expr_blk(
|
||||
cx.blk_all(sp, uses,
|
||||
~[stmt_let_sp,
|
||||
stmt_let_tt] + mk_tts(cx, sp, tts),
|
||||
Some(cx.expr_ident(sp, id_ext(cx, "tt")))))
|
||||
}
|
||||
|
||||
fn expand_parse_call(cx: @ext_ctxt,
|
||||
fn expand_parse_call(cx: @ExtCtxt,
|
||||
sp: span,
|
||||
parse_method: &str,
|
||||
arg_exprs: ~[@ast::expr],
|
||||
tts: &[ast::token_tree]) -> @ast::expr {
|
||||
let tts_expr = expand_tts(cx, sp, tts);
|
||||
|
||||
let cfg_call = || build::mk_method_call(
|
||||
cx, sp, build::mk_path(cx, sp, ids_ext(cx, ~[~"ext_cx"])),
|
||||
let cfg_call = || cx.expr_method_call(
|
||||
sp, cx.expr_ident(sp, id_ext(cx, "ext_cx")),
|
||||
id_ext(cx, "cfg"), ~[]);
|
||||
|
||||
let parse_sess_call = || build::mk_method_call(
|
||||
cx, sp, build::mk_path(cx, sp, ids_ext(cx, ~[~"ext_cx"])),
|
||||
let parse_sess_call = || cx.expr_method_call(
|
||||
sp, cx.expr_ident(sp, id_ext(cx, "ext_cx")),
|
||||
id_ext(cx, "parse_sess"), ~[]);
|
||||
|
||||
let new_parser_call =
|
||||
build::mk_call_global(cx, sp,
|
||||
ids_ext(cx, ~[~"syntax",
|
||||
~"ext",
|
||||
~"quote",
|
||||
~"rt",
|
||||
~"new_parser_from_tts"]),
|
||||
~[parse_sess_call(),
|
||||
cfg_call(),
|
||||
tts_expr]);
|
||||
cx.expr_call_global(sp,
|
||||
ids_ext(cx, ~[~"syntax",
|
||||
~"ext",
|
||||
~"quote",
|
||||
~"rt",
|
||||
~"new_parser_from_tts"]),
|
||||
~[parse_sess_call(),
|
||||
cfg_call(),
|
||||
tts_expr]);
|
||||
|
||||
build::mk_method_call(cx, sp,
|
||||
new_parser_call,
|
||||
id_ext(cx, parse_method),
|
||||
arg_exprs)
|
||||
cx.expr_method_call(sp, new_parser_call,
|
||||
id_ext(cx, parse_method),
|
||||
arg_exprs)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ use codemap::{FileMap, Loc, Pos, ExpandedFrom, span};
|
|||
use codemap::{CallInfo, NameAndSpan};
|
||||
use ext::base::*;
|
||||
use ext::base;
|
||||
use ext::build::{mk_base_vec_e, mk_uint, mk_u8, mk_base_str};
|
||||
use ext::build::AstBuilder;
|
||||
use parse;
|
||||
use print::pprust;
|
||||
|
||||
|
|
@ -23,49 +23,49 @@ use print::pprust;
|
|||
// a given file into the current one.
|
||||
|
||||
/* line!(): expands to the current line number */
|
||||
pub fn expand_line(cx: @ext_ctxt, sp: span, tts: &[ast::token_tree])
|
||||
pub fn expand_line(cx: @ExtCtxt, sp: span, tts: &[ast::token_tree])
|
||||
-> base::MacResult {
|
||||
base::check_zero_tts(cx, sp, tts, "line!");
|
||||
|
||||
let topmost = topmost_expn_info(cx.backtrace().get());
|
||||
let loc = cx.codemap().lookup_char_pos(topmost.call_site.lo);
|
||||
|
||||
base::MRExpr(mk_uint(cx, topmost.call_site, loc.line))
|
||||
base::MRExpr(cx.expr_uint(topmost.call_site, loc.line))
|
||||
}
|
||||
|
||||
/* col!(): expands to the current column number */
|
||||
pub fn expand_col(cx: @ext_ctxt, sp: span, tts: &[ast::token_tree])
|
||||
pub fn expand_col(cx: @ExtCtxt, sp: span, tts: &[ast::token_tree])
|
||||
-> base::MacResult {
|
||||
base::check_zero_tts(cx, sp, tts, "col!");
|
||||
|
||||
let topmost = topmost_expn_info(cx.backtrace().get());
|
||||
let loc = cx.codemap().lookup_char_pos(topmost.call_site.lo);
|
||||
base::MRExpr(mk_uint(cx, topmost.call_site, loc.col.to_uint()))
|
||||
base::MRExpr(cx.expr_uint(topmost.call_site, loc.col.to_uint()))
|
||||
}
|
||||
|
||||
/* file!(): expands to the current filename */
|
||||
/* The filemap (`loc.file`) contains a bunch more information we could spit
|
||||
* out if we wanted. */
|
||||
pub fn expand_file(cx: @ext_ctxt, sp: span, tts: &[ast::token_tree])
|
||||
pub fn expand_file(cx: @ExtCtxt, sp: span, tts: &[ast::token_tree])
|
||||
-> base::MacResult {
|
||||
base::check_zero_tts(cx, sp, tts, "file!");
|
||||
|
||||
let topmost = topmost_expn_info(cx.backtrace().get());
|
||||
let Loc { file: @FileMap { name: filename, _ }, _ } =
|
||||
cx.codemap().lookup_char_pos(topmost.call_site.lo);
|
||||
base::MRExpr(mk_base_str(cx, topmost.call_site, filename))
|
||||
base::MRExpr(cx.expr_str(topmost.call_site, filename))
|
||||
}
|
||||
|
||||
pub fn expand_stringify(cx: @ext_ctxt, sp: span, tts: &[ast::token_tree])
|
||||
pub fn expand_stringify(cx: @ExtCtxt, sp: span, tts: &[ast::token_tree])
|
||||
-> base::MacResult {
|
||||
let s = pprust::tts_to_str(tts, cx.parse_sess().interner);
|
||||
base::MRExpr(mk_base_str(cx, sp, s))
|
||||
base::MRExpr(cx.expr_str(sp, s))
|
||||
}
|
||||
|
||||
pub fn expand_mod(cx: @ext_ctxt, sp: span, tts: &[ast::token_tree])
|
||||
pub fn expand_mod(cx: @ExtCtxt, sp: span, tts: &[ast::token_tree])
|
||||
-> base::MacResult {
|
||||
base::check_zero_tts(cx, sp, tts, "module_path!");
|
||||
base::MRExpr(mk_base_str(cx, sp,
|
||||
base::MRExpr(cx.expr_str(sp,
|
||||
str::connect(cx.mod_path().map(
|
||||
|x| cx.str_of(*x)), "::")))
|
||||
}
|
||||
|
|
@ -73,7 +73,7 @@ pub fn expand_mod(cx: @ext_ctxt, sp: span, tts: &[ast::token_tree])
|
|||
// include! : parse the given file as an expr
|
||||
// This is generally a bad idea because it's going to behave
|
||||
// unhygienically.
|
||||
pub fn expand_include(cx: @ext_ctxt, sp: span, tts: &[ast::token_tree])
|
||||
pub fn expand_include(cx: @ExtCtxt, sp: span, tts: &[ast::token_tree])
|
||||
-> base::MacResult {
|
||||
let file = get_single_str_from_tts(cx, sp, tts, "include!");
|
||||
let p = parse::new_sub_parser_from_file(
|
||||
|
|
@ -83,7 +83,7 @@ pub fn expand_include(cx: @ext_ctxt, sp: span, tts: &[ast::token_tree])
|
|||
}
|
||||
|
||||
// include_str! : read the given file, insert it as a literal string expr
|
||||
pub fn expand_include_str(cx: @ext_ctxt, sp: span, tts: &[ast::token_tree])
|
||||
pub fn expand_include_str(cx: @ExtCtxt, sp: span, tts: &[ast::token_tree])
|
||||
-> base::MacResult {
|
||||
let file = get_single_str_from_tts(cx, sp, tts, "include_str!");
|
||||
let res = io::read_whole_file_str(&res_rel_file(cx, sp, &Path(file)));
|
||||
|
|
@ -94,18 +94,18 @@ pub fn expand_include_str(cx: @ext_ctxt, sp: span, tts: &[ast::token_tree])
|
|||
}
|
||||
}
|
||||
|
||||
base::MRExpr(mk_base_str(cx, sp, result::unwrap(res)))
|
||||
base::MRExpr(cx.expr_str(sp, result::unwrap(res)))
|
||||
}
|
||||
|
||||
pub fn expand_include_bin(cx: @ext_ctxt, sp: span, tts: &[ast::token_tree])
|
||||
pub fn expand_include_bin(cx: @ExtCtxt, sp: span, tts: &[ast::token_tree])
|
||||
-> base::MacResult {
|
||||
let file = get_single_str_from_tts(cx, sp, tts, "include_bin!");
|
||||
match io::read_whole_file(&res_rel_file(cx, sp, &Path(file))) {
|
||||
result::Ok(src) => {
|
||||
let u8_exprs = vec::map(src, |char| {
|
||||
mk_u8(cx, sp, *char)
|
||||
cx.expr_u8(sp, *char)
|
||||
});
|
||||
base::MRExpr(mk_base_vec_e(cx, sp, u8_exprs))
|
||||
base::MRExpr(cx.expr_vec(sp, u8_exprs))
|
||||
}
|
||||
result::Err(ref e) => {
|
||||
cx.parse_sess().span_diagnostic.handler().fatal((*e))
|
||||
|
|
@ -141,7 +141,7 @@ fn topmost_expn_info(expn_info: @codemap::ExpnInfo) -> @codemap::ExpnInfo {
|
|||
|
||||
// resolve a file-system path to an absolute file-system path (if it
|
||||
// isn't already)
|
||||
fn res_rel_file(cx: @ext_ctxt, sp: codemap::span, arg: &Path) -> Path {
|
||||
fn res_rel_file(cx: @ExtCtxt, sp: codemap::span, arg: &Path) -> Path {
|
||||
// NB: relative paths are resolved relative to the compilation unit
|
||||
if !arg.is_absolute {
|
||||
let cu = Path(cx.codemap().span_to_filename(sp));
|
||||
|
|
|
|||
|
|
@ -10,12 +10,12 @@
|
|||
|
||||
use ast;
|
||||
use codemap::span;
|
||||
use ext::base::ext_ctxt;
|
||||
use ext::base::ExtCtxt;
|
||||
use ext::base;
|
||||
use parse::lexer::{new_tt_reader, reader};
|
||||
use parse::parser::Parser;
|
||||
|
||||
pub fn expand_trace_macros(cx: @ext_ctxt,
|
||||
pub fn expand_trace_macros(cx: @ExtCtxt,
|
||||
sp: span,
|
||||
tt: &[ast::token_tree])
|
||||
-> base::MacResult {
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ use ast::{ident, matcher_, matcher, match_tok, match_nonterminal, match_seq};
|
|||
use ast::{tt_delim};
|
||||
use ast;
|
||||
use codemap::{span, spanned, dummy_sp};
|
||||
use ext::base::{ext_ctxt, MacResult, MRAny, MRDef, MacroDef, NormalTT};
|
||||
use ext::base::{ExtCtxt, MacResult, MRAny, MRDef, MacroDef, NormalTT};
|
||||
use ext::base;
|
||||
use ext::tt::macro_parser::{error};
|
||||
use ext::tt::macro_parser::{named_match, matched_seq, matched_nonterminal};
|
||||
|
|
@ -26,7 +26,7 @@ use print;
|
|||
|
||||
use core::io;
|
||||
|
||||
pub fn add_new_extension(cx: @ext_ctxt,
|
||||
pub fn add_new_extension(cx: @ExtCtxt,
|
||||
sp: span,
|
||||
name: ident,
|
||||
arg: ~[ast::token_tree])
|
||||
|
|
@ -73,7 +73,7 @@ pub fn add_new_extension(cx: @ext_ctxt,
|
|||
};
|
||||
|
||||
// Given `lhses` and `rhses`, this is the new macro we create
|
||||
fn generic_extension(cx: @ext_ctxt, sp: span, name: ident,
|
||||
fn generic_extension(cx: @ExtCtxt, sp: span, name: ident,
|
||||
arg: &[ast::token_tree],
|
||||
lhses: &[@named_match], rhses: &[@named_match])
|
||||
-> MacResult {
|
||||
|
|
@ -145,7 +145,7 @@ pub fn add_new_extension(cx: @ext_ctxt,
|
|||
cx.span_fatal(best_fail_spot, best_fail_msg);
|
||||
}
|
||||
|
||||
let exp: @fn(@ext_ctxt, span, &[ast::token_tree]) -> MacResult =
|
||||
let exp: @fn(@ExtCtxt, span, &[ast::token_tree]) -> MacResult =
|
||||
|cx, sp, arg| generic_extension(cx, sp, name, arg, *lhses, *rhses);
|
||||
|
||||
return MRDef(MacroDef{
|
||||
|
|
|
|||
|
|
@ -12,9 +12,9 @@
|
|||
|
||||
extern mod syntax;
|
||||
|
||||
use syntax::ext::base::ext_ctxt;
|
||||
use syntax::ext::base::ExtCtxt;
|
||||
|
||||
fn syntax_extension(ext_cx: @ext_ctxt) {
|
||||
fn syntax_extension(ext_cx: @ExtCtxt) {
|
||||
let e_toks : ~[syntax::ast::token_tree] = quote_tokens!(1 + 2);
|
||||
let p_toks : ~[syntax::ast::token_tree] = quote_tokens!((x, 1 .. 4, *));
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue