[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Chicken-hackers] [PATCH] Add 'a shorthand for forall types
From: |
Peter Bex |
Subject: |
Re: [Chicken-hackers] [PATCH] Add 'a shorthand for forall types |
Date: |
Fri, 8 Jun 2018 20:46:43 +0200 |
User-agent: |
NeoMutt/20170113 (1.7.2) |
Hi all,
In the interest of moving forward with CHICKEN 5, I propose
that we postpone all the below changes to 5.1.
On Tue, May 29, 2018 at 01:18:02PM +0300, megane wrote:
> Hello,
>
> This adds support for declaring forall types in more compact manner.
>
> It supports syntax like ('a -> 'a) to declare the type
> (forall (a) (a -> a)).
>
> diff --git a/manual/Types b/manual/Types
> index 6d5de10..cab029d 100644
> --- a/manual/Types
> +++ b/manual/Types
> @@ -158,6 +158,12 @@ or {{:}} should follow the syntax given below:
>
> (*) Note: no type-variables are bound inside {{(not TYPE)}}.
>
> +You can use a shorthand {{'SYMBOL}} for introducing free variables in
> +{{forall}} types, examples:
> +
> + ('a -> 'a) is translated to (forall (a) (a -> a))
> + (forall (a) ('a -> a)) is translated to (forall (a) (a -> a))
> +
> Note that type-variables in {{forall}} types may be given "constraint"
> types, i.e.
>
> (: sort (forall (e (s (or (vector-of e) (list-of e))))
> diff --git a/scrutinizer.scm b/scrutinizer.scm
> index ece07ed..6d4a0c8 100644
> --- a/scrutinizer.scm
> +++ b/scrutinizer.scm
> @@ -1967,6 +1967,16 @@
> (second t))
> constraints))
> (validate (third t) rec)))))
> + ((and (eq? 'quote (car t))
> + (pair? (cdr t))
> + (symbol? (second t))
> + (null? (cddr t))
> + (second t))
> + =>
> + (lambda (v)
> + (unless (memq v typevars)
> + (set! typevars (cons v typevars)))
> + v))
> ((eq? 'or (car t))
> (and (list? t)
> (let ((ts (map validate (cdr t))))
> diff --git a/tests/typematch-tests.scm b/tests/typematch-tests.scm
> index 44c6c32..8a01094 100644
> --- a/tests/typematch-tests.scm
> +++ b/tests/typematch-tests.scm
> @@ -3,6 +3,7 @@
>
> (import chicken.blob chicken.condition chicken.memory chicken.locative)
>
> +(define something)
>
> (define (make-list n x)
> (list-tabulate n (lambda _ x)))
> @@ -394,3 +395,22 @@
> (compiler-typecase #x7fffffffffffffff
> (fixnum #f)
> (bignum #t)))
> +
> +(assert
> + (compiler-typecase 1
> + ('a #t)))
> +
> +(assert
> + (compiler-typecase (the (list fixnum string string) something)
> + ((list 'a 'a 'b) #f)
> + ((list 'a 'b 'b) #t)))
> +
> +(assert
> + (compiler-typecase (the (list fixnum string string) something)
> + ((forall (a) (list a 'a 'b)) #f)
> + ((forall (b) (list 'a 'b b)) #t)))
> +
> +(assert
> + (compiler-typecase (the (list string (list string fixnum)) something)
> + ((list 'a (forall (a) (list 'b a))) #f)
> + ((list 'b (forall (b) (list b 'a))) #t)))
> _______________________________________________
> Chicken-hackers mailing list
> address@hidden
> https://lists.nongnu.org/mailman/listinfo/chicken-hackers
On Tue, May 29, 2018 at 10:51:37AM +0300, megane wrote:
> Hi,
>
> There were cases in match-types which essentially duplicated what
> expand-type was doing. This is a simple refactoring to remove that
> duplication.
>
> diff --git a/scrutinizer.scm b/scrutinizer.scm
> index ece07ed..c89bd60 100644
> --- a/scrutinizer.scm
> +++ b/scrutinizer.scm
> @@ -138,6 +138,15 @@
> s64vector f32vector f64vector thread queue environment time
> continuation lock mmap condition hash-table tcp-listener))
>
> +(define-constant type-expansions
> + '((pair . (pair * *))
> + (list . (list-of *))
> + (vector . (vector-of *))
> + (boolean . (or true false))
> + (integer . (or fixnum bignum))
> + (number . (or fixnum float bignum ratnum cplxnum))
> + (procedure . (procedure (#!rest *) . *))))
> +
> (define-inline (struct-type? t)
> (and (pair? t) (eq? (car t) 'struct)))
>
> @@ -1042,18 +1051,8 @@
> ((eq? t2 'undefined) #f)
> ((eq? t1 'noreturn))
> ((eq? t2 'noreturn))
> - ((eq? t1 'boolean) (match1 '(or true false) t2))
> - ((eq? t2 'boolean) (match1 t1 '(or true false)))
> - ((eq? t1 'integer) (match1 '(or fixnum bignum) t2))
> - ((eq? t2 'integer) (match1 t1 '(or fixnum bignum)))
> - ((eq? t1 'number) (match1 '(or fixnum float bignum ratnum cplxnum)
> t2))
> - ((eq? t2 'number) (match1 t1 '(or fixnum float bignum ratnum
> cplxnum)))
> - ((eq? t1 'pair) (match1 '(pair * *) t2))
> - ((eq? t2 'pair) (match1 t1 '(pair * *)))
> - ((eq? t1 'list) (match1 '(list-of *) t2))
> - ((eq? t2 'list) (match1 t1 '(list-of *)))
> - ((eq? t1 'vector) (match1 '(vector-of *) t2))
> - ((eq? t2 'vector) (match1 t1 '(vector-of *)))
> + ((maybe-expand-type t1) => (cut match1 <> t2))
> + ((maybe-expand-type t2) => (cut match1 t1 <>))
> ((and (pair? t1) (eq? 'not (car t1)))
> (fluid-let ((all (not all)))
> (let* ((trail0 trail)
> @@ -1356,17 +1355,9 @@
> (dd "simplify: ~a -> ~a" t t2)
> t2)))
>
> -(define (expand-type t)
> - (case t
> - ((pair) '(pair * *))
> - ((list) '(list-of *))
> - ((vector) '(vector-of *))
> - ((boolean) '(or true false))
> - ((integer) '(or fixnum bignum))
> - ((number) '(or fixnum float bignum ratnum cplxnum))
> - ((procedure) '(procedure (#!rest *) . *))
> - (else t)))
> -
> +(define (maybe-expand-type t)
> + (and (symbol? t)
> + (alist-ref t type-expansions eq?)))
>
> ;;; Merging types
>
> @@ -1432,10 +1423,8 @@
> (define (refine t1 t2 te)
> (let loop ((t1 t1) (t2 t2))
> (cond
> - ((and (symbol? t1) (memq t1 '(pair list vector boolean integer number)))
> - (loop (expand-type t1) t2))
> - ((and (symbol? t2) (memq t2 '(pair list vector boolean integer number)))
> - (loop t1 (expand-type t2)))
> + ((maybe-expand-type t1) => (cut loop <> t2))
> + ((maybe-expand-type t2) => (cut loop t1 <>))
> ((and (pair? t1) (memq (car t1) '(forall refine)))
> (let ((t1* (loop (third t1) t2)))
> (and t1* (list (car t1) (second t1) t1*))))
> _______________________________________________
> Chicken-hackers mailing list
> address@hidden
> https://lists.nongnu.org/mailman/listinfo/chicken-hackers
On Tue, May 29, 2018 at 06:42:33PM +1200, Evan Hanson wrote:
> Hello fellow hackers,
>
> Here is a big, gnarly patch that finishes the work I started in Bergen,
> which was to change the way we handle library dependencies so that units
> can be loaded conditionally. This was inspired by Peter's changes to
> make import expressions lexically-scoped, so that you can write a
> program like the following and have it work like you'd expect:
>
> (if (some-condition)
> (let () (import (foo)) ...)
> (let () (import (bar)) ...))
>
> With Peter's changes, those imports will only affect the syntactic
> environments of their respective branches. However, when the libraries
> "foo" and "bar" are compiled in (for example when "-static" is used),
> they'll both be loaded unconditionally. This patch changes things so
> that those libraries will only be loaded when program execution reaches
> the corresponding import expression.
>
> I'm sorry about the size of the diff, but I needed to rework quite a bit
> of bookkeeping for this to work. I also took the opportunity to clean up
> some related bits of code and rip out some provisional things that were
> left over from my last round of library loading changes. The commit
> message is exhaustive, and probably exhausting too.
>
> Note that I've taken care to preserve the current behaviour of the
> "-uses" flag and "(uses ...)" declaration, which "hoist" the named units
> to the top level and call them at the start of the program. This makes
> the code slightly more complex than it would otherwise be, but I wanted
> to preserve the idea that declarations have unit-global effect. The
> correct way to link a program with a unit that may *or may not* be
> loaded during program execution is to use the "-link" flag.
>
> Another complicating factor was static libraries containing modules that
> export syntax, which contain those now-infamous "(eval '(import-syntax
> ...))" forms. Previously, such `eval' expressions would never cause an
> [unsuccessful] attempt to load a dynamic library into a static program
> because the imported module's implementing library would have already
> been loaded (at the start of the program, thanks to the aforementioned
> unit hoisting), indicating that the module is already provided. Now,
> however, that library's top level is only entered when the "culpable"
> import expression is reached, but the `eval' form will always precede
> that point in the program. Luckily, the compiler knows exactly what
> libraries need to be loaded before the `eval' expression to avoid this
> situation, because it can consult the module's import forms. So, we now
> inject the necessary library entrypoints into the program just before
> the `eval' (this is the `compiled-module-dependencies' bit of the patch
> that does this, in modules.scm). This is only done when necessary, i.e.
> for statically compiled modules that export syntax.
>
> I've tested this pretty extensively, but I also know that it's nasty in
> terms of sheer size (15 files changed, 266 insertions, 309 deletions),
> so please just let me know if you have any questions and I'll do my best
> to help clarify what's going on.
>
> Cheers,
>
> Evan
> >From 7a4622bfcf1c727c05b6a6bf5cbfb754914d289b Mon Sep 17 00:00:00 2001
> From: Evan Hanson <address@hidden>
> Date: Tue, 29 May 2018 18:33:00 +1200
> Subject: [PATCH] Rework library loading to support conditional unit entry
>
> This makes a handful of changes to the way library dependencies are
> processed in order to support conditional unit loading, i.e. not calling
> a unit's entry procedure unless its code path is really visited:
>
> Drop the `file-requirements' hash table in favour of two "lset" globals,
> `library-requirements' and `unit-requirements', the first of which is a
> superset of the second. The `unit-requirements' list includes everything
> that needs to be linked with the program statically (i.e. as a unit),
> and everything else is a runtime dependency (i.e. loaded as a shared
> object or source file). Remove the "M" debug option.
>
> Introduce a new `uses-declarations' global to keep track of units that
> are specified with "-uses" or `(declare (uses))'. These are hoisted to
> the top level and called at the start of the program. Construct the list
> of `used-units', which is used to generate prototypes for external unit
> toplevels in the C backend, by simply remembering all `##core#callunit'
> nodes as they're encounted during canonicalisation.
>
> Split the batch driver's `initforms' list into two separate values, one
> for import forms (which must be included within the program's wrapper
> module's body, if one is used) and one for compiler-introduced
> initialisation forms (which must precede the profiling-related
> expressions that are inserted into the program when profiling is
> enabled, since they're responsible for loading the "profiler" unit).
> Move all "forms" bindings together in the `let' that introduces them.
>
> Simplify `##sys#process-require' so that it expects just a library name
> and compilation flag as arguments, and returns just a single value. Get
> rid of the `provided' list, which is no longer necessary.
>
> For modules that export syntax in static libraries (where module
> information is compiled into the libraries themselves), emit code that
> will load the module's library dependencies *before* the code for
> runtime evaluation of the module's import forms, that is, "(scheme#eval
> '(import-syntax ...))". This ensures that static programs do not attempt
> to dynamically load the named import libraries dynamically, since
> dlopen(3) et al. are specifically disabled by static compilation. We
> communicate this situation to `##sys#compiled-module-registration' with
> a compile mode flag, for consistency with `##sys#process-require'.
>
> Only include a library name in emitted import libraries when the program
> under compilation is actually a library. When it's an executable, it
> can't be loaded anyway, so including a library name in the import
> library isn't useful and only complicates the handling of later import
> forms.
>
> Do away with requirement identifiers for modules, which were always a
> hack. They muddy the runtime's require/provide mechanics, and they were
> only added to support the corner case where an import library is emitted
> for a dynamic library that is only accessible under a different name. We
> can do without this, given the above changes. A different approach to
> this problem may be developed under ticket #1463.
>
> Avoid inserting unnecessary `##core#callunit' forms into the program
> prelude by using `import-syntax' for all implicitly-available imports
> (rather than the standard `import' form, which will generate a
> corresponding `##core#require').
>
> Remove "files" from the list of core units in eval.scm, since it no
> longer exists. Add "profiler", "scheduler", and "debugger-client", which
> do exist and should be considered core units.
>
> Change the meaning of the "-link" option so that it indicates libraries
> that should be linked iff they're required, rather than always
> generating a call to their entrypoints (thus requiring them to be linked
> unconditionally, as is the case with "-uses"). This option now also
> needs to be plumbed through to the "chicken" program, which handles the
> differentiation between static and (potentially) dynamic requirements.
>
> There is also some only-very-slightly-related refactoring in this patch:
>
> Simplify some of the internal procedures in eval.scm. The
> `load-library/internal' and `##sys#load-library' procedures can be
> combined, as can `load-extension/internal' and `load-extension'. Rename
> the internal version of the `load-library' procedure to `load-unit',
> since that's really what it does, and use it in the expansion of
> `##core#require'.
>
> Refactor the `##core#module' canonicalisation code for better
> readability. It was previously unclear what values really needed to be
> parameterised over what, which these changes hope to clarify.
>
> Reconstruct import forms using the literal import prefix symbols in
> `##sys#decompose-import', to make clear that they are indeed stored on
> their modules sans aliasing in `module-import-forms' et al.
>
> Fix a latent bug in `##sys#decompose-import' where "spec" (a list) was
> used to issue a warning rather than "name" (a symbol). This led to an
> invalid argument error arising from `symbol->string'.
>
> Reindent two cond arrows that were aligned too far to the right in
> `##sys#decompose-import'.
>
> Drop the `stripu' alias from `process-declaration' and simply call
> `strip-syntax' directly instead. `stripu' was only used in two places.
>
> Mark `##sys#register-profile-info` and `##sys#set-profile-info-vector!'
> as always `bound-to-procedure' in the declarations that are inserted
> into profiled programs.
> ---
> batch-driver.scm | 144 ++++++++++++++-------------
> c-platform.scm | 8 +-
> chicken-syntax.scm | 2 +-
> core.scm | 214
> ++++++++++++++++-------------------------
> csc.scm | 2 +-
> eval.scm | 140 ++++++++++++---------------
> expand.scm | 2 +-
> modules.scm | 40 +++++---
> support.scm | 1 -
> tests/compiler-tests.scm | 7 ++
> tests/import-library-test2.scm | 2 -
> tests/runtests.bat | 2 +-
> tests/runtests.sh | 4 +-
> tests/scrutiny.expected | 4 +-
> tests/test-chained-modules.scm | 3 +-
> 15 files changed, 266 insertions(+), 309 deletions(-)
>
> diff --git a/batch-driver.scm b/batch-driver.scm
> index fc7afb04..0b84a1b5 100644
> --- a/batch-driver.scm
> +++ b/batch-driver.scm
> @@ -186,29 +186,31 @@
> (when (memq 'static options)
> (set! static-extensions #t)
> (register-feature! 'chicken-compile-static))
> - (let* ((dynamic (memq 'dynamic options))
> - (unit (memq 'unit options))
> - (initforms `((import-for-syntax ,@default-syntax-imports)
> - (##core#declare
> - ,@(append
> - default-declarations
> - (if emit-debug-info
> - '((uses debugger-client))
> - '())
> - (if explicit-use-flag
> - '()
> - `((uses ,@default-units)))
> - (if (and static-extensions
> - enable-module-registration
> - (not dynamic)
> - (not unit)
> - (not explicit-use-flag))
> - '((uses eval-modules))
> - '())))
> - ,@(if explicit-use-flag
> - '()
> - `((import ,@default-imports)))))
> - (verbose (memq 'verbose options))
> + (let* ((unit (memq 'unit options))
> + (dynamic (memq 'dynamic options))
> + (forms '())
> + (init-forms `((import-for-syntax ,@default-syntax-imports)
> + (##core#declare
> + ,@(append
> + default-declarations
> + (if emit-debug-info
> + '((uses debugger-client))
> + '())
> + (if explicit-use-flag
> + '()
> + `((uses ,@default-units)))
> + (if (and static-extensions
> + enable-module-registration
> + (not dynamic)
> + (not unit)
> + (not explicit-use-flag))
> + '((uses eval-modules))
> + '())))))
> + (import-forms `((import-for-syntax ,@default-syntax-imports)
> + ,@(if explicit-use-flag
> + '()
> + `((import-syntax ,@default-imports)))))
> + (cleanup-forms '(((chicken.base#implicit-exit-handler))))
> (outfile (cond ((memq 'output-file options)
> => (lambda (node)
> (let ((oname (option-arg node)))
> @@ -224,10 +226,8 @@
> (opasses (default-optimization-passes))
> (time0 #f)
> (time-breakdown #f)
> - (forms '())
> (inline-output-file #f)
> (type-output-file #f)
> - (cleanup-forms '(((chicken.base#implicit-exit-handler))))
> (profile (or (memq 'profile options)
> (memq 'accumulate-profile options)
> (memq 'profile-name options)))
> @@ -345,8 +345,9 @@
> (when (memq 'b debugging-chicken) (set! time-breakdown #t))
> (when (memq 'raw options)
> (set! explicit-use-flag #t)
> - (set! cleanup-forms '())
> - (set! initforms '()) )
> + (set! init-forms '())
> + (set! import-forms '())
> + (set! cleanup-forms '()))
> (when (memq 'no-lambda-info options)
> (set! emit-closure-info #f) )
> (when (memq 'no-compiler-syntax options)
> @@ -356,7 +357,8 @@
> (when (memq 'inline-global options)
> (set! enable-inline-files #t)
> (set! inline-locally #t))
> - (when verbose
> + (when (memq 'verbose options)
> + (set! verbose-mode #t)
> (set! ##sys#notices-enabled #t))
> (when (memq 'strict-types options)
> (set! strict-variable-types #t)
> @@ -413,7 +415,6 @@
> (keyword-style #:none)
> (parentheses-synonyms #f)
> (symbol-escape #f) )
> - (set! verbose-mode verbose)
> (set! ##sys#read-error-with-line-number #t)
> (set! ##sys#include-pathnames
> (append (map chop-separator (collect-options 'include-path))
> @@ -466,18 +467,23 @@
> (set! ##sys#features (cons '#:compiling ##sys#features))
> (set! upap (user-post-analysis-pass))
>
> + ;; Mark linked extensions as static requirements.
> + (let ((units (append-map
> + (lambda (l) (map string->symbol (string-split l ", ")))
> + (collect-options 'link))))
> + (set! unit-requirements (lset-union/eq? unit-requirements units)))
> +
> ;; Handle units added with the "-uses" flag.
> - (let ((uses (append-map
> - (lambda (u) (map string->symbol (string-split u ", ")))
> - (collect-options 'uses))))
> - (unless (null? uses)
> - (set! forms
> - (cons `(##core#declare (uses . ,uses)) forms))))
> + (let ((units (append-map
> + (lambda (u) (map string->symbol (string-split u ", ")))
> + (collect-options 'uses))))
> + (set! init-forms
> + (append init-forms `((##core#declare (uses . ,units))))))
>
> ;; Append required extensions to initforms:
> - (set! initforms
> + (set! import-forms
> (append
> - initforms
> + import-forms
> (map (lambda (r) `(import ,(string->symbol r)))
> (collect-options 'require-extension))))
>
> @@ -509,9 +515,9 @@
> "you need to specify -profile-name if using accumulated profiling
> runs"))
> (set! emit-profile #t)
> (set! profiled-procedures 'all)
> - (set! initforms
> + (set! init-forms
> (append
> - initforms
> + init-forms
> default-profiling-declarations
> (if acc
> '((set! ##sys#profile-append-mode #t))
> @@ -584,18 +590,22 @@
> (print-expr "source" '|1| forms)
> (begin-time)
> ;; Canonicalize s-expressions
> - (let* ((exps0 (map (lambda (x)
> + (let* ((init0 (map canonicalize-expression init-forms))
> + (exps0 (map (lambda (x)
> (fluid-let ((##sys#current-source-filename
> filename))
> (canonicalize-expression x)))
> - (let ((forms (append initforms forms)))
> + (let ((forms (append import-forms forms)))
> (if (not module-name)
> forms
> - `((##core#module
> - ,(string->symbol module-name) ()
> + `((##core#module ,(string->symbol
> module-name) ()
> ,@forms))))))
> + (uses0 (map (lambda (u)
> + (canonicalize-expression `(##core#require ,u)))
> + (##sys#fast-reverse uses-declarations)))
> (exps (append
> (map (lambda (ic) `(set! ,(cdr ic) ',(car ic)))
> immutable-constants)
> - (map (lambda (uu) `(##core#callunit ,uu)) used-units)
> + init0
> + uses0
> (if unit-name `((##core#provide ,unit-name)) '())
> (if emit-profile
> (profiling-prelude-exps (and (not unit-name)
> @@ -614,18 +624,6 @@
> (map (lambda (il) (->string (car il)))
> import-libraries) ", ")))
>
> - (and-let* ((reqs (hash-table-ref file-requirements 'dynamic))
> - (missing (remove (cut
> chicken.load#find-dynamic-extension <> #f) reqs)))
> - (when (null? (lset-intersection/eq? '(eval repl) used-units))
> - (notice ; XXX only issued when "-verbose" is used
> - (sprintf "~A has dynamic requirements but doesn't load
> (chicken eval): ~A"
> - (cond (unit-name "unit") (dynamic "library") (else
> "program"))
> - (string-intersperse (map ->string reqs) ", "))))
> - (when (pair? missing)
> - (warning
> - (sprintf "the following extensions are not currently
> installed: ~A"
> - (string-intersperse (map ->string missing) ", ")))))
> -
> (when (pair? compiler-syntax-statistics)
> (with-debugging-output
> 'S
> @@ -664,10 +662,17 @@
> (initialize-analysis-database)
>
> ;; collect requirements and load inline files
> - (let* ((req (concatenate (vector->list file-requirements)))
> - (mreq (concatenate (map cdr req))))
> - (when (debugging 'M "; requirements:")
> - (pp req))
> + (let* ((required-extensions
> + (remove chicken.load#core-unit? library-requirements))
> + (missing-extensions
> + (remove (lambda (id)
> + (or (chicken.load#find-static-extension id)
> + (chicken.load#find-dynamic-extension id
> #f)))
> + required-extensions)))
> + (when (pair? missing-extensions)
> + (warning
> + (sprintf "the following extensions are not currently
> installed: ~A"
> + (string-intersperse (map ->string
> missing-extensions) ", "))))
> (when enable-inline-files
> (for-each
> (lambda (id)
> @@ -675,7 +680,7 @@
> (symbol->string id) '(".inline") #t
> #f)))
> (dribble "Loading inline file ~a ..." ifile)
> (load-inline-file ifile)))
> - mreq))
> + required-extensions))
> (let ((ifs (collect-options 'consult-inline-file)))
> (unless (null? ifs)
> (set! inline-locally #t)
> @@ -702,7 +707,7 @@
> (load-type-database
> (make-pathname #f (symbol->string id) "types")
> enable-specialization))
> - mreq)
> + required-extensions)
> (begin-time)
> (set! first-analysis #f)
> (set! db (analyze 'scrutiny node0))
> @@ -831,12 +836,15 @@
> (begin-time)
>
> ;; generate link file
> - (when emit-link-file
> - (dribble "generating link file `~a' ..."
> emit-link-file)
> - (with-output-to-file
> - emit-link-file
> - (cut pp linked-static-extensions)))
> -
> + (when emit-link-file
> + (let ((objs (filter-map
> + (lambda (id)
> + (and-let* ((o
> (chicken.load#find-static-extension id)))
> + (pathname-strip-directory o)))
> + (remove chicken.load#core-unit?
> library-requirements))))
> + (dribble "generating link file `~a' ..."
> emit-link-file)
> + (with-output-to-file emit-link-file (cut pp
> objs))))
> +
> ;; Code generation
> (let ((out (if outfile (open-output-file outfile)
> (current-output-port))) )
> (dribble "generating `~A' ..." outfile)
> diff --git a/c-platform.scm b/c-platform.scm
> index 35a327cc..99cdae1e 100644
> --- a/c-platform.scm
> +++ b/c-platform.scm
> @@ -72,8 +72,10 @@
> (define default-profiling-declarations
> '((##core#declare
> (uses profiler)
> - (bound-to-procedure
> - ##sys#profile-entry ##sys#profile-exit) ) ) )
> + (bound-to-procedure ##sys#profile-entry
> + ##sys#profile-exit
> + ##sys#register-profile-info
> + ##sys#set-profile-info-vector!))))
>
> (define default-units '(library eval))
>
> @@ -105,7 +107,7 @@
> setup-mode no-module-registration) )
>
> (define valid-compiler-options-with-argument
> - '(debug emit-link-file
> + '(debug link emit-link-file
> output-file include-path heap-size stack-size unit uses module
> keyword-style require-extension inline-limit profile-name
> prelude postlude prologue epilogue nursery extend feature no-feature
> diff --git a/chicken-syntax.scm b/chicken-syntax.scm
> index 2451075e..3801ba20 100644
> --- a/chicken-syntax.scm
> +++ b/chicken-syntax.scm
> @@ -541,7 +541,7 @@
> (let-values (((name lib _ _ _ _) (##sys#decompose-import x r c
> 'import)))
> (if (not lib)
> '(##core#undefined)
> - `(##core#require ,lib ,(module-requirement name)))))
> + `(##core#require ,lib))))
> (cdr x))))))
>
> (##sys#extend-macro-environment
> diff --git a/core.scm b/core.scm
> index f0c88f76..c29f3699 100644
> --- a/core.scm
> +++ b/core.scm
> @@ -138,8 +138,8 @@
> ; (##core#foreign-callback-wrapper '<name> <qualifiers> '<type> '({<type>})
> <exp>)
> ; (##core#define-external-variable <name> <type> <bool> [<symbol>])
> ; (##core#check <exp>)
> -; (##core#require-for-syntax <id> ...)
> -; (##core#require <id> <id> ...)
> +; (##core#require-for-syntax <id>)
> +; (##core#require <id>)
> ; (##core#app <exp> {<exp>})
> ; (##core#define-syntax <symbol> <expr>)
> ; (##core#define-compiler-syntax <symbol> <expr>)
> @@ -276,10 +276,6 @@
> initialize-compiler perform-closure-conversion perform-cps-conversion
> prepare-for-code-generation build-toplevel-procedure
>
> - ;; These are both exported for use in eval.scm (which is a bit of
> - ;; a hack). file-requirements is also used by batch-driver
> - process-declaration file-requirements
> -
> ;; Various ugly global boolean flags that get set by the (batch) driver
> all-import-libraries bootstrap-mode compiler-syntax-enabled
> emit-closure-info emit-profile enable-inline-files explicit-use-flag
> @@ -293,14 +289,16 @@
> disable-stack-overflow-checking emit-trace-info external-protos-first
> external-variables insert-timer-checks no-argc-checks
> no-global-procedure-checks no-procedure-checks emit-debug-info
> - linked-static-extensions
>
> ;; Other, non-boolean, flags set by (batch) driver
> profiled-procedures import-libraries inline-max-size
> extended-bindings standard-bindings
>
> + ;; Non-booleans set and read by the (batch) driver
> + library-requirements unit-requirements uses-declarations
> +
> ;; non-booleans set by the (batch) driver, and read by the (c) backend
> - target-heap-size target-stack-size unit-name used-units provided
> + target-heap-size target-stack-size unit-name used-units
>
> ;; bindings, set by the (c) platform
> default-extended-bindings default-standard-bindings internal-bindings
> @@ -360,7 +358,6 @@
> (define-constant default-line-number-database-size 997)
> (define-constant inline-table-size 301)
> (define-constant constant-table-size 301)
> -(define-constant file-requirements-size 301)
> (define-constant default-inline-max-size 20)
>
>
> @@ -429,9 +426,9 @@
> (define callback-names '())
> (define toplevel-scope #t)
> (define toplevel-lambda-id #f)
> -(define file-requirements #f)
> -(define provided '())
> -(define linked-static-extensions '())
> +(define library-requirements '())
> +(define unit-requirements '())
> +(define uses-declarations '())
>
> (define unlikely-variables '(unquote unquote-splicing))
>
> @@ -454,9 +451,6 @@
> (set! constant-table (make-vector constant-table-size '())) )
> (reset-profile-info-vector-name!)
> (clear-real-name-table!)
> - (if file-requirements
> - (vector-fill! file-requirements '())
> - (set! file-requirements (make-vector file-requirements-size '())) )
> (clear-foreign-type-table!) )
>
>
> @@ -584,11 +578,11 @@
> ((not (memq x e)) (##sys#alias-global-hook x #f h)) ; only if global
> (else x))))
>
> - (define (emit-import-lib name il)
> + (define (emit-import-lib mod name il)
> (let* ((fname (if all-import-libraries
> (string-append (symbol->string name) ".import.scm")
> (cdr il)))
> - (imps (##sys#compiled-module-registration (##sys#current-module)))
> + (imps (##sys#compiled-module-registration mod #f))
> (oldimps
> (and (file-exists? fname)
> (call-with-input-file fname read-expressions))))
> @@ -682,12 +676,7 @@
> (hide-variable var)
> var) ] ) ) )
>
> - ((##core#callunit ##core#primitive ##core#undefined) x)
> -
> - ((##core#provide)
> - (let ((id (cadr x)))
> - (set! provided (lset-adjoin/eq? provided id))
> - `(##core#provide ,id)))
> + ((##core#provide ##core#primitive ##core#undefined) x)
>
> ((##core#inline_ref)
> `(##core#inline_ref
> @@ -699,24 +688,23 @@
> ,(walk (caddr x) e dest ldest h ln #f)))
>
> ((##core#require-for-syntax)
> - (chicken.load#load-extension (cadr x) '() 'require)
> + (chicken.load#load-extension (cadr x) 'require)
> '(##core#undefined))
>
> + ((##core#callunit)
> + (let ((id (cadr x)))
> + (set! used-units (lset-adjoin/eq? used-units id))
> + `(##core#callunit ,id)))
> +
> ((##core#require)
> - (let ((id (cadr x))
> - (alternates (cddr x)))
> - (let-values (((exp type)
> - (##sys#process-require
> - id #t
> - alternates provided
> - static-extensions
> - register-static-extension)))
> - (unless (not type)
> - (hash-table-update!
> - file-requirements type
> - (cut lset-adjoin/eq? <> id)
> - (cut list id)))
> - (walk exp e dest ldest h ln #f))))
> + (let ((id (cadr x)))
> + (set! library-requirements (lset-adjoin/eq?
> library-requirements id))
> + (walk (##sys#process-require
> + id
> + (if (or (memq id unit-requirements)
> static-extensions)
> + 'static
> + 'dynamic))
> + e dest ldest h ln #f)))
>
> ((##core#let)
> (let* ((bindings (cadr x))
> @@ -964,90 +952,72 @@
>
> ((##core#module)
> (let* ((name (strip-syntax (cadr x)))
> - (lib (or unit-name name))
> - (req (module-requirement name))
> - (exports
> - (or (eq? #t (caddr x))
> - (map (lambda (exp)
> - (cond ((symbol? exp) exp)
> - ((and (pair? exp)
> - (let loop ((exp exp))
> - (or (null? exp)
> - (and (symbol? (car
> exp))
> - (loop (cdr
> exp))))))
> - exp)
> - (else
> - (##sys#syntax-error-hook
> - 'module
> - "invalid export syntax" exp
> name))))
> - (strip-syntax (caddr x)))))
> + (il (or (assq name import-libraries)
> all-import-libraries))
> + (lib (and (not standalone-executable) il (or
> unit-name name)))
> + (mod (##sys#register-module
> + name lib
> + (or (eq? #t (caddr x))
> + (map (lambda (exp)
> + (cond ((symbol? exp) exp)
> + ((and (pair? exp)
> + (let loop ((exp
> exp))
> + (or (null? exp)
> + (and (symbol?
> (car exp))
> + (loop
> (cdr exp))))))
> + exp)
> + (else
> + (##sys#syntax-error-hook
> + 'module
> + "invalid export syntax"
> exp name))))
> + (strip-syntax (caddr x))))))
> (csyntax compiler-syntax))
> (when (##sys#current-module)
> (##sys#syntax-error-hook
> 'module "modules may not be nested" name))
> - (let-values (((body module-registration)
> - (parameterize ((##sys#current-module
> - (##sys#register-module
> name lib exports))
> -
> (##sys#current-environment '())
> - (##sys#macro-environment
> -
> ##sys#initial-macro-environment)
> -
> (##sys#module-alias-environment
> -
> (##sys#module-alias-environment)))
> - (##sys#with-property-restore
> - (lambda ()
> - (let loop ((body (cdddr x)) (xs
> '()))
> - (cond
> - ((null? body)
> + (let ((body (parameterize ((##sys#current-module mod)
> + (##sys#current-environment
> '())
> + (##sys#macro-environment
> +
> ##sys#initial-macro-environment)
> +
> (##sys#module-alias-environment
> +
> (##sys#module-alias-environment)))
> + (##sys#with-property-restore
> + (lambda ()
> + (let loop ((body (cdddr x)) (xs '()))
> + (if (null? body)
> (handle-exceptions ex
> (begin
> ;; avoid backtrace
> (print-error-message ex
> (current-error-port))
> (exit 1))
> - (##sys#finalize-module
> (##sys#current-module)))
> - (cond ((or (assq name
> import-libraries) all-import-libraries)
> - => (lambda (il)
> - (emit-import-lib
> name il)
> - ;; Remove from
> list to avoid error
> - (when (pair? il)
> - (set!
> import-libraries
> - (delete il
> import-libraries equal?)))
> - (values (reverse
> xs) '())))
> - ((not
> enable-module-registration)
> - (values (reverse xs)
> '()))
> - (else
> - (values
> - (reverse xs)
> -
> (##sys#compiled-module-registration
> -
> (##sys#current-module))))))
> - (else
> + (##sys#finalize-module mod)
> + (reverse xs))
> (loop
> (cdr body)
> - (cons (walk
> - (car body)
> - e ;?
> - #f #f h ln #t) ; reset
> to toplevel!
> - xs))))))))))
> - (let ((body
> - (canonicalize-begin-body
> - (append
> - (parameterize ((##sys#current-module #f)
> - (##sys#macro-environment
> -
> (##sys#meta-macro-environment))
> - (##sys#current-environment
> ; ???
> -
> (##sys#current-meta-environment)))
> - (map
> - (lambda (x)
> - (walk
> - x
> - e ;?
> - #f #f h ln tl?) )
> - (cons `(##core#provide ,req)
> module-registration)))
> - body))))
> - (do ((cs compiler-syntax (cdr cs)))
> - ((eq? cs csyntax))
> - (##sys#put! (caar cs)
> '##compiler#compiler-syntax (cdar cs)))
> - (set! compiler-syntax csyntax)
> - body))))
> + (cons (walk (car body)
> + e #f #f
> + h ln #t) ; reset
> to toplevel!
> + xs)))))))))
> + (do ((cs compiler-syntax (cdr cs)))
> + ((eq? cs csyntax) (set! compiler-syntax
> csyntax))
> + (##sys#put! (caar cs) '##compiler#compiler-syntax
> (cdar cs)))
> + (when il
> + (emit-import-lib mod name il)
> + (when (pair? il)
> + (set! import-libraries
> + (delete il import-libraries equal?))))
> + (canonicalize-begin-body
> + (append
> + (if (or (not enable-module-registration) il)
> + '()
> + (parameterize ((##sys#macro-environment
> +
> (##sys#meta-macro-environment))
> + (##sys#current-environment ;
> ???
> +
> (##sys#current-meta-environment)))
> + (map (lambda (x) (walk x e #f #f h ln tl?))
> + (##sys#compiled-module-registration
> + mod
> + (if static-extensions 'static
> 'dynamic)))))
> + body)))))
>
> ((##core#loop-lambda) ;XXX is this really needed?
> (let* ((vars (cadr x))
> @@ -1502,7 +1472,6 @@
> (syntax-error "invalid declaration" spec) ) ) )
> (define (stripa x) ; global aliasing
> (##sys#globalize x se))
> - (define stripu strip-syntax)
> (define (globalize-all syms)
> (filter-map
> (lambda (var)
> @@ -1520,17 +1489,12 @@
> (syntax-error "invalid declaration specification" spec) )
> (case (strip-syntax (car spec)) ; no global aliasing
> ((uses)
> - (let ((us (lset-difference/eq? (stripu (cdr spec)) used-units)))
> - (when (pair? us)
> - (set! provided (append provided us))
> - (set! used-units (append used-units us))
> - (hash-table-update!
> - file-requirements 'static
> - (cut lset-union/eq? us <>)
> - (lambda () us)))))
> + (let ((units (strip-syntax (cdr spec))))
> + (set! unit-requirements (lset-union/eq? unit-requirements units))
> + (set! uses-declarations (lset-union/eq? uses-declarations units))))
> ((unit)
> (check-decl spec 1 1)
> - (let ((u (stripu (cadr spec))))
> + (let ((u (strip-syntax (cadr spec))))
> (when (and unit-name (not (eq? unit-name u)))
> (warning "unit was already given a name (new name is ignored)"))
> (set! unit-name u)
> @@ -1764,14 +1728,6 @@
> '(##core#undefined) ) ) )
>
>
> -;;; Register statically linked extension
> -
> -(define (register-static-extension id path)
> - (set! linked-static-extensions
> - (cons (pathname-strip-directory path)
> - linked-static-extensions)))
> -
> -
> ;;; Create entry procedure:
>
> (define (build-toplevel-procedure node)
> diff --git a/csc.scm b/csc.scm
> index c9d7c969..be5fe6bc 100644
> --- a/csc.scm
> +++ b/csc.scm
> @@ -643,7 +643,7 @@ EOF
> (set! compile-options (cons "-DC_EMBEDDED" compile-options)) ]
> [(-link)
> (check s rest)
> - (t-options "-uses" (car rest))
> + (t-options "-link" (car rest))
> (set! linked-extensions
> (append linked-extensions (string-split (car rest) ", ")))
> (set! rest (cdr rest))]
> diff --git a/eval.scm b/eval.scm
> index a615fa72..dc8043da 100644
> --- a/eval.scm
> +++ b/eval.scm
> @@ -563,7 +563,6 @@
> (if (null? body)
> (let ((xs (reverse xs)))
> (##sys#finalize-module
> (##sys#current-module))
> - (##sys#provide (module-requirement
> name))
> (lambda (v)
> (let loop2 ((xs xs))
> (if (null? xs)
> @@ -589,14 +588,11 @@
> (compile `(##sys#provide (##core#quote ,(cadr x))) e
> #f tf cntr #f)]
>
> [(##core#require-for-syntax)
> - (chicken.load#load-extension (cadr x) '() 'require)
> + (chicken.load#load-extension (cadr x) #f)
> (compile '(##core#undefined) e #f tf cntr #f)]
>
> [(##core#require)
> - (let ((id (cadr x))
> - (alternates (cddr x)))
> - (let-values (((exp _) (##sys#process-require id #f
> alternates)))
> - (compile exp e #f tf cntr #f)))]
> + (compile (##sys#process-require (cadr x) #f) e #f tf
> cntr #f)]
>
> [(##core#elaborationtimeonly
> ##core#elaborationtimetoo) ; <- Note this!
> (##sys#eval/meta (cadr x))
> @@ -910,9 +906,10 @@
> (##core#require library)))))
>
> (define-constant core-units
> - '(chicken-syntax chicken-ffi-syntax continuation data-structures eval
> - expand extras file files internal irregex library lolevel pathname
> - port posix srfi-4 tcp repl read-syntax))
> + '(chicken-syntax chicken-ffi-syntax continuation data-structures
> + debugger-client eval eval-modules expand extras file internal
> + irregex library lolevel pathname port posix profiler scheduler
> + srfi-4 tcp repl read-syntax))
>
> (define-constant cygwin-default-dynamic-load-libraries '("cygchicken-0"))
> (define-constant macosx-load-library-extension ".dylib")
> @@ -937,6 +934,10 @@
>
> (define ##sys#load-dynamic-extension default-load-library-extension)
>
> +(define (chicken.load#core-unit? id) ; used by batch-driver.scm
> + (or (memq id core-units)
> + (assq id core-unit-requirements)))
> +
> ; these are actually in unit extras, but that is used by default
>
> (define-constant builtin-features
> @@ -1125,36 +1126,31 @@
> (##sys#check-list x)
> x) ) ) )
>
> -(define load-library/internal
> - (let ((display display))
> - (lambda (uname lib loc)
> - (let ((libs
> - (if lib
> - (##sys#list lib)
> - (cons (##sys#string-append (##sys#slot uname 1)
> load-library-extension)
> - (dynamic-load-libraries))))
> - (top
> - (c-toplevel uname loc)))
> - (when (load-verbose)
> - (display "; loading library ")
> - (display uname)
> - (display " ...\n") )
> - (let loop ((libs libs))
> - (cond ((null? libs)
> - (##sys#error loc "unable to load library" uname _dlerror))
> - ((##sys#dload (##sys#make-c-string (##sys#slot libs 0)
> 'load-library) top))
> - (else
> - (loop (##sys#slot libs 1)))))))))
> -
> -(define (##sys#load-library uname #!optional lib loc)
> - (unless (##sys#provided? uname)
> - (load-library/internal uname lib loc)
> - (##core#undefined)))
> -
> -(define (load-library uname #!optional lib)
> - (##sys#check-symbol uname 'load-library)
> +(define (load-unit unit-name lib loc)
> + (unless (##sys#provided? unit-name)
> + (let ((libs
> + (if lib
> + (##sys#list lib)
> + (cons (##sys#string-append (##sys#slot unit-name 1)
> load-library-extension)
> + (dynamic-load-libraries))))
> + (top
> + (c-toplevel unit-name loc)))
> + (when (load-verbose)
> + (display "; loading library ")
> + (display unit-name)
> + (display " ...\n"))
> + (let loop ((libs libs))
> + (cond ((null? libs)
> + (##sys#error loc "unable to load library" unit-name (or _dlerror
> "library not found")))
> + ((##sys#dload (##sys#make-c-string (##sys#slot libs 0)
> 'load-library) top)
> + (##core#undefined))
> + (else
> + (loop (##sys#slot libs 1))))))))
> +
> +(define (load-library unit-name #!optional lib)
> + (##sys#check-symbol unit-name 'load-library)
> (unless (not lib) (##sys#check-string lib 'load-library))
> - (##sys#load-library uname lib 'load-library))
> + (load-unit unit-name lib 'load-library))
>
> (define ##sys#include-forms-from-file
> (let ((with-input-from-file with-input-from-file)
> @@ -1266,25 +1262,20 @@
> (or (check pa)
> (loop (##sys#slot paths 1)) ) ) ) ) ) ) ))
>
> -(define (load-extension/internal id alternates loc)
> - (cond ((##sys#provided? id))
> - ((any ##sys#provided? alternates))
> - ((memq id core-units)
> - (load-library/internal id #f loc))
> +(define (load-extension id loc)
> + (cond ((##sys#provided? id) (##core#undefined))
> + ((memq id core-units) (load-unit id #f loc))
> ((find-dynamic-extension id #f) =>
> (lambda (ext)
> (load/internal ext #f #f #f #f id)
> - (##sys#provide id)))
> + (##sys#provide id)
> + (##core#undefined)))
> (else
> (##sys#error loc "cannot load extension" id))))
>
> -(define (chicken.load#load-extension id alternates loc)
> - (load-extension/internal id alternates loc)
> - (##core#undefined))
> -
> (define (require . ids)
> (for-each (cut ##sys#check-symbol <> 'require) ids)
> - (for-each (cut chicken.load#load-extension <> '() 'require) ids))
> + (for-each (cut load-extension <> 'require) ids))
>
> (define (provide . ids)
> (for-each (cut ##sys#check-symbol <> 'provide) ids)
> @@ -1299,42 +1290,29 @@
> (find-file (##sys#string-append p object-file-extension)
> (repository-path))))
>
> -;; Export for internal use in csc, modules and batch-driver:
> -(define chicken.load#find-file find-file)
> -(define chicken.load#find-static-extension find-static-extension)
> -(define chicken.load#find-dynamic-extension find-dynamic-extension)
> -
> -;;
> -;; Given a library specification, returns three values:
> -;;
> -;; - an expression for loading the library, if required
> -;; - a requirement type (e.g. 'dynamic) or #f if provided in core
> -;;
> -(define (##sys#process-require lib #!optional compiling? (alternates '())
> (provided '()) static? mark-static)
> +;; Do the right thing with a `##core#require' form.
> +(define (##sys#process-require lib compile-mode)
> (let ((id (library-id lib)))
> (cond
> - ((assq id core-unit-requirements) =>
> - (lambda (x) (values (cdr x) #f)))
> - ((memq id builtin-features)
> - (values '(##core#undefined) #f))
> - ((memq id provided)
> - (values '(##core#undefined) #f))
> - ((any (cut memq <> provided) alternates)
> - (values '(##core#undefined) #f))
> + ((assq id core-unit-requirements) => cdr)
> + ((memq id builtin-features) '(##core#undefined))
> ((memq id core-units)
> - (if compiling?
> - (values `(##core#declare (uses ,id)) #f)
> - (values `(##sys#load-library (##core#quote ,id)) #f)))
> - ((and compiling? static? (find-static-extension id)) =>
> - (lambda (path)
> - (mark-static id path)
> - (values `(##core#declare (uses ,id)) 'static)))
> + (if compile-mode
> + `(##core#callunit ,id)
> + `(chicken.load#load-unit (##core#quote ,id) #f #f)))
> + ((eq? compile-mode 'static)
> + `(##core#callunit ,id))
> (else
> - (values `(chicken.load#load-extension
> - (##core#quote ,id)
> - (##core#quote ,alternates)
> - (##core#quote require))
> - 'dynamic)))))
> + `(chicken.load#load-extension (##core#quote ,id) #f)))))
> +
> +;; Export for internal use in the expansion of `##core#require':
> +(define chicken.load#load-unit load-unit)
> +(define chicken.load#load-extension load-extension)
> +
> +;; Export for internal use in csc, modules and batch-driver:
> +(define chicken.load#find-file find-file)
> +(define chicken.load#find-static-extension find-static-extension)
> +(define chicken.load#find-dynamic-extension find-dynamic-extension)
>
> ;;; Find included file:
>
> diff --git a/expand.scm b/expand.scm
> index b2f97d4b..6021efde 100644
> --- a/expand.scm
> +++ b/expand.scm
> @@ -976,7 +976,7 @@
> ##sys#current-environment ##sys#macro-environment #f #f
> 'import))
> (if (not lib)
> '(##core#undefined)
> - `(##core#require ,lib ,(module-requirement name)))))
> + `(##core#require ,lib))))
> (cdr x)))))))
>
> (##sys#extend-macro-environment
> diff --git a/modules.scm b/modules.scm
> index 73e89474..06c6e1dd 100644
> --- a/modules.scm
> +++ b/modules.scm
> @@ -33,9 +33,9 @@
> (disable-interrupts)
> (fixnum)
> (not inline ##sys#alias-global-hook)
> - (hide check-for-redef find-export find-module/import-library
> - match-functor-argument merge-se module-indirect-exports
> - module-rename register-undefined))
> + (hide check-for-redef compiled-module-dependencies find-export
> + find-module/import-library match-functor-argument merge-se
> + module-indirect-exports module-rename register-undefined))
>
> (import scheme
> chicken.base
> @@ -304,14 +304,24 @@
> ((assq (caar se) rest) (fwd (cdr se) rest))
> (else (cons (car se) (fwd (cdr se) rest)))))))))
>
> -(define (##sys#compiled-module-registration mod)
> +(define (compiled-module-dependencies mod)
> + (let ((libs (filter-map ; extract library names
> + (lambda (x) (nth-value 1 (##sys#decompose-import x o eq?
> 'module)))
> + (module-import-forms mod))))
> + (map (lambda (lib) `(##core#require ,lib))
> + (delete-duplicates libs eq?))))
> +
> +(define (##sys#compiled-module-registration mod compile-mode)
> (let ((dlist (module-defined-list mod))
> (mname (module-name mod))
> (ifs (module-import-forms mod))
> (sexports (module-sexports mod))
> (mifs (module-meta-import-forms mod)))
> - `(,@(if (and (pair? ifs) (pair? sexports))
> - `((scheme#eval '(import-syntax ,@(strip-syntax ifs))))
> + `(,@(if (and (eq? compile-mode 'static) (pair? ifs) (pair? sexports))
> + (compiled-module-dependencies mod)
> + '())
> + ,@(if (and (pair? ifs) (pair? sexports))
> + `((scheme#eval '(import-syntax ,@(strip-syntax ifs))))
> '())
> ,@(if (and (pair? mifs) (pair? sexports))
> `((import-syntax ,@(strip-syntax mifs)))
> @@ -614,9 +624,9 @@
> (cond ((null? ids)
> (for-each
> (lambda (id)
> - (warn "imported identifier doesn't
> exist" spec id))
> + (warn "imported identifier doesn't
> exist" name id))
> missing)
> - (values name lib `(,head ,spec ,@imports) v
> s impi))
> + (values name lib `(only ,spec ,@imports) v
> s impi))
> ((assq (car ids) impv) =>
> (lambda (a)
> (loop (cdr ids) (cons a v) s missing)))
> @@ -637,15 +647,15 @@
> (lambda (id)
> (warn "excluded identifier
> doesn't exist" name id))
> ids)
> - (values name lib `(,head ,spec
> ,@imports) v s impi))
> + (values name lib `(except ,spec
> ,@imports) v s impi))
> ((memq (caar imps) ids) =>
> - (lambda (id)
> - (loop
> (cdr imps) s (delete (car id) ids eq?))))
> + (lambda (id)
> + (loop (cdr imps) s (delete (car
> id) ids eq?))))
> (else
> (loop (cdr imps) (cons (car imps)
> s) ids)))))
> ((memq (caar impv) ids) =>
> - (lambda (id)
> - (loop (cdr impv) v
> (delete (car id) ids eq?))))
> + (lambda (id)
> + (loop (cdr impv) v (delete (car id) ids
> eq?))))
> (else
> (loop (cdr impv) (cons (car impv) v)
> ids))))))
> ((c %rename head)
> @@ -660,7 +670,7 @@
> (lambda (id)
> (warn "renamed identifier
> doesn't exist" name id))
> (map car ids))
> - (values name lib `(,head ,spec
> ,@renames) v s impi))
> + (values name lib `(rename ,spec
> ,@renames) v s impi))
> ((assq (caar imps) ids) =>
> (lambda (a)
> (loop (cdr imps)
> @@ -684,7 +694,7 @@
> (##sys#string->symbol
> (##sys#string-append (tostr prefix)
> (##sys#symbol->string (car imp))))
> (cdr imp)))
> - (values name lib `(,head ,spec ,prefix) (map rename
> impv) (map rename imps) impi)))
> + (values name lib `(prefix ,spec ,prefix) (map rename
> impv) (map rename imps) impi)))
> (else
> (module-imports (strip-syntax x))))))))))))
>
> diff --git a/support.scm b/support.scm
> index 8d9baac2..fa5f1442 100644
> --- a/support.scm
> +++ b/support.scm
> @@ -1834,7 +1834,6 @@ Available debugging options:
> x display information about experimental features
> D when printing nodes, use node-tree output
> I show inferred type information for unexported globals
> - M show syntax-/runtime-requirements
> N show the real-name mapping table
> P show expressions after specialization
> S show applications of compiler syntax
> diff --git a/tests/compiler-tests.scm b/tests/compiler-tests.scm
> index b3ab13ed..338ada24 100644
> --- a/tests/compiler-tests.scm
> +++ b/tests/compiler-tests.scm
> @@ -436,3 +436,10 @@
> (let ((v0 ((foreign-lambda* c-string () "C_return(\"str\");")))
> (v1 ((foreign-lambda* (const c-string) () "C_return(\"str\");"))))
> (assert (equal? v0 v1)))
> +
> +; libraries are only loaded when entry point is called
> +(let ()
> + (if #f (require-library (chicken repl)))
> + (assert (not (##sys#symbol-has-toplevel-binding? 'chicken.repl#repl)))
> + (if #t (require-library (chicken repl)))
> + (assert (##sys#symbol-has-toplevel-binding? 'chicken.repl#repl)))
> diff --git a/tests/import-library-test2.scm b/tests/import-library-test2.scm
> index fb61aee5..32bba424 100644
> --- a/tests/import-library-test2.scm
> +++ b/tests/import-library-test2.scm
> @@ -1,5 +1,3 @@
> -(require-library import-library-test1)
> -
> (module bar (xcase)
> (import scheme (chicken base) foo)
> (assert (equal? '(123) (foo)))
> diff --git a/tests/runtests.bat b/tests/runtests.bat
> index 100e2f48..5bf3026e 100644
> --- a/tests/runtests.bat
> +++ b/tests/runtests.bat
> @@ -397,7 +397,7 @@ if errorlevel 1 exit /b 1
> if errorlevel 1 exit /b 1
> %interpret% -bn test-chained-modules.so
> if errorlevel 1 exit /b 1
> -%interpret% -bn test-chained-modules.so -e "(import m3) (s3)"
> +%interpret% -bn test-chained-modules.so -e "(import-syntax m3) (s3)"
> if errorlevel 1 exit /b 1
>
> echo ======================================== module tests (ec) ...
> diff --git a/tests/runtests.sh b/tests/runtests.sh
> index 35cd9920..e4a99f1d 100755
> --- a/tests/runtests.sh
> +++ b/tests/runtests.sh
> @@ -309,7 +309,7 @@ $compile module-tests-compiled.scm
> ./a.out
> $compile module-static-eval-compiled.scm
> ./a.out
> -$compile -static module-static-eval-compiled.scm
> +$compile -static -uses lolevel module-static-eval-compiled.scm -debug 2M
> ./a.out
>
> echo "======================================== module tests (chained) ..."
> @@ -318,7 +318,7 @@ $interpret -bnq test-chained-modules.scm
> $compile_s test-chained-modules.scm -j m3
> $compile_s m3.import.scm
> $interpret -bn test-chained-modules.so
> -$interpret -bn test-chained-modules.so -e '(import m3) (s3)'
> +$interpret -bn test-chained-modules.so -e '(import-syntax m3) (s3)'
>
> echo "======================================== module tests (ec) ..."
> rm -f ec.so ec.import.*
> diff --git a/tests/scrutiny.expected b/tests/scrutiny.expected
> index 44afef85..07b6e21e 100644
> --- a/tests/scrutiny.expected
> +++ b/tests/scrutiny.expected
> @@ -43,10 +43,10 @@ Warning: at toplevel:
> assignment of value of type `fixnum' to toplevel variable `scheme#car'
> does not match declared type `(forall (a) (procedure scheme#car ((pair a *))
> a))'
>
> Warning: at toplevel:
> - expected a single result in `let' binding of `g19', but received 2 results
> + expected a single result in `let' binding of `g24', but received 2 results
>
> Warning: at toplevel:
> - in procedure call to `g19', expected a value of type `(procedure () *)'
> but was given a value of type `fixnum'
> + in procedure call to `g24', expected a value of type `(procedure () *)'
> but was given a value of type `fixnum'
>
> Note: in toplevel procedure `foo':
> expected a value of type boolean in conditional, but was given a value of
> type `(procedure bar () *)' which is always true:
> diff --git a/tests/test-chained-modules.scm b/tests/test-chained-modules.scm
> index c278f3bd..ce1f3be8 100644
> --- a/tests/test-chained-modules.scm
> +++ b/tests/test-chained-modules.scm
> @@ -17,6 +17,5 @@
> (syntax-rules ()
> ((_) (s2)))))
>
> -(import m3)
> +(import-syntax m3)
> (s3)
> -
> --
> 2.11.0
>
> _______________________________________________
> Chicken-hackers mailing list
> address@hidden
> https://lists.nongnu.org/mailman/listinfo/chicken-hackers
On Fri, May 25, 2018 at 05:06:42PM +0300, megane wrote:
>
> This is totally wrong.
>
> The tests should be something more like this (use < instead of <=):
> (test (< (procedure (#!rest x) *)
> (procedure (x x) *)))
> (test (< (procedure (x #!rest x) *)
> (procedure (x x) *)))
> (test (< (procedure (x x #!rest x) *)
> (procedure (x x) *)))
> (test (not (< (procedure (#!rest x) *)
> (procedure (x y) *))))
> (test (< (procedure (#!rest (or x y)) *)
> (procedure (x y) *)))
> (test (< (procedure (x #!rest y) *)
> (procedure (x y) *)))
>
> (test (= (procedure (#!rest x) *)
> (procedure (#!rest x) *)))
> (test (< (procedure (#!rest x) *)
> (procedure (x #!rest x) *)))
> (test (< (procedure (#!rest (or x y)) *)
> (procedure (#!rest x) *)))
> (test (< (procedure (#!rest (or x y)) *)
> (procedure (y #!rest x) *)))
>
> I'm trying to find a better fix.
>
> megane <address@hidden> writes:
>
> > Hi,
> >
> > Currently this doesn't compile:
> > (compiler-typecase (the (#!rest fixnum -> *) 1)
> > ((fixnum fixnum -> *) 1))
> >
> > Error: at toplevel:
> > (rest.scm:7) no clause applies in `compiler-typecase' for expression of
> > type `(procedure (#!rest fixnum) *)':
> > (procedure (fixnum fixnum) *)
> >
> > Here's a more concrete case where this happens. The warning only appears
> > when the procedure contravariant patch is applied:
> >
> > (: foo ((number number -> number) number number -> number))
> > (define (foo f a b)
> > (f a b))
> >
> > (print (foo max 1 2))
> >
> > Warning: at toplevel:
> > (rest.scm:14) in procedure call to `foo', expected argument #1 of type
> > `(procedure (number number) number)' but was given an argument of type
> > `(procedure max (#!rest number) number)'
> >
> > diff --git a/scrutinizer.scm b/scrutinizer.scm
> > index ece07ed..5fc6524 100644
> > --- a/scrutinizer.scm
> > +++ b/scrutinizer.scm
> > @@ -969,7 +969,9 @@
> > (or (eq? '#!optional t)
> > (match1 rtype t)))
> > head)
> > - (match1 rtype (if (pair? tail) (rest-type (cdr tail)) '*)))))
> > + (if (pair? tail)
> > + (match1 rtype (rest-type (cdr tail)))
> > + #t))))
> >
> > (define (optargs? a)
> > (memq a '(#!rest #!optional)))
> > diff --git a/tests/scrutinizer-tests.scm b/tests/scrutinizer-tests.scm
> > index ed313a4..da4fa4f 100644
> > --- a/tests/scrutinizer-tests.scm
> > +++ b/tests/scrutinizer-tests.scm
> > @@ -240,6 +240,26 @@
> >
> > (test (! (procedure () x) (procedure ())))
> > (test (! (procedure () x) (procedure () x y)))
> > +
> > +(test (<= (procedure (#!rest x) *)
> > + (procedure (x x) *)))
> > +(test (<= (procedure (x #!rest x) *)
> > + (procedure (x x) *)))
> > +(test (<= (procedure (x x #!rest x) *)
> > + (procedure (x x) *)))
> > +(test (not (<= (procedure (#!rest x) *)
> > + (procedure (x y) *))))
> > +(test (<= (procedure (#!rest (or x y)) *)
> > + (procedure (x y) *)))
> > +(test (<= (procedure (x #!rest y) *)
> > + (procedure (x y) *)))
> > +
> > +(test (<= (procedure (#!rest x) *)
> > + (procedure (#!rest x) *)))
> > +(test (<= (procedure (#!rest x) *)
> > + (procedure (x #!rest x) *)))
> > +(test (<= (procedure (#!rest (or x y)) *)
> > + (procedure (y #!rest x) *)))
> > ;; s.a.
> > ;(test (? (procedure () x) (procedure () x . y)))
> >
>
>
> _______________________________________________
> Chicken-hackers mailing list
> address@hidden
> https://lists.nongnu.org/mailman/listinfo/chicken-hackers
On Thu, May 24, 2018 at 02:11:42PM +0300, megane wrote:
> Hi,
>
> Currently this doesn't compile:
> (compiler-typecase (the (#!rest fixnum -> *) 1)
> ((fixnum fixnum -> *) 1))
>
> Error: at toplevel:
> (rest.scm:7) no clause applies in `compiler-typecase' for expression of type
> `(procedure (#!rest fixnum) *)':
> (procedure (fixnum fixnum) *)
>
> Here's a more concrete case where this happens. The warning only appears
> when the procedure contravariant patch is applied:
>
> (: foo ((number number -> number) number number -> number))
> (define (foo f a b)
> (f a b))
>
> (print (foo max 1 2))
>
> Warning: at toplevel:
> (rest.scm:14) in procedure call to `foo', expected argument #1 of type
> `(procedure (number number) number)' but was given an argument of type
> `(procedure max (#!rest number) number)'
>
> diff --git a/scrutinizer.scm b/scrutinizer.scm
> index ece07ed..5fc6524 100644
> --- a/scrutinizer.scm
> +++ b/scrutinizer.scm
> @@ -969,7 +969,9 @@
> (or (eq? '#!optional t)
> (match1 rtype t)))
> head)
> - (match1 rtype (if (pair? tail) (rest-type (cdr tail)) '*)))))
> + (if (pair? tail)
> + (match1 rtype (rest-type (cdr tail)))
> + #t))))
>
> (define (optargs? a)
> (memq a '(#!rest #!optional)))
> diff --git a/tests/scrutinizer-tests.scm b/tests/scrutinizer-tests.scm
> index ed313a4..da4fa4f 100644
> --- a/tests/scrutinizer-tests.scm
> +++ b/tests/scrutinizer-tests.scm
> @@ -240,6 +240,26 @@
>
> (test (! (procedure () x) (procedure ())))
> (test (! (procedure () x) (procedure () x y)))
> +
> +(test (<= (procedure (#!rest x) *)
> + (procedure (x x) *)))
> +(test (<= (procedure (x #!rest x) *)
> + (procedure (x x) *)))
> +(test (<= (procedure (x x #!rest x) *)
> + (procedure (x x) *)))
> +(test (not (<= (procedure (#!rest x) *)
> + (procedure (x y) *))))
> +(test (<= (procedure (#!rest (or x y)) *)
> + (procedure (x y) *)))
> +(test (<= (procedure (x #!rest y) *)
> + (procedure (x y) *)))
> +
> +(test (<= (procedure (#!rest x) *)
> + (procedure (#!rest x) *)))
> +(test (<= (procedure (#!rest x) *)
> + (procedure (x #!rest x) *)))
> +(test (<= (procedure (#!rest (or x y)) *)
> + (procedure (y #!rest x) *)))
> ;; s.a.
> ;(test (? (procedure () x) (procedure () x . y)))
>
> _______________________________________________
> Chicken-hackers mailing list
> address@hidden
> https://lists.nongnu.org/mailman/listinfo/chicken-hackers
signature.asc
Description: PGP signature
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- Re: [Chicken-hackers] [PATCH] Add 'a shorthand for forall types,
Peter Bex <=