199 lines
7.2 KiB
Racket
199 lines
7.2 KiB
Racket
#lang racket/gui
|
|
|
|
(require drracket/tool
|
|
string-constants
|
|
unstable/dict
|
|
(only-in test-engine/scheme-gui make-formatter)
|
|
(only-in test-engine/scheme-tests
|
|
scheme-test-data test-format test-execute)
|
|
(lib "test-display.scm" "test-engine"))
|
|
|
|
(provide language-level^
|
|
language-level@)
|
|
|
|
(define (read-all-syntax [port (current-input-port)]
|
|
[source (object-name port)]
|
|
[reader read-syntax])
|
|
(let loop ()
|
|
(let* ([next (reader source port)])
|
|
(if (eof-object? next)
|
|
null
|
|
(cons next (loop))))))
|
|
|
|
(define (read-module-body [port (current-input-port)]
|
|
[source (object-name port)]
|
|
[reader read-syntax]
|
|
[path 'racket]
|
|
[name 'program])
|
|
(let*-values ([(line-1 col-1 pos-1) (port-next-location port)]
|
|
[(terms) (read-all-syntax port source reader)]
|
|
[(line-2 col-2 pos-2) (port-next-location port)]
|
|
[(loc) (list source line-1 col-1 pos-1
|
|
(and pos-1 pos-2 (- pos-2 pos-1)))])
|
|
(map (lambda (datum) (datum->syntax #'here datum loc))
|
|
(list `(module ,name ,path
|
|
(,(datum->syntax #f '#%module-begin) ,@terms))
|
|
`(require ',name)
|
|
`(current-namespace (module->namespace '',name))))))
|
|
|
|
(define-signature language-level^
|
|
(simple-language-level%
|
|
make-language-level
|
|
language-level-render-mixin
|
|
language-level-capability-mixin
|
|
language-level-eval-as-module-mixin
|
|
language-level-no-executable-mixin
|
|
language-level-macro-stepper-mixin
|
|
language-level-check-expect-mixin
|
|
language-level-metadata-mixin))
|
|
|
|
(define-unit language-level@
|
|
(import drracket:tool^)
|
|
(export language-level^)
|
|
|
|
(define (make-language-level
|
|
name path
|
|
#:number [number (equal-hash-code name)]
|
|
#:hierarchy [hierarchy experimental-language-hierarchy]
|
|
#:summary [summary name]
|
|
#:url [url #f]
|
|
#:reader [reader read-syntax]
|
|
. mixins)
|
|
(let* ([mx-default (drracket:language:get-default-mixin)]
|
|
[mx-custom (apply compose (reverse mixins))])
|
|
(new (mx-custom (mx-default simple-language-level%))
|
|
[module path]
|
|
[language-position (append (map car hierarchy) (list name))]
|
|
[language-numbers (append (map cdr hierarchy) (list number))]
|
|
[one-line-summary summary]
|
|
[language-url url]
|
|
[reader (make-namespace-syntax-reader reader)])))
|
|
|
|
(define simple-language-level%
|
|
(drracket:language:module-based-language->language-mixin
|
|
(drracket:language:simple-module-based-language->module-based-language-mixin
|
|
drracket:language:simple-module-based-language%)))
|
|
|
|
(define (language-level-render-mixin to-sexp show-void?)
|
|
(mixin (drracket:language:language<%>) ()
|
|
(super-new)
|
|
|
|
(define/override (render-value/format value settings port width)
|
|
(unless (and (void? value) (not show-void?))
|
|
(super render-value/format (to-sexp value) settings port width)))))
|
|
|
|
(define (language-level-capability-mixin dict)
|
|
(mixin (drracket:language:language<%>) ()
|
|
(super-new)
|
|
|
|
(define/augment (capability-value key)
|
|
(dict-ref/failure
|
|
dict key
|
|
(lambda ()
|
|
(inner (drracket:language:get-capability-default key)
|
|
capability-value key))))))
|
|
|
|
(define language-level-no-executable-mixin
|
|
(mixin (drracket:language:language<%>) ()
|
|
(super-new)
|
|
(inherit get-language-name)
|
|
|
|
(define/override (create-executable settings parent filename)
|
|
(message-box
|
|
"Create Executable: Error"
|
|
(format "Sorry, ~a does not support creating executables."
|
|
(get-language-name))
|
|
#f '(ok stop)))))
|
|
|
|
(define language-level-eval-as-module-mixin
|
|
(mixin (drracket:language:language<%>
|
|
drracket:language:module-based-language<%>) ()
|
|
(super-new)
|
|
|
|
(inherit get-reader get-module)
|
|
|
|
(define/override (front-end/complete-program port settings)
|
|
(let* ([terms #f])
|
|
(lambda ()
|
|
;; On the first run through, initialize the list.
|
|
(unless terms
|
|
(set! terms (read-module-body port
|
|
(object-name port)
|
|
(get-reader)
|
|
(get-module))))
|
|
;; Produce each list element in order.
|
|
(if (pair? terms)
|
|
;; Produce and remove a list element.
|
|
(begin0 (car terms) (set! terms (cdr terms)))
|
|
;; After null, eof forever.
|
|
eof))))))
|
|
|
|
(define language-level-macro-stepper-mixin
|
|
(language-level-capability-mixin
|
|
(make-immutable-hasheq
|
|
(list (cons 'macro-stepper:enabled #t)))))
|
|
|
|
(define language-level-check-expect-mixin
|
|
(mixin (drracket:language:language<%>) ()
|
|
(super-new)
|
|
(inherit render-value/format)
|
|
|
|
(define/augment (capability-value key)
|
|
(case key
|
|
[(tests:test-menu tests:dock-menu) #t]
|
|
[else (inner (drracket:language:get-capability-default key)
|
|
capability-value
|
|
key)]))
|
|
|
|
(define/override (on-execute settings run-in-user-thread)
|
|
(let* ([drracket-namespace (current-namespace)]
|
|
[test-engine-path
|
|
((current-module-name-resolver)
|
|
'test-engine/scheme-tests #f #f)])
|
|
(run-in-user-thread
|
|
(lambda ()
|
|
(namespace-attach-module drracket-namespace test-engine-path)
|
|
(namespace-require test-engine-path)
|
|
(scheme-test-data
|
|
(list (drracket:rep:current-rep)
|
|
drracket-eventspace
|
|
test-display%))
|
|
(test-execute (get-preference 'tests:enable? (lambda () #t)))
|
|
(test-format
|
|
(make-formatter
|
|
(lambda (v o) (render-value/format v settings o 40))))))
|
|
(super on-execute settings run-in-user-thread)))))
|
|
|
|
(define (language-level-metadata-mixin reader-module
|
|
meta-lines
|
|
meta->settings
|
|
settings->meta)
|
|
(mixin (drracket:language:language<%>) ()
|
|
(inherit default-settings)
|
|
(super-new)
|
|
|
|
(define/override (get-reader-module) reader-module)
|
|
|
|
(define/override (get-metadata modname settings)
|
|
(settings->meta modname settings))
|
|
|
|
(define/override (metadata->settings metadata)
|
|
(meta->settings metadata (default-settings)))
|
|
|
|
(define/override (get-metadata-lines) meta-lines)))
|
|
|
|
(define (generic-syntax-reader . args)
|
|
(parameterize ([read-accept-reader #t])
|
|
(apply read-syntax args)))
|
|
|
|
(define (make-namespace-syntax-reader reader)
|
|
(lambda args
|
|
(let ([stx (apply reader args)])
|
|
(if (syntax? stx) (namespace-syntax-introduce stx) stx))))
|
|
|
|
(define drracket-eventspace (current-eventspace))
|
|
|
|
(define experimental-language-hierarchy
|
|
(list (cons (string-constant experimental-languages)
|
|
1000))))
|