change 'read-language' protocol so that the result from 'get-info' accepts a key plus default value (instead of just a key)

svn: r16459
This commit is contained in:
Matthew Flatt 2009-10-29 23:05:56 +00:00
parent c3857c32e3
commit 973d51c20f
10 changed files with 42 additions and 33 deletions

View File

@ -24,8 +24,8 @@
wrap-reader wrap-reader
wrap-reader wrap-reader
(lambda (proc) (lambda (proc)
(lambda (key) (lambda (key defval)
(case key (case key
[(color-lexer) [(color-lexer)
(dynamic-require 'syntax-color/scribble-lexer 'scribble-lexer)] (dynamic-require 'syntax-color/scribble-lexer 'scribble-lexer)]
[else (and proc (proc key))])))))) [else (if proc (proc key defval) defval)]))))))

View File

@ -102,7 +102,7 @@
(contract (or/c #f (listof (list/c string? (contract (or/c #f (listof (list/c string?
(is-a?/c bitmap%) (is-a?/c bitmap%)
(-> (is-a?/c drscheme:unit:frame<%>) any)))) (-> (is-a?/c drscheme:unit:frame<%>) any))))
(info-result 'drscheme:toolbar-buttons) (info-result 'drscheme:toolbar-buttons #f)
(get-lang-name pos) (get-lang-name pos)
'drscheme/private/module-language-tools))))))) 'drscheme/private/module-language-tools)))))))

View File

@ -6,13 +6,13 @@ scribble/base/lang
#:read-syntax scribble:read-syntax-inside #:read-syntax scribble:read-syntax-inside
#:whole-body-readers? #t #:whole-body-readers? #t
#:wrapper1 (lambda (t) (list* 'doc 'values '() (t))) #:wrapper1 (lambda (t) (list* 'doc 'values '() (t)))
#:info (lambda (key default) #:info (lambda (key defval default)
(case key (case key
[(color-lexer) [(color-lexer)
(dynamic-require 'syntax-color/scribble-lexer 'scribble-inside-lexer)] (dynamic-require 'syntax-color/scribble-lexer 'scribble-inside-lexer)]
[(drscheme:toolbar-buttons) [(drscheme:toolbar-buttons)
(dynamic-require 'scribble/drscheme-buttons 'drscheme-buttons)] (dynamic-require 'scribble/drscheme-buttons 'drscheme-buttons)]
[else (default key)])) [else (default key defval)]))
(require (prefix-in scribble: "../../reader.ss")) (require (prefix-in scribble: "../../reader.ss"))

View File

@ -6,10 +6,10 @@ scribble/manual/lang
#:read-syntax scribble:read-syntax-inside #:read-syntax scribble:read-syntax-inside
#:whole-body-readers? #t #:whole-body-readers? #t
#:wrapper1 (lambda (t) (cons 'doc (t))) #:wrapper1 (lambda (t) (cons 'doc (t)))
#:info (lambda (key default) #:info (lambda (key defval default)
(case key (case key
[(color-lexer) [(color-lexer)
(dynamic-require 'syntax-color/scribble-lexer 'scribble-inside-lexer)] (dynamic-require 'syntax-color/scribble-lexer 'scribble-inside-lexer)]
[else (default key)])) [else (default defval key)]))
(require (prefix-in scribble: "../../reader.ss")) (require (prefix-in scribble: "../../reader.ss"))

View File

@ -6,10 +6,10 @@ scribble/sigplan/lang
#:read-syntax scribble:read-syntax-inside #:read-syntax scribble:read-syntax-inside
#:whole-body-readers? #t #:whole-body-readers? #t
#:wrapper1 (lambda (t) (cons 'doc (t))) #:wrapper1 (lambda (t) (cons 'doc (t)))
#:info (lambda (key default) #:info (lambda (key defval default)
(case key (case key
[(color-lexer) [(color-lexer)
(dynamic-require 'syntax-color/scribble-lexer 'scribble-inside-lexer)] (dynamic-require 'syntax-color/scribble-lexer 'scribble-inside-lexer)]
[else (default key)])) [else (default defval key)]))
(require (prefix-in scribble: "../../reader.ss")) (require (prefix-in scribble: "../../reader.ss"))

View File

