/*
 * This program demonstrates the use of function
 * pointers in a (very simple) lookup table.
 *
 * Operators in an expression are used to select
 * the appropriate function to be executed.
 */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <readline/readline.h>

#define PROMPT "> "
#define SEP " \t"
#define N 4

/*
 * A type definition for function pointers.
 */
typedef int (*fnptr)(int, int);

int sum(int x, int y){ return x+y; }
int mul(int x, int y){ return x*y; }
int sub(int x, int y){ return x-y; }
int dvs(int x, int y){ return x/y; }

/*
 * Array "table" provides an association among
 * strings and functions.
 */
struct {
  char * name;
	int (*fun)(int, int);
} table[N] = {
  { "+", sum },
	{ "*", mul },
	{ "-", sub },
  { "/", dvs },
};

/*
 * The lookup function demonstrates one way to
 * return a function pointer.
 * It is also possible to re-write the same code as:
 *
 * int (*lookup(char *name))(int, int){
 */
fnptr lookup(char *name){
	int i;
  for(i=0; i<N; i++) {
	 	if (strcmp(table[i].name, name)==0) 
			return table[i].fun;
	}
	return NULL;
}

int main(){
	char *command;
	char *c;
	int a, b;
	int (*function)(int, int);	
	while(1){
		command = readline(PROMPT);
		c = strtok(command,SEP);
		function = lookup(c);
		if (!function) exit(0);
		a = atoi(strtok(NULL,SEP));
		b = atoi(strtok(NULL,SEP));
		printf("%d\n",function(a,b));
		free(command);
	}
}
