Skip to content

Commit 9fd288b

Browse files
committed
add with compound statement
1 parent d6f693b commit 9fd288b

File tree

3 files changed

+71
-8
lines changed

3 files changed

+71
-8
lines changed

compiler/src/dmd/parse.d

Lines changed: 36 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5777,7 +5777,7 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
57775777

57785778
/*****************************************
57795779
* Input:
5780-
* flags PSxxxx
5780+
* flags = ParseStatementFlags
57815781
* Output:
57825782
* pEndloc if { ... statements ... }, store location of closing brace, otherwise loc of last token of statement
57835783
*/
@@ -6585,20 +6585,48 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
65856585
s = new AST.SynchronizedStatement(loc, exp, _body);
65866586
break;
65876587
}
6588-
case TOK.with_:
6588+
case TOK.with_: // https://dlang.org/spec/statement.html#with-statement
65896589
{
6590-
AST.Expression exp;
6591-
AST.Statement _body;
6592-
Loc endloc = loc;
6590+
Loc withLoc = loc;
65936591

65946592
nextToken();
65956593
check(TOK.leftParenthesis);
6596-
exp = parseExpression();
6594+
AST.Expression exp = parseExpression();
65976595
closeCondition("with", null, exp);
6598-
_body = parseStatement(ParseStatementFlags.scope_, null, &endloc);
6599-
s = new AST.WithStatement(loc, exp, _body, endloc);
6596+
6597+
if (token.value == TOK.colon) // with (Expression) : StatementList
6598+
{
6599+
nextToken();
6600+
6601+
const lookingForElseSave = lookingForElse;
6602+
lookingForElse = Loc.initial;
6603+
6604+
auto statements = new AST.Statements();
6605+
while (token.value != TOK.rightCurly && token.value != TOK.endOfFile)
6606+
{
6607+
statements.push(parseStatement(ParseStatementFlags.curlyScope | ParseStatementFlags.semiOk));
6608+
}
6609+
6610+
lookingForElse = lookingForElseSave;
6611+
6612+
s = new AST.CompoundStatement(loc, statements);
6613+
s = new AST.ScopeStatement(loc, s, token.loc);
6614+
s = new AST.WithStatement(loc, exp, s, withLoc);
6615+
6616+
if (token.value == TOK.endOfFile)
6617+
{
6618+
error(token.loc, "matching `}` expected following compound with statement, not `%s`",
6619+
token.toChars());
6620+
eSink.errorSupplemental(withLoc, "unmatched `with (exp):`");
6621+
s = new AST.ErrorStatement();
6622+
}
6623+
break;
6624+
}
6625+
AST.Statement _body = parseStatement(ParseStatementFlags.scope_, null, &withLoc);
6626+
s = new AST.WithStatement(loc, exp, _body, withLoc);
66006627
break;
66016628
}
6629+
66026630
case TOK.try_:
66036631
{
66046632
AST.Statement _body;

compiler/test/compilable/scope.d

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -375,3 +375,22 @@ struct Result
375375
auto r = Result(&s);
376376
r.save();
377377
}
378+
379+
/********************************************/
380+
381+
void withOmatic()
382+
{
383+
enum E { A, B }
384+
385+
{
386+
with (E):
387+
int i;
388+
if (A)
389+
return;
390+
}
391+
{
392+
with (e)
393+
if (A)
394+
return;
395+
}
396+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
/* TEST_OUTPUT:
2+
---
3+
fail_compilation/withspoon.d(17): Error: matching `}` expected following compound with statement, not `End of File`
4+
fail_compilation/withspoon.d(15): unmatched `with (exp):`
5+
with (E):
6+
^
7+
fail_compilation/withspoon.d(17): Error: matching `}` expected following compound statement, not `End of File`
8+
fail_compilation/withspoon.d(14): unmatched `{`
9+
---
10+
*/
11+
enum E { A, B }
12+
13+
void test2()
14+
{
15+
with (E):
16+
return;

0 commit comments

Comments
 (0)