Skip to content

Commit

Permalink
add with compound statement
Browse files Browse the repository at this point in the history
  • Loading branch information
WalterBright committed Jan 16, 2025
1 parent d6f693b commit 00db26d
Show file tree
Hide file tree
Showing 4 changed files with 96 additions and 8 deletions.
24 changes: 24 additions & 0 deletions changelog/dmd.with-colon.dd
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
Adds the with-colon statement.

Like at the global declarations level, a `with (expression) :` can be used to create
a scope until a `}` is encountered.

---
{
with (E):
statement;
statement;
}
---

which is equivalent to:

---
{
with (E)
{
statement;
statement;
}
}
---
44 changes: 36 additions & 8 deletions compiler/src/dmd/parse.d
Original file line number Diff line number Diff line change
Expand Up @@ -5777,7 +5777,7 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer

/*****************************************
* Input:
* flags PSxxxx
* flags = ParseStatementFlags
* Output:
* pEndloc if { ... statements ... }, store location of closing brace, otherwise loc of last token of statement
*/
Expand Down Expand Up @@ -6585,20 +6585,48 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
s = new AST.SynchronizedStatement(loc, exp, _body);
break;
}
case TOK.with_:
case TOK.with_: // https://dlang.org/spec/statement.html#with-statement
{
AST.Expression exp;
AST.Statement _body;
Loc endloc = loc;
Loc withLoc = loc;

nextToken();
check(TOK.leftParenthesis);
exp = parseExpression();
AST.Expression exp = parseExpression();
closeCondition("with", null, exp);
_body = parseStatement(ParseStatementFlags.scope_, null, &endloc);
s = new AST.WithStatement(loc, exp, _body, endloc);

if (token.value == TOK.colon) // with (Expression) : StatementList
{
nextToken();

const lookingForElseSave = lookingForElse;
lookingForElse = Loc.initial;

auto statements = new AST.Statements();
while (token.value != TOK.rightCurly && token.value != TOK.endOfFile)
{
statements.push(parseStatement(ParseStatementFlags.curlyScope | ParseStatementFlags.semiOk));
}

lookingForElse = lookingForElseSave;

s = new AST.CompoundStatement(loc, statements);
s = new AST.ScopeStatement(loc, s, token.loc);
s = new AST.WithStatement(loc, exp, s, withLoc);

if (token.value == TOK.endOfFile)
{
error(token.loc, "matching `}` expected following compound with statement, not `%s`",

Check warning on line 6618 in compiler/src/dmd/parse.d

View check run for this annotation

Codecov / codecov/patch

compiler/src/dmd/parse.d#L6618

Added line #L6618 was not covered by tests
token.toChars());
eSink.errorSupplemental(withLoc, "unmatched `with (exp):`");
s = new AST.ErrorStatement();

Check warning on line 6621 in compiler/src/dmd/parse.d

View check run for this annotation

Codecov / codecov/patch

compiler/src/dmd/parse.d#L6620-L6621

Added lines #L6620 - L6621 were not covered by tests
}
break;
}
AST.Statement _body = parseStatement(ParseStatementFlags.scope_, null, &withLoc);
s = new AST.WithStatement(loc, exp, _body, withLoc);
break;
}

case TOK.try_:
{
AST.Statement _body;
Expand Down
20 changes: 20 additions & 0 deletions compiler/test/compilable/scope.d
Original file line number Diff line number Diff line change
Expand Up @@ -375,3 +375,23 @@ struct Result
auto r = Result(&s);
r.save();
}

/********************************************/

void withOmatic()
{
enum E { A, B }
E e;

{
with (E):
int i;
if (A)
return;
}
{
with (e)
if (A)
return;
}
}
16 changes: 16 additions & 0 deletions compiler/test/fail_compilation/withspoon.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
/* TEST_OUTPUT:
---
fail_compilation/withspoon.d(17): Error: matching `}` expected following compound with statement, not `End of File`
fail_compilation/withspoon.d(15): unmatched `with (exp):`
fail_compilation/withspoon.d(17): Error: matching `}` expected following compound statement, not `End of File`
fail_compilation/withspoon.d(14): unmatched `{`
---
*/


enum E { A, B }

void test2()
{
with (E):
return;

0 comments on commit 00db26d

Please sign in to comment.