#include <iostream>
#include <stack>
using namespace std;
// Original function with nested blocks
void F(int n) {
int x = n * 2;
int y = n + 3;
int z = 0;
// Block 1
if (n > 0) {
int a = x + 1;
int b = y - 1;
// Block 2
{
int d = a * 2;
int e = b / 2;
z += d + e;
}
}
// Block 3
if (n > 1) {
int f = y + 10;
int g = x - 5;
z += f - g;
}
cout << "F(" << n << "): " << z << endl;
}
// Iterative implementation with single fb variable
struct ActivationRecord {
int n;
int x, y, z; // Persistent variables
// Temporary variables (only one set used at a time)
int temp1, temp2;
int fb; // Current flattened block (0-3)
ActivationRecord(int n) : n(n), x(0), y(0), z(0), fb(0) {}
};
void G(int n) {
stack<ActivationRecord> st;
st.push(ActivationRecord(n));
while (!st.empty()) {
ActivationRecord& ar = st.top();
switch (ar.fb) {
case 0: // Initialization
ar.x = ar.n * 2;
ar.y = ar.n + 3;
ar.z = 0;
ar.fb = 1;
break;
case 1: // Block 1
if (ar.n > 0) {
ar.temp1 = ar.x + 1; // a
ar.temp2 = ar.y - 1; // b
ar.fb = 2;
} else {
ar.fb = 3;
}
break;
case 2: // Block 2
{
int d = ar.temp1 * 2; // using temp1 as a
int e = ar.temp2 / 2; // using temp2 as b
ar.z += d + e;
ar.fb = 3;
break;
}
case 3: // Block 3
if (ar.n > 1) {
ar.temp1 = ar.y + 10; // f
ar.temp2 = ar.x - 5; // g
ar.z += ar.temp1 - ar.temp2;
}
cout << "G(" << ar.n << "): " << ar.z << endl;
st.pop();
break;
}
}
}
int main() {
cout << "Original function F():\n";
for (int i = 0; i < 5; i++) F(i);
cout << "\nIterative version G():\n";
for (int i = 0; i < 5; i++) G(i);
return 0;
}