vz0
vz0

Reputation: 32923

Compiling a for statement from BASIC to C++

I'm writing a compiler to migrate some legacy VB6 program to C++. I need to translate a for statement in the VB6 language into a C++ for statement:

For var = start To end Step S
  ...
Next var

The naive translation will not work since S might be negative:

for (var = start; var <= end; var += S) 

I've came up with this translation but the ternary if in the condition is ugly:

for (var = start; (S > 0) ? (var <= end) : (var >= end); var += S)

Upvotes: 0

Views: 103

Answers (2)

Jan Hudec
Jan Hudec

Reputation: 76296

It's a generated code. You'll only ever be looking at it when debugging the code generator. So it's totally irrelevant if it's ugly. It only matters if it is correct and then the simpler it is to generate, the better.


Update: However, if it's a migration, it might indeed make sense to try to make the code readable. Then I'd either:

  1. Resolve the operator to use in the translator if possible, since the step is almost always constant.
  2. Hide the logic in auxiliary definition and use a range-based for:

    for(auto var : basic_range(start, end, S))
    

    Unfortunately boost::irange did not make it to C++11 and it is defined using half-open range as usual for C++, i.e. end is not included while you want to include it. So you have to define the range yourself. Basically you'd just hide the direction logic in it, so it does not obscure the code. Look at the boost::irange for inspiration.

The largest issue would be object lifecycle anyway. VB6 (unlike earlier BASICs) is managed. So you'll probably end up using smart pointers for most things and it's not the most efficient thing to do.

Upvotes: 1

thus spake a.k.
thus spake a.k.

Reputation: 1637

You can avoid a ternary expression in the termination condition if you multiply var and end by the sign of S

int sign = S>=0 ? 1 : -1;
for (int var = start; sign*var <= sign*end; var += S)
{
    //...
}

Upvotes: 0

Related Questions