Invoking the compiler during runtime

2020-08-04 Thread cy via Digitalmars-d-learn
D's compile-time-execution is fantastic, but there are some times 
when I'd like to examine the generated code, or produce code that 
needs to pass through earlier phases before CTFE, or do AST 
stuff. Sometimes I simply don't want to generate the code with 
every compilation, so saving the generated code in a file some 
would be really neat, if I could then invoke the compiler during 
runtime to build it. Plus backtraces wouldn't just be 
"dlang-mixin-397."


I'm a big supporter of compiling from source and not using third 
party binaries, so I don't mind designing software that only 
works with runtime access to a D compiler. But I'm not sure how 
best to generate the code, or to invoke the compiler, or how to 
use what it compiles. In C I write a utility program in awful C 
to print out C code, have a cmake custom command run that awful C 
as needed, and assume the existence of that generated source in 
my main program.


So is that the best way to do it? Have a side program that writes 
D source to a file, and then the main program simply imports the 
file? Or is there some AST syntax I should be generating instead? 
Some way to import the compiler itself, instead of calling it in 
a subprocess? Is there a way in dub to specify that you run a D 
program contained in X.d during the build process, to build Y.d, 
that Z.d imports?


Re: How does one run a linux system command from a D main() fcn ?

2020-08-04 Thread Dennis via Digitalmars-d-learn

On Tuesday, 4 August 2020 at 19:52:47 UTC, Andy Balba wrote:

i.e.  D  equivalent to C++ command system("MyExe")


Apart from std.process, you can also call the C function in D 
after importing core.stdc.stdlib:


https://dlang.org/library/core/stdc/stdlib/system.html



Re: 2-D array initialization

2020-08-04 Thread tastyminerals via Digitalmars-d-learn

On Sunday, 2 August 2020 at 19:19:51 UTC, Andy Balba wrote:

On Sunday, 2 August 2020 at 06:37:06 UTC, tastyminerals wrote:

You haven't said anything about efficiency because if you care 
and your arrays are rather big, you better go with 
https://github.com/libmir/mir-algorithm as mentioned above. It 
might be a little finicky at the start but this post: 
https://tastyminerals.github.io/tasty-blog/dlang/2020/03/22/multidimensional_arrays_in_d.html should get you up to speed.



Keep in mind that std.array.staticArray is not efficient for  
large arrays.


If you want to stick to standard D, I would not initialize a 
2D array because it is just cumbersome but rather use a 1D 
array and transform it into 2D view on demand via ".chunks" 
method. Here is an example.


import std.range;
import std.array;

void main() {
int[] arr = 20.iota.array;
auto arr2dView = arr.chunks(5);
}

Should give you

┌  ┐
│ 0  1  2  3  4│
│ 5  6  7  8  9│
│10 11 12 13 14│
│15 16 17 18 19│
└  ┘

whenever you need to access its elements as arr.chunks(5)[1][1 
.. 3] --> [6, 7].


@ tastyminerals  Thanks for your help on this. These comments, 
combined with the others, are making my climb of the D learning 
curve much quicker.


I'm not a gitHub fan, but I like the mir functions; and it 
looks like I have to download mir before using it.
mir has quite a few .d files..Is there a quick way to download 
it ?


mir is a D package (akin to Python pip package). You can easily 
include it into your program by adding at the top of your file 
the following code:


/+ dub.sdl:
name "my_script"
dependency "mir-algorithm" version="~>3.9.12"
+/

And then just run your script with "dub my_script.d", dub will 
fetch the necessary dependencies, compile and run the file. 
However, it will not generate compiled versions of your 
my_script.d for that, you better set a dub project. Here, see to 
do it: 
https://tastyminerals.github.io/tasty-blog/dlang/2020/03/01/how_to_use_external_libraries_in_d_project.html




Re: How does one run a linux system command from a D main() fcn ?

2020-08-04 Thread Luhrel via Digitalmars-d-learn

