Re: __FILE__ and __LINE__ in case of import expression

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

On 8/23/20 8:42 AM, Andrey Zherikov wrote:

On Saturday, 22 August 2020 at 03:43:10 UTC, Steven Schveighoffer wrote:

On 8/21/20 6:34 PM, Adam D. Ruppe wrote:

On Friday, 21 August 2020 at 22:12:48 UTC, Steven Schveighoffer wrote:
And honestly, if it says the source is "mixin-50, line 1", I think 
people will get it.


I could probably live with that too, but the status quo is pretty 
useful as-is.


I wonder if the compiler could detect when you are using a string 
literal vs. a generated or imported string, and change the behavior 
accordingly.


As far as I understand behavior of this is that mixin() changes __FILE__ 
to point to the location of this mixin. But import expression doesn't do 
so. So if import("file") could change __FILE__ to "file" and __LINE__ to 
1 internally that will make sense IMHO.

I mean something like this:
     //__FILE__='test', __LINE__=1
mixin(  //__FILE__='test-mixin-2', __LINE__=2
     //__FILE__='test-mixin-2', __LINE__=3
import("file")  //__FILE__='file', __LINE__=1   - only inside 
import()  !!!

     //__FILE__='test-mixin-2', __LINE__=5
)
     //__FILE__='test', __LINE__=7



import("file") returns a string, the source of the string is no longer 
available for the compiler after it's done importing it as a string.


However, you can easily use the #line directive to automate this...

string getImport(string file)()
{
   return "#line 1 " ~ file ~ "\n" ~ import(file);
}

mixin(getImport!"file");

-Steve


Re: __FILE__ and __LINE__ in case of import expression

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

On Sunday, 23 August 2020 at 12:50:36 UTC, Andrey Zherikov wrote:
Even this approach can lead to unclear result if you move 
'q{...}' outside of mixin:


Yes, that's why I write it very specifically the way I do, with 
q{ and mixin on the same line.


Re: __FILE__ and __LINE__ in case of import expression

2020-08-23 Thread Andrey Zherikov via Digitalmars-d-learn

On Friday, 21 August 2020 at 22:34:49 UTC, Adam D. Ruppe wrote:
On Friday, 21 August 2020 at 22:12:48 UTC, Steven Schveighoffer 
wrote:

Who does that though?


An incompetent coder:

http://dpldocs.info/experimental-docs/source/arsd.cgi.d.html#L5713
http://dpldocs.info/experimental-docs/source/arsd.cgi.d.html#L5943
http://dpldocs.info/experimental-docs/source/arsd.cgi.d.html#L6018
http://dpldocs.info/experimental-docs/source/arsd.cgi.d.html#L6058


Even this approach can lead to unclear result if you move 
'q{...}' outside of mixin:

=
void test(string file = __FILE__, size_t line = __LINE__)
{
writefln("file: '%s', line: '%s'", file, line);
}

int main(string[] args)
{
enum code = q{
// empty line 15
// empty line 16
// empty line 17
// empty line 18
// empty line 19
test(); // line 20
};

test();// line 23
mixin(code);   // line 24
test();// line 25
return 0;  // line 26
}  // line 27
===

The output is the following:
file: 'test.d', line: '23'
file: 'test.d-mixin-24', line: '30'
file: 'test.d', line: '25'

Note that there is no line 30!


Re: __FILE__ and __LINE__ in case of import expression

2020-08-23 Thread Andrey Zherikov via Digitalmars-d-learn
On Saturday, 22 August 2020 at 03:43:10 UTC, Steven Schveighoffer 
wrote:

On 8/21/20 6:34 PM, Adam D. Ruppe wrote:
On Friday, 21 August 2020 at 22:12:48 UTC, Steven 
Schveighoffer wrote:
And honestly, if it says the source is "mixin-50, line 1", I 
think people will get it.


I could probably live with that too, but the status quo is 
pretty useful as-is.


I wonder if the compiler could detect when you are using a 
string literal vs. a generated or imported string, and change 
the behavior accordingly.


As far as I understand behavior of this is that mixin() changes 
__FILE__ to point to the location of this mixin. But import 
expression doesn't do so. So if import("file") could change 
__FILE__ to "file" and __LINE__ to 1 internally that will make 
sense IMHO.

I mean something like this:
//__FILE__='test', __LINE__=1
mixin(  //__FILE__='test-mixin-2', __LINE__=2
//__FILE__='test-mixin-2', __LINE__=3
import("file")  //__FILE__='file', __LINE__=1   - only 
inside import()  !!!

//__FILE__='test-mixin-2', __LINE__=5
)
//__FILE__='test', __LINE__=7



Re: __FILE__ and __LINE__ in case of import expression

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

On 8/21/20 6:34 PM, Adam D. Ruppe wrote:

On Friday, 21 August 2020 at 22:12:48 UTC, Steven Schveighoffer wrote:
And honestly, if it says the source is "mixin-50, line 1", I think 
people will get it.


I could probably live with that too, but the status quo is pretty useful 
as-is.


I wonder if the compiler could detect when you are using a string 
literal vs. a generated or imported string, and change the behavior 
accordingly.


-Steve


Re: __FILE__ and __LINE__ in case of import expression

2020-08-21 Thread Adam D. Ruppe via Digitalmars-d-learn
On Friday, 21 August 2020 at 22:12:48 UTC, Steven Schveighoffer 
wrote:

Who does that though?


An incompetent coder:

http://dpldocs.info/experimental-docs/source/arsd.cgi.d.html#L5713
http://dpldocs.info/experimental-docs/source/arsd.cgi.d.html#L5943
http://dpldocs.info/experimental-docs/source/arsd.cgi.d.html#L6018
http://dpldocs.info/experimental-docs/source/arsd.cgi.d.html#L6058

I actually do kinda a lot. It is kinda useful for adding 
declarations with mixed in names (the whole declaration must be 
mixed in even if the only unique part is the name), or the first 
instance there is to version out features where the compiler's 
parser worked (I maintain compatibility with 2+ year old 
compilers too and if the parser changes, version alone will not 
work).


And honestly, if it says the source is "mixin-50, line 1", I 
think people will get it.


I could probably live with that too, but the status quo is pretty 
useful as-is.


Re: __FILE__ and __LINE__ in case of import expression

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

On 8/21/20 5:56 PM, Adam D. Ruppe wrote:

On Friday, 21 August 2020 at 21:42:21 UTC, Steven Schveighoffer wrote:

While not necessarily a "bug", it's not very useful.


Maybe not in this case, but it is perfectly accurate for cases like:

mixin(q{
    some code here
});

Where it will actually line back up to the original file's line number 
perfectly.





Who does that though? Why not just write "some code here" right in the 
file? (I know that the string interpolation DIP might make this more likely)


And honestly, if it says the source is "mixin-50, line 1", I think 
people will get it.


Whereas, if the code is like:

mixin(generateTheMixin());

and it says the line is 67, and line 67 has nothing to do with the mixin 
source or the location it's mixed in, but instead, you need to subtract 
the line number of mixing in from 67 to get the *real* line number, I 
think the utility is really gone at that point.


-Steve


Re: __FILE__ and __LINE__ in case of import expression

2020-08-21 Thread Adam D. Ruppe via Digitalmars-d-learn
On Friday, 21 August 2020 at 21:42:21 UTC, Steven Schveighoffer 
wrote:

While not necessarily a "bug", it's not very useful.


Maybe not in this case, but it is perfectly accurate for cases 
like:


mixin(q{
   some code here
});

Where it will actually line back up to the original file's line 
number perfectly.





Re: __FILE__ and __LINE__ in case of import expression

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

On 8/21/20 5:08 PM, Adam D. Ruppe wrote:

On Friday, 21 August 2020 at 21:06:11 UTC, Steven Schveighoffer wrote:
The hybrid line number (original source line number + mixin line 
number) seems like a bug to me.


I'm not so sure without seeing all the code. Remember to the compiler, 
the mixin thing is just a big string literal at the location of the 
import statement.


So it adds the number of \n's in the string literal to the original line 
number to get the mixin line number.


Look at the OP. It says line 22. Neither test.d nor the imported foo.d 
has 22 lines.


While not necessarily a "bug", it's not very useful. The compiler should 
output a useful line number. I shouldn't have to do math to figure out 
what it "really" means.


I'd argue that should be the line number based on the mixin source. The 
file name already is based on the line the string was mixed in, so both 
items contain useful data.


To be fair to the compiler, when you are mixing in an import, the mixin 
doesn't know that the string came from an imported file, so it can't 
really determine the file automatically. But the line number should be 
reasonable.


-Steve


Re: __FILE__ and __LINE__ in case of import expression

2020-08-21 Thread Adam D. Ruppe via Digitalmars-d-learn
On Friday, 21 August 2020 at 21:06:11 UTC, Steven Schveighoffer 
wrote:
The hybrid line number (original source line number + mixin 
line number) seems like a bug to me.


I'm not so sure without seeing all the code. Remember to the 
compiler, the mixin thing is just a big string literal at the 
location of the import statement.


So it adds the number of \n's in the string literal to the 
original line number to get the mixin line number.


Re: __FILE__ and __LINE__ in case of import expression

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

On 8/21/20 4:54 PM, Andrey Zherikov wrote:

On Friday, 21 August 2020 at 20:44:27 UTC, Andrey Zherikov wrote:
Thanks for this link! I can use "#line" to fix line number but not 
file name:


file: 'foo.d-mixin-1', line: '6', module: 'test',
function: 'test.main', pretty function: 'int test.main(string[] args)',
file full path: 'C:\Users\andrey\foo.d-mixin-1'


I can actually fix this issue as well.

Changes in test.d:

     test();  // line #16 (1)
     mixin("#line 1 \"foo.d\"\n" ~ import("foo.d"));  // line #17 (2)
     test();  // line #18 (3)

Output:

file: 'test.d', line: '16', module: 'test',
function: 'test.main', pretty function: 'int test.main(string[] args)',
file full path: 'C:\Users\andrey\test.d'
file: 'foo.d', line: '6', module: 'test',
function: 'test.main', pretty function: 'int test.main(string[] args)',
file full path: 'C:\Users\andrey\foo.d'
file: 'test.d', line: '18', module: 'test',
function: 'test.main', pretty function: 'int test.main(string[] args)',
file full path: 'C:\Users\andrey\test.d'


Was just in the process of responding with this technique!

I think what you probably did first is:

int main(string[] args)
{
test();
#line 1 "foo.d"
mixin(import("foo.d"));
return 0;
}

Which sets the line and file of test.d at that point. But when the mixin 
happens, I believe the parser/lexer sets the filename, but does not set 
the line number to something different.


The hybrid line number (original source line number + mixin line number) 
seems like a bug to me.


-Steve


Re: __FILE__ and __LINE__ in case of import expression

2020-08-21 Thread Andrey Zherikov via Digitalmars-d-learn

On Friday, 21 August 2020 at 20:44:27 UTC, Andrey Zherikov wrote:
Thanks for this link! I can use "#line" to fix line number but 
not file name:


file: 'foo.d-mixin-1', line: '6', module: 'test',
function: 'test.main', pretty function: 'int test.main(string[] 
args)',

