C-like for() statement using macros

Source-code only - please, don't post questions here.
counting_pine
Site Admin
Posts: 5941
Joined: Jul 05, 2005 17:32
Location: Manchester, Lancs

C-like for() statement using macros

Postby counting_pine » Jul 19, 2018 12:40

This is a 'CFOR' macro that on use, runs the 'start' statement and sets up a while loop. It also creates a corresponding 'CNEXT_' macro - which is used for running the 'step' and marking the end of the loop.

Unfortunately you cannot nest CFOR statements, because CNEXT_ can only hold one definition. On the plus side, the macro is designed to prevent nesting attempts from compiling:

- CFOR expects the CNEXT_ macro not to exist. If you try to nest CFOR (and the 'step' statement is different), you will get a Duplicated Definition error.
- CNEXT_ #undef's itself when used, ensuring that it can't be used afterwards without using CFOR again.

For convenience, a CNEXT #define is also included, to prevent having to put '()' after it.

A couple of examples:

Code: Select all

#macro CFOR(start,cond,step)
  #macro CNEXT_()
    step
    wend
    #undef CNEXT_
  #endmacro
start: while cond
#endmacro
#define CNEXT CNEXT_()

dim i as integer

CFOR(i = 0, i < 10, i += 1)
  print i
CNEXT
print

CFOR(i = 1, i <= 256, i shl= 1)
  print i
CNEXT
Pritchard
Posts: 5442
Joined: Sep 12, 2005 20:06
Location: Ohio, USA

Re: C-like for() statement using macros

Postby Pritchard » Jul 21, 2018 7:06

Excuse the formatting. I'm using https://www.jdoodle.com/execute-freebasic-online to write and test this with.

I'd consider 6 levels deep sufficient for most programs. If you're using this to assist with automated conversions, I would consider it...

Code: Select all

#macro CFOR(start,cond,step)
  #ifndef CNEXT_
      #macro CNEXT_()
        step
        wend
        #undef CNEXT_
      #endmacro
  #else
    #ifndef CNEXT2_
      #macro CNEXT2_()
        step
        wend
        #undef CNEXT2_
      #endmacro
      #else
    #ifndef CNEXT3_
      #macro CNEXT3_()
        step
        wend
        #undef CNEXT3_
      #endmacro
    #endif
    #endif
  #endif
start: while cond
#endmacro
#macro CNEXT_exec()
    #ifndef CNEXT2_
        CNEXT_()
    #else
        #ifndef CNEXT3_
            CNEXT2_()
            #else
        #ifndef CNEXT4_
            CNEXT3_()
        #endif
        #endif
    #endif
#endmacro
#define CNEXT CNEXT_exec()

dim i as integer
dim j as integer
dim k as integer

CFOR(i = 1, i < 3, i += 1)
    print i
    CFOR(j = 1, j < 3, j += 1)
        print i*j
        CFOR(k = 1, k < 3, k += 1)
            print i*j*k
        CNEXT
    CNEXT
CNEXT
print

CFOR(i = 1, i <= 256, i shl= 1)
  print i
CNEXT


Output:

Code: Select all

 1
 1
 1
 2
 2
 2
 4
 2
 2
 2
 4
 4
 4
 8

 1
 2
 4
 8
 16
 32
 64
 128
 256


Would be neat to look here: https://www.boost.org/doc/libs/1_45_0/l ... index.html

And do something like this: https://www.boost.org/doc/libs/1_45_0/l ... slots.html

But tbh that stuff is giving me a headache trying to reason about it. I *think* I comprehend the article itself, but I don't think I could actually implement it in a spare time's worth of experimentation.

EDIT: Skimming Boost's source code and it's surprisingly naive. I think what's above is close to the right approach. You can define more macros to help you uh... define more macros... so like this pattern can be abstracted out a bit, but that seems to only be useful for the purpose of having a mechanism for defining other recursive / repetitive macros. Not sure we need any more layers of abstraction for this...
counting_pine
Site Admin
Posts: 5941
Joined: Jul 05, 2005 17:32
Location: Manchester, Lancs

Re: C-like for() statement using macros

Postby counting_pine » Jul 25, 2018 19:37

Hey, thanks Pritchard, that’s a pretty neat extension of the idea. I didn’t think of that.
It’s interesting to see what the preprocessor can be capable of.
IchMagBier
Posts: 25
Joined: Jan 13, 2018 8:47

Re: C-like for() statement using macros

Postby IchMagBier » Aug 08, 2018 2:53

I use python-like for loops in my codes. I guess that's easier to achieve.

Code: Select all

#define in(start,end) as integer=start to end

for i in(0,10)
   print i
next
dafhi
Posts: 1040
Joined: Jun 04, 2005 9:51

Re: C-like for() statement using macros

Postby dafhi » Aug 10, 2018 2:31

nice one, counting_pine! .. atm i'm experimenting with

wfor(i, 1, 10)
wend

Return to “Tips and Tricks”

Who is online

Users browsing this forum: No registered users and 1 guest