From d96fe6fc9dbad5d65abe271ceb692f732d53e2fe Mon Sep 17 00:00:00 2001 From: Jose Antonio Ortega Ruiz Date: Thu, 1 Apr 2010 02:19:32 +0200 Subject: PLT: Major module loading surgery. This is a dangerous commit. If you use PLT and don't like to live on the edge, just stick with tag 0.0.9 until 0.0.10 is out. --- scheme/plt/geiser.ss | 3 +- scheme/plt/geiser/enter.ss | 103 +++++++++++++++++++++++++++++++++++++++++++ scheme/plt/geiser/main.ss | 9 +--- scheme/plt/geiser/modules.ss | 21 +++++---- scheme/plt/geiser/user.ss | 57 ++++++++++++++++++++++++ 5 files changed, 173 insertions(+), 20 deletions(-) create mode 100644 scheme/plt/geiser/enter.ss create mode 100644 scheme/plt/geiser/user.ss diff --git a/scheme/plt/geiser.ss b/scheme/plt/geiser.ss index 9590377..29dff2a 100644 --- a/scheme/plt/geiser.ss +++ b/scheme/plt/geiser.ss @@ -17,7 +17,6 @@ "Mzscheme version 4.2 or better required (found ~a)" (version))) -(require geiser) -(geiser:init) +(require geiser/user) ;;; geiser.ss ends here diff --git a/scheme/plt/geiser/enter.ss b/scheme/plt/geiser/enter.ss new file mode 100644 index 0000000..b81ba48 --- /dev/null +++ b/scheme/plt/geiser/enter.ss @@ -0,0 +1,103 @@ +;;; enter.ss -- custom module loaders + +;; Copyright (C) 2010 Jose Antonio Ortega Ruiz + +;; This program is free software; you can redistribute it and/or +;; modify it under the terms of the Modified BSD License. You should +;; have received a copy of the license along with this program. If +;; not, see . + +;; Start date: Wed Mar 31, 2010 21:53 + +#lang scheme/base + +(require syntax/modcode + (for-syntax scheme/base)) + +(provide get-namespace enter-module module-loader module-loaded?) + +(define-struct mod (name timestamp depends)) + +(define loaded (make-hash)) + +(define (module-loaded? path) + (with-handlers ((exn? (lambda (_) #f))) + (let ((rp (module-path-index-resolve (module-path-index-join path #f)))) + (hash-has-key? loaded (resolved-module-path-name rp))))) + +(define (enter-module mod) + (dynamic-require mod #f) + (check-latest mod)) + +(define (module-loader orig) + (enter-load/use-compiled orig #f)) + +(define (notify re? path) + (when re? + (fprintf (current-error-port) " [re-loading ~a]\n" path))) + +(define inhibit-eval (make-parameter #f)) + +(define (get-namespace mod) + (parameterize ([inhibit-eval #t]) + (module->namespace mod))) + +(define ((enter-load/use-compiled orig re?) path name) + (when (inhibit-eval) + (raise (make-exn:fail "namespace not found" + (current-continuation-marks)))) + (if name + ;; Module load: + (let ([code (get-module-code path "compiled" compile + (lambda (ext loader?) + (load-extension ext) + #f) + #:notify (lambda (chosen) + (notify re? chosen)))] + [path (normal-case-path + (simplify-path + (path->complete-path path + (or (current-load-relative-directory) + (current-directory)))))]) + ;; Record module timestamp and dependencies: + (let ([mod (make-mod name + (get-timestamp path) + (if code + (apply append + (map cdr (module-compiled-imports code))) + null))]) + (hash-set! loaded path mod)) + ;; Evaluate the module: + (eval code)) + ;; Not a module: + (begin + (notify re? path) + (orig path name)))) + +(define (get-timestamp path) + (file-or-directory-modify-seconds path #f (lambda () -inf.0))) + +(define (check-latest mod) + (let ([mpi (module-path-index-join mod #f)] + [done (make-hash)]) + (let loop ([mpi mpi]) + (let* ([rpath (module-path-index-resolve mpi)] + [path (resolved-module-path-name rpath)]) + (when (path? path) + (let ([path (normal-case-path path)]) + (unless (hash-ref done path #f) + (hash-set! done path #t) + (let ([mod (hash-ref loaded path #f)]) + (when mod + (for-each loop (mod-depends mod)) + (let ([ts (get-timestamp path)]) + (when (ts . > . (mod-timestamp mod)) + (let ([orig (current-load/use-compiled)]) + (parameterize ([current-load/use-compiled + (enter-load/use-compiled orig #f)] + [current-module-declare-name rpath]) + ((enter-load/use-compiled orig #t) + path + (mod-name mod))))))))))))))) + +;;; enter.ss ends here diff --git a/scheme/plt/geiser/main.ss b/scheme/plt/geiser/main.ss index d342b15..f157ac6 100644 --- a/scheme/plt/geiser/main.ss +++ b/scheme/plt/geiser/main.ss @@ -13,8 +13,7 @@ #lang scheme/base -(provide geiser:init - geiser:eval +(provide geiser:eval geiser:compile geiser:load-file geiser:compile-file @@ -47,8 +46,4 @@ (define geiser:module-exports module-exports) (define geiser:macroexpand macroexpand) -(define (geiser:init) - (compile-enforce-module-constants #f) - (current-prompt-read (compose (make-repl-reader (current-prompt-read)) - current-namespace))) - +;;; main.ss ends here diff --git a/scheme/plt/geiser/modules.ss b/scheme/plt/geiser/modules.ss index 9842174..829cf77 100644 --- a/scheme/plt/geiser/modules.ss +++ b/scheme/plt/geiser/modules.ss @@ -20,7 +20,7 @@ module-list module-exports) -(require srfi/13 scheme/enter syntax/modresolve syntax/modcode) +(require srfi/13 syntax/modresolve syntax/modcode geiser/enter) (define (ensure-module-spec spec) (cond ((symbol? spec) spec) @@ -28,22 +28,22 @@ (else `(file ,spec)))) (define (module-spec->namespace spec (lang #f)) - (let ((spec (ensure-module-spec spec))) - (if spec - (with-handlers ((exn? - (lambda (_) - (with-handlers - ((exn? (const (current-namespace)))) + (let ((spec (ensure-module-spec spec)) + (try-lang (lambda (_) + (with-handlers ((exn? (const (current-namespace)))) + (and lang + (begin (load-module lang #f (current-namespace)) - (module->namespace lang))))) - (module->namespace spec)) + (module->namespace lang))))))) + (or (and spec + (with-handlers ((exn? try-lang)) (get-namespace spec))) (current-namespace)))) (define nowhere (open-output-nowhere)) (define (load-module spec (port #f) (ns #f)) (parameterize ((current-error-port (or port nowhere))) - (eval #`(enter! #,(ensure-module-spec spec))) + (enter-module (ensure-module-spec spec)) (when (namespace? ns) (current-namespace ns)))) @@ -79,7 +79,6 @@ ((symbol? path) (symbol->string path)) (else ""))) - (define (skippable-dir? path) (call-with-values (lambda () (split-path path)) (lambda (_ basename __) diff --git a/scheme/plt/geiser/user.ss b/scheme/plt/geiser/user.ss new file mode 100644 index 0000000..48b7dd5 --- /dev/null +++ b/scheme/plt/geiser/user.ss @@ -0,0 +1,57 @@ +;;; user.ss -- global bindings visible to geiser users + +;; Copyright (C) 2010 Jose Antonio Ortega Ruiz + +;; This program is free software; you can redistribute it and/or +;; modify it under the terms of the Modified BSD License. You should +;; have received a copy of the license along with this program. If +;; not, see . + +;; Start date: Wed Mar 31, 2010 22:24 + +#lang scheme/base + +(provide enter!) + +(require geiser/enter geiser/eval (for-syntax scheme/base)) + +(define-syntax (enter! stx) + (syntax-case stx () + [(enter! mod) + (if (or (not (syntax-e #'mod)) + (module-path? (syntax->datum #'mod))) + #'(do-enter! 'mod) + (raise-syntax-error + #f + "not a valid module path, and not #f" + stx + #'mod))] + [_ (raise-syntax-error + #f + "bad syntax; should be `(enter! )'" + stx)])) + +(define orig-namespace (current-namespace)) + +(define (do-enter! mod) + (if mod + (begin + (enter-module mod) + (let ([ns (module->namespace mod)]) + (current-namespace ns) + (namespace-require 'geiser/user))) + (current-namespace orig-namespace))) + + +(define orig-loader (current-load/use-compiled)) + +(define (init) + (compile-enforce-module-constants #f) + (current-load/use-compiled (module-loader orig-loader)) + (current-prompt-read (compose (make-repl-reader (current-prompt-read)) + current-namespace))) + +(init) + +;;; user.ss ends here + -- cgit v1.2.3