mirror of
https://github.com/DarkPlacesEngine/gmqcc.git
synced 2025-03-21 02:10:53 +00:00
do-while loops
This commit is contained in:
parent
4d47c40cb9
commit
339c0e5870
1 changed files with 65 additions and 0 deletions
65
parser.c
65
parser.c
|
@ -1114,6 +1114,67 @@ static bool parser_parse_while(parser_t *parser, ast_block *block, ast_expressio
|
|||
return true;
|
||||
}
|
||||
|
||||
static bool parser_parse_dowhile(parser_t *parser, ast_block *block, ast_expression **out)
|
||||
{
|
||||
ast_loop *aloop;
|
||||
ast_expression *cond, *ontrue;
|
||||
|
||||
lex_ctx ctx = parser_ctx(parser);
|
||||
|
||||
/* skip the 'do' and get the body */
|
||||
if (!parser_next(parser) || parser->tok != '(') {
|
||||
parseerror(parser, "expected loop body");
|
||||
return false;
|
||||
}
|
||||
ontrue = parser_parse_statement_or_block(parser);
|
||||
if (!ontrue)
|
||||
return false;
|
||||
|
||||
/* expect the "while" */
|
||||
if (parser->tok != TOKEN_KEYWORD ||
|
||||
!strcmp(parser_tokval(parser), "while"))
|
||||
{
|
||||
parseerror(parser, "expected 'while' and condition");
|
||||
ast_delete(ontrue);
|
||||
return false;
|
||||
}
|
||||
|
||||
/* skip the 'while' and check for opening paren */
|
||||
if (!parser_next(parser) || parser->tok != '(') {
|
||||
parseerror(parser, "expected 'while' condition in parenthesis");
|
||||
ast_delete(ontrue);
|
||||
return false;
|
||||
}
|
||||
/* parse into the expression */
|
||||
if (!parser_next(parser)) {
|
||||
parseerror(parser, "expected 'while' condition after opening paren");
|
||||
ast_delete(ontrue);
|
||||
return false;
|
||||
}
|
||||
/* parse the condition */
|
||||
cond = parser_expression_leave(parser);
|
||||
if (!cond)
|
||||
return false;
|
||||
/* closing paren */
|
||||
if (parser->tok != ')') {
|
||||
parseerror(parser, "expected closing paren after 'while' condition");
|
||||
ast_delete(ontrue);
|
||||
ast_delete(cond);
|
||||
return false;
|
||||
}
|
||||
/* parse on */
|
||||
if (!parser_next(parser)) {
|
||||
parseerror(parser, "parse error");
|
||||
ast_delete(ontrue);
|
||||
ast_delete(cond);
|
||||
return false;
|
||||
}
|
||||
|
||||
aloop = ast_loop_new(ctx, NULL, NULL, cond, NULL, ontrue);
|
||||
*out = (ast_expression*)aloop;
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool parser_parse_for(parser_t *parser, ast_block *block, ast_expression **out)
|
||||
{
|
||||
ast_loop *aloop;
|
||||
|
@ -1304,6 +1365,10 @@ static bool parser_parse_statement(parser_t *parser, ast_block *block, ast_expre
|
|||
{
|
||||
return parser_parse_while(parser, block, out);
|
||||
}
|
||||
else if (!strcmp(parser_tokval(parser), "do"))
|
||||
{
|
||||
return parser_parse_dowhile(parser, block, out);
|
||||
}
|
||||
else if (!strcmp(parser_tokval(parser), "for"))
|
||||
{
|
||||
return parser_parse_for(parser, block, out);
|
||||
|
|
Loading…
Reference in a new issue