Re: mixin issue

2023-11-29 Thread Paul Backus via Digitalmars-d-learn

On Wednesday, 29 November 2023 at 13:31:14 UTC, DLearner wrote:

```
Error: found `End of File` when expecting `;` following 
statement

```

If an extra ; is added:
```
   }(` ~ strStartPtr ~ `,` ~ strPLPtr ~ `);`;
```

it works but doesn't seem correct.


This is an annoying limitation of the D compiler.

The root of the problem is that there is an ambiguity in D's 
grammar. When the compiler sees


mixin(whatever);

...it cannot tell whether it's supposed to be a [Mixin 
Statement][1], or an [Expression Statement][2] that contains a 
[Mixin Expression][3].


If it's a Mixin Statement, then there should be a semicolon 
inside the mixin. If it's an Expression Statement with a Mixin 
Expression, then there shouldn't be a semicolon inside the mixin.


To resolve this ambiguity, the compiler (currently) *assumes* 
that it's always a Mixin Statement, which means that it will 
always require a semicolon inside the mixin.


As a result, it is impossible to write a string mixin that can be 
used as both a statement and an expression.


If you have an expression mixin and you would like to use it as a 
statement, you can work around this limitation by adding 
`cast(void)` in front of the mixin:


cast(void) mixin(whatever);

This forces the compiler to parse the line as an Expression 
Statement containing a [Cast Expression][4], but does not 
otherwise change the meaning of the code.


[1]: https://dlang.org/spec/statement.html#mixin-statement
[2]: https://dlang.org/spec/statement.html#expression-statement
[3]: https://dlang.org/spec/expression.html#mixin_expressions
[4]: https://dlang.org/spec/expression.html#cast_expressions


Re: mixin issue

2023-11-29 Thread Dennis via Digitalmars-d-learn

On Wednesday, 29 November 2023 at 13:31:14 UTC, DLearner wrote:

it works but doesn't seem correct.


You're mixing in an expression that creates an empty function and 
calls it. What do you want it to do?




mixin issue

2023-11-29 Thread DLearner via Digitalmars-d-learn

The code:

```
void main() {

   struct SB {
  char  SBChrFld1;
  char  SBChrFld2;
  int   SBIntFld1;
  int   SBIntFld2;
   }
   SB  SBVar;

   SB* wkSBPtr;


   void* StartPtr1 = null;

   mixin(mxnDelMbr("StartPtr1", "wkSBPtr"));
   return;
}

string mxnDelMbr()(string strStartPtr, string strPLPtr) {
   return `(void* StartPtr, typeof(` ~ strPLPtr ~ `) PLPtr) {

   }(` ~ strStartPtr ~ `,` ~ strPLPtr ~ `)`;
}
```
Fails with:

```
Error: found `End of File` when expecting `;` following statement
```

If an extra ; is added:
```
   }(` ~ strStartPtr ~ `,` ~ strPLPtr ~ `);`;
```

it works but doesn't seem correct.
Further, example above cloned from several other similar 
examples, which
not only work, but if ';' introduced in corresponding place, dmd 
complains with

empty statement deprecation.
FWIW only difference identified between successful examples and 
this one,

is that other functions all return something, this one does not.

Suggestions?


Re: Strange Mixin issue

2014-03-05 Thread Ali Çehreli

On 03/05/2014 03:10 PM, Frustrated wrote:

>> assert(s.Do(1, 2.5) == 3.5);

> And this is exactly what I don't what!

Sorry, I've completely misunderstood. :)

> Do, in my case, is a ctfe used
> only at compile time to make it easy to generate code. It's not needed
> at runtime and does not belong anywhere.

So, you want to mixin what D() generates. The following example mixes in 
a static member function and two variables to S:


// Makes a make() function that returns a T
string makeMakeFunc(T)()
{
import std.string;

return format("static %s make() { %s result; return result; }",
  T.stringof, T.stringof);
}

unittest
{
assert(makeMakeFunc!int() ==
   "static int make() { int result; return result; }",
   makeMakeFunc!int());
}

// Declares a make() function that returns T[0] and two variables of types
// T[1], T[2], etc.
string DoImpl(T...)()
{
import std.conv;

string result;
size_t i = 0;

foreach (Type; T[1 .. $]) {
result ~= Type.stringof ~ " var" ~ i.to!string ~ ";\n";
++i;
}

result ~= makeMakeFunc!(T[0])();

return result;
}

unittest
{
assert(DoImpl!(int, double, long) ==
"double var0;
long var1;
static int make() { int result; return result; }");
}

// Declares a make() function that returns typeof(this) and two variables of
// types T[0], T[1], etc.
template Do(T...)
{
mixin(DoImpl!(typeof(this), T)());
}

struct S
{
mixin Do!(int, double);
}

void main()
{
// S has a static member function that makes an S:
auto s = S.make();
static assert(is (typeof(s) == S));

// S has gained two member variables:
static assert(is (typeof(s.var0) == int));
static assert(is (typeof(s.var1) == double));
}

Ali



Re: Strange Mixin issue

2014-03-05 Thread Frustrated

On Wednesday, 5 March 2014 at 23:33:25 UTC, Frustrated wrote:
Maybe the problem isn't what I thought it was. I created a test 
case that works:


import std.stdio, std.cstream;

mixin template C()
{
alias A = typeof(this);
mixin(B!(A));
}

template B(T)
{
pragma(msg, T);
	enum B() { return "string foo() { return `<"~T.stringof~">`; 
}"; }

}

class A
{
//mixin(B!(A));
mixin C;
}


void main()
{
auto a = new A;
writeln(a.foo());
//a.B();
din.getc();
}


Note the difference in calls. C is much easier because you 
don't have to pass the parent type. This is all I'm trying to 
achieve in the other code but when I do the functions(foo in 
this case) do not get mixed in.



The actual error is quite strange in the other code:

When I simply wrap the code in an outside template I get the 
error(s)


Eror: gui.border is not an lvalue   

which is related to the line

auto ress = (gui.border = bb);

which works when I don't wrap the code. If I stick the output of 
the string mixin template directly into the class, it works fine. 
(so it has something to do wtih the template generation rather 
than what it generates)


e.g., this is what I did

template AbstractToInterface(B, T...)
{   
enum AbstractToInterface() {  }
}

to

mixin template AbstractToInterface(B, T...)
{
mixin(AbstractToInterface2!(B, T));
}

template AbstractToInterface2(B, T...)
{   
enum AbstractToInterface2() {  }
}

and convert

mixin(AbstractToInterface!(WindowsGui, iButton, WindowsButton, 
iBorder, WindowsBorder));


to

mixin AbstractToInterface!(WindowsGui, iButton, WindowsButton, 
iBorder, WindowsBorder);



and I get the error down the road about

Eror: gui.border is not an lvalue

Which I guess is saying border does not have a setter, which is 
what AbstractToInterface is suppose to be creating and adding... 
again, it works when I copy the output of the template direct to 
the class.


I'm betting it's a bug unless I'm doing something real stupid.



Re: Strange Mixin issue

2014-03-05 Thread Frustrated
Maybe the problem isn't what I thought it was. I created a test 
case that works:


import std.stdio, std.cstream;

mixin template C()
{
alias A = typeof(this);
mixin(B!(A));
}

template B(T)
{
pragma(msg, T);
	enum B() { return "string foo() { return `<"~T.stringof~">`; }"; 
}

}

class A
{
//mixin(B!(A));
mixin C;
}


void main()
{
auto a = new A;
writeln(a.foo());
//a.B();
din.getc();
}


Note the difference in calls. C is much easier because you don't 
have to pass the parent type. This is all I'm trying to achieve 
in the other code but when I do the functions(foo in this case) 
do not get mixed in.




Re: Strange Mixin issue

2014-03-05 Thread Frustrated

On Wednesday, 5 March 2014 at 23:04:06 UTC, Ali Çehreli wrote:

On 03/05/2014 02:37 PM, Frustrated wrote:

>> import std.typetuple;
>>
>> template fooImpl(T...)
>> {
>> static assert(is (T[0] == S));// <-- COOL!
>> static assert(is (T[1] == int));
>> static assert(is (T[2] == double));
>> }
>>
>> template foo(T...)
>> {
>> alias foo = fooImpl!(TypeTuple!(typeof(this), T));
>> }
>>
>> struct S
>> {
>> mixin foo!(int, double);
>> }
>>
>> void main()
>> {
>> auto s = S();
>> }
>>
>> Ali
>
> this is not quite the same.

I think you tried to give a link in your original code but it 
is missing. Still, it is very difficult for me to follow code 
unless it is really simple. :)


> You have static asserts.

Just to prove that I've managed to inject typeof(this) as the 
first template parameter.


> I'm trying to avoid
> mixing in ctfe code that might interfer with the class. (I
have a temp
> function Do which if I mixin as a normal template will mixin
Do into the
> class make Do a member of that class)

