From: Matthew Flatt <mflatt@cs.utah.edu> To: plt-scheme@web-ext.cs.brown.edu Subject: [plt-scheme] 299.102 Date: Mon, 11 Apr 2005 13:02:01 -0600 The exp-tagged code in CVS for MzScheme and MrEd is now version 299.102. This version is mainly about reader extension: * MzScheme’s reader now supports #reader <datum> in the input stream, at least when enabled via the parameter `read-accepts-reader’. The <datum> identifies a module that provides `read’ and `read-syntax’ functions to be applied to the port where `#reader’ is encountered. For example, if the module at the end of this message is put in MzLib, then you would write a MzScheme module as #reader(lib "mz.ss") (define x 10) (provide x) because the reader reads until EOF, and puts the read values into a `module’ form using the port’s name to name the module. (This is just an example. I didn’t add "mz.ss" to MzLib.) Of course, `#reader’ can be used in the middle of an S-expression, as well as at the beginning of an expression. The `read-accepts-reader’ parameter is #f by default, so that usig `read’ for data doesn’t implicitly allow code to be loaded. The REPL and the default load handler set the parameter to #t while reading code. A new `current-reader-guard’ parameter holds a procedure to filter module paths, so the set of paths allowed after `#reader’ can be limited. The default guard is the identity function. * MzScheme’s reader can now be parameterized by a readtable. It’s essentially the same as a Common LISP readtable, although the interface is slightly different because (1) readtables are immutable, (2) they deal with both `read’ and `read-syntax’, and (3) the default readtable entries are not reified, but they can be applied indirectly through `read[-syntax]/recursive’. See the docs for details. If you write code that depends on a readtable parameterization, use `#reader’ to install the readtable. Don’t expect people to load file A (which installs a readtable) before loading file B (which depends on the readtable), because PLT tools would not work on B. On other words, `#reader’ serves as a declarative specification for reader extension that all tools can use. A `#reader’-based syntax doesn’t have to be a variant of S-expressions, and it doesn’t have to be built in terms of MzScheme’s `read’. But `#reader’ and readtables work well together. I know that many are interested in parameterizing the printer as well as the reader. I expect to work on printing, too, but I haven’t yet gotten that far. Other changes: * When `read-square-brackets-as-parens’ is set to #f, a square bracket is treated as invalid input instead of the start of a symbol. Similarly, when `read-curly-braces-as-parens’ is #f, a square bracket is illegal. The old behavior is available through a readtable. * Added `module-provide-protected?’. (See earlier discussion, where I suggested `identifier-exported?’. It turns out that `module-provide-protected?’ is more general and easier to define.) * A struct type inspector can be #f, which makes the struct type transparent to all inspectors. Matthew ---------------------------------------- (module mz mzscheme (define (mz-read-one read-syntax src port offsets) `(module ,(let ([n (object-name port)]) (cond [(path? n) (let-values ([(base name dir?) (split-path n)]) (string->symbol (path->string (path-replace-suffix name #""))))] [(symbol? n) n] [else ’unknown])) mzscheme ,@(let loop () (let ([v (read-syntax src port offsets)]) (if (eof-object? v) null (cons v (loop))))))) (define (mz-read port) (mz-read-one (lambda (src port offsets) (read port)) #f port #f)) (define (mz-read-syntax src port offsets) (mz-read-one read-syntax src port offsets)) (provide (rename mz-read read) (rename mz-read-syntax read-syntax)))