;; eval.ss -- evaluation ;; Copyright (C) 2009 Jose Antonio Ortega Ruiz ;; Author: Jose Antonio Ortega Ruiz ;; Start date: Sun Apr 26, 2009 00:44 ;; This file is free software; you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by ;; the Free Software Foundation; either version 3 of the License, or ;; (at your option) any later version. ;; This file is distributed in the hope that it will be useful, ;; but WITHOUT ANY WARRANTY; without even the implied warranty of ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ;; GNU General Public License for more details. ;; You should have received a copy of the GNU General Public License ;; along with this program. If not, see . ;;; Comentary: ;; Evaluation functions ;;; Code: #lang scheme (provide eval-in compile-in load-file compile-file make-repl-reader) (require scheme/enter srfi/13) (define last-result (void)) (define nowhere (open-output-nowhere)) (define (ensure-spec spec) (cond ((symbol? spec) spec) ((not (string? spec)) #f) ((not (file-exists? spec)) #f) ((absolute-path? spec) `(file ,spec)) (else spec))) (define (load-module spec . port) (parameterize ((current-error-port (if (null? port) nowhere (car port)))) (eval #`(enter! #,spec)))) (define (ensure-namespace mod-spec) (letrec ((spec (ensure-spec mod-spec)) (handler (lambda (e) (load-module spec) (enter! #f) (module->namespace spec)))) (if spec (with-handlers ((exn:fail:contract? handler)) (module->namespace spec)) (current-namespace)))) (define (namespace->module-path-name ns) (let ((rmp (variable-reference->resolved-module-path (eval '(#%variable-reference) ns)))) (and (resolved-module-path? rmp) (resolved-module-path-name rmp)))) (define (namespace->module-name ns) (let ((path (namespace->module-path-name ns))) (if (not path) "" (let* ((path (path->string path)) (cpaths (map path->string (current-library-collection-paths))) (prefix-len (lambda (p) (let ((pl (string-length p))) (if (= pl (string-prefix-length p path)) pl 0)))) (lens (map prefix-len cpaths)) (real-path (substring path (apply max lens)))) (if (absolute-path? real-path) (call-with-values (lambda () (split-path path)) (lambda (_ basename __) basename)) (regexp-replace "\\.[^./]*$" real-path "")))))) (define last-namespace (make-parameter (current-namespace))) (define (exn-key e) (vector-ref (struct->vector e) 0)) (define (set-last-error e) (set! last-result `((error (key . ,(exn-key e)) (subr) (msg . ,(exn-message e)))))) (define (set-last-result v) (set! last-result `((result ,v)))) (define (eval-in form spec) (set-last-result (void)) (with-handlers ((exn? set-last-error)) (set-last-result (eval form (ensure-namespace spec)))) last-result) (define compile-in eval-in) (define (load-file file) (with-handlers ((exn? set-last-error)) (let ((current-path (namespace->module-path-name (last-namespace)))) (set-last-result (string-append (with-output-to-string (lambda () (load-module (ensure-spec file) (current-output-port)))) "done.")) (load-module (and (path? current-path) (ensure-spec (path->string current-path)))))) last-result) (define compile-file load-file) (define (make-repl-reader builtin-reader) (lambda (ns) (last-namespace ns) (printf "mzscheme@(~a)" (namespace->module-name ns)) (builtin-reader))) ;;; eval.ss ends here