mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2024-11-23 12:52:46 +00:00
Move the rest of the obj specific stuff into class.c.
This gives better hiding of implementation details.
This commit is contained in:
parent
7cb2e40bce
commit
3af031c33d
7 changed files with 62 additions and 38 deletions
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue