/* vi: set sw=4 ts=4: */
/*
 * Licensed under GPLv2 or later, see file LICENSE in this source tree.
 */

/* config/applet/usage bits are in bc.c */

//#include "libbb.h"
//#include "common_bufsiz.h"
#include <math.h>

#if 0
typedef unsigned data_t;
#define DATA_FMT ""
#elif 0
typedef unsigned long data_t;
#define DATA_FMT "l"
#else
typedef unsigned long long data_t;
#define DATA_FMT "ll"
#endif

struct globals {
	unsigned pointer;
	unsigned base;
	double stack[1];
} FIX_ALIASING;
enum { STACK_SIZE = (COMMON_BUFSIZE - offsetof(struct globals, stack)) / sizeof(double) };
#define G (*(struct globals*)bb_common_bufsiz1)
#define pointer   (G.pointer   )
#define base      (G.base      )
#define stack     (G.stack     )
#define INIT_G() do { \
	setup_common_bufsiz(); \
	base = 10; \
} while (0)

static void check_under(void)
{
	if (pointer == 0)
		bb_error_msg_and_die("stack underflow");
}

static void push(double a)
{
	if (pointer >= STACK_SIZE)
		bb_error_msg_and_die("stack overflow");
	stack[pointer++] = a;
}

static double pop(void)
{
	check_under();
	return stack[--pointer];
}

static void add(void)
{
	push(pop() + pop());
}

static void sub(void)
{
	double subtrahend = pop();

	push(pop() - subtrahend);
}

static void mul(void)
{
	push(pop() * pop());
}

#if ENABLE_FEATURE_DC_LIBM
static void power(void)
{
	double topower = pop();

	push(pow(pop(), topower));
}
#endif

static void divide(void)
{
	double divisor = pop();

	push(pop() / divisor);
}

static void mod(void)
{
	data_t d = pop();

	push((data_t) pop() % d);
}

static void and(void)
{
	push((data_t) pop() & (data_t) pop());
}

static void or(void)
{
	push((data_t) pop() | (data_t) pop());
}

static void eor(void)
{
	push((data_t) pop() ^ (data_t) pop());
}

static void not(void)
{
	push(~(data_t) pop());
}

static void set_output_base(void)
{
	static const char bases[] ALIGN1 = { 2, 8, 10, 16, 0 };
	unsigned b = (unsigned)pop();

	base = *strchrnul(bases, b);
	if (base == 0) {
		bb_error_msg("error, base %u is not supported", b);
		base = 10;
	}
}

static void print_base(double print)
{
	data_t x, i;

	x = (data_t) print;
	if (base == 10) {
		if (x == print) /* exactly representable as unsigned integer */
			printf("%"DATA_FMT"u\n", x);
		else
			printf("%g\n", print);
		return;
	}

	switch (base) {
	case 16:
		printf("%"DATA_FMT"x\n", x);
		break;
	case 8:
		printf("%"DATA_FMT"o\n", x);
		break;
	default: /* base 2 */
		i = MAXINT(data_t) - (MAXINT(data_t) >> 1);
		/* i is 100000...00000 */
		do {
			if (x & i)
				break;
			i >>= 1;
		} while (i > 1);
		do {
			bb_putchar('1' - !(x & i));
			i >>= 1;
		} while (i);
		bb_putchar('\n');
	}
}

static void print_stack_no_pop(void)
{
	unsigned i = pointer;
	while (i)
		print_base(stack[--i]);
}

static void print_no_pop(void)
{
	check_under();
	print_base(stack[pointer-1]);
}

struct op {
	const char name[4];
	void (*function) (void);
};

static const struct op operators[] = {
#if ENABLE_FEATURE_DC_LIBM
	{"^",   power},
//	{"exp", power},
//	{"pow", power},
#endif
	{"%",   mod},
//	{"mod", mod},
	// logic ops are not standard, remove?
	{"and", and},
	{"or",  or},
	{"not", not},
	{"xor", eor},
	{"+",   add},
//	{"add", add},
	{"-",   sub},
//	{"sub", sub},
	{"*",   mul},
//	{"mul", mul},
	{"/",   divide},
//	{"div", divide},
	{"p", print_no_pop},
	{"f", print_stack_no_pop},
	{"o", set_output_base},
};

/* Feed the stack machine */
static void stack_machine(const char *argument)
{
	char *end;
	double number;
	const struct op *o;

 next:
	number = strtod(argument, &end);
	if (end != argument) {
		argument = end;
		push(number);
		goto next;
	}

	/* We might have matched a digit, eventually advance the argument */
	argument = skip_whitespace(argument);

	if (*argument == '\0')
		return;

	o = operators;
	do {
		char *after_name = is_prefixed_with(argument, o->name);
		if (after_name) {
			argument = after_name;
			o->function();
			goto next;
		}
		o++;
	} while (o != operators + ARRAY_SIZE(operators));

	bb_error_msg_and_die("syntax error at '%s'", argument);
}

static void process_file(FILE *fp)
{
	char *line;
	while ((line = xmalloc_fgetline(fp)) != NULL) {
		stack_machine(line);
		free(line);
	}
}

int dc_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
int dc_main(int argc UNUSED_PARAM, char **argv)
{
	bool script = 0;

	INIT_G();

	/* Run -e'SCRIPT' and -fFILE in order of appearance, then handle FILEs */
	for (;;) {
		int n = getopt(argc, argv, "e:f:");
		if (n <= 0)
			break;
		switch (n) {
		case 'e':
			script = 1;
			stack_machine(optarg);
			break;
		case 'f':
			script = 1;
			process_file(xfopen_for_read(optarg));
			break;
		default:
			bb_show_usage();
		}
	}
	argv += optind;

	if (*argv) {
		do
			process_file(xfopen_for_read(*argv++));
		while (*argv);
	} else if (!script) {
		/* Take stuff from stdin if no args are given */
		process_file(stdin);
	}

	return EXIT_SUCCESS;
}
