fix numberous integer <-> float errors

type check function args in the correct order
This commit is contained in:
Bill Currie 2001-07-23 05:31:49 +00:00
parent b8874cab1c
commit 4b744b6be5
1 changed files with 57 additions and 40 deletions

View File

@ -507,7 +507,6 @@ do_op_integer (int op, expr_t *e1, expr_t *e2)
i1 = e1->e.integer_val; i1 = e1->e.integer_val;
i2 = e2->e.integer_val; i2 = e2->e.integer_val;
printf ("%d %s %d\n", i1, get_op_string (op), i2);
switch (op) { switch (op) {
case '+': case '+':
@ -637,8 +636,11 @@ test_expr (expr_t *e, int test)
new->type = ex_string; new->type = ex_string;
break; break;
case ev_integer: case ev_integer:
case ev_float:
return e; return e;
case ev_float:
new = new_expr ();
new->type = ex_float;
break;
case ev_vector: case ev_vector:
new = new_expr (); new = new_expr ();
new->type = ex_vector; new->type = ex_vector;
@ -667,10 +669,19 @@ test_expr (expr_t *e, int test)
return binary_expr (NE, e, new); return binary_expr (NE, e, new);
} }
void
convert_int (expr_t *e)
{
e->type = ex_float;
e->e.float_val = e->e.integer_val;
}
expr_t * expr_t *
binary_expr (int op, expr_t *e1, expr_t *e2) binary_expr (int op, expr_t *e1, expr_t *e2)
{ {
etype_t t1, t2; etype_t t1, t2;
type_t *type = 0;
expr_t *e;
if (op == '.') if (op == '.')
return field_expr (e1, e2); return field_expr (e1, e2);
@ -680,6 +691,23 @@ binary_expr (int op, expr_t *e1, expr_t *e2)
e2 = test_expr (e2, true); e2 = test_expr (e2, true);
} }
t1 = get_type (e1);
t2 = get_type (e2);
if (t1 == ev_void || t2 == ev_void) {
error (e1, "internal error");
abort ();
}
if (e1->type == ex_integer
&& (t2 == ev_float || t2 == ev_vector || t2 == ev_quaternion)) {
convert_int (e1);
t1 = ev_float;
} else if (e2->type == ex_integer
&& (t1 == ev_float || t1 == ev_vector || t1 == ev_quaternion)) {
convert_int (e2);
t2 = ev_float;
}
if (e1->type >= ex_string && e2->type >= ex_string) if (e1->type >= ex_string && e2->type >= ex_string)
return binary_const (op, e1, e2); return binary_const (op, e1, e2);
@ -688,60 +716,49 @@ binary_expr (int op, expr_t *e1, expr_t *e2)
warning (e1, "ambiguous logic. Suggest explicit parentheses with expressions involving ! and %c", op); warning (e1, "ambiguous logic. Suggest explicit parentheses with expressions involving ! and %c", op);
} }
t1 = get_type (e1); if (t1 != t2) {
t2 = get_type (e2);
if (t1 == ev_void || t2 == ev_void) {
error (e1, "internal error");
abort ();
}
if (t1 == t2) {
expr_t *e = new_binary_expr (op, e1, e2);
if ((op >= OR && op <= GT) || (op == '*' && t1 == ev_vector))
e->e.expr.type = &type_integer;
else
e->e.expr.type = types[t1];
if (op == '=' && e1->type == ex_expr && e1->e.expr.op == '.') {
e1->e.expr.type = &type_pointer;
}
return e;
} else {
switch (t1) { switch (t1) {
case ev_float: case ev_float:
if (t2 == ev_vector) { if (t2 == ev_vector) {
expr_t *e = new_binary_expr (op, e1, e2); type = &type_vector;
e->e.expr.type = &type_vector;
return e;
} else if (e2->type == ex_integer) {
expr_t *e = new_binary_expr (op, e1, e2);
e->e.expr.type = &type_float;
e2->type = ex_float;
e2->e.float_val = e2->e.integer_val;
return e;
} else { } else {
goto type_mismatch; goto type_mismatch;
} }
break;
case ev_vector: case ev_vector:
if (t2 == ev_float) { if (t2 == ev_float) {
expr_t *e = new_binary_expr (op, e1, e2); type = &type_vector;
e->e.expr.type = &type_vector;
return e;
} else { } else {
goto type_mismatch; goto type_mismatch;
} }
break;
case ev_field: case ev_field:
if (e1->e.expr.type->aux_type->type == t2) { if (e1->e.expr.type->aux_type->type == t2) {
expr_t *e = new_binary_expr (op, e1, e2); type = e1->e.expr.type->aux_type;
e->e.expr.type = e->e.expr.type->aux_type;
return e;
} else { } else {
goto type_mismatch; goto type_mismatch;
} }
break;
default: default:
type_mismatch: type_mismatch:
return type_mismatch (e1, e2, op); return type_mismatch (e1, e2, op);
} }
} else {
type = types[t1];
} }
if ((op >= OR && op <= GT) || op == '>' || op == '<')
type = &type_integer;
else if (op == '*' && t1 == ev_vector && t2 == ev_vector)
type = &type_float;
if (op == '=' && e1->type == ex_expr && e1->e.expr.op == '.') {
e1->e.expr.type = &type_pointer;
}
if (!type)
error (e1, "internal error");
e = new_binary_expr (op, e1, e2);
e->e.expr.type = type;
return e;
} }
expr_t * expr_t *
@ -800,7 +817,7 @@ unary_expr (int op, expr_t *e)
case ex_def: case ex_def:
{ {
expr_t *n = new_unary_expr (op, e); expr_t *n = new_unary_expr (op, e);
n->e.expr.type = &type_float; n->e.expr.type = &type_integer;
return n; return n;
} }
case ex_integer: case ex_integer:
@ -891,23 +908,23 @@ function_expr (expr_t *e1, expr_t *e2)
} else if (parm_count < ftype->num_parms) { } else if (parm_count < ftype->num_parms) {
return error (e1, "too few arguments"); return error (e1, "too few arguments");
} }
for (i = 0, e = e2; i < parm_count; i++, e = e->next) { for (i = parm_count, e = e2; i > 0; i--, e = e->next) {
type_t *t; type_t *t;
if (e->type == ex_expr) { if (e->type == ex_expr) {
t = e->e.expr.type; t = e->e.expr.type;
} else if (e->type == ex_def) { } else if (e->type == ex_def) {
t = e->e.def->type; t = e->e.def->type;
} else { } else {
if (ftype->parm_types[i] == &type_float if (ftype->parm_types[i - 1] == &type_float
&& e->type == ex_integer) { && e->type == ex_integer) {
e->type = ex_float; e->type = ex_float;
e->e.float_val = e->e.integer_val; e->e.float_val = e->e.integer_val;
} }
t = types[get_type (e)]; t = types[get_type (e)];
} }
if (t != ftype->parm_types[i]) if (t != ftype->parm_types[i - 1])
err = error (e, "type mismatch for parameter %d of %s", err = error (e, "type mismatch for parameter %d of %s",
i + 1, e1->e.def->name); i, e1->e.def->name);
} }
if (err) if (err)
return err; return err;