From 5f97de56d1a9127c08e0356aaba12e2aff3ec133 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Wed, 22 Oct 2003 09:14:53 +0000 Subject: [PATCH] fix a few bugs --- tools/qfcc/source/emit.c | 5 +++++ tools/qfcc/source/expr.c | 36 ++++++++++++++++++++++++------------ tools/qfcc/source/qc-parse.y | 32 ++++++++++++++++++++++++++++++++ 3 files changed, 61 insertions(+), 12 deletions(-) diff --git a/tools/qfcc/source/emit.c b/tools/qfcc/source/emit.c index 898d3e6c4..4c1bec25c 100644 --- a/tools/qfcc/source/emit.c +++ b/tools/qfcc/source/emit.c @@ -440,10 +440,12 @@ build_bool_block (expr_t *block, expr_t *e) switch (e->type) { case ex_bool: build_bool_block (block, e->e.bool.e); + free_tempdefs (); return; case ex_label: e->next = 0; append_expr (block, e); + free_tempdefs (); return; case ex_expr: if (e->e.expr.op == OR || e->e.expr.op == AND) { @@ -456,11 +458,13 @@ build_bool_block (expr_t *block, expr_t *e) e->next = 0; append_expr (block, e); } + free_tempdefs (); return; case ex_uexpr: if (e->e.expr.op == 'g') { e->next = 0; append_expr (block, e); + free_tempdefs (); return; } break; @@ -471,6 +475,7 @@ build_bool_block (expr_t *block, expr_t *e) t = e->next; build_bool_block (block, e); } + free_tempdefs (); return; } break; diff --git a/tools/qfcc/source/expr.c b/tools/qfcc/source/expr.c index e0268f74f..074c53ed7 100644 --- a/tools/qfcc/source/expr.c +++ b/tools/qfcc/source/expr.c @@ -1467,6 +1467,9 @@ backpatch (ex_list_t *list, expr_t *label) int i; expr_t *e; + if (!list) + return; + for (i = 0; i < list->size; i++) { e = list->e[i]; if (e->type == ex_uexpr && e->e.expr.op == 'g') @@ -1537,6 +1540,20 @@ convert_bool (expr_t *e, int block) return e; } +static expr_t * +convert_from_bool (expr_t *e, type_t *type) +{ + if (type == &type_float) + e = conditional_expr (e, new_float_expr (1), new_float_expr (0)); + else if (type == &type_integer) + e = conditional_expr (e, new_integer_expr (1), new_integer_expr (0)); + else if (type == &type_uinteger) + e = conditional_expr (e, new_uinteger_expr (1), new_uinteger_expr (0)); + else + e = error (e, "can't convert from bool value"); + return e; +} + expr_t * bool_expr (int op, expr_t *label, expr_t *e1, expr_t *e2) { @@ -1738,10 +1755,10 @@ binary_expr (int op, expr_t *e1, expr_t *e2) } if (e1->type == ex_bool) - e1 = conditional_expr (e1, new_integer_expr (1), new_integer_expr (0)); + e1 = convert_from_bool (e1, t2); if (e2->type == ex_bool) - e2 = conditional_expr (e2, new_integer_expr (1), new_integer_expr (0)); + e2 = convert_from_bool (e2, t1); if (e1->type == ex_short) { if (t2 == &type_integer) { @@ -2296,16 +2313,8 @@ return_expr (function_t *f, expr_t *e) return error (e, "returning a value for a void function"); warning (e, "returning a value for a void function"); } - if (e->type == ex_bool) { - if (f->def->type->aux_type == &type_float) - e = conditional_expr (e, new_float_expr (1), new_float_expr (0)); - else if (f->def->type->aux_type == &type_integer) - e = conditional_expr (e, new_integer_expr (1), - new_integer_expr (0)); - else if (f->def->type->aux_type == &type_uinteger) - e = conditional_expr (e, new_uinteger_expr (1), - new_uinteger_expr (0)); - } + if (e->type == ex_bool) + e = convert_from_bool (e, f->def->type->aux_type); if (f->def->type->aux_type == &type_float && e->type == ex_integer) { e->type = ex_float; e->e.float_val = e->e.integer_val; @@ -2594,6 +2603,9 @@ assign_expr (expr_t *e1, expr_t *e2) error (e1, "internal error"); abort (); } + if (e2->type == ex_bool) + e2 = convert_from_bool (e2, t1); + if (e2->type == ex_integer) { if (t1 == &type_float || t1 == &type_vector diff --git a/tools/qfcc/source/qc-parse.y b/tools/qfcc/source/qc-parse.y index 04ec87d4f..31d2ad181 100644 --- a/tools/qfcc/source/qc-parse.y +++ b/tools/qfcc/source/qc-parse.y @@ -654,6 +654,11 @@ statement { expr_t *l1 = new_label_expr (); expr_t *l2 = break_label; + int line = pr.source_line; + string_t file = pr.source_file; + + pr.source_line = $5->line; + pr.source_file = $5->file; restore_local_inits ($7); free_local_inits ($7); @@ -673,10 +678,18 @@ statement break_label = $2; continue_label = $3; + + pr.source_line = line; + pr.source_file = file; } | DO break_label continue_label statement WHILE '(' expr ')' ';' { expr_t *l1 = new_label_expr (); + int line = pr.source_line; + string_t file = pr.source_file; + + pr.source_line = $7->line; + pr.source_file = $7->file; $$ = new_block_expr (); @@ -692,6 +705,9 @@ statement break_label = $2; continue_label = $3; + + pr.source_line = line; + pr.source_file = file; } | LOCAL type { @@ -708,6 +724,11 @@ statement { expr_t *tl = new_label_expr (); expr_t *fl = new_label_expr (); + int line = pr.source_line; + string_t file = pr.source_file; + + pr.source_line = $3->line; + pr.source_file = $3->file; $$ = new_block_expr (); @@ -722,6 +743,9 @@ statement append_expr ($$, $6); append_expr ($$, fl); + + pr.source_line = line; + pr.source_file = file; } | IF '(' expr ')' save_inits statement ELSE { @@ -736,6 +760,11 @@ statement expr_t *e; hashtab_t *merged; hashtab_t *else_ini; + int line = pr.source_line; + string_t file = pr.source_file; + + pr.source_line = $3->line; + pr.source_file = $3->file; $$ = new_block_expr (); @@ -764,6 +793,9 @@ statement free_local_inits (merged); free_local_inits (else_ini); free_local_inits ($8); + + pr.source_line = line; + pr.source_file = file; } | FOR break_label continue_label '(' opt_expr ';' opt_expr ';' opt_expr ')' save_inits statement