get ivars working better (need to get rid of self.) and [super ...] now

works.
This commit is contained in:
Bill Currie 2002-05-17 06:20:27 +00:00
parent 9d59915fdc
commit 6965642030
6 changed files with 94 additions and 20 deletions

View file

@ -45,6 +45,8 @@ typedef struct class_s {
} class_t;
extern class_t class_id;
extern class_t class_Class;
extern class_t class_Protocol;
struct expr_s;
struct method_s;
@ -55,9 +57,12 @@ class_t *get_class (const char *name, int create);
void class_add_methods (class_t *class, struct methodlist_s *methods);
void class_add_protocol_methods (class_t *class, expr_t *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_check_ivars (class_t *class, struct type_s *ivars);
void class_begin (class_t *class);
void class_finish (class_t *class);
struct struct_field_s *class_find_ivar (class_t *class, int protected,
const char *name);
struct method_s *class_find_method (class_t *class, struct method_s *method);
struct method_s *class_message_response (class_t *class, struct expr_s *sel);
struct def_s *class_def (class_t *class);

View file

@ -48,6 +48,8 @@ static hashtab_t *category_hash;
static hashtab_t *protocol_hash;
class_t class_id = {1, "id", 0, 0, 0, 0, 0, 0, &type_id};
class_t class_Class = {1, "Class", 0, 0, 0, 0, 0, 0, &type_Class};
class_t class_Protocol = {1, "Protocl", 0, 0, 0, 0, 0, 0, &type_Protocol};
static const char *
class_get_key (void *class, void *unused)
@ -163,7 +165,8 @@ class_begin (class_t *class)
class->def->initialized = class->def->constant = 1;
cls = &G_STRUCT (pr_class_t, class->def->ofs);
cls->class_pointer = meta_def->ofs;
if (class->super_class)
if (class->super_class
&& class->super_class->def) //FIXME implementation only
cls->super_class = class->super_class->def->ofs;
cls->name = meta->name;
cls->protocols = meta->protocols;
@ -193,6 +196,31 @@ class_finish (class_t *class)
}
}
struct_field_t *
class_find_ivar (class_t *class, int protected, const char *name)
{
struct_field_t *ivar;
class_t *c;
ivar = struct_find_field (class->ivars, name);
if (ivar)
return ivar;
for (c = class->super_class; c; c = c->super_class) {
ivar = struct_find_field (c->ivars, name);
if (ivar) {
if (ivar->visibility == vis_private
|| (protected && ivar->visibility == vis_protected)) {
error (0, "%s.%s is not accessable here",
class->class_name, name);
return 0;
}
return ivar;
}
}
error (0, "%s.%s does not exist", class->class_name, name);
return 0;
}
method_t *
class_find_method (class_t *class, method_t *method)
{
@ -253,6 +281,12 @@ category_compare (void *_c1, void *_c2, void *unused)
&& strcmp (c1->category_name, c2->category_name) == 0;
}
void
class_add_ivars (class_t *class, struct type_s *ivars)
{
class->ivars = ivars;
}
void
class_check_ivars (class_t *class, struct type_s *ivars)
{
@ -295,8 +329,10 @@ class_def (class_t *class)
def = PR_GetDef (class->type,
va ("_OBJ_CLASS_POINTER_%s", class->class_name),
0, &numpr_globals);
def->initialized = def->constant = 1;
G_INT (def->ofs) = class->def->ofs;
if (class->def) { //FIXME need externals?
def->initialized = def->constant = 1;
G_INT (def->ofs) = class->def->ofs;
}
return def;
}

View file