The following is what I understand so far. :) The last line of 
main() proves that S gained a function Do() that takes (int, 
double) parameters.


import std.typetuple;

template DoImpl(T...)
{
auto Do(T[1] p1, T[2] p2)
{
return p1 + p2;
}
}

template Do(T...)
{
mixin DoImpl!(TypeTuple!(typeof(this), T));
}

struct S
{
mixin Do!(int, double);
}

void main()
{
auto s = S();
assert(s.Do(1, 2.5) == 3.5);
}

Ali


And this is exactly what I don't what! Do, in my case, is a ctfe 
used only at compile time to make it easy to generate code. It's 
not needed at runtime and does not belong anywhere.


Re: Strange Mixin issue

2014-03-05 Thread Ali Çehreli

On 03/05/2014 03:04 PM, Ali Çehreli wrote:


template Do(T...)
{
 mixin DoImpl!(TypeTuple!(typeof(this), T));


Actually, TypeTuple is not needed there:

mixin DoImpl!(typeof(this), T);

Ali



Re: Strange Mixin issue

2014-03-05 Thread Ali Çehreli

On 03/05/2014 02:37 PM, Frustrated wrote:

>> import std.typetuple;
>>
>> template fooImpl(T...)
>> {
>> static assert(is (T[0] == S));// <-- COOL!
>> static assert(is (T[1] == int));
>> static assert(is (T[2] == double));
>> }
>>
>> template foo(T...)
>> {
>> alias foo = fooImpl!(TypeTuple!(typeof(this), T));
>> }
>>
>> struct S
>> {
>> mixin foo!(int, double);
>> }
>>
>> void main()
>> {
>> auto s = S();
>> }
>>
>> Ali
>
> this is not quite the same.

I think you tried to give a link in your original code but it is 
missing. Still, it is very difficult for me to follow code unless it is 
really simple. :)


> You have static asserts.

Just to prove that I've managed to inject typeof(this) as the first 
template parameter.


> I'm trying to avoid
> mixing in ctfe code that might interfer with the class. (I have a temp
> function Do which if I mixin as a normal template will mixin Do into the
> class make Do a member of that class)

The following is what I understand so far. :) The last line of main() 
proves that S gained a function Do() that takes (int, double) parameters.


import std.typetuple;

template DoImpl(T...)
{
auto Do(T[1] p1, T[2] p2)
{
return p1 + p2;
}
}

template Do(T...)
{
mixin DoImpl!(TypeTuple!(typeof(this), T));
}

struct S
{
mixin Do!(int, double);
}

void main()
{
auto s = S();
assert(s.Do(1, 2.5) == 3.5);
}

Ali



Re: Strange Mixin issue

2014-03-05 Thread Ali Çehreli

On 03/05/2014 01:30 PM, Frustrated wrote:

I am trying to remove the unnecessary passing of the type of class to a
template but can't seem to get it to work:

see



The code is the


 mixin(AbstractToInterface!(WindowsGui, iButton, WindowsButton,
iBorder, WindowsBorder));

which I want to not have to specify WindowsGui.

I've tried wrapping AbstractToInterface in a mixin template and use that
and typeof(this) but then the mixin of the mixin does not get mixed in
to the class

e.g.,

mixin template AbstractToInterface2(T...)
{
 mixin(AbstractToInterface!(typeof(this), T));
}

Then use mixin AbstractTointerface2!(iButton, WindowsButton, iBorder,
WindowsBorder).

