123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129 |
- (define-module (lang elisp interface)
- #:use-module (lang elisp internals evaluation)
- #:use-module (lang elisp internals fset)
- #:use-module ((lang elisp internals load) #:select ((load . elisp:load)))
- #:use-module ((lang elisp transform) #:select (transformer))
- #:export (eval-elisp
- translate-elisp
- elisp-function
- elisp-variable
- load-elisp-file
- load-elisp-library
- use-elisp-file
- use-elisp-library
- export-to-elisp
- load-emacs))
- ;;; This file holds my ideas for the mechanisms that would be useful
- ;;; to exchange definitions between Scheme and Elisp.
- (define (eval-elisp x)
- "Evaluate the Elisp expression @var{x}."
- (eval x the-elisp-module))
- (define (translate-elisp x)
- "Translate the Elisp expression @var{x} to equivalent Scheme code."
- (transformer x))
- (define (elisp-function sym)
- "Return the procedure or macro that implements @var{sym} in Elisp.
- If @var{sym} has no Elisp function definition, return @code{#f}."
- (fref sym))
- (define (elisp-variable sym)
- "Return the variable that implements @var{sym} in Elisp.
- If @var{sym} has no Elisp variable definition, return @code{#f}."
- (module-variable the-elisp-module sym))
- (define (load-elisp-file file-name)
- "Load @var{file-name} into the Elisp environment.
- @var{file-name} is assumed to name a file containing Elisp code."
- ;; This is the same as Elisp's `load-file', so use that if it is
- ;; available, otherwise duplicate the definition of `load-file' from
- ;; files.el.
- (let ((load-file (elisp-function 'load-file)))
- (if load-file
- (load-file file-name)
- (elisp:load file-name #f #f #t))))
- (define (load-elisp-library library)
- "Load library @var{library} into the Elisp environment.
- @var{library} should name an Elisp code library that can be found in
- one of the directories of @code{load-path}."
- ;; This is the same as Elisp's `load-file', so use that if it is
- ;; available, otherwise duplicate the definition of `load-file' from
- ;; files.el.
- (let ((load-library (elisp-function 'load-library)))
- (if load-library
- (load-library library)
- (elisp:load library))))
- (define export-module-name
- (let ((counter 0))
- (lambda ()
- (set! counter (+ counter 1))
- (list 'lang 'elisp
- (string->symbol (string-append "imports:"
- (number->string counter)))))))
- (define-macro (use-elisp-file file-name . imports)
- "Load Elisp code file @var{file-name} and import its definitions
- into the current Scheme module. If any @var{imports} are specified,
- they are interpreted as selection and renaming specifiers as per
- @code{use-modules}."
- (let ((export-module-name (export-module-name)))
- `(begin
- (fluid-set! ,elisp-export-module (resolve-module ',export-module-name))
- (beautify-user-module! (resolve-module ',export-module-name))
- (load-elisp-file ,file-name)
- (use-modules (,export-module-name ,@imports))
- (fluid-set! ,elisp-export-module #f))))
- (define-macro (use-elisp-library library . imports)
- "Load Elisp library @var{library} and import its definitions into
- the current Scheme module. If any @var{imports} are specified, they
- are interpreted as selection and renaming specifiers as per
- @code{use-modules}."
- (let ((export-module-name (export-module-name)))
- `(begin
- (fluid-set! ,elisp-export-module (resolve-module ',export-module-name))
- (beautify-user-module! (resolve-module ',export-module-name))
- (load-elisp-library ,library)
- (use-modules (,export-module-name ,@imports))
- (fluid-set! ,elisp-export-module #f))))
- (define (export-to-elisp . defs)
- "Export procedures and variables specified by @var{defs} to Elisp.
- Each @var{def} is either an object, in which case that object must be
- a named procedure or macro and is exported to Elisp under its Scheme
- name; or a symbol, in which case the variable named by that symbol is
- exported under its Scheme name; or a pair @var{(obj . name)}, in which
- case @var{obj} must be a procedure, macro or symbol as already
- described and @var{name} specifies the name under which that object is
- exported to Elisp."
- (for-each (lambda (def)
- (let ((obj (if (pair? def) (car def) def))
- (name (if (pair? def) (cdr def) #f)))
- (cond ((procedure? obj)
- (or name
- (set! name (procedure-name obj)))
- (if name
- (fset name obj)
- (error "No procedure name specified or deducible:" obj)))
- ((macro? obj)
- (or name
- (set! name (macro-name obj)))
- (if name
- (fset name obj)
- (error "No macro name specified or deducible:" obj)))
- ((symbol? obj)
- (or name
- (set! name obj))
- (module-add! the-elisp-module name
- (module-ref (current-module) obj)))
- (else
- (error "Can't export this kind of object to Elisp:" obj)))))
- defs))
- (define load-emacs (elisp-function 'load-emacs))
|