file full path: 'C:\Users\andrey\foo.d-mixin-1'


I can actually fix this issue as well.

Changes in test.d:

test();  // line #16  
(1)
mixin("#line 1 \"foo.d\"\n" ~ import("foo.d"));  // line #17  
(2)
test();  // line #18  
(3)


Output:

file: 'test.d', line: '16', module: 'test',
function: 'test.main', pretty function: 'int test.main(string[] 
args)',

file full path: 'C:\Users\andrey\test.d'
file: 'foo.d', line: '6', module: 'test',
function: 'test.main', pretty function: 'int test.main(string[] 
args)',

file full path: 'C:\Users\andrey\foo.d'
file: 'test.d', line: '18', module: 'test',
function: 'test.main', pretty function: 'int test.main(string[] 
args)',

file full path: 'C:\Users\andrey\test.d'


Re: __FILE__ and __LINE__ in case of import expression

2020-08-21 Thread Andrey Zherikov via Digitalmars-d-learn



On Friday, 21 August 2020 at 15:34:49 UTC, Steven Schveighoffer 
wrote:

On 8/21/20 10:01 AM, Andrey Zherikov wrote:
How can I get __FILE__ and __LINE__ values correct in case of 
import expression?

...


So the output from line #16 (1) is correct although from line 
#17 (2) is not: file name is neither 'test.d' not 'foo.d' and 
line number is 22 although both test.d and foo.d are shorter.


