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

Attachment: signature.asc
Description: PGP signature

Reply via email to