Further WIP on classes

Changes to resolve and typeck. Still nothning working yet.
This commit is contained in:
Tim Chevalier 2012-02-09 14:16:12 -08:00
parent 9effae8413
commit 503dec1d62
6 changed files with 75 additions and 6 deletions

View File

@ -192,6 +192,13 @@ fn enc_sty(w: io::writer, cx: @ctxt, st: ty::sty) {
w.write_char(']');
}
ty::ty_opaque_box { w.write_char('B'); }
ty::ty_class(def, tys) {
w.write_str("c[");
w.write_str(cx.ds(def));
w.write_char('|');
for t: ty::t in tys { enc_ty(w, cx, t); }
w.write_char(']');
}
}
}
fn enc_proto(w: io::writer, proto: proto) {

View File

@ -472,6 +472,16 @@ fn visit_item_with_scope(e: @env, i: @ast::item, sc: scopes, v: vt<scopes>) {
v.visit_ty(m.decl.output, msc, v);
}
}
ast::item_class(tps, members, ctor_id, ctor_decl, ctor_block) {
visit::visit_ty_params(tps, sc, v);
let ctor_scope = cons(scope_fn_expr(ctor_decl, ctor_id, tps), @sc);
for cm in members {
alt cm.node.decl {
class_method(i) { visit_item_with_scope(e, i, ctor_scope, v); }
_ { } // instance var -- nothing to do
}
}
}
_ { visit::visit_item(i, sc, v); }
}
@ -1209,7 +1219,9 @@ fn found_def_item(i: @ast::item, ns: namespace) -> option<def> {
}
}
ast::item_class(_, _, _, _, _) {
fail "class! don't know what to do";
if ns == ns_type {
ret some(ast::def_class(local_def(i.id)));
}
}
ast::item_impl(_,_,_,_) { /* ??? */ }
}

View File

