/*
	@author herumi

	tiny calculator
	This program generates a function to calc the value of
	polynomial given by user in run-time.
	use boost::spirit::classic
	see calc2.cpp for new version of boost::spirit
*/
#include <stdio.h>
#include <sstream>
#include <map>
#include "xbyak/xbyak.h"
#ifdef _MSC_VER
	#pragma warning(disable : 4127) // for boost(constant condition)
	#pragma warning(disable : 4512) // for boost
#endif
#include <boost/spirit/include/classic_file_iterator.hpp>
#include <boost/spirit/include/classic_core.hpp>
#include <boost/bind.hpp>

enum Error {
	UNDEFINED_VARIABLE = 1
};

/*
	JIT assemble of given polynomial for VC or gcc
*/
class FuncGen : public Xbyak::CodeGenerator {
public:
	typedef std::map<std::string, int> Map;
private:
	enum {
		MAX_CONST_NUM = 32
	};
	double constTbl_[MAX_CONST_NUM];
	size_t constTblPos_;
	int regIdx_;
	Map varMap_; // map var name to index
	const Xbyak::Reg32e& valTbl_;
	const Xbyak::Reg32e& tbl_;
public:
	/*
		@param y [out] the value of f(var)
		@param var [in] table of input variables
		func(double *y, const double var[]);
		@note func does not return double to avoid difference of compiler
	*/
	FuncGen(const std::vector<std::string>& varTbl)
		: constTblPos_(0)
		, regIdx_(-1)
#ifdef XBYAK32
		, valTbl_(eax)
		, tbl_(edx)
#elif defined(XBYAK64_WIN)
		, valTbl_(rcx)
		, tbl_(rdx)
#else
		, valTbl_(rdi)
		, tbl_(rsi)
#endif
	{
#ifdef XBYAK32
		mov(valTbl_, ptr[esp+8]); // eax == varTbl
		mov(tbl_, (size_t)constTbl_);
#else
#ifdef XBYAK64_WIN
		movaps(ptr [rsp + 8], xm6); // save xm6, xm7
		movaps(ptr [rsp + 8 + 16], xm7);
#endif
		mov(tbl_, (size_t)constTbl_);
#endif
		for (int i = 0, n = static_cast<int>(varTbl.size()); i < n; i++) {
			varMap_[varTbl[i]] = i;
		}
	}
	// use edx
	void genPush(double n)
	{
		if (constTblPos_ >= MAX_CONST_NUM) throw;
		constTbl_[constTblPos_] = n;
		if (regIdx_ == 7) throw;
		movsd(Xbyak::Xmm(++regIdx_), ptr[tbl_ + constTblPos_ * sizeof(double)]);
		constTblPos_++;
	}
	// use eax
	void genVal(const char *begin, const char *end)
	{
		std::string var(begin, end);
		if (varMap_.find(var) == varMap_.end()) throw UNDEFINED_VARIABLE;
		if (regIdx_ == 7) throw;
		movsd(Xbyak::Xmm(++regIdx_), ptr[valTbl_ + varMap_[var] * sizeof(double)]);
	}
	void genAdd(const char*, const char*)
	{
		addsd(Xbyak::Xmm(regIdx_ - 1), Xbyak::Xmm(regIdx_)); regIdx_--;
	}
	void genSub(const char*, const char*)
	{
		subsd(Xbyak::Xmm(regIdx_ - 1), Xbyak::Xmm(regIdx_)); regIdx_--;
	}
	void genMul(const char*, const char*)
	{
		mulsd(Xbyak::Xmm(regIdx_ - 1), Xbyak::Xmm(regIdx_)); regIdx_--;
	}
	void genDiv(const char*, const char*)
	{
		divsd(Xbyak::Xmm(regIdx_ - 1), Xbyak::Xmm(regIdx_)); regIdx_--;
	}
	void complete()
	{
#ifdef XBYAK32
		mov(eax, ptr [esp + 4]); // eax = valTbl
		movsd(ptr [eax], xm0);
#else
#ifdef XBYAK64_WIN
		movaps(xm6, ptr [rsp + 8]);
		movaps(xm7, ptr [rsp + 8 + 16]);
#endif
#endif
		ret();
	}
};

