Re: "cannot coerce inexact literal to fixnum"

Peter Bex <[email protected]>
Newsgroups gmane.lisp.scheme.chicken
Message-ID <ZceKm7RCdyEQ9wDk@doggett>
On Sat, Feb 10, 2024 at 04:07:12PM +0200, Al wrote:
> On 2024-02-10 15:38, Peter Bex wrote:
> 
> > That's because you're using fixnum mode.  As I explained, using literals
> > that might be too large for fixnums break the fixnum mode's premise that
> > everything must be a fixnum.
> 
> Oh. So it refuses to emit C code that might break on 32-bit at runtime
> (silent truncation of atoi result, presumably), preferring instead to
> definitely break during Scheme compilation on any platform. OK, I get the
> rationale.

Yup.  Like I said, it might be doable to add some sort of mode where it
could be used to compile in fixnum mode exclusively for 64-bit
platforms, but someone would have to spend the time to do so.

> > That's because string->number gets constant-folded and evaluated at
> > compile-time.
> 
> Obviously; and I suppose there's no simple way to prevent that for just one
> line, not the entire unit?

Not really.  The foreign-value you've been using is a good hack because
it performs exactly the conversion that you're looking for under the hood.
It also forms an optimization barrier so the constant can't be
precalculated.

Note that foreign-value can still return bignums on 32-bit platforms if
the value doesn't fit in a fixnum (this is done by C_unsigned_int_to_num
in chicken.h) and you're using integer32.  The int32 version doesn't do
this and assumes it'll just fit into a fixnum.

> I did mention twice that I'm using them to implement int->u32.

That should only be needed if you generated values bigger than 32-bit.
Again, these could still be bignums when run on a 32-bit platform
(that's why the return type of s32vector-ref is defined as "integer" and
not "fixnum")

> There are also places where I need to increment-and-wrap int32's by INT32_MIN. I'm
> writing a Forth compiler incidentally (which may or may not have been a good
> idea). I store values in s32vector's, but they get turned into Scheme
> numbers by s32vector-ref. I guess I'd prefer native s32int/u32int types,
> complete with wrap-around and meaningful conversion to Scheme ints, but I
> don't think that exists.

Unfortunately, no.

Another way of accomplishing what you want is to use the fx operations
directly.  AFAICT those aren't constant-folded.

So something like this should work:

(define (->32bit x) (fxand (- (fxshl 1 32) 1) x))

Alternatively, put the conversion code (including big-fixnum literals)
in a separate Scheme file which is compiled *without* fixnum mode, and
call it from the file that is compiled in fixnum mode.

Cheers,
Peter
signature.asc (application/pgp-signature, 488 B)
-----BEGIN PGP SIGNATURE-----

iQEzBAEBCAAdFiEE6bh5EUSYP1EE+1UTER25+ctFibAFAmXHipcACgkQER25+ctF
ibAziwf8ChewtqX/xl4WZLLc0fTRFLrP4laBrUHzjogVl9tELR5mpnGRMTn5MNv9
uB2jjOf1rIX6PlF0rpHTI+01L2NUTqeo4Tl0ajvz1WbrtNxiu+jeIMA5k7z21u9z
QPbm85hcl+qsi6s41bPQWly91HQTHcXOK95bpFN7+/jmkeynmp0nZH2VDP+/EMBv
TAcwkfWzQx8h1uHcRnvxKkV6msb1DG9vlKxlminFKHdjU/wD0oO+jXuShf7+0vYQ
RD+ysMRIbS0PQHPNelqeOFOfX1dX1iqvzZF1EQi62nsc8BjJPblnSSZJ2dEWgBoa
gClxKKREfuOA1HzUe3ZPrGpW10E11A==
=SgEF
-----END PGP SIGNATURE-----
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.