/[guile]/guile/guile-core/lang/elisp/README
ViewVC logotype

Diff of /guile/guile-core/lang/elisp/README

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.1 by ossau, Fri Oct 19 14:43:38 2001 UTC revision 1.2 by ossau, Tue Jan 22 23:46:01 2002 UTC
# Line 0  Line 1 
1                                                        -*- outline -*-
2    
3    This directory holds the Scheme side of a translator for Emacs Lisp.
4    
5    * Usage
6    
7    To load up the base Elisp environment:
8    
9        (use-modules (lang elisp base))
10    
11    Then you can switch into this module
12    
13        (define-module (lang elisp base))
14    
15    and start typing away in Elisp, or evaluate an individual Elisp
16    expression from Scheme:
17    
18        (eval EXP (resolve-module '(lang elisp base)))
19    
20    A more convenient, higher-level interface is provided by (lang elisp
21    interface):
22    
23        (use-modules (lang elisp interface))
24    
25    With this interface, you can evaluate an Elisp expression
26    
27        (eval-elisp EXP)
28    
29    load an Elisp file with no effect on the Scheme world
30    
31        (load-elisp-file "/home/neil/Guile/cvs/guile-core/lang/elisp/example.el")
32    
33    load an Elisp file, automatically importing top level definitions into
34    Scheme
35    
36        (use-elisp-file "/home/neil/Guile/cvs/guile-core/lang/elisp/example.el")
37    
38    export Scheme objects to Elisp
39    
40        (export-to-elisp + - * my-func 'my-var)
41    
42    and try to bootstrap a complete Emacs environment:
43    
44        (load-emacs)
45    
46    * Status
47    
48    Please note that this is work in progress; the translator is
49    incomplete and not yet widely tested.
50    
51    ** Trying to load a complete Emacs environment.
52    
53    To try this, type `(use-modules (lang elisp interface))' and then
54    `(load-emacs)'.  The following output shows how far I get when I try
55    this.
56    
57    guile> (use-modules (lang elisp interface))
58    guile> (load-emacs)
59    Calling loadup.el to clothe the bare Emacs...
60    Loading /usr/share/emacs/20.7/lisp/loadup.el...
61    Using load-path ("/usr/share/emacs/20.7/lisp/" "/usr/share/emacs/20.7/lisp/emacs-lisp/")
62    Loading /usr/share/emacs/20.7/lisp/byte-run.el...
63    Loading /usr/share/emacs/20.7/lisp/byte-run.el...done
64    Loading /usr/share/emacs/20.7/lisp/subr.el...
65    Loading /usr/share/emacs/20.7/lisp/subr.el...done
66    Loading /usr/share/emacs/20.7/lisp/version.el...
67    Loading /usr/share/emacs/20.7/lisp/version.el...done
68    Loading /usr/share/emacs/20.7/lisp/map-ynp.el...
69    Loading /usr/share/emacs/20.7/lisp/map-ynp.el...done
70    Loading /usr/share/emacs/20.7/lisp/widget.el...
71    Loading /usr/share/emacs/20.7/lisp/emacs-lisp/cl.el...
72    Loading /usr/share/emacs/20.7/lisp/emacs-lisp/cl.el...done
73    Loading /usr/share/emacs/20.7/lisp/widget.el...done
74    Loading /usr/share/emacs/20.7/lisp/custom.el...
75    Loading /usr/share/emacs/20.7/lisp/custom.el...done
76    Loading /usr/share/emacs/20.7/lisp/cus-start.el...
77    Note, built-in variable `abbrev-all-caps' not bound
78      ... [many other variable not bound messages] ...
79    Loading /usr/share/emacs/20.7/lisp/cus-start.el...done
80    Loading /usr/share/emacs/20.7/lisp/international/mule.el...
81    <unnamed port>: In procedure make-char-table in expression (@fop make-char-table (# #)):
82    <unnamed port>: Symbol's function definition is void
83    ABORT: (misc-error)
84    
85    Type "(backtrace)" to get more information or "(debug)" to enter the debugger.
86    guile>
87    
88    That's 3279 lines ("wc -l") of Elisp code already, which isn't bad!
89    
90    I think that progress beyond this point basically means implementing
91    multilingual and multibyte strings properly for Guile.  Which is a
92    _lot_ of work and requires IMO a very clear plan for Guile's role with
93    respect to Emacs.
94    
95    * Design
96    
97    When thinking about how to implement an Elisp translator for Guile, it
98    is important to realize that the great power of Emacs does not arise
99    from Elisp (seen as a language in syntactic terms) alone, but from the
100    combination of this language with the collection of primitives
101    provided by the Emacs C source code.  Therefore, to be of practical
102    use, an Elisp translator needs to be more than just a transformer that
103    translates sexps to Scheme expressions.
104    
105    The finished translator should consist of several parts...
106    
107    ** Syntax transformation
108    
109    Although syntax transformation isn't all we need, we do still need it!
110    
111    This part is implemented by the (lang elisp transform) module; it is
112    close to complete and seems to work pretty reliably.
113    
114    Note that transformed expressions use the `@fop' and `@bind' macros
115    provided by...
116    
117    ** C support for transformed expressions
118    
119    For performance and historical reasons (and perhaps necessity - I
120    haven't thought about it enough yet), some of the transformation
121    support is written in C.
122    
123    *** @fop
124    
125    The `@fop' macro is used to dispatch Elisp applications.  Its first
126    argument is a symbol, and this symbol's function slot is examined to
127    find a procedure or macro to apply to the remaining arguments.  `@fop'
128    also handles aliasing (`defalias'): in this case the function slot
129    contains another symbol.
130    
131    Once `@fop' has found the appropriate procedure or macro to apply, it
132    returns an application expression in which that procedure or macro
133    replaces the `@fop' and the original symbol.  Hence no Elisp-specific
134    evaluator support is required to perform the application.
135    
136    *** @bind
137    
138    Currently, Elisp variables are the same as Scheme variables, so
139    variable references are effectively untransformed.
140    
141    The `@bind' macro does Elisp-style dynamic variable binding.
142    Basically, it locates the named top level variables, `set!'s them to
143    new values, evaluates its body, and then uses `set!' again to restore
144    the original values.
145    
146    Because of the body evaluation, `@bind' requires evaluator support.
147    In fact, the `@bind' macro code does little more than replace itself
148    with the memoized SCM_IM_BIND.  Most of the work is done by the
149    evaluator when it hits SCM_IM_BIND.
150    
151    One theoretical problem with `@bind' is that any local Scheme variable
152    in the same scope and with the same name as an Elisp variable will
153    shadow the Elisp variable.  But in practice it's difficult to set up
154    such a situation; an exception is the translator code itself, so there
155    we mangle the relevant Scheme variable names a bit to avoid the
156    problem.
157    
158    Other possible problems with this approach are that it might not be
159    possible to implement buffer local variables properly, and that
160    `@bind' might become too inefficient when we implement full support
161    for undefining Scheme variables.  So we might in future have to
162    transform Elisp variable references after all.
163    
164    *** Truth value stuff
165    
166    Lots of stuff to do with providing the special self-evaluating `nil'
167    and `t' symbols, and macros that convert between Scheme and Elisp
168    truth values, and so on.
169    
170    I'm hoping that most of this will go away, but I need to show that
171    it's feasible first.
172    
173    ** Emacs editing primitives
174    
175    Buffers, keymaps, text properties, windows, frames etc. etc.
176    
177    Basically, everything that is implemented as a primitive in the Emacs
178    C code needs to be implemented either in Scheme or in C for Guile.
179    
180    The Scheme files in the primitives subdirectory implement some of
181    these primitives in Scheme.  Not because that is the right decision,
182    but because this is a proof of concept and it's quicker to write badly
183    performing code in Scheme.
184    
185    Ultimately, most of these primitive definitions should really come
186    from the Emacs C code itself, translated or preprocessed in a way that
187    makes it compile with Guile.  I think this is pretty close to the work
188    that Ken Raeburn has been doing on the Emacs codebase.
189    
190    ** Reading and printing support
191    
192    Elisp is close enough to Scheme that it's convenient to coopt the
193    existing Guile reader rather than to write a new one from scratch, but
194    there are a few syntactic differences that will require adding Elisp
195    support to the reader.
196    
197    - Character syntax is `?a' rather than `#\a'.  (Not done.  More
198      precisely, `?a' in Elisp isn't character syntax but an alternative
199      integer syntax.  Note that we could support most of the `?a' syntax
200      simply by doing
201    
202          (define ?a (char->integer #\a)
203          (define ?b (char->integer #\b)
204    
205      and so on.)
206    
207    - `nil' and `t' should be read (I think) as #f and #t.  (Done.)
208    
209    - Vector syntax is `[1 2 3]' rather than `#(1 2 3)'.  (Not done.)
210    
211    Correspondingly, when printing, #f and '() should be written as
212    `nil'.  (Not done.)
213    
214    ** The Elisp evaluation module (lang elisp base)
215    
216    Fundamentally, Guile's module system can't be used to package Elisp
217    code in the same way it is used for Scheme code, because Elisp
218    function definitions are stored as symbol properties (in the symbol's
219    "function slot") and so are global.  On the other hand, it is useful
220    (necessary?) to associate some particular module with Elisp evaluation
221    because
222    
223    - Elisp variables are currently implemented as Scheme variables and so
224      need to live in some module
225    
226    - a syntax transformer is a property of a module.
227    
228    Therefore we have the (lang elisp base) module, which acts as the
229    repository for all Elisp variables and the site of all Elisp
230    evaluation.
231    
232    The initial environment provided by this module is intended to be a
233    non-Emacs-dependent subset of Elisp.  To get the idea, imagine someone
234    who wants to write an extension function for, say Gnucash, and simply
235    prefers to write in Elisp rather than in Scheme.  He/she therefore
236    doesn't buffers, keymaps and so on, just the basic language syntax and
237    core data functions like +, *, concat, length etc., plus specific
238    functions made available by Gnucash.
239    
240    (lang elisp base) achieves this by
241    
242    - importing Scheme definitions for some Emacs primitives from the
243      files in the primitives subdirectory
244    
245    - then switching into Elisp syntax.
246    
247    After this point, `(eval XXX (resolve-module '(lang elisp base)))'
248    will evaluate XXX as an Elisp expression in the (lang elisp base)
249    module.  (`eval-elisp' in (lang elisp interface) is a more convenient
250    wrapper for this.)
251    
252    ** Full Emacs environment
253    
254    The difference between the initial (lang elisp base) environment and a
255    fully loaded Emacs equivalent is
256    
257    - more primitives: buffers, char-tables and many others
258    
259    - the bootstrap Elisp code that an undumped Emacs loads during
260      installation by calling `(load "loadup.el")'.
261    
262    We don't have all the missing primitives, but we can already get
263    through some of loadup.el.  The Elisp function `load-emacs' (defined
264    in (lang elisp base) initiates the loading of loadup.el; (lang elisp
265    interface) exports `load-emacs' to Scheme.
266    
267    `load-emacs' loads so much Elisp code that it's an excellent way to
268    test the translator.  In current practice, it runs for a while and
269    then fails when it gets to an undefined primitive or a bug in the
270    translator.  Eventually, it should go all the way.  (And then we can
271    worry about adding unexec support to Guile!)  For the output that
272    currently results from calling `(load-emacs)', see above in the Status
273    section.
274    
275    * nil, #f and '()
276    
277    For Jim Blandy's notes on this, see the reference at the bottom of
278    this file.  Currently I'm investigating a different approach, which is
279    better IMO than Jim's proposal because it avoids requiring multiple
280    false values in the Scheme world.
281    
282    According to my approach...
283    
284    - `nil' and `t' are read (when in Elisp mode) as #f and #t.
285    
286    - `(if x ...)', `(while x ...)' etc. are translated to something
287      like `(if (and x (not (null? x))) ...)'.
288    
289    - Functions which interpret an argument as a list --
290      `cons', `setcdr', `memq', etc. -- either convert #f to '(), or
291      handle the #f case specially.
292    
293    - `eq' treats #f and '() as the same.
294    
295    - Optionally, functions which produce '() values -- i.e. the reader
296      and `cdr' -- could convert those immediately to #f.  This shouldn't
297      affect the validity of any Elisp code, but it alters the balance of
298      #f and '() values swimming around in that code and so affects what
299      happens if two such values are returned to the Scheme world and then
300      compared.  However, since you can never completely solve this
301      problem (unless you are prepared to convert arbitrarily deep
302      structures on entry to the Elisp world, which would kill performance),
303      I'm inclined not to try to solve it at all.
304    
305    * Resources
306    
307    ** Ken Raeburn's Guile Emacs page
308    
309    http://www.mit.edu/~raeburn/guilemacs/
310    
311    ** Keisuke Nishida's Gemacs project
312    
313    http://gemacs.sourceforge.net
314    
315    ** Jim Blandy's nil/#f/() notes
316    
317    http://sanpietro.red-bean.com/guile/guile/old/3114.html
318    
319    ** Mikael Djurfeldt's notes on translation
320    
321    See file guile-cvs/devel/translation/langtools.text in Guile CVS.

Legend:
Removed from v.1.1  
changed lines
  Added in v.1.2

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26