On Tuesday, 4 August 2020 at 19:52:47 UTC, Andy Balba wrote:

i.e.  D  equivalent to C++ command system("MyExe")


https://dlang.org/library/std/process.html


How does one run a linux system command from a D main() fcn ?

2020-08-04 Thread Andy Balba via Digitalmars-d-learn

i.e.  D  equivalent to C++ command system("MyExe")


Re: std.conv.ConvException from double to uint64_t, but only locally in a large project

2020-08-04 Thread Nathan S. via Digitalmars-d-learn

On Tuesday, 4 August 2020 at 17:49:56 UTC, drathier wrote:
Replaced all mentions of uint64_t with ulong, and now it works. 
Must have an enum called uint64_t defined somewhere in a 
library I depend on or something? Really wish this was clearer.


BTW I believe the reason that `uint64_t` is an enum (which is 
being imported by "import std" but isn't converting) solely on 
macOS/iOS is for compatibility with C++ name mangling.


Re: std.conv.ConvException from double to uint64_t, but only locally in a large project

2020-08-04 Thread Steven Schveighoffer via Digitalmars-d-learn

On 8/4/20 2:15 PM, Steven Schveighoffer wrote:

I'll file a bug.


https://issues.dlang.org/show_bug.cgi?id=21112

-Steve


Re: std.conv.ConvException from double to uint64_t, but only locally in a large project

2020-08-04 Thread Steven Schveighoffer via Digitalmars-d-learn

On 8/4/20 1:36 PM, drathier wrote:

I'm getting a crash when I'm converting a double to an uint64_t.

```
std.conv.ConvException@/usr/local/opt/dmd/include/dlang/dmd/std/conv.d(2054): 
Value (1596) does not match any member value of enum '__c_ulonglong'

```

I've narrowed down the code to this:
```
static import std.conv;
double thing = 42.0;
std.conv.to!(uint64_t)(thing);
```
which works just fine on https://run.dlang.io/ or in a single-file dmd 
invocation. When I compile and run it locally on my mac as part of a 
specific large app using dub, it always crashes like this.


Where would I even start debugging this?

DMD64 D Compiler v2.093.0
DUB version 1.22.0, built on Jul  9 2020



So a common way to typedef something is to use enum:

enum uint64_t : ulong;

This gives you a new type that works pretty much just like ulong, but 
will not implicitly convert from ulong.


However, std.conv.to is likely interpreting this as an enumeration type, 
where it has to match one of the enum members. But since this isn't an 
enumeration in the standard way, it fails (it has no members!)


This code reproduces the problem on run.dlang.io:

void main()
{
import core.stdc.config;
import std.conv;
auto x = 0.5;
auto y = x.to!__c_ulonglong;
}

Note the code in druntime which defines __c_ulonglong: 
https://github.com/dlang/druntime/blob/0db2e65bba7cc319309bd32957763882870d5b03/src/core/stdc/config.d#L121


I'll file a bug.

-Steve


Re: std.conv.ConvException from double to uint64_t, but only locally in a large project

2020-08-04 Thread drathier via Digitalmars-d-learn
Replaced all mentions of uint64_t with ulong, and now it works. 
Must have an enum called uint64_t defined somewhere in a library 
I depend on or something? Really wish this was clearer.


Re: std.conv.ConvException from double to uint64_t, but only locally in a large project

2020-08-04 Thread drathier via Digitalmars-d-learn

On Tuesday, 4 August 2020 at 17:37:56 UTC, drathier wrote:

```
std.conv.ConvException@/usr/local/opt/dmd/include/dlang/dmd/std/conv.d(2054): 
Value (1596) does not match any member value of enum '__c_ulonglong'
```

well,
```
std.conv.ConvException@/usr/local/opt/dmd/include/dlang/dmd/std/conv.d(2054): 
Value (42) does not match any member value of enum '__c_ulonglong'
```
but the specific value doesn't matter


full stack trace:
```
std.conv.ConvException@/usr/local/opt/dmd/include/dlang/dmd/std/conv.d(2054): 
Value (42) does not match any member value of enum '__c_ulonglong'

source/app.d:864 @safe core.stdc.config.__c_ulonglong 
std.conv.toImpl!(core.stdc.config.__c_ulonglong, 
double).toImpl(double) [0x10fa540f8]
source/app.d:864 @safe core.stdc.config.__c_ulonglong 
std.conv.to!(core.stdc.config.__c_ulonglong).to!(double).to(double) [0x10fa54072]
source/app.d:262 int app.processFromOffset(std.socket.Socket, 
app.KafkerMode, app.RuntimeState, core.stdc.config.__c_ulonglong, 
core.stdc.config.__c_ulonglong) [0x10f9d06b5]

source/app.d:175 _Dmain [0x10f9cfcae]
```


Re: std.conv.ConvException from double to uint64_t, but only locally in a large project

2020-08-04 Thread drathier via Digitalmars-d-learn

```
std.conv.ConvException@/usr/local/opt/dmd/include/dlang/dmd/std/conv.d(2054): 
Value (1596) does not match any member value of enum '__c_ulonglong'
```

well,
```
std.conv.ConvException@/usr/local/opt/dmd/include/dlang/dmd/std/conv.d(2054): 
Value (42) does not match any member value of enum '__c_ulonglong'
```
but the specific value doesn't matter


Re: D on lm32-CPU: string argument on stack instead of register

2020-08-04 Thread Michael Reese via Digitalmars-d-learn

On Saturday, 1 August 2020 at 23:08:38 UTC, Chad Joan wrote:
Though if the compiler is allowed to split a single uint64_t 
into two registers, I would expect it to split struct/string 
into two registers as well. At least, the manual doesn't seem 
to explicitly mention higher-level constructs like structs. It 
does suggest a one-to-one relationship between arguments and 
registers (up to a point), but GCC seems to have decided 
otherwise for certain uint64_t's. (Looking at Table 3...) It 
even gives you two registers for a return value: enough for a 
string or an array. And if the backend/ABI weren't up for it, 
it would be theoretically possible to have the frontend to 
lower strings (dynamic arrays) and small structs into their 
components before function calls and then also insert code on 
the other side to cast them back into their original form. I'm 
not sure if anyone would want to write it, though. o.O


Right, I think at some point one should fix the backend. C 
programs would also benefit from it when passing structs as 
arguments. However in C it is more common to just pass pointers 
and they go into registers. I guess this is why I never noticed 
before that struct passing is needlessly expensive.



Getting from pointer-length to string might be pretty easy:
string foo = ptr[0 .. len];


Ah cool! I did know about array slicing, but wasn't aware that it 
works on pointers, too.


It ended up being a little more complicated than I thought it 
would be. Hope I didn't ruin the fun. ;)


https://pastebin.com/y6e9mxre


Thanks :) I'll have to look into that more closely. But this is 
the kind of stuff that I hope to make use of in the future on the 
embedded CPU. But for now I cannot use it yet because I don't 
have phobos and druntime in my toolchain right now... just naked 
D.


Also, that part where you mentioned a 64-bit integer being 
passed as a pair of registers made me start to wonder if unions 
could be (ab)used to juke the ABI:


https://pastebin.com/eGfZN0SL


Thanks for suggesting! I tried, and the union works as well, i.e. 
the function args are registered. But I noticed another thing 
about all workarounds so far:
Even if calls are inlined and arguments end up on the stack, the 
linker puts code of the wrapper function in my final binary event 
if it is never explicitly called. So until I find a way to strip 
of uncalled functions from the binary (not sure the linker can do 
it), the workarounds don't solve the size problem. But they still 
make the code run faster.




std.conv.ConvException from double to uint64_t, but only locally in a large project

2020-08-04 Thread drathier via Digitalmars-d-learn

I'm getting a crash when I'm converting a double to an uint64_t.

```
std.conv.ConvException@/usr/local/opt/dmd/include/dlang/dmd/std/conv.d(2054): 
Value (1596) does not match any member value of enum '__c_ulonglong'
```

I've narrowed down the code to this:
```
static import std.conv;
double thing = 42.0;
std.conv.to!(uint64_t)(thing);
```
which works just fine on https://run.dlang.io/ or in a 
single-file dmd invocation. When I compile and run it locally on 
my mac as part of a specific large app using dub, it always 
crashes like this.


