more progress

This commit is contained in:
Bill Currie 2002-05-09 20:12:28 +00:00
parent e4f740bf02
commit f2b8dc7e7e
9 changed files with 220 additions and 40 deletions

View file

@ -33,6 +33,8 @@
#define __function_h
typedef struct param_s {
// the first two fields match the first two fiels of keywordarg_t in
// method.h
struct param_s *next;
const char *selector;
type_t *type;

View file

@ -49,20 +49,29 @@ typedef struct {
} methodlist_t;
typedef struct keywordarg_s {
// the first two fields match the first two fiels of param_t in
// functionl.h
struct keywordarg_s *next;
const char *selector;
expr_t *expr;
} keywordarg_t;
struct class_s;
struct category_s;
struct expr_s;
struct dstring_s;
method_t *new_method (type_t *ret_type, param_t *selector, param_t *opt_parms);
void add_method (methodlist_t *methodlist, method_t *method);
def_t *method_def (struct class_s *klass, method_t *method);
def_t *method_def (struct class_s *klass, struct category_s *category,
method_t *method);
keywordarg_t *new_keywordarg (const char *selector, struct expr_s *expr);
struct expr_s *send_message (void);
void selector_name (struct dstring_s *sel_id, keywordarg_t *selector);
void selector_types (struct dstring_s *sel_types, keywordarg_t *selector);
struct def_s *selector_def (const char *sel_id, const char *sel_types);
#endif//__method_h

View file

@ -47,7 +47,11 @@ extern type_t type_uinteger;
extern type_t type_short;
extern type_t type_struct;
extern type_t type_id;
extern type_t type_Class;
extern type_t type_SEL;
extern type_t type_IMP;
extern type_t type_method_list;
extern type_t *type_method;
extern def_t def_void;
extern def_t def_function;
@ -58,4 +62,6 @@ struct type_s *get_typedef (const char *name);
struct type_s *pointer_type (struct type_s *aux);
void print_type (struct type_s *type);
void init_types (void);
#endif//__type_h

View file

@ -32,6 +32,7 @@ static const char rcsid[] =
#include <stdlib.h>
#include <QF/dstring.h>
#include <QF/mathlib.h>
#include <QF/sys.h>
#include <QF/va.h>
@ -147,14 +148,7 @@ get_type (expr_t *e)
case ex_temp:
return e->e.temp.type;
case ex_pointer:
{
type_t new;
memset (&new, 0, sizeof (new));
new.type = ev_pointer;
new.aux_type = e->e.pointer.type;
return find_type (&new);
}
return pointer_type (e->e.pointer.type);
case ex_integer:
if (options.code.progsversion == PROG_ID_VERSION) {
e->type = ex_float;
@ -438,6 +432,15 @@ new_name_expr (const char *name)
return e;
}
expr_t *
new_def_expr (def_t *def)
{
expr_t *e = new_expr ();
e->type = ex_def;
e->e.def = def;
return e;
}
expr_t *
append_expr (expr_t *block, expr_t *e)
{
@ -1477,7 +1480,7 @@ function_expr (expr_t *e1, expr_t *e2)
return error (e1, "more than %d parameters", MAX_PARMS);
}
if (ftype->num_parms < -1) {
if (arg_count > ftype->num_parms + 1) {
if (-arg_count > ftype->num_parms + 1) {
if (!options.traditional)
return error (e1, "too few arguments");
warning (e1, "too few arguments");
@ -1927,7 +1930,16 @@ init_elements (def_t *def, expr_t *eles)
expr_t *
selector_expr (keywordarg_t *selector)
{
return error (0, "not implemented");
dstring_t *sel_id = dstring_newstr ();
dstring_t *sel_types = dstring_newstr ();
expr_t *sel;
selector_name (sel_id, selector);
selector_types (sel_types, selector);
//printf ("'%s' '%s'\n", sel_id->str, sel_types->str);
sel = new_def_expr (selector_def (sel_id->str, sel_types->str));
dstring_delete (sel_id);
dstring_delete (sel_types);
return address_expr (sel, 0, 0);
}
expr_t *
@ -1951,7 +1963,7 @@ message_expr (expr_t *receiver, keywordarg_t *message)
for (m = message; m; m = m->next) {
*a = m->expr;
while ((*a)->next)
while ((*a))
a = &(*a)->next;
}
*a = selector;

View file

@ -79,7 +79,7 @@ parse_params (type_t *type, param_t *parms)
new.aux_type = type;
new.num_parms = 0;
for (p = parms; p; p = p->next, new.num_parms++) {
for (p = parms; p; p = p->next) {
if (new.num_parms > MAX_PARMS) {
error (0, "too many params");
return type;
@ -90,9 +90,9 @@ parse_params (type_t *type, param_t *parms)
abort ();
}
new.num_parms = -(new.num_parms + 1);
break;
} else {
} else if (p->type) {
new.parm_types[new.num_parms] = p->type;
new.num_parms++;
}
}
//print_type (&new); puts("");
@ -111,6 +111,8 @@ build_scope (function_t *f, def_t *func, param_t *params)
for (p = params, i = 0; p; p = p->next, i++) {
if (!p->selector && !p->type && !p->name)
continue; // ellipsis marker
if (!p->type)
continue; // non-param selector
def = PR_GetDef (p->type, p->name, func, func->alloc);
f->parm_ofs[i] = def->ofs;
if (i > 0 && f->parm_ofs[i] < f->parm_ofs[i - 1])

View file

@ -31,6 +31,7 @@ static const char rcsid[] =
"$Id$";
#include "QF/dstring.h"
#include "QF/hash.h"
#include "qfcc.h"
@ -38,7 +39,6 @@ static const char rcsid[] =
#include "method.h"
#include "type.h"
static type_t *send_message_type;
static def_t *send_message_def;
static function_t *send_message_func;
@ -77,21 +77,28 @@ add_method (methodlist_t *methodlist, method_t *method)
}
def_t *
method_def (class_t *klass, method_t *method)
method_def (class_t *klass, category_t *category, method_t *method)
{
dstring_t *str = dstring_newstr ();
dstring_t *sel = dstring_newstr ();
param_t *p;
def_t *def;
char *s;
dsprintf (str, "_%c_%s", method->instance ? 'i' : 'c', klass->name);
for (p = method->selector; p && p->selector; p = p->next) {
dstring_clearstr (sel);
dsprintf (sel, "_%s", p->selector);
dstring_appendstr (str, sel->str);
}
selector_name (sel, (keywordarg_t *)method->selector);
dsprintf (str, "_%c_%s_%s_%s",
method->instance ? 'i' : 'c',
klass->name,
category ? category->name : "",
sel->str);
for (s = str->str; *s; s++)
if (*s == ':')
*s = '_';
//printf ("%s\n", str->str);
// FIXME need a file scope
return PR_GetDef (method->type, str->str, 0, &numpr_globals);
def = PR_GetDef (method->type, str->str, 0, &numpr_globals);
dstring_delete (str);
dstring_delete (sel);
return def;
}
keywordarg_t *
@ -111,11 +118,7 @@ send_message (void)
expr_t *e;
if (!send_message_def) {
send_message_type = parse_params (&type_id,
_reverse_params (new_param (0, &type_id, "receiver"),
_reverse_params (new_param (0, &type_SEL, "selector"),
new_param (0, 0, 0))));
send_message_def = PR_GetDef (send_message_type, "obj_msgSend",
send_message_def = PR_GetDef (&type_IMP, "obj_msgSend",
0, &numpr_globals);
send_message_func = new_function ();
send_message_func->builtin = 0;
@ -128,3 +131,78 @@ send_message (void)
e->e.def = send_message_def;
return e;
}
void
selector_name (dstring_t *sel_id, keywordarg_t *selector)
{
dstring_clearstr (sel_id);
while (selector && selector->selector) {
dstring_appendstr (sel_id, selector->selector);
dstring_appendstr (sel_id, ":");
selector = selector->next;
}
}
void
selector_types (dstring_t *sel_types, keywordarg_t *selector)
{
}
typedef struct {
string_t sel_id;
string_t sel_types;
def_t *def;
} sel_def_t;
static hashtab_t *sel_def_hash;
static unsigned long
sel_def_get_hash (void *_sel_def, void *unused)
{
sel_def_t *sel_def = (sel_def_t*)_sel_def;
unsigned long hash;
hash = Hash_String (G_STRING (sel_def->sel_id))
^ Hash_String (G_STRING (sel_def->sel_types));
return hash;
}
static int
sel_def_compare (void *_sd1, void *_sd2, void *unused)
{
sel_def_t *sd1 = (sel_def_t*)_sd1;
sel_def_t *sd2 = (sel_def_t*)_sd2;
int cmp;
cmp = strcmp (G_STRING (sd1->sel_id), G_STRING (sd2->sel_id)) == 0;
if (cmp)
cmp = strcmp (G_STRING (sd1->sel_types),
G_STRING (sd2->sel_types)) == 0;
return cmp;
}
def_t *
selector_def (const char *_sel_id, const char *_sel_types)
{
string_t sel_id = ReuseString (_sel_id);
string_t sel_types = ReuseString (_sel_types);
sel_def_t _sel_def = {sel_id, sel_types, 0};
sel_def_t *sel_def = &_sel_def;
if (!sel_def_hash) {
sel_def_hash = Hash_NewTable (1021, 0, 0, 0);
Hash_SetHashCompare (sel_def_hash, sel_def_get_hash, sel_def_compare);
}
sel_def = Hash_FindElement (sel_def_hash, sel_def);
if (sel_def)
return sel_def->def;
sel_def = malloc (sizeof (sel_def_t));
sel_def->sel_id = sel_id;
sel_def->sel_types = sel_types;
sel_def->def = PR_NewDef (type_SEL.aux_type, ".imm", 0);
sel_def->def->ofs = PR_NewLocation (type_SEL.aux_type);
G_INT (sel_def->def->ofs) = sel_id;
G_INT (sel_def->def->ofs + 1) = sel_types;
Hash_AddElement (sel_def_hash, sel_def);
return sel_def->def;
}

View file

@ -1020,7 +1020,7 @@ methoddef
methoddecl opt_state_expr
{
$2->instance = 0;
current_def = $2->def = method_def (current_class, $2);
current_def = $2->def = method_def (current_class, 0, $2);
current_params = $2->params;
}
begin_function statement_block end_function
@ -1038,7 +1038,7 @@ methoddef
methoddecl opt_state_expr
{
$2->instance = 1;
current_def = $2->def = method_def (current_class, $2);
current_def = $2->def = method_def (current_class, 0, $2);
current_params = $2->params;
}
begin_function statement_block end_function

View file

@ -486,10 +486,6 @@ PR_BeginCompilation (void)
for (i = 0; i < RESERVED_OFS; i++)
pr_global_defs[i] = &def_void;
// link the function type in so state forward declarations match proper
// type
pr.types = &type_function;
type_function.next = NULL;
pr_error_count = 0;
}
@ -1179,6 +1175,7 @@ main (int argc, char **argv)
PR_Opcode_Init_Tables ();
InitData ();
init_types ();
if (*sourcedir)
snprintf (filename, sizeof (filename), "%s/%s", sourcedir, progs_src);

View file

@ -37,6 +37,7 @@ static const char rcsid[] =
#include "qfcc.h"
#include "function.h"
#include "struct.h"
typedef struct {
const char *name;
@ -59,8 +60,13 @@ type_t type_integer = { ev_integer };
type_t type_uinteger = { ev_uinteger };
type_t type_short = { ev_short };
type_t type_struct = { ev_struct };
type_t type_id = {ev_pointer };
type_t type_SEL = {ev_pointer };
// these will be built up further
type_t type_id = { ev_pointer };
type_t type_Class = { 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_method_list = { ev_pointer };
type_t *type_method;
type_t type_floatfield = { ev_field, NULL, &type_float };
@ -69,6 +75,13 @@ def_t def_function = { &type_function, "temp" };
def_t def_ret, def_parms[MAX_PARMS];
static inline void
chain_type (type_t *type)
{
type->next = pr.types;
pr.types = type;
}
/*
find_type
@ -109,8 +122,8 @@ find_type (type_t *type)
if (!check)
Sys_Error ("find_type: Memory Allocation Failure\n");
*check = *type;
check->next = pr.types;
pr.types = check;
chain_type (check);
return check;
}
@ -165,6 +178,18 @@ pointer_type (type_t *aux)
return find_type (&new);
}
type_t *
array_type (type_t *aux, int size)
{
type_t new;
memset (&new, 0, sizeof (new));
new.type = ev_pointer;
new.aux_type = aux;
new.num_parms = size;
return find_type (&new);
}
void
print_type (type_t *type)
{
@ -209,3 +234,52 @@ print_type (type_t *type)
break;
}
}
void
init_types (void)
{
type_t *type;
chain_type (&type_void);
chain_type (&type_string);
chain_type (&type_float);
chain_type (&type_vector);
chain_type (&type_entity);
chain_type (&type_field);
chain_type (&type_function);
chain_type (&type_pointer);
chain_type (&type_floatfield);
chain_type (&type_quaternion);
chain_type (&type_integer);
chain_type (&type_uinteger);
chain_type (&type_short);
chain_type (&type_struct);
chain_type (&type_IMP);
type = type_SEL.aux_type = new_struct ("SEL");
new_struct_field (type, &type_string, "sel_id");
new_struct_field (type, &type_string, "sel_types");
chain_type (&type_SEL);
type_method = new_struct ("obj_method");
new_struct_field (type_method, &type_SEL, "method_name");
new_struct_field (type_method, &type_string, "method_types");
new_struct_field (type_method, &type_IMP, "method_imp");
chain_type (type_method);
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_integer, "method_count");
new_struct_field (type, array_type (type_method, 1),
"method_list");
chain_type (&type_method_list);
type = type_Class.aux_type = new_struct ("Class");
new_struct_field (type, &type_Class, "super_class");
new_struct_field (type, &type_Class, "methods");
chain_type (&type_Class);
type = type_id.aux_type = new_struct ("id");
new_struct_field (type, &type_Class, "class_pointer");
chain_type (&type_id);
}