mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2024-11-29 23:52:22 +00:00
getting closer to working categories
This commit is contained in:
parent
e544c1247f
commit
3c215ce13f
7 changed files with 228 additions and 172 deletions
|
@ -32,6 +32,14 @@
|
||||||
#ifndef __class_h
|
#ifndef __class_h
|
||||||
#define __class_h
|
#define __class_h
|
||||||
|
|
||||||
|
typedef struct class_type_s {
|
||||||
|
int is_class;
|
||||||
|
union {
|
||||||
|
struct category_s *category;
|
||||||
|
struct class_s *class;
|
||||||
|
} c;
|
||||||
|
} class_type_t;
|
||||||
|
|
||||||
typedef struct class_s {
|
typedef struct class_s {
|
||||||
int defined;
|
int defined;
|
||||||
const char *name;
|
const char *name;
|
||||||
|
@ -42,45 +50,53 @@ typedef struct class_s {
|
||||||
struct protocollist_s *protocols;
|
struct protocollist_s *protocols;
|
||||||
struct def_s *def;
|
struct def_s *def;
|
||||||
struct type_s *type;
|
struct type_s *type;
|
||||||
|
class_type_t class_type;
|
||||||
} class_t;
|
} class_t;
|
||||||
|
|
||||||
typedef struct category_s {
|
typedef struct category_s {
|
||||||
struct category_s *next;
|
struct category_s *next;
|
||||||
const char *name;
|
const char *name;
|
||||||
class_t *class;
|
class_t *class;
|
||||||
|
int defined;
|
||||||
struct methodlist_s *methods;
|
struct methodlist_s *methods;
|
||||||
struct protocollist_s *protocols;
|
struct protocollist_s *protocols;
|
||||||
|
struct def_s *def;
|
||||||
|
class_type_t class_type;
|
||||||
} category_t;
|
} category_t;
|
||||||
|
|
||||||
extern class_t class_id;
|
extern class_t class_id;
|
||||||
extern class_t class_Class;
|
extern class_t class_Class;
|
||||||
extern class_t class_Protocol;
|
extern class_t class_Protocol;
|
||||||
|
|
||||||
extern class_t *current_class;
|
extern class_type_t *current_class;
|
||||||
|
|
||||||
struct expr_s;
|
struct expr_s;
|
||||||
struct method_s;
|
struct method_s;
|
||||||
struct protocol_s;
|
struct protocol_s;
|
||||||
struct type_s;
|
struct type_s;
|
||||||
|
|
||||||
struct def_s *class_def (class_t *class, int external);
|
struct def_s *class_def (class_type_t *class_type, int external);
|
||||||
void class_init (void);
|
void class_init (void);
|
||||||
class_t *get_class (const char *name, int create);
|
class_t *get_class (const char *name, int create);
|
||||||
void class_add_methods (class_t *class, struct methodlist_s *methods);
|
void class_add_methods (class_t *class, struct methodlist_s *methods);
|
||||||
void class_add_protocol_methods (class_t *class, struct expr_s *protocols);
|
void class_add_protocol_methods (class_t *class, struct expr_s *protocols);
|
||||||
void class_add_protocol (class_t *class, struct protocol_s *protocol);
|
|
||||||
void class_add_ivars (class_t *class, struct type_s *ivars);
|
void class_add_ivars (class_t *class, struct type_s *ivars);
|
||||||
void class_check_ivars (class_t *class, struct type_s *ivars);
|
void class_check_ivars (class_t *class, struct type_s *ivars);
|
||||||
void class_begin (class_t *class);
|
void class_begin (class_type_t *class_type);
|
||||||
void class_finish (class_t *class);
|
void class_finish (class_type_t *class_type);
|
||||||
|
int class_access (class_type_t *current_class, class_t *class);
|
||||||
struct struct_field_s *class_find_ivar (class_t *class, int protected,
|
struct struct_field_s *class_find_ivar (class_t *class, int protected,
|
||||||
const char *name);
|
const char *name);
|
||||||
struct expr_s *class_ivar_expr (class_t *class, const char *name);
|
struct expr_s *class_ivar_expr (class_type_t *class_type, const char *name);
|
||||||
struct method_s *class_find_method (class_t *class, struct method_s *method);
|
struct method_s *class_find_method (class_type_t *class_type,
|
||||||
|
struct method_s *method);
|
||||||
struct method_s *class_message_response (class_t *class, struct expr_s *sel);
|
struct method_s *class_message_response (class_t *class, struct expr_s *sel);
|
||||||
struct def_s *class_pointer_def (class_t *class);
|
struct def_s *class_pointer_def (class_t *class_type);
|
||||||
class_t *get_category (const char *class_name, const char *category_name,
|
category_t *get_category (const char *class_name, const char *category_name,
|
||||||
int create);
|
int create);
|
||||||
|
void category_add_methods (category_t *category, struct methodlist_s *methods);
|
||||||
|
void category_add_protocol_methods (category_t *category,
|
||||||
|
struct expr_s *protocols);
|
||||||
void class_finish_module (void);
|
void class_finish_module (void);
|
||||||
|
|
||||||
typedef struct protocol_s {
|
typedef struct protocol_s {
|
||||||
|
|
|
@ -66,7 +66,7 @@ struct dstring_s;
|
||||||
method_t *new_method (struct type_s *ret_type, param_t *selector,
|
method_t *new_method (struct type_s *ret_type, param_t *selector,
|
||||||
param_t *opt_parms);
|
param_t *opt_parms);
|
||||||
void add_method (methodlist_t *methodlist, method_t *method);
|
void add_method (methodlist_t *methodlist, method_t *method);
|
||||||
struct def_s *method_def (struct class_s *class, method_t *method);
|
struct def_s *method_def (struct class_type_s *class_type, method_t *method);
|
||||||
|
|
||||||
methodlist_t *new_methodlist (void);
|
methodlist_t *new_methodlist (void);
|
||||||
void copy_methods (methodlist_t *dst, methodlist_t *src);
|
void copy_methods (methodlist_t *dst, methodlist_t *src);
|
||||||
|
|
|
@ -87,20 +87,18 @@ class_init (void)
|
||||||
}
|
}
|
||||||
|
|
||||||
def_t *
|
def_t *
|
||||||
class_def (class_t *class, int external)
|
class_def (class_type_t *class_type, int external)
|
||||||
{
|
{
|
||||||
const char *name;
|
const char *name;
|
||||||
type_t *type;
|
type_t *type;
|
||||||
storage_class_t storage = external ? st_extern : st_global;
|
storage_class_t storage = external ? st_extern : st_global;
|
||||||
|
|
||||||
if (!class->name)
|
if (!class_type->is_class) {
|
||||||
return 0;
|
name = va ("_OBJ_CATEGORY_%s_%s", class_type->c.category->class->name,
|
||||||
if (class->categories) {
|
class_type->c.category->name);
|
||||||
name = va ("_OBJ_CATEGORY_%s_%s",
|
|
||||||
class->name, class->categories->name);
|
|
||||||
type = type_category;
|
type = type_category;
|
||||||
} else {
|
} else {
|
||||||
name = va ("_OBJ_CLASS_%s", class->name);
|
name = va ("_OBJ_CLASS_%s", class_type->c.class->name);
|
||||||
type = type_Class.aux_type;
|
type = type_Class.aux_type;
|
||||||
}
|
}
|
||||||
return get_def (type, name, pr.scope, storage);
|
return get_def (type, name, pr.scope, storage);
|
||||||
|
@ -125,6 +123,8 @@ get_class (const char *name, int create)
|
||||||
new = *type_Class.aux_type;
|
new = *type_Class.aux_type;
|
||||||
new.class = c;
|
new.class = c;
|
||||||
c->type = pointer_type (find_type (&new));
|
c->type = pointer_type (find_type (&new));
|
||||||
|
c->class_type.is_class = 1;
|
||||||
|
c->class_type.c.class = c;
|
||||||
if (name)
|
if (name)
|
||||||
Hash_Add (class_hash, c);
|
Hash_Add (class_hash, c);
|
||||||
return c;
|
return c;
|
||||||
|
@ -135,18 +135,11 @@ class_add_methods (class_t *class, methodlist_t *methods)
|
||||||
{
|
{
|
||||||
if (!methods)
|
if (!methods)
|
||||||
return;
|
return;
|
||||||
if (class->categories) {
|
|
||||||
category_t *category = class->categories;
|
if (!class->methods)
|
||||||
if (!category->methods)
|
class->methods = new_methodlist ();
|
||||||
category->methods = new_methodlist ();
|
*class->methods->tail = methods->head;
|
||||||
*category->methods->tail = methods->head;
|
class->methods->tail = methods->tail;
|
||||||
category->methods->tail = methods->tail;
|
|
||||||
} else {
|
|
||||||
if (!class->methods)
|
|
||||||
class->methods = new_methodlist ();
|
|
||||||
*class->methods->tail = methods->head;
|
|
||||||
class->methods->tail = methods->tail;
|
|
||||||
}
|
|
||||||
free (methods);
|
free (methods);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -158,23 +151,13 @@ class_add_protocol_methods (class_t *class, expr_t *protocols)
|
||||||
|
|
||||||
if (!protocol_hash)
|
if (!protocol_hash)
|
||||||
protocol_hash = Hash_NewTable (1021, protocol_get_key, 0, 0);
|
protocol_hash = Hash_NewTable (1021, protocol_get_key, 0, 0);
|
||||||
if (class->categories) {
|
|
||||||
if (!class->categories->methods)
|
if (!class->methods)
|
||||||
class->categories->methods = new_methodlist ();
|
class->methods = new_methodlist ();
|
||||||
} else {
|
|
||||||
if (!class->methods)
|
|
||||||
class->methods = new_methodlist ();
|
|
||||||
}
|
|
||||||
|
|
||||||
for (e = protocols; e; e = e->next) {
|
for (e = protocols; e; e = e->next) {
|
||||||
methodlist_t *methods;
|
methodlist_t *methods = class->methods;
|
||||||
method_t **m;
|
method_t **m = methods->tail;
|
||||||
|
|
||||||
if (class->categories)
|
|
||||||
methods = class->categories->methods;
|
|
||||||
else
|
|
||||||
methods = class->methods;
|
|
||||||
m = methods->tail;
|
|
||||||
|
|
||||||
if (!(p = get_protocol (e->e.string_val, 0))) {
|
if (!(p = get_protocol (e->e.string_val, 0))) {
|
||||||
error (e, "undefined protocol `%s'", e->e.string_val);
|
error (e, "undefined protocol `%s'", e->e.string_val);
|
||||||
|
@ -189,35 +172,32 @@ class_add_protocol_methods (class_t *class, expr_t *protocols)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
class_add_protocol (class_t *class, protocol_t *protocol)
|
class_begin (class_type_t *class_type)
|
||||||
{
|
{
|
||||||
if (!class->protocols)
|
if (!class_type->is_class) {
|
||||||
class->protocols = new_protocollist ();
|
pr_category_t *pr_category;
|
||||||
add_protocol (class->protocols, protocol);
|
category_t *category = class_type->c.category;
|
||||||
}
|
class_t *class = category->class;
|
||||||
|
|
||||||
void
|
current_class = &category->class_type;
|
||||||
class_begin (class_t *class)
|
category->def = class_def (class_type, 0);
|
||||||
{
|
category->def->initialized = category->def->constant = 1;
|
||||||
current_class = class;
|
pr_category = &G_STRUCT (pr_category_t, category->def->ofs);
|
||||||
class->def = class_def (class, 0);
|
EMIT_STRING (pr_category->category_name, category->name);
|
||||||
if (class->name && class->categories) {
|
EMIT_STRING (pr_category->class_name, class->name);
|
||||||
pr_category_t *category;
|
EMIT_DEF (pr_category->protocols,
|
||||||
|
emit_protocol_list (category->protocols,
|
||||||
class->def->initialized = class->def->constant = 1;
|
|
||||||
category = &G_STRUCT (pr_category_t, class->def->ofs);
|
|
||||||
EMIT_STRING (category->category_name, class->categories->name);
|
|
||||||
EMIT_STRING (category->class_name, class->name);
|
|
||||||
EMIT_DEF (category->protocols,
|
|
||||||
emit_protocol_list (class->categories->protocols,
|
|
||||||
va ("%s_%s",
|
va ("%s_%s",
|
||||||
class->name,
|
class->name,
|
||||||
class->categories->name)));
|
category->name)));
|
||||||
} else if (class->name) {
|
} else {
|
||||||
def_t *meta_def;
|
def_t *meta_def;
|
||||||
pr_class_t *meta;
|
pr_class_t *meta;
|
||||||
pr_class_t *cls;
|
pr_class_t *cls;
|
||||||
|
class_t *class = class_type->c.class;
|
||||||
|
|
||||||
|
current_class = &class->class_type;
|
||||||
|
class->def = class_def (class_type, 0);
|
||||||
meta_def = get_def (type_Class.aux_type,
|
meta_def = get_def (type_Class.aux_type,
|
||||||
va ("_OBJ_METACLASS_%s", class->name),
|
va ("_OBJ_METACLASS_%s", class->name),
|
||||||
pr.scope, st_static);
|
pr.scope, st_static);
|
||||||
|
@ -237,8 +217,10 @@ class_begin (class_t *class)
|
||||||
cls = &G_STRUCT (pr_class_t, class->def->ofs);
|
cls = &G_STRUCT (pr_class_t, class->def->ofs);
|
||||||
EMIT_DEF (cls->class_pointer, meta_def);
|
EMIT_DEF (cls->class_pointer, meta_def);
|
||||||
if (class->super_class) {
|
if (class->super_class) {
|
||||||
|
class_type_t class_type = {1, {0}};
|
||||||
|
class_type.c.class = class->super_class;
|
||||||
EMIT_STRING (cls->super_class, class->super_class->name);
|
EMIT_STRING (cls->super_class, class->super_class->name);
|
||||||
class_def (class->super_class, 1);
|
class_def (&class_type, 1);
|
||||||
}
|
}
|
||||||
EMIT_STRING (cls->name, class->name);
|
EMIT_STRING (cls->name, class->name);
|
||||||
cls->info = _PR_CLS_CLASS;
|
cls->info = _PR_CLS_CLASS;
|
||||||
|
@ -247,13 +229,14 @@ class_begin (class_t *class)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
class_finish (class_t *class)
|
class_finish (class_type_t *class_type)
|
||||||
{
|
{
|
||||||
if (class->name && class->categories) {
|
if (!class_type->is_class) {
|
||||||
pr_category_t *pr_category;
|
pr_category_t *pr_category;
|
||||||
category_t *category = class->categories;
|
category_t *category = class_type->c.category;
|
||||||
|
class_t *class = category->class;
|
||||||
|
|
||||||
pr_category = &G_STRUCT (pr_category_t, class->def->ofs);
|
pr_category = &G_STRUCT (pr_category_t, category->def->ofs);
|
||||||
EMIT_DEF (pr_category->instance_methods,
|
EMIT_DEF (pr_category->instance_methods,
|
||||||
emit_methods (category->methods, va ("%s_%s",
|
emit_methods (category->methods, va ("%s_%s",
|
||||||
class->name,
|
class->name,
|
||||||
|
@ -262,9 +245,10 @@ class_finish (class_t *class)
|
||||||
emit_methods (category->methods, va ("%s_%s",
|
emit_methods (category->methods, va ("%s_%s",
|
||||||
class->name,
|
class->name,
|
||||||
category->name), 0));
|
category->name), 0));
|
||||||
} else if (class->name) {
|
} else {
|
||||||
pr_class_t *meta;
|
pr_class_t *meta;
|
||||||
pr_class_t *cls;
|
pr_class_t *cls;
|
||||||
|
class_t *class = class_type->c.class;
|
||||||
|
|
||||||
cls = &G_STRUCT (pr_class_t, class->def->ofs);
|
cls = &G_STRUCT (pr_class_t, class->def->ofs);
|
||||||
|
|
||||||
|
@ -280,6 +264,16 @@ class_finish (class_t *class)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
class_access (class_type_t *current_class, class_t *class)
|
||||||
|
{
|
||||||
|
if (!current_class)
|
||||||
|
return 1;
|
||||||
|
if (current_class->is_class)
|
||||||
|
return current_class->c.class != class;
|
||||||
|
return current_class->c.category->class != class;
|
||||||
|
}
|
||||||
|
|
||||||
struct_field_t *
|
struct_field_t *
|
||||||
class_find_ivar (class_t *class, int protected, const char *name)
|
class_find_ivar (class_t *class, int protected, const char *name)
|
||||||
{
|
{
|
||||||
|
@ -309,14 +303,19 @@ class_find_ivar (class_t *class, int protected, const char *name)
|
||||||
}
|
}
|
||||||
|
|
||||||
expr_t *
|
expr_t *
|
||||||
class_ivar_expr (class_t *class, const char *name)
|
class_ivar_expr (class_type_t *class_type, const char *name)
|
||||||
{
|
{
|
||||||
struct_field_t *ivar;
|
struct_field_t *ivar;
|
||||||
class_t *c;
|
class_t *c, *class;
|
||||||
|
|
||||||
if (!class)
|
if (!class_type)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
if (class_type->is_class) {
|
||||||
|
class = class_type->c.class;
|
||||||
|
} else {
|
||||||
|
class = class_type->c.category->class;
|
||||||
|
}
|
||||||
ivar = struct_find_field (class->ivars, name);
|
ivar = struct_find_field (class->ivars, name);
|
||||||
if (!ivar) {
|
if (!ivar) {
|
||||||
for (c = class->super_class; c; c = c->super_class) {
|
for (c = class->super_class; c; c = c->super_class) {
|
||||||
|
@ -336,16 +335,22 @@ class_ivar_expr (class_t *class, const char *name)
|
||||||
}
|
}
|
||||||
|
|
||||||
method_t *
|
method_t *
|
||||||
class_find_method (class_t *class, method_t *method)
|
class_find_method (class_type_t *class_type, method_t *method)
|
||||||
{
|
{
|
||||||
methodlist_t *methods;
|
methodlist_t *methods;
|
||||||
method_t *m;
|
method_t *m;
|
||||||
dstring_t *sel;
|
dstring_t *sel;
|
||||||
|
const char *class_name;
|
||||||
|
const char *category_name = 0;
|
||||||
|
|
||||||
if (class->categories)
|
if (!class_type->is_class) {
|
||||||
methods = class->categories->methods;
|
methods = class_type->c.category->methods;
|
||||||
else
|
category_name = class_type->c.category->name;
|
||||||
methods = class->methods;
|
class_name = class_type->c.category->class->name;
|
||||||
|
} else {
|
||||||
|
methods = class_type->c.class->methods;
|
||||||
|
class_name = class_type->c.class->name;
|
||||||
|
}
|
||||||
for (m = methods->head; m; m = m->next)
|
for (m = methods->head; m; m = m->next)
|
||||||
if (method_compare (method, m))
|
if (method_compare (method, m))
|
||||||
return m;
|
return m;
|
||||||
|
@ -353,8 +358,8 @@ class_find_method (class_t *class, method_t *method)
|
||||||
selector_name (sel, (keywordarg_t *)method->selector);
|
selector_name (sel, (keywordarg_t *)method->selector);
|
||||||
warning (0, "%s method %s not in %s%s",
|
warning (0, "%s method %s not in %s%s",
|
||||||
method->instance ? "instance" : "class",
|
method->instance ? "instance" : "class",
|
||||||
sel->str, class->name,
|
sel->str, class_name,
|
||||||
class->categories ? va (" (%s)", class->categories->name) : "");
|
category_name ? va (" (%s)", category_name) : "");
|
||||||
dstring_delete (sel);
|
dstring_delete (sel);
|
||||||
return method;
|
return method;
|
||||||
}
|
}
|
||||||
|
@ -423,10 +428,10 @@ class_check_ivars (class_t *class, struct type_s *ivars)
|
||||||
class->ivars = ivars;
|
class->ivars = ivars;
|
||||||
}
|
}
|
||||||
|
|
||||||
class_t *
|
category_t *
|
||||||
get_category (const char *class_name, const char *category_name, int create)
|
get_category (const char *class_name, const char *category_name, int create)
|
||||||
{
|
{
|
||||||
category_t *c;
|
category_t *category;
|
||||||
class_t *class;
|
class_t *class;
|
||||||
|
|
||||||
if (!category_hash) {
|
if (!category_hash) {
|
||||||
|
@ -437,41 +442,76 @@ get_category (const char *class_name, const char *category_name, int create)
|
||||||
class = get_class (class_name, 0);
|
class = get_class (class_name, 0);
|
||||||
if (!class) {
|
if (!class) {
|
||||||
error (0, "undefined class %s", class_name);
|
error (0, "undefined class %s", class_name);
|
||||||
return get_class (0, 1);
|
return 0;
|
||||||
}
|
}
|
||||||
if (class_name && category_name) {
|
if (class_name && category_name) {
|
||||||
class_t _c = {0, category_name, class};
|
category_t _c = {0, category_name, class};
|
||||||
|
|
||||||
c = Hash_FindElement (category_hash, &_c);
|
category = Hash_FindElement (category_hash, &_c);
|
||||||
if (c) {
|
if (category || !create)
|
||||||
category_t **cat = &class->categories;
|
return category;
|
||||||
category_t *t;
|
|
||||||
while (*cat != c)
|
|
||||||
cat = &(*cat)->next;
|
|
||||||
t = *cat;
|
|
||||||
*cat = (*cat)->next;
|
|
||||||
t->next = class->categories;
|
|
||||||
class->categories = t;
|
|
||||||
return class;
|
|
||||||
}
|
|
||||||
if (!create)
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
c = calloc (sizeof (category_t), 1);
|
category = calloc (sizeof (category_t), 1);
|
||||||
c->next = class->categories;
|
category->next = class->categories;
|
||||||
class->categories = c;
|
class->categories = category;
|
||||||
c->name = category_name;
|
category->name = category_name;
|
||||||
c->class = class;
|
category->class = class;
|
||||||
|
category->class_type.is_class = 0;
|
||||||
|
category->class_type.c.category = category;
|
||||||
if (class_name && category_name)
|
if (class_name && category_name)
|
||||||
Hash_AddElement (category_hash, c);
|
Hash_AddElement (category_hash, category);
|
||||||
return c->class;
|
return category;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
category_add_methods (category_t *category, methodlist_t *methods)
|
||||||
|
{
|
||||||
|
if (!methods)
|
||||||
|
return;
|
||||||
|
if (!category->methods)
|
||||||
|
category->methods = new_methodlist ();
|
||||||
|
*category->methods->tail = methods->head;
|
||||||
|
category->methods->tail = methods->tail;
|
||||||
|
free (methods);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
category_add_protocol_methods (category_t *category, expr_t *protocols)
|
||||||
|
{
|
||||||
|
expr_t *e;
|
||||||
|
protocol_t *p;
|
||||||
|
type_t *type;
|
||||||
|
|
||||||
|
if (!protocol_hash)
|
||||||
|
protocol_hash = Hash_NewTable (1021, protocol_get_key, 0, 0);
|
||||||
|
if (!category->methods)
|
||||||
|
category->methods = new_methodlist ();
|
||||||
|
type = category->class->type;
|
||||||
|
|
||||||
|
for (e = protocols; e; e = e->next) {
|
||||||
|
methodlist_t *methods = category->methods;
|
||||||
|
method_t **m = methods->tail;
|
||||||
|
|
||||||
|
if (!(p = get_protocol (e->e.string_val, 0))) {
|
||||||
|
error (e, "undefined protocol `%s'", e->e.string_val);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
copy_methods (methods, p->methods);
|
||||||
|
while (*m) {
|
||||||
|
(*m)->params->type = type;
|
||||||
|
m = &(*m)->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
def_t *
|
def_t *
|
||||||
class_pointer_def (class_t *class)
|
class_pointer_def (class_t *class)
|
||||||
{
|
{
|
||||||
def_t *def;
|
def_t *def;
|
||||||
|
class_type_t class_type = {1, {0}};
|
||||||
|
|
||||||
|
class_type.c.class = class;
|
||||||
|
|
||||||
def = get_def (class->type,
|
def = get_def (class->type,
|
||||||
va ("_OBJ_CLASS_POINTER_%s", class->name),
|
va ("_OBJ_CLASS_POINTER_%s", class->name),
|
||||||
|
@ -480,7 +520,7 @@ class_pointer_def (class_t *class)
|
||||||
return def;
|
return def;
|
||||||
def->initialized = def->constant = 1;
|
def->initialized = def->constant = 1;
|
||||||
if (!class->def)
|
if (!class->def)
|
||||||
class->def = class_def (class, 1);
|
class->def = class_def (&class_type, 1);
|
||||||
if (!class->def->external)
|
if (!class->def->external)
|
||||||
G_INT (def->ofs) = class->def->ofs;
|
G_INT (def->ofs) = class->def->ofs;
|
||||||
reloc_def_def (class->def, def->ofs);
|
reloc_def_def (class->def, def->ofs);
|
||||||
|
@ -490,9 +530,8 @@ class_pointer_def (class_t *class)
|
||||||
void
|
void
|
||||||
class_finish_module (void)
|
class_finish_module (void)
|
||||||
{
|
{
|
||||||
class_t **classes = 0;
|
class_t **classes = 0, **cl;
|
||||||
class_t **categories = 0;
|
category_t **categories = 0, **ca;
|
||||||
class_t **t;
|
|
||||||
int num_classes = 0;
|
int num_classes = 0;
|
||||||
int num_categories = 0;
|
int num_categories = 0;
|
||||||
int i;
|
int i;
|
||||||
|
@ -509,14 +548,14 @@ class_finish_module (void)
|
||||||
|
|
||||||
if (class_hash) {
|
if (class_hash) {
|
||||||
classes = (class_t **) Hash_GetList (class_hash);
|
classes = (class_t **) Hash_GetList (class_hash);
|
||||||
for (t = classes; *t; t++)
|
for (cl = classes; *cl; cl++)
|
||||||
if ((*t)->def && !(*t)->def->external)
|
if ((*cl)->def && !(*cl)->def->external)
|
||||||
num_classes++;
|
num_classes++;
|
||||||
}
|
}
|
||||||
if (category_hash) {
|
if (category_hash) {
|
||||||
categories = (class_t **) Hash_GetList (category_hash);
|
categories = (category_t **) Hash_GetList (category_hash);
|
||||||
for (t = categories; *t; t++)
|
for (ca = categories; *ca; ca++)
|
||||||
if ((*t)->def && !(*t)->def->external)
|
if ((*ca)->def && !(*ca)->def->external)
|
||||||
num_categories++;
|
num_categories++;
|
||||||
}
|
}
|
||||||
if (!num_classes && !num_categories)
|
if (!num_classes && !num_categories)
|
||||||
|
@ -534,18 +573,18 @@ class_finish_module (void)
|
||||||
symtab->cat_def_cnt = num_categories;
|
symtab->cat_def_cnt = num_categories;
|
||||||
def_ptr = symtab->defs;
|
def_ptr = symtab->defs;
|
||||||
if (classes) {
|
if (classes) {
|
||||||
for (t = classes; *t; t++) {
|
for (cl = classes; *cl; cl++) {
|
||||||
if ((*t)->def && !(*t)->def->external) {
|
if ((*cl)->def && !(*cl)->def->external) {
|
||||||
reloc_def_def ((*t)->def, POINTER_OFS (def_ptr));
|
reloc_def_def ((*cl)->def, POINTER_OFS (def_ptr));
|
||||||
*def_ptr++ = (*t)->def->ofs;
|
*def_ptr++ = (*cl)->def->ofs;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (categories) {
|
if (categories) {
|
||||||
for (t = categories; *t; t++) {
|
for (ca = categories; *ca; ca++) {
|
||||||
if ((*t)->def && !(*t)->def->external) {
|
if ((*ca)->def && !(*ca)->def->external) {
|
||||||
reloc_def_def ((*t)->def, POINTER_OFS (def_ptr));
|
reloc_def_def ((*ca)->def, POINTER_OFS (def_ptr));
|
||||||
*def_ptr++ = (*t)->def->ofs;
|
*def_ptr++ = (*ca)->def->ofs;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -639,15 +678,6 @@ new_protocollist (void)
|
||||||
return protocollist;
|
return protocollist;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
add_protocol (protocollist_t *protocollist, protocol_t *protocol)
|
|
||||||
{
|
|
||||||
protocollist->list = realloc (protocollist->list,
|
|
||||||
(protocollist->count + 1)
|
|
||||||
* sizeof (protocollist_t));
|
|
||||||
protocollist->list[protocollist->count++] = protocol;
|
|
||||||
}
|
|
||||||
|
|
||||||
def_t *
|
def_t *
|
||||||
emit_protocol (protocol_t *protocol)
|
emit_protocol (protocol_t *protocol)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1181,8 +1181,11 @@ field_expr (expr_t *e1, expr_t *e2)
|
||||||
case ev_object:
|
case ev_object:
|
||||||
case ev_class:
|
case ev_class:
|
||||||
if (e2->type == ex_name) {
|
if (e2->type == ex_name) {
|
||||||
|
int protected;
|
||||||
|
|
||||||
class = t1->aux_type->class;
|
class = t1->aux_type->class;
|
||||||
field = class_find_ivar (class, current_class != class,
|
protected = class_access (current_class, class);
|
||||||
|
field = class_find_ivar (class, protected,
|
||||||
e2->e.string_val);
|
e2->e.string_val);
|
||||||
if (!field)
|
if (!field)
|
||||||
return new_error_expr ();
|
return new_error_expr ();
|
||||||
|
|
|
@ -104,16 +104,25 @@ add_method (methodlist_t *methodlist, method_t *method)
|
||||||
}
|
}
|
||||||
|
|
||||||
def_t *
|
def_t *
|
||||||
method_def (class_t *class, method_t *method)
|
method_def (class_type_t *class_type, method_t *method)
|
||||||
{
|
{
|
||||||
dstring_t *str = dstring_newstr ();
|
dstring_t *str = dstring_newstr ();
|
||||||
def_t *def;
|
def_t *def;
|
||||||
char *s;
|
char *s;
|
||||||
|
const char *class_name;
|
||||||
|
const char *category_name = "";
|
||||||
|
|
||||||
|
if (class_type->is_class) {
|
||||||
|
class_name = class_type->c.class->name;
|
||||||
|
} else {
|
||||||
|
class_name = class_type->c.category->class->name;
|
||||||
|
category_name = class_type->c.category->name;
|
||||||
|
}
|
||||||
|
|
||||||
dsprintf (str, "_%c_%s_%s_%s",
|
dsprintf (str, "_%c_%s_%s_%s",
|
||||||
method->instance ? 'i' : 'c',
|
method->instance ? 'i' : 'c',
|
||||||
class->name,
|
class_name,
|
||||||
class->categories ? class->categories->name : "",
|
category_name,
|
||||||
method->name);
|
method->name);
|
||||||
str->str[--str->size - 1] = 0;
|
str->str[--str->size - 1] = 0;
|
||||||
for (s = str->str; *s; s++)
|
for (s = str->str; *s; s++)
|
||||||
|
|
|
@ -107,6 +107,8 @@ expr_t *argv_expr (void);
|
||||||
struct param_s *param;
|
struct param_s *param;
|
||||||
struct method_s *method;
|
struct method_s *method;
|
||||||
struct class_s *class;
|
struct class_s *class;
|
||||||
|
struct category_s *category;
|
||||||
|
struct class_type_s *class_type;
|
||||||
struct protocol_s *protocol;
|
struct protocol_s *protocol;
|
||||||
struct keywordarg_s *keywordarg;
|
struct keywordarg_s *keywordarg;
|
||||||
struct methodlist_s *methodlist;
|
struct methodlist_s *methodlist;
|
||||||
|
@ -159,8 +161,9 @@ expr_t *argv_expr (void);
|
||||||
%type <expr> protocolrefs
|
%type <expr> protocolrefs
|
||||||
%type <keywordarg> messageargs keywordarg keywordarglist selectorarg
|
%type <keywordarg> messageargs keywordarg keywordarglist selectorarg
|
||||||
%type <keywordarg> keywordnamelist keywordname
|
%type <keywordarg> keywordnamelist keywordname
|
||||||
%type <class> class_name new_class_name class_with_super new_class_with_super
|
%type <class> class_name new_class_name class_with_super new_class_with_super
|
||||||
%type <class> category_name new_category_name
|
%type <class> classdef
|
||||||
|
%type <category> category_name new_category_name
|
||||||
%type <protocol> protocol_name
|
%type <protocol> protocol_name
|
||||||
%type <methodlist> methodprotolist methodprotolist2
|
%type <methodlist> methodprotolist methodprotolist2
|
||||||
%type <type> ivar_decl_list
|
%type <type> ivar_decl_list
|
||||||
|
@ -172,7 +175,7 @@ expr_t *argv_expr (void);
|
||||||
function_t *current_func;
|
function_t *current_func;
|
||||||
param_t *current_params;
|
param_t *current_params;
|
||||||
expr_t *current_init;
|
expr_t *current_init;
|
||||||
class_t *current_class;
|
class_type_t *current_class;
|
||||||
expr_t *local_expr;
|
expr_t *local_expr;
|
||||||
expr_t *break_label;
|
expr_t *break_label;
|
||||||
expr_t *continue_label;
|
expr_t *continue_label;
|
||||||
|
@ -938,7 +941,6 @@ new_class_name
|
||||||
error (0, "redefinition of `%s'", $1);
|
error (0, "redefinition of `%s'", $1);
|
||||||
$$ = get_class (0, 1);
|
$$ = get_class (0, 1);
|
||||||
}
|
}
|
||||||
current_class = $$;
|
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
|
@ -956,7 +958,6 @@ new_class_with_super
|
||||||
{
|
{
|
||||||
$1->super_class = $3;
|
$1->super_class = $3;
|
||||||
$$ = $1;
|
$$ = $1;
|
||||||
current_class = $$;
|
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
|
@ -979,7 +980,6 @@ new_category_name
|
||||||
error (0, "redefinition of category `%s (%s)'", $1, $3);
|
error (0, "redefinition of category `%s (%s)'", $1, $3);
|
||||||
$$ = get_category (0, 0, 1);
|
$$ = get_category (0, 0, 1);
|
||||||
}
|
}
|
||||||
current_class = $$;
|
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
|
@ -999,38 +999,42 @@ protocol_name
|
||||||
classdef
|
classdef
|
||||||
: INTERFACE new_class_name
|
: INTERFACE new_class_name
|
||||||
protocolrefs { class_add_protocol_methods ($2, $3);}
|
protocolrefs { class_add_protocol_methods ($2, $3);}
|
||||||
'{' ivar_decl_list '}' { class_add_ivars ($2, $6); }
|
'{' { $$ = $2; }
|
||||||
methodprotolist { class_add_methods ($2, $9); }
|
ivar_decl_list '}' { class_add_ivars ($2, $7); $$ = $2; }
|
||||||
|
methodprotolist { class_add_methods ($2, $10); }
|
||||||
END { current_class = 0; }
|
END { current_class = 0; }
|
||||||
| INTERFACE new_class_name
|
| INTERFACE new_class_name
|
||||||
protocolrefs { class_add_protocol_methods ($2, $3);}
|
protocolrefs { class_add_protocol_methods ($2, $3); $$ = $2; }
|
||||||
methodprotolist { class_add_methods ($2, $5); }
|
methodprotolist { class_add_methods ($2, $5); }
|
||||||
END { current_class = 0; }
|
END { current_class = 0; }
|
||||||
| INTERFACE new_class_with_super
|
| INTERFACE new_class_with_super
|
||||||
protocolrefs { class_add_protocol_methods ($2, $3);}
|
protocolrefs { class_add_protocol_methods ($2, $3);}
|
||||||
'{' ivar_decl_list '}' { class_add_ivars ($2, $6); }
|
'{' { $$ = $2; }
|
||||||
methodprotolist { class_add_methods ($2, $9); }
|
ivar_decl_list '}' { class_add_ivars ($2, $7); $$ = $2; }
|
||||||
|
methodprotolist { class_add_methods ($2, $10); }
|
||||||
END { current_class = 0; }
|
END { current_class = 0; }
|
||||||
| INTERFACE new_class_with_super
|
| INTERFACE new_class_with_super
|
||||||
protocolrefs { class_add_protocol_methods ($2, $3);}
|
protocolrefs { class_add_protocol_methods ($2, $3); $$ = $2; }
|
||||||
methodprotolist { class_add_methods ($2, $5); }
|
methodprotolist { class_add_methods ($2, $5); }
|
||||||
END { current_class = 0; }
|
END { current_class = 0; }
|
||||||
| INTERFACE new_category_name
|
| INTERFACE new_category_name
|
||||||
protocolrefs { class_add_protocol_methods ($2, $3);}
|
protocolrefs { category_add_protocol_methods ($2, $3); $$ = $2->class;}
|
||||||
methodprotolist { class_add_methods ($2, $5); }
|
methodprotolist { category_add_methods ($2, $5); }
|
||||||
END { current_class = 0; }
|
END { current_class = 0; }
|
||||||
| IMPLEMENTATION class_name { class_begin ($2); }
|
| IMPLEMENTATION class_name { class_begin (&$2->class_type); }
|
||||||
'{' ivar_decl_list '}' { class_check_ivars ($2, $5); }
|
'{' { $$ = $2; }
|
||||||
| IMPLEMENTATION class_name { class_begin ($2); }
|
ivar_decl_list '}' { class_check_ivars ($2, $6); }
|
||||||
| IMPLEMENTATION class_with_super { class_begin ($2); }
|
| IMPLEMENTATION class_name { class_begin (&$2->class_type); }
|
||||||
'{' ivar_decl_list '}' { class_check_ivars ($2, $5); }
|
| IMPLEMENTATION class_with_super { class_begin (&$2->class_type); }
|
||||||
| IMPLEMENTATION class_with_super { class_begin ($2); }
|
'{' { $$ = $2; }
|
||||||
| IMPLEMENTATION category_name { class_begin ($2); }
|
ivar_decl_list '}' { class_check_ivars ($2, $6); }
|
||||||
|
| IMPLEMENTATION class_with_super { class_begin (&$2->class_type); }
|
||||||
|
| IMPLEMENTATION category_name { class_begin (&$2->class_type); }
|
||||||
;
|
;
|
||||||
|
|
||||||
protocoldef
|
protocoldef
|
||||||
: PROTOCOL protocol_name
|
: PROTOCOL protocol_name
|
||||||
protocolrefs { protocol_add_protocol_methods ($2, $3); }
|
protocolrefs { protocol_add_protocol_methods ($2, $3); $<class>$ = 0; }
|
||||||
methodprotolist { protocol_add_methods ($2, $5); }
|
methodprotolist { protocol_add_methods ($2, $5); }
|
||||||
END
|
END
|
||||||
;
|
;
|
||||||
|
@ -1045,9 +1049,9 @@ ivar_decl_list
|
||||||
{
|
{
|
||||||
current_visibility = vis_protected;
|
current_visibility = vis_protected;
|
||||||
current_ivars = new_struct (0);
|
current_ivars = new_struct (0);
|
||||||
if (current_class->super_class)
|
if ($<class>0->super_class)
|
||||||
new_struct_field (current_ivars,
|
new_struct_field (current_ivars,
|
||||||
current_class->super_class->ivars, 0,
|
$<class>0->super_class->ivars, 0,
|
||||||
vis_private);
|
vis_private);
|
||||||
}
|
}
|
||||||
ivar_decl_list_2
|
ivar_decl_list_2
|
||||||
|
@ -1158,10 +1162,10 @@ methodprotolist
|
||||||
;
|
;
|
||||||
|
|
||||||
methodprotolist2
|
methodprotolist2
|
||||||
: methodproto
|
: { } methodproto
|
||||||
{
|
{
|
||||||
$$ = new_methodlist ();
|
$$ = new_methodlist ();
|
||||||
add_method ($$, $1);
|
add_method ($$, $2);
|
||||||
}
|
}
|
||||||
| methodprotolist2 methodproto
|
| methodprotolist2 methodproto
|
||||||
{
|
{
|
||||||
|
@ -1180,8 +1184,8 @@ methodproto
|
||||||
| '-' methoddecl ';'
|
| '-' methoddecl ';'
|
||||||
{
|
{
|
||||||
$2->instance = 1;
|
$2->instance = 1;
|
||||||
if (current_class)
|
if ($<class>-1)
|
||||||
$2->params->type = current_class->type;
|
$2->params->type = $<class>-1->type;
|
||||||
$$ = $2;
|
$$ = $2;
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
|
@ -235,8 +235,6 @@ array_type (type_t *aux, int size)
|
||||||
void
|
void
|
||||||
print_type (type_t *type)
|
print_type (type_t *type)
|
||||||
{
|
{
|
||||||
class_t *class;
|
|
||||||
|
|
||||||
if (!type) {
|
if (!type) {
|
||||||
printf (" (null)");
|
printf (" (null)");
|
||||||
return;
|
return;
|
||||||
|
@ -275,11 +273,7 @@ print_type (type_t *type)
|
||||||
break;
|
break;
|
||||||
case ev_object:
|
case ev_object:
|
||||||
case ev_class:
|
case ev_class:
|
||||||
class = type->class;
|
printf (" %s", type->class->name);
|
||||||
printf (" %s%s",
|
|
||||||
class->name,
|
|
||||||
class->categories ? va (" (%s)", class->categories->name)
|
|
||||||
: "");
|
|
||||||
break;
|
break;
|
||||||
case ev_struct:
|
case ev_struct:
|
||||||
printf (" %s %s", pr_type_name[type->type], type->name);
|
printf (" %s %s", pr_type_name[type->type], type->name);
|
||||||
|
|
Loading…
Reference in a new issue