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;
|
struct symbol_s;
|
||||||
|
|
||||||
int obj_is_id (const struct type_s *type);
|
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);
|
class_t *extract_class (class_type_t *class_type);
|
||||||
const char *get_class_name (class_type_t *class_type, int pretty);
|
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_math (const type_t *type);
|
||||||
int is_pointer (const type_t *type);
|
int is_pointer (const type_t *type);
|
||||||
int is_struct (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 is_array (const type_t *type);
|
||||||
int type_assignable (const type_t *dst, const type_t *src);
|
int type_assignable (const type_t *dst, const type_t *src);
|
||||||
int type_size (const type_t *type);
|
int type_size (const type_t *type);
|
||||||
|
|
|
@ -190,6 +190,50 @@ obj_is_id (const type_t *type)
|
||||||
return 0;
|
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 *
|
static const char *
|
||||||
class_get_key (const void *class, void *unused)
|
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)
|
if (!space && storage != sc_extern)
|
||||||
internal_error (0, "non-external def with no storage space");
|
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",
|
error (0, "statically allocated instance of class %s",
|
||||||
type->t.class->name);
|
type->t.class->name);
|
||||||
return def;
|
return def;
|
||||||
|
|
|
@ -989,7 +989,7 @@ field_expr (expr_t *e1, expr_t *e2)
|
||||||
e = new_binary_expr ('&', e1, e2);
|
e = new_binary_expr ('&', e1, e2);
|
||||||
e->e.expr.type = pointer_type (field->type);
|
e->e.expr.type = pointer_type (field->type);
|
||||||
return unary_expr ('.', e);
|
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;
|
class_t *class = t1->t.fldptr.type->t.class;
|
||||||
symbol_t *sym = e2->e.symbol;//FIXME need to check
|
symbol_t *sym = e2->e.symbol;//FIXME need to check
|
||||||
symbol_t *ivar;
|
symbol_t *ivar;
|
||||||
|
@ -1039,7 +1039,7 @@ field_expr (expr_t *e1, expr_t *e2)
|
||||||
e = address_expr (e1, e2, field->type);
|
e = address_expr (e1, e2, field->type);
|
||||||
return unary_expr ('.', e);
|
return unary_expr ('.', e);
|
||||||
}
|
}
|
||||||
} else if (is_class (t1)) {
|
} else if (obj_is_class (t1)) {
|
||||||
internal_error (e1, "access to class instances not implemented");
|
internal_error (e1, "access to class instances not implemented");
|
||||||
}
|
}
|
||||||
return type_mismatch (e1, e2, '.');
|
return type_mismatch (e1, e2, '.');
|
||||||
|
@ -2830,7 +2830,7 @@ message_expr (expr_t *receiver, keywordarg_t *message)
|
||||||
} else {
|
} else {
|
||||||
if (rec_type->type == ev_pointer)
|
if (rec_type->type == ev_pointer)
|
||||||
rec_type = rec_type->t.fldptr.type;
|
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");
|
return error (receiver, "not a class/object");
|
||||||
|
|
||||||
if (self) {
|
if (self) {
|
||||||
|
|
|
@ -582,7 +582,7 @@ struct_defs
|
||||||
| DEFS '(' identifier ')'
|
| DEFS '(' identifier ')'
|
||||||
{
|
{
|
||||||
$3 = check_undefined ($3);
|
$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);
|
error (0, "`%s' is not a class", $3->name);
|
||||||
} else {
|
} else {
|
||||||
// replace the struct symbol table with one built from
|
// replace the struct symbol table with one built from
|
||||||
|
@ -1338,7 +1338,7 @@ class_name
|
||||||
: identifier %prec CLASS_NOT_CATEGORY
|
: identifier %prec CLASS_NOT_CATEGORY
|
||||||
{
|
{
|
||||||
$1 = check_undefined ($1);
|
$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);
|
error (0, "`%s' is not a class %p", $1->name, $1->type);
|
||||||
$$ = get_class (0, 1);
|
$$ = get_class (0, 1);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -101,7 +101,7 @@ low_level_type (type_t *type)
|
||||||
return type->type;
|
return type->type;
|
||||||
if (is_enum (type))
|
if (is_enum (type))
|
||||||
return type_default->type;
|
return type_default->type;
|
||||||
if (is_struct (type) || is_class (type)) {
|
if (is_struct (type)) {
|
||||||
//FIXME does this break anything?
|
//FIXME does this break anything?
|
||||||
//maybe the peephole optimizer should do this sort of thing.
|
//maybe the peephole optimizer should do this sort of thing.
|
||||||
if (type_size (type) == 1)
|
if (type_size (type) == 1)
|
||||||
|
@ -704,14 +704,6 @@ is_pointer (const type_t *type)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
|
||||||
is_class (const type_t *type)
|
|
||||||
{
|
|
||||||
if (type->type == ev_invalid && type->meta == ty_class)
|
|
||||||
return 1;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
int
|
||||||
is_array (const type_t *type)
|
is_array (const type_t *type)
|
||||||
{
|
{
|
||||||
|
@ -723,7 +715,7 @@ is_array (const type_t *type)
|
||||||
int
|
int
|
||||||
type_assignable (const type_t *dst, const type_t *src)
|
type_assignable (const type_t *dst, const type_t *src)
|
||||||
{
|
{
|
||||||
class_t *dst_class, *src_class;
|
int ret;
|
||||||
|
|
||||||
// same type
|
// same type
|
||||||
if (dst == src)
|
if (dst == src)
|
||||||
|
@ -731,14 +723,6 @@ type_assignable (const type_t *dst, const type_t *src)
|
||||||
// any field = any field
|
// any field = any field
|
||||||
if (dst->type == ev_field && src->type == ev_field)
|
if (dst->type == ev_field && src->type == ev_field)
|
||||||
return 1;
|
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
|
// pointer = array
|
||||||
if (dst->type == ev_pointer
|
if (dst->type == ev_pointer
|
||||||
&& src->type == ev_invalid && src->meta == ty_array) {
|
&& 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)
|
if (dst->type != ev_pointer || src->type != ev_pointer)
|
||||||
return is_scalar (dst) && is_scalar (src);
|
return is_scalar (dst) && is_scalar (src);
|
||||||
|
|
||||||
// pointer = pointer
|
// 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;
|
dst = dst->t.fldptr.type;
|
||||||
src = src->t.fldptr.type;
|
src = src->t.fldptr.type;
|
||||||
if (dst->type == ev_void)
|
if (dst->type == ev_void)
|
||||||
return 1;
|
return 1;
|
||||||
if (src->type == ev_void)
|
if (src->type == ev_void)
|
||||||
return 1;
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue