~ chicken-core (chicken-5) 5c3923fbd40bcc786bc4c803d8d737231d18e4e7


commit 5c3923fbd40bcc786bc4c803d8d737231d18e4e7
Author:     felix <felix@call-with-current-continuation.org>
AuthorDate: Fri Mar 18 19:24:31 2011 +0100
Commit:     felix <felix@call-with-current-continuation.org>
CommitDate: Fri Mar 18 19:24:31 2011 +0100

    moved module-specific code into modules.scm, added new core unit, added define-interface

diff --git a/chicken-syntax.scm b/chicken-syntax.scm
index 20c9e822..2db03701 100644
--- a/chicken-syntax.scm
+++ b/chicken-syntax.scm
@@ -1110,6 +1110,25 @@
      (##core#let-compiler-syntax (binding ...) body ...)))))
 
 
+;;; interface definition
+
+(##sys#extend-macro-environment
+ 'define-interface '()
+ (##sys#er-transformer
+  (lambda (x r c)
+    (##sys#check-syntax 'define-interface x '(_ symbol _))
+    (let ((name (##sys#strip-syntax (cadr x))))
+      `(,(r 'begin-for-syntax)
+	(##sys#register-interface
+	 ',name
+	 ',(let ((exps (##sys#strip-syntax (caddr x))))
+	     (cond ((eq? '* exps) '*)
+		   ((symbol? exps) `(#:interface ,exps))
+		   ((list? exps) (##sys#validate-exports exps 'define-interface))
+		   (else (##sys#syntax-error-hook
+			  'define-interface "invalid exports" (caddr x)))))))))))
+
+
 (##sys#macro-subset me0 ##sys#default-macro-environment)))
 
 ;; register features
diff --git a/defaults.make b/defaults.make
index 64d91044..361d0310 100644
--- a/defaults.make
+++ b/defaults.make
@@ -303,7 +303,7 @@ CHICKEN_STATUS_PROGRAM = $(PROGRAM_PREFIX)chicken-status$(PROGRAM_SUFFIX)
 CHICKEN_BUG_PROGRAM = $(PROGRAM_PREFIX)chicken-bug$(PROGRAM_SUFFIX)
 IMPORT_LIBRARIES = chicken lolevel srfi-1 srfi-4 data-structures ports files posix srfi-13 srfi-69 extras srfi-14 tcp foreign scheme srfi-18 utils csi irregex
 IMPORT_LIBRARIES += setup-api setup-download
-SCRUTINIZED_LIBRARIES = library eval data-structures ports files extras lolevel utils tcp srfi-1 srfi-4 srfi-13 srfi-14 srfi-18 srfi-69 $(POSIXFILE) irregex scheduler profiler stub expand chicken-syntax chicken-ffi-syntax
+SCRUTINIZED_LIBRARIES = library eval data-structures ports files extras lolevel utils tcp srfi-1 srfi-4 srfi-13 srfi-14 srfi-18 srfi-69 $(POSIXFILE) irregex scheduler profiler stub expand modules chicken-syntax chicken-ffi-syntax
 
 ifdef STATICBUILD
 CHICKEN_STATIC_EXECUTABLE = $(CHICKEN_PROGRAM)$(EXE)
diff --git a/distribution/manifest b/distribution/manifest
index abdc28fe..6f805100 100644
--- a/distribution/manifest
+++ b/distribution/manifest
@@ -200,6 +200,8 @@ compiler-namespace.scm
 synrules.scm
 expand.scm
 expand.c
+modules.scm
+modules.c
 chicken-syntax.scm
 chicken-syntax.c
 common-declarations.scm
diff --git a/expand.scm b/expand.scm
index e4387532..9b12f0ba 100644
--- a/expand.scm
+++ b/expand.scm
@@ -26,14 +26,15 @@
 
 (declare
   (unit expand)
+  (uses modules)
   (disable-interrupts)
   (fixnum)
   (hide match-expression
-	macro-alias module-indirect-exports
-	d dd dm dx map-se merge-se
+	macro-alias
+	d dd dm dx map-se
 	lookup check-for-redef) 
   (not inline ##sys#syntax-error-hook ##sys#compiler-syntax-hook
-       ##sys#alias-global-hook ##sys#toplevel-definition-hook))
+       ##sys#toplevel-definition-hook))
 
 (include "common-declarations.scm")
 
@@ -267,37 +268,6 @@
 (define ##sys#compiler-syntax-hook #f)
 (define ##sys#enable-runtime-macros #f)
 
-(define (##sys#module-rename sym prefix)
-  (##sys#string->symbol (string-append
-                         (##sys#slot prefix 1)
-                         "#"
-                         (##sys#slot sym 1) ) ) )
-
-(define (##sys#alias-global-hook sym assign where)
-  (define (mrename sym)
-    (cond ((##sys#current-module) => 
-	   (lambda (mod)
-	     (dm "(ALIAS) global alias " sym " in " (module-name mod))
-	     (unless assign 
-	       (##sys#register-undefined sym mod where))
-	     (##sys#module-rename sym (module-name mod))))
-	  (else sym)))
-  (cond ((##sys#qualified-symbol? sym) sym)
-	((getp sym '##core#primitive) =>
-	 (lambda (p)
-	   (dm "(ALIAS) primitive: " p)
-	   p))
-	((getp sym '##core#aliased) 
-	 (dm "(ALIAS) marked: " sym)
-	 sym)
-	((assq sym (##sys#current-environment)) =>
-	 (lambda (a)
-	   (dm "(ALIAS) in current environment: " sym)
-	   (let ((sym2 (cdr a)))
-	     (if (pair? sym2)		; macro (*** can this be?)
-		 (mrename sym)
-		 (or (getp sym2 '##core#primitive) sym2)))))
-	(else (mrename sym))))
 
 
 ;;; User-level macroexpansion
@@ -888,176 +858,8 @@
 (define (er-macro-transformer x) x)
 (define ir-macro-transformer ##sys#ir-transformer)
 
-;;; Macro definitions:
 
-(define (##sys#expand-import x r c import-env macro-env meta? reexp? loc)
-  (let ((%only (r 'only))
-	(%rename (r 'rename))
-	(%except (r 'except))
-	(%prefix (r 'prefix))
-	(%srfi (r 'srfi)))
-    (define (resolve sym)
-      (or (lookup sym '()) sym))	;*** empty se?
-    (define (tostr x)
-      (cond ((string? x) x)
-	    ((keyword? x) (##sys#string-append (##sys#symbol->string x) ":")) ; hack
-	    ((symbol? x) (##sys#symbol->string x))
-	    ((number? x) (number->string x))
-	    (else (syntax-error loc "invalid prefix" ))))
-    (define (import-name spec)
-      (let* ((mname (##sys#strip-syntax spec))
-	     (mod (##sys#find-module mname #f)))
-	(unless mod
-	  (let ((il (##sys#find-extension
-		     (string-append (symbol->string mname) ".import")
-		     #t)))
-	    (cond (il (parameterize ((##sys#current-module #f)
-				     (##sys#current-environment '())
-				     (##sys#current-meta-environment 
-				      (##sys#current-meta-environment))
-				     (##sys#macro-environment
-				      (##sys#meta-macro-environment)))
-			(fluid-let ((##sys#notices-enabled #f)) ; to avoid re-import warnings
-			  (##sys#load il #f #f)))
-		      (set! mod (##sys#find-module mname)))
-		  (else
-		   (syntax-error
-		    loc "cannot import from undefined module" 
-		    mname)))))
-	(let ((vexp (module-vexports mod))
-	      (sexp (module-sexports mod)))
-	  (cons vexp sexp))))	  
-    (define (import-spec spec)
-      (cond ((symbol? spec) (import-name spec))
-	    ((or (not (list? spec)) (< (length spec) 2))
-	     (syntax-error loc "invalid import specification" spec))
-	    ((and (c %srfi (car spec)) (fixnum? (cadr spec)) (null? (cddr spec))) ; only one number
-	     (import-name 
-	      (##sys#intern-symbol
-	       (##sys#string-append "srfi-" (##sys#number->string (cadr spec))))))
-	    (else
-	     (let* ((s (car spec))
-		    (imp (import-spec (cadr spec)))
-		    (impv (car imp))
-		    (imps (cdr imp)))
-	       (cond ((c %only s)
-		      (##sys#check-syntax loc spec '(_ _ . #(symbol 0)))
-		      (let ((ids (map resolve (cddr spec))))
-			(let loop ((ids ids) (v '()) (s '()))
-			  (cond ((null? ids) (cons v s))
-				((assq (car ids) impv) =>
-				 (lambda (a) 
-				   (loop (cdr ids) (cons a v) s)))
-				((assq (car ids) imps) =>
-				 (lambda (a) 
-				   (loop (cdr ids) v (cons a s))))
-				(else (loop (cdr ids) v s))))))
-		     ((c %except s)
-		      (##sys#check-syntax loc spec '(_ _ . #(symbol 0)))
-		      (let ((ids (map resolve (cddr spec))))
-			(let loop ((impv impv) (v '()))
-			  (cond ((null? impv)
-				 (let loop ((imps imps) (s '()))
-				   (cond ((null? imps) (cons v s))
-					 ((memq (caar imps) ids) (loop (cdr imps) s))
-					 (else (loop (cdr imps) (cons (car imps) s))))))
-				((memq (caar impv) ids) (loop (cdr impv) v))
-				(else (loop (cdr impv) (cons (car impv) v)))))))
-		     ((c %rename s)
-		      (##sys#check-syntax loc spec '(_ _ . #((symbol symbol) 0)))
-		      (let loop ((impv impv) (imps imps) (v '()) (s '()) (ids (cddr spec)))
-			(cond ((null? impv) 
-			       (cond ((null? imps)
-				      (for-each
-				       (lambda (id)
-					 (##sys#warn "renamed identifier not imported" id) )
-				       ids)
-				      (cons v s))
-				     ((assq (caar imps) ids) =>
-				      (lambda (a)
-					(loop impv (cdr imps)
-					      v
-					      (cons (cons (cadr a) (cdar imps)) s)
-					      (##sys#delq a ids))))
-				     (else (loop impv (cdr imps) v (cons (car imps) s) ids))))
-			      ((assq (caar impv) ids) =>
-			       (lambda (a)
-				 (loop (cdr impv) imps
-				       (cons (cons (cadr a) (cdar impv)) v)
-				       s
-				       (##sys#delq a ids))))
-			      (else (loop (cdr impv) imps
-					  (cons (car impv) v)
-					  s ids)))))
-		     ((c %prefix s)
-		      (##sys#check-syntax loc spec '(_ _ _))
-		      (let ((pref (tostr (caddr spec))))
-			(define (ren imp)
-			  (cons 
-			   (##sys#string->symbol 
-			    (##sys#string-append pref (##sys#symbol->string (car imp))) )
-			   (cdr imp) ) )
-			(cons (map ren impv) (map ren imps))))
-		     (else (syntax-error loc "invalid import specification" spec)))))))
-    (##sys#check-syntax loc x '(_ . #(_ 1)))
-    (let ((cm (##sys#current-module)))
-      (when cm
-	;; save import form
-	(if meta?
-	    (set-module-meta-import-forms! 
-	     cm
-	     (append (module-meta-import-forms cm) (cdr x)))
-	    (set-module-import-forms!
-	     cm 
-	     (append (module-import-forms cm) (cdr x)))))
-      (for-each
-       (lambda (spec)
-	 (let* ((vs (import-spec spec))
-		(vsv (car vs))
-		(vss (cdr vs))
-		(prims '()))
-	   (dd `(IMPORT: ,loc))
-	   (dd `(V: ,(if cm (module-name cm) '<toplevel>) ,(map-se vsv)))
-	   (dd `(S: ,(if cm (module-name cm) '<toplevel>) ,(map-se vss)))
-	   (##sys#mark-imported-symbols vsv) ; mark imports as ##core#aliased
-	   (for-each
-	    (lambda (imp)
-	      (let* ((id (car imp))
-		     (aid (cdr imp))
-		     (prim (getp aid '##core#primitive)))
-		(when prim
-		  (set! prims (cons imp prims)))
-		(and-let* ((a (assq id (import-env)))
-			   ((not (eq? aid (cdr a)))))
-		  (##sys#notice "re-importing already imported identifier" id))))
-	    vsv)
-	   (for-each
-	    (lambda (imp)
-	      (and-let* ((a (assq (car imp) (macro-env)))
-			 ((not (eq? (cdr imp) (cdr a)))))
-		(##sys#notice "re-importing already imported syntax" (car imp))) )
-	    vss)
-	   (when reexp?
-	     (unless cm
-	       (syntax-error loc "`reexport' only valid inside a module"))
-	     (set-module-export-list! 
-	      cm
-	      (append 
-	       (let ((xl (module-export-list cm) ))
-		 (if (eq? #t xl) '() xl))
-	       (map car vsv)
-	       (map car vss)))
-	     (when (pair? prims)
-	       (set-module-meta-expressions! 
-		cm
-		(append
-		 (module-meta-expressions cm)
-		 `((##sys#mark-primitive ',prims)))))
-	     (dm "export-list: " (module-export-list cm)))
-	   (import-env (append vsv (import-env)))
-	   (macro-env (append vss (macro-env)))))
-       (cdr x))
-      '(##core#undefined))))
+;;; Macro definitions:
 
 (define (##sys#mark-primitive prims)
   (for-each
@@ -1548,7 +1350,7 @@
 			      ((not (pair? iexp)) #t)
 			      ((not (symbol? (car iexp))) #t)
 			      (else (loop (cdr iexp))))))
-	     (syntax-error 'export "invalid export syntax" exp (module-name mod))))
+	     (##sys#syntax-error-hook 'export "invalid export syntax" exp (module-name mod))))
 	 exps)
 	(set-module-export-list! 
 	 mod
@@ -1590,421 +1392,6 @@
   (##sys#fixup-macro-environment (##sys#macro-environment)))
 
 
-;;; low-level module support
-
-(define ##sys#meta-macro-environment (make-parameter (##sys#macro-environment)))
-(define ##sys#current-module (make-parameter #f))
-
-(declare 
-  (hide make-module module? %make-module
-	module-name module-vexports module-sexports
-	set-module-vexports! set-module-sexports!
-	module-export-list set-module-export-list! 
-	module-defined-list set-module-defined-list!
-	module-import-forms set-module-import-forms!
-	module-meta-import-forms set-module-meta-import-forms!
-	module-exist-list set-module-exist-list!
-	module-meta-expressions set-module-meta-expressions!
-	module-defined-syntax-list set-module-defined-syntax-list!))
-
-(define-record-type module
-  (%make-module name export-list defined-list exist-list defined-syntax-list
-		undefined-list import-forms meta-import-forms meta-expressions 
-		vexports sexports) 
-  module?
-  (name module-name)			; SYMBOL
-  (export-list module-export-list set-module-export-list!) ; (SYMBOL | (SYMBOL ...) ...)
-  (defined-list module-defined-list set-module-defined-list!) ; ((SYMBOL . VALUE) ...)    - *exported* value definitions
-  (exist-list module-exist-list set-module-exist-list!)	      ; (SYMBOL ...)    - only for checking refs to undef'd
-  (defined-syntax-list module-defined-syntax-list set-module-defined-syntax-list!) ; ((SYMBOL . VALUE) ...)
-  (undefined-list module-undefined-list set-module-undefined-list!) ; ((SYMBOL WHERE1 ...) ...)
-  (import-forms module-import-forms set-module-import-forms!)	    ; (SPEC ...)
-  (meta-import-forms module-meta-import-forms set-module-meta-import-forms!)	    ; (SPEC ...)
-  (meta-expressions module-meta-expressions set-module-meta-expressions!) ; (EXP ...)
-  (vexports module-vexports set-module-vexports!)	      ; ((SYMBOL . SYMBOL) ...)
-  (sexports module-sexports set-module-sexports!) )	      ; ((SYMBOL SE TRANSFORMER) ...)
-
-(define ##sys#module-name module-name)
-
-(define (##sys#module-exports m)
-  (values 
-   (module-export-list m)
-   (module-vexports m)
-   (module-sexports m)))
-
-(define (make-module name explist vexports sexports)
-  (%make-module name explist '() '() '() '() '() '() '() vexports sexports))
-
-(define (##sys#find-module name #!optional (err #t))
-  (cond ((assq name ##sys#module-table) => cdr)
-	(err (error 'import "module not found" name))
-	(else #f)))
-
-(define (##sys#toplevel-definition-hook sym mod exp val) #f)
-
-(define (##sys#register-meta-expression exp)
-  (and-let* ((mod (##sys#current-module)))
-    (set-module-meta-expressions! mod (cons exp (module-meta-expressions mod)))))
-
-(define (check-for-redef sym env senv)
-  (and-let* ((a (assq sym env)))
-    (##sys#warn "redefinition of imported value binding" sym) )
-  (and-let* ((a (assq sym senv)))
-    (##sys#warn "redefinition of imported syntax binding" sym)))
-
-(define (##sys#register-export sym mod)
-  (when mod
-    (let ((exp (or (eq? #t (module-export-list mod))
-		   (##sys#find-export sym mod #t)))
-	  (ulist (module-undefined-list mod)))
-      (##sys#toplevel-definition-hook	; in compiler, hides unexported bindings
-       (##sys#module-rename sym (module-name mod)) 
-       mod exp #f)
-      (and-let* ((a (assq sym ulist)))
-	(set-module-undefined-list! mod (##sys#delq a ulist)))
-      (check-for-redef sym (##sys#current-environment) (##sys#macro-environment))
-      (set-module-exist-list! mod (cons sym (module-exist-list mod)))
-      (when exp
-	(dm "defined: " sym)
-	(set-module-defined-list! 
-	 mod
-	 (cons (cons sym #f)
-	       (module-defined-list mod)))))) )
-
-(define (##sys#register-syntax-export sym mod val)
-  (when mod
-    (let ((exp (or (eq? #t (module-export-list mod))
-		   (##sys#find-export sym mod #t)))
-	  (ulist (module-undefined-list mod))
-	  (mname (module-name mod)))
-      (when (assq sym ulist)	    
-	(##sys#warn "use of syntax precedes definition" sym)) ;XXX could report locations
-      (check-for-redef sym (##sys#current-environment) (##sys#macro-environment))
-      (dm "defined syntax: " sym)
-      (when exp
-	(set-module-defined-list! 
-	 mod
-	 (cons (cons sym val)
-	       (module-defined-list mod))) )
-      (set-module-defined-syntax-list! 
-       mod
-       (cons (cons sym val) (module-defined-syntax-list mod))))))
-
-(define (##sys#register-undefined sym mod where)
-  (when mod
-    (let ((ul (module-undefined-list mod)))
-      (cond ((assq sym ul) =>
-	     (lambda (a)
-	       (when (and where (not (memq where (cdr a))))
-		 (set-cdr! a (cons where (cdr a))))))
-	    (else
-	     (set-module-undefined-list!
-	      mod
-	      (cons (cons sym (if where (list where) '())) ul)))))))
-
-(define (##sys#register-module name explist #!optional (vexports '()) (sexports '()))
-  (let ((mod (make-module name explist vexports sexports)))
-    (set! ##sys#module-table (cons (cons name mod) ##sys#module-table))
-    mod) )
-
-(define (##sys#mark-imported-symbols se)
-  (for-each
-   (lambda (imp)
-     (when (and (symbol? (cdr imp)) (not (eq? (car imp) (cdr imp))))
-       (dm `(MARKING: ,(cdr imp)))
-       (putp (cdr imp) '##core#aliased #t)))
-   se))
-
-(define (module-indirect-exports mod)
-  (let ((exports (module-export-list mod))
-	(mname (module-name mod))
-	(dlist (module-defined-list mod)))
-    (define (indirect? id)
-      (let loop ((exports exports))
-	(and (not (null? exports))
-	     (or (and (pair? (car exports))
-		      (memq id (cdar exports)))
-		 (loop (cdr exports))))))
-    (define (warn msg id)
-      (##sys#warn
-       (string-append msg " in module `" (symbol->string mname) "'")
-       id))
-    (if (eq? #t exports)
-	'()
-	(let loop ((exports exports))	; walk export list
-	  (cond ((null? exports) '())
-		((symbol? (car exports)) (loop (cdr exports))) ; normal export
-		(else
-		 (let loop2 ((iexports (cdar exports))) ; walk indirect exports for a given entry
-		   (cond ((null? iexports) (loop (cdr exports)))
-			 ((assq (car iexports) (##sys#macro-environment))
-			  (warn "indirect export of syntax binding" (car iexports))
-			  (loop2 (cdr iexports)))
-			 ((assq (car iexports) dlist) => ; defined in current module?
-			  (lambda (a) 
-			    (cons 
-			     (cons 
-			      (car iexports)
-			      (or (cdr a) (##sys#module-rename (car iexports) mname)))
-			     (loop2 (cdr iexports)))))
-			 ((assq (car iexports) (##sys#current-environment)) =>
-			  (lambda (a)	; imported in current env.
-			    (cond ((symbol? (cdr a)) ; not syntax
-				   (cons (cons (car iexports) (cdr a)) (loop2 (cdr iexports))) )
-				  (else
-				   (warn "indirect reexport of syntax" (car iexports))
-				   (loop2 (cdr iexports))))))
-			 (else 
-			  (warn "indirect export of unknown binding" (car iexports))
-			  (loop2 (cdr iexports)))))))))))
-
-(define (merge-se . ses)		; later occurrences take precedence to earlier ones
-  (let ((se (apply append ses)))
-    (dm "merging " (length ses) " se's with total length of " (length se))
-    (let ((se2
-	   (let loop ((se se))
-	     (cond ((null? se) '())
-		   ((assq (caar se) (cdr se)) (loop (cdr se)))
-		   (else (cons (car se) (loop (cdr se))))))))
-      (dm "  merged has length " (length se2))
-      se2)))
-
-(define (##sys#compiled-module-registration mod)
-  (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 (pair? ifs) `((eval '(import ,@(##sys#strip-syntax ifs)))) '())
-      ,@(if (pair? mifs) `((import ,@(##sys#strip-syntax mifs))) '())
-      ,@(reverse (map ##sys#strip-syntax (module-meta-expressions mod)))
-      (##sys#register-compiled-module
-       ',(module-name mod)
-       (list
-	,@(map (lambda (ie)
-		 (if (symbol? (cdr ie))
-		     `'(,(car ie) . ,(cdr ie))
-		     `(list ',(car ie) '() ,(cdr ie))))
-	       (module-indirect-exports mod)))
-       ',(module-vexports mod)
-       (list 
-	,@(map (lambda (sexport)
-		 (let* ((name (car sexport))
-			(a (assq name dlist)))
-		   (cond ((pair? a) 
-			  `(cons ',(car sexport) ,(##sys#strip-syntax (cdr a))))
-			 (else
-			  (dm "re-exported syntax" name mname)
-			  `',name))))
-	       sexports))
-       (list 
-	,@(if (null? sexports)
-	      '() 			; no syntax exported - no more info needed
-	      (let loop ((sd (module-defined-syntax-list mod)))
-		(cond ((null? sd) '())
-		      ((assq (caar sd) sexports) (loop (cdr sd)))
-		      (else
-		       (let ((name (caar sd)))
-			 (cons `(cons ',(caar sd) ,(##sys#strip-syntax (cdar sd)))
-			       (loop (cdr sd)))))))))))))
-
-(define (##sys#register-compiled-module name iexports vexports sexports #!optional
-					(sdefs '()))
-  (define (find-reexport name)
-    (let ((a (assq name (##sys#macro-environment))))
-      (if (and a (pair? (cdr a)))
-	  a
-	  (##sys#error
-	   'import "cannot find implementation of re-exported syntax"
-	   name))))
-  (let* ((sexps
-	  (map (lambda (se)
-		 (if (symbol? se)
-		     (find-reexport se)
-		     (list (car se) #f (##sys#er-transformer (cdr se)))))
-	       sexports))
-	 (iexps 
-	  (map (lambda (ie)
-		 (if (pair? (cdr ie))
-		     (list (car ie) (cadr ie) (##sys#er-transformer (caddr ie)))
-		     ie))
-	       iexports))
-	 (nexps
-	  (map (lambda (ne)
-		 (list (car ne) #f (##sys#er-transformer (cdr ne))))
-	       sdefs))
-	 (mod (make-module name '() vexports sexps))
-	 (senv (merge-se 
-		(##sys#macro-environment)
-		(##sys#current-environment)
-		iexps vexports sexps nexps)))
-    (##sys#mark-imported-symbols iexps)
-    (for-each
-     (lambda (sexp)
-       (set-car! (cdr sexp) senv))
-     sexps)
-    (for-each
-     (lambda (iexp)
-       (when (pair? (cdr iexp))
-	 (set-car! (cdr iexp) senv)))
-     iexps)
-    (for-each
-     (lambda (nexp)
-       (set-car! (cdr nexp) senv))
-     nexps)
-    (set! ##sys#module-table (cons (cons name mod) ##sys#module-table)) 
-    mod))
-
-(define (##sys#primitive-alias sym)
-  (let ((palias 
-	 (##sys#string->symbol 
-	  (##sys#string-append "#%" (##sys#slot sym 1)))))
-    (putp palias '##core#primitive sym)
-    palias))
-
-(define (##sys#register-primitive-module name vexports #!optional (sexports '()))
-  (let* ((me (##sys#macro-environment))
-	 (mod (make-module 
-	       name '()
-	       (map (lambda (ve)
-		      (if (symbol? ve)
-			  (cons ve (##sys#primitive-alias ve))
-			  ve))
-		    vexports)
-	       (map (lambda (se)
-		      (if (symbol? se)
-			  (or (assq se me)
-			      (##sys#error
-			       "unknown syntax referenced while registering module" 
-			       se name))
-			  se))
-		    sexports))))
-    (set! ##sys#module-table (cons (cons name mod) ##sys#module-table)) 
-    mod))
-
-(define (##sys#find-export sym mod indirect)
-  (let ((exports (module-export-list mod)))
-    (let loop ((xl (if (eq? #t exports) (module-exists-list mod) exports)))
-      (cond ((null? xl) #f)
-	    ((eq? sym (car xl)))
-	    ((pair? (car xl))
-	     (or (eq? sym (caar xl))
-		 (and indirect (memq sym (cdar xl)))
-		 (loop (cdr xl))))
-	    (else (loop (cdr xl)))))))
-
-(define ##sys#finalize-module 
-  (let ((display display)
-	(write-char write-char))
-    (lambda (mod)
-      (let* ((explist (module-export-list mod))
-	     (name (module-name mod))
-	     (dlist (module-defined-list mod))
-	     (elist (module-exist-list mod))
-	     (missing #f)
-	     (sdlist (map (lambda (sym) (assq (car sym) (##sys#macro-environment)))
-			  (module-defined-syntax-list mod)))
-	     (sexports
-	      (if (eq? #t explist)
-		  sdlist
-		  (let loop ((me (##sys#macro-environment)))
-		    (cond ((null? me) '())
-			  ((##sys#find-export (caar me) mod #f)
-			   (cons (car me) (loop (cdr me))))
-			  (else (loop (cdr me)))))))
-	     (vexports
-	      (let loop ((xl (if (eq? #t explist) elist explist)))
-		(if (null? xl)
-		    '()
-		    (let* ((h (car xl))
-			   (id (if (symbol? h) h (car h))))
-		      (if (assq id sexports) 
-			  (loop (cdr xl))
-			  (cons 
-			   (cons 
-			    id
-			    (let ((def (assq id dlist)))
-			      (if (and def (symbol? (cdr def))) 
-				  (cdr def)
-				  (let ((a (assq id (##sys#current-environment))))
-				    (cond ((and a (symbol? (cdr a))) 
-					   (dm "reexporting: " id " -> " (cdr a))
-					   (cdr a)) 
-					  ((not def)
-					   (set! missing #t)
-					   (##sys#warn 
-					    (string-append 
-					     "exported identifier of module `" 
-					     (symbol->string name)
-					     "' has not been defined")
-					    id)
-					   #f)
-					  (else (##sys#module-rename id name)))))))
-			   (loop (cdr xl)))))))))
-	(for-each
-	 (lambda (u)
-	   (let* ((where (cdr u))
-		  (u (car u)))
-	     (unless (memq u elist)
-	       (let ((out (open-output-string)))
-		 (set! missing #t)
-		 (display "reference to possibly unbound identifier `" out)
-		 (display u out)
-		 (write-char #\' out)
-		 (when (pair? where)
-		   (display " in:" out)
-		   (for-each
-		    (lambda (sym)
-		      (display "\nWarning:    " out)
-		      (display sym out))
-		    where))
-		 (and-let* ((a (getp u '##core#db)))
-		   (cond ((= 1 (length a))
-			  (display "\nWarning:    suggesting: `(import " out)
-			  (display (cadar a) out)
-			  (display ")'" out))
-			 (else
-			  (display "\nWarning:    suggesting one of:" out)
-			  (for-each
-			   (lambda (a)
-			     (display "\nWarning:    (import " out)
-			     (display (cadr a) out)
-			     (write-char #\) out))
-			   a))))
-		 (##sys#warn (get-output-string out))))))
-	 (module-undefined-list mod))
-	(when missing
-	  (##sys#error "module unresolved" name))
-	(let* ((iexports 
-		(map (lambda (exp)
-		       (cond ((symbol? (cdr exp)) exp)
-			     ((assq (car exp) (##sys#macro-environment)))
-			     (else (##sys#error "(internal) indirect export not found" (car exp)))) )
-		     (module-indirect-exports mod)))
-	       (new-se (merge-se 
-			(##sys#macro-environment) 
-			(##sys#current-environment) 
-			iexports vexports sexports sdlist)))
-	  (##sys#mark-imported-symbols iexports)
-	  (for-each
-	   (lambda (m)
-	     (let ((se (merge-se (cadr m) new-se))) ;XXX needed?
-	       (dm `(FIXUP: ,(car m) ,@(map-se se)))
-	       (set-car! (cdr m) se)))
-	   sdlist)
-	  (dm `(EXPORTS: 
-		,(module-name mod) 
-		(DLIST: ,@dlist)
-		(SDLIST: ,@(map-se sdlist))
-		(IEXPORTS: ,@(map-se iexports))
-		(VEXPORTS: ,@(map-se vexports))
-		(SEXPORTS: ,@(map-se sexports))))
-	  (set-module-vexports! mod vexports)
-	  (set-module-sexports! mod sexports))))))
-
-(define ##sys#module-table '())
-
-
 ;; Used by the syntax-rules implementation (and possibly handy elsewhere)
 ;; (kindly contributed by Peter Bex)
 
diff --git a/modules.scm b/modules.scm
new file mode 100644
index 00000000..a4db59f9
--- /dev/null
+++ b/modules.scm
@@ -0,0 +1,706 @@
+;;;; modules.scm - module-system support
+;
+; Copyright (c) 2011, The Chicken Team
+; All rights reserved.
+;
+; Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following
+; conditions are met:
+;
+;   Redistributions of source code must retain the above copyright notice, this list of conditions and the following
+;     disclaimer. 
+;   Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following
+;     disclaimer in the documentation and/or other materials provided with the distribution. 
+;   Neither the name of the author nor the names of its contributors may be used to endorse or promote
+;     products derived from this software without specific prior written permission. 
+;
+; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
+; OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+; AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR
+; CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+; SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+; THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+; OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+; POSSIBILITY OF SUCH DAMAGE.
+
+
+(declare
+  (unit modules)
+  (disable-interrupts)
+  (fixnum)
+  (hide lookup merge-se module-indirect-exports)
+  (not inline ##sys#alias-global-hook))
+
+(include "common-declarations.scm")
+
+(define-alias dd d)
+(define-alias dm d)
+(define-alias dx d)
+
+(define-inline (getp sym prop)
+  (##core#inline "C_i_getprop" sym prop #f))
+
+(define-inline (putp sym prop val)
+  (##core#inline_allocate ("C_a_i_putprop" 8) sym prop val))
+
+
+;;; Support definitions
+
+;; duoplicates code in the hope of being inlined
+(define (lookup id se)
+  (cond ((##core#inline "C_u_i_assq" id se) => cdr)
+	((getp id '##core#macro-alias))
+	(else #f)))
+
+
+;;; low-level module support
+
+(define ##sys#meta-macro-environment (make-parameter (##sys#macro-environment)))
+(define ##sys#current-module (make-parameter #f))
+
+(declare 
+  (hide make-module module? %make-module
+	module-name module-vexports module-sexports
+	set-module-vexports! set-module-sexports!
+	module-export-list set-module-export-list! 
+	module-defined-list set-module-defined-list!
+	module-import-forms set-module-import-forms!
+	module-meta-import-forms set-module-meta-import-forms!
+	module-exist-list set-module-exist-list!
+	module-meta-expressions set-module-meta-expressions!
+	module-defined-syntax-list set-module-defined-syntax-list!))
+
+(define-record-type module
+  (%make-module name export-list defined-list exist-list defined-syntax-list
+		undefined-list import-forms meta-import-forms meta-expressions 
+		vexports sexports) 
+  module?
+  (name module-name)			; SYMBOL
+  (export-list module-export-list set-module-export-list!) ; (SYMBOL | (SYMBOL ...) ...)
+  (defined-list module-defined-list set-module-defined-list!) ; ((SYMBOL . VALUE) ...)    - *exported* value definitions
+  (exist-list module-exist-list set-module-exist-list!)	      ; (SYMBOL ...)    - only for checking refs to undef'd
+  (defined-syntax-list module-defined-syntax-list set-module-defined-syntax-list!) ; ((SYMBOL . VALUE) ...)
+  (undefined-list module-undefined-list set-module-undefined-list!) ; ((SYMBOL WHERE1 ...) ...)
+  (import-forms module-import-forms set-module-import-forms!)	    ; (SPEC ...)
+  (meta-import-forms module-meta-import-forms set-module-meta-import-forms!)	    ; (SPEC ...)
+  (meta-expressions module-meta-expressions set-module-meta-expressions!) ; (EXP ...)
+  (vexports module-vexports set-module-vexports!)	      ; ((SYMBOL . SYMBOL) ...)
+  (sexports module-sexports set-module-sexports!) )	      ; ((SYMBOL SE TRANSFORMER) ...)
+
+(define ##sys#module-name module-name)
+
+(define (##sys#module-exports m)
+  (values 
+   (module-export-list m)
+   (module-vexports m)
+   (module-sexports m)))
+
+(define (make-module name explist vexports sexports)
+  (%make-module name explist '() '() '() '() '() '() '() vexports sexports))
+
+(define (##sys#find-module name #!optional (err #t))
+  (cond ((assq name ##sys#module-table) => cdr)
+	(err (error 'import "module not found" name))
+	(else #f)))
+
+(define (##sys#toplevel-definition-hook sym mod exp val) #f)
+
+(define (##sys#register-meta-expression exp)
+  (and-let* ((mod (##sys#current-module)))
+    (set-module-meta-expressions! mod (cons exp (module-meta-expressions mod)))))
+
+(define (check-for-redef sym env senv)
+  (and-let* ((a (assq sym env)))
+    (##sys#warn "redefinition of imported value binding" sym) )
+  (and-let* ((a (assq sym senv)))
+    (##sys#warn "redefinition of imported syntax binding" sym)))
+
+(define (##sys#register-export sym mod)
+  (when mod
+    (let ((exp (or (eq? #t (module-export-list mod))
+		   (##sys#find-export sym mod #t)))
+	  (ulist (module-undefined-list mod)))
+      (##sys#toplevel-definition-hook	; in compiler, hides unexported bindings
+       (##sys#module-rename sym (module-name mod)) 
+       mod exp #f)
+      (and-let* ((a (assq sym ulist)))
+	(set-module-undefined-list! mod (##sys#delq a ulist)))
+      (check-for-redef sym (##sys#current-environment) (##sys#macro-environment))
+      (set-module-exist-list! mod (cons sym (module-exist-list mod)))
+      (when exp
+	(dm "defined: " sym)
+	(set-module-defined-list! 
+	 mod
+	 (cons (cons sym #f)
+	       (module-defined-list mod)))))) )
+
+(define (##sys#register-syntax-export sym mod val)
+  (when mod
+    (let ((exp (or (eq? #t (module-export-list mod))
+		   (##sys#find-export sym mod #t)))
+	  (ulist (module-undefined-list mod))
+	  (mname (module-name mod)))
+      (when (assq sym ulist)	    
+	(##sys#warn "use of syntax precedes definition" sym)) ;XXX could report locations
+      (check-for-redef sym (##sys#current-environment) (##sys#macro-environment))
+      (dm "defined syntax: " sym)
+      (when exp
+	(set-module-defined-list! 
+	 mod
+	 (cons (cons sym val)
+	       (module-defined-list mod))) )
+      (set-module-defined-syntax-list! 
+       mod
+       (cons (cons sym val) (module-defined-syntax-list mod))))))
+
+(define (##sys#register-undefined sym mod where)
+  (when mod
+    (let ((ul (module-undefined-list mod)))
+      (cond ((assq sym ul) =>
+	     (lambda (a)
+	       (when (and where (not (memq where (cdr a))))
+		 (set-cdr! a (cons where (cdr a))))))
+	    (else
+	     (set-module-undefined-list!
+	      mod
+	      (cons (cons sym (if where (list where) '())) ul)))))))
+
+(define (##sys#register-module name explist #!optional (vexports '()) (sexports '()))
+  (let ((mod (make-module name explist vexports sexports)))
+    (set! ##sys#module-table (cons (cons name mod) ##sys#module-table))
+    mod) )
+
+(define (##sys#mark-imported-symbols se)
+  (for-each
+   (lambda (imp)
+     (when (and (symbol? (cdr imp)) (not (eq? (car imp) (cdr imp))))
+       (dm `(MARKING: ,(cdr imp)))
+       (putp (cdr imp) '##core#aliased #t)))
+   se))
+
+(define (module-indirect-exports mod)
+  (let ((exports (module-export-list mod))
+	(mname (module-name mod))
+	(dlist (module-defined-list mod)))
+    (define (indirect? id)
+      (let loop ((exports exports))
+	(and (not (null? exports))
+	     (or (and (pair? (car exports))
+		      (memq id (cdar exports)))
+		 (loop (cdr exports))))))
+    (define (warn msg id)
+      (##sys#warn
+       (string-append msg " in module `" (symbol->string mname) "'")
+       id))
+    (if (eq? #t exports)
+	'()
+	(let loop ((exports exports))	; walk export list
+	  (cond ((null? exports) '())
+		((symbol? (car exports)) (loop (cdr exports))) ; normal export
+		(else
+		 (let loop2 ((iexports (cdar exports))) ; walk indirect exports for a given entry
+		   (cond ((null? iexports) (loop (cdr exports)))
+			 ((assq (car iexports) (##sys#macro-environment))
+			  (warn "indirect export of syntax binding" (car iexports))
+			  (loop2 (cdr iexports)))
+			 ((assq (car iexports) dlist) => ; defined in current module?
+			  (lambda (a) 
+			    (cons 
+			     (cons 
+			      (car iexports)
+			      (or (cdr a) (##sys#module-rename (car iexports) mname)))
+			     (loop2 (cdr iexports)))))
+			 ((assq (car iexports) (##sys#current-environment)) =>
+			  (lambda (a)	; imported in current env.
+			    (cond ((symbol? (cdr a)) ; not syntax
+				   (cons (cons (car iexports) (cdr a)) (loop2 (cdr iexports))) )
+				  (else
+				   (warn "indirect reexport of syntax" (car iexports))
+				   (loop2 (cdr iexports))))))
+			 (else 
+			  (warn "indirect export of unknown binding" (car iexports))
+			  (loop2 (cdr iexports)))))))))))
+
+(define (merge-se . ses)		; later occurrences take precedence to earlier ones
+  (let ((se (apply append ses)))
+    (dm "merging " (length ses) " se's with total length of " (length se))
+    (let ((se2
+	   (let loop ((se se))
+	     (cond ((null? se) '())
+		   ((assq (caar se) (cdr se)) (loop (cdr se)))
+		   (else (cons (car se) (loop (cdr se))))))))
+      (dm "  merged has length " (length se2))
+      se2)))
+
+(define (##sys#compiled-module-registration mod)
+  (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 (pair? ifs) `((eval '(import ,@(##sys#strip-syntax ifs)))) '())
+      ,@(if (pair? mifs) `((import ,@(##sys#strip-syntax mifs))) '())
+      ,@(reverse (map ##sys#strip-syntax (module-meta-expressions mod)))
+      (##sys#register-compiled-module
+       ',(module-name mod)
+       (list
+	,@(map (lambda (ie)
+		 (if (symbol? (cdr ie))
+		     `'(,(car ie) . ,(cdr ie))
+		     `(list ',(car ie) '() ,(cdr ie))))
+	       (module-indirect-exports mod)))
+       ',(module-vexports mod)
+       (list 
+	,@(map (lambda (sexport)
+		 (let* ((name (car sexport))
+			(a (assq name dlist)))
+		   (cond ((pair? a) 
+			  `(cons ',(car sexport) ,(##sys#strip-syntax (cdr a))))
+			 (else
+			  (dm "re-exported syntax" name mname)
+			  `',name))))
+	       sexports))
+       (list 
+	,@(if (null? sexports)
+	      '() 			; no syntax exported - no more info needed
+	      (let loop ((sd (module-defined-syntax-list mod)))
+		(cond ((null? sd) '())
+		      ((assq (caar sd) sexports) (loop (cdr sd)))
+		      (else
+		       (let ((name (caar sd)))
+			 (cons `(cons ',(caar sd) ,(##sys#strip-syntax (cdar sd)))
+			       (loop (cdr sd)))))))))))))
+
+(define (##sys#register-compiled-module name iexports vexports sexports #!optional
+					(sdefs '()))
+  (define (find-reexport name)
+    (let ((a (assq name (##sys#macro-environment))))
+      (if (and a (pair? (cdr a)))
+	  a
+	  (##sys#error
+	   'import "cannot find implementation of re-exported syntax"
+	   name))))
+  (let* ((sexps
+	  (map (lambda (se)
+		 (if (symbol? se)
+		     (find-reexport se)
+		     (list (car se) #f (##sys#er-transformer (cdr se)))))
+	       sexports))
+	 (iexps 
+	  (map (lambda (ie)
+		 (if (pair? (cdr ie))
+		     (list (car ie) (cadr ie) (##sys#er-transformer (caddr ie)))
+		     ie))
+	       iexports))
+	 (nexps
+	  (map (lambda (ne)
+		 (list (car ne) #f (##sys#er-transformer (cdr ne))))
+	       sdefs))
+	 (mod (make-module name '() vexports sexps))
+	 (senv (merge-se 
+		(##sys#macro-environment)
+		(##sys#current-environment)
+		iexps vexports sexps nexps)))
+    (##sys#mark-imported-symbols iexps)
+    (for-each
+     (lambda (sexp)
+       (set-car! (cdr sexp) senv))
+     sexps)
+    (for-each
+     (lambda (iexp)
+       (when (pair? (cdr iexp))
+	 (set-car! (cdr iexp) senv)))
+     iexps)
+    (for-each
+     (lambda (nexp)
+       (set-car! (cdr nexp) senv))
+     nexps)
+    (set! ##sys#module-table (cons (cons name mod) ##sys#module-table)) 
+    mod))
+
+(define (##sys#primitive-alias sym)
+  (let ((palias 
+	 (##sys#string->symbol 
+	  (##sys#string-append "#%" (##sys#slot sym 1)))))
+    (putp palias '##core#primitive sym)
+    palias))
+
+(define (##sys#register-primitive-module name vexports #!optional (sexports '()))
+  (let* ((me (##sys#macro-environment))
+	 (mod (make-module 
+	       name '()
+	       (map (lambda (ve)
+		      (if (symbol? ve)
+			  (cons ve (##sys#primitive-alias ve))
+			  ve))
+		    vexports)
+	       (map (lambda (se)
+		      (if (symbol? se)
+			  (or (assq se me)
+			      (##sys#error
+			       "unknown syntax referenced while registering module" 
+			       se name))
+			  se))
+		    sexports))))
+    (set! ##sys#module-table (cons (cons name mod) ##sys#module-table)) 
+    mod))
+
+(define (##sys#find-export sym mod indirect)
+  (let ((exports (module-export-list mod)))
+    (let loop ((xl (if (eq? #t exports) (module-exists-list mod) exports)))
+      (cond ((null? xl) #f)
+	    ((eq? sym (car xl)))
+	    ((pair? (car xl))
+	     (or (eq? sym (caar xl))
+		 (and indirect (memq sym (cdar xl)))
+		 (loop (cdr xl))))
+	    (else (loop (cdr xl)))))))
+
+(define ##sys#finalize-module 
+  (let ((display display)
+	(write-char write-char))
+    (lambda (mod)
+      (let* ((explist (module-export-list mod))
+	     (name (module-name mod))
+	     (dlist (module-defined-list mod))
+	     (elist (module-exist-list mod))
+	     (missing #f)
+	     (sdlist (map (lambda (sym) (assq (car sym) (##sys#macro-environment)))
+			  (module-defined-syntax-list mod)))
+	     (sexports
+	      (if (eq? #t explist)
+		  sdlist
+		  (let loop ((me (##sys#macro-environment)))
+		    (cond ((null? me) '())
+			  ((##sys#find-export (caar me) mod #f)
+			   (cons (car me) (loop (cdr me))))
+			  (else (loop (cdr me)))))))
+	     (vexports
+	      (let loop ((xl (if (eq? #t explist) elist explist)))
+		(if (null? xl)
+		    '()
+		    (let* ((h (car xl))
+			   (id (if (symbol? h) h (car h))))
+		      (if (assq id sexports) 
+			  (loop (cdr xl))
+			  (cons 
+			   (cons 
+			    id
+			    (let ((def (assq id dlist)))
+			      (if (and def (symbol? (cdr def))) 
+				  (cdr def)
+				  (let ((a (assq id (##sys#current-environment))))
+				    (cond ((and a (symbol? (cdr a))) 
+					   (dm "reexporting: " id " -> " (cdr a))
+					   (cdr a)) 
+					  ((not def)
+					   (set! missing #t)
+					   (##sys#warn 
+					    (string-append 
+					     "exported identifier of module `" 
+					     (symbol->string name)
+					     "' has not been defined")
+					    id)
+					   #f)
+					  (else (##sys#module-rename id name)))))))
+			   (loop (cdr xl)))))))))
+	(for-each
+	 (lambda (u)
+	   (let* ((where (cdr u))
+		  (u (car u)))
+	     (unless (memq u elist)
+	       (let ((out (open-output-string)))
+		 (set! missing #t)
+		 (display "reference to possibly unbound identifier `" out)
+		 (display u out)
+		 (write-char #\' out)
+		 (when (pair? where)
+		   (display " in:" out)
+		   (for-each
+		    (lambda (sym)
+		      (display "\nWarning:    " out)
+		      (display sym out))
+		    where))
+		 (and-let* ((a (getp u '##core#db)))
+		   (cond ((= 1 (length a))
+			  (display "\nWarning:    suggesting: `(import " out)
+			  (display (cadar a) out)
+			  (display ")'" out))
+			 (else
+			  (display "\nWarning:    suggesting one of:" out)
+			  (for-each
+			   (lambda (a)
+			     (display "\nWarning:    (import " out)
+			     (display (cadr a) out)
+			     (write-char #\) out))
+			   a))))
+		 (##sys#warn (get-output-string out))))))
+	 (module-undefined-list mod))
+	(when missing
+	  (##sys#error "module unresolved" name))
+	(let* ((iexports 
+		(map (lambda (exp)
+		       (cond ((symbol? (cdr exp)) exp)
+			     ((assq (car exp) (##sys#macro-environment)))
+			     (else (##sys#error "(internal) indirect export not found" (car exp)))) )
+		     (module-indirect-exports mod)))
+	       (new-se (merge-se 
+			(##sys#macro-environment) 
+			(##sys#current-environment) 
+			iexports vexports sexports sdlist)))
+	  (##sys#mark-imported-symbols iexports)
+	  (for-each
+	   (lambda (m)
+	     (let ((se (merge-se (cadr m) new-se))) ;XXX needed?
+	       (dm `(FIXUP: ,(car m) ,@(map-se se)))
+	       (set-car! (cdr m) se)))
+	   sdlist)
+	  (dm `(EXPORTS: 
+		,(module-name mod) 
+		(DLIST: ,@dlist)
+		(SDLIST: ,@(map-se sdlist))
+		(IEXPORTS: ,@(map-se iexports))
+		(VEXPORTS: ,@(map-se vexports))
+		(SEXPORTS: ,@(map-se sexports))))
+	  (set-module-vexports! mod vexports)
+	  (set-module-sexports! mod sexports))))))
+
+(define ##sys#module-table '())
+
+
+;;; Import-expansion
+
+(define (##sys#expand-import x r c import-env macro-env meta? reexp? loc)
+  (let ((%only (r 'only))
+	(%rename (r 'rename))
+	(%except (r 'except))
+	(%prefix (r 'prefix))
+	(%srfi (r 'srfi)))
+    (define (resolve sym)
+      (or (lookup sym '()) sym))	;*** empty se?
+    (define (tostr x)
+      (cond ((string? x) x)
+	    ((keyword? x) (##sys#string-append (##sys#symbol->string x) ":")) ; hack
+	    ((symbol? x) (##sys#symbol->string x))
+	    ((number? x) (number->string x))
+	    (else (##sys#syntax-error-hook loc "invalid prefix" ))))
+    (define (import-name spec)
+      (let* ((mname (##sys#strip-syntax spec))
+	     (mod (##sys#find-module mname #f)))
+	(unless mod
+	  (let ((il (##sys#find-extension
+		     (string-append (symbol->string mname) ".import")
+		     #t)))
+	    (cond (il (parameterize ((##sys#current-module #f)
+				     (##sys#current-environment '())
+				     (##sys#current-meta-environment 
+				      (##sys#current-meta-environment))
+				     (##sys#macro-environment
+				      (##sys#meta-macro-environment)))
+			(fluid-let ((##sys#notices-enabled #f)) ; to avoid re-import warnings
+			  (##sys#load il #f #f)))
+		      (set! mod (##sys#find-module mname)))
+		  (else
+		   (##sys#syntax-error-hook
+		    loc "cannot import from undefined module" 
+		    mname)))))
+	(let ((vexp (module-vexports mod))
+	      (sexp (module-sexports mod)))
+	  (cons vexp sexp))))	  
+    (define (import-spec spec)
+      (cond ((symbol? spec) (import-name spec))
+	    ((or (not (list? spec)) (< (length spec) 2))
+	     (##sys#syntax-error-hook loc "invalid import specification" spec))
+	    ((and (c %srfi (car spec)) (fixnum? (cadr spec)) (null? (cddr spec))) ; only one number
+	     (import-name 
+	      (##sys#intern-symbol
+	       (##sys#string-append "srfi-" (##sys#number->string (cadr spec))))))
+	    (else
+	     (let* ((s (car spec))
+		    (imp (import-spec (cadr spec)))
+		    (impv (car imp))
+		    (imps (cdr imp)))
+	       (cond ((c %only s)
+		      (##sys#check-syntax loc spec '(_ _ . #(symbol 0)))
+		      (let ((ids (map resolve (cddr spec))))
+			(let loop ((ids ids) (v '()) (s '()))
+			  (cond ((null? ids) (cons v s))
+				((assq (car ids) impv) =>
+				 (lambda (a) 
+				   (loop (cdr ids) (cons a v) s)))
+				((assq (car ids) imps) =>
+				 (lambda (a) 
+				   (loop (cdr ids) v (cons a s))))
+				(else (loop (cdr ids) v s))))))
+		     ((c %except s)
+		      (##sys#check-syntax loc spec '(_ _ . #(symbol 0)))
+		      (let ((ids (map resolve (cddr spec))))
+			(let loop ((impv impv) (v '()))
+			  (cond ((null? impv)
+				 (let loop ((imps imps) (s '()))
+				   (cond ((null? imps) (cons v s))
+					 ((memq (caar imps) ids) (loop (cdr imps) s))
+					 (else (loop (cdr imps) (cons (car imps) s))))))
+				((memq (caar impv) ids) (loop (cdr impv) v))
+				(else (loop (cdr impv) (cons (car impv) v)))))))
+		     ((c %rename s)
+		      (##sys#check-syntax loc spec '(_ _ . #((symbol symbol) 0)))
+		      (let loop ((impv impv) (imps imps) (v '()) (s '()) (ids (cddr spec)))
+			(cond ((null? impv) 
+			       (cond ((null? imps)
+				      (for-each
+				       (lambda (id)
+					 (##sys#warn "renamed identifier not imported" id) )
+				       ids)
+				      (cons v s))
+				     ((assq (caar imps) ids) =>
+				      (lambda (a)
+					(loop impv (cdr imps)
+					      v
+					      (cons (cons (cadr a) (cdar imps)) s)
+					      (##sys#delq a ids))))
+				     (else (loop impv (cdr imps) v (cons (car imps) s) ids))))
+			      ((assq (caar impv) ids) =>
+			       (lambda (a)
+				 (loop (cdr impv) imps
+				       (cons (cons (cadr a) (cdar impv)) v)
+				       s
+				       (##sys#delq a ids))))
+			      (else (loop (cdr impv) imps
+					  (cons (car impv) v)
+					  s ids)))))
+		     ((c %prefix s)
+		      (##sys#check-syntax loc spec '(_ _ _))
+		      (let ((pref (tostr (caddr spec))))
+			(define (ren imp)
+			  (cons 
+			   (##sys#string->symbol 
+			    (##sys#string-append pref (##sys#symbol->string (car imp))) )
+			   (cdr imp) ) )
+			(cons (map ren impv) (map ren imps))))
+		     (else (##sys#syntax-error-hook loc "invalid import specification" spec)))))))
+    (##sys#check-syntax loc x '(_ . #(_ 1)))
+    (let ((cm (##sys#current-module)))
+      (when cm
+	;; save import form
+	(if meta?
+	    (set-module-meta-import-forms! 
+	     cm
+	     (append (module-meta-import-forms cm) (cdr x)))
+	    (set-module-import-forms!
+	     cm 
+	     (append (module-import-forms cm) (cdr x)))))
+      (for-each
+       (lambda (spec)
+	 (let* ((vs (import-spec spec))
+		(vsv (car vs))
+		(vss (cdr vs))
+		(prims '()))
+	   (dd `(IMPORT: ,loc))
+	   (dd `(V: ,(if cm (module-name cm) '<toplevel>) ,(map-se vsv)))
+	   (dd `(S: ,(if cm (module-name cm) '<toplevel>) ,(map-se vss)))
+	   (##sys#mark-imported-symbols vsv) ; mark imports as ##core#aliased
+	   (for-each
+	    (lambda (imp)
+	      (let* ((id (car imp))
+		     (aid (cdr imp))
+		     (prim (getp aid '##core#primitive)))
+		(when prim
+		  (set! prims (cons imp prims)))
+		(and-let* ((a (assq id (import-env)))
+			   ((not (eq? aid (cdr a)))))
+		  (##sys#notice "re-importing already imported identifier" id))))
+	    vsv)
+	   (for-each
+	    (lambda (imp)
+	      (and-let* ((a (assq (car imp) (macro-env)))
+			 ((not (eq? (cdr imp) (cdr a)))))
+		(##sys#notice "re-importing already imported syntax" (car imp))) )
+	    vss)
+	   (when reexp?
+	     (unless cm
+	       (##sys#syntax-error-hook loc "`reexport' only valid inside a module"))
+	     (set-module-export-list! 
+	      cm
+	      (append 
+	       (let ((xl (module-export-list cm) ))
+		 (if (eq? #t xl) '() xl))
+	       (map car vsv)
+	       (map car vss)))
+	     (when (pair? prims)
+	       (set-module-meta-expressions! 
+		cm
+		(append
+		 (module-meta-expressions cm)
+		 `((##sys#mark-primitive ',prims)))))
+	     (dm "export-list: " (module-export-list cm)))
+	   (import-env (append vsv (import-env)))
+	   (macro-env (append vss (macro-env)))))
+       (cdr x))
+      '(##core#undefined))))
+
+(define (##sys#module-rename sym prefix)
+  (##sys#string->symbol
+   (string-append
+    (##sys#slot prefix 1)
+    "#"
+    (##sys#slot sym 1) ) ) )
+
+(define (##sys#alias-global-hook sym assign where)
+  (define (mrename sym)
+    (cond ((##sys#current-module) => 
+	   (lambda (mod)
+	     (dm "(ALIAS) global alias " sym " in " (module-name mod))
+	     (unless assign 
+	       (##sys#register-undefined sym mod where))
+	     (##sys#module-rename sym (module-name mod))))
+	  (else sym)))
+  (cond ((##sys#qualified-symbol? sym) sym)
+	((getp sym '##core#primitive) =>
+	 (lambda (p)
+	   (dm "(ALIAS) primitive: " p)
+	   p))
+	((getp sym '##core#aliased) 
+	 (dm "(ALIAS) marked: " sym)
+	 sym)
+	((assq sym (##sys#current-environment)) =>
+	 (lambda (a)
+	   (dm "(ALIAS) in current environment: " sym)
+	   (let ((sym2 (cdr a)))
+	     (if (pair? sym2)		; macro (*** can this be?)
+		 (mrename sym)
+		 (or (getp sym2 '##core#primitive) sym2)))))
+	(else (mrename sym))))
+
+(define (##sys#register-interface name exps)
+  ;; expects exps to be stripped and validated
+  (putp name '##core#interface exps))
+
+(define (##sys#validate-exports exps loc)
+  ;; expects "exps" to be stripped
+  (define (err . args)
+    (apply ##sys#syntax-error-hook loc args))
+  (cond ((eq? '* exps) exps)
+	((not (pair? exps))
+	 (err "invalid exports" exps))
+	(else
+	 (let loop ((xps exps))
+	   (cond ((null? xps) '())
+		 ((not (pair? xps))
+		  (err "invalid exports" exps))
+		 (else
+		  (let ((x (car xps)))
+		    (cond ((symbol? x) (cons x (loop (cdr xps))))
+			  ((not (list? x))
+			   (err "invalid export" x exps))
+			  ((eq? #:syntax (car x))
+			   (cons (cdr x) (loop (cdr xps)))) ; currently not used
+			  ((eq? #:interface (car x))
+			   (if (and (pair? (cdr x)) (symbol? (cadr x)))
+			       (cond ((getp (cadr x) '##core#interface) =>
+				      (lambda (iface)
+					(append iface (loop (cdr xps)))))
+				     (else
+				      (err "invalid interface specification" x exps)))
+			       (err "invalid interface specification" x exps)))
+			  (else (err "invalid export" x exps))))))))))
diff --git a/rules.make b/rules.make
index 521a8010..f0bc4bb3 100644
--- a/rules.make
+++ b/rules.make
@@ -38,7 +38,7 @@ SETUP_API_OBJECTS_1 = setup-api setup-download
 LIBCHICKEN_OBJECTS_1 = \
        library eval data-structures ports files extras lolevel utils tcp srfi-1 srfi-4 srfi-13 \
        srfi-14 srfi-18 srfi-69 $(POSIXFILE) irregex scheduler \
-       profiler stub expand chicken-syntax chicken-ffi-syntax runtime
+       profiler stub expand modules chicken-syntax chicken-ffi-syntax runtime
 LIBCHICKEN_SHARED_OBJECTS = $(LIBCHICKEN_OBJECTS_1:=$(O))
 LIBCHICKEN_STATIC_OBJECTS = $(LIBCHICKEN_OBJECTS_1:=-static$(O))
 
@@ -473,6 +473,8 @@ eval.c: $(SRCDIR)eval.scm $(SRCDIR)common-declarations.scm
 	$(bootstrap-lib)
 expand.c: $(SRCDIR)expand.scm $(SRCDIR)synrules.scm $(SRCDIR)common-declarations.scm
 	$(bootstrap-lib)
+modules.c: $(SRCDIR)modules.scm $(SRCDIR)common-declarations.scm
+	$(bootstrap-lib)
 extras.c: $(SRCDIR)extras.scm $(SRCDIR)private-namespace.scm $(SRCDIR)common-declarations.scm
 	$(bootstrap-lib)
 posixunix.c: $(SRCDIR)posixunix.scm $(SRCDIR)posix-common.scm $(SRCDIR)common-declarations.scm
Trap