mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-03-19 17:01:46 +00:00
get ivars working better (need to get rid of self.) and [super ...] now
works.
This commit is contained in:
parent
9d59915fdc
commit
6965642030
6 changed files with 94 additions and 20 deletions
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
;
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in a new issue