diff options
author | Robin Templeton <robin@terpri.org> | 2014-08-04 23:11:29 -0400 |
---|---|---|
committer | Ricardo Wurmus <rekado@elephly.net> | 2020-04-04 16:24:57 +0200 |
commit | 60540ec28872bd6c15ed1631489579aab47905b1 (patch) | |
tree | 0085d25dad39efc4c8d837ebe4eda156730cb276 | |
parent | 3d4c39a8aa264b72bbfeb2e3e3f2abcdc6d8c048 (diff) |
compiler macros
(Best-ability ChangeLog annotation added by Christopher Allan Webber.)
* module/language/elisp/boot.el (%define-compiler-macro): New macro.
* module/language/elisp/compile-tree-il.scm: New function.
(compile-pair): Update to handle %compiler-macro condition.
-rw-r--r-- | module/language/elisp/boot.el | 12 | ||||
-rw-r--r-- | module/language/elisp/compile-tree-il.scm | 12 |
2 files changed, 24 insertions, 0 deletions
diff --git a/module/language/elisp/boot.el b/module/language/elisp/boot.el index bef4c1d7c..fe9af290f 100644 --- a/module/language/elisp/boot.el +++ b/module/language/elisp/boot.el @@ -41,6 +41,18 @@ (eval-when-compile ,@body) (progn ,@body))) +(defmacro %define-compiler-macro (name args &rest body) + `(eval-and-compile + (%funcall + (@ (language elisp runtime) set-symbol-plist!) + ',name + (%funcall + (@ (guile) cons*) + '%compiler-macro + #'(lambda ,args ,@body) + (%funcall (@ (language elisp runtime) symbol-plist) ',name))) + ',name)) + (eval-and-compile (defun eval (form) (%funcall (@ (language elisp runtime) eval-elisp) form))) diff --git a/module/language/elisp/compile-tree-il.scm b/module/language/elisp/compile-tree-il.scm index 8a78d3970..3cbd29740 100644 --- a/module/language/elisp/compile-tree-il.scm +++ b/module/language/elisp/compile-tree-il.scm @@ -801,6 +801,11 @@ (make-void loc)) (else (report-error loc "bad %set-lexical-binding-mode" args)))) +(define (eget s p) + (if (symbol-fbound? 'get) + ((symbol-function 'get) s p) + #nil)) + ;;; Compile a compound expression to Tree-IL. (define (compile-pair loc expr) @@ -813,6 +818,13 @@ ((find-operator operator 'macro) => (lambda (macro-function) (compile-expr (apply macro-function arguments)))) + ((and (symbol? operator) + (eget operator '%compiler-macro)) + => (lambda (compiler-macro-function) + (let ((new (compiler-macro-function expr))) + (if (eq? new expr) + (compile-expr `(%funcall (%function ,operator) ,@arguments)) + (compile-expr new))))) (else (compile-expr `(%funcall (%function ,operator) ,@arguments)))))) |