Overloading relational operators separately; thoughts?

rikki cattermole via Digitalmars-d digitalmars-d at puremagic.com
Thu Sep 29 06:33:50 PDT 2016


On 30/09/2016 2:18 AM, Jacob Carlborg wrote:
> On 2016-09-29 14:57, rikki cattermole wrote:
>> Me and Cauterite were toying with the idea of AST macros but in a
>> completely new form a while ago.
>>
>> Below is the usage of it.
>>
>> Something you'll notice about it is that it could turn the asm block
>> into a library solution (which is clearly what we'd want anyway). Not to
>> mention Linq style queries.
>>
>> In theory it shouldn't be too complex to implement since you are only
>> doing basic checks to determine if to parse the given statement / block
>> to a rewriter function.
>>
>> ```D
>> void main() {
>>     // \/ parsed by iasm.c by matches {}'s and sending contents to it
>>     asm {
>>         ...
>>     }
>>
>>     import linq;
>>     @Linq
>>     DataSource source = ...;
>>     Tree[] trees = source.trees.where(name = "abc").limit(20);
>>
>>     import Assembly_x86;
>>
>>     asm {
>>         ...
>>     }
>> }
>>
>> struct Linq {
>>     string __ast(OnType, ExpectedType)(string statement) {
>>         assert(statement == "source.trees.where(name =
>> "abc").limit(20);");
>>         static assert(OnType == DataSource);
>>         static assert(ExpectedType == Tree[]);
>>     }
>> }
>>
>> // Assembly_x86.d
>>
>> struct X86 {}
>> struct ASM {
>>
>>     string __ast(OnType, ExpectedType)(string statement) {
>>         assert(statement == "asm {\n        ...\n    };");
>>         static assert(OnType == X86);
>>         static assert(ExpectedType == void);
>>     }
>> }
>>
>> @ASM
>> X86 asm;
>> ```
>
> Hmm, I find this to be somewhat difficult to follow. You get the AST as
> a string? Which means you need to implement a parser. How will the macro
> invocation be transformed? Return a string from the macro which will be
> reparsed by the compiler and inserted at the call site?

I'll expand on what I wrote above.

There are two kinds of invocations here. Blocks and statements.
Statements are the type of thing you expect from e.g. Linq. Where as 
blocks would be what asm would be defined as being.

The invocation defines where the start/end of the input file to be 
passed to __ast is and that is all it does.

In each case, if the first token (or for assignment statements the first 
token of the expression) is a variable that happens to have a UDA on it 
with __ast member it will pass said invocation text directly to it. What 
ever that may be.

As far as guarantees go for the input, it will always end in a 
semicolon. To determine if it was a statement vs a block just check if 
ExpectedType is void.

So something like:

```D
      @Linq
      DataSource source = ...;
      Tree[] trees = source.trees.where(name = "abc").limit(20);
```

Could be transformed into:

```D
     @Linq
     DataSource source = ...;
     Tree[] trees = mixin(__traits(getAttributes, 
source)[0].__ast("source.trees.where(name = "abc").limit(20);"));
```

They key here is explicitly marking non-vanilla-D-code as such without 
adding syntax like ``macro{ stuff here }``.


More information about the Digitalmars-d mailing list