getting closer to working categories

This commit is contained in:
Bill Currie 2002-11-14 18:17:43 +00:00
parent e544c1247f
commit 3c215ce13f
7 changed files with 228 additions and 172 deletions

View file

@ -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 {

View file

@ -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);

View file

@ -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)
{ {

View file

@ -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 ();

View file

@ -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++)

View file

@ -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;
} }
; ;

View file

@ -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);