revamp the struct system so "struct foo;" does the right thing (ala C)

This commit is contained in:
Bill Currie 2003-07-30 04:11:45 +00:00
parent da86367824
commit 6ecb707257
20 changed files with 367 additions and 259 deletions

View file

@ -41,11 +41,12 @@ Array movement_bindings;
Array misc_bindings;
Array weapon_bindings;
struct binding_t = {
struct binding_s = {
string text;
string command;
string keys;
};
typedef struct binding_s binding_t;
binding_t [16] movement_binding_list = {
{"Jump/Swin up", "+jump"},

View file

@ -4,7 +4,7 @@
#include "Object.h"
struct _inputline_t = {}; // opaque type :)
typedef _inputline_t [] inputline_t;
typedef struct _inputline_t [] inputline_t;
@extern inputline_t (integer lines, integer size, integer prompt) InputLine_Create;
@extern void (inputline_t il, void [] data) InputLine_SetUserData;
@ -26,7 +26,7 @@ struct il_data_t = {
@interface InputLine: Object
{
il_data_t control;
struct il_data_t control;
inputline_t il;
}

View file

@ -3,17 +3,11 @@
#include "Object.h"
struct list_bucket_t = {
list_bucket_t [] next;
list_bucket_t [][] prev;
id obj;
};
@interface List: Object
{
integer count;
list_bucket_t [] head;
list_bucket_t [][] tail;
struct list_bucket_s [] head;
struct list_bucket_s [][] tail;
}
- (id) init;
- (void) free;

View file

@ -7,7 +7,7 @@ struct _qpic_t = {
integer width;
integer height;
};
typedef _qpic_t [] qpic_t;
typedef struct _qpic_t [] qpic_t;
@extern qpic_t (string name, integer alpha) Draw_CachePic;
@ -25,7 +25,7 @@ typedef _qpic_t [] qpic_t;
@interface QPic : Object
{
string name;
_qpic_t size;
struct _qpic_t size;
BOOL centered;
}
-initName:(string)n;

View file

@ -2,7 +2,7 @@
#define __ruamoko_hash_h
struct _hashtab_t = {};
typedef _hashtab_t [] hashtab_t;
typedef struct _hashtab_t [] hashtab_t;
@extern hashtab_t () Hash_NewTable;
@extern void () Hash_SetHashCompare;

View file

@ -1,7 +1,8 @@
#ifndef __ruamoko_plist_h
#define __ruamoko_plist_h
struct plitem_t = {integer [2] dummy;};
struct plitem_s = {integer [2] dummy;};
typedef struct plitem_s plitem_t;
@extern plitem_t (string str) PL_GetPropertyList;
@extern plitem_t (plitem_t item, string key) PL_ObjectForKey;

View file

@ -2,7 +2,7 @@
#define __ruamoko_qfile_h
struct _qfile_t = {};
typedef _qfile_t [] QFile;
typedef struct _qfile_t [] QFile;
@extern integer (string old, string new) Qrename;
@extern integer (string path) Qremove;

View file

@ -1,5 +1,12 @@
#include "List.h"
struct list_bucket_s = {
struct list_bucket_s [] next;
struct list_bucket_s [][] prev;
id obj;
};
typedef struct list_bucket_s list_bucket_t;
@implementation List
- (id) init

View file

@ -45,7 +45,7 @@ typedef struct class_s {
const char *name;
struct class_s *super_class;
struct category_s *categories;
struct type_s *ivars;
struct struct_s *ivars;
struct methodlist_s *methods;
struct protocollist_s *protocols;
struct def_s *def;
@ -73,15 +73,15 @@ extern class_type_t *current_class;
struct expr_s;
struct method_s;
struct protocol_s;
struct type_s;
struct def_s *class_def (class_type_t *class_type, int external);
void class_init (void);
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, struct expr_s *protocols);
void class_add_ivars (class_t *class, struct type_s *ivars);
void class_check_ivars (class_t *class, struct type_s *ivars);
struct struct_s *class_new_ivars (class_t *class);
void class_add_ivars (class_t *class, struct struct_s *ivars);
void class_check_ivars (class_t *class, struct struct_s *ivars);
void class_begin (class_type_t *class_type);
void class_finish (class_type_t *class_type);
int class_access (class_type_t *current_class, class_t *class);

View file

@ -36,20 +36,31 @@ typedef enum {
vis_private,
vis_protected,
vis_public,
} visibility_t;
} visibility_type;
typedef enum {
str_none,
str_struct,
str_union,
} struct_type;
typedef struct struct_field_s {
struct struct_field_s *next;
const char *name;
struct type_s *type;
int offset;
visibility_t visibility;
visibility_type visibility;
} struct_field_t;
typedef struct struct_s {
const char *name;
struct type_s *type;
int is_union;
struct_type stype;
struct hashtab_s *struct_fields;
struct_field_t *struct_head;
struct_field_t **struct_tail;
int size;
void *return_addr; // who allocated this
} struct_t;
typedef struct enum_s {
@ -57,18 +68,17 @@ typedef struct enum_s {
int value;
} enum_t;
struct_field_t *new_struct_field (struct type_s *strct, struct type_s *type,
const char *name, visibility_t visibility);
struct_field_t *struct_find_field (struct type_s *strct, const char *name);
int struct_compare_fields (struct type_s *s1, struct type_s *s2);
struct_field_t *new_struct_field (struct_t *strct, struct type_s *type,
const char *name,
visibility_type visibility);
struct_field_t *struct_find_field (struct_t *strct, const char *name);
int struct_compare_fields (struct_t *s1, struct_t *s2);
struct type_s *init_struct (struct_t *strct, struct type_s *type,
const char *name);
struct type_s *new_struct (const char *name);
struct type_s *new_union (const char *name);
struct type_s *find_struct (const char *name);
void copy_struct_fields (struct type_s *dst, struct type_s *src);
struct_type stype, const char *name);
struct_t *get_struct (const char *name, int create);
void copy_struct_fields (struct_t *dst, struct_t *src);
struct def_s *emit_struct (struct type_s *strct, const char *name);
struct def_s *emit_struct (struct_t *strct, const char *name);
void process_enum (struct expr_s *enm);
struct expr_s *get_enum (const char *name);
@ -76,4 +86,9 @@ struct expr_s *get_enum (const char *name);
void clear_structs (void);
void clear_enums (void);
struct_t *new_struct (const char *name);
struct_t *new_union (const char *name);
struct_t *decl_struct (const char *name);
struct_t *decl_union (const char *name);
#endif//__struct_h

View file

@ -42,10 +42,10 @@ typedef struct type_s {
struct type_s *aux_type; // return type or field type
int num_parms; // -1 = variable args
struct type_s *parm_types[MAX_PARMS]; // only [num_parms] allocated
struct hashtab_s *struct_fields;
struct struct_field_s *struct_head;
struct struct_field_s **struct_tail;
struct class_s *class; // for ev_class
union {
struct class_s *class; // for ev_class
struct struct_s *strct; // for ev_struct
} s;
} type_t;
extern type_t type_void;
@ -78,7 +78,7 @@ extern type_t type_va_list;
extern type_t type_param;
extern type_t type_zero;
extern type_t *vector_struct;
extern struct struct_s *vector_struct;
struct dstring_s;

View file

@ -122,7 +122,7 @@ get_class (const char *name, int create)
c = calloc (sizeof (class_t), 1);
c->name = name;
new = *type_Class.aux_type;
new.class = c;
new.s.class = c;
c->type = pointer_type (find_type (&new));
c->class_type.is_class = 1;
c->class_type.c.class = c;
@ -212,9 +212,10 @@ class_begin (class_type_t *class_type)
EMIT_STRING (meta->name, class->name);
meta->info = _PR_CLS_META;
meta->instance_size = type_size (type_Class.aux_type);
EMIT_DEF (meta->ivars, emit_struct (type_Class.aux_type, "Class"));
EMIT_DEF (meta->protocols, emit_protocol_list (class->protocols,
class->name));
EMIT_DEF (meta->ivars,
emit_struct (type_Class.aux_type->s.class->ivars, "Class"));
EMIT_DEF (meta->protocols,
emit_protocol_list (class->protocols, class->name));
class->def->initialized = class->def->constant = 1;
class->def->nosave = 1;
@ -311,7 +312,7 @@ class_finish (class_type_t *class_type)
EMIT_DEF (meta->methods, emit_methods (class->methods,
class->name, 0));
cls->instance_size = type_size (class->ivars);
cls->instance_size = class->ivars? type_size (class->ivars->type) : 0;
EMIT_DEF (cls->ivars, emit_struct (class->ivars, class->name));
EMIT_DEF (cls->methods, emit_methods (class->methods,
class->name, 1));
@ -481,14 +482,24 @@ category_compare (void *_c1, void *_c2, void *unused)
&& strcmp (c1->class->name, c2->class->name) == 0;
}
struct_t *
class_new_ivars (class_t *class)
{
struct_t *ivars = new_struct (0);
if (class->super_class)
new_struct_field (ivars, class->super_class->ivars->type, 0,
vis_private);
return ivars;
}
void
class_add_ivars (class_t *class, struct type_s *ivars)
class_add_ivars (class_t *class, struct_t *ivars)
{
class->ivars = ivars;
}
void
class_check_ivars (class_t *class, struct type_s *ivars)
class_check_ivars (class_t *class, struct_t *ivars)
{
if (!struct_compare_fields (class->ivars, ivars))
warning (0, "instance variable missmatch for %s", class->name);
@ -603,7 +614,7 @@ class_finish_module (void)
int num_classes = 0;
int num_categories = 0;
int i;
type_t *symtab_type;
struct_t *symtab_type;
def_t *symtab_def;
pr_symtab_t *symtab;
pointer_t *def_ptr;
@ -628,13 +639,15 @@ class_finish_module (void)
}
if (!num_classes && !num_categories)
return;
symtab_type = new_struct (0);
symtab_type = get_struct (0, 1);
init_struct (symtab_type, new_type (), str_struct, 0);
new_struct_field (symtab_type, &type_integer, "sel_ref_cnt", vis_public);
new_struct_field (symtab_type, &type_integer, "cls_def_cnt", vis_public);
new_struct_field (symtab_type, &type_integer, "cat_def_cnt", vis_public);
for (i = 0; i < num_classes + num_categories; i++)
new_struct_field (symtab_type, &type_pointer, 0, vis_public);
symtab_def = get_def (symtab_type, "_OBJ_SYMTAB", pr.scope, st_static);
symtab_def = get_def (symtab_type->type, "_OBJ_SYMTAB", pr.scope,
st_static);
symtab_def->initialized = symtab_def->constant = 1;
symtab_def->nosave = 1;
symtab = &G_STRUCT (pr_symtab_t, symtab_def->ofs);
@ -779,13 +792,14 @@ def_t *
emit_protocol_list (protocollist_t *protocols, const char *name)
{
def_t *proto_list_def;
type_t *protocol_list;
struct_t *protocol_list;
pr_protocol_list_t *proto_list;
int i;
if (!protocols)
return 0;
protocol_list = new_struct (0);
protocol_list = get_struct (0, 1);
init_struct (protocol_list, new_type (), str_struct, 0);
new_struct_field (protocol_list, &type_pointer, "next", vis_public);
new_struct_field (protocol_list, &type_integer, "count", vis_public);
for (i = 0; i < protocols->count; i++)

View file

@ -94,7 +94,7 @@ check_for_name (type_t *type, const char *name, scope_t *scope,
}
if (!name)
return 0;
if (scope->type == sc_global && (find_struct (name) || get_enum (name))) {
if (scope->type == sc_global && get_enum (name)) {
error (0, "%s redeclared", name);
return 0;
}
@ -102,8 +102,11 @@ check_for_name (type_t *type, const char *name, scope_t *scope,
def = (def_t *) Hash_Find (defs_by_name, name);
if (def) {
if (storage != st_none && scope == def->scope)
if (type && def->type != type)
if (type && def->type != type) {
print_type (type);
print_type (def->type);
error (0, "Type mismatch on redeclaration of %s", name);
}
if (storage == st_none || def->scope == scope)
return def;
}

View file

@ -342,13 +342,13 @@ emit_move_expr (expr_t *e)
if (dst_type->type == ev_struct && src_type->type == ev_struct) {
size_expr = new_short_expr (type_size (dst->type));
} else if (dst_type->type == ev_struct) {
if (dst->alias)
dst = dst->alias;
//if (dst->alias)
// dst = dst->alias;
dst = emit_sub_expr (address_expr (new_def_expr (dst), 0, 0), 0);
size_expr = new_integer_expr (type_size (dst_type));
} else if (src_type->type == ev_struct) {
if (src->alias)
src = src->alias;
//if (src->alias)
// src = src->alias;
src = emit_sub_expr (address_expr (new_def_expr (src), 0, 0), 0);
size_expr = new_integer_expr (type_size (dst_type->aux_type));
} else {
@ -401,6 +401,14 @@ emit_deref_expr (expr_t *e, def_t *dest)
}
return d;
}
if (e->type == ex_uexpr && e->e.expr.op == '&'
&& e->e.expr.e1->type == ex_def) {
d = new_def (e->e.expr.type->aux_type, 0, current_scope);
d->alias = e->e.expr.e1->e.def;
d->local = d->alias->local;
d->ofs = d->alias->ofs;
return d;
}
if (!dest) {
dest = get_tempdef (type, current_scope);
dest->users += 2;

View file

@ -1119,6 +1119,7 @@ field_expr (expr_t *e1, expr_t *e2)
int i;
struct_field_t *field;
class_t *class;
struct_t *strct;
if (e1->type == ex_error)
return e1;
@ -1129,7 +1130,11 @@ field_expr (expr_t *e1, expr_t *e2)
check_initialized (e1);
if (e2->type != ex_name)
return error (e2, "structure field name expected");
field = struct_find_field (t1, e2->e.string_val);
if (t1->type == ev_struct)
strct = t1->s.strct;
else
strct = t1->s.class->ivars;
field = struct_find_field (strct, e2->e.string_val);
if (!field)
return error (e2, "structure has no field %s",
e2->e.string_val);
@ -1142,7 +1147,7 @@ field_expr (expr_t *e1, expr_t *e2)
switch (t1->aux_type->type) {
case ev_struct:
if (e2->type == ex_name) {
field = struct_find_field (t1->aux_type,
field = struct_find_field (t1->aux_type->s.strct,
e2->e.string_val);
if (!field)
return error (e2, "structure has no field %s",
@ -1157,7 +1162,7 @@ field_expr (expr_t *e1, expr_t *e2)
if (e2->type == ex_name) {
int protected;
class = t1->aux_type->class;
class = t1->aux_type->s.class;
protected = class_access (current_class, class);
field = class_find_ivar (class, protected,
e2->e.string_val);
@ -2070,7 +2075,7 @@ expr_t *
address_expr (expr_t *e1, expr_t *e2, type_t *t)
{
expr_t *e;
type_t *type = 0;
type_t *type;
if (e1->type == ex_error)
return e1;
@ -2100,7 +2105,7 @@ address_expr (expr_t *e1, expr_t *e2, type_t *t)
e->e.pointer.def = def;
} else {
e = new_unary_expr ('&', e1);
e->e.expr.type = pointer_type (type);
e->e.expr.type = pointer_type (t);
}
break;
}
@ -2119,7 +2124,6 @@ address_expr (expr_t *e1, expr_t *e2, type_t *t)
case ex_uexpr:
if (e1->e.expr.op == '.') {
e = e1->e.expr.e1;
type = get_type (e)->aux_type;
if (e->type == ex_expr && e->e.expr.op == '.') {
e->e.expr.type = e->e.expr.type;
e->e.expr.op = '&';
@ -2324,11 +2328,11 @@ init_elements (def_t *def, expr_t *eles)
} else if (def->type->type == ev_struct) {
struct_field_t *field;
for (i = 0, field = def->type->struct_head; field;
for (i = 0, field = def->type->s.strct->struct_head; field;
i++, field = field->next)
;
elements = calloc (i, sizeof (def_t));
for (i = 0, field = def->type->struct_head; field;
for (i = 0, field = def->type->s.strct->struct_head; field;
i++, field = field->next) {
elements[i].type = field->type;
elements[i].ofs = def->ofs + field->offset;
@ -2343,9 +2347,9 @@ init_elements (def_t *def, expr_t *eles)
free (elements);
return;
}
if (count > def->type->num_parms) {
if (count > num_params) {
warning (eles, "excessive elements in initializer");
count = def->type->num_parms;
count = num_params;
}
for (i = 0, e = eles->e.block.head; i < count; i++, e = e->next) {
g = G_POINTER (pr_type_t, elements[i].ofs);
@ -2485,7 +2489,7 @@ message_expr (expr_t *receiver, keywordarg_t *message)
|| (rec_type->aux_type->type != ev_object
&& rec_type->aux_type->type != ev_class))
return error (receiver, "not a class/object");
class = rec_type->aux_type->class;
class = rec_type->aux_type->s.class;
}
method = class_message_response (class, class_msg, selector);

View file

@ -316,7 +316,7 @@ emit_methods (methodlist_t *_methods, const char *name, int instance)
int i, count;
def_t *methods_def;
pr_method_list_t *methods;
type_t *method_list;
struct_t *method_list;
if (!_methods)
return 0;
@ -329,12 +329,14 @@ emit_methods (methodlist_t *_methods, const char *name, int instance)
}
if (!count)
return 0;
method_list = new_struct (0);
method_list = get_struct (0, 1);
init_struct (method_list, new_type (), str_struct, 0);
new_struct_field (method_list, &type_pointer, "method_next", vis_public);
new_struct_field (method_list, &type_integer, "method_count", vis_public);
for (i = 0; i < count; i++)
new_struct_field (method_list, type_Method.aux_type, 0, vis_public);
methods_def = get_def (method_list, va ("_OBJ_%s_METHODS_%s", type, name),
methods_def = get_def (method_list->type,
va ("_OBJ_%s_METHODS_%s", type, name),
pr.scope, st_static);
methods_def->initialized = methods_def->constant = 1;
methods_def->nosave = 1;

View file

@ -378,7 +378,7 @@ type_or_name (char *token)
if (token[0] == '@') {
return '@';
}
if ((type = find_struct (token)) || (type = get_typedef (token))) {
if ((type = get_typedef (token))) {
yylval.type = type;
return TYPE;
}

View file

@ -118,6 +118,7 @@ expr_t *argv_expr (void);
struct protocol_s *protocol;
struct keywordarg_s *keywordarg;
struct methodlist_s *methodlist;
struct struct_s *strct;
}
%right <op> '=' ASX PAS /* pointer assign */
@ -172,7 +173,7 @@ expr_t *argv_expr (void);
%type <category> category_name new_category_name
%type <protocol> protocol_name
%type <methodlist> methodprotolist methodprotolist2
%type <type> ivar_decl_list
%type <strct> ivar_decl_list
%expect 4
@ -186,9 +187,9 @@ expr_t *local_expr;
expr_t *break_label;
expr_t *continue_label;
switch_block_t *switch_block;
type_t *struct_type;
visibility_t current_visibility;
type_t *current_ivars;
struct_t *current_struct;
visibility_type current_visibility;
struct_t *current_ivars;
scope_t *current_scope;
storage_class_t current_storage;
@ -209,9 +210,11 @@ def
| storage_class type { $$ = $2; } def_list { }
| storage_class '{' simple_defs '}' { }
| STRUCT NAME
{ struct_type = new_struct ($2); } '=' '{' struct_defs '}' { }
{ current_struct = new_struct ($2); } '=' '{' struct_defs '}' { }
| UNION NAME
{ struct_type = new_union ($2); } '=' '{' struct_defs '}' { }
{ current_struct = new_union ($2); } '=' '{' struct_defs '}' { }
| STRUCT NAME { decl_struct ($2)->type; }
| UNION NAME { decl_union ($2)->type; }
| ENUM '{' enum_list opt_comma '}'
{ process_enum ($3); }
| TYPEDEF type NAME
@ -246,7 +249,7 @@ struct_defs
class_t *class = get_class ($3, 0);
if (class) {
copy_struct_fields (struct_type, class->ivars);
copy_struct_fields (current_struct, class->ivars);
} else {
error (0, "undefined symbol `%s'", $3);
}
@ -320,6 +323,8 @@ type_name
}
$$ = class->type;
}
| STRUCT NAME { $$ = decl_struct ($2)->type; }
| UNION NAME { $$ = decl_union ($2)->type; }
;
function_decl
@ -372,7 +377,7 @@ struct_def_list
;
struct_def_item
: NAME { new_struct_field (struct_type, $<type>0, $1, vis_public); }
: NAME { new_struct_field (current_struct, $<type>0, $1, vis_public); }
;
def_list
@ -1022,7 +1027,8 @@ classdef
END { current_class = 0; }
| INTERFACE new_class_name
protocolrefs { class_add_protocol_methods ($2, $3); $$ = $2; }
methodprotolist { class_add_methods ($2, $5); }
{ class_add_ivars ($2, class_new_ivars ($2)); }
methodprotolist { class_add_methods ($2, $6); }
END { current_class = 0; }
| INTERFACE new_class_with_super
protocolrefs { class_add_protocol_methods ($2, $3);}
@ -1032,7 +1038,8 @@ classdef
END { current_class = 0; }
| INTERFACE new_class_with_super
protocolrefs { class_add_protocol_methods ($2, $3); $$ = $2; }
methodprotolist { class_add_methods ($2, $5); }
{ class_add_ivars ($2, class_new_ivars ($2)); }
methodprotolist { class_add_methods ($2, $6); }
END { current_class = 0; }
| INTERFACE new_category_name
protocolrefs { category_add_protocol_methods ($2, $3); $$ = $2->class;}
@ -1078,11 +1085,7 @@ ivar_decl_list
: /* */
{
current_visibility = vis_protected;
current_ivars = new_struct (0);
if ($<class>0->super_class)
new_struct_field (current_ivars,
$<class>0->super_class->ivars, 0,
vis_private);
current_ivars = class_new_ivars ($<class>0);
}
ivar_decl_list_2
{

View file

@ -79,8 +79,8 @@ enums_get_key (void *e, void *unused)
}
struct_field_t *
new_struct_field (type_t *strct, type_t *type, const char *name,
visibility_t visibility)
new_struct_field (struct_t *strct, type_t *type, const char *name,
visibility_type visibility)
{
struct_field_t *field;
@ -90,13 +90,14 @@ new_struct_field (type_t *strct, type_t *type, const char *name,
field->visibility = visibility;
field->name = name;
field->type = type;
if (((struct_t *) strct->class)->is_union) {
if (strct->stype == str_union) {
int size = type_size (type);
field->offset = 0;
strct->num_parms = strct->num_parms > size ? strct->num_parms : size;
if (size > strct->size)
strct->size = size;
} else {
field->offset = strct->num_parms;
strct->num_parms += type_size (type);
field->offset = strct->size;;
strct->size += type_size (type);
}
field->next = 0;
*strct->struct_tail = field;
@ -107,7 +108,7 @@ new_struct_field (type_t *strct, type_t *type, const char *name,
}
struct_field_t *
struct_find_field (type_t *strct, const char *name)
struct_find_field (struct_t *strct, const char *name)
{
if (!structs || !strct)
return 0;
@ -115,66 +116,46 @@ struct_find_field (type_t *strct, const char *name)
}
type_t *
init_struct (struct_t *strct, type_t *type, const char *name)
init_struct (struct_t *strct, type_t *type, struct_type stype,
const char *name)
{
strct->name = name ? save_string (name) : 0;
if (name)
strct->name = save_string (name);
strct->type = type;
strct->type->type = ev_struct;
strct->type->struct_tail = &strct->type->struct_head;
strct->type->struct_fields = Hash_NewTable (61, struct_field_get_key, 0, 0);
strct->type->class = (struct class_s *)strct;
strct->is_union = 0;
strct->struct_tail = &strct->struct_head;
strct->struct_fields = Hash_NewTable (61, struct_field_get_key, 0, 0);
strct->type->s.strct = strct;
strct->stype = stype;
if (name) {
strct->type->name = save_string (name);
strct->type->name = strct->name;
Hash_Add (structs, strct);
}
return strct->type;
}
type_t *
new_struct (const char *name)
struct_t *
get_struct (const char *name, int create)
{
struct_t *strct;
if (!structs) {
structs = Hash_NewTable (16381, structs_get_key, 0, 0);
}
if (name) {
strct = (struct_t *) Hash_Find (structs, name);
if (strct) {
error (0, "duplicate struct definition: `%s'", name);
return 0;
}
}
strct = malloc (sizeof (struct_t));
return init_struct (strct, new_type (), name);
}
type_t *
new_union (const char *name)
{
type_t *un = new_struct (name);
if (un)
((struct_t *) un->class)->is_union = 1;
return un;
}
type_t *
find_struct (const char *name)
{
struct_t *strct;
struct_t *s;
if (!structs)
return 0;
strct = (struct_t *) Hash_Find (structs, name);
if (strct)
return strct->type;
return 0;
structs = Hash_NewTable (16381, structs_get_key, 0, 0);
if (name) {
s = Hash_Find (structs, name);
if (s || !create)
return s;
}
s = calloc (sizeof (struct_t), 1);
s->name = name;
s->return_addr = __builtin_return_address (0);
if (name)
Hash_Add (structs, s);
return s;
}
void
copy_struct_fields (type_t *dst, type_t *src)
copy_struct_fields (struct_t *dst, struct_t *src)
{
struct_field_t *s;
@ -185,7 +166,7 @@ copy_struct_fields (type_t *dst, type_t *src)
}
int
struct_compare_fields (struct type_s *s1, struct type_s *s2)
struct_compare_fields (struct_t *s1, struct_t *s2)
{
struct_field_t *f1 = s1->struct_head;
struct_field_t *f2 = s2->struct_head;
@ -200,14 +181,75 @@ struct_compare_fields (struct type_s *s1, struct type_s *s2)
return !((!f1) ^ !(f2));
}
static struct_t *
start_struct (const char *name, struct_type stype)
{
struct_t *strct = get_struct (name, 1);
if (strct->struct_head) {
error (0, "%s redeclared", name);
goto err;
}
if (strct->stype != str_none && strct->stype != stype) {
error (0, "%s defined as wrong kind of tag", name);
goto err;
}
if (!strct->type)
init_struct (strct, new_type (), stype, 0);
return strct;
err:
strct = get_struct (0, 0);
init_struct (strct, new_type (), stype, 0);
return strct;
}
struct_t *
new_struct (const char *name)
{
return start_struct (name, str_struct);
}
struct_t *
new_union (const char *name)
{
return start_struct (name, str_union);
}
static struct_t *
check_struct (const char *name, struct_type stype)
{
struct_t *strct = get_struct (name, 0);
if (!strct)
return start_struct (name, stype);
if (strct->stype != stype) {
error (0, "%s defined as wrong kind of tag", name);
strct = get_struct (0, 0);
init_struct (strct, new_type (), stype, 0);
}
return strct;
}
struct_t *
decl_struct (const char *name)
{
return check_struct (name, str_struct);
}
struct_t *
decl_union (const char *name)
{
return check_struct (name, str_union);
}
def_t *
emit_struct(type_t *strct, const char *name)
emit_struct(struct_t *strct, const char *name)
{
struct_field_t *field;
int i, count;
def_t *ivars_def;
pr_ivar_list_t *ivars;
type_t *ivar_list;
struct_t *ivar_list;
dstring_t *encoding = dstring_newstr ();
dstring_t *ivars_name = dstring_newstr ();
@ -221,10 +263,11 @@ emit_struct(type_t *strct, const char *name)
for (i = 0; i < count; i++)
new_struct_field (ivar_list, type_ivar, 0, vis_public);
dsprintf (ivars_name, "_OBJ_INSTANCE_VARIABLES_%s", name);
ivars_def = get_def (ivar_list, ivars_name->str, pr.scope, st_none);
ivars_def = get_def (ivar_list->type, ivars_name->str, pr.scope, st_none);
if (ivars_def)
goto done;
ivars_def = get_def (ivar_list, ivars_name->str, pr.scope, st_static);
ivars_def = get_def (ivar_list->type, ivars_name->str, pr.scope,
st_static);
ivars_def->initialized = ivars_def->constant = 1;
ivars_def->nosave = 1;
ivars = &G_STRUCT (pr_ivar_list_t, ivars_def->ofs);
@ -277,8 +320,7 @@ process_enum (expr_t *enm)
val = name->e.expr.e2;
name = name->e.expr.e1;
}
if ((structs && find_struct (name->e.string_val))
|| get_enum (name->e.string_val)
if (get_enum (name->e.string_val)
|| get_def (NULL, name->e.string_val, pr.scope, st_none)) {
error (name, "%s redeclared", name->e.string_val);
continue;

View file

@ -98,7 +98,7 @@ type_t type_va_list;
type_t type_param;
type_t type_zero;
type_t *vector_struct;
struct_t *vector_struct;
type_t type_floatfield = { ev_field, ".float", NULL, &type_float };
@ -135,7 +135,7 @@ find_type (type_t *type)
if (check->type != type->type
|| check->aux_type != type->aux_type
|| check->num_parms != type->num_parms
|| check->class != type->class)
|| check->s.class != type->s.class)
continue;
if (check->type != ev_func)
@ -279,7 +279,7 @@ print_type (type_t *type)
break;
case ev_object:
case ev_class:
printf (" %s", type->class->name);
printf (" %s", type->s.class->name);
break;
case ev_struct:
printf (" %s %s", pr_type_name[type->type], type->name);
@ -369,15 +369,21 @@ _encode_type (dstring_t *encoding, type_t *type, int level)
if (type->name) {
dstring_appendstr (encoding, type->name);
} else if (type->type == ev_object || type->type == ev_class) {
dstring_appendstr (encoding, type->class->name);
dstring_appendstr (encoding, type->s.class->name);
}
if (level < 2) {
struct_t *s;
if (type->type == ev_struct
&& ((struct_t *)type->class)->is_union)
&& type->s.strct->stype == str_union)
dstring_appendstr (encoding, "-");
else
dstring_appendstr (encoding, "=");
for (field = type->struct_head; field; field = field->next)
if (type->type == ev_struct) {
s = type->s.strct;
} else {
s = type->s.class->ivars;
}
for (field = s->struct_head; field; field = field->next)
_encode_type (encoding, field->type, level + 1);
}
dstring_appendstr (encoding, "}");
@ -407,6 +413,7 @@ static type_t *
_parse_type (const char **str)
{
type_t new;
struct_t *strct;
dstring_t *name;
const char *s;
@ -464,9 +471,10 @@ _parse_type (const char **str)
return 0;
dstring_appendsubstr (name, *str, s - *str);
*str = s;
strct = 0;
if (name->str[0])
new.aux_type = find_struct (name->str);
if (new.aux_type) {
strct = get_struct (name->str, 0);
if (strct) {
dstring_delete (name);
if (**str == '=' || **str == '-') {
(*str)++;
@ -476,24 +484,25 @@ _parse_type (const char **str)
if (**str != '}')
return 0;
(*str)++;
return new.aux_type;
return strct->type;
}
if (**str != '=' && **str != '-') {
dstring_delete (name);
return 0;
}
new.aux_type = new_struct (*name->str ? name->str : 0);
strct = get_struct (*name->str ? name->str : 0, 1);
if (**str == '-')
((struct_t *) new.aux_type->class)->is_union = 1;
init_struct (strct, new_type (), str_union, 0);
else
init_struct (strct, new_type (), str_struct, 0);
dstring_delete (name);
(*str)++;
while (**str && **str != '}')
new_struct_field (new.aux_type, _parse_type (str), 0,
vis_public);
new_struct_field (strct, _parse_type (str), 0, vis_public);
if (**str != '}')
return 0;
(*str)++;
return new.aux_type;
return strct->type;
case '[':
new.type = ev_array;
while (isdigit ((byte)**str)) {
@ -536,8 +545,8 @@ type_assignable (type_t *dst, type_t *src)
if ((dst->type != ev_object && dst->type != ev_class)
|| (src->type != ev_object && src->type != ev_class))
return 0;
dst_class = dst->class;
src_class = src->class;
dst_class = dst->s.class;
src_class = src->s.class;
//printf ("%s %s\n", dst_class->class_name, src_class->class_name);
if (!dst_class || dst_class == &class_id)
return 1;
@ -556,9 +565,6 @@ type_assignable (type_t *dst, type_t *src)
int
type_size (type_t *type)
{
struct_field_t *field;
int size;
if (!type)
return 0;
switch (type->type) {
@ -578,14 +584,12 @@ type_size (type_t *type)
case ev_type_count:
return pr_type_size[type->type];
case ev_struct:
return type->num_parms;
return type->s.strct->size;
case ev_object:
case ev_class:
for (size = 0, field = type->struct_head;
field;
field = field->next)
size += type_size (field->type);
return size;
if (!type->s.class->ivars)
return 0;
return type->s.class->ivars->size;
case ev_array:
return type->num_parms * type_size (type->aux_type);
}
@ -596,113 +600,121 @@ void
init_types (void)
{
type_t *type;
struct_t *strct;
init_struct (malloc (sizeof (struct_t)), type = &type_zero, 0);
((struct_t *) type->class)->is_union = 1;
new_struct_field (type, &type_string, "string_val", vis_public);
new_struct_field (type, &type_float, "float_val", vis_public);
new_struct_field (type, &type_entity, "entity_val", vis_public);
new_struct_field (type, &type_field, "field_val", vis_public);
new_struct_field (type, &type_function, "func_val", vis_public);
new_struct_field (type, &type_pointer, "pointer_val", vis_public);
new_struct_field (type, &type_integer, "integer_val", vis_public);
new_struct_field (type, &type_uinteger, "uinteger_val", vis_public);
init_struct (malloc (sizeof (struct_t)), type = &type_param, 0);
((struct_t *) type->class)->is_union = 1;
new_struct_field (type, &type_string, "string_val", vis_public);
new_struct_field (type, &type_float, "float_val", vis_public);
new_struct_field (type, &type_vector, "vector_val", vis_public);
new_struct_field (type, &type_entity, "entity_val", vis_public);
new_struct_field (type, &type_field, "field_val", vis_public);
new_struct_field (type, &type_function, "func_val", vis_public);
new_struct_field (type, &type_pointer, "pointer_val", vis_public);
new_struct_field (type, &type_integer, "integer_val", vis_public);
new_struct_field (type, &type_uinteger, "uinteger_val", vis_public);
strct = calloc (sizeof (struct_t), 1);
init_struct (strct, &type_zero, str_union, 0);
new_struct_field (strct, &type_string, "string_val", vis_public);
new_struct_field (strct, &type_float, "float_val", vis_public);
new_struct_field (strct, &type_entity, "entity_val", vis_public);
new_struct_field (strct, &type_field, "field_val", vis_public);
new_struct_field (strct, &type_function, "func_val", vis_public);
new_struct_field (strct, &type_pointer, "pointer_val", vis_public);
new_struct_field (strct, &type_integer, "integer_val", vis_public);
new_struct_field (strct, &type_uinteger, "uinteger_val", vis_public);
if (options.traditional)
return;
type = vector_struct = new_struct (0);
new_struct_field (type, &type_float, "x", vis_public);
new_struct_field (type, &type_float, "y", vis_public);
new_struct_field (type, &type_float, "z", vis_public);
strct = vector_struct = get_struct (0, 1);
init_struct (strct, new_type (), str_struct, 0);
new_struct_field (strct, &type_float, "x", vis_public);
new_struct_field (strct, &type_float, "y", vis_public);
new_struct_field (strct, &type_float, "z", vis_public);
type = type_SEL.aux_type = new_struct (0);
new_struct_field (type, &type_string, "sel_id", vis_public);
new_struct_field (type, &type_string, "sel_types", vis_public);
strct = get_struct (0, 1);
init_struct (strct, new_type (), str_struct, 0);
new_struct_field (strct, &type_string, "sel_id", vis_public);
new_struct_field (strct, &type_string, "sel_types", vis_public);
type_SEL.aux_type = strct->type;
type = type_Method.aux_type = new_struct (0);
new_struct_field (type, type_SEL.aux_type, "method_name", vis_public);
new_struct_field (type, &type_string, "method_types", vis_public);
new_struct_field (type, &type_IMP, "method_imp", vis_public);
strct = get_struct (0, 1);
init_struct (strct, new_type (), str_struct, 0);
new_struct_field (strct, type_SEL.aux_type, "method_name", vis_public);
new_struct_field (strct, &type_string, "method_types", vis_public);
new_struct_field (strct, &type_IMP, "method_imp", vis_public);
type_Method.aux_type = strct->type;
type = type_Class.aux_type = new_struct (0);
strct = get_struct (0, 1);
init_struct (strct, type = new_type (), str_struct, 0);
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);
new_struct_field (type, &type_integer, "version", vis_public);
new_struct_field (type, &type_integer, "info", vis_public);
new_struct_field (type, &type_integer, "instance_size", vis_public);
new_struct_field (type, &type_pointer, "ivars", vis_public);
new_struct_field (type, &type_pointer, "methods", vis_public);
new_struct_field (type, &type_pointer, "dtable", vis_public);
new_struct_field (type, &type_pointer, "subclass_list", vis_public);
new_struct_field (type, &type_pointer, "sibling_class", vis_public);
new_struct_field (type, &type_pointer, "protocols", vis_public);
new_struct_field (type, &type_pointer, "gc_object_type", vis_public);
type->s.class = &class_Class;
new_struct_field (strct, &type_Class, "class_pointer", vis_public);
new_struct_field (strct, &type_Class, "super_class", vis_public);
new_struct_field (strct, &type_string, "name", vis_public);
new_struct_field (strct, &type_integer, "version", vis_public);
new_struct_field (strct, &type_integer, "info", vis_public);
new_struct_field (strct, &type_integer, "instance_size", vis_public);
new_struct_field (strct, &type_pointer, "ivars", vis_public);
new_struct_field (strct, &type_pointer, "methods", vis_public);
new_struct_field (strct, &type_pointer, "dtable", vis_public);
new_struct_field (strct, &type_pointer, "subclass_list", vis_public);
new_struct_field (strct, &type_pointer, "sibling_class", vis_public);
new_struct_field (strct, &type_pointer, "protocols", vis_public);
new_struct_field (strct, &type_pointer, "gc_object_type", vis_public);
type_Class.aux_type = strct->type;
class_Class.ivars = strct;
type = type_Protocol.aux_type = new_struct (0);
strct = get_struct (0, 1);
init_struct (strct, type = new_type (), str_struct, 0);
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);
new_struct_field (type, &type_pointer, "instance_methods", vis_public);
new_struct_field (type, &type_pointer, "class_methods", vis_public);
type->s.class = &class_Protocol;
new_struct_field (strct, &type_Class, "class_pointer", vis_public);
new_struct_field (strct, &type_string, "protocol_name", vis_public);
new_struct_field (strct, &type_pointer, "protocol_list", vis_public);
new_struct_field (strct, &type_pointer, "instance_methods", vis_public);
new_struct_field (strct, &type_pointer, "class_methods", vis_public);
type_Protocol.aux_type = strct->type;
class_Protocol.ivars = strct;
type = type_id.aux_type = new_struct ("id");
strct = get_struct (0, 1);
init_struct (strct, type = new_type (), str_struct, 0);
type->type = ev_object;
type->class = &class_id;
class_id.ivars = type_id.aux_type;
new_struct_field (type, &type_Class, "class_pointer", vis_public);
type->s.class = &class_id;
new_struct_field (strct, &type_Class, "class_pointer", vis_public);
type_id.aux_type = strct->type;
class_id.ivars = strct;
type = type_category = new_struct (0);
new_struct_field (type, &type_string, "category_name", vis_public);
new_struct_field (type, &type_string, "class_name", vis_public);
new_struct_field (type, &type_pointer, "instance_methods", vis_public);
new_struct_field (type, &type_pointer, "class_methods", vis_public);
new_struct_field (type, &type_pointer, "protocols", vis_public);
strct = get_struct (0, 1);
init_struct (strct, new_type (), str_struct, 0);
new_struct_field (strct, &type_string, "category_name", vis_public);
new_struct_field (strct, &type_string, "class_name", vis_public);
new_struct_field (strct, &type_pointer, "instance_methods", vis_public);
new_struct_field (strct, &type_pointer, "class_methods", vis_public);
new_struct_field (strct, &type_pointer, "protocols", vis_public);
type_category = strct->type;
type = type_ivar = new_struct (0);
new_struct_field (type, &type_string, "ivar_name", vis_public);
new_struct_field (type, &type_string, "ivar_type", vis_public);
new_struct_field (type, &type_integer, "ivar_offset", vis_public);
strct = get_struct (0, 1);
init_struct (strct, new_type (), str_struct, 0);
new_struct_field (strct, &type_string, "ivar_name", vis_public);
new_struct_field (strct, &type_string, "ivar_type", vis_public);
new_struct_field (strct, &type_integer, "ivar_offset", vis_public);
type_ivar = strct->type;
init_struct (malloc (sizeof (struct_t)), &type_va_list, 0);
new_struct_field (&type_va_list, &type_integer, "count", vis_public);
new_struct_field (&type_va_list, pointer_type (&type_param), "list",
vis_public);
strct = calloc (sizeof (struct_t), 1);
init_struct (strct, &type_va_list, str_union, 0);
new_struct_field (strct, &type_integer, "count", vis_public);
new_struct_field (strct, pointer_type (&type_param), "list", vis_public);
type = type_Super.aux_type = new_struct ("Super");
new_struct_field (type, &type_id, "self", vis_public);
new_struct_field (type, &type_Class, "class", vis_public);
strct = get_struct ("Super", 1);
init_struct (strct, new_type (), str_struct, 0);
new_struct_field (strct, &type_id, "self", vis_public);
new_struct_field (strct, &type_Class, "class", vis_public);
type_Super.aux_type = strct->type;
#if 0
type = type_module = new_struct ("obj_module_t");
new_struct_field (type, &type_integer, "version", vis_public);
new_struct_field (type, &type_integer, "size", vis_public);
new_struct_field (type, &type_string, "name", vis_public);
new_struct_field (type, &type_pointer, "symtab", vis_public);
new_struct_field (strct, &type_integer, "version", vis_public);
new_struct_field (strct, &type_integer, "size", vis_public);
new_struct_field (strct, &type_string, "name", vis_public);
new_struct_field (strct, &type_pointer, "symtab", vis_public);
#endif
}
void
chain_initial_types (void)
{
struct_t *strct;
chain_type (&type_void);
chain_type (&type_string);
chain_type (&type_float);
@ -738,16 +750,18 @@ chain_initial_types (void)
type_supermsg.parm_types[0] = &type_Super;
chain_type (&type_supermsg);
type_module = new_struct ("obj_module_t");
new_struct_field (type_module, &type_integer, "version", vis_public);
new_struct_field (type_module, &type_integer, "size", vis_public);
new_struct_field (type_module, &type_string, "name", vis_public);
new_struct_field (type_module, &type_pointer, "symtab", vis_public);
strct = get_struct ("obj_module_s", 1);
init_struct (strct, new_type (), str_struct, 0);
new_struct_field (strct, &type_integer, "version", vis_public);
new_struct_field (strct, &type_integer, "size", vis_public);
new_struct_field (strct, &type_string, "name", vis_public);
new_struct_field (strct, &type_pointer, "symtab", vis_public);
type_module = strct->type;
new_typedef ("obj_module_t", type_module);
chain_type (type_module);
chain_type (&type_obj_exec_class);
type_obj_exec_class.parm_types[0] = pointer_type (type_module);
chain_type (&type_obj_exec_class);
}
void