larcenists / larceny

Larceny Scheme implementation
Other
202 stars 32 forks source link

Problem with library compiler #777

Closed mnieper closed 7 years ago

mnieper commented 8 years ago

I have encountered a strange bug:

$ cat program.scm
(import (scheme base)
            (lib))

(and-let*
    ((a 1))
  2)
$ cat lib.sld
(define-library (lib)
  (export and-let*)
  (cond-expand
   ((library (srfi 2))
    (import (srfi 2)))))
$ compile-stale
Compiling lib.sld
$ larceny -path . -r7rs -program program.scm

Syntax violation: and-let*

Undefined variable or reference to macro keyword out of context

Form: (and-let* ((a 1)) 2)

Trace: 

  (and-let* ((a 1)) 2)

Error: unhandled condition:
Compound condition has these components: 
#<record &who>
    who : and-let*
#<record &message>
    message : "Undefined variable or reference to macro keyword out of context"
#<record &syntax>
    form : (and-let* ((a 1)) 2)
    subform : #f

Entering debugger; type "?" for help.
debug>    
WillClinger commented 8 years ago

Experimentation and examination of the .slfasl files suggests a build-consistency problem, as though compile-stale isn't seeing the pre-compiled version of (srfi 2).

WillClinger commented 7 years ago

No, it appears to be a cond-expand problem.

The build-consistency red herring arose because I was trying to use a development version of compile-stale, which calls scheme-script, which resolved to a production version of Larceny and therefore used the production versions of R7RS libraries instead of the development versions of those libraries.

WillClinger commented 7 years ago

No, it isn't a cond-expand problem either. It has something to do with using multiple import declarations to import libraries that define macros that will be exported.

(define-library (lib)
  (export and-let* receive)
  (import (scheme base)
          (srfi 2)
          (srfi 8)))

works but

(define-library (lib)
  (export and-let* receive)
  (import (scheme base))
  (import (srfi 2))
  (import (srfi 8)))

does not.

WillClinger commented 7 years ago

Allowing import declarations to appear anywhere within a library body was new in R7RS, and I didn't quite implement it correctly. It looks as though libraries that aren't imported at the beginning of the define-library form are being invoked correctly but are not being visited (for expand) correctly.

This should be straightforward to fix, but it's delicate because it may interact with the semantics of for/run/expand/meta in R6RS library forms. There appears to be near-consensus that strict enforcement of meta levels is unnecessary and counter-productive even for R6RS programs. (See also ticket #747.) I may try to repair those problems all at once, because all involve changes to related parts of Andre van Tonder's library/macro expander, but that ambition will make the repair even more delicate.

WillClinger commented 7 years ago

Fixed by changeset a58411fa747caff7226388aad54ee07bca32dcfa

Strict enforcement of meta levels was dropped beginning with v0.99; see changeset 7636ef5fa8f62b369b2eb1830578d4973d9c36eb