Compiling guile-2.2.4 for mingw

2018-11-20 Thread Christoph Buck
Hi!

Currently i try to compile guile-2.2.4 under mingw64 bit. I had some
minor issues in the c source code which i managed to fix by applying
some of the patches from https://github.com/mkeeter/guile-mingw. Namely 

1) 0003-winsock-compat.mingw.patch
2) 0004-start_child.mingw.patch

Now i am at the point where i have a working guile binary and the helper
scripts in the meta directory. But at this point the boostrapping fails
with the following error:

> make[2]: Entering directory '/home/Christoph.Buck/guile-2.2.4/bootstrap'
>   BOOTSTRAP GUILEC ice-9/eval.go
> Backtrace:
> In ice-9/eval.scm:
> 619:8 19 (_ #(#(#)))
> 155:9 18 (_ _)
> In srfi/srfi-1.scm:
> 640:9 17 (for-each # ▒)
> In ice-9/eval.scm:
> 163:9 16 (_ _)
> In ice-9/boot-9.scm:
> 152:2 15 (with-fluid* _ _ _)
> In system/base/target.scm:
>  57:6 14 (with-target _ _)
> In system/base/compile.scm:
> 152:6 13 (compile-file _ #:output-file _ #:from _ #:to _ #:env _ ▒)
>  43:4 12 (call-once _)
> In ice-9/boot-9.scm:
> 841:4 11 (with-throw-handler _ _ _)
> In system/base/compile.scm:
> 59:11 10 (_)
>155:11  9 (_ #)
>224:14  8 (read-and-compile _ #:from _ #:to _ #:env _ #:opts _)
> 255:6  7 (compile _ #:from _ #:to _ #:env _ #:opts _)
>183:32  6 (compile-fold _ _ _ (#:to-file? #t #:warnings (#) # #t ▒))
> In language/cps/compile-bytecode.scm:
>591:12  5 (emit-bytecode _ # _)
> In ice-9/eval.scm:
> 163:9  4 (_ #(#(#) # #t))
> In unknown file:
>3 (_ # #<▒> ▒)
> In ice-9/eval.scm:
> 619:8  2 (_ #(#(#(#(#(#(#(#(#(#(#(▒) ▒) ▒) ▒) ▒) ▒) ▒) ▒) ▒) ▒) ▒))
> In unknown file:
>1 (bytevector-u64-set! #vu8(0 0 0 0 0 0 0 0 0 0 0 0 0 0 ▒) ▒)
> In ice-9/boot-9.scm:
>752:25  0 (dispatch-exception _ _ _)

> ice-9/boot-9.scm:752:25: In procedure dispatch-exception:
> In procedure bytevector-u64-set!: Value out of range: -149659645
> make[2]: *** [Makefile:1931: ice-9/eval.go] Error 1
> make[2]: Leaving directory '/home/Christoph.Buck/guile-2.2.4/bootstrap'
> make[1]: *** [Makefile:1857: all-recursive] Error 1
> make[1]: Leaving directory '/home/Christoph.Buck/guile-2.2.4'
> make: *** [Makefile:1743: all] Error 2

I have no idea what might be wrong here or how to fix this problem. Does
anbody have an idea?

Best regards

Christoph Buck



Re: Compiling guile-2.2.4 for mingw

2018-11-20 Thread tomas
On Tue, Nov 20, 2018 at 03:31:25PM +0100, Christoph Buck wrote:
> Hi!
> 
> Currently i try to compile guile-2.2.4 under mingw64 bit. I had some
> minor issues in the c source code which i managed to fix by applying
> some of the patches from https://github.com/mkeeter/guile-mingw. Namely 

[...]

> > ice-9/boot-9.scm:752:25: In procedure dispatch-exception:
> > In procedure bytevector-u64-set!: Value out of range: -149659645
> > make[2]: *** [Makefile:1931: ice-9/eval.go] Error 1
> > make[2]: Leaving directory '/home/Christoph.Buck/guile-2.2.4/bootstrap'
> > make[1]: *** [Makefile:1857: all-recursive] Error 1
> > make[1]: Leaving directory '/home/Christoph.Buck/guile-2.2.4'
> > make: *** [Makefile:1743: all] Error 2

This looks a bit like an integer wraparound. It could well be that mingw
has a different size for some of its integral types (long int?).

Sorry, this is from a big distance here...

Cheers
-- t


signature.asc
Description: Digital signature


Re: Compiling guile-2.2.4 for mingw

2018-11-20 Thread Eli Zaretskii
> From: Christoph Buck 
> Date: Tue, 20 Nov 2018 15:31:25 +0100
> 
> > ice-9/boot-9.scm:752:25: In procedure dispatch-exception:
> > In procedure bytevector-u64-set!: Value out of range: -149659645
> > make[2]: *** [Makefile:1931: ice-9/eval.go] Error 1
> > make[2]: Leaving directory '/home/Christoph.Buck/guile-2.2.4/bootstrap'
> > make[1]: *** [Makefile:1857: all-recursive] Error 1
> > make[1]: Leaving directory '/home/Christoph.Buck/guile-2.2.4'
> > make: *** [Makefile:1743: all] Error 2
> 
> I have no idea what might be wrong here or how to fix this problem. Does
> anbody have an idea?

I have a guess: bytevector-u64-set! uses GMP functions to store a
64-bit value, but GMP doesn't yet support that on Windows, because it
thinks it can get away with the 'long' type for that, and 'long' is a
32-bit type on Windows, even in 64-bit builds.

I would suggest first to build a 32-bit Guile against a 32-bit GMP.
If that fails in the same way, then my guess is wrong ;-)



Re: Compiling guile-2.2.4 for mingw

2018-11-20 Thread Christoph Buck
Mike Gran  writes:

> Hey Chris,
>
> This is one of two errors.  One problem is that Guile makes assumptions
> about the size of long vs the size of a pointer, as do some the
> libraries on which Guile depends.  In practice, your Guile needs to be
> compiled under MinGW 32-bit where sizeof(void *) == sizeof(long)

Ok that makes sense.

> There is another error that causes similar problems to the one you are
> seeing.  That error is because there is an error in Guile that under
> MinGW where it saves temporary files generated by 'mkstemp!' using the
> text encoding, so you end up with random carriage returns in your
> compiled scheme files.

I already wondered why my file-pathes were messed up.

> I do have a working mostly working MinGW Guile on my system.  You can
> check out the patches I did on a branch of the repo called
> wip-mingw-guile-2.2
>
> git.savannah.gnu.org/cgit/guile.git/log/?h=wip-mingw-guile-2.2
>
> At the beginning of the year, I think I submitted the first of these
> patches upstream, but, I got around to submitting the rest of them.
>
Ok i checked out your branch and it indeed seems to compile under
mingw32. However, I needed to comment out the pollfd struct definition in
lib/poll.in.h to prevent a collusion in the winsock2.h header (see
attached patch file). I guess this can be fixed more adequate somewhere
in the configure scripts? 

> Also note that the MinGW threading library (winpthreads) almost works
> with garbage collection, but, it isn't 100%, so you may need to only
> compile the single-threaded version of Guile.

Ok good to know.

Is there currently no way to get guile running under mingw-64bit? My plan
was to integrate guile in a project of mine which currently only builds
under 64bit.

> Good luck,
>
> Mike
>

Thanks

Christoph

--- lib/poll.in.h.orig	2018-11-20 17:58:03.317863600 +0100
+++ lib/poll.in.h	2018-11-20 17:58:35.920887000 +0100
@@ -55,12 +55,12 @@
 
 # if !GNULIB_defined_poll_types
 
-struct pollfd
-{
-  int fd;   /* which file descriptor to poll */
-  short events; /* events we are interested in   */
-  short revents;/* events found on return*/
-};
+/* struct pollfd */
+/* { */
+/*   int fd;   /\* which file descriptor to poll *\/ */
+/*   short events; /\* events we are interested in   *\/ */
+/*   short revents;/\* events found on return*\/ */
+/* }; */
 
 typedef unsigned long nfds_t;
 
@@ -75,28 +75,28 @@
 #endif
 
 
-#if @GNULIB_POLL@
-# if @REPLACE_POLL@
-#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
-#   undef poll
-#   define poll rpl_poll
-#  endif
-_GL_FUNCDECL_RPL (poll, int, (struct pollfd *pfd, nfds_t nfd, int timeout));
-_GL_CXXALIAS_RPL (poll, int, (struct pollfd *pfd, nfds_t nfd, int timeout));
-# else
-#  if !@HAVE_POLL@
-_GL_FUNCDECL_SYS (poll, int, (struct pollfd *pfd, nfds_t nfd, int timeout));
-#  endif
-_GL_CXXALIAS_SYS (poll, int, (struct pollfd *pfd, nfds_t nfd, int timeout));
-# endif
-_GL_CXXALIASWARN (poll);
-#elif defined GNULIB_POSIXCHECK
-# undef poll
-# if HAVE_RAW_DECL_POLL
-_GL_WARN_ON_USE (poll, "poll is unportable - "
- "use gnulib module poll for portability");
-# endif
-#endif
+/* #if @GNULIB_POLL@ */
+/* # if @REPLACE_POLL@ */
+/* #  if !(defined __cplusplus && defined GNULIB_NAMESPACE) */
+/* #   undef poll */
+/* #   define poll rpl_poll */
+/* #  endif */
+/* _GL_FUNCDECL_RPL (poll, int, (struct pollfd *pfd, nfds_t nfd, int timeout)); */
+/* _GL_CXXALIAS_RPL (poll, int, (struct pollfd *pfd, nfds_t nfd, int timeout)); */
+/* # else */
+/* #  if !@HAVE_POLL@ */
+/* _GL_FUNCDECL_SYS (poll, int, (struct pollfd *pfd, nfds_t nfd, int timeout)); */
+/* #  endif */
+/* _GL_CXXALIAS_SYS (poll, int, (struct pollfd *pfd, nfds_t nfd, int timeout)); */
+/* # endif */
+/* _GL_CXXALIASWARN (poll); */
+/* #elif defined GNULIB_POSIXCHECK */
+/* # undef poll */
+/* # if HAVE_RAW_DECL_POLL */
+/* _GL_WARN_ON_USE (poll, "poll is unportable - " */
+/*  "use gnulib module poll for portability"); */
+/* # endif */
+/* #endif */
 
 
 #endif /* _@GUARD_PREFIX@_POLL_H */



Re: Compiling guile-2.2.4 for mingw

2018-11-20 Thread Mike Gran
On Tue, Nov 20, 2018 at 06:16:32PM +0100, Christoph Buck wrote:
> Mike Gran  writes:
> 
> > Hey Chris,
> >
> > This is one of two errors.  One problem is that Guile makes assumptions
> > about the size of long vs the size of a pointer, as do some the
> > libraries on which Guile depends.  In practice, your Guile needs to be
> > compiled under MinGW 32-bit where sizeof(void *) == sizeof(long)
> 
> Ok that makes sense.
> 
> > There is another error that causes similar problems to the one you are
> > seeing.  That error is because there is an error in Guile that under
> > MinGW where it saves temporary files generated by 'mkstemp!' using the
> > text encoding, so you end up with random carriage returns in your
> > compiled scheme files.
> 
> I already wondered why my file-pathes were messed up.
> 
> > I do have a working mostly working MinGW Guile on my system.  You can
> > check out the patches I did on a branch of the repo called
> > wip-mingw-guile-2.2
> >
> > git.savannah.gnu.org/cgit/guile.git/log/?h=wip-mingw-guile-2.2
> >
> > At the beginning of the year, I think I submitted the first of these
> > patches upstream, but, I got around to submitting the rest of them.
> >
> Ok i checked out your branch and it indeed seems to compile under
> mingw32. However, I needed to comment out the pollfd struct definition in
> lib/poll.in.h to prevent a collusion in the winsock2.h header (see
> attached patch file). I guess this can be fixed more adequate somewhere
> in the configure scripts? 

OK. I don't remember running into that, but, I'll double check when I
get a chance.

> 
> > Also note that the MinGW threading library (winpthreads) almost works
> > with garbage collection, but, it isn't 100%, so you may need to only
> > compile the single-threaded version of Guile.
> 
> Ok good to know.
> 
> Is there currently no way to get guile running under mingw-64bit? My plan
> was to integrate guile in a project of mine which currently only builds
> under 64bit.

Well anything is possible, of course. Here is a list of my recollections,
but it has been a few months since I looked at it.

First, as Eli Z mentions in his email, GMP may need to be fixed to not
make incorrect assumptions about the sizeof(long) and int, etc.

Second, the Guile numbers infrastructure should probably be rejiggered
to keep using 32-bit INum immediate number types even under 64-bit
builds if long == 32-bit, or to always use int64_t instead of int.

Third, there are a few of the Guile Virtual Machine opcodes that need
to disambiguate if it means sizeof(void *) or size of an integer type.

Sorry that is pretty vague.  I can't recall the details.

I think it might be a tricky business overall.

I only fixed that MinGW build enough to enter a game jam with Guile,
so I haven't put too much effort into it, really.  But I came in
10th place, so hooray.

Regards,

Mike Gran





Re: Compiling guile-2.2.4 for mingw

2018-11-20 Thread Jan Nieuwenhuizen
Christoph Buck writes:

> Currently i try to compile guile-2.2.4 under mingw64 bit.

Oh, interesting!

> I had some minor issues in the c source code which i managed to fix by
> applying some of the patches from
> https://github.com/mkeeter/guile-mingw. Namely
>
> 1) 0003-winsock-compat.mingw.patch
> 2) 0004-start_child.mingw.patch

What is the relation with or status of the wip-mingw-guile branch on
savannah?

http://git.savannah.gnu.org/cgit/guile.git/log/?h=wip-mingw-guile-2.2

Does this build on top of that, what would be needed to get
wip-mingw-guile merged?

janneke

-- 
Jan Nieuwenhuizen  | GNU LilyPond http://lilypond.org
Freelance IT http://JoyofSource.com | Avatar® http://AvatarAcademy.com



Re: Compiling guile-2.2.4 for mingw

2018-11-20 Thread Mark H Weaver
Mike Gran  writes:

> On Tue, Nov 20, 2018 at 06:16:32PM +0100, Christoph Buck wrote:
>> Is there currently no way to get guile running under mingw-64bit? My plan
>> was to integrate guile in a project of mine which currently only builds
>> under 64bit.
>
> Well anything is possible, of course. Here is a list of my recollections,
> but it has been a few months since I looked at it.
>
> First, as Eli Z mentions in his email, GMP may need to be fixed to not
> make incorrect assumptions about the sizeof(long) and int, etc.

bytevector-u64-{ref,set!} use 'mpz_import' and 'mpz_export', but I don't
see any assumption in that particular code that 'long' is 64-bits.

However, in general, it does seem to be the case that Guile code has
often been written with the assumption that sizeof(long) ==
sizeof(void*).  I fixed several of these instances, but I suspect that
many more remain.  That issue is being tracked here:

  https://bugs.gnu.org/22406

> Second, the Guile numbers infrastructure should probably be rejiggered
> to keep using 32-bit INum immediate number types even under 64-bit
> builds if long == 32-bit, or to always use int64_t instead of int.

No need for rejiggering, because it's already the case.  Guile currently
always uses 'long' as the immediate number type, precisely because
that's the C integer type that GMP's mpz_*_si functions accept.
Specifically, numbers.h contains this:

  typedef long scm_t_inum;
  #define SCM_I_FIXNUM_BIT (SCM_LONG_BIT - 2)
  #define SCM_MOST_NEGATIVE_FIXNUM (-1L << (SCM_I_FIXNUM_BIT - 1))
  #define SCM_MOST_POSITIVE_FIXNUM (- (SCM_MOST_NEGATIVE_FIXNUM + 1))

> Third, there are a few of the Guile Virtual Machine opcodes that need
> to disambiguate if it means sizeof(void *) or size of an integer type.

I'm not sure I understand.  Can you give a specific example of an opcode
that needs to be disambiguated?

> I think it might be a tricky business overall.
>
> I only fixed that MinGW build enough to enter a game jam with Guile,
> so I haven't put too much effort into it, really.  But I came in
> 10th place, so hooray.

Nice! :)

Thanks,
  Mark



Re: Feature request: Expose `ellipsis?' from psyntax.ss

2018-11-20 Thread Mark H Weaver
Hi Marc,

Marc Nieper-Wißkirchen  writes:

>  > Let's run the following example:
>  >
>  > (eval-when (expand)
>  >   (define-syntax bar
>  > (syntax-rules ()
>  >   ((_ stx)
>  >(syntax-case stx ()
>  >  ((_ a (... ...))
>  >   #'#t)
>  >  ((_ a b c)
>  >   #'#f))
>  >
>  > (define-syntax foo
>  >   (lambda (stx)
>  > (with-ellipsis e (bar stx
>  >
>  > (display (foo 1 2 3))
>  > (newline)
>
>  [Note: I fixed the indentation in the definition of 'bar' above, which
> was misleading as it appeared in your email.]
>
>  > This one displays `#t' in Guile, which is exactly what we want. I
>  > guess the reason is that the macro invocation `(bar stx)' creates a
>  > new transformer environment, in which `{# $sc-ellipsis #}' becomes
>  > unbound again.
>
>  No, this is not quite right.  When the transformer code of 'foo' is
>  expanded, 'bar' expands into a 'syntax-case' form, and that
>  'syntax-case' form is indeed expanded within a transformer environment
>  that includes the ellipsis binding introduced by the 'with-ellipsis'
>  form in 'foo'.
>
>  However, all of the bindings in the transformer environment bind
>  *gensyms*.  These gensyms are effectively inaccessible unless the wrap
>  includes a substitution that maps user-visible identifiers into those
>  gensyms.
>
> So I should view the transformer environment as a store, shouldn't I?
> During the course of expansion, the transformer environment is
> monotonically growing,

No, it does not monotonically grow during the course of expansion.  One
way to think about it is that it's the lexical environment of the
_expanded_ code.  It therefore only grows when the macro expander
_descends_ into a core lexical binding form.  For example, in

  (let ((x (let ((y 4))
 (+ y y
(+ x x))

the expansion environment used to expand (+ x x) does not include a
binding for the gensym corresponding to 'y'.

>  In general, that's how Psyntax implements lexical binding.  When a core
>  binding form is encountered, a fresh gensym is bound in the transformer
>  environment, and that new environment is used to expand all forms
>  within, including the results of expanding macros within, which in
>  general include identifiers that originally appeared in macro
>  definitions elsewhere that are not in the lexical scope of those
>  bindings.
>
>  The reason this works is because when a core binding form is encountered
>  by the expander, the fresh gensym is substituted for all free references
>  of the user-visible identifier in the body, *before* expanding the
>  macros found within.  The substitution is deferred using the 'wrap'
>  mechanism, but the result is the same.  Any identifiers not visible in
>  the body at that time are not affected by that subtitution.
>
>  Ellipsis identifiers are a bit more tricky, because unlike other
>  bindings, the user-visible ellipsis identifiers are not actually
>  substituted.  We can't do that because ellipsis identifiers can be used
>  for other purposes, e.g. bound to ordinary variables or macros, and
>  these two ways of binding ellipsis identifiers should not shadow each
>  other.
>
> Is this universally true? Maybe I misunderstood what you mean about
> shadowing. How about the following?
>
> (use-modules (guile))
> (define-syntax ... (syntax-rules ()))
> (define-syntax bar
>   (syntax-rules ()
> ((_ ...) ...)))
>
> At least by the R7RS, this shouldn't yield an error due to a misplaced
> ellipsis.

I'm not aware of any language in the R[567]RS that makes it clear
whether '...' should be recognized as an ellipsis if it is bound to a
variable.  The Scheme implementations I tried do not seem to agree.

For example, consider this example:

  (let ((... 'hello))
(let-syntax ((foo (syntax-rules ()
((foo x ...)
 '((x) ...)
  (foo 1 2)))

If '...' is recognized as an ellipsis within the 'let', then the result
will be '((1) (2)).  Otherwise, the result will be '((1) 2).

I found that Racket 7.0, Chicken 4.13.0, and Scheme48 1.9.2 return
'((1) (2)).  Chibi-Scheme returns '((1) 2).  I see the same results
with this variant:

  (let-syntax ((... (syntax-rules (
(let-syntax ((foo (syntax-rules ()
((foo x ...)
 '((x) ...)
  (foo 1 2)))

If we instead bind '...' as a top-level variable:

  (define-syntax ... (syntax-rules ()))
  (let-syntax ((foo (syntax-rules ()
  ((foo x ...)
   '((x) ...)
(foo 1 2))

Then all four of these Schemes agree that the answer is '((1) (2)),
including Chibi-Scheme.

> And what about:
>
> (with-ellipsis e
>   (define-syntax e (syntax-rules ()))
>   (define-syntax bar
> (syntax-rules ()
>   ---)))
>
> Is `e' recognized as the ellipsis in `---'?

Yes.  For example:

  (with-ellipsis e
(define-syntax e (syntax-rules ()))
(let-syntax ((foo (syntax-rules