diff options
| author | Tim Chevalier <chevalier@alum.wellesley.edu> | 2012-03-03 17:49:23 -0800 |
|---|---|---|
| committer | Tim Chevalier <chevalier@alum.wellesley.edu> | 2012-03-04 12:43:17 -0800 |
| commit | e2fa6f03f5b3195b2f81e259a6b946567440b576 (patch) | |
| tree | ed57e10c040505678b037902964f6d543d2cd52f /src/rustc/syntax/parse/parser.rs | |
| parent | 1d826b735c30a89bfe3aac8acbcda4efc8b5286f (diff) | |
| download | rust-e2fa6f03f5b3195b2f81e259a6b946567440b576.tar.gz rust-e2fa6f03f5b3195b2f81e259a6b946567440b576.zip | |
Translate simple classes
Programs using classes with fields only (no methods) compile and run,
as long as nothing refers to a class in a different crate (todo).
Also changed the AST representation of classes to have a separate
record for constructor info (instead of inlining the fields in the
item_class node), and fixed up spans and pretty-printing for
classes.
Diffstat (limited to 'src/rustc/syntax/parse/parser.rs')
| -rw-r--r-- | src/rustc/syntax/parse/parser.rs | 47 |
1 files changed, 28 insertions, 19 deletions
diff --git a/src/rustc/syntax/parse/parser.rs b/src/rustc/syntax/parse/parser.rs index 5837baf1ff9..e8df2f86305 100644 --- a/src/rustc/syntax/parse/parser.rs +++ b/src/rustc/syntax/parse/parser.rs @@ -1590,8 +1590,9 @@ fn parse_let(p: parser) -> @ast::decl { ret @spanned(lo, p.last_span.hi, ast::decl_local(locals)); } -fn parse_instance_var(p:parser) -> ast::class_member { +fn parse_instance_var(p:parser) -> (ast::class_member, codemap::span) { let is_mutbl = ast::class_immutable; + let lo = p.span.lo; expect_word(p, "let"); if eat_word(p, "mut") || eat_word(p, "mutable") { is_mutbl = ast::class_mutable; @@ -1602,7 +1603,8 @@ fn parse_instance_var(p:parser) -> ast::class_member { let name = parse_ident(p); expect(p, token::COLON); let ty = parse_ty(p, false); - ret ast::instance_var(name, ty, is_mutbl, p.get_id()); + ret (ast::instance_var(name, ty, is_mutbl, p.get_id()), + ast_util::mk_sp(lo, p.last_span.hi)); } fn parse_stmt(p: parser, first_item_attrs: [ast::attribute]) -> @ast::stmt { @@ -1976,27 +1978,33 @@ fn parse_item_class(p: parser, attrs: [ast::attribute]) -> @ast::item { expect(p, token::LBRACE); let items: [@ast::class_item] = []; let ctor_id = p.get_id(); - let the_ctor : option<(ast::fn_decl, ast::blk)> = none; + let the_ctor : option<(ast::fn_decl, ast::blk, codemap::span)> = none; while p.token != token::RBRACE { alt parse_class_item(p, class_path) { - ctor_decl(a_fn_decl, blk) { - the_ctor = some((a_fn_decl, blk)); + ctor_decl(a_fn_decl, blk, s) { + the_ctor = some((a_fn_decl, blk, s)); } - plain_decl(a_decl) { + plain_decl(a_decl, s) { items += [@{node: {privacy: ast::pub, decl: a_decl}, - span: p.last_span}]; + span: s}]; } priv_decls(some_decls) { - items += vec::map(some_decls, {|d| + items += vec::map(some_decls, {|p| + let (d, s) = p; @{node: {privacy: ast::priv, decl: d}, - span: p.last_span}}); + span: s}}); } } } p.bump(); alt the_ctor { - some((ct_d, ct_b)) { ret mk_item(p, lo, p.last_span.hi, class_name, - ast::item_class(ty_params, items, ctor_id, ct_d, ct_b), attrs); } + some((ct_d, ct_b, ct_s)) { ret mk_item(p, lo, p.last_span.hi, + class_name, + ast::item_class(ty_params, items, + {node: {id: ctor_id, + dec: ct_d, + body: ct_b}, + span: ct_s}), attrs); } /* Is it strange for the parser to check this? */ @@ -2007,16 +2015,17 @@ fn parse_item_class(p: parser, attrs: [ast::attribute]) -> @ast::item { // lets us identify the constructor declaration at // parse time // we don't really want just the fn_decl... -enum class_contents { ctor_decl(ast::fn_decl, ast::blk), +enum class_contents { ctor_decl(ast::fn_decl, ast::blk, codemap::span), // assumed to be public - plain_decl(ast::class_member), + plain_decl(ast::class_member, codemap::span), // contents of a priv section -- // parse_class_item ensures that // none of these are a ctor decl - priv_decls([ast::class_member])} + priv_decls([(ast::class_member, codemap::span)])} fn parse_class_item(p:parser, class_name:@ast::path) -> class_contents { if eat_word(p, "new") { + let lo = p.last_span.lo; // Can ctors have attrs? // result type is always the type of the class let decl_ = parse_fn_decl(p, ast::impure_fn); @@ -2024,7 +2033,7 @@ enum class_contents { ctor_decl(ast::fn_decl, ast::blk), span: decl_.output.span} with decl_}; let body = parse_block(p); - ret ctor_decl(decl, body); + ret ctor_decl(decl, body, ast_util::mk_sp(lo, p.last_span.hi)); } // FIXME: refactor else if eat_word(p, "priv") { @@ -2033,7 +2042,7 @@ enum class_contents { ctor_decl(ast::fn_decl, ast::blk), while p.token != token::RBRACE { alt parse_item(p, []) { some(i) { - results += [ast::class_method(i)]; + results += [(ast::class_method(i), i.span)]; } _ { let a_var = parse_instance_var(p); @@ -2049,12 +2058,12 @@ enum class_contents { ctor_decl(ast::fn_decl, ast::blk), // Probably need to parse attrs alt parse_item(p, []) { some(i) { - ret plain_decl(ast::class_method(i)); + ret plain_decl(ast::class_method(i), i.span); } _ { - let a_var = parse_instance_var(p); + let (a_var, a_span) = parse_instance_var(p); expect(p, token::SEMI); - ret plain_decl(a_var); + ret plain_decl(a_var, a_span); } } } |