It's probably something stupid but I can't seem to get it to work(have a
very similar case in some other code and it works fine... the only
difference is I'm not using nested mixins.



The following works for me maybe because the templates are not mixin 
templates. What's a mixin template again?


import std.typetuple;

template fooImpl(This, T...)
{
static assert(is (This == S));// <-- IT WORKED!
static assert(is (T == TypeTuple!(int, double)));
}

template foo(T...)
{
alias foo = fooImpl!(typeof(this), T);
}

struct S
{
mixin foo!(int, double);
}

void main()
{
auto s = S();
}

Even better:

import std.typetuple;

template fooImpl(T...)
{
static assert(is (T[0] == S));// <-- COOL!
static assert(is (T[1] == int));
static assert(is (T[2] == double));
}

template foo(T...)
{
alias foo = fooImpl!(TypeTuple!(typeof(this), T));
}

struct S
{
mixin foo!(int, double);
}

void main()
{
auto s = S();
}

Ali



Re: Strange Mixin issue

2014-03-05 Thread Frustrated

On Wednesday, 5 March 2014 at 22:35:46 UTC, Ali Çehreli wrote:

On 03/05/2014 01:30 PM, Frustrated wrote:
I am trying to remove the unnecessary passing of the type of 
class to a

template but can't seem to get it to work:

see



The code is the


mixin(AbstractToInterface!(WindowsGui, iButton, 
WindowsButton,

iBorder, WindowsBorder));

which I want to not have to specify WindowsGui.

I've tried wrapping AbstractToInterface in a mixin template 
and use that
and typeof(this) but then the mixin of the mixin does not get 
mixed in

to the class

e.g.,

mixin template AbstractToInterface2(T...)
{
mixin(AbstractToInterface!(typeof(this), T));
}

Then use mixin AbstractTointerface2!(iButton, WindowsButton, 
iBorder,

WindowsBorder).

It's probably something stupid but I can't seem to get it to 
work(have a
very similar case in some other code and it works fine... the 
only

difference is I'm not using nested mixins.



The following works for me maybe because the templates are not 
mixin templates. What's a mixin template again?


import std.typetuple;

template fooImpl(This, T...)
{
static assert(is (This == S));// <-- IT WORKED!
static assert(is (T == TypeTuple!(int, double)));
}

template foo(T...)
{
alias foo = fooImpl!(typeof(this), T);
}

struct S
{
mixin foo!(int, double);
}

void main()
{
auto s = S();
}

Even better:

import std.typetuple;

template fooImpl(T...)
{
static assert(is (T[0] == S));// <-- COOL!
static assert(is (T[1] == int));
static assert(is (T[2] == double));
}

template foo(T...)
{
alias foo = fooImpl!(TypeTuple!(typeof(this), T));
}

struct S
{
mixin foo!(int, double);
}

void main()
{
auto s = S();
}

Ali


this is not quite the same. You have static asserts. I'm trying 
to avoid mixing in ctfe code that might interfer with the class. 
(I have a temp function Do which if I mixin as a normal template 
will mixin Do into the class make Do a member of that class)




Strange Mixin issue

2014-03-05 Thread Frustrated
I am trying to remove the unnecessary passing of the type of 
class to a template but can't seem to get it to work:


see



The code is the


	mixin(AbstractToInterface!(WindowsGui, iButton, WindowsButton, 
iBorder, WindowsBorder));


which I want to not have to specify WindowsGui.

I've tried wrapping AbstractToInterface in a mixin template and 
use that and typeof(this) but then the mixin of the mixin does 
not get mixed in to the class


e.g.,

mixin template AbstractToInterface2(T...)
{
mixin(AbstractToInterface!(typeof(this), T));
}

Then use mixin AbstractTointerface2!(iButton, WindowsButton, 
iBorder, WindowsBorder).


It's probably something stupid but I can't seem to get it to 
work(have a very similar case in some other code and it works 
fine... the only difference is I'm not using nested mixins.




Re: Template Mixin issue

2009-01-30 Thread Christopher Wright

Christopher Wright wrote:

Mike L. wrote:
If the compiler can tell that B!(int) is a type, why can't it tell 
that it is a child class of A!(int) ?


This is a bug. In template specializations, : means equality. In static 
if, : means convertibility.


This is only with template specializations involving templates, by the 
way. Template specializations involving any other type are fine.


Re: Template Mixin issue

2009-01-30 Thread Christopher Wright

Mike L. wrote:

If the compiler can tell that B!(int) is a type, why can't it tell that it is a 
child class of A!(int) ?


This is a bug. In template specializations, : means equality. In static 
if, : means convertibility.


So, you can use:
template ADefaults(Type, AType)
{
static assert (is (AType : A!(Type)));
Type blah()
{ return Type.init; }
}

http://d.puremagic.com/issues/show_bug.cgi?id=1715 if you want to vote.


Template Mixin issue

2009-01-29 Thread Mike L.
Hello,

I was wondering why the following does not work:

interface A(Type)
{ Type blah(); }

template ADefaults(Type, AType : A!(Type))
{
Type blah()
{ return Type.init; }
}

class B(Type) : A!(Type)
{ mixin ADefaults!(Type, B!(Type)); }

void main()
{ auto x = new B!(int)(); }

It gives the error: test.d(11): mixin ADefault!(int,B) does not match any 
template declaration

However, it will compile if you change the ADefaults header to:

template ADefaults(Type, AType)

If the compiler can tell that B!(int) is a type, why can't it tell that it is a 
child class of A!(int) ?