Re: macros (was: Paul Graham's teaching style is bad}

From: Marco Parrone (marc0_at_autistici.org)
Date: 08/15/04


Date: Sat, 14 Aug 2004 23:55:01 GMT

Bruce Hoult on Sun, 15 Aug 2004 10:49:15 +1200 writes:

> Oh, and btw, you didn't run your code before posting it.

Yes, I run it. I just had not known `repeat ... until'. I've never
seen it before, and I had misunderstood the description I found with a
little googling. I've run the code befor posting. All the code I
posted compile and run without errors nor warnings, running giving
meaningful output, with GCC 3.4.1.

>> /* repeat ... until: implementation #2: using GCC local labels */
>> /*
>> #define repeat { __label__ loop; loop:
>> #define until(cond) if (cond) goto loop; }
>> */
>>
>> /* repeat ... until: implementation #3: using GAS local labels */
>> #define repeat __asm__ ("1:");
>> #define until(cond) if (cond) __asm__ ("jmp 1b")
>
> Neither of these is going to handle nested loops.

Yes, the first nests. `myfor' nests too. I fixed the
`repeat...until' error.

#include <stdio.h>

#define repeat { __label__ loop; loop:
#define until(cond) if (! (cond)) goto loop; }

int
main (int argc, char *argv[])
{
  int i;
  int k;

  k = 0;
  repeat
    i = 10;
    printf ("[%d:", k);
    repeat
      printf (" %d", i);
      --i;
    until (i == 0);
    printf ("]\n");
    k++;
  until (k == 10);

  printf ("\n");
  return 0;
}

marco@marc0:~/tmp$ gcc -Wall until.c
marco@marc0:~/tmp$ ./a.out
[0: 10 9 8 7 6 5 4 3 2 1]
[1: 10 9 8 7 6 5 4 3 2 1]
[2: 10 9 8 7 6 5 4 3 2 1]
[3: 10 9 8 7 6 5 4 3 2 1]
[4: 10 9 8 7 6 5 4 3 2 1]
[5: 10 9 8 7 6 5 4 3 2 1]
[6: 10 9 8 7 6 5 4 3 2 1]
[7: 10 9 8 7 6 5 4 3 2 1]
[8: 10 9 8 7 6 5 4 3 2 1]
[9: 10 9 8 7 6 5 4 3 2 1]

marco@marc0:~/tmp$

#include <stdio.h>

#define myfor(init, cond, step, body) { init; while (cond) { body; step; } }

int
main (int argc, char *argv[])
{
  int i;
  int j;

  myfor (i = 0,
         i < 10,
         ++i,
         printf ("[%d:", i);
         myfor (j = 10,
                j > 0,
                --j,
                printf (" %d", j));
         printf ("]\n"));
  return 0;
}

marco@marc0:~/tmp$ gcc -Wall myfor.c
marco@marc0:~/tmp$ ./a.out
[0: 10 9 8 7 6 5 4 3 2 1]
[1: 10 9 8 7 6 5 4 3 2 1]
[2: 10 9 8 7 6 5 4 3 2 1]
[3: 10 9 8 7 6 5 4 3 2 1]
[4: 10 9 8 7 6 5 4 3 2 1]
[5: 10 9 8 7 6 5 4 3 2 1]
[6: 10 9 8 7 6 5 4 3 2 1]
[7: 10 9 8 7 6 5 4 3 2 1]
[8: 10 9 8 7 6 5 4 3 2 1]
[9: 10 9 8 7 6 5 4 3 2 1]
marco@marc0:~/tmp$

> All your examples have the same problem that while a programmer *can*
> correctly match up your new macros, there is no way to check that they
> have.

true, i just wanted to see if it can be done easily, not if it can be
done with checks and all that fancy things ;)

I find that the latest 2 challenges about walking the sources harder,
I don't think I can solve them, however I will try.

I like more the more explicit/detailed replies that I got in the
thread, than justing having to trust `this can not be done in C'.

> You also haven't shown how to write a C macro coresponding to the given
> example, that expands to arbitrarily nested for loops, with the depth
> depending on the way the user uses the macro.

Please let me see how it does not nest. Please note that the `myfor'
macro definition is not changed.

> Common Lisp and Dylan and Scheme macros actually create new syntax and
> integrate it into the language so seamlessly that you can't tell it
> isn't built in.

> That's no important when you're doing macros used to just one level, but
> when almost everything you do is a macro that expands to a macro that
> expands to a macro it is essential.

-- 
Marco Parrone <marc0@autistici.org> [0x45070AD6]


Relevant Pages

  • Re: Preprocessor possibilities
    ... > Is it possible to write a macro (in unextended C89) such that ... > TEST(int, (1,2,3)); ... > expands to ...
    (comp.lang.c)
  • Re: Preprocessor possibilities
    ... > Is it possible to write a macro (in unextended C89) such that ... > TEST(int, (1,2,3)); ... > expands to ...
    (comp.lang.c)
  • Re: time()
    ... What does int sum ... The first #define defines a macro that expands into the macro argument ... macro that uses the first macro to change it's argument into a string. ...
    (comp.lang.c)
  • Re: Preprocessor possibilities
    ... > Is it possible to write a macro (in unextended C89) such that ... > TEST(int, (1,2,3)); ... > expands to ...
    (comp.lang.c)
  • Re: Referencing a global array outside a function
    ... > a macro which expands to `3', and use it to both initialize the zeroth ... int array=; ...
    (comp.lang.c)