Add "is_math" type check and use for unary +/-.

This commit is contained in:
Bill Currie 2011-01-23 11:12:58 +09:00
parent 341f370662
commit 20b14af024
3 changed files with 20 additions and 2 deletions

View file

@ -125,6 +125,7 @@ const char *encode_params (type_t *type);
void encode_type (struct dstring_s *encoding, type_t *type);
type_t *parse_type (const char *str);
int is_scalar (type_t *type);
int is_math (type_t *type);
int is_struct (type_t *type);
int is_class (type_t *type);
int is_array (type_t *type);

View file

@ -1308,6 +1308,8 @@ unary_expr (int op, expr_t *e)
return e;
switch (op) {
case '-':
if (!is_math (get_type (e)))
return error (e, "invalid type for unary +");
if (is_constant (e)) {
switch (extract_type (e)) {
case ev_string:
@ -1315,7 +1317,7 @@ unary_expr (int op, expr_t *e)
case ev_field:
case ev_func:
case ev_pointer:
return error (e, "invalid type for unary -");
internal_error (e, "type check failed!");
case ev_float:
return new_float_expr (-expr_float (e));
case ev_vector:
@ -1493,7 +1495,9 @@ bitnot_expr:
e->e.expr.type = get_type (e->e.expr.e1)->t.fldptr.type;
return e;
case '+':
return e; // FIXME typechecking
if (!is_math (get_type (e)))
return error (e, "invalid type for unary +");
return e;
}
internal_error (e, 0);
}

View file

@ -73,6 +73,9 @@ type_t type_pointer = { ev_pointer, "pointer", ty_none, {{&type_void}} };
type_t type_quaternion = { ev_quat, "quaternion" };
type_t type_integer = { ev_integer, "integer" };
type_t type_short = { ev_short, "short" };
type_t *type_nil;
// these will be built up further
type_t type_id = { ev_pointer, "id" };
type_t type_Class = { ev_pointer, "Class" };
@ -637,6 +640,14 @@ is_scalar (type_t *type)
return 0;
}
int
is_math (type_t *type)
{
etype_t t = type->type;
return t == ev_vector || t == ev_quat || is_scalar (type);
}
int
is_struct (type_t *type)
{
@ -844,6 +855,7 @@ init_types (void)
{0, 0}
};
type_nil = &type_quaternion;
if (options.code.progsversion == PROG_ID_VERSION) {
// vector can't be part of .zero for v6 progs because for v6 progs,
// .zero is only one word wide.
@ -851,6 +863,7 @@ init_types (void)
// v6 progs don't have quaternions
zero_struct[8].name = 0;
param_struct[8].name = 0;
type_nil = &type_vector;
}
make_structure (0, 'u', zero_struct, &type_zero);