Move the rest of the obj specific stuff into class.c.

This gives better hiding of implementation details.
This commit is contained in:
Bill Currie 2012-12-19 11:53:19 +09:00
parent 7cb2e40bce
commit 3af031c33d
7 changed files with 62 additions and 38 deletions

View file

@ -108,6 +108,8 @@ struct method_s;
struct symbol_s;
int obj_is_id (const struct type_s *type);
int obj_is_class (const struct type_s *type);
int obj_types_assignable (const struct type_s *dst, const struct type_s *src);
class_t *extract_class (class_type_t *class_type);
const char *get_class_name (class_type_t *class_type, int pretty);

View file

@ -156,7 +156,6 @@ int is_scalar (const type_t *type);
int is_math (const type_t *type);
int is_pointer (const type_t *type);
int is_struct (const type_t *type);
int is_class (const type_t *type);
int is_array (const type_t *type);
int type_assignable (const type_t *dst, const type_t *src);
int type_size (const type_t *type);

View file

@ -190,6 +190,50 @@ obj_is_id (const type_t *type)
return 0;
}
int
obj_is_class (const type_t *type)
{
if (type->type == ev_invalid && type->meta == ty_class)
return 1;
return 0;
}
int
obj_types_assignable (const type_t *dst, const type_t *src)
{
class_t *dst_class, *src_class;
if (obj_is_id (dst)
&& (obj_is_id (src)
|| obj_is_class (src->t.fldptr.type)
|| src == &type_Class)) {
return 1;
}
if (obj_is_id (src)
&& (obj_is_id (dst)
|| obj_is_class (dst->t.fldptr.type)
|| dst == &type_Class)) {
return 1;
}
if (!obj_is_class (dst->t.fldptr.type)
|| !obj_is_class (src->t.fldptr.type))
return -1;
// check dst is a base class of src
dst_class = dst->t.fldptr.type->t.class;
src_class = src->t.fldptr.type->t.class;
//printf ("%s %s\n", dst_class->name, src_class->name);
while (dst_class != src_class && src_class) {
src_class = src_class->super_class;
//if (src_class)
// printf ("%s %s\n", dst_class->name, src_class->name);
}
if (dst_class == src_class)
return 1;
return 0;
}
static const char *
class_get_key (const void *class, void *unused)
{

View file

@ -140,7 +140,7 @@ new_def (const char *name, type_t *type, defspace_t *space,
if (!space && storage != sc_extern)
internal_error (0, "non-external def with no storage space");
if (is_class (type)) {
if (obj_is_class (type)) {
error (0, "statically allocated instance of class %s",
type->t.class->name);
return def;

View file

@ -989,7 +989,7 @@ field_expr (expr_t *e1, expr_t *e2)
e = new_binary_expr ('&', e1, e2);
e->e.expr.type = pointer_type (field->type);
return unary_expr ('.', e);
} else if (is_class (t1->t.fldptr.type)) {
} else if (obj_is_class (t1->t.fldptr.type)) {
class_t *class = t1->t.fldptr.type->t.class;
symbol_t *sym = e2->e.symbol;//FIXME need to check
symbol_t *ivar;
@ -1039,7 +1039,7 @@ field_expr (expr_t *e1, expr_t *e2)
e = address_expr (e1, e2, field->type);
return unary_expr ('.', e);
}
} else if (is_class (t1)) {
} else if (obj_is_class (t1)) {
internal_error (e1, "access to class instances not implemented");
}
return type_mismatch (e1, e2, '.');
@ -2830,7 +2830,7 @@ message_expr (expr_t *receiver, keywordarg_t *message)
} else {
if (rec_type->type == ev_pointer)
rec_type = rec_type->t.fldptr.type;
if (!is_class (rec_type))
if (!obj_is_class (rec_type))
return error (receiver, "not a class/object");
if (self) {

View file

@ -582,7 +582,7 @@ struct_defs
| DEFS '(' identifier ')'
{
$3 = check_undefined ($3);
if (!$3->type || !is_class ($3->type)) {
if (!$3->type || !obj_is_class ($3->type)) {
error (0, "`%s' is not a class", $3->name);
} else {
// replace the struct symbol table with one built from
@ -1338,7 +1338,7 @@ class_name
: identifier %prec CLASS_NOT_CATEGORY
{
$1 = check_undefined ($1);
if (!$1->type || !is_class ($1->type)) {
if (!$1->type || !obj_is_class ($1->type)) {
error (0, "`%s' is not a class %p", $1->name, $1->type);
$$ = get_class (0, 1);
} else {

View file

@ -101,7 +101,7 @@ low_level_type (type_t *type)
return type->type;
if (is_enum (type))
return type_default->type;
if (is_struct (type) || is_class (type)) {
if (is_struct (type)) {
//FIXME does this break anything?
//maybe the peephole optimizer should do this sort of thing.
if (type_size (type) == 1)
@ -704,14 +704,6 @@ is_pointer (const type_t *type)
return 0;
}
int
is_class (const type_t *type)
{
if (type->type == ev_invalid && type->meta == ty_class)
return 1;
return 0;
}
int
is_array (const type_t *type)
{
@ -723,7 +715,7 @@ is_array (const type_t *type)
int
type_assignable (const type_t *dst, const type_t *src)
{
class_t *dst_class, *src_class;
int ret;
// same type
if (dst == src)
@ -731,14 +723,6 @@ type_assignable (const type_t *dst, const type_t *src)
// any field = any field
if (dst->type == ev_field && src->type == ev_field)
return 1;
// id = any class pointer
if (obj_is_id (dst) && src->type == ev_pointer
&& (is_class (src->t.fldptr.type) || src == &type_Class))
return 1;
// any class pointer = id
if (obj_is_id (src) && dst->type == ev_pointer
&& (is_class (dst->t.fldptr.type) || dst == &type_Class))
return 1;
// pointer = array
if (dst->type == ev_pointer
&& src->type == ev_invalid && src->meta == ty_array) {
@ -748,26 +732,21 @@ type_assignable (const type_t *dst, const type_t *src)
}
if (dst->type != ev_pointer || src->type != ev_pointer)
return is_scalar (dst) && is_scalar (src);
// pointer = pointer
// give the object system first shot because the pointee types might have
// protocols attached.
ret = obj_types_assignable (dst, src);
// ret < 0 means obj_types_assignable can't decide
if (ret >= 0)
return ret;
dst = dst->t.fldptr.type;
src = src->t.fldptr.type;
if (dst->type == ev_void)
return 1;
if (src->type == ev_void)
return 1;
if (!is_class (dst) || !is_class (src))
return 0;
// check dst is a base class of src
dst_class = dst->t.class;
src_class = src->t.class;
//printf ("%s %s\n", dst_class->class_name, src_class->class_name);
while (dst_class != src_class && src_class) {
src_class = src_class->super_class;
//if (src_class)
// printf ("%s %s\n", dst_class->class_name, src_class->class_name);
}
if (dst_class == src_class)
return 1;
return 0;
}