mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-03-19 17:01:46 +00:00
beginnings of array support. no array initialization yet and foo[i] = bar is
broken.
This commit is contained in:
parent
8aa83d04f3
commit
7d9266a3f0
4 changed files with 74 additions and 12 deletions
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue