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 outsideSome 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