beginnings of array support. no array initialization yet and foo[i] = bar is

broken.
This commit is contained in:
Bill Currie 2001-11-15 00:46:36 +00:00
parent 8aa83d04f3
commit 7d9266a3f0
4 changed files with 74 additions and 12 deletions

View file

@ -66,7 +66,7 @@ typedef struct expr_s {
int pointer_val;
float quaternion_val[4];
int integer_val;
int uinteger_val;
unsigned int uinteger_val;
} e;
} expr_t;
@ -102,6 +102,7 @@ expr_t *function_expr (expr_t *e1, expr_t *e2);
expr_t *return_expr (function_t *f, expr_t *e);
expr_t *conditional_expr (expr_t *cond, expr_t *e1, expr_t *e2);
expr_t *incop_expr (int op, expr_t *e, int postop);
expr_t *array_expr (expr_t *array, expr_t *index);
def_t *emit_statement (int line, opcode_t *op, def_t *var_a, def_t *var_b, def_t *var_c);
void emit_expr (expr_t *e);

View file

@ -793,14 +793,16 @@ field_expr (expr_t *e1, expr_t *e2)
t1 = extract_type (e1);
t2 = extract_type (e2);
if (t1 != ev_entity || t2 != ev_field) {
if ((t1 != ev_entity || t2 != ev_field)
&& (t1 != ev_pointer || (t2 != ev_integer && t2 != ev_uinteger))) {
return error (e1, "type missmatch for .");
}
e = new_binary_expr ('.', e1, e2);
e->e.expr.type = (e2->type == ex_def)
? e2->e.def->type->aux_type
: e2->e.expr.type;
if (t1 == ev_pointer)
e->e.expr.type = get_type (e1)->aux_type;
else
e->e.expr.type = get_type (e2)->aux_type;
return e;
}
@ -986,12 +988,15 @@ type_mismatch:
type = &type_float;
}
if (op == '=' && e1->type == ex_expr && e1->e.expr.op == '.') {
type_t new;
if (t1 == &type_entity) {
type_t new;
memset (&new, 0, sizeof (new));
new.type = ev_pointer;
type = new.aux_type = e1->e.expr.type;
e1->e.expr.type = PR_FindType (&new);
memset (&new, 0, sizeof (new));
new.type = ev_pointer;
type = new.aux_type = e1->e.expr.type;
e1->e.expr.type = PR_FindType (&new);
} else {
}
}
if (!type)
error (e1, "internal error");
@ -1380,3 +1385,28 @@ incop_expr (int op, expr_t *e, int postop)
}
return incop;
}
expr_t *
array_expr (expr_t *array, expr_t *index)
{
type_t *array_type = get_type (array);
type_t *index_type = get_type (index);
expr_t *scale;
int size;
if (array_type->type != ev_pointer || array_type->num_parms < 1)
return error (array, "not an array");
if (index_type != &type_integer && index_type != &type_uinteger)
return error (index, "invalid array index type");
if (index->type >= ex_integer &&
index->e.uinteger_val >= array_type->num_parms)
return error (index, "array index out of bounds");
size = pr_type_size[array_type->aux_type->type];
if (size > 1) {
scale = new_expr ();
scale->type = expr_types [index_type->type];
scale->e.integer_val = size;
index = binary_expr ('*', index, scale);
}
return binary_expr ('.', array, index);
}

View file

@ -80,6 +80,7 @@ find_type (type_t *type, type_t *aux_type)
memset (&new, 0, sizeof (new));
new.type = type->type;
new.aux_type = aux_type;
new.num_parms = 0;
return PR_FindType (&new);
}
@ -171,6 +172,9 @@ PR_GetDef (type_t *type, const char *name, def_t *scope, int *allocate)
} else {
pr.size_fields += pr_type_size[type->aux_type->type];
}
} else if (type->type == ev_pointer) {
*allocate += type->num_parms * pr_type_size[type->aux_type->type];
def->initialized = def->constant = 1;
}
return def;

View file

@ -60,6 +60,7 @@ void finish_function (function_t *f);
void emit_function (function_t *f, expr_t *e);
void build_scope (function_t *f, def_t *func);
type_t *build_type (int is_field, type_t *type);
type_t *build_array_type (int size);
hashtab_t *save_local_inits (def_t *scope);
hashtab_t *merge_local_inits (hashtab_t *dl_1, hashtab_t *dl_2);
@ -99,7 +100,7 @@ typedef struct {
%left '*' '/' '&' '|' '^' '%'
//%left '!' '~'
%right <op> UNARY INCOP
%right '('
%right '(' '['
%left '.'
%token <string_val> NAME STRING_VAL
@ -113,7 +114,7 @@ typedef struct {
%token SWITCH CASE DEFAULT
%token <type> TYPE
%type <type> type opt_func func_parms
%type <type> type opt_func func_parms array_decl
%type <integer_val> opt_field
%type <def> param param_list def_name
%type <def> var_def_item var_def_list
@ -153,6 +154,8 @@ defs
def
: opt_field TYPE
{ current_type = build_type ($1, $2); } var_def_list
| opt_field TYPE { current_type = $2; } array_decl
{ current_type = build_type ($1, $4); } var_def_list
| opt_field TYPE { current_type = $2; } func_parms
{ current_type = build_type ($1, $4); } func_def_list
;
@ -205,6 +208,17 @@ func_parms
}
;
array_decl
: '[' const ']'
{
if ($2->type != ex_integer || $2->e.integer_val < 1)
error (0, "invalid array size");
else
$$ = build_array_type ($2->e.integer_val);
}
| '[' ']' { $$ = build_array_type (0); }
;
var_def_list
: var_def_list ',' var_def_item
| var_def_item
@ -661,6 +675,7 @@ expr
| expr '%' expr { $$ = binary_expr ('%', $1, $3); }
| expr '(' arg_list ')' { $$ = function_expr ($1, $3); }
| expr '(' ')' { $$ = function_expr ($1, 0); }
| expr '[' expr ']' { $$ = array_expr ($1, $3); }
| expr '.' expr { $$ = binary_expr ('.', $1, $3); }
| '+' expr %prec UNARY { $$ = $2; }
| '-' expr %prec UNARY { $$ = unary_expr ('-', $2); }
@ -798,6 +813,18 @@ build_type (int is_field, type_t *type)
}
}
type_t *
build_array_type (int size)
{
type_t new;
memset (&new, 0, sizeof (new));
new.type = ev_pointer;
new.aux_type = current_type;
new.num_parms = size;
return PR_FindType (&new);
}
function_t *
new_function (void)
{