This is the mail archive of the guile@cygnus.com mailing list for the Guile project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: How can I write gh_longlong2scm, gh_ulonglong2scm and reverse?


Rob Browning <rlb@cs.utexas.edu> writes:

> Is there an easy way?  I'm trying to add long-long support to g-wrap.
> I've already got symbol-as-string, types with optional cleanup
> functions, and several other things working.  This is one of the last
> bits I need.

For anyone who's interested (which judging from the response isn't
many :>), here's how I added ulonglongs.  This is probably not the
most efficient implementation (it's fairly awkward), but given my
limited knowledge of guile's internals, it's the best I could come up
with in the short time I had.  It also hasn't been thoroughly tested
yet, but it seems OK.  Corrections, improvements, suggestions, all
welcome.

This code is freely available for guile (or whoever) under the terms
of the GPL.

  static int initialized_p = 0;
  static SCM longlongoffset;
  static SCM mult;
  static SCM add;
  static SCM quotient;
  static SCM remainder;

  static void
  initialize_longlongs() {
    longlongoffset = gh_eval_str("#x100000000");
    mult = gh_eval_str("*");
    add = gh_eval_str("+");
    quotient = gh_eval_str("quotient");
    remainder = gh_eval_str("remainder");
    initialized_p = 42;
  }

  SCM
  gh_ulonglong2scm(unsigned long long x) {
    const unsigned long upper = x >> 32;
    const unsigned long lower = (unsigned long) (x & 0xFFFFFFFF);
    SCM result;

    if(!initialized_p) initialize_longlongs();

    result = gh_call2(mult, gh_ulong2scm(upper), longlongoffset);
    result = gh_call2(add, result, gh_ulong2scm(lower));

    return(result);
  }

  unsigned long long
  gh_scm2ulonglong(SCM x) {
    unsigned long long result;
    unsigned long upper;
    unsigned long lower;
    SCM upper_scm;
    SCM lower_scm;

    if(!initialized_p) initialize_longlongs();

    upper_scm = gh_call2(quotient, x, longlongoffset);
    lower_scm = gh_call2(remainder, x, longlongoffset);

    upper = gh_scm2ulong(upper_scm);
    lower = gh_scm2ulong(lower_scm);

    result = (((unsigned long long) upper) << 32) | lower;

    return(result);
  }

-- 
Rob Browning <rlb@cs.utexas.edu> PGP=E80E0D04F521A094 532B97F5D64E3930

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]