mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-05-15 02:00:22 +02:00
(Best-ability ChangeLog annotation added by Christine Lemmer-Webber.) * module/language/elisp/bindings.scm (get-lexical-binding) (get-function-binding): Use cadr instead of fluid-ref on slot. (with-fluids**): New procedure. (with-symbol-bindings, with-function-bindings): Use with-fluids**. Also stop using "make-fluid", use "(list #f #f)" instead as default lexical-bindings hashtable value. (with-lexical-bindings): Drop the error checking for invalid targets. * module/language/elisp/boot.el (defun, save-excursion) (save-current-buffer, save-restriction, track-mouse, setq-default) (catch, condition-case): New macros. (omega, eval, gensym, interactive, autoload-do-load, fset, prin1) (backtrace-frame, backtrace, %set-eager-macroexpansion-mode): New functions. (null, consp, listp, car, cdr, make-symbol, signal): Wrap in eval-and-compile. (prog1, cond, or, while): Update to make use of gensym. (unwind-protect): Switch from funcall to %funcall. (%functionp): Rename from functionp. (%indirect-function): Update to use %functionp instead of functionp. Add check for if object is null, signaling void-function. Instead of calling symbol-function directly, call via %funcall from the module "(language elisp runtime)". (fset): Significant additions and refactoring. (gload): Renamed from fload. (defvaralias, nthcdr, nth, eq): Move functions to a different location. (eq): Also stop using null. (dolist): Remove quasiquoting, build list manually. (random): Fix indentation. (progn, eval-when-compile, if, defconst, defvar, setq, let, flet) (labels, let*, function, defmacro, quote): Protect as special operators by raising error if invoked as a function. * module/language/elisp/compile-tree-il.scm: Import "(ice-9 format)". Export compile-%function. (lexical-binding, handle-var-def, defun, valid-symbol-list-arg?) (process-options!): Remove. (reference-variable): Adjust functions passed to access-variable. (global?): Drop module parameter, use value-slot instead. (ensure-globals!, set-variable!, parse-body-1, parse-lambda-list) (compile-lambda, defconst, defvar, let, let*, compile-pair): Refactor. (reference-function): Use '(elisp-functions) instead of function-slot. (bind-lexically?): Drop module parameter, simplify. (make-dynlet): Switch from using make-primcall to make-call. (find-operator): Switch from using resolve-interface/resolve-module to using function-slot. (if, defconst, defvar, let, let*, flet, labels, guile-ref) (guile-private-ref, guile-primitive, defmacro, `, quote, %funcall) (%set-lexical-binding-mode): Add error checking. (setq): Pass in args to report-error. (function): Simplified, now calling %function. (%function): New function, based on prior "function". Refactor, including adding support for matching against a closure. (%set-lexical-binding-mode): Switch from using fluid-set! to set-lexical-binding-mode. (special-operators): New variable. Build from following for-each statement. (compile-tree-il): Drop call to "process-options!" * module/language/elisp/lexer.scm: Import "(language elisp runtime)". (lex): Switch from using "list->string" to "make-lisp-string". * module/language/elisp/runtime.scm: Use modules "(ice-9 format)", "(system base compile)". Remove from export list list, removing ensure-fluid!, symbol-fluid!, set-symbol-fluid!. Add to export list ensure-dynamic!, symbol-name, symbol-plist, set-symbol-plist!, bind-symbol, symbol-desc, proclaim-symbol! special? emacs! unbound, lexical-binding?, set-lexical-binding-mode, log!, eval-elisp, local-eval-elisp, make-lisp-string, lisp-string? (make-list-string, lisp-string?) New function aliases. (value-slot-module, function-slot-module): Adjust module resolution. (nil_, t_): New variables. (ensure-fluid!, symbol-fluid, set-symbol-fluid!): Removed. (lexical-binding, unbound): New variables. (lexical-binding?, set-lexical-binding-mode, unbound, dynamic?) (make-dynamic, dynamic-ref, dynamic-set!, dynamic-unset!) (dynamic-bound?, dynamic-bind, ensure-present!, ensure-desc!) (schemify, symbol-name, symbol-desc, ensure-dynamic!, symbol-dynamic) (set-symbol-plist!, special?, proclaim-special!, emacs!, eval-elisp) (make-string): New procedures. (symbol-value): Use dynamic-ref! instead of fluid-ref!. (set-symbol-value!): Use dynamic-set! instead of fluid-set!. (symbol-function, set-symbol-function!, symbol-bound?) (symbol-fbound?, makunbound!, fmakunbound!): Refactor, including adjusting how module resolution is being done. * module/language/elisp/spec.scm: Import module "(system vm vm)". Setup elisp-symbols, elisp-functions, elisp-plists. Use "set-default-vm-engine!" and "set-vm-engine!" to be set to 'debug. (elisp): Comment out joiner. |
||
---|---|---|
.. | ||
runtime | ||
bindings.scm | ||
boot.el | ||
compile-tree-il.scm | ||
falias.scm | ||
lexer.scm | ||
parser.scm | ||
README | ||
runtime.scm | ||
spec.scm |
Guile's Emacs Lisp compiler =========================== This is more or less a lot of work in progress. Here are some notes as well as status information. Already implemented: * progn, prog1, prog2 * if, cond, when, unless * not, and, or * referencing and setting (setq) variables * set, symbol-value, makunbound, boundp functions * fset, symbol-function, fmakunbound, fboundp * funcall, apply (also with raw lists as arguments and the like!) * eval * while, dotimes, dolist * catch, throw, unwind-protect * let, let* * lambda expressions, function calls using list notation * some built-ins (mainly numbers/arithmetic) * defconst, defvar, defun * macros * quotation and backquotation with unquote/unquote-splicing * specific elisp reader Especially still missing: * more general built-ins * advice? * defsubst and inlining * recursive macros * anonymous macros Other ideas and things to think about: * #nil vs. #f/'() handling in Guile Compiler options implemented: * #:disable-void-check ['all / '(sym1 sym2 sym3)] to disable the check for void value on access either completely or for some symbols * #:always-lexical (usable same as disable-void-check) to always bind certain or all symbols lexically (including lambda arguments) Extensions over original elisp: * guile-ref, guile-primitive * flet and flet* * lexical-let and lexical-let* * without-void-checks, with-always-lexical Details to the implemented extensions ===================================== guile-ref and guile-primitive: ------------------------------ (guile-ref module sym) is a new special construct to access symbols from the Guile-world. Actually, (guile-ref module sym) is the same as (@ module sym) would be in Scheme. Both module and sym must be statically given and are not evaluated. (guile-primitive sym) does the same to access a Guile primitive directly, which is slightly faster where applicable. flet and flet*: --------------- These constructs behave exactly like let and let*, except that they bind the function slots rather than the value slots, and so make dynamic scoping available for functions, too. The distinction between flet and flet* is probably less useful than the one between let and let*, but it was easy to implement both flet and flet* based on the existing let and let* code, so not having both of them seemed a little inconsistent. lexical-let and lexical-let*: ----------------------------- lexical-let and lexical-let* are constructs provided by the elisp package 'cl originally, but in Guile they are natively implemented because using lexical instead of dynamic binding gives better performance in this case. They work just like let and let*, but bind their target symbols lexically. Some oberservations with the Emacs 'cl implementation that we mimic in Guile for compatibility: * Ordinary let's within the lexical scope of a lexical-let still establish new *lexical* bindings for symbols already lexically bound. So once lexical, always lexical (on a per-symbol basis). * However, lambda constructs within the lexical scope of a lexical-let where one of their arguments is already lexically bound still bind it dynamically for their scope. * On the other hand, symbols lexically bound that are not rebound via the argument-list build lexical closures just well. * If symbols are accessed where they are not known at compile-time (like symbol-value or set primitives), this always refers to the dynamic binding and never the lexical one. That's very nice to the implementor... without-void-checks: -------------------- Disable void checks in addition to the compiler option for all or some symbols in the lexical scope of this construct: (without-void-checks all body...) or (without-void-checks (sym1 sym2 ...) body... with-always-lexical: -------------------- As without-void-checks but adds to list of symbols that should always be bound lexically. This lexical binding includes lambda arguments (if the symbols match up with the list), which can not be bound lexically otherwise.