mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-01-17 22:50:51 +00:00
arrays are /almost/ working again
This commit is contained in:
parent
c23a74ecd9
commit
88fc0be127
6 changed files with 100 additions and 34 deletions
|
@ -35,7 +35,7 @@ typedef enum {
|
|||
ev_entity,
|
||||
ev_field,
|
||||
ev_func,
|
||||
ev_pointer,
|
||||
ev_pointer, // end of v6 types
|
||||
ev_quaternion,
|
||||
ev_integer,
|
||||
ev_uinteger,
|
||||
|
@ -44,6 +44,7 @@ typedef enum {
|
|||
ev_object,
|
||||
ev_class,
|
||||
ev_sel,
|
||||
ev_array,
|
||||
|
||||
ev_type_count // not a type, gives number of types
|
||||
} etype_t;
|
||||
|
|
|
@ -70,10 +70,11 @@ int pr_type_size[ev_type_count] = {
|
|||
1, // ev_integer
|
||||
1, // ev_uinteger
|
||||
0, // ev_short value in opcode
|
||||
1, // ev_struct variable
|
||||
1, // ev_object variable
|
||||
1, // ev_class variable
|
||||
0, // ev_struct variable
|
||||
0, // ev_object variable
|
||||
0, // ev_class variable
|
||||
2, // ev_sel
|
||||
0, // ev_array variable
|
||||
};
|
||||
|
||||
const char *pr_type_name[ev_type_count] = {
|
||||
|
@ -93,6 +94,7 @@ const char *pr_type_name[ev_type_count] = {
|
|||
"object",
|
||||
"Class",
|
||||
"SEL",
|
||||
"array",
|
||||
};
|
||||
|
||||
ddef_t *ED_FieldAtOfs (progs_t * pr, int ofs);
|
||||
|
|
|
@ -57,6 +57,8 @@ static const char rcsid[] =
|
|||
|
||||
def_t *emit_sub_expr (expr_t *e, def_t *dest);
|
||||
|
||||
static expr_t zero;
|
||||
|
||||
void
|
||||
add_statement_ref (def_t *def, dstatement_t *st, reloc_type type)
|
||||
{
|
||||
|
@ -247,7 +249,8 @@ emit_assign_expr (int oper, expr_t *e)
|
|||
def_b = emit_sub_expr (e2, 0);
|
||||
if (e->rvalue && def_b->managed)
|
||||
def_b->users++;
|
||||
if (e1->type == ex_expr && extract_type (e1->e.expr.e1) == ev_pointer) {
|
||||
if (e1->type == ex_expr && extract_type (e1->e.expr.e1) == ev_pointer
|
||||
&& e1->e.expr.e1->type < ex_string) {
|
||||
def_a = emit_sub_expr (e1->e.expr.e1, 0);
|
||||
def_c = emit_sub_expr (e1->e.expr.e2, 0);
|
||||
op = opcode_find (operator, def_b, def_a, def_c);
|
||||
|
@ -285,13 +288,59 @@ emit_bind_expr (expr_t *e1, expr_t *e2)
|
|||
return e2->e.temp.def;
|
||||
}
|
||||
|
||||
def_t *
|
||||
emit_address_expr (expr_t *e)
|
||||
{
|
||||
def_t *def_a, *def_b, *d;
|
||||
opcode_t *op;
|
||||
|
||||
def_a = emit_sub_expr (e->e.expr.e1, 0);
|
||||
def_b = emit_sub_expr (e->e.expr.e2, 0);
|
||||
op = opcode_find ("&", def_a, def_b, 0);
|
||||
d = emit_statement (e->line, op, def_a, def_b, 0);
|
||||
return d;
|
||||
}
|
||||
|
||||
def_t *
|
||||
emit_deref_expr (expr_t *e, def_t *dest)
|
||||
{
|
||||
def_t *d;
|
||||
type_t *type = e->e.expr.type;
|
||||
|
||||
e = e->e.expr.e1;
|
||||
if (!dest && (e->type != ex_pointer
|
||||
|| !(e->e.pointer.val > 0
|
||||
&& e->e.pointer.val < 65536))) {
|
||||
dest = get_tempdef (type, current_scope);
|
||||
dest->users += 2;
|
||||
}
|
||||
print_expr (e); printf ("%p\n", dest);
|
||||
if (e->type == ex_expr
|
||||
&& e->e.expr.op == '&'
|
||||
&& e->e.expr.e1->type < ex_string)
|
||||
e->e.expr.op = '.';
|
||||
d = emit_sub_expr (e, dest);
|
||||
if (dest && d != dest) {
|
||||
def_t *z;
|
||||
opcode_t *op;
|
||||
|
||||
zero.type = ex_short;
|
||||
z = emit_sub_expr (&zero, 0);
|
||||
op = opcode_find (".", d, z, dest);
|
||||
return emit_statement (e->line, op, d, z, dest);
|
||||
} else {
|
||||
if (!d->name)
|
||||
d->type = type;
|
||||
}
|
||||
return d;
|
||||
}
|
||||
|
||||
def_t *
|
||||
emit_sub_expr (expr_t *e, def_t *dest)
|
||||
{
|
||||
opcode_t *op;
|
||||
const char *operator;
|
||||
def_t *def_a, *def_b, *d = 0;
|
||||
static expr_t zero;
|
||||
def_t *tmp = 0;
|
||||
|
||||
switch (e->type) {
|
||||
|
@ -319,6 +368,10 @@ emit_sub_expr (expr_t *e, def_t *dest)
|
|||
d->users++;
|
||||
break;
|
||||
}
|
||||
if (e->e.expr.op == '&' && e->e.expr.type->type == ev_pointer) {
|
||||
d = emit_address_expr (e);
|
||||
break;
|
||||
}
|
||||
if (e->e.expr.e1->type == ex_block
|
||||
&& e->e.expr.e1->e.block.is_call) {
|
||||
def_b = emit_sub_expr (e->e.expr.e2, 0);
|
||||
|
@ -377,20 +430,7 @@ emit_sub_expr (expr_t *e, def_t *dest)
|
|||
}
|
||||
break;
|
||||
case '.':
|
||||
if (!dest
|
||||
&& (e->e.expr.e1->type != ex_pointer
|
||||
|| !(e->e.expr.e1->e.pointer.val > 0
|
||||
&& e->e.expr.e1->e.pointer.val < 65536))) {
|
||||
dest = get_tempdef (e->e.expr.type, current_scope);
|
||||
dest->users += 2;
|
||||
}
|
||||
if (e->e.expr.e1->type == ex_expr
|
||||
&& e->e.expr.e1->e.expr.op == '&')
|
||||
e->e.expr.e1->e.expr.op = '.';
|
||||
d = emit_sub_expr (e->e.expr.e1, dest);
|
||||
if (!d->name)
|
||||
d->type = e->e.expr.type;
|
||||
return d;
|
||||
return emit_deref_expr (e, dest);
|
||||
case 'C':
|
||||
def_a = emit_sub_expr (e->e.expr.e1, 0);
|
||||
if (def_a->type->type == ev_pointer
|
||||
|
@ -428,7 +468,8 @@ emit_sub_expr (expr_t *e, def_t *dest)
|
|||
case ex_pointer:
|
||||
if (e->e.pointer.val > 0 && e->e.pointer.val < 65536
|
||||
&& e->e.pointer.type->type != ev_struct) {
|
||||
d = new_def (e->e.pointer.type, 0, current_scope);
|
||||
d = new_def (pointer_type (e->e.pointer.type), 0,
|
||||
current_scope);
|
||||
d->ofs = e->e.short_val;
|
||||
d->absolute = e->e.pointer.abs;
|
||||
d->users = 1;
|
||||
|
|
|
@ -103,6 +103,7 @@ type_t *types[] = {
|
|||
&type_void, // FIXME what type?
|
||||
&type_void, // FIXME what type?
|
||||
&type_SEL,
|
||||
&type_void, // FIXME what type?
|
||||
};
|
||||
|
||||
expr_type expr_types[] = {
|
||||
|
@ -122,6 +123,7 @@ expr_type expr_types[] = {
|
|||
ex_nil, // ev_object
|
||||
ex_nil, // ev_class
|
||||
ex_nil, // ev_sel
|
||||
ex_nil, // ev_array
|
||||
};
|
||||
|
||||
void
|
||||
|
@ -1072,6 +1074,7 @@ expr_t *
|
|||
test_expr (expr_t *e, int test)
|
||||
{
|
||||
expr_t *new = 0;
|
||||
etype_t type;
|
||||
|
||||
if (e->type == ex_error)
|
||||
return e;
|
||||
|
@ -1081,7 +1084,7 @@ test_expr (expr_t *e, int test)
|
|||
if (!test)
|
||||
return unary_expr ('!', e);
|
||||
|
||||
switch (extract_type (e)) {
|
||||
switch (type = extract_type (e)) {
|
||||
case ev_type_count:
|
||||
error (e, "internal error");
|
||||
abort ();
|
||||
|
@ -1129,7 +1132,8 @@ test_expr (expr_t *e, int test)
|
|||
case ev_object:
|
||||
case ev_class:
|
||||
case ev_sel:
|
||||
return error (e, "struct cannot be tested");
|
||||
case ev_array:
|
||||
return error (e, "%s cannot be tested", pr_type_name[type]);
|
||||
}
|
||||
new->line = e->line;
|
||||
new->file = e->file;
|
||||
|
@ -1748,7 +1752,7 @@ array_expr (expr_t *array, expr_t *index)
|
|||
if (index->type == ex_error)
|
||||
return index;
|
||||
|
||||
if (array_type->type != ev_pointer || array_type->num_parms < 1)
|
||||
if (array_type->type != ev_pointer && array_type->type != ev_array)
|
||||
return error (array, "not an array");
|
||||
if (index_type != &type_integer && index_type != &type_uinteger)
|
||||
return error (index, "invalid array index type");
|
||||
|
@ -1769,9 +1773,14 @@ array_expr (expr_t *array, expr_t *index)
|
|||
&& index->e.uinteger_val < 32768)) {
|
||||
index->type = ex_short;
|
||||
}
|
||||
if (array_type->type == ev_array) {
|
||||
e = address_expr (array, index, array_type->aux_type);
|
||||
} else {
|
||||
e = new_binary_expr ('.', array, index);
|
||||
e->e.expr.type = pointer_type (array_type->aux_type);
|
||||
return unary_expr ('.', e);
|
||||
}
|
||||
e = unary_expr ('.', e);
|
||||
return e;
|
||||
}
|
||||
|
||||
expr_t *
|
||||
|
@ -1789,7 +1798,7 @@ address_expr (expr_t *e1, expr_t *e2, type_t *t)
|
|||
switch (e1->type) {
|
||||
case ex_def:
|
||||
type = e1->e.def->type;
|
||||
if (type->type == ev_struct) {
|
||||
if (type->type == ev_struct || type->type == ev_array) {
|
||||
int abs = e1->e.def->global;
|
||||
def_t *def = e1->e.def;
|
||||
|
||||
|
@ -1930,13 +1939,15 @@ assign_expr (expr_t *e1, expr_t *e2)
|
|||
e = e2->e.expr.e1;
|
||||
if (e->type != ex_pointer
|
||||
|| !(e->e.pointer.val > 0 && e->e.pointer.val < 65536)) {
|
||||
if (e->type == ex_expr && e->e.expr.op == '&'
|
||||
&& e->e.expr.type->type == ev_pointer
|
||||
&& e->e.expr.e1->type < ex_string) {
|
||||
e2 = e;
|
||||
if (e2->type == ex_expr && e2->e.expr.op == '&'
|
||||
&& e2->e.expr.type->type == ev_pointer)
|
||||
e2->e.expr.op = '.';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!type)
|
||||
error (e1, "internal error");
|
||||
|
||||
|
@ -1979,7 +1990,7 @@ init_elements (def_t *def, expr_t *eles)
|
|||
{
|
||||
expr_t *e;
|
||||
int count, i;
|
||||
float *g = &G_FLOAT (G_INT (def->ofs));
|
||||
pr_type_t *g = G_POINTER (pr_type_t, def->ofs);
|
||||
|
||||
for (count = 0, e = eles->e.block.head; e; count++, e = e->next)
|
||||
if (e->type == ex_error)
|
||||
|
@ -1997,7 +2008,7 @@ init_elements (def_t *def, expr_t *eles)
|
|||
g += type_size (def->type->aux_type);
|
||||
} else {
|
||||
if (e->type == ex_string) {
|
||||
*(int*)g = ReuseString (e->e.string_val);
|
||||
g->string_var = ReuseString (e->e.string_val);
|
||||
} else {
|
||||
memcpy (g, &e->e, type_size (get_type (e)) * 4);
|
||||
}
|
||||
|
|
|
@ -212,7 +212,7 @@ array_type (type_t *aux, int size)
|
|||
type_t new;
|
||||
|
||||
memset (&new, 0, sizeof (new));
|
||||
new.type = ev_pointer;
|
||||
new.type = ev_array;
|
||||
new.aux_type = aux;
|
||||
new.num_parms = size;
|
||||
return find_type (&new);
|
||||
|
@ -342,6 +342,12 @@ _encode_type (dstring_t *encoding, type_t *type, int level)
|
|||
case ev_sel:
|
||||
dstring_appendstr (encoding, ":");
|
||||
break;
|
||||
case ev_array:
|
||||
dstring_appendstr (encoding, "[");
|
||||
dstring_appendstr (encoding, va ("%d ", type->num_parms));
|
||||
//XXX dstring_appendstr (encoding, name);
|
||||
dstring_appendstr (encoding, "]");
|
||||
break;
|
||||
case ev_type_count:
|
||||
dstring_appendstr (encoding, "?");
|
||||
break;
|
||||
|
@ -415,6 +421,8 @@ type_size (type_t *type)
|
|||
field = field->next)
|
||||
size += type_size (field->type);
|
||||
return size;
|
||||
case ev_array:
|
||||
return type->num_parms * type_size (type->aux_type);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -48,10 +48,13 @@ dump_strings (progs_t *pr)
|
|||
int i = 0;
|
||||
char *s = pr->pr_strings;
|
||||
|
||||
printf ("%d ", 0);
|
||||
while (i++ < pr->pr_stringsize) {
|
||||
switch (*s) {
|
||||
case 0:
|
||||
fputs ("\n", stdout);
|
||||
if (i < pr->pr_stringsize)
|
||||
printf ("%d ", i);
|
||||
break;
|
||||
case 9:
|
||||
fputs ("\\t", stdout);
|
||||
|
|
Loading…
Reference in a new issue