arrays are /almost/ working again

This commit is contained in:
Bill Currie 2002-06-12 22:37:18 +00:00
parent c23a74ecd9
commit 88fc0be127
6 changed files with 100 additions and 34 deletions

View file

@ -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;

View file

@ -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);

View file

@ -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;

View file

@ -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);
}

View file

@ -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;
}

View file

@ -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);