/* 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 unsigned check_under(void)
{
	unsigned p = pointer;
	if (p == 0)
		bb_simple_error_msg_and_die("stack underflow");
	return p - 1;
}

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

static double pop(void)
{
	unsigned p = check_under();
	pointer = p;
	return stack[p];
}

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();

	/* compat with dc (GNU bc 1.07.1) 1.4.1:
	 * $ dc -e '4 0 % p'
	 * dc: remainder by zero
	 * 0
	 */
	if (d == 0) {
		bb_error_msg("remainder by zero");
		pop();
		push(0);
		return;
	}
	/* ^^^^ without this, we simply get SIGFPE and die */

	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)
{
	print_base(stack[check_under()]);
}

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;
}
