mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-02-21 11:11:37 +00:00
more progress
This commit is contained in:
parent
f2b8dc7e7e
commit
2cd716176a
10 changed files with 372 additions and 229 deletions
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue