diff --git a/tools/qfcc/include/type.h b/tools/qfcc/include/type.h index 7e375f573..0522602b9 100644 --- a/tools/qfcc/include/type.h +++ b/tools/qfcc/include/type.h @@ -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); diff --git a/tools/qfcc/source/expr.c b/tools/qfcc/source/expr.c index 45c5363dc..2c6449582 100644 --- a/tools/qfcc/source/expr.c +++ b/tools/qfcc/source/expr.c @@ -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); } diff --git a/tools/qfcc/source/type.c b/tools/qfcc/source/type.c index 0efca005d..4a1ccd67e 100644 --- a/tools/qfcc/source/type.c +++ b/tools/qfcc/source/type.c @@ -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);