Exemple #1
0
double Calculator::parseSymbol(std::string_view &ref)
{
	double value = 0;
	skipSpaces(ref);
	if (!ref.empty() && ref[0] == '(')
	{
		ref.remove_prefix(1);
		value = parseExprSum(ref);
		skipSpaces(ref);
		if (!ref.empty() && ref[0] == ')')
		{
			ref.remove_prefix(1);
			return value;
		}
		else
		{
			return std::numeric_limits<double>::quiet_NaN();
		}
	}
	else if (!ref.empty() && !std::isdigit(ref[0]) && ref[0] != '-')
	{
		return parseFunction(ref);
	}
	else
	{
		return parseDouble(ref);
	}
}
Exemple #2
0
double Calculator::parseExprSum(std::string_view &ref)
{
	double value = parseExprMul(ref);
	while (true)
	{
		skipSpaces(ref);
		if (!ref.empty() && ref[0] == '+')
		{
			ref.remove_prefix(1);
			value += parseExprMul(ref);
			m_printStrategy->printAddition();
		}
		else if (!ref.empty() && ref[0] == '-')
		{
			ref.remove_prefix(1);
			value -= parseExprMul(ref);
			m_printStrategy->printSubstraction();
		}
		else
		{
			break;
		}
	}

	return value;
}
Exemple #3
0
double Calculator::parseExprMul(std::string_view &ref)
{
	double value = parseSymbol(ref);
	while (true)
	{
		skipSpaces(ref);
		if (!ref.empty() && ref[0] == '*')
		{
			ref.remove_prefix(1);
			value *= parseSymbol(ref);
			m_printStrategy->printMultiplication();
		}
		else if (!ref.empty() && ref[0] == '/')
		{
			ref.remove_prefix(1);
			value /= parseSymbol(ref);
			m_printStrategy->printDivision();
		}
		else
		{
			break;
		}
	}

	return value;
}
bool CSeqConversionDefault::ToValue(std::string_view sv)
{
	m_bReady = false;
	if (sv == "$$") {
		m_bHex = true;
		return true;
	}

	if (auto nextTerm = GetNextTerm(sv)) {
		m_iTargetValue = m_iCurrentValue = *nextTerm;
		m_iRepeat = m_iValueDiv = 1;
		if (!sv.empty() && sv.front() == ':') {
			if (sv.remove_prefix(1), !sv.empty()) {
				if (auto divTerm = GetNextInteger(sv)) {
					m_iValueDiv = *divTerm;
					if (m_iValueDiv <= 0)
						return false;
					if (!sv.empty() && sv.front() == ':') {
						if (sv.remove_prefix(1), sv.empty())
							return false;
						if (auto target = GetNextTerm(sv))
							m_iTargetValue = *target;
						else
							return false;
					}
				}
				else
					return false;
			}
			else
				return false;
		}
		if (!sv.empty() && sv.front() == '\'') {
			if (sv.remove_prefix(1), !sv.empty()) {
				if (auto repTerm = GetNextInteger(sv)) {
					m_iRepeat = *repTerm;
					if (m_iRepeat <= 0)
						return false;
				}
			}
			else
				return false;
		}
		if (sv.empty()) {
			m_iValueInc = m_iTargetValue - m_iCurrentValue;
			m_iRepeatCounter = m_iCounter = m_iValueMod = 0;
			return m_bReady = true;
		}
	}

	return false;
}
Exemple #5
0
double Calculator::parseDouble(std::string_view &ref)
{
	double value = 0;
	bool isNegative = false;
	bool parsedAny = false;

	skipSpaces(ref);
	if (!ref.empty() && ref[0] == '-')
	{
		isNegative = true;
		ref.remove_prefix(1);
	}
	skipSpaces(ref);

	while (!ref.empty() && std::isdigit(ref[0]))
	{
		parsedAny = true;
		const int digit = ref[0] - '0';
		value = value * 10.0f + double(digit);
		ref.remove_prefix(1);
	}

	if (!parsedAny)
	{
		return std::numeric_limits<double>::quiet_NaN();
	}

	if (isNegative)
	{
		value *= -1;
	}

	if (ref.empty() || (ref[0] != '.'))
	{
		m_printStrategy->printNumber(value);
		return value;
	}

	ref.remove_prefix(1);
	double factor = 1.f;
	while (!ref.empty() && std::isdigit(ref[0]))
	{
		const int digit = ref[0] - '0';
		factor *= 0.1f;
		value += factor * double(digit);
		ref.remove_prefix(1);
	}

	m_printStrategy->printNumber(value);
	return value;
}
Exemple #6
0
void Calculator::skipSpaces(std::string_view &ref)
{
	size_t i = 0;
	while (i < ref.size() && std::isspace(ref[i]))
	{
		++i;
	}
	ref.remove_prefix(i);
}
Exemple #7
0
double Calculator::ParseArguments(std::string_view &ref)
{
	double value = 0;
	if (!ref.empty() && ref[0] == '(')
	{
		ref.remove_prefix(1);
		value = parseExprSum(ref);
		skipSpaces(ref);
		if (!ref.empty() && ref[0] == ')')
		{
			ref.remove_prefix(1);
			return value;
		}
		else
		{
			return std::numeric_limits<double>::quiet_NaN();
		}
	}
	else
	{
		return std::numeric_limits<double>::quiet_NaN();
	}
}
Exemple #8
0
double Calculator::parseFunction(std::string_view &ref)
{
	try
	{
		std::string_view partStr = ref.substr(0, 3);

		if (partStr == std::string_view("sin"))
		{
			ref.remove_prefix(3);
			m_printStrategy->printFunctionName("sin");
			return sin(ParseArguments(ref) * M_PI / 180);
		}
		else if (partStr == std::string_view("cos"))
		{
			ref.remove_prefix(3);
			m_printStrategy->printFunctionName("cos");
			return cos(ParseArguments(ref) * M_PI / 180);
		}
		else
		{
			std::string_view partStr = ref.substr(0, 4);

			if (partStr == std::string_view("sqrt"))
			{
				ref.remove_prefix(4);
				m_printStrategy->printFunctionName("sqrt");
				return sqrt(ParseArguments(ref));
			}
		}
	}
	catch(const std::out_of_range&)
	{
		return std::numeric_limits<double>::quiet_NaN();
	}
	
	return std::numeric_limits<double>::quiet_NaN();
}
std::optional<int> CSeqConversionDefault::GetNextInteger(std::string_view &sv, bool Signed) const
{
	re::svmatch m;

	if (m_bHex) {
		static const std::regex HEX_RE {R"(^([\+-]?)[0-9A-Fa-f]+)", std::regex_constants::optimize};
		if (std::regex_search(sv.begin(), sv.end(), m, HEX_RE))
			if (!(Signed && !m[1].length()))
				if (auto val = conv::to_int(re::sv_from_submatch(m[0]), 16)) {
					sv.remove_prefix(std::distance(sv.begin(), m.suffix().first));
					return val;
				}
	}
	else {
		static const std::regex NUMBER_RE {R"(^([\+-]?)[0-9]+)", std::regex_constants::optimize};
		static const std::regex HEX_PREFIX_RE {R"(^([\+-]?)[\$x]([0-9A-Fa-f]+))", std::regex_constants::optimize}; // do not allow 0x prefix
		if (std::regex_search(sv.begin(), sv.end(), m, HEX_PREFIX_RE)) {
			if (!(Signed && !m[1].length()))
				if (auto val = conv::to_int(re::sv_from_submatch(m[2]), 16)) {
					if (m[1] == "-")
						*val = -*val;
					sv.remove_prefix(std::distance(sv.begin(), m.suffix().first));
					return val;
				}
		}
		else if (std::regex_search(sv.begin(), sv.end(), m, NUMBER_RE)) {
			if (!(Signed && !m[1].length()))
				if (auto val = conv::to_int(re::sv_from_submatch(m[0]))) {
					sv.remove_prefix(std::distance(sv.begin(), m.suffix().first));
					return val;
				}
		}
	}

	return std::nullopt;
}

