mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2024-11-26 22:31:05 +00:00
more progress
This commit is contained in:
parent
e4f740bf02
commit
f2b8dc7e7e
9 changed files with 220 additions and 40 deletions
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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])
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue