www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Strange cast error in compile-time function

reply =?UTF-8?B?U3TDqXBoYW4gS29jaGVu?= <stephan kochen.nl> writes:
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

-----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,
- -- Stéphan
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.6 (GNU/Linux)

iD8DBQFGpiQucFUq0gzqDwQRAjz0AJ0ZexMPgBxHxQXBGshI6hghgXDD8ACgspRd
GWIHuG9P7iV9k/CNf+bGKsU=
=jyR8
-----END PGP SIGNATURE-----
Jul 24 2007
parent reply Max Samukha <samukha voliacable.com.removethis> writes:
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.
Jul 24 2007
parent reply Max Samukha <samukha voliacable.com.removethis> writes:
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.
Jul 24 2007
parent reply =?ISO-8859-1?Q?St=E9phan_Kochen?= <stephan kochen.nl> writes:
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: 8bit

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

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 -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.6 (GNU/Linux) iD8DBQFGpktocFUq0gzqDwQRAtWRAKDUPdPhp8KQ/ePPdjckKah1kG8jCgCgojgB ABzvVtOoqam9E86/fgRmvpI= =Ou+U -----END PGP SIGNATURE-----
Jul 24 2007
parent reply Frits van Bommel <fvbommel REMwOVExCAPSs.nl> writes:
Stéphan Kochen wrote:
 Now it's complaining about genSingleCategoryIf. I can't seem to identify
 this with any of the earlier problems.

 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];'.
Jul 24 2007
parent reply =?UTF-8?B?U3TDqXBoYW4gS29jaGVu?= <stephan kochen.nl> writes:
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

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 -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.6 (GNU/Linux) iD8DBQFGplpCcFUq0gzqDwQRAmtkAKDfO9p+0F72Ka26wtL9ZVAKqdMi9gCgobNl 9Qujy9md6XcZgeSW57SZiOQ= =d74o -----END PGP SIGNATURE-----
Jul 24 2007
parent Christian Kamm <kamm.incasoftware shift-at-left-and-remove-this.de> writes:
 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
Jul 24 2007