struct Grammar : public boost::spirit::classic::grammar<Grammar> {
	FuncGen& f_;
	Grammar(FuncGen& f) : f_(f) { }
	template<typename ScannerT>
	struct definition {
		boost::spirit::classic::rule<ScannerT> poly0, poly1, poly2, var;

		definition(const Grammar& self)
		{
			using namespace boost;
			using namespace boost::spirit::classic;

			poly0 = poly1 >> *(('+' >> poly1)[bind(&FuncGen::genAdd, ref(self.f_), _1, _2)]
			                 | ('-' >> poly1)[bind(&FuncGen::genSub, ref(self.f_), _1, _2)]);
			poly1 = poly2 >> *(('*' >> poly2)[bind(&FuncGen::genMul, ref(self.f_), _1, _2)]
			                 | ('/' >> poly2)[bind(&FuncGen::genDiv, ref(self.f_), _1, _2)]);
			var = (+alpha_p)[bind(&FuncGen::genVal, ref(self.f_), _1, _2)];
			poly2 = real_p[bind(&FuncGen::genPush, ref(self.f_), _1)]
				| var
				| '(' >> poly0 >> ')';
		}
		const boost::spirit::classic::rule<ScannerT>& start() const { return poly0; }
	};
};

void put(const std::vector<double>& x)
{
	printf("%f", x[0]);
	for (size_t i = 1, n = x.size(); i < n; i++) {
		printf(", %f", x[i]);
	}
}

int main(int argc, char *argv[])
{
	if (argc <= 2) {
		fprintf(stderr, "calc \"var1 var2 ...\" \"function of var\"\n");
		fprintf(stderr, "eg. calc x \"x*x\"\n");
		fprintf(stderr, "eg. calc \"x y z\"  \"x*x + y - z\"\n");
		return 1;
	}
	const char *poly = argv[2];
	try {
		std::vector<std::string> varTbl;

		// get varTbl from argv[1]
		{
			std::istringstream is(argv[1]);
			int i = 0;
			printf("varTbl = { ");
			while (is) {
				std::string var;
				is >> var;
				if (var.empty()) break;
				printf("%s:%d, ", var.c_str(), i);
				varTbl.push_back(var);
				i++;
			}
			printf("}\n");
		}
		FuncGen funcGen(varTbl);
		Grammar calc(funcGen);
		boost::spirit::classic::parse_info<> r = parse(poly, calc, boost::spirit::classic::space_p);
		if (!r.full) {
			printf("err poly=%s\n", poly);
			return 1;
		}
		funcGen.complete();
		std::vector<double> valTbl;
		valTbl.resize(varTbl.size());
#ifdef XBYAK32
		puts("32bit mode");
		void (*func)(double *ret, const double *valTbl) = (void (*)(double *, const double*))(const void*)funcGen.getCode();
#else
		puts("64bit mode");
		double (*func)(const double *valTbl) = (double (*)(const double*))(const void*)funcGen.getCode();
#endif
		for (int i = 0; i < 10; i++) {
			for (size_t j = 0, n = valTbl.size(); j < n; j++) {
				valTbl[j] = rand() % 7;
			}
			double y;
#ifdef XBYAK32
			func(&y, &valTbl[0]);
#else
			y = func(&valTbl[0]);
#endif
			printf("f("); put(valTbl); printf(")=%f\n", y);
		}
	} catch (Xbyak::Error err) {
		printf("ERR:%s(%d)\n", Xbyak::ConvertErrorToString(err), err);
	} catch (Error err) {
		printf("ERR:%d\n", err);
	} catch (...) {
		printf("unknown error\n");
	}

	return 0;
}
