On Thu, 08 May 2008, frank van nuffel wrote: Hi Frank,
[...] > For whomever wonders what applicability pp evaluation precedence > modification is useful for, here's a quick idea regarding how to define pp > macro's that are suspendable and resumable at specific places in source > code, and that avoid to also substitute a corresponding function definition, > for the case where this macro was suspended, leading to the effect that the > macro behaves just like a normal function call (for which the corresponding > function needs to be defined somewhere) > > --- system definitions ----- > > #xTRAN ppparam( , <f>, <b>, [<a,...>] ) => ; > PPIIF( %% _SUSPEND_(), <f>(<a>,), <b> ) > > // removing %% in line above leads to wrong results > > # TRAN function ppparam( , <f>, <b>, ) => func <f> > # TRAN function ppparam( , <f>, <b>, <a,...> ) => func <f> ; PARAM <a> > > # TRAN procedure ppparam( , <f>, <b>, ) => proc <f> > # TRAN procedure ppparam( , <f>, <b>, <a,...> ) => proc <f> ; PARAM <a> > > #xCOMM MACRO SECTION BEGIN => #undef _EXPAND_ > #xCOMM MACRO <f>( [ <a,...> ] ) <b> => #define <f>( <a> ) ; > ppparam( _EXPAND_(), <f>, <b>, <a> ) > #xCOMM MACRO SECTION END => #define _EXPAND_() > > #xCOMM MACRO SUSPEND => #xTRAN _SUSPEND_\\() => .T. > #xCOMM MACRO RESUME => #xTRAN _SUSPEND_\\() => .F. > > #xTRAN _SUSPEND_() => .F. > > #xTRAN %% => > > #xTRAN PPIIF( <x>, <a>, <b> ) => <b> > #xTRAN PPIIF( .T. , <a>, <b> ) => <a> In this example using 1_ instead of %% also works anyhow it can be written in simpler way. But first please note that in Clipper it's not possible to use #undef <NAME> inside result pattern because if <NAME> is defined then it is substituted. I can only guess that the above is some type of mixed Clipper and old PP code. If you want to use #undef in such way using Clipper's PP then you have to put it in a separate file and use #include directive. Now alternative version: --- system definitions ----- #xCOMM MACRO SECTION BEGIN => #undef _EXPAND_ #xCOMM MACRO <f>( [ <a,...> ] ) <b> => #define <f>( <a> ) ; ppparam( _EXPAND_ <f> | <b>, <a> ) #xCOMM MACRO SECTION END => #define _EXPAND_ #xCOMM MACRO SUSPEND => #undef _EXPAND_ #xCOMM MACRO RESUME => #define _EXPAND_ #xTRAN ppparam( _EXPAND_ <f> | <b> [, <a,...>] ) => <b> #xTRAN ppparam( <f> | <b> [, <a,...>] ) => <f>( <a>, ) # TRAN function ppparam( [_EXPAND_] <f> | <b> [, <a,...>] ) => ; func <f> ; PARAM <a> # TRAN procedure ppparam( [_EXPAND_] <f> | <b> [, <a,...>] ) => ; func <f> ; PARAM <a> --- end of system definitions ----- It gives the same results is much faster and IMHO simpler. It's for Harbour only. If you want to adopt it to Clipper then you have to make the trick with #include I've written above: create file undef.ch with one line: #undef _EXPAND_ and in the above code change: #undef _EXPAND_ to: #include "undef.ch" Such tricks makes also class(y).ch I intentionally haven't used TRANS rules because each time you call MACRO SUSPEND / MACRO RESUME new rules are added and the PP table is systematically growing up reducing the memory for compiler and slowing the preprocessing. Clipper's PP does not have #untrans directive. But if you change it to use TRANS then it will not be necessary to make the trick with #include. > since neither in ca-clipper/harbour it is possible to apply P.J. Plauger's > suggestion to avoid macro defines to trigger upon corresponding function > definitions as he does in his C implementations, the only viable alternative > i've found so far, is sth like above; in C it is enough to do: > > #define someMacro( a, b ) a+b > > int (someMacro)( int a, int b ) // definition (guarded against substitution) > { ... In this code you make two different tricks to disable infinite translation. 1-st you added additional dummy parameter to function call so instead of fun2( 3, 5 ) we have fun2( 3, 5, ) and this is not recognized by #define declaration 2-nd for function declaration you moved parameters to PARAM statement. Such tricks are possible if you have alternative syntax which is not affected by your PP rules. Just like the above trick in C which is also for one situation only and resolves the problem by alternative code. If you need general solution then we should introduce new PP token which is significant for PP but neutral for compiler. F.e. <-> as result marker. #trans func( <a,...> ) => func( <-> 1, <a> ) The <-> in result pattern will block infinite translation and because it will be invisible for compiler then it will not break compilation process. I can add such marker in the future. best regards, Przemek _______________________________________________ Harbour mailing list Harbour@harbour-project.org http://lists.harbour-project.org/mailman/listinfo/harbour