#include	<stdio.h>
#include	<string.h>

#define MAX_BUF	80

int add(int arg1, int arg2)	{ return arg1 + arg2; }
int sub(int arg1, int arg2)	{ return arg1 - arg2; }
int mul(int arg1, int arg2)	{ return arg1 * arg2; }
int div(int arg1, int arg2)	{ return arg1 / arg2; }
int and(int arg1, int arg2)	{ return arg1 & arg2; }
int  or(int arg1, int arg2)	{ return arg1 | arg2; }

typedef int (*t_op_func)(int, int);

typedef struct  {
	char     *op_name;
	t_op_func op_func;
} t_dispatch;

/* declare the dispatch_lookup function */
t_op_func dispatch_lookup(char *, char **, int);


int main()
{
	char		 buffer[MAX_BUF + 1];
	char		 op_name[MAX_BUF + 1];
	int		 arg1, arg2;
	t_op_func	 fp;
	char		*err;

	printf("> ");
	while (fgets(buffer, sizeof(buffer), stdin) != NULL) {
		if (sscanf(buffer, "%d %s %d", &arg1, op_name, &arg2) != 3)
			fprintf(stderr, "Invalid input.\n");
		else if ((fp = dispatch_lookup(op_name, &err, arg2)) != NULL)
			printf("%d\n", (*fp)(arg1, arg2));
		else
			fprintf(stderr, err);
		printf("> ");
	}
	return 0;
}

t_op_func dispatch_lookup(char *op_name, char **err, int arg2)
{
	t_dispatch dispatch[] = {
		{ "+",	add }, { "-",	sub }, 
		{ "*",	mul }, { "/",	div },
		{ "&",	and }, { "|",	 or }
	};
	int		i;
	static char	error[MAX_BUF + 20 + 1];

	for (i = 0; i < sizeof(dispatch) / sizeof(dispatch[0]); i++) {
		if (strcmp(dispatch[i].op_name, op_name) == 0) {
			if (strcmp(op_name, "/") == 0 && arg2 == 0) {
				*err = "Division by 0\n";
				return NULL;
			}
			*err = NULL;
			return dispatch[i].op_func;
		}
	}
	sprintf(error, "Invalid operator: %s\n", op_name);
	*err = error;
	return NULL;
}