Where would I even start debugging this?

DMD64 D Compiler v2.093.0
DUB version 1.22.0, built on Jul  9 2020



Re: Template functions inside interface

2020-08-04 Thread Steven Schveighoffer via Digitalmars-d-learn

On 8/4/20 9:39 AM, Adam D. Ruppe wrote:

On Tuesday, 4 August 2020 at 13:36:15 UTC, Zans wrote:
Is there any way to declare template functions inside interface and 
then override them in a class?


No, the templates in the interface are automatically considered `final`. 
So the body must be in the interface too to avoid that undefined 
reference error.


You can have them forward to normal methods in the interface though, 
just there needs to be a fixed number of them with concrete types.


I was kind of surprised the compiler didn't complain about override 
there. Is override ever a valid attribute for a template function? Is 
there a reason we ignore it for templates?


I can imagine a lot of confusion for something like:

import std.stdio;

interface MyInterface
{
T doAndReturnSomething(T)(T param){return T.init;}
}

class MyClass : MyInterface
{
override T doAndReturnSomething(T)(T param)
{
return param;
}
}

void main()
{
MyInterface myClass = new MyClass();
writeln(myClass.doAndReturnSomething("Hello"));
}

Which compiles, runs, and prints nothing.

-Steve


Re: safety and auto vectorization

2020-08-04 Thread Andy Balba via Digitalmars-d-learn
On Monday, 3 August 2020 at 19:42:51 UTC, Steven Schveighoffer 
wrote:

On 8/3/20 3:22 PM, Bruce Carneal wrote:


Thanks Steve (and Chad).  Summary: underspecified, varying 
behavior across versions, buggy.


Steve, what's the best way for me to report this?  Are spec 
issues lumped in with the other bugzilla reports?


Yep. You can file under dlang.org with the spec keyword.

Although this looks like it's not exactly a spec issue. I'd 
start it as a dmd bug (I don't know the exact interaction with 
the compiler and the library). It might also be a druntime bug.


-Steve


FWIW   ..using gdc Debian 8.3.0-6,   dst[]= generates a range 
error

auto a = [1, 2, 3];
auto b = [4, 5, 6];
int[] dst = new int[4]; // note the extra element
dst[] = a[] + b[];
writeln(dst[3]);


Re: Template functions inside interface

2020-08-04 Thread Adam D. Ruppe via Digitalmars-d-learn

On Tuesday, 4 August 2020 at 13:36:15 UTC, Zans wrote:
Is there any way to declare template functions inside interface 
and then override them in a class?


No, the templates in the interface are automatically considered 
`final`. So the body must be in the interface too to avoid that 
undefined reference error.


You can have them forward to normal methods in the interface 
though, just there needs to be a fixed number of them with 
concrete types.


Template functions inside interface

2020-08-04 Thread Zans via Digitalmars-d-learn
Is there any way to declare template functions inside interface 
and then override them in a class?
Trying to compile the following code results in "undefined 
reference" error:


import std.stdio;

interface MyInterface
{
T doAndReturnSomething(T)(T param);
}

class MyClass : MyInterface
{
override T doAndReturnSomething(T)(T param)
{
return param;
}
}

void main()
{
MyInterface myClass = new MyClass();
writeln(myClass.doAndReturnSomething!(string)("Hello"));
}

Thanks in advance!