@ -969,16 +969,33 @@ field_expr (expr_t *e1, expr_t *e2)
e = unary_expr ('.', address_expr (e1, e2, field->type));
return e;
case ev_pointer:
if (t1->aux_type->type == ev_struct) {
if (e2->type == ex_name) {
field = struct_find_field (t1->aux_type, e2->e.string_val);
if (!field)
return error (e2, "structure has no field %s",
e2->e.string_val);
e2->type = ex_short;
e2->e.short_val = field->offset;
t1 = pointer_type (field->type);
}
switch (t1->aux_type->type) {
case ev_struct:
if (e2->type == ex_name) {
field = struct_find_field (t1->aux_type,
e2->e.string_val);
if (!field)
return error (e2, "structure has no field %s",
e2->e.string_val);
e2->type = ex_short;
e2->e.short_val = field->offset;
t1 = pointer_type (field->type);
}
break;
case ev_class:
if (e2->type == ex_name) {
field = class_find_ivar (t1->aux_type->class,
0,
e2->e.string_val);
if (!field)
return new_error_expr ();
e2->type = ex_short;
e2->e.short_val = field->offset;
t1 = pointer_type (field->type);
}
break;
default:
break;
}
if (e1->type == ex_pointer) {
if (e2->type == ex_short) {
@ -1807,16 +1824,17 @@ assign_expr (expr_t *e1, expr_t *e2)
type_t *t1, *t2, *type;
expr_t *e;
convert_name (e1);
convert_name (e2);
if (e1->type == ex_error)
return e1;
if (e2->type == ex_error)
return e2;
convert_name (e1);
if (e1->type == ex_def)
PR_DefInitialized (e1->e.def);
//XXX func = func ???
convert_name (e2);
check_initialized (e2);
t1 = get_type (e1);
t2 = get_type (e2);
@ -1992,6 +2010,7 @@ message_expr (expr_t *receiver, keywordarg_t *message)
if (receiver->type == ex_name
&& strcmp (receiver->e.string_val, "super") == 0) {
super = 1;
receiver->e.string_val = "self";
}
rec_type = get_type (receiver);
if (rec_type->type != ev_pointer || rec_type->aux_type->type != ev_class)

View file

@ -158,8 +158,7 @@ new_keywordarg (const char *selector, struct expr_s *expr)
static void
make_message_def (const char *name, def_t **def, function_t **func)
{
*def = PR_GetDef (&type_IMP, "obj_msgSend",
0, &numpr_globals);
*def = PR_GetDef (&type_IMP, name, 0, &numpr_globals);
*func = new_function ();
(*func)->builtin = 0;
(*func)->def = *def;

View file

@ -938,6 +938,7 @@ new_class_with_super
{
$1->super_class = $3;
$$ = $1;
current_class = $$;
}
;
@ -980,7 +981,7 @@ protocol_name
classdef
: INTERFACE new_class_name
protocolrefs { class_add_protocol_methods ($2, $3);}
'{' ivar_decl_list '}' { $2->ivars = $6; }
'{' ivar_decl_list '}' { class_add_ivars ($2, $6); }
methodprotolist { class_add_methods ($2, $9); }
END { current_class = 0; }
| INTERFACE new_class_name
@ -989,7 +990,7 @@ classdef
END { current_class = 0; }
| INTERFACE new_class_with_super
protocolrefs { class_add_protocol_methods ($2, $3);}
'{' ivar_decl_list '}' { $2->ivars = $6; }
'{' ivar_decl_list '}' { class_add_ivars ($2, $6); }
methodprotolist { class_add_methods ($2, $9); }
END { current_class = 0; }
| INTERFACE new_class_with_super
@ -1022,7 +1023,15 @@ protocolrefs
;
ivar_decl_list
: { current_ivars = new_struct (0); } ivar_decl_list_2
: /* */
{
current_ivars = new_struct (0);
if (current_class->super_class)
new_struct_field (current_ivars,
current_class->super_class->ivars, 0,
vis_private);
}
ivar_decl_list_2
{
$$ = current_ivars;
current_ivars = 0;
@ -1129,11 +1138,13 @@ methodproto
: '+' methoddecl ';'
{
$2->instance = 0;
$2->params->type = &type_Class;
$$ = $2;
}
| '-' methoddecl ';'
{
$2->instance = 1;
$2->params->type = current_class->type;
$$ = $2;
}
;

View file

@ -428,6 +428,8 @@ init_types (void)
type = type_Class.aux_type = new_struct ("Class");
type->type = ev_class;
type->class = &class_Class;
class_Class.ivars = type_Class.aux_type;
new_struct_field (type, &type_Class, "class_pointer", vis_public);
new_struct_field (type, &type_Class, "super_class", vis_public);
new_struct_field (type, &type_string, "name", vis_public);
@ -445,6 +447,8 @@ init_types (void)
type = type_Protocol.aux_type = new_struct ("Protocol");
type->type = ev_class;
type->class = &class_Protocol;
class_Protocol.ivars = type_Protocol.aux_type;
new_struct_field (type, &type_Class, "class_pointer", vis_public);
new_struct_field (type, &type_string, "protocol_name", vis_public);
new_struct_field (type, &type_pointer, "protocol_list", vis_public);