macros with parameters

classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

macros with parameters

Marc Santhoff
Hi,

the docs only show examples of macros without any parameters. Is it
possible to use them?

Can I make this work anyhow:

{$MACRO ON}
{$define HOFFSET(rec,field) := pointer(@rec.field) - pointer(@rec)}

type
        s1_t = record
                a: longint;
                b: single;
                c: double;
        end;
var
        s1: s1_t;
BEGIN
        s1.a := 12345;
        s1.b := 1.000000001;
        s1.c := 1.000000002;

        writeln(HOFFSET(s1, a)); { Line 32 in my code }
END.

Written as it is the compiler doesn't like it:

$ fpc offsetof
Free Pascal Compiler version 2.0.2 [2005/11/17] for i386
Copyright (c) 1993-2005 by Florian Klaempfl
Target OS: FreeBSD/ELF for i386
Compiling offsetof.pas
offsetof.pas(32,10) Error: Identifier not found "HOFFSET"
offsetof.pas(32,22) Error: Identifier not found "a"
offsetof.pas(32,25) Error: Illegal expression

Other solutions are very welcome...

TIA,
Marc


_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: macros with parameters

Michalis Kamburelis
Marc Santhoff wrote:

> Hi,
>
> the docs only show examples of macros without any parameters. Is it
> possible to use them?
>
> Can I make this work anyhow:
>
> {$MACRO ON}
> {$define HOFFSET(rec,field) := pointer(@rec.field) - pointer(@rec)}
>
> type
> s1_t = record
> a: longint;
> b: single;
> c: double;
> end;
> var
> s1: s1_t;
> BEGIN
> s1.a := 12345;
> s1.b := 1.000000001;
> s1.c := 1.000000002;
>
> writeln(HOFFSET(s1, a)); { Line 32 in my code }
> END.
>
> Written as it is the compiler doesn't like it:
>
> $ fpc offsetof
> Free Pascal Compiler version 2.0.2 [2005/11/17] for i386
> Copyright (c) 1993-2005 by Florian Klaempfl
> Target OS: FreeBSD/ELF for i386
> Compiling offsetof.pas
> offsetof.pas(32,10) Error: Identifier not found "HOFFSET"
> offsetof.pas(32,22) Error: Identifier not found "a"
> offsetof.pas(32,25) Error: Illegal expression
>
> Other solutions are very welcome...
>

Macros with parameters are not supported, AFAIK. I always workaround it
by employing the fact that macros within macros are expanded. So instead of

  {$define HOFFSET(rec,field) := pointer(@rec.field) - pointer(@rec)}

you can define parameter-less macro like

  {$define HOFFSET := pointer(@HOFFSET_rec.HOFFSET_field) -
pointer(@HOFFSET_rec)}

(I prefix macro params with "HOFFSET_" just for safety, you could as
well just use original "rec" and "field" identifiers). And then to use
it, instead of

  writeln(HOFFSET(s1, a));

you can write

  {$define HOFFSET_rec := s1}
  {$define HOFFSET_field := a}
  writeln(HOFFSET);

This way you get behavior of macros with parameters. Admittedly, this
looks clumsy, but at least works.

Michalis
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: macros with parameters

Marc Santhoff
Am Mittwoch, den 20.09.2006, 00:55 +0200 schrieb Michalis Kamburelis:

> Marc Santhoff wrote:
> > Hi,
> >
> > the docs only show examples of macros without any parameters. Is it
> > possible to use them?
> >
> > Can I make this work anyhow:
> >
> > {$MACRO ON}
> > {$define HOFFSET(rec,field) := pointer(@rec.field) - pointer(@rec)}
> >
> > type
> > s1_t = record
> > a: longint;
> > b: single;
> > c: double;
> > end;
> > var
> > s1: s1_t;
> > BEGIN
> > s1.a := 12345;
> > s1.b := 1.000000001;
> > s1.c := 1.000000002;
> >
> > writeln(HOFFSET(s1, a)); { Line 32 in my code }
> > END.
> >
> > Written as it is the compiler doesn't like it:
> >
> > $ fpc offsetof
> > Free Pascal Compiler version 2.0.2 [2005/11/17] for i386
> > Copyright (c) 1993-2005 by Florian Klaempfl
> > Target OS: FreeBSD/ELF for i386
> > Compiling offsetof.pas
> > offsetof.pas(32,10) Error: Identifier not found "HOFFSET"
> > offsetof.pas(32,22) Error: Identifier not found "a"
> > offsetof.pas(32,25) Error: Illegal expression
> >
> > Other solutions are very welcome...
> >
>
> Macros with parameters are not supported, AFAIK.

Heavy grep'ing found some files with single parameter macros, so in
principle it may work.

> I always workaround it
> by employing the fact that macros within macros are expanded. So instead of
>
>   {$define HOFFSET(rec,field) := pointer(@rec.field) - pointer(@rec)}
>
> you can define parameter-less macro like
>
>   {$define HOFFSET := pointer(@HOFFSET_rec.HOFFSET_field) -
> pointer(@HOFFSET_rec)}
>
> (I prefix macro params with "HOFFSET_" just for safety, you could as
> well just use original "rec" and "field" identifiers). And then to use
> it, instead of
>
>   writeln(HOFFSET(s1, a));
>
> you can write
>
>   {$define HOFFSET_rec := s1}
>   {$define HOFFSET_field := a}
>   writeln(HOFFSET);
>
> This way you get behavior of macros with parameters. Admittedly, this
> looks clumsy, but at least works.

This does not do what I need, the goal is to pass arbitrary record
variables and contained field names for calculating the offset in byte
of the field from the start of the record.

I've started trying by making it a function but found no way to declare
the function parameters for passing any record type without casting.

I'll try thinking about recursive macros some more, maybe there is a
soolution in that direction ...

Thanks a lot,
Marc


_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: macros with parameters

Marc Santhoff
In reply to this post by Michalis Kamburelis
Hi again,

I've forgotten to give a pointer:

<rtl/os2/pmgpi.pas:761>
{$define BYTE_ORDER(oc):=((oc)=OCODE_GNOP1 or (oc)=OCODE_GESD)}
<--->

Marc


_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal