gnu-arch-users
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Gnu-arch-users] Re: Tla spork


From: Andrew Suffield
Subject: Re: [Gnu-arch-users] Re: Tla spork
Date: Fri, 27 Aug 2004 19:36:01 +0100
User-agent: Mutt/1.5.6+20040803i

On Fri, Aug 27, 2004 at 07:13:48PM +0200, Haakon Riiser wrote:
> > I could add code to gcc's C parser to implement any macro system you
> > care to specify. It would take no more than a few days.
> > 
> > I'm not going to waste a few days on something so useless just to
> > prove a point. But I could.
> 
> How would you do that?  Unlike trivial macro processors such
> as cpp, m4, etc., macros in Common Lisp work directly on the
> parse tree.  This is natural in Common Lisp because the code
> you're writing maps directly to the parsed form.  Other languages
> have caught up with Lisp in every way, *except* for true macros,
> which I (as of yet) have not seen anywhere else.
> 
> You could probably do something similar for C by having the macro
> processor work on the parsed C code, but I imagine it would be
> much harder to work with because the written code bears little
> resemblance to the parse tree.

What, have you never seen a C parser? I can do the translations back
and forth in my head; here's a (trivial) example:

Take the following code:

int
foo(int x, int y)
{
  int a = x + y;
  a++;
  return a * 2;
}

You'll get a parse tree that's something like this:

[] is a set of attributes, {} is a list

defun foo [return: int, args: {declare-variable [type: int, name : x],
                               declare-variable [type: int, name : y]},
           body: {assign [var: declare-variable [type: int, name: a],
                          value: {plus [arg1: variable [name: x], arg2: 
variable [name: y]]}],
                  increment [var: variable [name: a]],
                  return [value: multiply [arg1: variable [name: a], arg2: 
integer [value: 2]]]}]

There's absolutely no reason why I cannot say:

#define-macro (x + y) magic_plus(x, y)

Parse tree for this is:

define-macro plus [arg1: declare-macro-argument [name: x],
                   arg2: declare-macro-argument [name: y],
                   value: {function-call [name: magic_plus, args: 
{macro-argument [name: x], macro-argument [name: y]}]}]

Apply this macro parse tree to the function parse tree (this is a
simple case of pattern matching on name and arguments, and
substitution of the value) and we get:

defun foo [return: int, args: {declare-variable [type: int, name : x],
                               declare-variable [type: int, name : y]},
           body: {assign [var: declare-variable [type: int, name: a],
                          value: {function-call [name: magic_plus, args: 
{variable [name: x], variable [name: y]}]}],
                  increment [var: variable [name: a]],
                  return [value: multiply [arg1: {variable [name: a]}, arg2 
{integer [value: 2]}]]}]

Dumping that out as C code, it's:

int
foo(int x, int y)
{
  int a = magic_plus(x, y);
  a++;
  return a * 2;
}

[You could have written these parse trees as lisp-like forms if you
wanted to. I find this notation easier to read; it's a variation on
the one used by gcc].

The only prerequisite is a syntax that can be expressed in BNF. That's
where macros are applied anyway.

Anything you can come up with in lisp that I can get my head around, I
can come up with an equivalent in C (although I haven't introduced
enough parser magic to cover all the cases yet).

-- 
  .''`.  ** Debian GNU/Linux ** | Andrew Suffield
 : :' :  http://www.debian.org/ |
 `. `'                          |
   `-             -><-          |

Attachment: signature.asc
Description: Digital signature


reply via email to

[Prev in Thread] Current Thread [Next in Thread]