more progress

This commit is contained in:
Bill Currie 2002-05-10 00:00:23 +00:00
parent f2b8dc7e7e
commit 2cd716176a
10 changed files with 372 additions and 229 deletions

View file

@ -32,29 +32,27 @@
#ifndef __class_h #ifndef __class_h
#define __class_h #define __class_h
#include "method.h"
typedef struct class_s { typedef struct class_s {
int defined;
const char *name; const char *name;
struct class_s *base; struct class_s *base;
methodlist_t methods; struct methodlist_s *methods;
struct type_s *ivars;
} class_t; } class_t;
typedef struct protocol_s { typedef struct protocol_s {
const char *name; const char *name;
methodlist_t methods; struct methodlist_s *methods;
} protocol_t; } protocol_t;
typedef struct category_s { class_t *get_class (const char *name, int create);
const char *name; void class_add_methods (class_t *class, struct methodlist_s *methods);
class_t *klass; void class_add_protocol_methods (class_t *class, expr_t *protocols);
methodlist_t methods; struct def_s *class_def (class_t *class);
} category_t;
class_t *new_class (const char *name, class_t *base); protocol_t *get_protocol (const char *name, int create);
protocol_t *new_protocol (const char *name); void protocol_add_methods (protocol_t *protocol, struct methodlist_s *methods);
category_t *new_category (const char *name, class_t *klass); void protocol_add_protocol_methods (protocol_t *protocol, expr_t *protocols);
class_t *find_class (const char *name); struct def_s *protocol_def (protocol_t *protocol);
protocol_t *find_protocol (const char *name);
#endif//__class_h #endif//__class_h

View file

@ -43,7 +43,7 @@ typedef struct method_s {
def_t *def; def_t *def;
} method_t; } method_t;
typedef struct { typedef struct methodlist_s {
method_t *head; method_t *head;
method_t **tail; method_t **tail;
} methodlist_t; } methodlist_t;
@ -57,15 +57,17 @@ typedef struct keywordarg_s {
} keywordarg_t; } keywordarg_t;
struct class_s; struct class_s;
struct category_s;
struct expr_s; struct expr_s;
struct dstring_s; struct dstring_s;
method_t *new_method (type_t *ret_type, param_t *selector, param_t *opt_parms); method_t *new_method (type_t *ret_type, param_t *selector, param_t *opt_parms);
void add_method (methodlist_t *methodlist, method_t *method); void add_method (methodlist_t *methodlist, method_t *method);
def_t *method_def (struct class_s *klass, struct category_s *category, def_t *method_def (struct class_s *class, struct class_s *category,
method_t *method); method_t *method);
methodlist_t *new_methodlist (void);
void copy_methods (methodlist_t *dst, methodlist_t *src);
keywordarg_t *new_keywordarg (const char *selector, struct expr_s *expr); keywordarg_t *new_keywordarg (const char *selector, struct expr_s *expr);
struct expr_s *send_message (void); struct expr_s *send_message (void);

View file

@ -32,18 +32,26 @@
#ifndef __struct_h #ifndef __struct_h
#define __struct_h #define __struct_h
typedef enum {
vis_private,
vis_protected,
vis_public,
} visibility_t;
typedef struct struct_field_s { typedef struct struct_field_s {
struct struct_field_s *next; struct struct_field_s *next;
const char *name; const char *name;
struct type_s *type; struct type_s *type;
int offset; int offset;
visibility_t visibility;
} struct_field_t; } struct_field_t;
struct_field_t *new_struct_field (struct type_s *strct, struct type_s *type, struct_field_t *new_struct_field (struct type_s *strct, struct type_s *type,
const char *name); const char *name, visibility_t visibility);
struct_field_t *struct_find_field (struct type_s *strct, const char *name); struct_field_t *struct_find_field (struct type_s *strct, const char *name);
struct type_s *new_struct (const char *name); struct type_s *new_struct (const char *name);
struct type_s *find_struct (const char *name); struct type_s *find_struct (const char *name);
void copy_struct_fields (struct type_s *dst, struct type_s *src);
void process_enum (struct expr_s *enm); void process_enum (struct expr_s *enm);
expr_t *get_enum (const char *name); expr_t *get_enum (const char *name);

View file

@ -48,6 +48,7 @@ extern type_t type_short;
extern type_t type_struct; extern type_t type_struct;
extern type_t type_id; extern type_t type_id;
extern type_t type_Class; extern type_t type_Class;
extern type_t type_Protocol;
extern type_t type_SEL; extern type_t type_SEL;
extern type_t type_IMP; extern type_t type_IMP;
extern type_t type_method_list; extern type_t type_method_list;

View file

@ -31,55 +31,135 @@ static const char rcsid[] =
"$Id$"; "$Id$";
#include "QF/dstring.h" #include "QF/dstring.h"
#include "QF/hash.h"
#include "qfcc.h" #include "qfcc.h"
#include "class.h" #include "class.h"
#include "method.h"
#include "type.h" #include "type.h"
class_t * static hashtab_t *class_hash;
new_class (const char *name, class_t *base) static hashtab_t *protocol_hash;
{
class_t *c = malloc (sizeof (class_t));
static const char *
class_get_key (void *class, void *unused)
{
return ((class_t *) class)->name;
}
static const char *
protocol_get_key (void *protocol, void *unused)
{
return ((protocol_t *) protocol)->name;
}
class_t *
get_class (const char *name, int create)
{
class_t *c;
if (!class_hash)
class_hash = Hash_NewTable (1021, class_get_key, 0, 0);
if (name) {
c = Hash_Find (class_hash, name);
if (c || !create)
return c;
}
c = calloc (sizeof (class_t), 1);
c->name = name; c->name = name;
c->base = base; Hash_Add (class_hash, c);
c->methods.head = 0;
c->methods.tail = &c->methods.head;
return c; return c;
} }
protocol_t * void
new_protocol (const char *name) class_add_methods (class_t *class, methodlist_t *methods)
{ {
protocol_t *p = malloc (sizeof (protocol_t)); if (!methods)
return;
if (!class->methods)
class->methods = new_methodlist ();
*class->methods->tail = methods->head;
class->methods->tail = methods->tail;
free (methods);
}
void
class_add_protocol_methods (class_t *class, expr_t *protocols)
{
expr_t *e;
protocol_t *p;
if (!protocol_hash)
protocol_hash = Hash_NewTable (1021, protocol_get_key, 0, 0);
if (!class->methods)
class->methods = new_methodlist ();
for (e = protocols; e; e = e->next) {
if (!(p = get_protocol (e->e.string_val, 0))) {
error (e, "undefined protocol `%s'", e->e.string_val);
continue;
}
copy_methods (class->methods, p->methods);
}
}
def_t *
class_def (class_t *class)
{
return PR_GetDef (&type_Class, class->name, 0, &numpr_globals);
}
protocol_t *
get_protocol (const char *name, int create)
{
protocol_t *p;
if (name) {
p = Hash_Find (protocol_hash, name);
if (p || !create)
return p;
}
p = calloc (sizeof (protocol_t), 1);
p->name = name; p->name = name;
p->methods.head = 0; Hash_Add (protocol_hash, p);
p->methods.tail = &p->methods.head;
return p; return p;
} }
category_t * void
new_category (const char *name, class_t *klass) protocol_add_methods (protocol_t *protocol, methodlist_t *methods)
{ {
category_t *c = malloc (sizeof (category_t)); if (!methods)
return;
c->name = name; if (!protocol->methods)
c->klass = klass; protocol->methods = new_methodlist ();
c->methods.head = 0; *protocol->methods->tail = methods->head;
c->methods.tail = &c->methods.head; protocol->methods->tail = methods->tail;
return c; free (methods);
} }
class_t * void
find_class (const char *name) protocol_add_protocol_methods (protocol_t *protocol, expr_t *protocols)
{ {
return 0; expr_t *e;
protocol_t *p;
if (!protocol->methods)
protocol->methods = new_methodlist ();
for (e = protocols; e; e = e->next) {
if (!(p = get_protocol (e->e.string_val, 0))) {
error (e, "undefined protocol `%s'", e->e.string_val);
continue;
}
copy_methods (protocol->methods, p->methods);
}
} }
protocol_t * def_t *
find_protocol (const char *name) protocol_def (protocol_t *protocol)
{ {
return 0; return PR_GetDef (&type_Protocol, protocol->name, 0, &numpr_globals);
} }

View file

@ -39,6 +39,7 @@ static const char rcsid[] =
#include "qfcc.h" #include "qfcc.h"
#include "function.h" #include "function.h"
#include "class.h"
#include "method.h" #include "method.h"
#include "struct.h" #include "struct.h"
#include "type.h" #include "type.h"
@ -107,9 +108,17 @@ convert_name (expr_t *e)
{ {
if (e->type == ex_name) { if (e->type == ex_name) {
const char *name = e->e.string_val; const char *name = e->e.string_val;
def_t *d = PR_GetDef (NULL, name, pr_scope, 0); def_t *d;
expr_t *enm; expr_t *enm;
class_t *class;
class = get_class (name, 0);
if (class) {
e->type = ex_def;
e->e.def = class_def (class);
return;
}
d = PR_GetDef (NULL, name, pr_scope, 0);
if (d) { if (d) {
e->type = ex_def; e->type = ex_def;
e->e.def = d; e->e.def = d;
@ -198,7 +207,6 @@ error (expr_t *e, const char *fmt, ...)
pr_error_count++; pr_error_count++;
if (e) { if (e) {
e = new_expr ();
e->type = ex_error; e->type = ex_error;
} }
return e; return e;
@ -1444,6 +1452,8 @@ function_expr (expr_t *e1, expr_t *e2)
if (e1->type == ex_error) if (e1->type == ex_error)
return e1; return e1;
for (e = e2; e; e = e->next)
convert_name (e);
for (e = e2; e; e = e->next) { for (e = e2; e; e = e->next) {
if (e->type == ex_error) if (e->type == ex_error)
return e; return e;

View file

@ -77,7 +77,7 @@ add_method (methodlist_t *methodlist, method_t *method)
} }
def_t * def_t *
method_def (class_t *klass, category_t *category, method_t *method) method_def (class_t *class, class_t *category, method_t *method)
{ {
dstring_t *str = dstring_newstr (); dstring_t *str = dstring_newstr ();
dstring_t *sel = dstring_newstr (); dstring_t *sel = dstring_newstr ();
@ -87,7 +87,7 @@ method_def (class_t *klass, category_t *category, method_t *method)
selector_name (sel, (keywordarg_t *)method->selector); selector_name (sel, (keywordarg_t *)method->selector);
dsprintf (str, "_%c_%s_%s_%s", dsprintf (str, "_%c_%s_%s_%s",
method->instance ? 'i' : 'c', method->instance ? 'i' : 'c',
klass->name, class->name,
category ? category->name : "", category ? category->name : "",
sel->str); sel->str);
for (s = str->str; *s; s++) for (s = str->str; *s; s++)
@ -101,6 +101,28 @@ method_def (class_t *klass, category_t *category, method_t *method)
return def; return def;
} }
methodlist_t *
new_methodlist (void)
{
methodlist_t *l = malloc (sizeof (methodlist_t));
l->head = 0;
l->tail = &l->head;
return l;
}
void
copy_methods (methodlist_t *dst, methodlist_t *src)
{
method_t *s, *d;
for (s = src->head; s; s++) {
d = malloc (sizeof (method_t));
*d = *s;
d->next = 0;
add_method (dst, d);
}
}
keywordarg_t * keywordarg_t *
new_keywordarg (const char *selector, struct expr_s *expr) new_keywordarg (const char *selector, struct expr_s *expr)
{ {

View file

@ -64,16 +64,10 @@ hashtab_t *merge_local_inits (hashtab_t *dl_1, hashtab_t *dl_2);
void restore_local_inits (hashtab_t *def_list); void restore_local_inits (hashtab_t *def_list);
void free_local_inits (hashtab_t *def_list); void free_local_inits (hashtab_t *def_list);
typedef struct {
type_t *type;
def_t *scope;
} scope_t;
%} %}
%union { %union {
int op; int op;
def_t *scope;
def_t *def; def_t *def;
struct hashtab_s *def_list; struct hashtab_s *def_list;
type_t *type; type_t *type;
@ -87,10 +81,10 @@ typedef struct {
struct switch_block_s *switch_block; struct switch_block_s *switch_block;
struct param_s *param; struct param_s *param;
struct method_s *method; struct method_s *method;
struct class_s *klass; struct class_s *class;
struct protocol_s *protocol; struct protocol_s *protocol;
struct category_s *category;
struct keywordarg_s *keywordarg; struct keywordarg_s *keywordarg;
struct methodlist_s *methodlist;
} }
%right <op> '=' ASX PAS /* pointer assign */ %right <op> '=' ASX PAS /* pointer assign */
@ -131,14 +125,17 @@ typedef struct {
%type <function> begin_function %type <function> begin_function
%type <def_list> save_inits %type <def_list> save_inits
%type <switch_block> switch_block %type <switch_block> switch_block
%type <scope> param_scope
%type <string_val> selector reserved_word %type <string_val> selector reserved_word
%type <param> optparmlist unaryselector keyworddecl keywordselector %type <param> optparmlist unaryselector keyworddecl keywordselector
%type <method> methodproto methoddecl %type <method> methodproto methoddecl
%type <expr> obj_expr identifier_list obj_messageexpr obj_string receiver %type <expr> obj_expr identifier_list obj_messageexpr obj_string receiver
%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
%type <protocol> protocol_name
%type <methodlist> methodprotolist methodprotolist2
%expect 2 // statement : if | if else, defs : defs def ';' | defs obj_def %expect 2 // statement : if | if else, defs : defs def ';' | defs obj_def
@ -150,12 +147,12 @@ 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_t *current_class;
methodlist_t *current_methodlist;
expr_t *local_expr; expr_t *local_expr;
expr_t *break_label; expr_t *break_label;
expr_t *continue_label; expr_t *continue_label;
switch_block_t *switch_block; switch_block_t *switch_block;
type_t *struct_type; type_t *struct_type;
visibility_t current_visibility;
def_t *pr_scope; // the function being parsed, or NULL def_t *pr_scope; // the function being parsed, or NULL
string_t s_file; // filename for function definition string_t s_file; // filename for function definition
@ -190,6 +187,16 @@ def
struct_defs struct_defs
: /* empty */ : /* empty */
| struct_defs struct_def ';' | struct_defs struct_def ';'
| DEFS '(' NAME ')'
{
class_t *class = get_class ($3, 0);
if (class) {
copy_struct_fields (struct_type, class->ivars);
} else {
error (0, "undefined symbol `%s'", $3);
}
}
; ;
struct_def struct_def
@ -242,44 +249,20 @@ type_name
; ;
function_decl function_decl
: '(' param_scope param_list : '(' param_list ')' { $$ = reverse_params ($2); }
| '(' param_list ',' ELLIPSIS ')'
{ {
PR_FlushScope (pr_scope, 1);
pr_scope = $<scope>2;
}
')'
{
$$ = reverse_params ($3);
}
| '(' param_scope param_list ',' ELLIPSIS ')'
{
PR_FlushScope (pr_scope, 1);
pr_scope = $<scope>2;
$$ = new_param (0, 0, 0); $$ = new_param (0, 0, 0);
$$->next = $3; $$->next = $2;
$$ = reverse_params ($$); $$ = reverse_params ($$);
} }
| '(' ELLIPSIS ')' | '(' ELLIPSIS ')' { $$ = new_param (0, 0, 0); }
{
$$ = new_param (0, 0, 0);
}
| '(' ')' | '(' ')'
{ {
$$ = 0; $$ = 0;
} }
; ;
param_scope
: /* empty */
{
$$ = pr_scope;
pr_scope = PR_NewDef (0, 0, 0);
pr_scope->alloc = &pr_scope->locals;
*pr_scope->alloc = 0;
}
;
param_list param_list
: param : param
| param_list ',' param | param_list ',' param
@ -312,7 +295,7 @@ struct_def_list
; ;
struct_def_item struct_def_item
: NAME { new_struct_field (struct_type, current_type, $1); } : NAME { new_struct_field (struct_type, current_type, $1, vis_public); }
; ;
def_list def_list
@ -887,132 +870,147 @@ identifier_list
} }
; ;
classdecl /* XXX */ classdecl
: CLASS identifier_list : CLASS identifier_list
{ {
expr_t *e; expr_t *e;
for (e = $2->e.block.head; e; e = e->next) for (e = $2->e.block.head; e; e = e->next)
new_class (e->e.string_val, 0); get_class (e->e.string_val, 1);
} }
; ;
classdef /* XXX */ class_name
: INTERFACE NAME : NAME
protocolrefs
{ {
$<klass>$ = new_class ($2, 0); current_visibility = vis_private;
current_methodlist = &$<klass>$->methods; $$ = get_class ($1, 0);
} if (!$$) {
'{' ivar_decl_list '}' error (0, "undefined symbol `%s'", $1);
methodprotolist $$ = get_class (0, 1);
END
| INTERFACE NAME
protocolrefs
{
$<klass>$ = new_class ($2, 0);
current_methodlist = &$<klass>$->methods;
}
methodprotolist
END
| INTERFACE NAME ':' NAME
protocolrefs
{
class_t *base = find_class ($4);
$<klass>$ = new_class ($2, base);
current_methodlist = &$<klass>$->methods;
}
'{' ivar_decl_list '}'
methodprotolist
END
| INTERFACE NAME ':' NAME
protocolrefs
{
class_t *base = find_class ($4);
$<klass>$ = new_class ($2, base);
current_methodlist = &$<klass>$->methods;
}
methodprotolist
END
| INTERFACE NAME '(' NAME ')'
{
class_t *klass = find_class ($4);
$<category>$ = new_category ($2, klass);
current_methodlist = &$<category>$->methods;
}
protocolrefs
methodprotolist
END
| IMPLEMENTATION NAME
{
current_class = new_class ($2, 0);
}
'{' ivar_decl_list '}'
| IMPLEMENTATION NAME
{
current_class = new_class ($2, 0);
}
| IMPLEMENTATION NAME ':' NAME
{
class_t *base = find_class ($4);
current_class = new_class ($2, base);
}
'{' ivar_decl_list '}'
| IMPLEMENTATION NAME ':' NAME
{
class_t *base = find_class ($4);
current_class = new_class ($2, base);
}
| IMPLEMENTATION NAME '(' NAME ')'
;
protocoldef /* XXX */
: PROTOCOL NAME
{
$<protocol>$ = new_protocol ($2);
current_methodlist = &$<protocol>$->methods;
}
protocolrefs
methodprotolist END
;
protocolrefs /* XXX */
: /* emtpy */
| LT identifier_list GT
{
expr_t *e;
for (e = $2->e.block.head; e; e = e->next) {
//puts (e->e.string_val);
} }
} }
; ;
ivar_decl_list /* XXX */ new_class_name
: NAME
{
$$ = get_class ($1, 1);
if ($$->defined) {
error (0, "redefinition of `%s'", $1);
$$ = get_class (0, 1);
}
current_class = $$;
}
protocol_name
: NAME
{
$$ = get_protocol ($1, 1);
if ($$->methods) {
error (0, "redefinition of %s", $1);
$$ = get_protocol (0, 1);
}
}
classdef /* XXX */
: INTERFACE new_class_name
protocolrefs { class_add_protocol_methods ($2, $3); }
'{' { $2->ivars = new_struct (0); }
ivar_decl_list '}'
methodprotolist { class_add_methods ($2, $9); }
END
| INTERFACE new_class_name
protocolrefs { class_add_protocol_methods ($2, $3); }
methodprotolist { class_add_methods ($2, $5); }
END
| INTERFACE new_class_name ':' class_name
protocolrefs { class_add_protocol_methods ($2, $5); }
'{'
{
$2->ivars = new_struct (0);
copy_struct_fields ($2->ivars, $4->ivars);
}
ivar_decl_list '}'
methodprotolist { class_add_methods ($2, $11); }
END
| INTERFACE new_class_name ':' class_name
protocolrefs { class_add_protocol_methods ($2, $5); }
methodprotolist { class_add_methods ($2, $7); }
END
| INTERFACE new_class_name '(' class_name ')'
protocolrefs { class_add_protocol_methods ($2, $6); }
methodprotolist { class_add_methods ($2, $8); }
END
| IMPLEMENTATION class_name '{'
{
$2->ivars = new_struct (0);
current_class = $2;
}
ivar_decl_list '}'
| IMPLEMENTATION class_name { current_class = $2; }
| IMPLEMENTATION class_name ':' class_name '{'
{
if ($4 != $2->base)
warning (0, "%s is not a super class of %s",
$4->name, $2->name);
$2->ivars = new_struct (0);
copy_struct_fields ($2->ivars, $4->ivars);
current_class = $2;
}
ivar_decl_list '}'
| IMPLEMENTATION class_name ':' class_name
{
if ($4 != $2->base)
warning (0, "%s is not a super class of %s",
$4->name, $2->name);
current_class = $2;
}
| IMPLEMENTATION class_name '(' class_name ')' { current_class = $2; }
;
protocoldef
: PROTOCOL protocol_name
protocolrefs { protocol_add_protocol_methods ($2, $3); }
methodprotolist { protocol_add_methods ($2, $5); }
END
;
protocolrefs
: /* emtpy */ { $$ = 0; }
| LT identifier_list GT { $$ = $2->e.block.head; }
;
ivar_decl_list
: ivar_decl_list visibility_spec ivar_decls : ivar_decl_list visibility_spec ivar_decls
| ivar_decls | ivar_decls
; ;
visibility_spec /* XXX */ visibility_spec
: PRIVATE : PRIVATE { current_visibility = vis_private; }
| PROTECTED | PROTECTED { current_visibility = vis_protected; }
| PUBLIC | PUBLIC { current_visibility = vis_public; }
; ;
ivar_decls /* XXX */ ivar_decls
: /* empty */ : /* empty */
| ivar_decls ivar_decl ';' | ivar_decls ivar_decl ';'
; ;
ivar_decl /* XXX */ ivar_decl
: type ivars {} : type ivars { current_type = $1 }
; ;
ivars /* XXX */ ivars
: ivar_declarator : ivar_declarator
| ivars ',' ivar_declarator | ivars ',' ivar_declarator
; ;
ivar_declarator /* XXX */ ivar_declarator
: NAME {} : NAME
{
new_struct_field (current_class->ivars, current_type,
$1, current_visibility);
}
; ;
methoddef methoddef
@ -1055,13 +1053,21 @@ methoddef
; ;
methodprotolist methodprotolist
: /* emtpy */ : /* emtpy */ { $$ = 0; }
| methodprotolist2 | methodprotolist2
; ;
methodprotolist2 methodprotolist2
: methodproto { add_method (current_methodlist, $1); } : methodproto
| methodprotolist2 methodproto { add_method (current_methodlist, $2); } {
$$ = new_methodlist ();
add_method ($$, $1);
}
| methodprotolist2 methodproto
{
add_method ($1, $2);
$$ = $1;
}
; ;
methodproto methodproto
@ -1089,12 +1095,9 @@ methoddecl
; ;
optparmlist optparmlist
: /* empty */ : /* empty */ { $$ = 0; }
{ $$ = 0; } | ',' ELLIPSIS { $$ = new_param (0, 0, 0); }
| ',' ELLIPSIS | ',' param_list { $$ = $2; }
{ $$ = new_param (0, 0, 0); }
| ',' param_list
{ $$ = $2; }
| ',' param_list ',' ELLIPSIS | ',' param_list ',' ELLIPSIS
{ {
$$ = new_param (0, 0, 0); $$ = new_param (0, 0, 0);
@ -1103,7 +1106,7 @@ optparmlist
; ;
unaryselector unaryselector
: selector { $$ = new_param ($1, 0, 0); } : selector { $$ = new_param ($1, 0, 0); }
; ;
keywordselector keywordselector
@ -1113,27 +1116,27 @@ keywordselector
selector selector
: NAME : NAME
| TYPE { $$ = strdup (yytext); } | TYPE { $$ = strdup (yytext); }
| reserved_word | reserved_word
; ;
reserved_word reserved_word
: LOCAL { $$ = strdup (yytext); } : LOCAL { $$ = strdup (yytext); }
| RETURN { $$ = strdup (yytext); } | RETURN { $$ = strdup (yytext); }
| WHILE { $$ = strdup (yytext); } | WHILE { $$ = strdup (yytext); }
| DO { $$ = strdup (yytext); } | DO { $$ = strdup (yytext); }
| IF { $$ = strdup (yytext); } | IF { $$ = strdup (yytext); }
| ELSE { $$ = strdup (yytext); } | ELSE { $$ = strdup (yytext); }
| FOR { $$ = strdup (yytext); } | FOR { $$ = strdup (yytext); }
| BREAK { $$ = strdup (yytext); } | BREAK { $$ = strdup (yytext); }
| CONTINUE { $$ = strdup (yytext); } | CONTINUE { $$ = strdup (yytext); }
| SWITCH { $$ = strdup (yytext); } | SWITCH { $$ = strdup (yytext); }
| CASE { $$ = strdup (yytext); } | CASE { $$ = strdup (yytext); }
| DEFAULT { $$ = strdup (yytext); } | DEFAULT { $$ = strdup (yytext); }
| NIL { $$ = strdup (yytext); } | NIL { $$ = strdup (yytext); }
| STRUCT { $$ = strdup (yytext); } | STRUCT { $$ = strdup (yytext); }
| ENUM { $$ = strdup (yytext); } | ENUM { $$ = strdup (yytext); }
| TYPEDEF { $$ = strdup (yytext); } | TYPEDEF { $$ = strdup (yytext); }
; ;
keyworddecl keyworddecl

View file

@ -68,13 +68,15 @@ enums_get_key (void *e, void *unused)
} }
struct_field_t * struct_field_t *
new_struct_field (type_t *strct, type_t *type, const char *name) new_struct_field (type_t *strct, type_t *type, const char *name,
visibility_t visibility)
{ {
struct_field_t *field; struct_field_t *field;
if (!strct) if (!strct)
return 0; return 0;
field = malloc (sizeof (struct_field_t)); field = malloc (sizeof (struct_field_t));
field->visibility = visibility;
field->name = name; field->name = name;
field->type = type; field->type = type;
field->offset = strct->num_parms; field->offset = strct->num_parms;
@ -102,10 +104,12 @@ new_struct (const char *name)
if (!structs) { if (!structs) {
structs = Hash_NewTable (16381, structs_get_key, 0, 0); structs = Hash_NewTable (16381, structs_get_key, 0, 0);
} }
strct = (struct_t *) Hash_Find (structs, name); if (name) {
if (strct) { strct = (struct_t *) Hash_Find (structs, name);
error (0, "duplicate struct definition"); if (strct) {
return 0; error (0, "duplicate struct definition");
return 0;
}
} }
strct = malloc (sizeof (struct_t)); strct = malloc (sizeof (struct_t));
strct->name = name; strct->name = name;
@ -130,6 +134,17 @@ find_struct (const char *name)
return 0; return 0;
} }
void
copy_struct_fields (type_t *dst, type_t *src)
{
struct_field_t *s;
if (!src)
return;
for (s = src->struct_head; s; s = s->next)
new_struct_field (dst, s->type, s->name, s->visibility);
}
void void
process_enum (expr_t *enm) process_enum (expr_t *enm)
{ {

View file

@ -63,6 +63,7 @@ type_t type_struct = { ev_struct };
// these will be built up further // these will be built up further
type_t type_id = { ev_pointer }; type_t type_id = { ev_pointer };
type_t type_Class = { ev_pointer }; type_t type_Class = { ev_pointer };
type_t type_Protocol = { ev_pointer };
type_t type_SEL = { ev_pointer }; type_t type_SEL = { ev_pointer };
type_t type_IMP = { ev_func, NULL, &type_id, -3, { &type_id, &type_SEL }}; type_t type_IMP = { ev_func, NULL, &type_id, -3, { &type_id, &type_SEL }};
type_t type_method_list = { ev_pointer }; type_t type_method_list = { ev_pointer };
@ -257,29 +258,32 @@ init_types (void)
chain_type (&type_IMP); chain_type (&type_IMP);
type = type_SEL.aux_type = new_struct ("SEL"); type = type_SEL.aux_type = new_struct ("SEL");
new_struct_field (type, &type_string, "sel_id"); new_struct_field (type, &type_string, "sel_id", vis_public);
new_struct_field (type, &type_string, "sel_types"); new_struct_field (type, &type_string, "sel_types", vis_public);
chain_type (&type_SEL); chain_type (&type_SEL);
type_method = new_struct ("obj_method"); type_method = new_struct ("obj_method");
new_struct_field (type_method, &type_SEL, "method_name"); new_struct_field (type_method, &type_SEL, "method_name", vis_public);
new_struct_field (type_method, &type_string, "method_types"); new_struct_field (type_method, &type_string, "method_types", vis_public);
new_struct_field (type_method, &type_IMP, "method_imp"); new_struct_field (type_method, &type_IMP, "method_imp", vis_public);
chain_type (type_method); chain_type (type_method);
type = type_method_list.aux_type = new_struct ("obj_method_list"); type = type_method_list.aux_type = new_struct ("obj_method_list");
new_struct_field (type, &type_method_list, "method_next"); new_struct_field (type, &type_method_list, "method_next", vis_public);
new_struct_field (type, &type_integer, "method_count"); new_struct_field (type, &type_integer, "method_count", vis_public);
new_struct_field (type, array_type (type_method, 1), new_struct_field (type, array_type (type_method, 1),
"method_list"); "method_list", vis_public);
chain_type (&type_method_list); chain_type (&type_method_list);
type = type_Class.aux_type = new_struct ("Class"); type = type_Class.aux_type = new_struct ("Class");
new_struct_field (type, &type_Class, "super_class"); new_struct_field (type, &type_Class, "super_class", vis_public);
new_struct_field (type, &type_Class, "methods"); new_struct_field (type, &type_Class, "methods", vis_public);
chain_type (&type_Class); chain_type (&type_Class);
type = type_Protocol.aux_type = new_struct ("Protocol");
chain_type (&type_Protocol);
type = type_id.aux_type = new_struct ("id"); type = type_id.aux_type = new_struct ("id");
new_struct_field (type, &type_Class, "class_pointer"); new_struct_field (type, &type_Class, "class_pointer", vis_public);
chain_type (&type_id); chain_type (&type_id);
} }