www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - int to char at compile time

reply Hendrik Renken <funsheep gmx.net> writes:
hello,

i am trying something like that:

char[] foo(int level, char[] msg)
{
     static c = toString(level);
     return "writefln(\"%d: %s\""~ c ~", \"" ~ msg ~ "\");";
}


int main(char[][] args)
{
    mixin(foo(100, "Test"));
    return 1;
}

but gdmd complaints that toString() cannot be evaluated at compile time. 
is there a way to convert the int to char at compile time?

regards,
Hendrik
Mar 20 2007
next sibling parent reply BCS <ao pathlink.com> writes:
Reply to Hendrik,

 hello,
 
 i am trying something like that:
 
 char[] foo(int level, char[] msg)
 {
 static c = toString(level);
 return "writefln(\"%d: %s\""~ c ~", \"" ~ msg ~ "\");";
 }
 int main(char[][] args)
 {
 mixin(foo(100, "Test"));
 return 1;
 }
 but gdmd complaints that toString() cannot be evaluated at compile
 time. is there a way to convert the int to char at compile time?
 
 regards,
 Hendrik

Don Clugston's decimaldigit and itoa, see http://trac.dsource.org/projects/ddl/browser/trunk/meta/conv.d template decimalDigit(int n) { const char[] decimalDigit = "0123456789"[n..n+1]; } template itoa(long n) { static if (n < 0) const char[] itoa = "-" ~ itoa!(-n); else static if (n < 10) const char[] itoa = decimalDigit!(n); else const char[] itoa = itoa!(n/10L) ~ decimalDigit!(n%10L); }
Mar 20 2007
parent reply Hendrik Renken <funsheep gmx.net> writes:
BCS wrote:
 Reply to Hendrik,
 
 hello,

 i am trying something like that:

 char[] foo(int level, char[] msg)
 {
 static c = toString(level);
 return "writefln(\"%d: %s\""~ c ~", \"" ~ msg ~ "\");";
 }
 int main(char[][] args)
 {
 mixin(foo(100, "Test"));
 return 1;
 }
 but gdmd complaints that toString() cannot be evaluated at compile
 time. is there a way to convert the int to char at compile time?

Don Clugston's decimaldigit and itoa, see http://trac.dsource.org/projects/ddl/browser/trunk/meta/conv.d

this doesn't work for variables like "level", just with directly wrote numbers. char[] foo(int level, char[] msg) { char[] c = itoa!(level); //does not work char[] c = itoa!(100); //does work } is there no chance, to get this variable value converted?
Mar 20 2007
parent Frits van Bommel <fvbommel REMwOVExCAPSs.nl> writes:
Hendrik Renken wrote:
 BCS wrote:
 Reply to Hendrik,

 i am trying something like that:

 char[] foo(int level, char[] msg)
 {
 static c = toString(level);



You can't make it static, since parameters aren't known when the function is compiled. Remember the function is also compiled for regular run-time use. It needs to make sense as such. Also, std.string.toString(int) unfortunately isn't compile-time executable.
 return "writefln(\"%d: %s\""~ c ~", \"" ~ msg ~ "\");";
 }
 int main(char[][] args)
 {
 mixin(foo(100, "Test"));
 return 1;
 }
 but gdmd complaints that toString() cannot be evaluated at compile
 time. is there a way to convert the int to char at compile time?



Yes, see below
 Don Clugston's decimaldigit and itoa, see 
 http://trac.dsource.org/projects/ddl/browser/trunk/meta/conv.d


Doesn't work for CTFE parameters.
 this doesn't work for variables like "level", just with directly wrote 
 numbers.
 
 char[] foo(int level, char[] msg)
 {
     char[] c = itoa!(level); //does not work
     char[] c = itoa!(100);   //does work
 }
 
 is there no chance, to get this variable value converted?

--- import std.stdio; char[] ctfe_itoa(int value) { if (value < 0) return "-" ~ ctfe_itoa(-value); if (value < 10) return "0123456789"[value .. value+1]; return ctfe_itoa(value / 10) ~ ctfe_itoa(value % 10); } char[] foo(int level, char[] msg) { auto c = ctfe_itoa(level); return "writefln(\"%d: %s\","~ c ~", \"" ~ msg ~ "\");"; } int main(char[][] args) { pragma(msg, foo(42u, "The answer")); pragma(msg, foo(int.max, "int.max")); mixin(foo(100, "Test")); return 1; } --- I originally wrote that function to be more efficient (so it could also reasonably be used at runtime) by using a stack-based buffer and returning buffer.dup, without any recursion. Unfortunately CTFE didn't like it :(. This version will of course still work at runtime, but will perform way too many allocations for a function like this. (I'm not sure if this will be a problem at compile time).
Mar 20 2007
prev sibling parent reply torhu <fake address.dude> writes:
Hendrik Renken wrote:

 but gdmd complaints that toString() cannot be evaluated at compile time. 
 is there a way to convert the int to char at compile time?

std.metastrings has a couple of ways of doing this.
Mar 20 2007
parent reply Hendrik Renken <funsheep gmx.net> writes:
torhu wrote:
 Hendrik Renken wrote:
 
 but gdmd complaints that toString() cannot be evaluated at compile 
 time. is there a way to convert the int to char at compile time?

std.metastrings has a couple of ways of doing this.

just for the records: with std.metastrings i am running in the same problems having with DDL. the ctfe_itoa function from Frits van Bommel works great. Thanks again. another little problem/maybe-bug i ran into: since i currently only have defined int values for "level", i use a switch-Statement to get propper String representations. const int CORE = 100; char[] foo(int level, char[] msg) { char[] name; switch(level) { case CORE: name = "CORE"; /******* important line ********/ break; default: name = "TEST"; } return "writefln(\"%s: %s\", "~ name ~", \"" ~ msg ~ "\");"; } int main(char[][] args) { mixin(foo(CORE, "Testmsg")); return 1; } using name = "CORE"; writes to the console 100: Testmsg using name = "\"CORE\""; gives me what i want CORE: Testmsg shouldnt it also work with "CORE"? or am i missing something here? regards Hendrik
Mar 21 2007
parent Hendrik Renken <funsheep gmx.net> writes:
--------8< snip code 8<----------
 
 using
 name = "CORE";
 writes to the console
 
 100: Testmsg
 
 
 using
 name = "\"CORE\"";
 gives me what i want
 
 CORE: Testmsg
 
 shouldnt it also work with "CORE"? or am i missing something here?

sorry for bothering, answered the question myself. Code: "writefln(\"%s: %s\", "~ name ~", \"" ~ msg ~ "\");" using name = "CORE"; gives us the line "writefln(\"%s: %s\", CORE, "Testmsg");" note: around ~msg~ i inserted " with \" so this is not "CORE", instead is uses the defined int variable, which has (of course) the value 100. giving 100: Testmsg
Mar 21 2007