interface.scm 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. (define-module (lang elisp interface)
  2. #:use-module (lang elisp internals evaluation)
  3. #:use-module (lang elisp internals fset)
  4. #:use-module ((lang elisp internals load) #:select ((load . elisp:load)))
  5. #:use-module ((lang elisp transform) #:select (transformer))
  6. #:export (eval-elisp
  7. translate-elisp
  8. elisp-function
  9. elisp-variable
  10. load-elisp-file
  11. load-elisp-library
  12. use-elisp-file
  13. use-elisp-library
  14. export-to-elisp
  15. load-emacs))
  16. ;;; This file holds my ideas for the mechanisms that would be useful
  17. ;;; to exchange definitions between Scheme and Elisp.
  18. (define (eval-elisp x)
  19. "Evaluate the Elisp expression @var{x}."
  20. (eval x the-elisp-module))
  21. (define (translate-elisp x)
  22. "Translate the Elisp expression @var{x} to equivalent Scheme code."
  23. (transformer x))
  24. (define (elisp-function sym)
  25. "Return the procedure or macro that implements @var{sym} in Elisp.
  26. If @var{sym} has no Elisp function definition, return @code{#f}."
  27. (fref sym))
  28. (define (elisp-variable sym)
  29. "Return the variable that implements @var{sym} in Elisp.
  30. If @var{sym} has no Elisp variable definition, return @code{#f}."
  31. (module-variable the-elisp-module sym))
  32. (define (load-elisp-file file-name)
  33. "Load @var{file-name} into the Elisp environment.
  34. @var{file-name} is assumed to name a file containing Elisp code."
  35. ;; This is the same as Elisp's `load-file', so use that if it is
  36. ;; available, otherwise duplicate the definition of `load-file' from
  37. ;; files.el.
  38. (let ((load-file (elisp-function 'load-file)))
  39. (if load-file
  40. (load-file file-name)
  41. (elisp:load file-name #f #f #t))))
  42. (define (load-elisp-library library)
  43. "Load library @var{library} into the Elisp environment.
  44. @var{library} should name an Elisp code library that can be found in
  45. one of the directories of @code{load-path}."
  46. ;; This is the same as Elisp's `load-file', so use that if it is
  47. ;; available, otherwise duplicate the definition of `load-file' from
  48. ;; files.el.
  49. (let ((load-library (elisp-function 'load-library)))
  50. (if load-library
  51. (load-library library)
  52. (elisp:load library))))
  53. (define export-module-name
  54. (let ((counter 0))
  55. (lambda ()
  56. (set! counter (+ counter 1))
  57. (list 'lang 'elisp
  58. (string->symbol (string-append "imports:"
  59. (number->string counter)))))))
  60. (define-macro (use-elisp-file file-name . imports)
  61. "Load Elisp code file @var{file-name} and import its definitions
  62. into the current Scheme module. If any @var{imports} are specified,
  63. they are interpreted as selection and renaming specifiers as per
  64. @code{use-modules}."
  65. (let ((export-module-name (export-module-name)))
  66. `(begin
  67. (fluid-set! ,elisp-export-module (resolve-module ',export-module-name))
  68. (beautify-user-module! (resolve-module ',export-module-name))
  69. (load-elisp-file ,file-name)
  70. (use-modules (,export-module-name ,@imports))
  71. (fluid-set! ,elisp-export-module #f))))
  72. (define-macro (use-elisp-library library . imports)
  73. "Load Elisp library @var{library} and import its definitions into
  74. the current Scheme module. If any @var{imports} are specified, they
  75. are interpreted as selection and renaming specifiers as per
  76. @code{use-modules}."
  77. (let ((export-module-name (export-module-name)))
  78. `(begin
  79. (fluid-set! ,elisp-export-module (resolve-module ',export-module-name))
  80. (beautify-user-module! (resolve-module ',export-module-name))
  81. (load-elisp-library ,library)
  82. (use-modules (,export-module-name ,@imports))
  83. (fluid-set! ,elisp-export-module #f))))
  84. (define (export-to-elisp . defs)
  85. "Export procedures and variables specified by @var{defs} to Elisp.
  86. Each @var{def} is either an object, in which case that object must be
  87. a named procedure or macro and is exported to Elisp under its Scheme
  88. name; or a symbol, in which case the variable named by that symbol is
  89. exported under its Scheme name; or a pair @var{(obj . name)}, in which
  90. case @var{obj} must be a procedure, macro or symbol as already
  91. described and @var{name} specifies the name under which that object is
  92. exported to Elisp."
  93. (for-each (lambda (def)
  94. (let ((obj (if (pair? def) (car def) def))
  95. (name (if (pair? def) (cdr def) #f)))
  96. (cond ((procedure? obj)
  97. (or name
  98. (set! name (procedure-name obj)))
  99. (if name
  100. (fset name obj)
  101. (error "No procedure name specified or deducible:" obj)))
  102. ((macro? obj)
  103. (or name
  104. (set! name (macro-name obj)))
  105. (if name
  106. (fset name obj)
  107. (error "No macro name specified or deducible:" obj)))
  108. ((symbol? obj)
  109. (or name
  110. (set! name obj))
  111. (module-add! the-elisp-module name
  112. (module-ref (current-module) obj)))
  113. (else
  114. (error "Can't export this kind of object to Elisp:" obj)))))
  115. defs))
  116. (define load-emacs (elisp-function 'load-emacs))