You can override the filename and line number to the lexer: 
https://dlang.org/spec/lex.html#special-token-sequence


vibe.d does this so when errors from the trans-piled diet files 
happen, they match (mostly) back to the diet file, not the 
source file where they are mixed in.


I understand that I can create a workaround but want to check 
first whether this is desired behavior or a bug that should be 
fixed?


That's a good question. I would say it should say line 17 or 
line 6 (preferably the latter). That may be considered a bug, I 
don't know.


Thanks for this link! I can use "#line" to fix line number but 
not file name:


file: 'foo.d-mixin-1', line: '6', module: 'test',
function: 'test.main', pretty function: 'int test.main(string[] 
args)',

file full path: 'C:\Users\andrey\foo.d-mixin-1'



Re: __FILE__ and __LINE__ in case of import expression

2020-08-21 Thread Andrey Zherikov via Digitalmars-d-learn

On Friday, 21 August 2020 at 15:27:14 UTC, Adam D. Ruppe wrote:
On Friday, 21 August 2020 at 14:01:24 UTC, Andrey Zherikov 
wrote:

mixin(import("foo.d"));  // line #17(2)


Why are you doing this? This kind of thing is almost never an 
ideal solution in D.


See, the compiler just sees a big string literal there. It 
isn't a separate file at that point, the import expression just 
pastes in the file contents as a string, and then mixin makes a 
chunk of code from it.


These two features are not really meant to be used together, at 
least not without some custom translation code in the middle.


Currently this is for illustration only but why can't I do this?
This can be an alternative to `rdmd --eval` that takes code from 
a file, not as CLI parameter.




Re: __FILE__ and __LINE__ in case of import expression

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

On 8/21/20 10:01 AM, Andrey Zherikov wrote:
How can I get __FILE__ and __LINE__ values correct in case of import 
expression?

...


So the output from line #16 (1) is correct although from line #17 (2) is 
not: file name is neither 'test.d' not 'foo.d' and line number is 22 
although both test.d and foo.d are shorter.


You can override the filename and line number to the lexer: 
https://dlang.org/spec/lex.html#special-token-sequence


vibe.d does this so when errors from the trans-piled diet files happen, 
they match (mostly) back to the diet file, not the source file where 
they are mixed in.


I understand that I can create a workaround but want to check first 
whether this is desired behavior or a bug that should be fixed?


That's a good question. I would say it should say line 17 or line 6 
(preferably the latter). That may be considered a bug, I don't know.


-Steve


Re: __FILE__ and __LINE__ in case of import expression

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

On Friday, 21 August 2020 at 14:01:24 UTC, Andrey Zherikov wrote:

mixin(import("foo.d"));  // line #17(2)


Why are you doing this? This kind of thing is almost never an 
ideal solution in D.


See, the compiler just sees a big string literal there. It isn't 
a separate file at that point, the import expression just pastes 
in the file contents as a string, and then mixin makes a chunk of 
code from it.


These two features are not really meant to be used together, at 
least not without some custom translation code in the middle.