-
Notifications
You must be signed in to change notification settings - Fork 3
/
parser-stmt-expr.c
73 lines (63 loc) · 1.57 KB
/
parser-stmt-expr.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
#include "parser-stmt-expr.h"
#include "config.h"
#include "lexer.h"
#include "parser-expr.h"
#include "parser-priv.h"
#include "parser-stmt.h"
#include "parser-type.h"
#include "style.h"
#include "token.h"
static int
is_loop_stmt(struct parser *pr, const struct token *semi)
{
struct lexer_state s;
struct lexer *lx = pr->pr_lx;
struct token *ident, *lparen, *nx, *rparen;
int peek = 0;
lexer_peek_enter(lx, &s);
if (lexer_if(lx, TOKEN_IDENT, &ident) &&
lexer_if_pair(lx, TOKEN_LPAREN, TOKEN_RPAREN, &lparen, &rparen) &&
lexer_peek(lx, &nx) && nx != semi && token_cmp(rparen, nx) < 0 &&
parser_stmt_peek(pr))
peek = 1;
lexer_peek_leave(lx, &s);
return peek;
}
int
parser_stmt_expr(struct parser *pr, struct doc *dc)
{
struct doc *expr = NULL;
struct token *nx, *semi;
int error;
if (parser_type_peek(pr, NULL, 0) || !parser_expr_peek(pr, &nx))
return parser_none(pr);
nx = token_next(nx);
if (nx->tk_type != TOKEN_SEMI)
return parser_none(pr);
semi = nx;
/*
* Do not confuse a loop construct hidden behind cpp followed by a sole
* statement:
*
* foreach()
* func();
*/
if (is_loop_stmt(pr, semi))
return parser_none(pr);
error = parser_expr(pr, &expr, &(struct parser_expr_arg){
.dc = dc,
.indent = style(pr->pr_st, ContinuationIndentWidth),
});
if (error & HALT)
return parser_fail(pr);
return parser_semi(pr, expr);
}
int
parser_stmt_expr_gnu(struct parser *pr, struct doc *dc)
{
return parser_stmt_block(pr, &(struct parser_stmt_block_arg){
.head = dc,
.tail = dc,
.flags = PARSER_STMT_BLOCK_EXPR_GNU,
});
}