3 This directory holds the Scheme side of a translator for Emacs Lisp.
7 To load up the base Elisp environment:
9 (use-modules (lang elisp base))
11 Then you can switch into this module
13 (define-module (lang elisp base))
15 and start typing away in Elisp, or evaluate an individual Elisp
16 expression from Scheme:
18 (eval EXP (resolve-module '(lang elisp base)))
20 A more convenient, higher-level interface is provided by (lang elisp
23 (use-modules (lang elisp interface))
25 With this interface, you can evaluate an Elisp expression
29 load an Elisp file with no effect on the Scheme world
31 (load-elisp-file "/home/neil/Guile/cvs/guile-core/lang/elisp/example.el")
33 load an Elisp file, automatically importing top level definitions into
36 (use-elisp-file "/home/neil/Guile/cvs/guile-core/lang/elisp/example.el")
38 export Scheme objects to Elisp
40 (export-to-elisp + - * my-func 'my-var)
42 and try to bootstrap a complete Emacs environment:
48 Please see the STATUS file for the full position.
50 ** Trying to load a complete Emacs environment.
52 To try this, type `(use-modules (lang elisp interface))' and then
53 `(load-emacs)'. The following output shows how far I get when I try
56 guile> (use-modules (lang elisp interface))
58 Calling loadup.el to clothe the bare Emacs...
59 Loading /usr/share/emacs/20.7/lisp/loadup.el...
60 Using load-path ("/usr/share/emacs/20.7/lisp/" "/usr/share/emacs/20.7/lisp/emacs-lisp/")
61 Loading /usr/share/emacs/20.7/lisp/byte-run.el...
62 Loading /usr/share/emacs/20.7/lisp/byte-run.el...done
63 Loading /usr/share/emacs/20.7/lisp/subr.el...
64 Loading /usr/share/emacs/20.7/lisp/subr.el...done
65 Loading /usr/share/emacs/20.7/lisp/version.el...
66 Loading /usr/share/emacs/20.7/lisp/version.el...done
67 Loading /usr/share/emacs/20.7/lisp/map-ynp.el...
68 Loading /usr/share/emacs/20.7/lisp/map-ynp.el...done
69 Loading /usr/share/emacs/20.7/lisp/widget.el...
70 Loading /usr/share/emacs/20.7/lisp/emacs-lisp/cl.el...
71 Loading /usr/share/emacs/20.7/lisp/emacs-lisp/cl.el...done
72 Loading /usr/share/emacs/20.7/lisp/widget.el...done
73 Loading /usr/share/emacs/20.7/lisp/custom.el...
74 Loading /usr/share/emacs/20.7/lisp/custom.el...done
75 Loading /usr/share/emacs/20.7/lisp/cus-start.el...
76 Note, built-in variable `abbrev-all-caps' not bound
77 ... [many other variable not bound messages] ...
78 Loading /usr/share/emacs/20.7/lisp/cus-start.el...done
79 Loading /usr/share/emacs/20.7/lisp/international/mule.el...
80 <unnamed port>: In procedure make-char-table in expression (@fop make-char-table (# #)):
81 <unnamed port>: Symbol's function definition is void
84 Type "(backtrace)" to get more information or "(debug)" to enter the debugger.
87 That's 3279 lines ("wc -l") of Elisp code already, which isn't bad!
89 I think that progress beyond this point basically means implementing
90 multilingual and multibyte strings properly for Guile. Which is a
91 _lot_ of work and requires IMO a very clear plan for Guile's role with
96 When thinking about how to implement an Elisp translator for Guile, it
97 is important to realize that the great power of Emacs does not arise
98 from Elisp (seen as a language in syntactic terms) alone, but from the
99 combination of this language with the collection of primitives
100 provided by the Emacs C source code. Therefore, to be of practical
101 use, an Elisp translator needs to be more than just a transformer that
102 translates sexps to Scheme expressions.
104 The finished translator should consist of several parts...
106 ** Syntax transformation
108 Although syntax transformation isn't all we need, we do still need it!
110 This part is implemented by the (lang elisp transform) module; it is
111 close to complete and seems to work pretty reliably.
113 Note that transformed expressions use the `@fop' and `@bind' macros
116 ** C support for transformed expressions
118 For performance and historical reasons (and perhaps necessity - I
119 haven't thought about it enough yet), some of the transformation
120 support is written in C.
124 The `@fop' macro is used to dispatch Elisp applications. Its first
125 argument is a symbol, and this symbol's function slot is examined to
126 find a procedure or macro to apply to the remaining arguments. `@fop'
127 also handles aliasing (`defalias'): in this case the function slot
128 contains another symbol.
130 Once `@fop' has found the appropriate procedure or macro to apply, it
131 returns an application expression in which that procedure or macro
132 replaces the `@fop' and the original symbol. Hence no Elisp-specific
133 evaluator support is required to perform the application.
137 Currently, Elisp variables are the same as Scheme variables, so
138 variable references are effectively untransformed.
140 The `@bind' macro does Elisp-style dynamic variable binding.
141 Basically, it locates the named top level variables, `set!'s them to
142 new values, evaluates its body, and then uses `set!' again to restore
145 Because of the body evaluation, `@bind' requires evaluator support.
146 In fact, the `@bind' macro code does little more than replace itself
147 with the memoized SCM_IM_BIND. Most of the work is done by the
148 evaluator when it hits SCM_IM_BIND.
150 One theoretical problem with `@bind' is that any local Scheme variable
151 in the same scope and with the same name as an Elisp variable will
152 shadow the Elisp variable. But in practice it's difficult to set up
153 such a situation; an exception is the translator code itself, so there
154 we mangle the relevant Scheme variable names a bit to avoid the
157 Other possible problems with this approach are that it might not be
158 possible to implement buffer local variables properly, and that
159 `@bind' might become too inefficient when we implement full support
160 for undefining Scheme variables. So we might in future have to
161 transform Elisp variable references after all.
163 *** Truth value stuff
165 Following extensive discussions on the Guile mailing list between
166 September 2001 and January 2002, we decided to go with Jim Blandy's
167 proposal. See devel/translation/lisp-and-scheme.text for details.
169 - The Elisp nil value is a new immediate SCM_MAKIFLAG, eq?-distinct
170 from both #f and '() (and of course any other Scheme value). It can
171 be accessed via the (guile) binding `%nil', and prints as `#nil'.
173 - All Elisp primitives treat #nil, #f and '() as identical.
175 - Scheme truth-testing primitives have been modified so that they
176 treat #nil the same as #f.
178 - Scheme list-manipulating primitives have been modified so that they
179 treat #nil the same as '().
181 - The Elisp t value is the same as #t.
183 ** Emacs editing primitives
185 Buffers, keymaps, text properties, windows, frames etc. etc.
187 Basically, everything that is implemented as a primitive in the Emacs
188 C code needs to be implemented either in Scheme or in C for Guile.
190 The Scheme files in the primitives subdirectory implement some of
191 these primitives in Scheme. Not because that is the right decision,
192 but because this is a proof of concept and it's quicker to write badly
193 performing code in Scheme.
195 Ultimately, most of these primitive definitions should really come
196 from the Emacs C code itself, translated or preprocessed in a way that
197 makes it compile with Guile. I think this is pretty close to the work
198 that Ken Raeburn has been doing on the Emacs codebase.
200 ** Reading and printing support
202 Elisp is close enough to Scheme that it's convenient to coopt the
203 existing Guile reader rather than to write a new one from scratch, but
204 there are a few syntactic differences that will require changes in
205 reading and printing. None of the following changes has yet been
208 - Character syntax is `?a' rather than `#\a'. (Not done. More
209 precisely, `?a' in Elisp isn't character syntax but an alternative
210 integer syntax. Note that we could support most of the `?a' syntax
213 (define ?a (char->integer #\a)
214 (define ?b (char->integer #\b)
218 - Vector syntax is `[1 2 3]' rather than `#(1 2 3)'.
220 - When in an Elisp environment, #nil and #t should print as `nil' and
223 ** The Elisp evaluation module (lang elisp base)
225 Fundamentally, Guile's module system can't be used to package Elisp
226 code in the same way it is used for Scheme code, because Elisp
227 function definitions are stored as symbol properties (in the symbol's
228 "function slot") and so are global. On the other hand, it is useful
229 (necessary?) to associate some particular module with Elisp evaluation
232 - Elisp variables are currently implemented as Scheme variables and so
233 need to live in some module
235 - a syntax transformer is a property of a module.
237 Therefore we have the (lang elisp base) module, which acts as the
238 repository for all Elisp variables and the site of all Elisp
241 The initial environment provided by this module is intended to be a
242 non-Emacs-dependent subset of Elisp. To get the idea, imagine someone
243 who wants to write an extension function for, say Gnucash, and simply
244 prefers to write in Elisp rather than in Scheme. He/she therefore
245 doesn't buffers, keymaps and so on, just the basic language syntax and
246 core data functions like +, *, concat, length etc., plus specific
247 functions made available by Gnucash.
249 (lang elisp base) achieves this by
251 - importing Scheme definitions for some Emacs primitives from the
252 files in the primitives subdirectory
254 - then switching into Elisp syntax.
256 After this point, `(eval XXX (resolve-module '(lang elisp base)))'
257 will evaluate XXX as an Elisp expression in the (lang elisp base)
258 module. (`eval-elisp' in (lang elisp interface) is a more convenient
261 ** Full Emacs environment
263 The difference between the initial (lang elisp base) environment and a
264 fully loaded Emacs equivalent is
266 - more primitives: buffers, char-tables and many others
268 - the bootstrap Elisp code that an undumped Emacs loads during
269 installation by calling `(load "loadup.el")'.
271 We don't have all the missing primitives, but we can already get
272 through some of loadup.el. The Elisp function `load-emacs' (defined
273 in (lang elisp base) initiates the loading of loadup.el; (lang elisp
274 interface) exports `load-emacs' to Scheme.
276 `load-emacs' loads so much Elisp code that it's an excellent way to
277 test the translator. In current practice, it runs for a while and
278 then fails when it gets to an undefined primitive or a bug in the
279 translator. Eventually, it should go all the way. (And then we can
280 worry about adding unexec support to Guile!) For the output that
281 currently results from calling `(load-emacs)', see above in the Status
286 ** Ken Raeburn's Guile Emacs page
288 http://www.mit.edu/~raeburn/guilemacs/
290 ** Keisuke Nishida's Gemacs project
292 http://gemacs.sourceforge.net
294 ** Jim Blandy's nil/#f/() notes
296 http://sanpietro.red-bean.com/guile/guile/old/3114.html
298 Also now stored as guile-core/devel/translation/lisp-and-scheme.text
301 ** Mikael Djurfeldt's notes on translation
303 See file guile-core/devel/translation/langtools.text in Guile CVS.