digitalmars.D.learn - Structure initializer VS lambda function
- realhet (20/20) Dec 12 2022 Hi,
- Steven Schveighoffer (7/36) Dec 12 2022 This has actually been discussed recently on discord, I believe the
- Tim (10/14) Dec 12 2022 Some statements don't end in a semicolon, so you would also need
- realhet (42/42) Feb 19 2023 Hi again and thanks for the suggestions.
Hi,
I'm writing a DLang parser and got confused of this.
What is a good way to distinguish lambda functions and structure
initialization blocks.
Both of them are {} blocks.
I'm thinking of something like this:
1. checking inside (on the first hierarchy level inside {})
, => must be a struct initializer
; => must be a lambda
no , and no ; => check it from the outside
2. checking outside (on the same hierarchy level as the {}):
() before {} -> lambda
=> before {} -> lambda
() after {} -> lambda //this check feels wrong to me.
otherwise -> struct initializer
But I think it's logically loose.
I have only the syntax tree, I have no access to semantics. I
don't know if an identifier is a struct for example.
Is there a better way to do this?
Thank You in advance!
Dec 12 2022
On 12/12/22 3:54 AM, realhet wrote:
Hi,
I'm writing a DLang parser and got confused of this.
What is a good way to distinguish lambda functions and structure
initialization blocks.
Both of them are {} blocks.
I'm thinking of something like this:
1. checking inside (on the first hierarchy level inside {})
, => must be a struct initializer
; => must be a lambda
no , and no ; => check it from the outside
2. checking outside (on the same hierarchy level as the {}):
() before {} -> lambda
=> before {} -> lambda
() after {} -> lambda //this check feels wrong to me.
otherwise -> struct initializer
But I think it's logically loose.
I have only the syntax tree, I have no access to semantics. I don't know
if an identifier is a struct for example.
Is there a better way to do this?
Thank You in advance!
This has actually been discussed recently on discord, I believe the
difference is if you see a statement inside the braces (e.g. a semicolon).
It's not a great situation, and I think if we removed the ability to do
lambdas with `{}` without leading parentheses, it could clear this up
pretty well.
-Steve
Dec 12 2022
On Monday, 12 December 2022 at 08:54:33 UTC, realhet wrote:
1. checking inside (on the first hierarchy level inside {})
, => must be a struct initializer
; => must be a lambda
no , and no ; => check it from the outside
Some statements don't end in a semicolon, so you would also need
to check for those. For example:
```
auto lambda = { while(f()){} };
```
A lambda can also contain a comma expression:
```
auto lambda = { f(), g(); };
```
Dec 12 2022
Hi again and thanks for the suggestions.
I ended up checking every {} block with the following program:
It works on a string where all the nested blocks are reduced to a
single symbol. For example: '{', '"', '['
And all the comments and whitespaces are reduced to ' ' space.
```
enum CurlyBlockKind { empty, declarationsOrStatements, list }
auto detectCurlyBlock(CodeColumn col_)
{
auto p = col_.extractThisLevelDString.text;
p = p.replace("\n", " ");
p = p.replace(" ", " ");
p = p.replace(" {", "{");
p = p.replace(" [", "]");
p = p.replace(" (", ")");
//opt: these replaces are slow.
p = p.strip;
//first start with easy decisions at the end of the block
if(p=="") return CurlyBlockKind.empty;
if(p.endsWith(';') || p.endsWith(':')) return
CurlyBlockKind.declarationsOrStatements;
if(p.canFind("{,") || p.canFind(",{")) return
CurlyBlockKind.list;
if(p.canFind(';')||p.canFind('{')) return
CurlyBlockKind.declarationsOrStatements;
//give it up: it's not a declaration, neither a statement
block
return CurlyBlockKind.list;
}
```
Since 2.5 months I didn't changed it, and I use it every day, so
it seems ok.
The only unsure thing in this detector is the empty block. That
would require to check what's around the empty block, but I just
decided to represent it with it's own category: "empty".
The recursive detection of all D statements and declarations
become easy:
- declarationsOrStatements -> Go inside this block and detect all
the statements and declarations.
- list -> Discover the nested blocks inside this block, but don't
treat this block as declarations or statements, this is a list!
- empty -> do nothing
Feb 19 2023









Steven Schveighoffer <schveiguy gmail.com> 