I am trying to extend a verison of Lisp I have, as a project just to
learn
about using Lisp.
I have a question about special forms.
I found an article: Metacircular Semantics for Common Lisp Special
Forms.
In the article Henry Baker discusses implementing Special Forms as
macros in terms of each other.
I am having a problem because the Lisp I am working with has: Prog1,
Prog2, Progn, Let, Let*, Tagbody, Unwind-Protect, Go.
How ever it is missing: Progv, Labels, Flet, Macrolet,
Symbol-Macrolet.
The article discusses how to implement Labels in terms of Flet. And
how to implement Progv (a working but not fully ANSI compliant
version) with Unwind-Protect. How ever the problem is that he
implements Flet in terms of Macrolet, and does not discuss how to
implement Macrolet.
I have two questions:
1.) how could Macrolet/Symbol-Macrolet be implemented.
2.) Is it possible to implement all of the special forms in terms of
each other so I could bootstrap my Lisp with all of the special forms.
Here is some code I am using from the Article:
;; From Henry Bakers article /w functions renamed to prevent
;; redefining Lisp's Special Forms.
;; hopefully it would be possible to implement portable special
;; forms that are defined interms of each other so that a small
;; kernal Lisp could be turned into ANSI CL.
(defconstant *unbound-value* (list nil))
(defun msymbol-value (var)
(if (boundp var) (symbol-value var) *unbound-value*))
(defun mset (var val)
(if (eq val *unbound-value*) (makunbound var) (set var val)))
(defmacro -progv (syms vals &body forms)
(let* ((vsyms (gensym)) (vvals (gensym)) (vovals (gensym)))
`(let* ((,vsyms ,syms)
(,vvals ,vals)
(,vovals ,(mapcar #'msymbol-value ,vsyms)))
(unwind-protect
(progn (mapc #'mset ,vsyms ,vvals)
(mapc #'makunbound
(subseq ,vsyms (min (length ,vsyms) (length
,vvals))))
,@forms)
(mapc #'mset ,vsyms ,vovals)))))
(eval-when (compile)
(defun iota-list (n &optional (m 0))
(if (zerop n) nil `(,m ,@(iota-list (1- n) (1+ m))))))
(defmacro -flet (fns &body forms)
(let* ((fnames (mapcar #'car fns))
(nfnames (mapcar #'(lambda (ignore) (gensym)) fnames))
(nfbodies (mapcar #'(lambda (f) `#'(lambda ,@(cdr f))) fns)))
`(let ,(mapcar #'(lambda (nfn nfb) `(,fnf ,nfb))
nfnames nfbodies)
(macrolet
,(mapcar #'(lambda (f nf) `(,f (&rest a) `(apply ,',nf ,a)))
fnames nfnames)
,@forms))))
(defmacro -labels (fns &body forms)
(let* ((fnames (mapcar #'car fns))
(fnvec (gensym))
(findicies (iota-list (length fns)))
(fbodies (mapcar #'(lambda (f i)
`(,f (&rest a) (apply (svref ,fnvec ,i)
a)))
fnames findicies))
(fdecls `(declare (inline ,@fnames)))
(nfbodies (mapcar #'(lambda (f)
`#'(lambda (,fnvec ,@(cadr f))
(-flet ,fbodies ,fdecls ,@(cddr
f))))
fns)))
`(let ((,fnvec (vector ,@nfbodies)))
(-flet ,fbodies ,fdecls ,@forms))))
I put a '-' in front of the special forms so thay would not conflict
with the real special forms.
I am trying to implement special forms using ANSI CL, and the other
special forms so that I can create a file that will allow Lisp
dialects that lack special forms to be able to add them.
I am trying to add: FLET, LABELS, MACROLET, and PROGV to Star Sapphire
Common Lisp, and anyother CL that needs them.
Thanks in Advance.
PS
I have not been able to test the code yet because I could not
implement Macrolet.
In article <····························@posting.google.com>,
Franz Kafka <·································@hotmail.com> wrote:
>I have two questions:
>1.) how could Macrolet/Symbol-Macrolet be implemented.
You'd need to implement a code walker that performs the substitutions in
the body by itself.
--
Barry Margolin, ··············@level3.com
Genuity Managed Services, a Level(3) Company, Woburn, MA
*** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups.
Please DON'T copy followups to me -- I'll assume it wasn't posted to the group.
Barry Margolin <··············@level3.com> wrote in message news:<················@paloalto-snr1.gtei.net>...
> In article <····························@posting.google.com>,
> Franz Kafka <·································@hotmail.com> wrote:
> >I have two questions:
> >1.) how could Macrolet/Symbol-Macrolet be implemented.
>
> You'd need to implement a code walker that performs the substitutions in
> the body by itself.
This might be a stupid question--but how would I implement a code walker.
Are their any books about how to do it.
Is it even possible to do in ANSI CL?
I understand the basics, but might get the details wrong: a code walker
expands Lisp code and can modify the code as it is running usually to
cause some form of compiler transformation with the code--could
macros be used to write a code walker.
Can you please give me some sample code about how to write a code walker.
Thanks.
From: Bill Clementson
Subject: Re: Help Implementing 'Special Forms' in ANSI Lisp. (Long)
Date:
Message-ID: <wk7k9gv6ss.fsf@attbi.com>
·································@hotmail.com (Franz Kafka) writes:
> Can you please give me some sample code about how to write a code walker.
>
> Thanks.
Google is your friend - try searching for "code walker lisp":
http://www-2.cs.cmu.edu/afs/cs/project/ai-repository/ai/lang/lisp/code/codewalk/0.html
--
Bill Clementson