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.
This commit is contained in:
parent
1d826b735c
commit
e2fa6f03f5
18 changed files with 493 additions and 232 deletions
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue