Thread: Eval() in C?
View Single Post
  #6   Spotlight this post!  
Unread 07-01-2008, 09:45
AndrewN's Avatar
AndrewN AndrewN is offline
it's alive!
AKA: Andrew Nicholson
FRC #1778 (Chill Out)
Team Role: Mentor
 
Join Date: Jan 2007
Rookie Year: 2006
Location: Edmonds, WA
Posts: 48
AndrewN is just really niceAndrewN is just really niceAndrewN is just really niceAndrewN is just really niceAndrewN is just really nice
Re: Eval() in C?

Quote:
Originally Posted by CapnKernel View Post
I basically want to be able to store a string in a struct and then be able to call that method when "the time is right." It's almost like Flash's event based structure, so I can't really have separate if statements for every string.
The way to do this in C is to do the command matching yourself and use function pointers to store a table of the functions you want to use.

The following code compiles with ANSI C. While running it waits for individual characters. If the character matches the command character 'cmd' then it de-references the function pointer, and calls the function. It passes no arguments onto the called function. (Hint: that's an exercise for you).

Code:
#include <stdlib.h>
#include <stdio.h>

// Four command functions. They must have identical arguments.

void go_left(void) { printf("Going Left\n"); }
void go_right(void) { printf("Going Right\n"); }
void stop(void) { printf("Stopped\n"); }
void quit(void) { printf("Bye\n"); exit(0); }

// An array of a two value structures.

struct {
    char cmd;			// The character
    void (*function)(void);	// a pointer to a function.
} commands[] = {
    {'l', &go_left},	// put the address of the function
    {'r', &go_right},	// into the function pointer
    {'s', &stop},
    {'q', &quit},
    {0, 0}		// marks the end of the array.
};

int
main(void) {
    char c; int i;

    while (1) {
        c = getchar();	// not available on FRC
        i = 0;
        while (commands[i].cmd) {
	    if (commands[i].cmd == c) {
		// dereference the pointer and call the function.
                // note the bracketing
		(*(commands[i].function))();
            }
	    i++;
        }
    }
}
You could obviously extend this to match whole strings instead of characters.

You do not have a "getchar()" function in the FRC code instead you'll have to read a character from one of the serial ports.

The above code is not pretty, badly commented, terse, and follows an arcane indenting style (I'm old).

You should use 'typedef' to define the structure instead of using it inline like this.

The structure is initialized after the command functions have been declared. If the command functions are in another file then you'll have to use 'extern' declarations of the functions before initializing the array.

A sample run:
Code:
$ cc ex1.c
$ ./a.out
l
Going Left
r
Going Right
q
Bye
$
__________________
Andrew Nicholson
2011 FRC Robot Inspector (Seattle, Portland)
Mentor FRC 1778 "Chill Out", FTC 3018, 3940 "Hawks", 4434 "Heat Misers"

"Everything should be made as simple as possible, but no simpler."