ais523 said:
BartC wrote:
The only way I can think of offhand involves using indexes into arrays
of function pointers; you do arithmetic to choose a "next function" to
call, then index the array to call one of multiple functions without
any conditionals inovlved. You could create loops using recursion.
You're right of course. I've just had a go at something along those lines
(see code below).
The function testfn() is what I'm trying to execute without using any
control flow statements or conditional (?
expressions. It's a silly loop
that outputs the sequence 0 1 2 3 4 5 8 9 10.
The first step was to convert into the set of 'flat' statements shown in
testfnflat(), although at this point it still uses the if and goto
statements (now also paired as if-goto) that I prefer.
Then, each line is put into its own function, an array of those functions is
created (program[]), and a 'program counter' is set up in pc (an index into
the function array). If-goto pairs have to be transformed.
'Control flow' inside this 'function' (since this is now disseminated
throughout the file, and any local variables have become globals), is done
by manipulating the value of pc through arithmetic.
The function dispatch loop was turned into recursive calls, relying on an
exit(0) in the code to execution (I suppose a stop flag is simple enough
too).
It worked. Although it is more now of a little virtual machine to execute
the code, rather than executing it directly.
#include <stdio.h>
#include <stdlib.h>
void testfn (void)
{int i;
i=0;
while (1) {
printf("%d ",i);
if (i==10) break;
if (i==5)
i=i+3;
else
++i;
}
}
void testfnflat (void)
{int i;
i=0; // line 1
L1: // line 2
printf("%d ",i); // line 3
if (i==10) goto L2; // line 4
if (i!=5) goto L3; // line 5
i=i+3; // line 6
goto L4; // line 7
L3: // line 8
++i; // line 9
L4: // line 10
goto L1; // line 11
L2: // line 12
; // (Why? read OP...)
}
int pc=1;
int i;
void line1(void) {i=0; ++pc;}
void line2(void) {++pc;}
void line3(void) {printf("%d ",i); ++pc;}
void line4(void) {pc=(i==10)*12+(i!=10)*(pc+1);}
void line5(void) {pc=(i!=5)*8+(i==5)*(pc+1);}
void line6(void) {i=i+3; ++pc;}
void line7(void) {pc=10;}
void line8(void) {++pc;}
void line9(void) {++i; ++pc;}
void line10(void) {++pc;}
void line11(void) {pc=2;}
void line12(void) {exit(0);}
void* program[] = {NULL, line1, line2, line3, line4, line5, line6,
line7, line8, line9, line10, line11, line12};
void execute(void) {
typedef void (*(fnptr))(void);
(*(fnptr)(program[pc]))();
execute();
}
int main (void) {
execute();
}