Thread overview
Strange cast error in compile-time function
Jul 24, 2007
Stéphan Kochen
Jul 24, 2007
Max Samukha
Jul 24, 2007
Max Samukha
Jul 24, 2007
Stéphan Kochen
Jul 24, 2007
Frits van Bommel
Jul 24, 2007
Stéphan Kochen
Jul 24, 2007
Christian Kamm
July 24, 2007
Hello all,

I'm stuck on something. I'm writing some compile-time stuff to generate a function that gets me the Unicode general category for a dchar. I have some compile-time functions that read from the TXTs from the Unicode Character Database and create the actual D code for me.

The source code is attached.

The functions work at run-time and output the correct D code, when I
print the string return value using writefln. But when I try to use a
mixin to 'paste' it in a function at compile-time, I get a vague error:
	"Error: cannot cast int to RowData"
(and nothing else.)

RowData is a struct I use. It might be interesting to note that this
happens with DMD 1.0 (and the GDC based on it), but with DMD 1.020 I get
a slightly different (but equally vague) error:
	"Error: cannot cast int to char[][]"

I've been staring at this for hours. Halp! :)

Thanks in advance,
- -- Stéphan
July 24, 2007
On Tue, 24 Jul 2007 18:09:18 +0200, Stephan Kochen <stephan@kochen.nl> wrote:

>-----BEGIN PGP SIGNED MESSAGE-----
>Hash: SHA1
>
>Hello all,
>
>I'm stuck on something. I'm writing some compile-time stuff to generate a function that gets me the Unicode general category for a dchar. I have some compile-time functions that read from the TXTs from the Unicode Character Database and create the actual D code for me.
>
>The source code is attached.
>
>The functions work at run-time and output the correct D code, when I
>print the string return value using writefln. But when I try to use a
>mixin to 'paste' it in a function at compile-time, I get a vague error:
>	"Error: cannot cast int to RowData"
>(and nothing else.)
>
>RowData is a struct I use. It might be interesting to note that this
>happens with DMD 1.0 (and the GDC based on it), but with DMD 1.020 I get
>a slightly different (but equally vague) error:
>	"Error: cannot cast int to char[][]"
>
>I've been staring at this for hours. Halp! :)
>
>Thanks in advance,
>- -- Stephan
>-----BEGIN PGP SIGNATURE-----
>Version: GnuPG v1.4.6 (GNU/Linux)
>
>iD8DBQFGpiQucFUq0gzqDwQRAjz0AJ0ZexMPgBxHxQXBGshI6hghgXDD8ACgspRd
>GWIHuG9P7iV9k/CNf+bGKsU=
>=jyR8
>-----END PGP SIGNATURE-----

There are still bugs in the compiler that make writing compile-time functions a difficult task. In your case, the error is caused by retval not being explicitly initialized (in parseUnicodeCSV). Try

RowData retval = RowData.init;

But even if it is, the function still cannot be evaluated at compile-time. Trying to figure out why.
July 24, 2007
On Tue, 24 Jul 2007 19:47:39 +0300, Max Samukha <samukha@voliacable.com.removethis> wrote:

>On Tue, 24 Jul 2007 18:09:18 +0200, Stephan Kochen <stephan@kochen.nl> wrote:
>
>>-----BEGIN PGP SIGNED MESSAGE-----
>>Hash: SHA1
>>
>>Hello all,
>>
>>I'm stuck on something. I'm writing some compile-time stuff to generate a function that gets me the Unicode general category for a dchar. I have some compile-time functions that read from the TXTs from the Unicode Character Database and create the actual D code for me.
>>
>>The source code is attached.
>>
>>The functions work at run-time and output the correct D code, when I
>>print the string return value using writefln. But when I try to use a
>>mixin to 'paste' it in a function at compile-time, I get a vague error:
>>	"Error: cannot cast int to RowData"
>>(and nothing else.)
>>
>>RowData is a struct I use. It might be interesting to note that this
>>happens with DMD 1.0 (and the GDC based on it), but with DMD 1.020 I get
>>a slightly different (but equally vague) error:
>>	"Error: cannot cast int to char[][]"
>>
>>I've been staring at this for hours. Halp! :)
>>
>>Thanks in advance,
>>- -- Stephan
>>-----BEGIN PGP SIGNATURE-----
>>Version: GnuPG v1.4.6 (GNU/Linux)
>>
>>iD8DBQFGpiQucFUq0gzqDwQRAjz0AJ0ZexMPgBxHxQXBGshI6hghgXDD8ACgspRd
>>GWIHuG9P7iV9k/CNf+bGKsU=
>>=jyR8
>>-----END PGP SIGNATURE-----
>
>There are still bugs in the compiler that make writing compile-time functions a difficult task. In your case, the error is caused by retval not being explicitly initialized (in parseUnicodeCSV). Try
>
>RowData retval = RowData.init;
>
>But even if it is, the function still cannot be evaluated at compile-time. Trying to figure out why.

The compiler doesn't like string-to-null comparison in 'if' (looks like a compiler bug).  Try to make your algorythm not to rely on it.
July 24, 2007
Max Samukha wrote:
>> There are still bugs in the compiler that make writing compile-time functions a difficult task. In your case, the error is caused by retval not being explicitly initialized (in parseUnicodeCSV). Try
>>
>> RowData retval = RowData.init;
>>
>> But even if it is, the function still cannot be evaluated at compile-time. Trying to figure out why.

> The compiler doesn't like string-to-null comparison in 'if' (looks like a compiler bug).  Try to make your algorythm not to rely on it.

Many thanks for your help so far! :)

I've fixed it up so it's now no longer complaining about parseUnicodeCSV. So that's nice progress.

RowData.init was indeed a problem. Getting rid of the null-comparison
didn't work outright, though. I replaced it with:
	if (retval.len == 0)
but it was still complaining. It only started working when I initialized
the string to an empty string.

My guess is it doesn't like any pass-by-reference variable that is
uninitialized or null, and was probably going wrong at:
	if (start >= line.length)
just a couple of lines further down the code.

Now it's complaining about genSingleCategoryIf. I can't seem to identify this with any of the earlier problems.

I've reattached the latest version.

- -- Stéphan

July 24, 2007
Stéphan Kochen wrote:
> Now it's complaining about genSingleCategoryIf. I can't seem to identify
> this with any of the earlier problems.
[snip]
> private string uintToString(uint i)
> {
>     if (i < 10)
> 	    return [cast(char) (i + '0')];
>     else
>     	return uintToString(i / 10) ~ uintToString(i % 10);
> }
> 
> private string genSingleCategoryIf(string prop, uint start, uint end)
> {
>     if (start == end)
>     {
>         return "if (c == " ~ uintToString(start) ~ ")\n" ~
>                "    return GeneralCategory." ~ prop ~ ";\n" ~
>                "else ";
>     }
>     else
>     {
>         return "if (c >= " ~ uintToString(start) ~ " && " ~
>                "c <= " ~ uintToString(end) ~ ")\n" ~
>                "    return GeneralCategory." ~ prop ~ ";\n" ~
>                "else ";
>     }
> }

DMD doesn't seem to like that call to uintToString(start) from genSingleCategoryIf, even though it works fine on its own. The workaround is simple though, just change the single-digit case to 'return "0123456789"[i..i+1];'.
July 24, 2007
Frits van Bommel wrote:
> DMD doesn't seem to like that call to uintToString(start) from genSingleCategoryIf, even though it works fine on its own. The workaround is simple though, just change the single-digit case to 'return "0123456789"[i..i+1];'.

Awesome, it works! Many thanks! :)

Sad thing is, when running it over the full UnicodeData.txt, the thing dives deep into swap and even gets killed for excessive memory usage. XD

For now, I suppose I can leave the code intact for whenever the compiler improves. I can still use this at run-time with the alternate main (that just prints it using writefln) as an intermediate step to generate the actual getGeneralCategory (which is then compiled separately).

- -- Stéphan
July 24, 2007
> Sad thing is, when running it over the full UnicodeData.txt, the thing dives deep into swap and even gets killed for excessive memory usage. XD
> 
> For now, I suppose I can leave the code intact for whenever the compiler improves.

I've had to do the same thing with my code generation project, unfortunately. The issue seems to be that each write to an array will reallocate all of its contents while the old data is never removed.

Here's the post about it: http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmars.D.bugs&article_id=11471

I never got around to writing a bug report though...

Regards,
Christian