std::optional<int> CSeqConversionDefault::GetNextTerm(std::string_view &sv)
{
	return GetNextInteger(sv);
}



std::string CSeqConversion5B::ToString(char Value) const
{
	std::string Str = std::to_string(Value & 0x1F);
	uint8_t m = (uint8_t)Value & 0xE0;
	if ((m & value_cast(s5b_mode_t::Square)) == value_cast(s5b_mode_t::Square))
		Str.push_back('t');
	if ((m & value_cast(s5b_mode_t::Noise)) == value_cast(s5b_mode_t::Noise))
		Str.push_back('n');
	if ((m & value_cast(s5b_mode_t::Envelope)) == value_cast(s5b_mode_t::Envelope))
		Str.push_back('e');
//	auto m = enum_cast<s5b_mode_t>((unsigned char)Value);
//	if ((m & s5b_mode_t::Square) == s5b_mode_t::Square)
//		Str.push_back('t');
//	if ((m & s5b_mode_t::Noise) == s5b_mode_t::Noise)
//		Str.push_back('n');
//	if ((m & s5b_mode_t::Envelope) == s5b_mode_t::Envelope)
//		Str.push_back('e');
	return Str;
}

bool CSeqConversion5B::ToValue(std::string_view sv)
{
	m_iEnableFlags = -1;
	return CSeqConversionDefault::ToValue(sv);
}

char CSeqConversion5B::GetValue()
{
	return CSeqConversionDefault::GetValue() | m_iEnableFlags;
}

std::optional<int> CSeqConversion5B::GetNextTerm(std::string_view &sv)
{
	if (auto o = GetNextInteger(sv)) {
		static const std::regex S5B_FLAGS_RE {R"(^[TtNnEe]*)", std::regex_constants::optimize};
		if (re::svmatch m; std::regex_search(sv.begin(), sv.end(), m, S5B_FLAGS_RE)) {
			if (m_iEnableFlags == -1) {
				m_iEnableFlags = 0;
				auto flags = re::sv_from_submatch(m[0]);
				if (flags.find_first_of("Tt") != std::string::npos)
					m_iEnableFlags |= value_cast(s5b_mode_t::Square);
				if (flags.find_first_of("Nn") != std::string::npos)
					m_iEnableFlags |= value_cast(s5b_mode_t::Noise);
				if (flags.find_first_of("Ee") != std::string::npos)
					m_iEnableFlags |= value_cast(s5b_mode_t::Envelope);
			}
			sv.remove_prefix(std::distance(sv.begin(), m.suffix().first));
		}
Exemple #10
0
std::string_view trim(std::string_view str)
{
    str.remove_prefix(str.find_first_not_of(' '));
    str.remove_suffix(str.size() - (str.find_last_not_of(' ') + 1));
    return str;
}