@ -63,6 +63,7 @@ const shape_stack_fn: u8 = 26u8;
const shape_bare_fn: u8 = 27u8;
const shape_tydesc: u8 = 28u8;
const shape_send_tydesc: u8 = 29u8;
const shape_class: u8 = 30u8;
// FIXME: This is a bad API in trans_common.
fn C_u8(n: u8) -> ValueRef { ret trans::common::C_u8(n as uint); }
@ -404,6 +405,7 @@ fn shape_of(ccx: @crate_ctxt, t: ty::t, ty_param_map: [uint]) -> [u8] {
add_substr(s, sub);
}
ty::ty_iface(_, _) { s += [shape_iface]; }
ty::ty_class(_, _) { s += [shape_class]; }
ty::ty_res(did, raw_subt, tps) {
let subt = ty::substitute_type_params(ccx.tcx, tps, raw_subt);
let ri = {did: did, t: subt};

View File

@ -40,6 +40,7 @@ export is_pred_ty;
export lookup_item_type;
export method;
export method_idx;
export mk_class;
export mk_ctxt;
export mk_named, type_name;
export mt;
@ -225,6 +226,7 @@ enum sty {
ty_rec([field]),
ty_fn(fn_ty),
ty_iface(def_id, [t]),
ty_class(def_id, [t]),
ty_res(def_id, t, [t]),
ty_tup([t]),
@ -354,7 +356,7 @@ fn mk_t_named(cx: ctxt, st: sty, name: option<str>) -> t {
ty_opaque_box {}
ty_param(_, _) { has_params = true; }
ty_var(_) | ty_self(_) { has_vars = true; }
ty_enum(_, tys) | ty_iface(_, tys) {
ty_enum(_, tys) | ty_iface(_, tys) | ty_class(_, tys) {
for tt in tys { derive_flags(has_params, has_vars, tt); }
}
ty_box(m) | ty_uniq(m) | ty_vec(m) | ty_ptr(m) {
@ -442,6 +444,10 @@ fn mk_iface(cx: ctxt, did: ast::def_id, tys: [t]) -> t {
mk_t(cx, ty_iface(did, tys))
}
fn mk_class(cx: ctxt, class_id: ast::def_id, tys: [t]) -> t {
mk_t(cx, ty_class(class_id, tys))
}
fn mk_res(cx: ctxt, did: ast::def_id, inner: t, tps: [t]) -> t {
mk_t(cx, ty_res(did, inner, tps))
}
@ -487,7 +493,8 @@ fn walk_ty(cx: ctxt, ty: t, f: fn(t)) {
ty_str | ty_send_type | ty_type | ty_opaque_box |
ty_opaque_closure_ptr(_) | ty_var(_) | ty_param(_, _) {}
ty_box(tm) | ty_vec(tm) | ty_ptr(tm) { walk_ty(cx, tm.ty, f); }
ty_enum(_, subtys) | ty_iface(_, subtys) | ty_self(subtys) {
ty_enum(_, subtys) | ty_iface(_, subtys) | ty_class(_, subtys)
| ty_self(subtys) {
for subty: t in subtys { walk_ty(cx, subty, f); }
}
ty_rec(fields) {
@ -1155,6 +1162,11 @@ fn hash_type_structure(st: sty) -> uint {
ty_opaque_closure_ptr(ck_box) { 42u }
ty_opaque_closure_ptr(ck_uniq) { 43u }
ty_opaque_box { 44u }
ty_class(did, tys) {
let h = hash_def(45u, did);
for typ: t in tys { h = hash_subty(h, typ); }
h
}
}
}
@ -2410,6 +2422,9 @@ fn lookup_item_type(cx: ctxt, did: ast::def_id) -> ty_param_bounds_and_ty {
alt cx.tcache.find(did) {
some(tpt) { ret tpt; }
none {
/* where do things get added to the cache?
Have to add class members */
// The item is in this crate. The caller should have added it to the
// type cache already
assert did.crate != ast::local_crate;

View File

@ -108,7 +108,9 @@ fn ty_param_bounds_and_ty_for_def(fcx: @fn_ctxt, sp: span, defn: ast::def) ->
}
}
ast::def_fn(id, _) | ast::def_const(id) |
ast::def_variant(_, id) { ret ty::lookup_item_type(fcx.ccx.tcx, id); }
ast::def_variant(_, id) | ast::def_class(id)
| ast::def_class_method(_, id) | ast::def_class_field(_, id)
{ ret ty::lookup_item_type(fcx.ccx.tcx, id); }
ast::def_binding(id) {
assert (fcx.locals.contains_key(id.node));
let typ = ty::mk_var(fcx.ccx.tcx, lookup_local(fcx, sp, id.node));
@ -422,8 +424,12 @@ fn ty_of_item(tcx: ty::ctxt, mode: mode, it: @ast::item)
tcx.tcache.insert(local_def(it.id), tpt);
ret tpt;
}
ast::item_class(_,_,_,_,_) {
fail "ty_of_item: implement item_class";
ast::item_class(tps,_,_,_,_) {
let {bounds,params} = mk_ty_params(tcx, tps);
let t = ty::mk_class(tcx, local_def(it.id), params);
let tpt = {bounds: bounds, ty: t};
tcx.tcache.insert(local_def(it.id), tpt);
ret tpt;
}
ast::item_impl(_, _, _, _) | ast::item_mod(_) |
ast::item_native_mod(_) { fail; }
@ -755,6 +761,10 @@ mod collect {
_ { fail; }
}
}
fn convert_class_item(cx: @ctxt, parent_ty: ty::t,
ci: ast::class_member) {
/* TODO */
}
fn convert(cx: @ctxt, it: @ast::item) {
alt it.node {
// These don't define types.
@ -847,6 +857,19 @@ mod collect {
write_ty(cx.tcx, it.id, tpt.ty);
ensure_iface_methods(cx.tcx, it.id);
}
ast::item_class(tps, members, ctor_id, ctor_decl, ctor_block) {
let parent_ty = ty::lookup_item_type(cx.tcx, local_def(it.id));
// Write the ctor type
let t_ctor = ty::mk_fn(cx.tcx,
ty_of_fn_decl(cx.tcx, m_collect,
ast::proto_any, ctor_decl));
write_ty(cx.tcx, ctor_id, t_ctor);
/* FIXME: check for proper public/privateness */
// Write the type of each of the members
for m in members {
convert_class_item(cx, parent_ty.ty, m.node.decl);
}
}
_ {
// This call populates the type cache with the converted type
// of the item in passing. All we have to do here is to write

View File

@ -0,0 +1,10 @@
// xfail-test
class cat {
priv {
let mutable meows : uint;
}
let how_hungry : int;
new(in_x : uint, in_y : int) { meows = in_x; how_hungry = in_y; }
}