Skip to content

Commit 6d9aacd

Browse files
committed
---
yaml --- r: 3062 b: refs/heads/master c: 471436a h: refs/heads/master v: v3
1 parent 687e06c commit 6d9aacd

File tree

13 files changed

+115
-31
lines changed

13 files changed

+115
-31
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
---
2-
refs/heads/master: 8c06d1bcb01f1b45946adb8620149056b8e70d54
2+
refs/heads/master: 471436a2996b2f141e6ceeac87362cfb321807ff

trunk/src/comp/front/ast.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -271,6 +271,7 @@ tag expr_ {
271271
expr_for_each(@local, @expr, block, ann);
272272
expr_do_while(block, @expr, ann);
273273
expr_alt(@expr, vec[arm], ann);
274+
expr_fn(_fn, ann);
274275
expr_block(block, ann);
275276
expr_move(@expr /* TODO: @expr|is_lval */, @expr, ann);
276277
expr_assign(@expr /* TODO: @expr|is_lval */, @expr, ann);

trunk/src/comp/front/parser.rs

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -815,7 +815,8 @@ fn parse_bottom_expr(&parser p) -> @ast::expr {
815815
ret parse_alt_expr(p);
816816
} else if (eat_word(p, "spawn")) {
817817
ret parse_spawn_expr(p);
818-
818+
} else if (eat_word(p, "fn")) {
819+
ret parse_fn_expr(p);
819820
} else if (eat_word(p, "tup")) {
820821
fn parse_elt(&parser p) -> ast::elt {
821822
auto m = parse_mutability(p);
@@ -1114,8 +1115,11 @@ fn parse_self_method(&parser p) -> @ast::expr {
11141115
}
11151116

11161117
fn parse_dot_or_call_expr(&parser p) -> @ast::expr {
1117-
auto lo = p.get_lo_pos();
1118-
auto e = parse_bottom_expr(p);
1118+
ret parse_dot_or_call_expr_with(p, parse_bottom_expr(p));
1119+
}
1120+
1121+
fn parse_dot_or_call_expr_with(&parser p, @ast::expr e) -> @ast::expr {
1122+
auto lo = e.span.lo;
11191123
auto hi = e.span.hi;
11201124
while (true) {
11211125
alt (p.peek()) {
@@ -1357,6 +1361,14 @@ fn parse_if_expr(&parser p) -> @ast::expr {
13571361
ret @spanned(lo, hi, ast::expr_if(cond, thn, els, p.get_ann()));
13581362
}
13591363

1364+
fn parse_fn_expr(&parser p) -> @ast::expr {
1365+
auto lo = p.get_last_lo_pos();
1366+
auto decl = parse_fn_decl(p, ast::impure_fn);
1367+
auto body = parse_block(p);
1368+
auto _fn = rec(decl=decl, proto=ast::proto_fn, body=body);
1369+
ret @spanned(lo, body.span.hi, ast::expr_fn(_fn, p.get_ann()));
1370+
}
1371+
13601372
fn parse_else_expr(&parser p) -> @ast::expr {
13611373
if (eat_word(p, "if")) {
13621374
ret parse_if_expr(p);
@@ -1630,10 +1642,14 @@ fn parse_source_stmt(&parser p) -> @ast::stmt {
16301642
auto decl = @spanned(lo, hi, ast::decl_item(i));
16311643
ret @spanned(lo, hi, ast::stmt_decl(decl, p.get_ann()));
16321644
}
1645+
case (fn_no_item) { // parse_item will have already skipped "fn"
1646+
auto e = parse_fn_expr(p);
1647+
e = parse_dot_or_call_expr_with(p, e);
1648+
ret @spanned(lo, e.span.hi, ast::stmt_expr(e, p.get_ann()));
1649+
}
16331650
case (no_item) {
16341651
// Remainder are line-expr stmts.
16351652
auto e = parse_expr(p);
1636-
auto hi = p.get_span();
16371653
ret @spanned(lo, e.span.hi, ast::stmt_expr(e, p.get_ann()));
16381654
}
16391655
}
@@ -1676,6 +1692,7 @@ fn stmt_ends_with_semi(&ast::stmt stmt) -> bool {
16761692
case (ast::expr_while(_,_,_)) { ret false; }
16771693
case (ast::expr_do_while(_,_,_)) { ret false; }
16781694
case (ast::expr_alt(_,_,_)) { ret false; }
1695+
case (ast::expr_fn(_,_)) { ret false; }
16791696
case (ast::expr_block(_,_)) { ret false; }
16801697
case (ast::expr_assign(_,_,_)) { ret true; }
16811698
case (ast::expr_assign_op(_,_,_,_))
@@ -2152,16 +2169,18 @@ fn parse_auth(&parser p) -> ast::_auth {
21522169
fail;
21532170
}
21542171

2155-
// FIXME will be extended to help parse anon functions
21562172
tag parsed_item {
21572173
got_item(@ast::item);
21582174
no_item;
2175+
fn_no_item;
21592176
}
21602177

21612178
fn parse_item(&parser p) -> parsed_item {
21622179
if (eat_word(p, "const")) {
21632180
ret got_item(parse_item_const(p));
21642181
} else if (eat_word(p, "fn")) {
2182+
// This is an anonymous function
2183+
if (p.peek() == token::LPAREN) { ret fn_no_item; }
21652184
ret got_item(parse_item_fn_or_iter(p, ast::impure_fn, ast::proto_fn));
21662185
} else if (eat_word(p, "pred")) {
21672186
ret got_item(parse_item_fn_or_iter(p, ast::pure_fn, ast::proto_fn));

trunk/src/comp/middle/resolve.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -346,6 +346,9 @@ fn visit_expr_with_scope(&@ast::expr x, &scopes sc, &vt[scopes] v) {
346346
case (ast::expr_for_each(?d, _, _, _)) {
347347
cons[scope](scope_loop(d.node), @sc)
348348
}
349+
case (ast::expr_fn(?f, _)) {
350+
cons(scope_fn(f.decl, []), @sc)
351+
}
349352
case (_) { sc }
350353
};
351354
visit::visit_expr(x, new_sc, v);

trunk/src/comp/middle/trans.rs

Lines changed: 36 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -6020,6 +6020,22 @@ fn trans_expr_out(&@block_ctxt cx, &@ast::expr e, out_method output)
60206020
cx, ann, output);
60216021
}
60226022

6023+
case (ast::expr_fn(?f, ?ann)) {
6024+
auto ccx = cx.fcx.lcx.ccx;
6025+
let TypeRef llfnty = alt (ty::struct(ccx.tcx,
6026+
node_ann_type(ccx, ann))) {
6027+
case (ty::ty_fn(?proto, ?inputs, ?output, _, _)) {
6028+
type_of_fn_full(ccx, e.span, proto, none, inputs,
6029+
output, 0u)
6030+
}
6031+
};
6032+
auto sub_cx = extend_path(cx.fcx.lcx, ccx.names.next("anon"));
6033+
auto s = mangle_internal_name_by_path(ccx, sub_cx.path);
6034+
auto llfn = decl_internal_fastcall_fn(ccx.llmod, s, llfnty);
6035+
trans_fn(sub_cx, e.span, f, llfn, none, [], ann);
6036+
ret res(cx, create_fn_pair(ccx, s, llfnty, llfn, false));
6037+
}
6038+
60236039
case (ast::expr_block(?blk, ?ann)) {
60246040
*cx = rec(sp=blk.span with *cx);
60256041
auto sub_cx = new_scope_block_ctxt(cx, "block-expr body");
@@ -7668,10 +7684,9 @@ fn finish_fn(&@fn_ctxt fcx, BasicBlockRef lltop) {
76687684

76697685
// trans_fn: creates an LLVM function corresponding to a source language
76707686
// function.
7671-
fn trans_fn(@local_ctxt cx, &span sp, &ast::_fn f, ast::def_id fid,
7687+
fn trans_fn(@local_ctxt cx, &span sp, &ast::_fn f, ValueRef llfndecl,
76727688
option::t[ty_self_pair] ty_self,
76737689
&vec[ast::ty_param] ty_params, &ast::ann ann) {
7674-
auto llfndecl = cx.ccx.item_ids.get(fid);
76757690
set_uwtable(llfndecl);
76767691

76777692
// Set up arguments to the function.
@@ -7765,7 +7780,7 @@ fn create_vtbl(@local_ctxt cx,
77657780
cx.ccx.item_ids.insert(m.node.id, llfn);
77667781
cx.ccx.item_symbols.insert(m.node.id, s);
77677782

7768-
trans_fn(mcx, m.span, m.node.meth, m.node.id,
7783+
trans_fn(mcx, m.span, m.node.meth, llfn,
77697784
some[ty_self_pair](tup(llself_ty, self_ty)),
77707785
ty_params, m.node.ann);
77717786
methods += [llfn];
@@ -7794,7 +7809,7 @@ fn trans_dtor(@local_ctxt cx,
77947809
cx.ccx.item_ids.insert(dtor.node.id, llfn);
77957810
cx.ccx.item_symbols.insert(dtor.node.id, s);
77967811

7797-
trans_fn(cx, dtor.span, dtor.node.meth, dtor.node.id,
7812+
trans_fn(cx, dtor.span, dtor.node.meth, llfn,
77987813
some[ty_self_pair](tup(llself_ty, self_ty)),
77997814
ty_params, dtor.node.ann);
78007815

@@ -8119,7 +8134,8 @@ fn trans_item(@local_ctxt cx, &ast::item item) {
81198134
alt (item.node) {
81208135
case (ast::item_fn(?name, ?f, ?tps, ?fid, ?ann)) {
81218136
auto sub_cx = extend_path(cx, name);
8122-
trans_fn(sub_cx, item.span, f, fid, none[ty_self_pair],
8137+
auto llfndecl = cx.ccx.item_ids.get(fid);
8138+
trans_fn(sub_cx, item.span, f, llfndecl, none[ty_self_pair],
81238139
tps, ann);
81248140
}
81258141
case (ast::item_obj(?name, ?ob, ?tps, ?oid, ?ann)) {
@@ -8168,12 +8184,10 @@ fn decl_fn_and_pair(&@crate_ctxt ccx, &span sp,
81688184
ast::def_id id) {
81698185

81708186
auto llfty;
8171-
auto llpairty;
81728187
alt (ty::struct(ccx.tcx, node_ann_type(ccx, ann))) {
81738188
case (ty::ty_fn(?proto, ?inputs, ?output, _, _)) {
81748189
llfty = type_of_fn(ccx, sp, proto, inputs, output,
81758190
vec::len[ast::ty_param](ty_params));
8176-
llpairty = T_fn_pair(ccx.tn, llfty);
81778191
}
81788192
case (_) {
81798193
ccx.sess.bug("decl_fn_and_pair(): fn item doesn't have fn type!");
@@ -8192,7 +8206,7 @@ fn decl_fn_and_pair(&@crate_ctxt ccx, &span sp,
81928206

81938207
// Declare the global constant pair that points to it.
81948208
let str ps = mangle_exported_name(ccx, path, node_ann_type(ccx, ann));
8195-
register_fn_pair(ccx, ps, llpairty, llfn, id);
8209+
register_fn_pair(ccx, ps, llfty, llfn, id);
81968210

81978211
if (is_main) {
81988212
if (ccx.main_fn != none[ValueRef]) {
@@ -8205,22 +8219,25 @@ fn decl_fn_and_pair(&@crate_ctxt ccx, &span sp,
82058219

82068220
}
82078221

8208-
fn register_fn_pair(&@crate_ctxt cx, str ps, TypeRef llpairty, ValueRef llfn,
8209-
ast::def_id id) {
8210-
let ValueRef gvar = llvm::LLVMAddGlobal(cx.llmod, llpairty,
8211-
str::buf(ps));
8212-
auto pair = C_struct([llfn,
8213-
C_null(T_opaque_closure_ptr(cx.tn))]);
8214-
8222+
fn create_fn_pair(&@crate_ctxt cx, str ps, TypeRef llfnty, ValueRef llfn,
8223+
bool external) -> ValueRef {
8224+
auto gvar = llvm::LLVMAddGlobal
8225+
(cx.llmod, T_fn_pair(cx.tn, llfnty), str::buf(ps));
8226+
auto pair = C_struct([llfn, C_null(T_opaque_closure_ptr(cx.tn))]);
82158227
llvm::LLVMSetInitializer(gvar, pair);
82168228
llvm::LLVMSetGlobalConstant(gvar, True);
8217-
8218-
// FIXME: We should also hide the unexported pairs in crates.
8219-
if (!cx.sess.get_opts().shared) {
8229+
if (!external) {
82208230
llvm::LLVMSetLinkage(gvar, lib::llvm::LLVMInternalLinkage
82218231
as llvm::Linkage);
82228232
}
8233+
ret gvar;
8234+
}
82238235

8236+
fn register_fn_pair(&@crate_ctxt cx, str ps, TypeRef llfnty, ValueRef llfn,
8237+
ast::def_id id) {
8238+
// FIXME: We should also hide the unexported pairs in crates.
8239+
auto gvar = create_fn_pair(cx, ps, llfnty, llfn,
8240+
cx.sess.get_opts().shared);
82248241
cx.item_ids.insert(id, llfn);
82258242
cx.item_symbols.insert(id, ps);
82268243
cx.fn_pairs.insert(id, gvar);
@@ -8268,10 +8285,9 @@ fn decl_native_fn_and_pair(&@crate_ctxt ccx,
82688285
wrapper_type);
82698286

82708287
// Declare the global constant pair that points to it.
8271-
auto wrapper_pair_type = T_fn_pair(ccx.tn, wrapper_type);
82728288
let str ps = mangle_exported_name(ccx, path, node_ann_type(ccx, ann));
82738289

8274-
register_fn_pair(ccx, ps, wrapper_pair_type, wrapper_fn, id);
8290+
register_fn_pair(ccx, ps, wrapper_type, wrapper_fn, id);
82758291

82768292
// Build the wrapper.
82778293
auto fcx = new_fn_ctxt(new_local_ctxt(ccx), sp, wrapper_fn);

trunk/src/comp/middle/tstate/pre_post_conditions.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -301,6 +301,10 @@ fn find_pre_post_expr(&fn_ctxt fcx, @expr e) -> () {
301301
}
302302
}
303303
}
304+
// FIXME this was just put in here as a placeholder
305+
case (expr_fn(?f, ?a)) {
306+
clear_pp(expr_pp(fcx.ccx, e));
307+
}
304308
case (expr_block(?b, ?a)) {
305309
find_pre_post_block(fcx, b);
306310
auto p = block_pp(fcx.ccx, b);

trunk/src/comp/middle/tstate/states.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,10 @@ fn find_pre_post_state_expr(&fn_ctxt fcx, &prestate pres, @expr e) -> bool {
223223
case (expr_lit(?l,?a)) {
224224
ret pure_exp(fcx.ccx, a, pres);
225225
}
226+
// FIXME This was just put in here as a placeholder
227+
case (expr_fn(?f,?a)) {
228+
ret pure_exp(fcx.ccx, a, pres);
229+
}
226230
case (expr_block(?b,?a)) {
227231
changed = find_pre_post_state_block(fcx, pres, b)
228232
|| changed;

trunk/src/comp/middle/ty.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1662,6 +1662,7 @@ fn expr_ann(&@ast::expr e) -> ast::ann {
16621662
case (ast::expr_for_each(_,_,_,?a)) { ret a; }
16631663
case (ast::expr_do_while(_,_,?a)) { ret a; }
16641664
case (ast::expr_alt(_,_,?a)) { ret a; }
1665+
case (ast::expr_fn(_,?a)) { ret a; }
16651666
case (ast::expr_block(_,?a)) { ret a; }
16661667
case (ast::expr_move(_,_,?a)) { ret a; }
16671668
case (ast::expr_assign(_,_,?a)) { ret a; }

trunk/src/comp/middle/typeck.rs

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -474,14 +474,18 @@ mod collect {
474474
&ast::fn_decl decl,
475475
ast::proto proto,
476476
&vec[ast::ty_param] ty_params,
477-
&ast::def_id def_id) -> ty::ty_param_count_and_ty {
477+
&option::t[ast::def_id] def_id)
478+
-> ty::ty_param_count_and_ty {
478479
auto input_tys = vec::map[ast::arg,arg](ty_of_arg, decl.inputs);
479480
auto output_ty = convert(decl.output);
480481
auto t_fn = ty::mk_fn(cx.tcx, proto, input_tys, output_ty,
481482
decl.cf, decl.constraints);
482483
auto ty_param_count = vec::len[ast::ty_param](ty_params);
483484
auto tpt = tup(ty_param_count, t_fn);
484-
cx.tcx.tcache.insert(def_id, tpt);
485+
alt (def_id) {
486+
case (some(?did)) { cx.tcx.tcache.insert(did, tpt); }
487+
case (_) {}
488+
}
485489
ret tpt;
486490
}
487491

@@ -589,7 +593,7 @@ mod collect {
589593
case (ast::item_fn(?ident, ?fn_info, ?tps, ?def_id, _)) {
590594
auto f = bind ty_of_arg(cx, _);
591595
ret ty_of_fn_decl(cx, convert, f, fn_info.decl, fn_info.proto,
592-
tps, def_id);
596+
tps, some(def_id));
593597
}
594598

595599
case (ast::item_obj(?ident, ?obj_info, ?tps, ?odid, _)) {
@@ -1897,6 +1901,17 @@ fn check_expr(&@fn_ctxt fcx, &@ast::expr expr) {
18971901
write::ty_only_fixup(fcx, a.id, result_ty);
18981902
}
18991903

1904+
case (ast::expr_fn(?f, ?a)) {
1905+
auto cx = @rec(tcx = fcx.ccx.tcx);
1906+
auto convert = bind ast_ty_to_ty
1907+
(cx.tcx, bind collect::getter(cx, _), _);
1908+
auto ty_of_arg = bind collect::ty_of_arg(cx, _);
1909+
auto fty = collect::ty_of_fn_decl(cx, convert, ty_of_arg,
1910+
f.decl, f.proto, [], none)._1;
1911+
write::ty_only_fixup(fcx, a.id, fty);
1912+
check_fn(fcx.ccx, f.decl, f.proto, f.body, a);
1913+
}
1914+
19001915
case (ast::expr_block(?b, ?a)) {
19011916
check_block(fcx, b);
19021917
alt (b.node.expr) {

trunk/src/comp/middle/visit.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -335,6 +335,10 @@ fn visit_expr[E](&@expr ex, &E e, &vt[E] v) {
335335
vt(v).visit_arm(a, e, v);
336336
}
337337
}
338+
case (expr_fn(?f, _)) {
339+
visit_fn_decl(f.decl, e, v);
340+
vt(v).visit_block(f.body, e, v);
341+
}
338342
case (expr_block(?b, _)) {
339343
vt(v).visit_block(b, e, v);
340344
}

trunk/src/comp/middle/walk.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -410,6 +410,10 @@ fn walk_expr(&ast_visitor v, @ast::expr e) {
410410
v.visit_arm_post(a);
411411
}
412412
}
413+
case (ast::expr_fn(?f, ?a)) {
414+
walk_fn_decl(v, f.decl);
415+
walk_block(v, f.body);
416+
}
413417
case (ast::expr_block(?b, _)) {
414418
walk_block(v, b);
415419
}

trunk/src/comp/pretty/pprust.rs

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -671,6 +671,12 @@ fn print_expr(&ps s, &@ast::expr expr) {
671671
}
672672
bclose(s, expr.span);
673673
}
674+
case (ast::expr_fn(?f, _)) {
675+
head(s, "fn");
676+
print_fn_args_and_ret(s, f.decl);
677+
space(s.s);
678+
print_block(s, f.body);
679+
}
674680
case (ast::expr_block(?block,_)) {
675681
// containing cbox, will be closed by print-block at }
676682
cbox(s, indent_unit);
@@ -954,6 +960,10 @@ fn print_fn(&ps s, ast::fn_decl decl, ast::proto proto, str name,
954960
}
955961
word(s.s, name);
956962
print_type_params(s, typarams);
963+
print_fn_args_and_ret(s, decl);
964+
}
965+
966+
fn print_fn_args_and_ret(&ps s, &ast::fn_decl decl) {
957967
popen(s);
958968
fn print_arg(&ps s, &ast::arg x) {
959969
ibox(s, indent_unit);
@@ -963,8 +973,7 @@ fn print_fn(&ps s, ast::fn_decl decl, ast::proto proto, str name,
963973
word(s.s, x.ident);
964974
end(s);
965975
}
966-
auto f = print_arg;
967-
commasep[ast::arg](s, inconsistent, decl.inputs, f);
976+
commasep[ast::arg](s, inconsistent, decl.inputs, print_arg);
968977
pclose(s);
969978
maybe_print_comment(s, decl.output.span.lo);
970979
if (decl.output.node != ast::ty_nil) {

trunk/src/test/run-pass/fn-expr.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
fn main() {
2+
auto x = fn(int a) -> int { ret a + 1; };
3+
assert (x(4) == 5);
4+
}

0 commit comments

Comments
 (0)