about summary refs log tree commit diff
path: root/src/rustc/syntax
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
parent1d826b735c30a89bfe3aac8acbcda4efc8b5286f (diff)
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')
-rw-r--r--src/rustc/syntax/ast.rs12
-rw-r--r--src/rustc/syntax/fold.rs12
-rw-r--r--src/rustc/syntax/parse/parser.rs47
-rw-r--r--src/rustc/syntax/print/pprust.rs9
-rw-r--r--src/rustc/syntax/visit.rs6
5 files changed, 50 insertions, 36 deletions
diff --git a/src/rustc/syntax/ast.rs b/src/rustc/syntax/ast.rs
index eea47191eef..2f0c4bf7839 100644
--- a/src/rustc/syntax/ast.rs
+++ b/src/rustc/syntax/ast.rs
@@ -9,9 +9,6 @@ type ident = str;
 // Functions may or may not have names.
 type fn_ident = option<ident>;
 
-// FIXME: with typestate constraint, could say
-// idents and types are the same length, and are
-// non-empty
 type path_ = {global: bool, idents: [ident], types: [@ty]};
 
 type path = spanned<path_>;
@@ -499,9 +496,7 @@ enum item_ {
     item_class([ty_param], /* ty params for class */
                [@class_item], /* methods, etc. */
                              /* (not including ctor) */
-               node_id,  /* ctor id */
-               fn_decl, /* ctor decl */
-               blk /* ctor body */
+               class_ctor
                ),
     item_iface([ty_param], [ty_method]),
     item_impl([ty_param], option<@ty> /* iface */,
@@ -523,6 +518,11 @@ enum class_mutability { class_mutable, class_immutable }
 
 enum privacy { priv, pub }
 
+type class_ctor = spanned<class_ctor_>;
+type class_ctor_ = {id: node_id,
+                    dec: fn_decl,
+                    body: blk};
+
 type native_item =
     {ident: ident,
      attrs: [attribute],
diff --git a/src/rustc/syntax/fold.rs b/src/rustc/syntax/fold.rs
index 7ceae548769..d8088e39cb6 100644
--- a/src/rustc/syntax/fold.rs
+++ b/src/rustc/syntax/fold.rs
@@ -269,12 +269,14 @@ fn noop_fold_item_underscore(i: item_, fld: ast_fold) -> item_ {
             item_enum(vec::map(variants, fld.fold_variant),
                       fold_ty_params(typms, fld))
           }
-          item_class(typms, items, id, ctor_decl, ctor_body) {
-              item_class(fold_ty_params(typms, fld),
+          item_class(typms, items, ctor) {
+              let ctor_body = fld.fold_block(ctor.node.body);
+              let ctor_decl = fold_fn_decl(ctor.node.dec, fld);
+              item_class(typms,
                          vec::map(items, fld.fold_class_item),
-                         id,
-                         fold_fn_decl(ctor_decl, fld),
-                         fld.fold_block(ctor_body))
+                         {node: {body: ctor_body,
+                                     dec: ctor_decl with ctor.node}
+                             with ctor})
           }
           item_impl(tps, ifce, ty, methods) {
             item_impl(tps, option::map(ifce, fld.fold_ty), fld.fold_ty(ty),
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);
          }
         }
     }
diff --git a/src/rustc/syntax/print/pprust.rs b/src/rustc/syntax/print/pprust.rs
index 5f92b5d5beb..d74d5d92c5f 100644
--- a/src/rustc/syntax/print/pprust.rs
+++ b/src/rustc/syntax/print/pprust.rs
@@ -471,22 +471,24 @@ fn print_item(s: ps, &&item: @ast::item) {
             bclose(s, item.span);
         }
       }
-      ast::item_class(tps,items,_,ctor_decl,ctor_body) {
+      ast::item_class(tps,items,ctor) {
           head(s, "class");
           word_nbsp(s, item.ident);
           print_type_params(s, tps);
           bopen(s);
           hardbreak_if_not_bol(s);
+          maybe_print_comment(s, ctor.span.lo);
           head(s, "new");
-          print_fn_args_and_ret(s, ctor_decl);
+          print_fn_args_and_ret(s, ctor.node.dec);
           space(s.s);
-          print_block(s, ctor_body);
+          print_block(s, ctor.node.body);
           for ci in items {
                   /*
                      FIXME: collect all private items and print them
                      in a single "priv" section
                    */
              hardbreak_if_not_bol(s);
+             maybe_print_comment(s, ci.span.lo);
              alt ci.node.privacy {
                 ast::priv {
                     head(s, "priv");
@@ -516,6 +518,7 @@ fn print_item(s: ps, &&item: @ast::item) {
                  _ {}
              }
           }
+          bclose(s, item.span);
        }
       ast::item_impl(tps, ifce, ty, methods) {
         head(s, "impl");
diff --git a/src/rustc/syntax/visit.rs b/src/rustc/syntax/visit.rs
index 55958abd7af..dd1a53942fa 100644
--- a/src/rustc/syntax/visit.rs
+++ b/src/rustc/syntax/visit.rs
@@ -133,13 +133,13 @@ fn visit_item<E>(i: @item, e: E, v: vt<E>) {
             visit_method_helper(m, e, v)
         }
       }
-      item_class(tps, members, _, ctor_decl, ctor_blk) {
+      item_class(tps, members, ctor) {
           v.visit_ty_params(tps, e, v);
           for m in members {
              v.visit_class_item(m.span, m.node.privacy, m.node.decl, e, v);
           }
-          visit_fn_decl(ctor_decl, e, v);
-          v.visit_block(ctor_blk, e, v);
+          visit_fn_decl(ctor.node.dec, e, v);
+          v.visit_block(ctor.node.body, e, v);
       }
       item_iface(tps, methods) {
         v.visit_ty_params(tps, e, v);