diff options
| author | Marijn Haverbeke <marijnh@gmail.com> | 2011-07-27 14:19:39 +0200 |
|---|---|---|
| committer | Marijn Haverbeke <marijnh@gmail.com> | 2011-07-27 15:54:33 +0200 |
| commit | df7f21db093b0f206048b18e977161f91b7c28f1 (patch) | |
| tree | 36c56d12572266bd0b8d2b3379e52d04bf0e9152 /src/comp/syntax/ext | |
| parent | 0e3ee39c41462652f41993a5610265abea6daa96 (diff) | |
Reformat for new syntax
Diffstat (limited to 'src/comp/syntax/ext')
| -rw-r--r-- | src/comp/syntax/ext/base.rs | 98 | ||||
| -rw-r--r-- | src/comp/syntax/ext/env.rs | 23 | ||||
| -rw-r--r-- | src/comp/syntax/ext/expand.rs | 86 | ||||
| -rw-r--r-- | src/comp/syntax/ext/fmt.rs | 482 | ||||
| -rw-r--r-- | src/comp/syntax/ext/simplext.rs | 845 |
5 files changed, 739 insertions, 795 deletions
diff --git a/src/comp/syntax/ext/base.rs b/src/comp/syntax/ext/base.rs index ac970c64961..ed869e79f4e 100644 --- a/src/comp/syntax/ext/base.rs +++ b/src/comp/syntax/ext/base.rs @@ -7,10 +7,10 @@ import std::map::new_str_hash; import codemap; type syntax_expander = - fn(&ext_ctxt, span, &(@ast::expr)[], option::t[str]) -> @ast::expr; -type macro_def = rec(str ident, syntax_extension ext); -type macro_definer = fn(&ext_ctxt, span, &(@ast::expr)[], - option::t[str]) -> macro_def; + fn(&ext_ctxt, span, &(@ast::expr)[], option::t[str]) -> @ast::expr ; +type macro_def = {ident: str, ext: syntax_extension}; +type macro_definer = + fn(&ext_ctxt, span, &(@ast::expr)[], option::t[str]) -> macro_def ; tag syntax_extension { normal(syntax_expander); @@ -20,7 +20,7 @@ tag syntax_extension { // A temporary hard-coded map of methods for expanding syntax extension // AST nodes into full ASTs fn syntax_expander_table() -> hashmap[str, syntax_extension] { - auto syntax_expanders = new_str_hash[syntax_extension](); + let syntax_expanders = new_str_hash[syntax_extension](); syntax_expanders.insert("fmt", normal(ext::fmt::expand_syntax_ext)); syntax_expanders.insert("env", normal(ext::env::expand_syntax_ext)); syntax_expanders.insert("macro", @@ -37,34 +37,31 @@ type next_id_fn = fn() -> ast::node_id ; // Provides a limited set of services necessary for syntax extensions // to do their thing type ext_ctxt = - rec(str crate_file_name_hack, - span_msg_fn span_fatal, - span_msg_fn span_unimpl, - span_msg_fn span_bug, - msg_fn bug, - next_id_fn next_id); - -fn mk_ctxt(&session sess) -> ext_ctxt { - fn ext_span_fatal_(&session sess, span sp, str msg) -> ! { + {crate_file_name_hack: str, + span_fatal: span_msg_fn, + span_unimpl: span_msg_fn, + span_bug: span_msg_fn, + bug: msg_fn, + next_id: next_id_fn}; + +fn mk_ctxt(sess: &session) -> ext_ctxt { + fn ext_span_fatal_(sess: &session, sp: span, msg: str) -> ! { sess.span_err(sp, msg); fail; } - auto ext_span_fatal = bind ext_span_fatal_(sess, _, _); - fn ext_span_unimpl_(&session sess, span sp, str msg) -> ! { + let ext_span_fatal = bind ext_span_fatal_(sess, _, _); + fn ext_span_unimpl_(sess: &session, sp: span, msg: str) -> ! { sess.span_err(sp, "unimplemented " + msg); fail; } - auto ext_span_unimpl = bind ext_span_unimpl_(sess, _, _); - fn ext_span_bug_(&session sess, span sp, str msg) -> ! { + let ext_span_unimpl = bind ext_span_unimpl_(sess, _, _); + fn ext_span_bug_(sess: &session, sp: span, msg: str) -> ! { sess.span_bug(sp, msg); fail; } - auto ext_span_bug = bind ext_span_bug_(sess, _, _); - fn ext_bug_(&session sess, str msg) -> ! { - sess.bug(msg); - fail; - } - auto ext_bug = bind ext_bug_(sess, _); + let ext_span_bug = bind ext_span_bug_(sess, _, _); + fn ext_bug_(sess: &session, msg: str) -> ! { sess.bug(msg); fail; } + let ext_bug = bind ext_bug_(sess, _); // FIXME: Some extensions work by building ASTs with paths to functions @@ -74,45 +71,40 @@ fn mk_ctxt(&session sess) -> ext_ctxt { // the extensions the file name of the crate being compiled so they can // use it to guess whether paths should be prepended with "std::". This is // super-ugly and needs a better solution. - auto crate_file_name_hack = sess.get_codemap().files.(0).name; + let crate_file_name_hack = sess.get_codemap().files.(0).name; - fn ext_next_id_(&session sess) -> ast::node_id { + fn ext_next_id_(sess: &session) -> ast::node_id { ret sess.next_node_id(); // temporary, until bind works better } - auto ext_next_id = bind ext_next_id_(sess); - ret rec(crate_file_name_hack=crate_file_name_hack, - span_fatal=ext_span_fatal, - span_unimpl=ext_span_unimpl, - span_bug=ext_span_bug, - bug=ext_bug, - next_id=ext_next_id); + let ext_next_id = bind ext_next_id_(sess); + ret {crate_file_name_hack: crate_file_name_hack, + span_fatal: ext_span_fatal, + span_unimpl: ext_span_unimpl, + span_bug: ext_span_bug, + bug: ext_bug, + next_id: ext_next_id}; } -fn expr_to_str(&ext_ctxt cx, @ast::expr expr, str error) -> str { - alt (expr.node) { - case (ast::expr_lit(?l)) { - alt (l.node) { - case (ast::lit_str(?s, _)) { ret s; } - case (_) { cx.span_fatal(l.span, error); } - } +fn expr_to_str(cx: &ext_ctxt, expr: @ast::expr, error: str) -> str { + alt expr.node { + ast::expr_lit(l) { + alt l.node { + ast::lit_str(s, _) { ret s; } + _ { cx.span_fatal(l.span, error); } } - case (_) { cx.span_fatal(expr.span, error); } + } + _ { cx.span_fatal(expr.span, error); } } } -fn expr_to_ident(&ext_ctxt cx, @ast::expr expr, str error) -> ast::ident { - alt(expr.node) { - case (ast::expr_path(?p)) { - if (ivec::len(p.node.types) > 0u - || ivec::len(p.node.idents) != 1u) { - cx.span_fatal(expr.span, error); - } else { - ret p.node.idents.(0); - } - } - case (_) { +fn expr_to_ident(cx: &ext_ctxt, expr: @ast::expr, error: str) -> ast::ident { + alt expr.node { + ast::expr_path(p) { + if ivec::len(p.node.types) > 0u || ivec::len(p.node.idents) != 1u { cx.span_fatal(expr.span, error); - } + } else { ret p.node.idents.(0); } + } + _ { cx.span_fatal(expr.span, error); } } } diff --git a/src/comp/syntax/ext/env.rs b/src/comp/syntax/ext/env.rs index 8c02d2e1e2f..88b3e3a720c 100644 --- a/src/comp/syntax/ext/env.rs +++ b/src/comp/syntax/ext/env.rs @@ -12,27 +12,28 @@ import std::generic_os; import base::*; export expand_syntax_ext; -fn expand_syntax_ext(&ext_ctxt cx, codemap::span sp, &(@ast::expr)[] args, - option::t[str] body) -> @ast::expr { - if (ivec::len[@ast::expr](args) != 1u) { +fn expand_syntax_ext(cx: &ext_ctxt, sp: codemap::span, args: &(@ast::expr)[], + body: option::t[str]) -> @ast::expr { + if ivec::len[@ast::expr](args) != 1u { cx.span_fatal(sp, "malformed #env call"); } // FIXME: if this was more thorough it would manufacture an // option::t[str] rather than just an maybe-empty string. - auto var = expr_to_str(cx, args.(0), "#env requires a string"); - alt (generic_os::getenv(var)) { - case (option::none) { ret make_new_str(cx, sp, ""); } - case (option::some(?s)) { ret make_new_str(cx, sp, s); } + let var = expr_to_str(cx, args.(0), "#env requires a string"); + alt generic_os::getenv(var) { + option::none. { ret make_new_str(cx, sp, ""); } + option::some(s) { ret make_new_str(cx, sp, s); } } } -fn make_new_lit(&ext_ctxt cx, codemap::span sp, ast::lit_ lit) -> @ast::expr { - auto sp_lit = @rec(node=lit, span=sp); - ret @rec(id=cx.next_id(), node=ast::expr_lit(sp_lit), span=sp); +fn make_new_lit(cx: &ext_ctxt, sp: codemap::span, lit: ast::lit_) -> + @ast::expr { + let sp_lit = @{node: lit, span: sp}; + ret @{id: cx.next_id(), node: ast::expr_lit(sp_lit), span: sp}; } -fn make_new_str(&ext_ctxt cx, codemap::span sp, str s) -> @ast::expr { +fn make_new_str(cx: &ext_ctxt, sp: codemap::span, s: str) -> @ast::expr { ret make_new_lit(cx, sp, ast::lit_str(s, ast::sk_rc)); } // diff --git a/src/comp/syntax/ext/expand.rs b/src/comp/syntax/ext/expand.rs index d6fbae88628..e47a0fc2a71 100644 --- a/src/comp/syntax/ext/expand.rs +++ b/src/comp/syntax/ext/expand.rs @@ -13,56 +13,54 @@ import std::option::some; import std::map::hashmap; import std::ivec; -fn expand_expr(&hashmap[str, base::syntax_extension] exts, - &session::session sess, &expr_ e, ast_fold fld, - &fn(&ast::expr_, ast_fold) -> expr_ orig) -> expr_ { - ret alt(e) { - case (expr_mac(?mac)) { - alt(mac.node) { - case (mac_invoc(?pth, ?args, ?body)) { - assert(ivec::len(pth.node.idents) > 0u); - auto extname = pth.node.idents.(0); - auto ext_cx = base::mk_ctxt(sess); - alt (exts.find(extname)) { - case (none) { - emit_error(some(pth.span), - "unknown syntax expander: '" - + extname + "'", sess.get_codemap()); - fail - } - case (some(base::normal(?ext))) { - //keep going, outside-in - fld.fold_expr(ext(ext_cx, pth.span, - args, body)).node - } - case (some(base::macro_defining(?ext))) { - auto named_extension - = ext(ext_cx, pth.span, args, body); - exts.insert(named_extension.ident, - named_extension.ext); - ast::expr_rec(~[], none) - } - } - } - case (_) { - emit_error(some(mac.span), "naked syntactic bit", +fn expand_expr(exts: &hashmap[str, base::syntax_extension], + sess: &session::session, e: &expr_, fld: ast_fold, + orig: &fn(&ast::expr_, ast_fold) -> expr_ ) -> expr_ { + ret alt e { + expr_mac(mac) { + alt mac.node { + mac_invoc(pth, args, body) { + assert (ivec::len(pth.node.idents) > 0u); + let extname = pth.node.idents.(0); + let ext_cx = base::mk_ctxt(sess); + alt exts.find(extname) { + none. { + emit_error(some(pth.span), + "unknown syntax expander: '" + extname + "'", sess.get_codemap()); fail + } + some(base::normal(ext)) { + + //keep going, outside-in + fld.fold_expr(ext(ext_cx, pth.span, args, body)).node + } + some(base::macro_defining(ext)) { + let named_extension = ext(ext_cx, pth.span, args, body); + exts.insert(named_extension.ident, named_extension.ext); + ast::expr_rec(~[], none) + } } + } + _ { + emit_error(some(mac.span), "naked syntactic bit", + sess.get_codemap()); + fail + } } - } - case (_) { orig(e, fld) } - }; + } + _ { orig(e, fld) } + }; } -fn expand_crate(&session::session sess, &@crate c) -> @crate { - auto exts = ext::base::syntax_expander_table(); - auto afp = default_ast_fold(); - auto f_pre = - rec(fold_expr = bind expand_expr(exts, sess, _, _, afp.fold_expr) - with *afp); - auto f = make_fold(f_pre); - auto res = @f.fold_crate(*c); +fn expand_crate(sess: &session::session, c: &@crate) -> @crate { + let exts = ext::base::syntax_expander_table(); + let afp = default_ast_fold(); + let f_pre = + {fold_expr: bind expand_expr(exts, sess, _, _, afp.fold_expr) + with *afp}; + let f = make_fold(f_pre); + let res = @f.fold_crate(*c); dummy_out(f); //temporary: kill circular reference ret res; diff --git a/src/comp/syntax/ext/fmt.rs b/src/comp/syntax/ext/fmt.rs index b69b27f5ef4..4374030d10a 100644 --- a/src/comp/syntax/ext/fmt.rs +++ b/src/comp/syntax/ext/fmt.rs @@ -16,116 +16,110 @@ import base::*; import codemap::span; export expand_syntax_ext; -fn expand_syntax_ext(&ext_ctxt cx, span sp, &(@ast::expr)[] args, - option::t[str] body) -> @ast::expr { - if (ivec::len[@ast::expr](args) == 0u) { +fn expand_syntax_ext(cx: &ext_ctxt, sp: span, args: &(@ast::expr)[], + body: option::t[str]) -> @ast::expr { + if ivec::len[@ast::expr](args) == 0u { cx.span_fatal(sp, "#fmt requires a format string"); } - auto fmt = expr_to_str(cx, args.(0), "first argument to #fmt must be a " - + "string literal."); - auto fmtspan = args.(0).span; + let fmt = + expr_to_str(cx, args.(0), + "first argument to #fmt must be a " + "string literal."); + let fmtspan = args.(0).span; log "Format string:"; log fmt; - fn parse_fmt_err_(&ext_ctxt cx, span sp, str msg) -> ! { + fn parse_fmt_err_(cx: &ext_ctxt, sp: span, msg: str) -> ! { cx.span_fatal(sp, msg); } - auto parse_fmt_err = bind parse_fmt_err_(cx, fmtspan, _); - auto pieces = parse_fmt_string(fmt, parse_fmt_err); + let parse_fmt_err = bind parse_fmt_err_(cx, fmtspan, _); + let pieces = parse_fmt_string(fmt, parse_fmt_err); ret pieces_to_expr(cx, sp, pieces, args); } // FIXME: A lot of these functions for producing expressions can probably // be factored out in common with other code that builds expressions. // FIXME: Cleanup the naming of these functions -fn pieces_to_expr(&ext_ctxt cx, span sp, vec[piece] pieces, - &(@ast::expr)[] args) -> @ast::expr { - fn make_new_lit(&ext_ctxt cx, span sp, ast::lit_ lit) -> - @ast::expr { - auto sp_lit = @rec(node=lit, span=sp); - ret @rec(id=cx.next_id(), node=ast::expr_lit(sp_lit), span=sp); +fn pieces_to_expr(cx: &ext_ctxt, sp: span, pieces: vec[piece], + args: &(@ast::expr)[]) -> @ast::expr { + fn make_new_lit(cx: &ext_ctxt, sp: span, lit: ast::lit_) -> @ast::expr { + let sp_lit = @{node: lit, span: sp}; + ret @{id: cx.next_id(), node: ast::expr_lit(sp_lit), span: sp}; } - fn make_new_str(&ext_ctxt cx, span sp, str s) -> @ast::expr { - auto lit = ast::lit_str(s, ast::sk_rc); + fn make_new_str(cx: &ext_ctxt, sp: span, s: str) -> @ast::expr { + let lit = ast::lit_str(s, ast::sk_rc); ret make_new_lit(cx, sp, lit); } - fn make_new_int(&ext_ctxt cx, span sp, int i) -> @ast::expr { - auto lit = ast::lit_int(i); + fn make_new_int(cx: &ext_ctxt, sp: span, i: int) -> @ast::expr { + let lit = ast::lit_int(i); ret make_new_lit(cx, sp, lit); } - fn make_new_uint(&ext_ctxt cx, span sp, uint u) -> @ast::expr { - auto lit = ast::lit_uint(u); + fn make_new_uint(cx: &ext_ctxt, sp: span, u: uint) -> @ast::expr { + let lit = ast::lit_uint(u); ret make_new_lit(cx, sp, lit); } - fn make_add_expr(&ext_ctxt cx, span sp, @ast::expr lhs, - @ast::expr rhs) -> @ast::expr { - auto binexpr = ast::expr_binary(ast::add, lhs, rhs); - ret @rec(id=cx.next_id(), node=binexpr, span=sp); + fn make_add_expr(cx: &ext_ctxt, sp: span, lhs: @ast::expr, + rhs: @ast::expr) -> @ast::expr { + let binexpr = ast::expr_binary(ast::add, lhs, rhs); + ret @{id: cx.next_id(), node: binexpr, span: sp}; } - fn make_path_expr(&ext_ctxt cx, span sp, &ast::ident[] idents) - -> @ast::expr { - auto path = rec(global=false, idents=idents, types=~[]); - auto sp_path = rec(node=path, span=sp); - auto pathexpr = ast::expr_path(sp_path); - ret @rec(id=cx.next_id(), node=pathexpr, span=sp); + fn make_path_expr(cx: &ext_ctxt, sp: span, idents: &ast::ident[]) -> + @ast::expr { + let path = {global: false, idents: idents, types: ~[]}; + let sp_path = {node: path, span: sp}; + let pathexpr = ast::expr_path(sp_path); + ret @{id: cx.next_id(), node: pathexpr, span: sp}; } - fn make_vec_expr(&ext_ctxt cx, span sp, &(@ast::expr)[] exprs) -> + fn make_vec_expr(cx: &ext_ctxt, sp: span, exprs: &(@ast::expr)[]) -> @ast::expr { - auto vecexpr = ast::expr_vec(exprs, ast::imm, ast::sk_rc); - ret @rec(id=cx.next_id(), node=vecexpr, span=sp); + let vecexpr = ast::expr_vec(exprs, ast::imm, ast::sk_rc); + ret @{id: cx.next_id(), node: vecexpr, span: sp}; } - fn make_call(&ext_ctxt cx, span sp, &ast::ident[] fn_path, - &(@ast::expr)[] args) -> @ast::expr { - auto pathexpr = make_path_expr(cx, sp, fn_path); - auto callexpr = ast::expr_call(pathexpr, args); - ret @rec(id=cx.next_id(), node=callexpr, span=sp); + fn make_call(cx: &ext_ctxt, sp: span, fn_path: &ast::ident[], + args: &(@ast::expr)[]) -> @ast::expr { + let pathexpr = make_path_expr(cx, sp, fn_path); + let callexpr = ast::expr_call(pathexpr, args); + ret @{id: cx.next_id(), node: callexpr, span: sp}; } - fn make_rec_expr(&ext_ctxt cx, span sp, - vec[rec(ast::ident ident, @ast::expr ex)] fields) - -> @ast::expr { - let ast::field[] astfields = ~[]; - for (rec(ast::ident ident, @ast::expr ex) field in fields) { - auto ident = field.ident; - auto val = field.ex; - auto astfield = - rec(node=rec(mut=ast::imm, ident=ident, expr=val), span=sp); + fn make_rec_expr(cx: &ext_ctxt, sp: span, + fields: vec[{ident: ast::ident, ex: @ast::expr}]) -> + @ast::expr { + let astfields: ast::field[] = ~[]; + for field: {ident: ast::ident, ex: @ast::expr} in fields { + let ident = field.ident; + let val = field.ex; + let astfield = + {node: {mut: ast::imm, ident: ident, expr: val}, span: sp}; astfields += ~[astfield]; } - auto recexpr = ast::expr_rec(astfields, option::none[@ast::expr]); - ret @rec(id=cx.next_id(), node=recexpr, span=sp); + let recexpr = ast::expr_rec(astfields, option::none[@ast::expr]); + ret @{id: cx.next_id(), node: recexpr, span: sp}; } - fn make_path_vec(&ext_ctxt cx, str ident) -> str[] { - fn compiling_std(&ext_ctxt cx) -> bool { + fn make_path_vec(cx: &ext_ctxt, ident: str) -> str[] { + fn compiling_std(cx: &ext_ctxt) -> bool { ret str::find(cx.crate_file_name_hack, "std.rc") >= 0; } - if (compiling_std(cx)) { + if compiling_std(cx) { ret ~["extfmt", "rt", ident]; - } else { - ret ~["std", "extfmt", "rt", ident]; - } + } else { ret ~["std", "extfmt", "rt", ident]; } } - fn make_rt_path_expr(&ext_ctxt cx, span sp, str ident) -> - @ast::expr { - auto path = make_path_vec(cx, ident); + fn make_rt_path_expr(cx: &ext_ctxt, sp: span, ident: str) -> @ast::expr { + let path = make_path_vec(cx, ident); ret make_path_expr(cx, 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(&ext_ctxt cx, span sp, &conv cnv) -> - @ast::expr { - fn make_flags(&ext_ctxt cx, span sp, vec[flag] flags) -> + fn make_rt_conv_expr(cx: &ext_ctxt, sp: span, cnv: &conv) -> @ast::expr { + fn make_flags(cx: &ext_ctxt, sp: span, flags: vec[flag]) -> @ast::expr { - let (@ast::expr)[] flagexprs = ~[]; - for (flag f in flags) { - auto fstr; - alt (f) { - case (flag_left_justify) { fstr = "flag_left_justify"; } - case (flag_left_zero_pad) { fstr = "flag_left_zero_pad"; } - case (flag_space_for_sign) { - fstr = "flag_space_for_sign"; - } - case (flag_sign_always) { fstr = "flag_sign_always"; } - case (flag_alternate) { fstr = "flag_alternate"; } + let flagexprs: (@ast::expr)[] = ~[]; + for f: flag in flags { + let fstr; + alt f { + flag_left_justify. { fstr = "flag_left_justify"; } + flag_left_zero_pad. { fstr = "flag_left_zero_pad"; } + flag_space_for_sign. { fstr = "flag_space_for_sign"; } + flag_sign_always. { fstr = "flag_sign_always"; } + flag_alternate. { fstr = "flag_alternate"; } } flagexprs += ~[make_rt_path_expr(cx, sp, fstr)]; } @@ -133,235 +127,211 @@ fn pieces_to_expr(&ext_ctxt cx, span sp, vec[piece] pieces, // through the rec that these flags are a member of, so // this is a hack placeholder flag - if (ivec::len[@ast::expr](flagexprs) == 0u) { + if ivec::len[@ast::expr](flagexprs) == 0u { flagexprs += ~[make_rt_path_expr(cx, sp, "flag_none")]; } ret make_vec_expr(cx, sp, flagexprs); } - fn make_count(&ext_ctxt cx, span sp, &count cnt) -> - @ast::expr { - alt (cnt) { - case (count_implied) { - ret make_rt_path_expr(cx, sp, "count_implied"); - } - case (count_is(?c)) { - auto count_lit = make_new_int(cx, sp, c); - auto count_is_path = make_path_vec(cx, "count_is"); - auto count_is_args = ~[count_lit]; - ret make_call(cx, sp, count_is_path, count_is_args); - } - case (_) { - cx.span_unimpl(sp, "unimplemented #fmt conversion"); - } + fn make_count(cx: &ext_ctxt, sp: span, cnt: &count) -> @ast::expr { + alt cnt { + count_implied. { + ret make_rt_path_expr(cx, sp, "count_implied"); + } + count_is(c) { + let count_lit = make_new_int(cx, sp, c); + let count_is_path = make_path_vec(cx, "count_is"); + let count_is_args = ~[count_lit]; + ret make_call(cx, sp, count_is_path, count_is_args); + } + _ { cx.span_unimpl(sp, "unimplemented #fmt conversion"); } } } - fn make_ty(&ext_ctxt cx, span sp, &ty t) -> @ast::expr { - auto rt_type; - alt (t) { - case (ty_hex(?c)) { - alt (c) { - case (case_upper) { rt_type = "ty_hex_upper"; } - case (case_lower) { rt_type = "ty_hex_lower"; } - } + fn make_ty(cx: &ext_ctxt, sp: span, t: &ty) -> @ast::expr { + let rt_type; + alt t { + ty_hex(c) { + alt c { + case_upper. { rt_type = "ty_hex_upper"; } + case_lower. { rt_type = "ty_hex_lower"; } } - case (ty_bits) { rt_type = "ty_bits"; } - case (ty_octal) { rt_type = "ty_octal"; } - case (_) { rt_type = "ty_default"; } + } + ty_bits. { rt_type = "ty_bits"; } + ty_octal. { rt_type = "ty_octal"; } + _ { rt_type = "ty_default"; } } ret make_rt_path_expr(cx, sp, rt_type); } - fn make_conv_rec(&ext_ctxt cx, span sp, @ast::expr flags_expr, - @ast::expr width_expr, @ast::expr precision_expr, - @ast::expr ty_expr) -> @ast::expr { + fn make_conv_rec(cx: &ext_ctxt, sp: span, flags_expr: @ast::expr, + width_expr: @ast::expr, precision_expr: @ast::expr, + ty_expr: @ast::expr) -> @ast::expr { ret make_rec_expr(cx, sp, - [rec(ident="flags", ex=flags_expr), - rec(ident="width", ex=width_expr), - rec(ident="precision", ex=precision_expr), - rec(ident="ty", ex=ty_expr)]); + [{ident: "flags", ex: flags_expr}, + {ident: "width", ex: width_expr}, + {ident: "precision", ex: precision_expr}, + {ident: "ty", ex: ty_expr}]); } - auto rt_conv_flags = make_flags(cx, sp, cnv.flags); - auto rt_conv_width = make_count(cx, sp, cnv.width); - auto rt_conv_precision = make_count(cx, sp, cnv.precision); - auto rt_conv_ty = make_ty(cx, sp, cnv.ty); + let rt_conv_flags = make_flags(cx, sp, cnv.flags); + let rt_conv_width = make_count(cx, sp, cnv.width); + let rt_conv_precision = make_count(cx, sp, cnv.precision); + let rt_conv_ty = make_ty(cx, sp, cnv.ty); ret make_conv_rec(cx, sp, rt_conv_flags, rt_conv_width, rt_conv_precision, rt_conv_ty); } - fn make_conv_call(&ext_ctxt cx, span sp, str conv_type, &conv cnv, - @ast::expr arg) -> @ast::expr { - auto fname = "conv_" + conv_type; - auto path = make_path_vec(cx, fname); - auto cnv_expr = make_rt_conv_expr(cx, sp, cnv); - auto args = ~[cnv_expr, arg]; + fn make_conv_call(cx: &ext_ctxt, sp: span, conv_type: str, cnv: &conv, + arg: @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]; ret make_call(cx, arg.span, path, args); } - fn make_new_conv(&ext_ctxt cx, span sp, conv cnv, @ast::expr arg) - -> @ast::expr { + fn make_new_conv(cx: &ext_ctxt, sp: span, cnv: conv, arg: @ast::expr) -> + @ast::expr { // FIXME: Extract all this validation into extfmt::ct - fn is_signed_type(conv cnv) -> bool { - alt (cnv.ty) { - case (ty_int(?s)) { - alt (s) { - case (signed) { ret true; } - case (unsigned) { ret false; } - } - } - case (_) { ret false; } + fn is_signed_type(cnv: conv) -> bool { + alt cnv.ty { + ty_int(s) { + alt s { signed. { ret true; } unsigned. { ret false; } } + } + _ { ret false; } } } - auto unsupported = "conversion not supported in #fmt string"; - alt (cnv.param) { - case (option::none) { } - case (_) { cx.span_unimpl(sp, unsupported); } + let unsupported = "conversion not supported in #fmt string"; + alt cnv.param { + option::none. { } + _ { cx.span_unimpl(sp, unsupported); } } - for (flag f in cnv.flags) { - alt (f) { - case (flag_left_justify) { } - case (flag_sign_always) { - if (!is_signed_type(cnv)) { - cx.span_fatal(sp, - "+ flag only valid in " + - "signed #fmt conversion"); - } + for f: flag in cnv.flags { + alt f { + flag_left_justify. { } + flag_sign_always. { + if !is_signed_type(cnv) { + cx.span_fatal(sp, + "+ flag only valid in " + + "signed #fmt conversion"); } - case (flag_space_for_sign) { - if (!is_signed_type(cnv)) { - cx.span_fatal(sp, - "space flag only valid in " + - "signed #fmt conversions"); - } + } + flag_space_for_sign. { + if !is_signed_type(cnv) { + cx.span_fatal(sp, + "space flag only valid in " + + "signed #fmt conversions"); } - case (flag_left_zero_pad) { } - case (_) { cx.span_unimpl(sp, unsupported); } + } + flag_left_zero_pad. { } + _ { cx.span_unimpl(sp, unsupported); } } } - alt (cnv.width) { - case (count_implied) { } - case (count_is(_)) { } - case (_) { cx.span_unimpl(sp, unsupported); } + alt cnv.width { + count_implied. { } + count_is(_) { } + _ { cx.span_unimpl(sp, unsupported); } } - alt (cnv.precision) { - case (count_implied) { } - case (count_is(_)) { } - case (_) { cx.span_unimpl(sp, unsupported); } + alt cnv.precision { + count_implied. { } + count_is(_) { } + _ { cx.span_unimpl(sp, unsupported); } } - alt (cnv.ty) { - case (ty_str) { - ret make_conv_call(cx, arg.span, "str", cnv, arg); - } - case (ty_int(?sign)) { - alt (sign) { - case (signed) { - ret make_conv_call(cx, arg.span, "int", cnv, arg); - } - case (unsigned) { - ret make_conv_call(cx, arg.span, "uint", cnv, arg); - } - } - } - case (ty_bool) { - ret make_conv_call(cx, arg.span, "bool", cnv, arg); - } - case (ty_char) { - ret make_conv_call(cx, arg.span, "char", cnv, arg); - } - case (ty_hex(_)) { - ret make_conv_call(cx, arg.span, "uint", cnv, arg); - } - case (ty_bits) { - ret make_conv_call(cx, arg.span, "uint", cnv, arg); - } - case (ty_octal) { + alt cnv.ty { + ty_str. { ret make_conv_call(cx, arg.span, "str", cnv, arg); } + ty_int(sign) { + alt sign { + signed. { ret make_conv_call(cx, arg.span, "int", cnv, arg); } + unsigned. { ret make_conv_call(cx, arg.span, "uint", cnv, arg); + } } - case (_) { cx.span_unimpl(sp, unsupported); } + } + ty_bool. { ret make_conv_call(cx, arg.span, "bool", cnv, arg); } + ty_char. { ret make_conv_call(cx, arg.span, "char", cnv, arg); } + ty_hex(_) { ret make_conv_call(cx, arg.span, "uint", cnv, arg); } + ty_bits. { ret make_conv_call(cx, arg.span, "uint", cnv, arg); } + ty_octal. { ret make_conv_call(cx, arg.span, "uint", cnv, arg); } + _ { cx.span_unimpl(sp, unsupported); } } } - fn log_conv(conv c) { - alt (c.param) { - case (some(?p)) { log "param: " + std::int::to_str(p, 10u); } - case (_) { log "param: none"; } + fn log_conv(c: conv) { + alt c.param { + some(p) { log "param: " + std::int::to_str(p, 10u); } + _ { log "param: none"; } } - for (flag f in c.flags) { - alt (f) { - case (flag_left_justify) { log "flag: left justify"; } - case (flag_left_zero_pad) { log "flag: left zero pad"; } - case (flag_space_for_sign) { log "flag: left space pad"; } - case (flag_sign_always) { log "flag: sign always"; } - case (flag_alternate) { log "flag: alternate"; } + for f: flag in c.flags { + alt f { + flag_left_justify. { log "flag: left justify"; } + flag_left_zero_pad. { log "flag: left zero pad"; } + flag_space_for_sign. { log "flag: left space pad"; } + flag_sign_always. { log "flag: sign always"; } + flag_alternate. { log "flag: alternate"; } } } - alt (c.width) { - case (count_is(?i)) { - log "width: count is " + std::int::to_str(i, 10u); - } - case (count_is_param(?i)) { - log "width: count is param " + std::int::to_str(i, 10u); - } - case (count_is_next_param) { log "width: count is next param"; } - case (count_implied) { log "width: count is implied"; } + alt c.width { + count_is(i) { log "width: count is " + std::int::to_str(i, 10u); } + count_is_param(i) { + log "width: count is param " + std::int::to_str(i, 10u); + } + count_is_next_param. { log "width: count is next param"; } + count_implied. { log "width: count is implied"; } } - alt (c.precision) { - case (count_is(?i)) { - log "prec: count is " + std::int::to_str(i, 10u); - } - case (count_is_param(?i)) { - log "prec: count is param " + std::int::to_str(i, 10u); - } - case (count_is_next_param) { log "prec: count is next param"; } - case (count_implied) { log "prec: count is implied"; } + alt c.precision { + count_is(i) { log "prec: count is " + std::int::to_str(i, 10u); } + count_is_param(i) { + log "prec: count is param " + std::int::to_str(i, 10u); + } + count_is_next_param. { log "prec: count is next param"; } + count_implied. { log "prec: count is implied"; } } - alt (c.ty) { - case (ty_bool) { log "type: bool"; } - case (ty_str) { log "type: str"; } - case (ty_char) { log "type: char"; } - case (ty_int(?s)) { - alt (s) { - case (signed) { log "type: signed"; } - case (unsigned) { log "type: unsigned"; } - } + alt c.ty { + ty_bool. { log "type: bool"; } + ty_str. { log "type: str"; } + ty_char. { log "type: char"; } + ty_int(s) { + alt s { + signed. { log "type: signed"; } + unsigned. { log "type: unsigned"; } } - case (ty_bits) { log "type: bits"; } - case (ty_hex(?cs)) { - alt (cs) { - case (case_upper) { log "type: uhex"; } - case (case_lower) { log "type: lhex"; } - } + } + ty_bits. { log "type: bits"; } + ty_hex(cs) { + alt cs { + case_upper. { log "type: uhex"; } + case_lower. { log "type: lhex"; } } - case (ty_octal) { log "type: octal"; } + } + ty_octal. { log "type: octal"; } } } - auto fmt_sp = args.(0).span; - auto n = 0u; - auto tmp_expr = make_new_str(cx, sp, ""); - auto nargs = ivec::len[@ast::expr](args); - for (piece pc in pieces) { - alt (pc) { - case (piece_string(?s)) { - auto s_expr = make_new_str(cx, fmt_sp, s); - tmp_expr = make_add_expr(cx, fmt_sp, tmp_expr, s_expr); - } - case (piece_conv(?conv)) { - n += 1u; - if (n >= nargs) { - cx.span_fatal(sp, - "not enough arguments to #fmt " + - "for the given format string"); - } - log "Building conversion:"; - log_conv(conv); - auto arg_expr = args.(n); - auto c_expr = make_new_conv(cx, fmt_sp, conv, arg_expr); - tmp_expr = make_add_expr(cx, fmt_sp, tmp_expr, c_expr); + let fmt_sp = args.(0).span; + let n = 0u; + let tmp_expr = make_new_str(cx, sp, ""); + let nargs = ivec::len[@ast::expr](args); + for pc: piece in pieces { + alt pc { + piece_string(s) { + let s_expr = make_new_str(cx, fmt_sp, s); + tmp_expr = make_add_expr(cx, fmt_sp, tmp_expr, s_expr); + } + piece_conv(conv) { + n += 1u; + if n >= nargs { + cx.span_fatal(sp, + "not enough arguments to #fmt " + + "for the given format string"); } + log "Building conversion:"; + log_conv(conv); + let arg_expr = args.(n); + let c_expr = make_new_conv(cx, fmt_sp, conv, arg_expr); + tmp_expr = make_add_expr(cx, fmt_sp, tmp_expr, c_expr); + } } } - auto expected_nargs = n + 1u; // n conversions + the fmt string + let expected_nargs = n + 1u; // n conversions + the fmt string - if (expected_nargs < nargs) { + if expected_nargs < nargs { cx.span_fatal(sp, - #fmt("too many arguments to #fmt. found %u, expected %u", - nargs, expected_nargs)); + #fmt("too many arguments to #fmt. found %u, expected %u", + nargs, expected_nargs)); } ret tmp_expr; } diff --git a/src/comp/syntax/ext/simplext.rs b/src/comp/syntax/ext/simplext.rs index d6f7a7c5370..729e8e5000e 100644 --- a/src/comp/syntax/ext/simplext.rs +++ b/src/comp/syntax/ext/simplext.rs @@ -34,22 +34,18 @@ import ast::mac_invoc; export add_new_extension; -fn path_to_ident(&path pth) -> option::t[ident] { - if (ivec::len(pth.node.idents) == 1u - && ivec::len(pth.node.types) == 0u) { +fn path_to_ident(pth: &path) -> option::t[ident] { + if ivec::len(pth.node.idents) == 1u && ivec::len(pth.node.types) == 0u { ret some(pth.node.idents.(0u)); } ret none; } //an ivec of binders might be a little big. -type clause = rec((binders)[] params, @expr body); +type clause = {params: binders[], body: @expr}; /* logically, an arb_depth should contain only one kind of matchable */ -tag arb_depth[T] { - leaf(T); - seq(vec[arb_depth[T]], span); -} +tag arb_depth[T] { leaf(T); seq(vec[arb_depth[T]], span); } tag matchable { @@ -62,31 +58,29 @@ tag matchable { } /* for when given an incompatible bit of AST */ -fn match_error(&ext_ctxt cx, &matchable m, &str expected) -> ! { - alt(m) { - case (match_expr(?x)) { - cx.span_fatal(x.span, "this argument is an expr, expected " - + expected); - } - case (match_path(?x)) { - cx.span_fatal(x.span, "this argument is a path, expected " - + expected); +fn match_error(cx: &ext_ctxt, m: &matchable, expected: &str) -> ! { + alt m { + match_expr(x) { + cx.span_fatal(x.span, + "this argument is an expr, expected " + expected); } - case (match_ident(?x)) { - cx.span_fatal(x.span, "this argument is an ident, expected " - + expected); + match_path(x) { + cx.span_fatal(x.span, + "this argument is a path, expected " + expected); } - case (match_ty(?x)) { - cx.span_fatal(x.span, "this argument is a type, expected " - + expected); + match_ident(x) { + cx.span_fatal(x.span, + "this argument is an ident, expected " + expected); } - case (match_block(?x)) { - cx.span_fatal(x.span, "this argument is a block, expected " - + expected); + match_ty(x) { + cx.span_fatal(x.span, + "this argument is a type, expected " + expected); } - case (match_exact) { - cx.bug("what is a match_exact doing in a bindings?"); + match_block(x) { + cx.span_fatal(x.span, + "this argument is a block, expected " + expected); } + match_exact. { cx.bug("what is a match_exact doing in a bindings?"); } } } @@ -97,88 +91,82 @@ fn match_error(&ext_ctxt cx, &matchable m, &str expected) -> ! { // we'll want to return something indicating amount of progress and location // of failure instead of `none`. type match_result = option::t[arb_depth[matchable]]; -type selector = fn(&matchable) -> match_result; - -fn elts_to_ell(&ext_ctxt cx, &(@expr)[] elts) -> option::t[@expr] { - let uint idx = 0u; - for (@expr elt in elts) { - alt (elt.node) { - case (expr_mac(?m)) { - alt (m.node) { - case (ast::mac_ellipsis) { - if (idx != 1u || ivec::len(elts) != 2u) { +type selector = fn(&matchable) -> match_result ; + +fn elts_to_ell(cx: &ext_ctxt, elts: &(@expr)[]) -> option::t[@expr] { + let idx: uint = 0u; + for elt: @expr in elts { + alt elt.node { + expr_mac(m) { + alt m.node { + ast::mac_ellipsis. { + if idx != 1u || ivec::len(elts) != 2u { cx.span_fatal(m.span, - "Ellpisis may only appear" - +" after exactly 1 item."); + "Ellpisis may only appear" + + " after exactly 1 item."); } ret some(elts.(0)); } } } - case (_) { } + _ { } } idx += 1u; } ret none; } -fn option_flatten_map[T,U](&fn(&T)->option::t[U] f, &vec[T] v) - -> option::t[vec[U]] { - auto res = vec::alloc[U](vec::len(v)); - for (T elem in v) { - alt (f(elem)) { - case (none) { ret none; } - case (some(?fv)) { res += [fv]; } - } +fn option_flatten_map[T, U](f: &fn(&T) -> option::t[U] , v: &vec[T]) -> + option::t[vec[U]] { + let res = vec::alloc[U](vec::len(v)); + for elem: T in v { + alt f(elem) { none. { ret none; } some(fv) { res += [fv]; } } } ret some(res); } -fn a_d_map(&arb_depth[matchable] ad, &selector f) - -> match_result { - alt (ad) { - case (leaf(?x)) { ret f(x); } - case (seq(?ads,?span)) { - alt (option_flatten_map(bind a_d_map(_, f), ads)) { - case (none) { ret none; } - case (some(?ts)) { ret some(seq(ts,span)); } +fn a_d_map(ad: &arb_depth[matchable], f: &selector) -> match_result { + alt ad { + leaf(x) { ret f(x); } + seq(ads, span) { + alt option_flatten_map(bind a_d_map(_, f), ads) { + none. { ret none; } + some(ts) { ret some(seq(ts, span)); } } } } } -fn compose_sels(selector s1, selector s2) -> selector { - fn scomp(selector s1, selector s2, &matchable m) -> - match_result { - ret alt (s1(m)) { - case (none) { none } - case (some(?matches)) { a_d_map(matches, s2) } - } +fn compose_sels(s1: selector, s2: selector) -> selector { + fn scomp(s1: selector, s2: selector, m: &matchable) -> match_result { + ret alt s1(m) { + none. { none } + some(matches) { a_d_map(matches, s2) } + } } ret bind scomp(s1, s2, _); } -type binders = rec(hashmap[ident,selector] real_binders, - mutable (selector)[] literal_ast_matchers); +type binders = + {real_binders: hashmap[ident, selector], + mutable literal_ast_matchers: selector[]}; type bindings = hashmap[ident, arb_depth[matchable]]; -fn acumm_bindings(&ext_ctxt cx, &bindings b_dest, &bindings b_src) { -} +fn acumm_bindings(cx: &ext_ctxt, b_dest: &bindings, b_src: &bindings) { } /* these three functions are the big moving parts */ /* create the selectors needed to bind and verify the pattern */ -fn pattern_to_selectors(&ext_ctxt cx, @expr e) -> binders { - let binders res = rec(real_binders=new_str_hash[selector](), - mutable literal_ast_matchers=~[]); +fn pattern_to_selectors(cx: &ext_ctxt, e: @expr) -> binders { + let res: binders = + {real_binders: new_str_hash[selector](), + mutable literal_ast_matchers: ~[]}; //this oughta return binders instead, but macro args are a sequence of //expressions, rather than a single expression - fn trivial_selector(&matchable m) -> match_result { - ret some(leaf(m)); - } + fn trivial_selector(m: &matchable) -> match_result { ret some(leaf(m)); } p_t_s_rec(cx, match_expr(e), trivial_selector, res); ret res; } @@ -189,146 +177,140 @@ fn pattern_to_selectors(&ext_ctxt cx, @expr e) -> binders { bindings. Most of the work is done in p_t_s, which generates the selectors. */ -fn use_selectors_to_bind(&binders b, @expr e) -> option::t[bindings] { - auto res = new_str_hash[arb_depth[matchable]](); - let bool never_mind = false; - for each(@rec(ident key, selector val) pair - in b.real_binders.items()) { - alt (pair.val(match_expr(e))) { - case (none) { never_mind = true; } - case (some(?mtc)) { res.insert(pair.key, mtc); } +fn use_selectors_to_bind(b: &binders, e: @expr) -> option::t[bindings] { + let res = new_str_hash[arb_depth[matchable]](); + let never_mind: bool = false; + for each pair: @{key: ident, val: selector} in b.real_binders.items() { + alt pair.val(match_expr(e)) { + none. { never_mind = true; } + some(mtc) { res.insert(pair.key, mtc); } } } - if (never_mind) { ret none; } //HACK: `ret` doesn't work in `for each` - for (selector sel in b.literal_ast_matchers) { - alt (sel(match_expr(e))) { - case (none) { ret none; } - case (_) { } - } + if never_mind { + ret none; //HACK: `ret` doesn't work in `for each` + } + for sel: selector in b.literal_ast_matchers { + alt sel(match_expr(e)) { none. { ret none; } _ { } } } ret some(res); } /* use the bindings on the body to generate the expanded code */ -fn transcribe(&ext_ctxt cx, &bindings b, @expr body) -> @expr { - let @mutable vec[uint] idx_path = @mutable []; - auto afp = default_ast_fold(); - auto f_pre = - rec(fold_ident = bind transcribe_ident(cx, b, idx_path, _, _), - fold_path = bind transcribe_path(cx, b, idx_path, _, _), - fold_expr = bind transcribe_expr(cx, b, idx_path, _, _, - afp.fold_expr), - fold_ty = bind transcribe_type(cx, b, idx_path, _, _, - afp.fold_ty), - fold_block = bind transcribe_block(cx, b, idx_path, _, _, - afp.fold_block), - map_exprs = bind transcribe_exprs(cx, b, idx_path, _, _) - with *afp); - auto f = make_fold(f_pre); - auto result = f.fold_expr(body); - dummy_out(f); //temporary: kill circular reference +fn transcribe(cx: &ext_ctxt, b: &bindings, body: @expr) -> @expr { + let idx_path: @mutable vec[uint] = @mutable []; + let afp = default_ast_fold(); + let f_pre = + {fold_ident: bind transcribe_ident(cx, b, idx_path, _, _), + fold_path: bind transcribe_path(cx, b, idx_path, _, _), + fold_expr: + bind transcribe_expr(cx, b, idx_path, _, _, afp.fold_expr), + fold_ty: bind transcribe_type(cx, b, idx_path, _, _, afp.fold_ty), + fold_block: + bind transcribe_block(cx, b, idx_path, _, _, afp.fold_block), + map_exprs: bind transcribe_exprs(cx, b, idx_path, _, _) with *afp}; + let f = make_fold(f_pre); + let result = f.fold_expr(body); + dummy_out(f); //temporary: kill circular reference ret result; } /* helper: descend into a matcher */ -fn follow(&arb_depth[matchable] m, @mutable vec[uint] idx_path) - -> arb_depth[matchable] { - let arb_depth[matchable] res = m; - for (uint idx in *idx_path) { - alt(res) { - case (leaf(_)) { ret res; /* end of the line */ } - case (seq(?new_ms,_)) { res = new_ms.(idx); } +fn follow(m: &arb_depth[matchable], idx_path: @mutable vec[uint]) -> + arb_depth[matchable] { + let res: arb_depth[matchable] = m; + for idx: uint in *idx_path { + alt res { + leaf(_) { ret res;/* end of the line */ } + seq(new_ms, _) { res = new_ms.(idx); } } } ret res; } -fn follow_for_trans(&ext_ctxt cx, &option::t[arb_depth[matchable]] mmaybe, - @mutable vec[uint] idx_path) -> option::t[matchable] { - alt(mmaybe) { - case (none) { ret none } - case (some(?m)) { - ret alt(follow(m, idx_path)) { - case (seq(_,?sp)) { - cx.span_fatal(sp, "syntax matched under ... but not " - + "used that way.") - } - case (leaf(?m)) { - ret some(m) - } - } +fn follow_for_trans(cx: &ext_ctxt, mmaybe: &option::t[arb_depth[matchable]], + idx_path: @mutable vec[uint]) -> option::t[matchable] { + alt mmaybe { + none. { ret none } + some(m) { + ret alt follow(m, idx_path) { + seq(_, sp) { + cx.span_fatal(sp, + "syntax matched under ... but not " + + "used that way.") + } + leaf(m) { ret some(m) } + } } } } /* helper for transcribe_exprs: what vars from `b` occur in `e`? */ -iter free_vars(&bindings b, @expr e) -> ident { - let hashmap[ident,()] idents = new_str_hash[()](); - fn mark_ident(&ident i, ast_fold fld, &bindings b, - &hashmap[ident,()] idents) -> ident { - if(b.contains_key(i)) { idents.insert(i,()); } +iter free_vars(b: &bindings, e: @expr) -> ident { + let idents: hashmap[ident, ()] = new_str_hash[()](); + fn mark_ident(i: &ident, fld: ast_fold, b: &bindings, + idents: &hashmap[ident, ()]) -> ident { + if b.contains_key(i) { idents.insert(i, ()); } ret i; } // using fold is a hack: we want visit, but it doesn't hit idents ) : // solve this with macros - auto f_pre = rec(fold_ident=bind mark_ident(_, _, b, idents) - with *default_ast_fold()); - auto f = make_fold(f_pre); + let f_pre = + {fold_ident: bind mark_ident(_, _, b, idents) + with *default_ast_fold()}; + let f = make_fold(f_pre); f.fold_expr(e); // ignore result dummy_out(f); - for each(ident id in idents.keys()) { put id; } + for each id: ident in idents.keys() { put id; } } /* handle sequences (anywhere in the AST) of exprs, either real or ...ed */ -fn transcribe_exprs(&ext_ctxt cx, &bindings b, @mutable vec[uint] idx_path, - fn(&@expr)->@expr recur, (@expr)[] exprs) -> (@expr)[] { - alt (elts_to_ell(cx, exprs)) { - case (some(?repeat_me)) { - let option::t[rec(uint rep_count, ident name)] repeat = none; +fn transcribe_exprs(cx: &ext_ctxt, b: &bindings, idx_path: @mutable vec[uint], + recur: fn(&@expr) -> @expr , exprs: (@expr)[]) -> + (@expr)[] { + alt elts_to_ell(cx, exprs) { + some(repeat_me) { + let repeat: option::t[{rep_count: uint, name: ident}] = none; /* we need to walk over all the free vars in lockstep, except for the leaves, which are just duplicated */ - for each (ident fv in free_vars(b, repeat_me)) { - auto cur_pos = follow(b.get(fv), idx_path); - alt (cur_pos) { - case (leaf(_)) { } - case (seq(?ms,_)) { - alt (repeat) { - case (none) { - repeat = some - (rec(rep_count=vec::len(ms), name=fv)); + for each fv: ident in free_vars(b, repeat_me) { + let cur_pos = follow(b.get(fv), idx_path); + alt cur_pos { + leaf(_) { } + seq(ms, _) { + alt repeat { + none. { + repeat = some({rep_count: vec::len(ms), name: fv}); } - case (some({rep_count: ?old_len, - name: ?old_name})) { - auto len = vec::len(ms); - if (old_len != len) { - cx.span_fatal - (repeat_me.span, - #fmt("'%s' occurs %u times, but ", - fv, len)+ - #fmt("'%s' occurs %u times", - old_name, old_len)); + some({rep_count: old_len, name: old_name}) { + let len = vec::len(ms); + if old_len != len { + cx.span_fatal(repeat_me.span, + #fmt("'%s' occurs %u times, but ", fv, + len) + + #fmt("'%s' occurs %u times", + old_name, old_len)); } } } } } } - auto res = ~[]; - alt (repeat) { - case (none) { + let res = ~[]; + alt repeat { + none. { cx.span_fatal(repeat_me.span, - "'...' surrounds an expression without any" - + " repeating syntax variables"); + "'...' surrounds an expression without any" + + " repeating syntax variables"); } - case (some({rep_count: ?rc, _})) { + some({rep_count: rc, _}) { /* Whew, we now know how how many times to repeat */ - let uint idx = 0u; - while (idx < rc) { + let idx: uint = 0u; + while idx < rc { vec::push(*idx_path, idx); res += ~[recur(repeat_me)]; // whew! vec::pop(*idx_path); @@ -338,139 +320,141 @@ fn transcribe_exprs(&ext_ctxt cx, &bindings b, @mutable vec[uint] idx_path, } ret res; } - case (none) { ret ivec::map(recur, exprs); } + none. { ret ivec::map(recur, exprs); } } } // substitute, in a position that's required to be an ident -fn transcribe_ident(&ext_ctxt cx, &bindings b, @mutable vec[uint] idx_path, - &ident i, ast_fold fld) -> ident { - ret alt (follow_for_trans(cx, b.find(i), idx_path)) { - case (some(match_ident(?a_id))) { a_id.node } - case (some(?m)) { match_error(cx, m, "an identifier") } - case (none) { i } - } +fn transcribe_ident(cx: &ext_ctxt, b: &bindings, idx_path: @mutable vec[uint], + i: &ident, fld: ast_fold) -> ident { + ret alt follow_for_trans(cx, b.find(i), idx_path) { + some(match_ident(a_id)) { a_id.node } + some(m) { match_error(cx, m, "an identifier") } + none. { i } + } } -fn transcribe_path(&ext_ctxt cx, &bindings b, @mutable vec[uint] idx_path, - &path_ p, ast_fold fld) -> path_ { +fn transcribe_path(cx: &ext_ctxt, b: &bindings, idx_path: @mutable vec[uint], + p: &path_, fld: ast_fold) -> path_ { // Don't substitute into qualified names. - if (ivec::len(p.types) > 0u || ivec::len(p.idents) != 1u) { ret p; } - ret alt (follow_for_trans(cx, b.find(p.idents.(0)), idx_path)) { - case (some(match_ident(?id))) { - rec(global=false, idents=~[id.node], types=~[]) - } - case (some(match_path(?a_pth))) { a_pth.node } - case (some(?m)) { match_error(cx, m, "a path") } - case (none) { p } - } + if ivec::len(p.types) > 0u || ivec::len(p.idents) != 1u { ret p; } + ret alt follow_for_trans(cx, b.find(p.idents.(0)), idx_path) { + some(match_ident(id)) { + {global: false, idents: ~[id.node], types: ~[]} + } + some(match_path(a_pth)) { a_pth.node } + some(m) { match_error(cx, m, "a path") } + none. { p } + } } -fn transcribe_expr(&ext_ctxt cx, &bindings b, @mutable vec[uint] idx_path, - &ast::expr_ e, ast_fold fld, - fn(&ast::expr_, ast_fold) -> ast::expr_ orig) - -> ast::expr_ { - ret alt(e) { - case (expr_path(?p)){ - // Don't substitute into qualified names. - if (ivec::len(p.node.types) > 0u || - ivec::len(p.node.idents) != 1u) { e } - alt (follow_for_trans(cx, b.find(p.node.idents.(0)), idx_path)) { - case (some(match_ident(?id))) { - expr_path(respan(id.span, - rec(global=false, - idents=~[id.node],types=~[]))) +fn transcribe_expr(cx: &ext_ctxt, b: &bindings, idx_path: @mutable vec[uint], + e: &ast::expr_, fld: ast_fold, + orig: fn(&ast::expr_, ast_fold) -> ast::expr_ ) -> + ast::expr_ { + ret alt e { + expr_path(p) { + // Don't substitute into qualified names. + if ivec::len(p.node.types) > 0u || ivec::len(p.node.idents) != 1u + { + e + } + alt follow_for_trans(cx, b.find(p.node.idents.(0)), idx_path) { + some(match_ident(id)) { + expr_path(respan(id.span, + {global: false, + idents: ~[id.node], + types: ~[]})) + } + some(match_path(a_pth)) { expr_path(a_pth) } + some(match_expr(a_exp)) { a_exp.node } + some(m) { match_error(cx, m, "an expression") } + none. { orig(e, fld) } + } } - case (some(match_path(?a_pth))) { expr_path(a_pth) } - case (some(match_expr(?a_exp))) { a_exp.node } - case (some(?m)) { match_error(cx, m, "an expression")} - case (none) { orig(e,fld) } + _ { orig(e, fld) } } - } - case (_) { orig(e,fld) } - } } -fn transcribe_type(&ext_ctxt cx, &bindings b, @mutable vec[uint] idx_path, - &ast::ty_ t, ast_fold fld, - fn(&ast::ty_, ast_fold) -> ast::ty_ orig) -> ast::ty_ { - ret alt(t) { - case (ast::ty_path(?pth,_)) { - alt (path_to_ident(pth)) { - case (some(?id)) { - alt (follow_for_trans(cx, b.find(id), idx_path)) { - case (some(match_ty(?ty))) { ty.node } - case (some(?m)) { match_error(cx, m, "a type") } - case (none) { orig(t, fld) } +fn transcribe_type(cx: &ext_ctxt, b: &bindings, idx_path: @mutable vec[uint], + t: &ast::ty_, fld: ast_fold, + orig: fn(&ast::ty_, ast_fold) -> ast::ty_ ) -> ast::ty_ { + ret alt t { + ast::ty_path(pth, _) { + alt path_to_ident(pth) { + some(id) { + alt follow_for_trans(cx, b.find(id), idx_path) { + some(match_ty(ty)) { ty.node } + some(m) { match_error(cx, m, "a type") } + none. { orig(t, fld) } + } + } + none. { orig(t, fld) } } } - case (none) { orig(t, fld) } + _ { orig(t, fld) } } - } - case (_) { orig(t, fld) } - } } /* for parsing reasons, syntax variables bound to blocks must be used like `{v}` */ -fn transcribe_block(&ext_ctxt cx, &bindings b, @mutable vec[uint] idx_path, - &blk_ blk, ast_fold fld, - fn(&blk_, ast_fold) -> blk_ orig) -> blk_ { - ret alt (block_to_ident(blk)) { - case (some(?id)) { - alt (follow_for_trans(cx, b.find(id), idx_path)) { - case (some(match_block(?new_blk))) { new_blk.node } - // possibly allow promotion of ident/path/expr to blocks? - case (some(?m)) { match_error(cx, m, "a block")} - case (none) { orig(blk, fld) } +fn transcribe_block(cx: &ext_ctxt, b: &bindings, idx_path: @mutable vec[uint], + blk: &blk_, fld: ast_fold, + orig: fn(&blk_, ast_fold) -> blk_ ) -> blk_ { + ret alt block_to_ident(blk) { + some(id) { + alt follow_for_trans(cx, b.find(id), idx_path) { + some(match_block(new_blk)) { new_blk.node } + + // possibly allow promotion of ident/path/expr to blocks? + some(m) { + match_error(cx, m, "a block") + } + none. { orig(blk, fld) } + } + } + none. { orig(blk, fld) } } - } - case (none) { orig(blk, fld) } - } } /* traverse the pattern, building instructions on how to bind the actual argument. ps accumulates instructions on navigating the tree.*/ -fn p_t_s_rec(&ext_ctxt cx, &matchable m, &selector s, &binders b) { +fn p_t_s_rec(cx: &ext_ctxt, m: &matchable, s: &selector, b: &binders) { + //it might be possible to traverse only exprs, not matchables - alt (m) { - case (match_expr(?e)) { - alt (e.node) { - case (expr_path(?p_pth)) { - p_t_s_r_path(cx,p_pth, s, b); - } - case (expr_vec(?p_elts, _, _)) { - alt (elts_to_ell(cx, p_elts)) { - case (some(?repeat_me)) { - p_t_s_r_ellipses(cx, repeat_me, s, b); - } - case (none) { - p_t_s_r_actual_vector(cx, p_elts, s, b); - } + alt m { + match_expr(e) { + alt e.node { + expr_path(p_pth) { p_t_s_r_path(cx, p_pth, s, b); } + expr_vec(p_elts, _, _) { + alt elts_to_ell(cx, p_elts) { + some(repeat_me) { p_t_s_r_ellipses(cx, repeat_me, s, b); } + none. { p_t_s_r_actual_vector(cx, p_elts, s, b); } } } + /* TODO: handle embedded types and blocks, at least */ - case (expr_mac(?mac)) { + expr_mac(mac) { p_t_s_r_mac(cx, mac, s, b); } - case (_) { - fn select(&ext_ctxt cx, &matchable m, @expr pat) - -> match_result { - ret alt(m) { - case (match_expr(?e)) { - if (e==pat) { some(leaf(match_exact)) } else { none } - } - case (_) { cx.bug("broken traversal in p_t_s_r"); fail } - } + _ { + fn select(cx: &ext_ctxt, m: &matchable, pat: @expr) -> + match_result { + ret alt m { + match_expr(e) { + if e == pat { some(leaf(match_exact)) } else { none } + } + _ { cx.bug("broken traversal in p_t_s_r"); fail } + } } - b.literal_ast_matchers += ~[bind select(cx,_,e)]; + b.literal_ast_matchers += ~[bind select(cx, _, e)]; } } } @@ -479,111 +463,103 @@ fn p_t_s_rec(&ext_ctxt cx, &matchable m, &selector s, &binders b) { /* make a match more precise */ -fn specialize_match(&matchable m) -> matchable { - ret alt (m) { - case (match_expr(?e)) { - alt (e.node) { - case (expr_path(?pth)) { - alt (path_to_ident(pth)) { - case (some(?id)) { match_ident(respan(pth.span,id)) } - case (none) { match_path(pth) } +fn specialize_match(m: &matchable) -> matchable { + ret alt m { + match_expr(e) { + alt e.node { + expr_path(pth) { + alt path_to_ident(pth) { + some(id) { match_ident(respan(pth.span, id)) } + none. { match_path(pth) } + } + } + _ { m } } } - case (_) { m } + _ { m } } - } - case (_) { m } - } } /* pattern_to_selectors helper functions */ -fn p_t_s_r_path(&ext_ctxt cx, &path p, &selector s, &binders b) { - alt (path_to_ident(p)) { - case (some(?p_id)) { - fn select(&ext_ctxt cx, &matchable m) -> match_result { - ret alt (m) { - case (match_expr(?e)) { some(leaf(specialize_match(m))) } - case (_) { cx.bug("broken traversal in p_t_s_r"); fail } - } +fn p_t_s_r_path(cx: &ext_ctxt, p: &path, s: &selector, b: &binders) { + alt path_to_ident(p) { + some(p_id) { + fn select(cx: &ext_ctxt, m: &matchable) -> match_result { + ret alt m { + match_expr(e) { some(leaf(specialize_match(m))) } + _ { cx.bug("broken traversal in p_t_s_r"); fail } + } } - if (b.real_binders.contains_key(p_id)) { + if b.real_binders.contains_key(p_id) { cx.span_fatal(p.span, "duplicate binding identifier"); } - b.real_binders.insert(p_id, compose_sels(s, bind select(cx,_))); + b.real_binders.insert(p_id, compose_sels(s, bind select(cx, _))); } - case (none) { } + none. { } } } -fn block_to_ident(&blk_ blk) -> option::t[ident] { - if(ivec::len(blk.stmts) != 0u) { ret none; } - ret alt (blk.expr) { - case (some(?expr)) { - alt (expr.node) { - case (expr_path(?pth)) { path_to_ident(pth) } - case (_) { none } +fn block_to_ident(blk: &blk_) -> option::t[ident] { + if ivec::len(blk.stmts) != 0u { ret none; } + ret alt blk.expr { + some(expr) { + alt expr.node { expr_path(pth) { path_to_ident(pth) } _ { none } } + } + none. { none } } - } - case(none) { none } - } } -fn p_t_s_r_mac(&ext_ctxt cx, &ast::mac mac, &selector s, &binders b) { - fn select_pt_1(&ext_ctxt cx, &matchable m, fn(&ast::mac) -> - match_result fn_m) -> match_result { - ret alt(m) { - case (match_expr(?e)) { - alt(e.node) { - case (expr_mac(?mac)) { fn_m(mac) } - case (_) { none } +fn p_t_s_r_mac(cx: &ext_ctxt, mac: &ast::mac, s: &selector, b: &binders) { + fn select_pt_1(cx: &ext_ctxt, m: &matchable, + fn_m: fn(&ast::mac) -> match_result ) -> match_result { + ret alt m { + match_expr(e) { + alt e.node { expr_mac(mac) { fn_m(mac) } _ { none } } + } + _ { cx.bug("broken traversal in p_t_s_r"); fail } } - } - case (_) { cx.bug("broken traversal in p_t_s_r"); fail } - } } - fn no_des(&ext_ctxt cx, &span sp, &str syn) -> ! { - cx.span_fatal(sp, "destructuring "+syn+" is not yet supported"); + fn no_des(cx: &ext_ctxt, sp: &span, syn: &str) -> ! { + cx.span_fatal(sp, "destructuring " + syn + " is not yet supported"); } - alt (mac.node) { - case (ast::mac_ellipsis) { cx.span_fatal(mac.span, "misused `...`"); } - case (ast::mac_invoc(_,_, _)) { no_des(cx, mac.span, "macro calls"); } - case (ast::mac_embed_type(?ty)) { - alt (ty.node) { - case ast::ty_path(?pth, _) { - alt (path_to_ident(pth)) { - case (some(?id)) { + alt mac.node { + ast::mac_ellipsis. { cx.span_fatal(mac.span, "misused `...`"); } + ast::mac_invoc(_, _, _) { no_des(cx, mac.span, "macro calls"); } + ast::mac_embed_type(ty) { + alt ty.node { + ast::ty_path(pth, _) { + alt path_to_ident(pth) { + some(id) { /* look for an embedded type */ - fn select_pt_2(&ast::mac m) -> match_result { - ret alt (m.node) { - case (ast::mac_embed_type(?t)) { - some(leaf(match_ty(t))) - } - case (_) { none } - } + fn select_pt_2(m: &ast::mac) -> match_result { + ret alt m.node { + ast::mac_embed_type(t) { some(leaf(match_ty(t))) } + _ { none } + } } b.real_binders.insert(id, bind select_pt_1(cx, _, select_pt_2)); } - case (none) { no_des(cx, pth.span, "under `#<>`"); } + none. { no_des(cx, pth.span, "under `#<>`"); } } } - case (_) { no_des(cx, ty.span, "under `#<>`"); } + _ { no_des(cx, ty.span, "under `#<>`"); } } } - case (ast::mac_embed_block(?blk)) { - alt (block_to_ident(blk.node)) { - case (some(?id)) { - fn select_pt_2(&ast::mac m) -> match_result { - ret alt (m.node) { - case (ast::mac_embed_block(?blk)) { - some(leaf(match_block(blk))) - } - case (_) { none } - } + ast::mac_embed_block(blk) { + alt block_to_ident(blk.node) { + some(id) { + fn select_pt_2(m: &ast::mac) -> match_result { + ret alt m.node { + ast::mac_embed_block(blk) { + some(leaf(match_block(blk))) + } + _ { none } + } } b.real_binders.insert(id, bind select_pt_1(cx, _, select_pt_2)); } - case (none) { no_des(cx, blk.span, "under `#{}`"); } + none. { no_des(cx, blk.span, "under `#{}`"); } } } } @@ -591,68 +567,72 @@ fn p_t_s_r_mac(&ext_ctxt cx, &ast::mac mac, &selector s, &binders b) { /* TODO: move this to vec.rs */ -fn ivec_to_vec[T](&(T)[] v) -> vec[T] { - let vec[T] rs = vec::alloc[T](ivec::len(v)); - for (T ve in v) { rs += [ve]; } +fn ivec_to_vec[T](v: &T[]) -> vec[T] { + let rs: vec[T] = vec::alloc[T](ivec::len(v)); + for ve: T in v { rs += [ve]; } ret rs; } -fn p_t_s_r_ellipses(&ext_ctxt cx, @expr repeat_me, &selector s, &binders b) { - fn select(&ext_ctxt cx, @expr repeat_me, &matchable m) -> match_result { - ret alt (m) { - case (match_expr(?e)) { - alt (e.node) { - case (expr_vec(?arg_elts, _, _)) { - auto elts = ivec::map(leaf, ivec::map(match_expr, - arg_elts)); - // using repeat_me.span is a little wacky, but the - // error we want to report is one in the macro def - some(seq(ivec_to_vec(elts), repeat_me.span)) +fn p_t_s_r_ellipses(cx: &ext_ctxt, repeat_me: @expr, s: &selector, + b: &binders) { + fn select(cx: &ext_ctxt, repeat_me: @expr, m: &matchable) -> + match_result { + ret alt m { + match_expr(e) { + alt e.node { + expr_vec(arg_elts, _, _) { + let elts = + ivec::map(leaf, ivec::map(match_expr, arg_elts)); + + // using repeat_me.span is a little wacky, but the + // error we want to report is one in the macro def + some(seq(ivec_to_vec(elts), repeat_me.span)) + } + _ { none } + } } - case (_) { none } + _ { cx.bug("broken traversal in p_t_s_r"); fail } } - } - case (_) { cx.bug("broken traversal in p_t_s_r"); fail } - } } p_t_s_rec(cx, match_expr(repeat_me), compose_sels(s, bind select(cx, repeat_me, _)), b); } -fn p_t_s_r_actual_vector(&ext_ctxt cx, (@expr)[] elts, &selector s, - &binders b) { - fn len_select(&ext_ctxt cx, &matchable m, uint len) -> match_result { - ret alt (m) { - case (match_expr(?e)) { - alt (e.node) { - case (expr_vec(?arg_elts, _, _)) { - if (ivec::len(arg_elts) == len) { some(leaf(match_exact)) } - else { none } +fn p_t_s_r_actual_vector(cx: &ext_ctxt, elts: (@expr)[], s: &selector, + b: &binders) { + fn len_select(cx: &ext_ctxt, m: &matchable, len: uint) -> match_result { + ret alt m { + match_expr(e) { + alt e.node { + expr_vec(arg_elts, _, _) { + if ivec::len(arg_elts) == len { + some(leaf(match_exact)) + } else { none } + } + _ { none } + } } - case (_) { none } + _ { none } } - } - case (_) { none } - } } b.literal_ast_matchers += ~[compose_sels(s, bind len_select(cx, _, ivec::len(elts)))]; - let uint idx = 0u; - while (idx < ivec::len(elts)) { - fn select(&ext_ctxt cx, &matchable m, uint idx) -> match_result { - ret alt (m) { - case (match_expr(?e)) { - alt (e.node) { - case (expr_vec(?arg_elts, _, _)) { - some(leaf(match_expr(arg_elts.(idx)))) + let idx: uint = 0u; + while idx < ivec::len(elts) { + fn select(cx: &ext_ctxt, m: &matchable, idx: uint) -> match_result { + ret alt m { + match_expr(e) { + alt e.node { + expr_vec(arg_elts, _, _) { + some(leaf(match_expr(arg_elts.(idx)))) + } + _ { none } + } } - case (_) { none } + _ { cx.bug("broken traversal in p_t_s_r"); fail } } - } - case (_) { cx.bug("broken traversal in p_t_s_r"); fail} - } } p_t_s_rec(cx, match_expr(elts.(idx)), compose_sels(s, bind select(cx, _, idx)), b); @@ -660,90 +640,93 @@ fn p_t_s_r_actual_vector(&ext_ctxt cx, (@expr)[] elts, &selector s, } } -fn add_new_extension(&ext_ctxt cx, span sp, &(@expr)[] args, - option::t[str] body) -> base::macro_def { - let option::t[str] macro_name = none; - let (clause)[] clauses = ~[]; - for (@expr arg in args) { - alt(arg.node) { - case(expr_vec(?elts, ?mut, ?seq_kind)) { - if (ivec::len(elts) != 2u) { +fn add_new_extension(cx: &ext_ctxt, sp: span, args: &(@expr)[], + body: option::t[str]) -> base::macro_def { + let macro_name: option::t[str] = none; + let clauses: clause[] = ~[]; + for arg: @expr in args { + alt arg.node { + expr_vec(elts, mut, seq_kind) { + if ivec::len(elts) != 2u { cx.span_fatal((*arg).span, "extension clause must consist of [" + - "macro invocation, expansion body]"); + "macro invocation, expansion body]"); } - alt(elts.(0u).node) { - case(expr_mac(?mac)) { - alt (mac.node) { - case (mac_invoc(?pth, ?invoc_args, ?body)) { - alt (path_to_ident(pth)) { - case (some(?id)) { macro_name=some(id); } - case (none) { - cx.span_fatal(pth.span, "macro name " - + "must not be a path"); + + alt elts.(0u).node { + expr_mac(mac) { + alt mac.node { + mac_invoc(pth, invoc_args, body) { + alt path_to_ident(pth) { + some(id) { macro_name = some(id); } + none. { + cx.span_fatal(pth.span, + "macro name " + "must not be a path"); } } - auto bdrses = ~[]; - for(@expr arg in invoc_args) { - bdrses += - ~[pattern_to_selectors(cx, arg)]; + let bdrses = ~[]; + for arg: @expr in invoc_args { + bdrses += ~[pattern_to_selectors(cx, arg)]; } - clauses += - ~[rec(params=bdrses, body=elts.(1u))]; + clauses += ~[{params: bdrses, body: elts.(1u)}]; // FIXME: check duplicates (or just simplify // the macro arg situation) } } } - case(_) { - cx.span_fatal(elts.(0u).span, "extension clause must" - + " start with a macro invocation."); + _ { + cx.span_fatal(elts.(0u).span, + "extension clause must" + + " start with a macro invocation."); } } } - case(_) { - cx.span_fatal((*arg).span, "extension must be [clause, " - + " ...]"); + _ { + cx.span_fatal((*arg).span, + "extension must be [clause, " + " ...]"); } } } - auto ext = bind generic_extension(_,_,_,_,clauses); + let ext = bind generic_extension(_, _, _, _, clauses); + + ret {ident: + alt macro_name { + some(id) { id } + none. { + cx.span_fatal(sp, + "macro definition must have " + + "at least one clause") + } + }, + ext: normal(ext)}; - ret rec(ident=alt (macro_name) { - case (some(?id)) { id } - case (none) { - cx.span_fatal(sp, "macro definition must have " - + "at least one clause") - } - }, ext=normal(ext)); + fn generic_extension(cx: &ext_ctxt, sp: span, args: &(@expr)[], + body: option::t[str], clauses: clause[]) -> @expr { - fn generic_extension(&ext_ctxt cx, span sp, &(@expr)[] args, - option::t[str] body, (clause)[] clauses) - -> @expr { + for c: clause in clauses { + if ivec::len(args) != ivec::len(c.params) { cont; } + let i: uint = 0u; + let bdgs: bindings = new_str_hash[arb_depth[matchable]](); + let abort: bool = false; + while i < ivec::len(args) { + alt use_selectors_to_bind(c.params.(i), args.(i)) { + some(new_bindings) { - for (clause c in clauses) { - if (ivec::len(args) != ivec::len(c.params)) { cont; } - let uint i = 0u; - let bindings bdgs = new_str_hash[arb_depth[matchable]](); - let bool abort = false; - while (i < ivec::len(args)) { - alt (use_selectors_to_bind(c.params.(i), args.(i))) { - case (some(?new_bindings)) { /* ick; I wish macros just took one expr */ - for each (@rec(ident key, arb_depth[matchable] val) it - in new_bindings.items()) { + for each it: @{key: ident, val: arb_depth[matchable]} in + new_bindings.items() { bdgs.insert(it.key, it.val); } } - case (none) { abort = true; } + none. { abort = true; } } i += 1u; } - if (abort) { cont; } + if abort { cont; } ret transcribe(cx, bdgs, c.body); } cx.span_fatal(sp, "no clauses match macro invocation"); |
