diff --git a/tools/qfcc/include/expr.h b/tools/qfcc/include/expr.h index a3348e9d7..819969afc 100644 --- a/tools/qfcc/include/expr.h +++ b/tools/qfcc/include/expr.h @@ -600,9 +600,9 @@ expr_t *pointer_expr (expr_t *pointer); expr_t *address_expr (expr_t *e1, expr_t *e2, struct type_s *t); expr_t *build_if_statement (int not, expr_t *test, expr_t *s1, expr_t *els, expr_t *s2); -expr_t *build_while_statement (expr_t *test, expr_t *statement, +expr_t *build_while_statement (int not, expr_t *test, expr_t *statement, expr_t *break_label, expr_t *continue_label); -expr_t *build_do_while_statement (expr_t *statement, expr_t *test, +expr_t *build_do_while_statement (expr_t *statement, int not, expr_t *test, expr_t *break_label, expr_t *continue_label); expr_t *build_for_statement (expr_t *init, expr_t *test, expr_t *next, expr_t *statement, diff --git a/tools/qfcc/source/expr.c b/tools/qfcc/source/expr.c index ff1ebab3e..67307b0e2 100644 --- a/tools/qfcc/source/expr.c +++ b/tools/qfcc/source/expr.c @@ -2337,7 +2337,7 @@ build_if_statement (int not, expr_t *test, expr_t *s1, expr_t *els, expr_t *s2) } expr_t * -build_while_statement (expr_t *test, expr_t *statement, +build_while_statement (int not, expr_t *test, expr_t *statement, expr_t *break_label, expr_t *continue_label) { int line = pr.source_line; @@ -2358,8 +2358,13 @@ build_while_statement (expr_t *test, expr_t *statement, test = convert_bool (test, 1); if (test->type != ex_error) { - backpatch (test->e.bool.true_list, l1); - backpatch (test->e.bool.false_list, l2); + if (not) { + backpatch (test->e.bool.true_list, l2); + backpatch (test->e.bool.false_list, l1); + } else { + backpatch (test->e.bool.true_list, l1); + backpatch (test->e.bool.false_list, l2); + } append_expr (test->e.bool.e, l2); append_expr (while_expr, test); } @@ -2371,7 +2376,7 @@ build_while_statement (expr_t *test, expr_t *statement, } expr_t * -build_do_while_statement (expr_t *statement, expr_t *test, +build_do_while_statement (expr_t *statement, int not, expr_t *test, expr_t *break_label, expr_t *continue_label) { expr_t *l1 = new_label_expr (); @@ -2390,8 +2395,13 @@ build_do_while_statement (expr_t *statement, expr_t *test, test = convert_bool (test, 1); if (test->type != ex_error) { - backpatch (test->e.bool.true_list, l1); - backpatch (test->e.bool.false_list, break_label); + if (not) { + backpatch (test->e.bool.true_list, break_label); + backpatch (test->e.bool.false_list, l1); + } else { + backpatch (test->e.bool.true_list, l1); + backpatch (test->e.bool.false_list, break_label); + } append_expr (test->e.bool.e, break_label); append_expr (do_while_expr, test); } diff --git a/tools/qfcc/source/qc-parse.y b/tools/qfcc/source/qc-parse.y index 7304f7f0e..14937a811 100644 --- a/tools/qfcc/source/qc-parse.y +++ b/tools/qfcc/source/qc-parse.y @@ -1165,15 +1165,16 @@ statement break_label = $2; continue_label = $3; } - | WHILE break_label continue_label '(' texpr ')' statement + | WHILE break_label continue_label not '(' texpr ')' statement { - $$ = build_while_statement ($5, $7, break_label, continue_label); + $$ = build_while_statement ($4, $6, $8, break_label, + continue_label); break_label = $2; continue_label = $3; } - | DO break_label continue_label statement WHILE '(' texpr ')' ';' + | DO break_label continue_label statement WHILE not '(' texpr ')' ';' { - $$ = build_do_while_statement ($4, $7, + $$ = build_do_while_statement ($4, $6, $8, break_label, continue_label); break_label = $2; continue_label = $3; diff --git a/tools/qfcc/source/qp-parse.y b/tools/qfcc/source/qp-parse.y index a2b94acea..9731402a5 100644 --- a/tools/qfcc/source/qp-parse.y +++ b/tools/qfcc/source/qp-parse.y @@ -362,7 +362,7 @@ statement } | WHILE expression DO statement { - $$ = build_while_statement ($2, $4, + $$ = build_while_statement (0, $2, $4, new_label_expr (), new_label_expr ()); }