>From 95dbd419ed6753fbcadb3f4c1b9b4fdd5287a7a6 Mon Sep 17 00:00:00 2001
From: Peter Bex
Date: Sat, 16 Aug 2014 17:02:01 +0200
Subject: [PATCH 10/19] compiler-modules: Simplify compiler module import
forms
Prefix the get, get-all, get-list and put! procedures with "db-".
This prevents confusion with the 2-argument "get" and "put!" versions
from library.scm, and it also cleans up the chicken module import.
Remove syntax-error from exclusion list: The module system merely
aliases identifiers, so it doesn't need any special handling in order
to prevent compiler modules from including the "wrong" syntax-error
procedure. Add a test for the aliasing behaviour of the module
system.
The debugging-chicken variable is used in a similar fashion: it is
defined in and exported by support, and it is set! in batch-driver.
It is read by both support and compiler.
---
batch-driver.scm | 7 +-
c-backend.scm | 3 +-
c-platform.scm | 37 +++++----
compiler-namespace.scm | 1 -
compiler-syntax.scm | 2 +-
compiler.scm | 180 +++++++++++++++++++++--------------------
lfa2.scm | 6 +-
optimizer.scm | 211 ++++++++++++++++++++++++------------------------
scrutinizer.scm | 23 +++---
support.scm | 101 ++++++++++++-----------
tests/module-tests.scm | 42 ++++++++++
11 files changed, 325 insertions(+), 288 deletions(-)
diff --git a/batch-driver.scm b/batch-driver.scm
index be286f9..b71d016 100644
--- a/batch-driver.scm
+++ b/batch-driver.scm
@@ -43,8 +43,7 @@
user-options-pass user-read-pass user-preprocessor-pass user-pass
user-post-analysis-pass)
-(import (except chicken put! get syntax-error) scheme
- extras data-structures files srfi-1
+(import chicken scheme extras data-structures files srfi-1
support lfa2 compiler-syntax optimizer scrutinizer c-platform c-backend)
(include "tweaks")
@@ -177,8 +176,8 @@
(let ((db (analyze-expression node)))
(when upap
(upap pass db node
- (cut get db <> <>)
- (cut put! db <> <> <>)
+ (cut db-get db <> <>)
+ (cut db-put! db <> <> <>)
no contf) )
db) ) )
diff --git a/c-backend.scm b/c-backend.scm
index 6d1131d..f91077b 100644
--- a/c-backend.scm
+++ b/c-backend.scm
@@ -42,8 +42,7 @@
;; For "foreign" (aka chicken-ffi-syntax):
foreign-type-declaration)
-(import (except chicken put! get syntax-error) scheme foreign
- srfi-1 data-structures
+(import chicken scheme foreign srfi-1 data-structures
c-platform support)
;;; Write atoms to output-port:
diff --git a/c-platform.scm b/c-platform.scm
index 50967db..bde46db 100644
--- a/c-platform.scm
+++ b/c-platform.scm
@@ -46,8 +46,7 @@
target-include-file words-per-flonum
parameter-limit small-parameter-limit)
-(import (except chicken put! get syntax-error) scheme
- srfi-1 data-structures
+(import chicken scheme srfi-1 data-structures
optimizer support)
(include "tweaks")
@@ -489,22 +488,22 @@
(and (= (length callargs) 1)
(call-with-current-continuation
(lambda (return)
- (let ([arg (first callargs)])
+ (let ((arg (first callargs)))
(make-node
'##core#call (list #t)
(list
cont
- (cond [(and (eq? '##core#variable (node-class arg))
- (eq? 'vector (get db (first (node-parameters arg)) 'rest-parameter)) )
+ (cond ((and (eq? '##core#variable (node-class arg))
+ (eq? 'vector (db-get db (first (node-parameters arg)) 'rest-parameter)) )
(make-node
'##core#inline
(if unsafe
'("C_slot")
'("C_i_vector_ref") )
- (list arg (qnode index)) ) ]
- [(and unsafe iop2) (make-node '##core#inline (list iop2) callargs)]
- [iop1 (make-node '##core#inline (list iop1) callargs)]
- [else (return #f)] ) ) ) ) ) ) ) ) ) )
+ (list arg (qnode index)) ) )
+ ((and unsafe iop2) (make-node '##core#inline (list iop2) callargs))
+ (iop1 (make-node '##core#inline (list iop1) callargs))
+ (else (return #f)) ) ) ) ) ) ) ) ) ) )
(rewrite-c..r 'car "C_i_car" "C_u_i_car" 0)
(rewrite-c..r '##sys#car "C_i_car" "C_u_i_car" 0)
@@ -535,7 +534,7 @@
(and (eq? '##core#variable (node-class arg1)) ; probably not needed
(eq? '##core#variable (node-class arg2))
(and-let* ((sym (car (node-parameters arg2)))
- (val (get db sym 'value)) )
+ (val (db-get db sym 'value)) )
(and (eq? '##core#lambda (node-class val))
(let ((llist (third (node-parameters val))))
(and (proper-list? llist)
@@ -1085,19 +1084,19 @@
(define (rewrite-call/cc db classargs cont callargs)
;; (call/cc ), = (lambda (kont k) ... k is never used ...) -> ( #f)
(and (= 1 (length callargs))
- (let ([val (first callargs)])
+ (let ((val (first callargs)))
(and (eq? '##core#variable (node-class val))
- (and-let* ([proc (get db (first (node-parameters val)) 'value)]
- [(eq? '##core#lambda (node-class proc))] )
- (let ([llist (third (node-parameters proc))])
+ (and-let* ((proc (db-get db (first (node-parameters val)) 'value))
+ ((eq? '##core#lambda (node-class proc))) )
+ (let ((llist (third (node-parameters proc))))
(##sys#decompose-lambda-list
llist
(lambda (vars argc rest)
(and (= argc 2)
- (let ([var (or rest (second llist))])
- (and (not (get db var 'references))
- (not (get db var 'assigned))
- (not (get db var 'inline-transient))
+ (let ((var (or rest (second llist))))
+ (and (not (db-get db var 'references))
+ (not (db-get db var 'assigned))
+ (not (db-get db var 'inline-transient))
(make-node
'##core#call (list #t)
(list val cont (qnode #f)) ) ) ) ) ) ) ) ) ) ) ) )
@@ -1161,7 +1160,7 @@
'##core#call (list #t)
(list cont
(if (and (eq? '##core#variable (node-class arg))
- (not (get db (car (node-parameters arg)) 'global)) )
+ (not (db-get db (car (node-parameters arg)) 'global)) )
(qnode #t)
(make-node
'##core#inline '("C_anyp")
diff --git a/compiler-namespace.scm b/compiler-namespace.scm
index 2a6a0fc..c0210b8 100644
--- a/compiler-namespace.scm
+++ b/compiler-namespace.scm
@@ -47,7 +47,6 @@
debug-info-vector-name
debug-lambda-list
debug-variable-list
- debugging-chicken
debugging-executable
default-default-target-heap-size
default-extended-bindings
diff --git a/compiler-syntax.scm b/compiler-syntax.scm
index 7c42bf2..e55ec5f 100644
--- a/compiler-syntax.scm
+++ b/compiler-syntax.scm
@@ -36,7 +36,7 @@
(module compiler-syntax
(compiler-syntax-statistics)
-(import (except chicken put! get syntax-error) scheme srfi-1 data-structures
+(import chicken scheme srfi-1 data-structures
support)
(include "tweaks.scm")
diff --git a/compiler.scm b/compiler.scm
index ce31f96..8c1013e 100644
--- a/compiler.scm
+++ b/compiler.scm
@@ -1860,9 +1860,9 @@
(unless (memq var localenv)
(grow 1)
(cond ((memq var env)
- (put! db var 'captured #t))
- ((not (get db var 'global))
- (put! db var 'global #t) ) ) ) ) )
+ (db-put! db var 'captured #t))
+ ((not (db-get db var 'global))
+ (db-put! db var 'global #t) ) ) ) ) )
((##core#callunit ##core#recurse)
(grow 1)
@@ -1884,7 +1884,7 @@
(walk (car vals) env (append params localenv) env2 here #f)
(let ([var (car vars)]
[val (car vals)] )
- (put! db var 'home here)
+ (db-put! db var 'home here)
(assign var val env2 here)
(walk val env localenv fullenv here #f)
(loop (cdr vars) (cdr vals)) ) ) ) ) )
@@ -1895,7 +1895,7 @@
(first params)
(lambda (vars argc rest)
(for-each
- (lambda (var) (put! db var 'unknown #t))
+ (lambda (var) (db-put! db var 'unknown #t))
vars)
(let ([tl toplevel-scope])
(set! toplevel-scope #f)
@@ -1911,15 +1911,15 @@
[size0 current-program-size] )
(when here
(collect! db here 'contains id)
- (put! db id 'contained-in here) )
+ (db-put! db id 'contained-in here) )
(for-each
(lambda (var)
- (put! db var 'home here)
- (put! db var 'unknown #t) )
+ (db-put! db var 'home here)
+ (db-put! db var 'unknown #t) )
vars)
(when rest
- (put! db rest 'rest-parameter 'list) )
- (when (simple-lambda-node? n) (put! db id 'simple #t))
+ (db-put! db rest 'rest-parameter 'list) )
+ (when (simple-lambda-node? n) (db-put! db id 'simple #t))
(let ([tl toplevel-scope])
(unless toplevel-lambda-id (set! toplevel-lambda-id id))
(when (and (second params) (not (eq? toplevel-lambda-id id)))
@@ -1938,16 +1938,16 @@
(warning "redefinition of standard binding" var) )
((extended)
(warning "redefinition of extended binding" var) ) ))
- (put! db var 'potential-value val)
+ (db-put! db var 'potential-value val)
(unless (memq var localenv)
(grow 1)
(cond ((memq var env)
- (put! db var 'captured #t))
- ((not (get db var 'global))
- (put! db var 'global #t) ) ) )
+ (db-put! db var 'captured #t))
+ ((not (db-get db var 'global))
+ (db-put! db var 'global #t) ) ) )
(assign var val fullenv here)
- (unless toplevel-scope (put! db var 'assigned-locally #t))
- (put! db var 'assigned #t)
+ (unless toplevel-scope (db-put! db var 'assigned-locally #t))
+ (db-put! db var 'assigned #t)
(walk (car subs) env localenv fullenv here #f) ) )
((##core#primitive ##core#inline)
@@ -1963,30 +1963,30 @@
(define (assign var val env here)
(cond ((eq? '##core#undefined (node-class val))
- (put! db var 'undefined #t) )
+ (db-put! db var 'undefined #t) )
((and (eq? '##core#variable (node-class val)) ; assignment to itself
(eq? var (first (node-parameters val))) ) )
((or (memq var env)
(variable-mark var '##compiler#constant)
(not (variable-visible? var)))
- (let ((props (get-all db var 'unknown 'value))
- (home (get db var 'home)) )
+ (let ((props (db-get-all db var 'unknown 'value))
+ (home (db-get db var 'home)) )
(unless (assq 'unknown props)
(if (assq 'value props)
- (put! db var 'unknown #t)
+ (db-put! db var 'unknown #t)
(if (or (not home) (eq? here home))
- (put! db var 'value val)
- (put! db var 'unknown #t) ) ) ) ) )
+ (db-put! db var 'value val)
+ (db-put! db var 'unknown #t) ) ) ) ) )
((and (or local-definitions
(variable-mark var '##compiler#local))
- (not (get db var 'unknown)))
- (let ((home (get db var 'home)))
- (cond ((get db var 'local-value)
- (put! db var 'unknown #t))
+ (not (db-get db var 'unknown)))
+ (let ((home (db-get db var 'home)))
+ (cond ((db-get db var 'local-value)
+ (db-put! db var 'unknown #t))
((or (not home) (eq? here home))
- (put! db var 'local-value val) )
- (else (put! db var 'unknown #t)))))
- (else (put! db var 'unknown #t)) ) )
+ (db-put! db var 'local-value val) )
+ (else (db-put! db var 'unknown #t)))))
+ (else (db-put! db var 'unknown #t)) ) )
(define (ref var node)
(collect! db var 'references node) )
@@ -2078,7 +2078,7 @@
(when (and (eq? '##core#lambda (node-class value))
(or (not (second valparams))
(every
- (lambda (v) (get db v 'global))
+ (lambda (v) (db-get db v 'global))
(nth-value 0 (scan-free-variables value)) ) ) )
(if (and (= 1 nreferences) (= 1 ncall-sites))
(quick-put! plist 'contractable #t)
@@ -2088,12 +2088,12 @@
(let ((valparams (node-parameters local-value)))
(when (eq? '##core#lambda (node-class local-value))
(let-values (((vars hvars) (scan-free-variables local-value)))
- (when (and (get db sym 'global)
+ (when (and (db-get db sym 'global)
(pair? hvars))
(quick-put! plist 'hidden-refs #t))
(when (or (not (second valparams))
(every
- (lambda (v) (get db v 'global))
+ (lambda (v) (db-get db v 'global))
vars))
(quick-put! plist 'inlinable #t) ) ) ) ) )
((variable-mark sym '##compiler#inline-global) =>
@@ -2127,10 +2127,10 @@
;; - if the procedure is internal (a continuation) do NOT mark unused parameters.
;; - also: if procedure has rest-parameter and no unused params, mark f-id as 'explicit-rest.
(when value
- (let ([has #f])
+ (let ((has #f))
(when (and (eq? '##core#lambda (node-class value))
(= nreferences ncall-sites) )
- (let ([lparams (node-parameters value)])
+ (let ((lparams (node-parameters value)))
(when (second lparams)
(##sys#decompose-lambda-list
(third lparams)
@@ -2138,17 +2138,17 @@
(unless rest
(for-each
(lambda (var)
- (cond [(and (not (get db var 'references))
- (not (get db var 'assigned)) )
- (put! db var 'unused #t)
+ (cond ((and (not (db-get db var 'references))
+ (not (db-get db var 'assigned)) )
+ (db-put! db var 'unused #t)
(set! has #t)
- #t]
- [else #f] ) )
+ #t)
+ (else #f) ) )
vars) )
- (cond [(and has (not (rassoc sym callback-names eq?)))
- (put! db (first lparams) 'has-unused-parameters #t) ]
- [rest
- (put! db (first lparams) 'explicit-rest #t) ] ) ) ) ) ) ) ) )
+ (cond ((and has (not (rassoc sym callback-names eq?)))
+ (db-put! db (first lparams) 'has-unused-parameters #t) )
+ (rest
+ (db-put! db (first lparams) 'explicit-rest #t) ) ) ) ) ) ) ) ) )
;; Make 'removable, if it has no references and is not assigned to, and if it
;; has either a value that does not cause any side-effects or if it is 'undefined:
@@ -2157,7 +2157,7 @@
(or (and value
(if (eq? '##core#variable (node-class value))
(let ((varname (first (node-parameters value))))
- (or (not (get db varname 'global))
+ (or (not (db-get db varname 'global))
(variable-mark varname '##core#always-bound)
(intrinsic? varname)))
(not (expression-has-side-effects? value db)) ))
@@ -2173,40 +2173,41 @@
;; it was contracted).
(when (and value (not global))
(when (eq? '##core#variable (node-class value))
- (let* ([name (first (node-parameters value))]
- [nrefs (get db name 'references)] )
+ (let* ((name (first (node-parameters value)))
+ (nrefs (db-get db name 'references)) )
(when (and (not captured)
- (or (and (not (get db name 'unknown)) (get db name 'value))
- (and (not (get db name 'captured))
+ (or (and (not (db-get db name 'unknown))
+ (db-get db name 'value))
+ (and (not (db-get db name 'captured))
nrefs
(= 1 (length nrefs))
(not assigned)
- (not (get db name 'assigned))
+ (not (db-get db name 'assigned))
(or (not (variable-visible? name))
- (not (get db name 'global))) ) ))
+ (not (db-get db name 'global))) ) ))
(quick-put! plist 'replacable name)
- (put! db name 'replacing #t) ) ) ) )
+ (db-put! db name 'replacing #t) ) ) ) )
;; Make 'replacable, if it has a known value of the form: '(lambda () ( ))' and
;; is an internally created procedure: (See above for 'replacing)
(when (and value (eq? '##core#lambda (node-class value)))
- (let ([params (node-parameters value)])
+ (let ((params (node-parameters value)))
(when (not (second params))
- (let ([llist (third params)]
- [body (first (node-subexpressions value))] )
+ (let ((llist (third params))
+ (body (first (node-subexpressions value))) )
(when (and (pair? llist)
(null? (cdr llist))
(eq? '##core#call (node-class body)) )
- (let ([subs (node-subexpressions body)])
+ (let ((subs (node-subexpressions body)))
(when (= 2 (length subs))
- (let ([v1 (first subs)]
- [v2 (second subs)] )
+ (let ((v1 (first subs))
+ (v2 (second subs)) )
(when (and (eq? '##core#variable (node-class v1))
(eq? '##core#variable (node-class v2))
(eq? (first llist) (first (node-parameters v2))) )
- (let ([kvar (first (node-parameters v1))])
+ (let ((kvar (first (node-parameters v1))))
(quick-put! plist 'replacable kvar)
- (put! db kvar 'replacing #t) ) ) ) ) ) ) ) ) ) ) ) )
+ (db-put! db kvar 'replacing #t) ) ) ) ) ) ) ) ) ) ) ) )
db)
@@ -2228,11 +2229,11 @@
(customizable '())
(lexicals '()))
- (define (test sym item) (get db sym item))
+ (define (test sym item) (db-get db sym item))
(define (register-customizable! var id)
(set! customizable (lset-adjoin eq? customizable var))
- (put! db id 'customizable #t) )
+ (db-put! db id 'customizable #t) )
(define (register-direct-call! id)
(set! direct-calls (add1 direct-calls))
@@ -2320,8 +2321,8 @@
(let ((id (if here (first params) 'toplevel)))
(fluid-let ((lexicals (append locals lexicals)))
(let ((c (delete-duplicates (gather (first subs) id vars) eq?)))
- (put! db id 'closure-size (length c))
- (put! db id 'captured-variables c)
+ (db-put! db id 'closure-size (length c))
+ (db-put! db id 'captured-variables c)
(lset-difference eq? c locals vars)))))))
(else (concatenate (map (lambda (n) (gather n here locals)) subs)) ) ) ))
@@ -2366,24 +2367,24 @@
(maptransform subs here closure) ) ) ) )
((##core#lambda ##core#direct_lambda)
- (let ([llist (third params)])
+ (let ((llist (third params)))
(##sys#decompose-lambda-list
llist
(lambda (vars argc rest)
- (let* ([boxedvars (filter (lambda (v) (test v 'boxed)) vars)]
- [boxedaliases (map cons boxedvars (map gensym boxedvars))]
- [cvar (gensym 'c)]
- [id (if here (first params) 'toplevel)]
- [capturedvars (or (test id 'captured-variables) '())]
- [csize (or (test id 'closure-size) 0)]
- [info (and emit-closure-info (second params) (pair? llist))] )
+ (let* ((boxedvars (filter (lambda (v) (test v 'boxed)) vars))
+ (boxedaliases (map cons boxedvars (map gensym boxedvars)))
+ (cvar (gensym 'c))
+ (id (if here (first params) 'toplevel))
+ (capturedvars (or (test id 'captured-variables) '()))
+ (csize (or (test id 'closure-size) 0))
+ (info (and emit-closure-info (second params) (pair? llist))) )
;; If rest-parameter is boxed: mark it as 'boxed-rest
;; (if we don't do this than preparation will think the (boxed) alias
;; of the rest-parameter is never used)
- (and-let* ([rest]
- [(test rest 'boxed)]
- [rp (test rest 'rest-parameter)] )
- (put! db (cdr (assq rest boxedaliases)) 'boxed-rest #t) )
+ (and-let* ((rest)
+ ((test rest 'boxed))
+ (rp (test rest 'rest-parameter)) )
+ (db-put! db (cdr (assq rest boxedaliases)) 'boxed-rest #t) )
(make-node
'##core#closure (list (+ csize (if info 2 1)))
(cons
@@ -2540,7 +2541,7 @@
unsafe
(variable-mark var '##compiler#always-bound)
(intrinsic? var))]
- [blockvar (and (get db var 'assigned)
+ [blockvar (and (db-get db var 'assigned)
(not (variable-visible? var)))])
(when blockvar (set! fastrefs (add1 fastrefs)))
(make-node
@@ -2615,23 +2616,24 @@
(##sys#decompose-lambda-list
(third params)
(lambda (vars argc rest)
- (let* ([id (first params)]
- [rest-mode
+ (let* ((id (first params))
+ (rest-mode
(and rest
- (let ([rrefs (get db rest 'references)])
- (cond [(get db rest 'assigned) 'list]
- [(and (not (get db rest 'boxed-rest)) (or (not rrefs) (null? rrefs))) 'none]
- [else (get db rest 'rest-parameter)] ) ) ) ]
- [body (walk
+ (let ((rrefs (db-get db rest 'references)))
+ (cond ((db-get db rest 'assigned) 'list)
+ ((and (not (db-get db rest 'boxed-rest))
+ (or (not rrefs) (null? rrefs))) 'none)
+ (else (db-get db rest 'rest-parameter)) ) ) ) )
+ (body (walk
(car subs)
(##sys#fast-reverse (if (eq? 'none rest-mode)
- (butlast vars)
- vars))
- (if (eq? 'none rest-mode)
+ (butlast vars)
+ vars))
+ (if (eq? 'none rest-mode)
(fx- (length vars) 1)
(length vars))
id
- '()) ] )
+ '()) ) )
(when (eq? rest-mode 'none)
(debugging 'o "unused rest argument" rest id))
(when (and direct rest)
@@ -2650,13 +2652,13 @@
signatures
allocated
(or direct (memq id direct-call-ids))
- (or (get db id 'closure-size) 0)
+ (or (db-get db id 'closure-size) 0)
(and (not rest)
(> looping 0)
(begin
(debugging 'o "identified direct recursive calls" id looping)
#t) )
- (or direct (get db id 'customizable))
+ (or direct (db-get db id 'customizable))
rest-mode
body
direct) )
diff --git a/lfa2.scm b/lfa2.scm
index 3e58989..386fd16 100644
--- a/lfa2.scm
+++ b/lfa2.scm
@@ -44,7 +44,7 @@
(module lfa2
(perform-secondary-flow-analysis)
-(import (except chicken put! get syntax-error) scheme srfi-1
+(import chicken scheme srfi-1
support)
(include "tweaks")
@@ -191,14 +191,14 @@
(else (set! stats (alist-cons elim 1 stats)))))
(define (assigned? var)
- (get db var 'assigned))
+ (db-get db var 'assigned))
(define (droppable? n)
(or (memq (node-class n)
'(quote ##core#undefined ##core#primitive ##core#lambda))
(and (eq? '##core#variable (node-class n))
(let ((var (first (node-parameters n))))
- (or (not (get db var 'global))
+ (or (not (db-get db var 'global))
(variable-mark var '##compiler#always-bound))))))
(define (drop! n)
diff --git a/optimizer.scm b/optimizer.scm
index 1b54c51..c4aa8f3 100644
--- a/optimizer.scm
+++ b/optimizer.scm
@@ -40,8 +40,7 @@
eq-inline-operator membership-test-operators membership-unfold-limit
default-optimization-passes rewrite)
-(import (except chicken put! get syntax-error) scheme
- srfi-1 data-structures
+(import chicken scheme srfi-1 data-structures
support)
(include "tweaks")
@@ -150,14 +149,14 @@
(define simplified-ops '())
(define (perform-high-level-optimizations node db)
- (let ([removed-lets 0]
- [removed-ifs 0]
- [replaced-vars 0]
- [rest-consers '()]
- [simplified-classes '()]
- [dirty #f] )
-
- (define (test sym item) (get db sym item))
+ (let ((removed-lets 0)
+ (removed-ifs 0)
+ (replaced-vars 0)
+ (rest-consers '())
+ (simplified-classes '())
+ (dirty #f) )
+
+ (define (test sym item) (db-get db sym item))
(define (constant-node? n) (eq? 'quote (node-class n)))
(define (node-value n) (first (node-parameters n)))
(define (touch) (set! dirty #t))
@@ -234,7 +233,7 @@
(lambda (rvar)
(let ((final-var (replace-var rvar)))
;; Store intermediate vars to avoid recurring same chain again
- (put! db var 'replacable final-var)
+ (db-put! db var 'replacable final-var)
final-var)))
(else var)))
@@ -341,7 +340,7 @@
(check-signature var args llist)
(debugging 'o "contracted procedure" info)
(touch)
- (for-each (cut put! db <> 'inline-target #t) fids)
+ (for-each (cut db-put! db <> 'inline-target #t) fids)
(walk
(inline-lambda-bindings
llist args (first (node-subexpressions lval)) #f db
@@ -393,7 +392,7 @@
"global inlining"
"inlining")
info ifid (fourth lparams))
- (for-each (cut put! db <> 'inline-target #t) fids)
+ (for-each (cut db-put! db <> 'inline-target #t) fids)
(check-signature var args llist)
(debugging 'o "inlining procedure" info)
(call/cc
@@ -569,7 +568,7 @@
(removed-nots 0) )
(define (touch) (set! dirty #t) #t)
- (define (test sym prop) (get db sym prop))
+ (define (test sym prop) (db-get db sym prop))
(debugging 'p "pre-optimization phase...")
@@ -581,7 +580,7 @@
(subs (node-subexpressions n))
(kont (first (node-parameters (second subs))))
(lnode (and (not (test kont 'unknown)) (test kont 'value)))
- (krefs (get-list db kont 'references)) )
+ (krefs (db-get-list db kont 'references)) )
;; Call-site has one argument and a known continuation (which is a ##core#lambda)
;; that has only one use:
(when (and lnode krefs (= 1 (length krefs)) (= 3 (length subs))
@@ -592,7 +591,7 @@
;; Continuation has one parameter?
(if (and (proper-list? llist) (null? (cdr llist)))
(let* ((var (car llist))
- (refs (get-list db var 'references)) )
+ (refs (db-get-list db var 'references)) )
;; Parameter is only used once?
(if (and refs (= 1 (length refs)) (eq? 'if (node-class body)))
;; Continuation contains an 'if' node?
@@ -662,8 +661,8 @@
(and (equal? op (eq-inline-operator))
(immediate? const1)
(immediate? const2)
- (= 1 (length (get-list db var1 'references)))
- (= 1 (length (get-list db var2 'references)))
+ (= 1 (length (db-get-list db var1 'references)))
+ (= 1 (length (db-get-list db var2 'references)))
(make-node
'##core#switch
'(2)
@@ -688,7 +687,7 @@
,(lambda (db var op var0 const d body n clauses)
(and (equal? op (eq-inline-operator))
(immediate? const)
- (= 1 (length (get-list db var 'references)))
+ (= 1 (length (db-get-list db var 'references)))
(make-node
'##core#switch
(list (add1 n))
@@ -710,46 +709,46 @@
more)
(var1 more)
,(lambda (db var1 more)
- (let loop1 ([vars (list var1)]
- [body more] )
- (let ([c (node-class body)]
- [params (node-parameters body)]
- [subs (node-subexpressions body)] )
+ (let loop1 ((vars (list var1))
+ (body more) )
+ (let ((c (node-class body))
+ (params (node-parameters body))
+ (subs (node-subexpressions body)) )
(and (eq? c 'let)
(null? (cdr params))
- (not (get db (first params) 'inline-transient))
- (not (get db (first params) 'references))
- (let* ([val (first subs)]
- [valparams (node-parameters val)]
- [valsubs (node-subexpressions val)] )
+ (not (db-get db (first params) 'inline-transient))
+ (not (db-get db (first params) 'references))
+ (let* ((val (first subs))
+ (valparams (node-parameters val))
+ (valsubs (node-subexpressions val)) )
(case (node-class val)
- [(##core#undefined) (loop1 (cons (first params) vars) (second subs))]
- [(set!)
- (let ([allvars (reverse vars)])
+ ((##core#undefined) (loop1 (cons (first params) vars) (second subs)))
+ ((set!)
+ (let ((allvars (reverse vars)))
(and (pair? allvars)
(eq? (first valparams) (first allvars))
- (let loop2 ([vals (list (first valsubs))]
- [vars (cdr allvars)]
- [body (second subs)] )
- (let ([c (node-class body)]
- [params (node-parameters body)]
- [subs (node-subexpressions body)] )
- (cond [(and (eq? c 'let)
+ (let loop2 ((vals (list (first valsubs)))
+ (vars (cdr allvars))
+ (body (second subs)) )
+ (let ((c (node-class body))
+ (params (node-parameters body))
+ (subs (node-subexpressions body)) )
+ (cond ((and (eq? c 'let)
(null? (cdr params))
- (not (get db (first params) 'inline-transient))
- (not (get db (first params) 'references))
+ (not (db-get db (first params) 'inline-transient))
+ (not (db-get db (first params) 'references))
(pair? vars)
(eq? 'set! (node-class (first subs)))
(eq? (car vars) (first (node-parameters (first subs)))) )
(loop2 (cons (first (node-subexpressions (first subs))) vals)
(cdr vars)
- (second subs) ) ]
- [(null? vars)
+ (second subs) ) )
+ ((null? vars)
(receive (n progress)
(reorganize-recursive-bindings allvars (reverse vals) body)
- (and progress n) ) ]
- [else #f] ) ) ) ) ) ]
- [else #f] ) ) ) ) ) ) )
+ (and progress n) ) )
+ (else #f) ) ) ) ) ) )
+ (else #f) ) ) ) ) ) ) )
;; (let (( ))
;; ( ...) )
@@ -760,7 +759,7 @@
(##core#call p (##core#variable (var1)) . more) ) ; `p' was `#t', bombed also
(var1 var2 p more)
,(lambda (db var1 var2 p more)
- (and (= 1 (length (get-list db var1 'references)))
+ (and (= 1 (length (db-get-list db var1 'references)))
(make-node
'##core#call p
(cons (varnode var2) more) ) ) ) )
@@ -778,7 +777,7 @@
(var op args d x y)
,(lambda (db var op args d x y)
(and (not (equal? op (eq-inline-operator)))
- (= 1 (length (get-list db var 'references)))
+ (= 1 (length (db-get-list db var 'references)))
(make-node
'if d
(list (make-node '##core#inline (list op) args)
@@ -935,7 +934,7 @@
(##sys#hash-table-set! substitution-table name (append old (list class-and-args))) ) )
(define (simplify-named-call db params name cont class classargs callargs)
- (define (test sym prop) (get db sym prop))
+ (define (test sym prop) (db-get db sym prop))
(define (defarg x)
(cond ((symbol? x) (varnode x))
((and (pair? x) (eq? 'quote (car x))) (qnode (cadr x)))
@@ -1339,10 +1338,10 @@
;;; Optimize direct leaf routines:
(define (transform-direct-lambdas! node db)
- (let ([dirty #f]
- [inner-ks '()]
- [hoistable '()]
- [allocated 0] )
+ (let ((dirty #f)
+ (inner-ks '())
+ (hoistable '())
+ (allocated 0) )
;; Process node tree and walk lambdas that meet the following constraints:
;; - Only external lambdas (no CPS redexes),
@@ -1352,18 +1351,18 @@
;; - The lambda is not marked as a callback lambda
(define (walk d n dn)
- (let ([params (node-parameters n)]
- [subs (node-subexpressions n)] )
+ (let ((params (node-parameters n))
+ (subs (node-subexpressions n)) )
(case (node-class n)
- [(##core#lambda)
- (let ([llist (third params)])
+ ((##core#lambda)
+ (let ((llist (third params)))
(if (and d
(second params)
- (not (get db d 'unknown))
+ (not (db-get db d 'unknown))
(proper-list? llist)
- (and-let* ([val (get db d 'value)]
- [refs (get-list db d 'references)]
- [sites (get-list db d 'call-sites)] )
+ (and-let* ((val (db-get db d 'value))
+ (refs (db-get-list db d 'references))
+ (sites (db-get-list db d 'call-sites)) )
;; val must be lambda, since `sites' is set
(and (eq? n val)
(not (variable-mark
@@ -1372,87 +1371,87 @@
(= (length refs) (length sites))
(scan (first subs) (first llist) d dn (cons d llist)) ) ) )
(transform n d inner-ks hoistable dn allocated)
- (walk #f (first subs) #f) ) ) ]
- [(set!) (walk (first params) (first subs) #f)]
- [(let)
+ (walk #f (first subs) #f) ) ) )
+ ((set!) (walk (first params) (first subs) #f))
+ ((let)
(walk (first params) (first subs) n)
- (walk #f (second subs) #f) ]
- [else (for-each (lambda (x) (walk #f x #f)) subs)] ) ) )
+ (walk #f (second subs) #f) )
+ (else (for-each (lambda (x) (walk #f x #f)) subs)) ) ) )
(define (scan n kvar fnvar destn env)
- (let ([closures '()]
- [recursive #f] )
+ (let ((closures '())
+ (recursive #f) )
(define (rec n v vn e)
- (let ([params (node-parameters n)]
- [subs (node-subexpressions n)] )
+ (let ((params (node-parameters n))
+ (subs (node-subexpressions n)) )
(case (node-class n)
- [(##core#variable)
- (let ([v (first params)])
- (or (not (get db v 'boxed))
+ ((##core#variable)
+ (let ((v (first params)))
+ (or (not (db-get db v 'boxed))
(not (memq v env))
(and (not recursive)
(begin
(set! allocated (+ allocated 2))
- #t) ) ) ) ]
- [(##core#lambda)
+ #t) ) ) ) )
+ ((##core#lambda)
(and v
(##sys#decompose-lambda-list
(third params)
(lambda (vars argc rest)
(set! closures (cons v closures))
- (rec (first subs) #f #f (append vars e)) ) ) ) ]
- [(##core#inline_allocate)
+ (rec (first subs) #f #f (append vars e)) ) ) ) )
+ ((##core#inline_allocate)
(and (not recursive)
(begin
(set! allocated (+ allocated (second params)))
- (every (lambda (x) (rec x #f #f e)) subs) ) ) ]
- [(##core#direct_lambda)
+ (every (lambda (x) (rec x #f #f e)) subs) ) ) )
+ ((##core#direct_lambda)
(and vn destn
(null? (scan-used-variables (first subs) e))
(begin
(set! hoistable (alist-cons v vn hoistable))
- #t) ) ]
- [(##core#inline_ref)
- (and (let ([n (estimate-foreign-result-size (second params))])
+ #t) ) )
+ ((##core#inline_ref)
+ (and (let ((n (estimate-foreign-result-size (second params))))
(or (zero? n)
(and (not recursive)
(begin
(set! allocated (+ allocated n))
#t) ) ) )
- (every (lambda (x) (rec x #f #f e)) subs) ) ]
- [(##core#inline_loc_ref)
- (and (let ([n (estimate-foreign-result-size (first params))])
+ (every (lambda (x) (rec x #f #f e)) subs) ) )
+ ((##core#inline_loc_ref)
+ (and (let ((n (estimate-foreign-result-size (first params))))
(or (zero? n)
(and (not recursive)
(begin
(set! allocated (+ allocated n))
#t) ) ) )
- (every (lambda (x) (rec x #f #f e)) subs) ) ]
- [(##core#call)
- (let ([fn (first subs)])
+ (every (lambda (x) (rec x #f #f e)) subs) ) )
+ ((##core#call)
+ (let ((fn (first subs)))
(and (eq? '##core#variable (node-class fn))
- (let ([v (first (node-parameters fn))])
- (cond [(eq? v fnvar)
+ (let ((v (first (node-parameters fn))))
+ (cond ((eq? v fnvar)
(and (zero? allocated)
- (let ([k (second subs)])
+ (let ((k (second subs)))
(when (eq? '##core#variable (node-class k))
(set! inner-ks (cons (first (node-parameters k)) inner-ks)) )
(set! recursive #t)
- #t) ) ]
- [else (eq? v kvar)] ) )
- (every (lambda (x) (rec x #f #f e)) (cdr subs)) ) ) ]
- [(##core#direct_call)
- (let ([n (fourth params)])
+ #t) ) )
+ (else (eq? v kvar)) ) )
+ (every (lambda (x) (rec x #f #f e)) (cdr subs)) ) ) )
+ ((##core#direct_call)
+ (let ((n (fourth params)))
(or (zero? n)
(and (not recursive)
(begin
(set! allocated (+ allocated n))
- (every (lambda (x) (rec x #f #f e)) subs) ) ) ) ) ]
- [(set!) (rec (first subs) (first params) #f e)]
- [(let)
+ (every (lambda (x) (rec x #f #f e)) subs) ) ) ) ) )
+ ((set!) (rec (first subs) (first params) #f e))
+ ((let)
(and (rec (first subs) (first params) n e)
- (rec (second subs) #f #f (append params e)) ) ]
- [else (every (lambda (x) (rec x #f #f e)) subs)] ) ) )
+ (rec (second subs) #f #f (append params e)) ) )
+ (else (every (lambda (x) (rec x #f #f e)) subs)) ) ) )
(set! inner-ks '())
(set! hoistable '())
(set! allocated 0)
@@ -1464,11 +1463,11 @@
(debugging 'o "direct leaf routine with hoistable closures/allocation" fnvar (delay (unzip1 hoistable)) allocated)
(debugging 'o "direct leaf routine/allocation" fnvar allocated) )
(set! dirty #t)
- (let* ([params (node-parameters n)]
- [argc (length (third params))]
- [klambdas '()]
- [sites (or (get db fnvar 'call-sites) '())]
- [ksites '()] )
+ (let* ((params (node-parameters n))
+ (argc (length (third params)))
+ (klambdas '())
+ (sites (or (db-get db fnvar 'call-sites) '()))
+ (ksites '()) )
(if (and (list? params) (= (length params) 4) (list? (caddr params)))
(let ((id (car params))
(kvar (caaddr params))
diff --git a/scrutinizer.scm b/scrutinizer.scm
index 3eed5b6..5421355 100644
--- a/scrutinizer.scm
+++ b/scrutinizer.scm
@@ -37,8 +37,7 @@
(scrutinize load-type-database emit-type-file
validate-type check-and-validate-type install-specializations)
-(import (except chicken put! get syntax-error) scheme
- srfi-1 data-structures extras ports files
+(import chicken scheme srfi-1 data-structures extras ports files
support)
(include "tweaks")
@@ -192,7 +191,7 @@
(define (variable-result id e loc flow)
(cond ((blist-type id flow) => list)
((and (not strict-variable-types)
- (get db id 'assigned)
+ (db-get db id 'assigned)
(not (variable-mark id '##compiler#declared-type)))
'(*))
((assq id e) =>
@@ -550,9 +549,9 @@
(walk val e loc var #f flow #f)
loc)))
(when (and (eq? (node-class val) '##core#variable)
- (not (get db var 'assigned)))
+ (not (db-get db var 'assigned)))
(let ((var2 (first (node-parameters val))))
- (unless (get db var2 'assigned) ;XXX too conservative?
+ (unless (db-get db var2 'assigned) ;XXX too conservative?
(set! aliased (alist-cons var var2 aliased)))))
(loop (cdr vars) (cdr body) (alist-cons (car vars) t e2))))))
((##core#lambda lambda)
@@ -593,7 +592,7 @@
(list
(let loop ((argc argc) (vars vars) (args args))
(cond ((zero? argc) args)
- ((and (not (get db (car vars) 'assigned))
+ ((and (not (db-get db (car vars) 'assigned))
(assoc (cons (car vars) initial-tag) blist))
=>
(lambda (a)
@@ -634,9 +633,9 @@
(when (and (not type) ;XXX global declaration could allow this
(not b)
(not (eq? '* rt))
- (not (get db var 'unknown)))
- (and-let* ((val (or (get db var 'value)
- (get db var 'local-value))))
+ (not (db-get db var 'unknown)))
+ (and-let* ((val (or (db-get db var 'value)
+ (db-get db var 'local-value))))
(when (and (eq? val (first subs))
(or (not (variable-visible? var))
(not (eq? (variable-mark var '##compiler#inline)
@@ -666,7 +665,7 @@
#t)))))
;; don't use "add-to-blist" since the current operation does not affect aliases
(let ((t (if (or strict-variable-types
- (not (get db var 'captured)))
+ (not (db-get db var 'captured)))
rt
'*))
(fl (car flow)))
@@ -737,7 +736,7 @@
(oparg? (eq? arg (first subs)))
(pred (and pt
ctags
- (not (get db var 'assigned))
+ (not (db-get db var 'assigned))
(not oparg?))))
(cond (pred
;;XXX is this needed? "typeenv" is the te of "args",
@@ -766,7 +765,7 @@
(if (type<=? t argr)
t
argr)))
- ((get db var 'assigned) '*)
+ ((db-get db var 'assigned) '*)
((type<=? (cdr a) argr) (cdr a))
(else argr))))
(d " assuming: ~a -> ~a (flow: ~a)"
diff --git a/support.scm b/support.scm
index c08cd27..b067d70 100644
--- a/support.scm
+++ b/support.scm
@@ -35,16 +35,17 @@
(module support
(compiler-cleanup-hook bomb collected-debugging-output debugging
- with-debugging-output quit-compiling emit-syntax-trace-info
- check-signature posq posv stringify symbolify
+ debugging-chicken with-debugging-output quit-compiling
+ emit-syntax-trace-info check-signature posq posv stringify symbolify
build-lambda-list string->c-identifier c-ify-string valid-c-identifier?
bytes->words words->bytes
check-and-open-input-file close-checked-input-file fold-inner
constant? collapsable-literal? immediate? basic-literal?
canonicalize-begin-body string->expr llist-length llist-match?
- expand-profile-lambda initialize-analysis-database get get-all put!
- collect! get-list get-line get-line-2 display-line-number-database
- display-analysis-database make-node node? node-class node-class-set!
+ expand-profile-lambda initialize-analysis-database db-get db-get-all
+ db-put! collect! db-get-list get-line get-line-2
+ display-line-number-database display-analysis-database
+ make-node node? node-class node-class-set!
node-parameters node-parameters-set!
node-subexpressions node-subexpressions-set! varnode qnode
build-node-graph build-expression-tree fold-boolean inline-lambda-bindings
@@ -65,8 +66,7 @@
mark-variable variable-mark intrinsic? foldable? load-identifier-database
print-version print-usage print-debug-options)
-(import (except chicken put! get syntax-error) scheme foreign
- data-structures srfi-1 files extras ports)
+(import chicken scheme foreign data-structures srfi-1 files extras ports)
(include "tweaks")
(include "banner")
@@ -409,21 +409,19 @@
internal-bindings))
(set! initial #f))))
-;; TODO: Rename this to avoid conflict/confusion with the one from scheme
-(define (get db key prop)
+(define (db-get db key prop)
(let ((plist (##sys#hash-table-ref db key)))
(and plist
(let ([a (assq prop plist)])
(and a (##sys#slot a 1)) ) ) ) )
-(define (get-all db key . props)
+(define (db-get-all db key . props)
(let ((plist (##sys#hash-table-ref db key)))
(if plist
(filter-map (lambda (prop) (assq prop plist)) props)
'() ) ) )
-;; TODO: Rename this to avoid conflict/confusion with the one from scheme
-(define (put! db key prop val)
+(define (db-put! db key prop val)
(let ([plist (##sys#hash-table-ref db key)])
(if plist
(let ([a (assq prop plist)])
@@ -439,15 +437,15 @@
[else (##sys#setslot plist 1 (alist-cons prop (list val) (##sys#slot plist 1)))] ) )
(##sys#hash-table-set! db key (list (list prop val)))) ) )
-(define (get-list db key prop) ; returns '() if not set
- (let ((x (get db key prop)))
+(define (db-get-list db key prop) ; returns '() if not set
+ (let ((x (db-get db key prop)))
(or x '())))
;;; Line-number database management:
(define (get-line exp)
- (get ##sys#line-number-database (car exp) exp) )
+ (db-get ##sys#line-number-database (car exp) exp) )
(define (get-line-2 exp)
(let* ((name (car exp))
@@ -739,40 +737,40 @@
;; Copy along with the above
(define (copy-node-tree-and-rename node vars aliases db cfk)
- (let ([rlist (map cons vars aliases)])
+ (let ((rlist (map cons vars aliases)))
(define (rename v rl) (alist-ref v rl eq? v))
(define (walk n rl)
- (let ([subs (node-subexpressions n)]
- [params (node-parameters n)]
- [class (node-class n)] )
+ (let ((subs (node-subexpressions n))
+ (params (node-parameters n))
+ (class (node-class n)) )
(case class
((quote)
(make-node class params '()))
- [(##core#variable)
+ ((##core#variable)
(let ((var (first params)))
- (when (get db var 'contractable)
+ (when (db-get db var 'contractable)
(cfk var))
- (varnode (rename var rl))) ]
- [(set!)
+ (varnode (rename var rl))) )
+ ((set!)
(make-node
'set! (list (rename (first params) rl))
- (list (walk (first subs) rl)) ) ]
- [(let)
+ (list (walk (first subs) rl)) ) )
+ ((let)
(let* ((v (first params))
(val1 (walk (first subs) rl))
(a (gensym v))
(rl2 (alist-cons v a rl)) )
- (put! db a 'inline-transient #t)
+ (db-put! db a 'inline-transient #t)
(make-node
'let (list a)
- (list val1 (walk (second subs) rl2)))) ]
- [(##core#lambda)
+ (list val1 (walk (second subs) rl2)))) )
+ ((##core#lambda)
(##sys#decompose-lambda-list
(third params)
(lambda (vars argc rest)
(let* ((as (map (lambda (v)
(let ((a (gensym v)))
- (put! db v 'inline-transient #t)
+ (db-put! db v 'inline-transient #t)
a))
vars) )
(rl2 (append (map cons vars as) rl)) )
@@ -781,8 +779,9 @@
(list (gensym 'f) (second params) ; new function-id
(build-lambda-list as argc (and rest (rename rest rl2)))
(fourth params) )
- (map (cut walk <> rl2) subs) ) ) ) ) ]
- [else (make-node class (tree-copy params) (map (cut walk <> rl) subs))] ) ) )
+ (map (cut walk <> rl2) subs) ) ) ) ) )
+ (else (make-node class (tree-copy params)
+ (map (cut walk <> rl) subs))) ) ) )
(walk node rlist) ) )
;; Maybe move to scrutinizer. It's generic enough to keep it here though
@@ -822,7 +821,7 @@
(not (eq? 'unknown (cdr val))))))
((assq 'inlinable plist))
(lparams (node-parameters (cdr val)))
- ((not (get db sym 'hidden-refs)))
+ ((not (db-get db sym 'hidden-refs)))
((case (variable-mark sym '##compiler#inline)
((yes) #t)
((no) #f)
@@ -1442,30 +1441,30 @@
(define (real-name var . db)
(define (resolve n)
- (let ([n2 (##sys#hash-table-ref real-name-table n)])
+ (let ((n2 (##sys#hash-table-ref real-name-table n)))
(if n2
(or (##sys#hash-table-ref real-name-table n2)
n2)
n) ) )
- (let ([rn (resolve var)])
- (cond [(not rn) (##sys#symbol->qualified-string var)]
- [(pair? db)
- (let ([db (car db)])
- (let loop ([nesting (list (##sys#symbol->qualified-string rn))]
- [depth 0]
- [container (get db var 'contained-in)] )
+ (let ((rn (resolve var)))
+ (cond ((not rn) (##sys#symbol->qualified-string var))
+ ((pair? db)
+ (let ((db (car db)))
+ (let loop ((nesting (list (##sys#symbol->qualified-string rn)))
+ (depth 0)
+ (container (db-get db var 'contained-in)) )
(cond
- ((> depth real-name-max-depth)
- (string-intersperse (reverse (cons "..." nesting)) " in "))
- (container
- (let ([rc (resolve container)])
- (if (eq? rc container)
- (string-intersperse (reverse nesting) " in ")
- (loop (cons (symbol->string rc) nesting)
- (fx+ depth 1)
- (get db container 'contained-in) ) ) ))
- (else (string-intersperse (reverse nesting) " in "))) ) ) ]
- [else (##sys#symbol->qualified-string rn)] ) ) )
+ ((> depth real-name-max-depth)
+ (string-intersperse (reverse (cons "..." nesting)) " in "))
+ (container
+ (let ((rc (resolve container)))
+ (if (eq? rc container)
+ (string-intersperse (reverse nesting) " in ")
+ (loop (cons (symbol->string rc) nesting)
+ (fx+ depth 1)
+ (db-get db container 'contained-in) ) ) ))
+ (else (string-intersperse (reverse nesting) " in "))) ) ) )
+ (else (##sys#symbol->qualified-string rn)) ) ) )
(define (real-name2 var db) ; Used only in c-backend.scm
(and-let* ([rn (##sys#hash-table-ref real-name-table var)])
diff --git a/tests/module-tests.scm b/tests/module-tests.scm
index 6d7bd1c..45b0cd7 100644
--- a/tests/module-tests.scm
+++ b/tests/module-tests.scm
@@ -298,6 +298,48 @@
(m29-baz))
'foo)
+;; Ensure that the modules system is simply an aliasing mechanism:
+;; Module instantion does not create multiple variable copies.
+
+(module m31 *
+ (import chicken scheme)
+ (define mutation-count 0)
+ (define (internally-mutate!)
+ (set! mutation-count (add1 mutation-count)))
+ (define (get-count)
+ mutation-count))
+
+(module m32 *
+ (import chicken scheme m31)
+ (define (externally-mutate!)
+ (set! mutation-count (add1 mutation-count))))
+
+(import m31 m32)
+(test-equal
+ "initial state"
+ 0 mutation-count)
+
+(internally-mutate!)
+
+(test-equal
+ "After mutating inside defining module"
+ 1 mutation-count)
+
+(set! mutation-count 2)
+
+(test-equal
+ "After mutating outside module"
+ 2 mutation-count)
+
+(externally-mutate!)
+
+(test-equal
+ "After mutation by another module"
+ 3 mutation-count)
+
+(test-equal
+ "Internal getter returns same thing"
+ 3 (get-count))
(test-end "modules")
--
1.7.10.4