@ -107,7 +107,7 @@ See @secref["readtables"] for an extended example that uses
@defproc[(read-language [in input-port? (current-input-port)] @defproc[(read-language [in input-port? (current-input-port)]
[fail-thunk (-> any) (lambda () (error ...))]) [fail-thunk (-> any) (lambda () (error ...))])
(any/c . -> . any)]{ (any/c any/c . -> . any)]{
Reads @scheme[in] in the same way as @scheme[read], but stopping as Reads @scheme[in] in the same way as @scheme[read], but stopping as
soon as a @tech{reader language} (or its absence) is determined. soon as a @tech{reader language} (or its absence) is determined.
@ -119,16 +119,16 @@ a @schemeidfont{read} or @schemeidfont{read-syntax} form as
@scheme[read] and @scheme[read-syntax] do, @scheme[read-language] @scheme[read] and @scheme[read-syntax] do, @scheme[read-language]
dispatches to a @schemeidfont{get-info} function (if any) exported by dispatches to a @schemeidfont{get-info} function (if any) exported by
the same module. The result of the @schemeidfont{get-info} function is the same module. The result of the @schemeidfont{get-info} function is
the result of @scheme[read-language] if it is a function of one the result of @scheme[read-language] if it is a function of two
argument; if @schemeidfont{get-info} produces any other kind of arguments; if @schemeidfont{get-info} produces any other kind of
result, the @exnraise[exn:fail:contract]. result, the @exnraise[exn:fail:contract].
The function produced by @schemeidfont{get-info} reflects information The function produced by @schemeidfont{get-info} reflects information
about the expected syntax of the input stream. The argument to the about the expected syntax of the input stream. The first argument to the
function serves as a key on such information; acceptable keys and the function serves as a key on such information; acceptable keys and the
interpretation of results is up to external tools, such as DrScheme. interpretation of results is up to external tools, such as DrScheme.
If no information is available for a given key, the result should be If no information is available for a given key, the result should be
@scheme[#f]. the second argument.
The @schemeidfont{get-info} function itself is applied to five The @schemeidfont{get-info} function itself is applied to five
arguments: the input port being read, the module path from which the arguments: the input port being read, the module path from which the
@ -138,7 +138,8 @@ integer or @scheme[#f]), and position (positive exact integer or
@scheme[#f]) of the start of the @litchar{#lang} or @litchar{#!} @scheme[#f]) of the start of the @litchar{#lang} or @litchar{#!}
form. The @schemeidfont{get-info} function may further read from the form. The @schemeidfont{get-info} function may further read from the
given input port to determine its result, but it should read no given input port to determine its result, but it should read no
further than necessary. further than necessary. The @schemeidfont{get-info} function should
not read from the port after returning a function.
If @scheme[in] starts with a @tech{reader language} specification but If @scheme[in] starts with a @tech{reader language} specification but
the relevant module does not export @schemeidfont{get-info} (but the relevant module does not export @schemeidfont{get-info} (but
@ -146,8 +147,13 @@ perhaps does export @schemeidfont{read} and
@schemeidfont{read-syntax}), then the result of @scheme[read-language] @schemeidfont{read-syntax}), then the result of @scheme[read-language]
is @scheme[#f]. is @scheme[#f].
If @scheme[in] does not specify a @tech{reader language}, then If @scheme[in] has a @litchar{#lang} or @litchar{#!} specification,
@scheme[fail-thunk] is called. The default @scheme[fail-thunk] raises but parsing and resolving the specification raises an exception, the
exception is propagated by @scheme[read-language].
If @scheme[in] does not specify a @tech{reader language} with
@litchar{#lang} or @litchar{#!}, then @scheme[fail-thunk] is
called. The default @scheme[fail-thunk] raises
@scheme[exn:fail:contract].} @scheme[exn:fail:contract].}

View File

@ -36,7 +36,7 @@
start-pos start-pos
end-pos end-pos
0 0
(or (let ([v (get-info 'color-lexer)]) (or (let ([v (get-info 'color-lexer #f)])
(and v (and v
(if (procedure-arity-includes? v 3) (if (procedure-arity-includes? v 3)
(cons v #f) (cons v #f)

View File

@ -50,6 +50,8 @@
(err "must specify either both #:read and #:read-syntax, or none")) (err "must specify either both #:read and #:read-syntax, or none"))
(when (and ~whole-body-readers? (not (and ~read ~read-syntax))) (when (and ~whole-body-readers? (not (and ~read ~read-syntax)))
(err "got a #:whole-body-readers? without #:read and #:read-syntax"))]) (err "got a #:whole-body-readers? without #:read and #:read-syntax"))])
;; FIXME: a lot of the generated code is constant and should be lifted
;; out of the template:
(quasisyntax/loc stx (quasisyntax/loc stx
(#%module-begin (#%module-begin
#,@body #,@body
@ -112,24 +114,24 @@
(define (get-info-getter props) (define (get-info-getter props)
(define lang (car props)) (define lang (car props))
(define data (cadr props)) (define data (cadr props))
(define (default-info what) (define (default-info what defval)
(case what (case what
[(module-language) (car props)] [(module-language) (car props)]
;; ... more? ;; ... more?
[else #f])) [else defval]))
(define info (define info
(let* ([#,<lang-id> lang] ;\ visible in (let* ([#,<lang-id> lang] ;\ visible in
[#,<data-id> data] ;/ user-code [#,<data-id> data] ;/ user-code
[info #,~info]) [info #,~info])
(if (or (not info) (and (procedure? info) (ar? info 2))) (if (or (not info) (and (procedure? info) (ar? info 3)))
info info
(raise-type-error 'syntax/module-reader (raise-type-error 'syntax/module-reader
"info procedure of 1 or 0 arguments" info)))) "info procedure of 3 arguments" info))))
(define (language-info what) (define (language-info what defval)
(if info (if info
(let ([r (info what default-info)]) (let ([r (info what defval default-info)])
(if (eq? r default-info) (default-info what) r)) (if (eq? r default-info) (default-info what defval) r))
(default-info what))) (default-info what defval)))
language-info)))) language-info))))
(syntax-case stx () (syntax-case stx ()
[(_ lang body ...) [(_ lang body ...)
@ -206,7 +208,7 @@
(define (-get-info inp mod line col pos) (define (-get-info inp mod line col pos)
(let ([r (get inp 'get-info (object-name inp) line col pos (let ([r (get inp 'get-info (object-name inp) line col pos
(lambda (spec) (lambda () (lambda (inp mod line col pos) (lambda (spec) (lambda () (lambda (inp mod line col pos)
(lambda (tag) #f)))))]) (lambda (tag defval) defval)))))])
(convert-get-info (r inp mod line col pos)))) (convert-get-info (r inp mod line col pos))))
(define (read-fn in read-sym args src mod line col pos convert) (define (read-fn in read-sym args src mod line col pos convert)

View File

@ -76,10 +76,11 @@ using:
Similarly, the @scheme[#:info] keyword supplies a procedure to be used Similarly, the @scheme[#:info] keyword supplies a procedure to be used
by a @scheme[get-info] export (see @scheme[read-language]). The by a @scheme[get-info] export (see @scheme[read-language]). The
procedure produced by @scheme[info-expr] should consume two arguments: procedure produced by @scheme[info-expr] should consume three
a key symbol and a default info-getting procedure (to be called with arguments: a key value, a default result, and a default info-getting
the key for default handling). If @scheme[#:info] is not supplied, the procedure (to be called with the key and default result for default
default info-getting procedure is used. handling). If @scheme[#:info] is not supplied, the default
info-getting procedure is used.
You can also use the (optional) module @scheme[body] forms to provide more You can also use the (optional) module @scheme[body] forms to provide more
definitions that might be needed to implement your reader functions. definitions that might be needed to implement your reader functions.

View File

@ -5657,8 +5657,8 @@ static Scheme_Object *readtable_call(int w_char, int ch, Scheme_Object *proc, Re
if (get_info) { if (get_info) {
a[0] = v; a[0] = v;
if (!scheme_check_proc_arity(NULL, 1, 0, 1, a)) { if (!scheme_check_proc_arity(NULL, 2, 0, 1, a)) {
scheme_wrong_type("read-language", "procedure (arity 1)", -1, -1, a); scheme_wrong_type("read-language", "procedure (arity 2)", -1, -1, a);
} }
} }