mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2024-11-10 23:32:09 +00:00
Implement "not" logic for while and do-while.
This goes towards complementing the "if not" logic extension. I need to check if fteqcc supports "not" with "while" (the version I have access to at the moment does not), and also whether it would be good to support "not" with "for", and if so, what form the syntax should take.
This commit is contained in:
parent
45a09e195e
commit
cef2136050
4 changed files with 24 additions and 13 deletions
|
@ -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 *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 *build_if_statement (int not, expr_t *test, expr_t *s1, expr_t *els,
|
||||||
expr_t *s2);
|
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 *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 *break_label, expr_t *continue_label);
|
||||||
expr_t *build_for_statement (expr_t *init, expr_t *test, expr_t *next,
|
expr_t *build_for_statement (expr_t *init, expr_t *test, expr_t *next,
|
||||||
expr_t *statement,
|
expr_t *statement,
|
||||||
|
|
|
@ -2337,7 +2337,7 @@ build_if_statement (int not, expr_t *test, expr_t *s1, expr_t *els, expr_t *s2)
|
||||||
}
|
}
|
||||||
|
|
||||||
expr_t *
|
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)
|
expr_t *break_label, expr_t *continue_label)
|
||||||
{
|
{
|
||||||
int line = pr.source_line;
|
int line = pr.source_line;
|
||||||
|
@ -2358,8 +2358,13 @@ build_while_statement (expr_t *test, expr_t *statement,
|
||||||
|
|
||||||
test = convert_bool (test, 1);
|
test = convert_bool (test, 1);
|
||||||
if (test->type != ex_error) {
|
if (test->type != ex_error) {
|
||||||
backpatch (test->e.bool.true_list, l1);
|
if (not) {
|
||||||
backpatch (test->e.bool.false_list, l2);
|
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 (test->e.bool.e, l2);
|
||||||
append_expr (while_expr, test);
|
append_expr (while_expr, test);
|
||||||
}
|
}
|
||||||
|
@ -2371,7 +2376,7 @@ build_while_statement (expr_t *test, expr_t *statement,
|
||||||
}
|
}
|
||||||
|
|
||||||
expr_t *
|
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 *break_label, expr_t *continue_label)
|
||||||
{
|
{
|
||||||
expr_t *l1 = new_label_expr ();
|
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);
|
test = convert_bool (test, 1);
|
||||||
if (test->type != ex_error) {
|
if (test->type != ex_error) {
|
||||||
backpatch (test->e.bool.true_list, l1);
|
if (not) {
|
||||||
backpatch (test->e.bool.false_list, break_label);
|
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 (test->e.bool.e, break_label);
|
||||||
append_expr (do_while_expr, test);
|
append_expr (do_while_expr, test);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1165,15 +1165,16 @@ statement
|
||||||
break_label = $2;
|
break_label = $2;
|
||||||
continue_label = $3;
|
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;
|
break_label = $2;
|
||||||
continue_label = $3;
|
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, continue_label);
|
||||||
break_label = $2;
|
break_label = $2;
|
||||||
continue_label = $3;
|
continue_label = $3;
|
||||||
|
|
|
@ -362,7 +362,7 @@ statement
|
||||||
}
|
}
|
||||||
| WHILE expression DO statement
|
| WHILE expression DO statement
|
||||||
{
|
{
|
||||||
$$ = build_while_statement ($2, $4,
|
$$ = build_while_statement (0, $2, $4,
|
||||||
new_label_expr (),
|
new_label_expr (),
|
||||||
new_label_expr ());
|
new_label_expr ());
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue