about summary refs log tree commit diff
path: root/src/rustc/syntax/parse/parser.rs
diff options
context:
space:
mode:
authorTim Chevalier <chevalier@alum.wellesley.edu>2012-03-03 17:49:23 -0800
committerTim Chevalier <chevalier@alum.wellesley.edu>2012-03-04 12:43:17 -0800
commite2fa6f03f5b3195b2f81e259a6b946567440b576 (patch)
treeed57e10c040505678b037902964f6d543d2cd52f /src/rustc/syntax/parse/parser.rs
parent1d826b735c30a89bfe3aac8acbcda4efc8b5286f (diff)
downloadrust-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.rs47
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);
          }
         }
     }