From: Franz Kafka
Subject: Help Implementing 'Special Forms' in ANSI Lisp. (Long)
Date: 
Message-ID: <b3b6b110.0304211016.200e427c@posting.google.com>
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.

From: Barry Margolin
Subject: Re: Help Implementing 'Special Forms' in ANSI Lisp. (Long)
Date: 
Message-ID: <zQepa.10$304.451@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.

-- 
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.
From: Franz Kafka
Subject: Re: Help Implementing 'Special Forms' in ANSI Lisp. (Long)
Date: 
Message-ID: <b3b6b110.0304262033.212c53d5@posting.google.com>
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