diff --git a/include/chaiscript/chaiscript_defines.hpp b/include/chaiscript/chaiscript_defines.hpp index 0a76a82..97f969f 100644 --- a/include/chaiscript/chaiscript_defines.hpp +++ b/include/chaiscript/chaiscript_defines.hpp @@ -144,21 +144,6 @@ namespace chaiscript { }; - template - auto parse_num(const char *t_str) -> typename std::enable_if::value, T>::type - { - T t = 0; - for (char c = *t_str; (c = *t_str) != 0; ++t_str) { - if (c < '0' || c > '9') { - return t; - } - t *= 10; - t += c - '0'; - } - return t; - } - - template auto parse_num(const char *t_str) -> typename std::enable_if::value, T>::type { @@ -176,6 +161,16 @@ namespace chaiscript { } }; + const bool neg = [&](){ + if (t_str[0] == '-') { + ++t_str; + return true; + } else { + return false; + } + }(); + + for(; *t_str != '\0'; ++t_str) { char c = *t_str; if (c == '.') { @@ -200,7 +195,7 @@ namespace chaiscript { } } - return final_value(t, base, exponent, neg_exponent); + return final_value(t, base, exponent, neg_exponent) * (neg?-1:1); } template diff --git a/include/chaiscript/language/chaiscript_parser.hpp b/include/chaiscript/language/chaiscript_parser.hpp index 3e7315b..fe275ec 100644 --- a/include/chaiscript/language/chaiscript_parser.hpp +++ b/include/chaiscript/language/chaiscript_parser.hpp @@ -722,7 +722,10 @@ namespace chaiscript } } - const auto val = prefixed?std::string(t_val.begin()+2,t_val.end()):t_val; + + const bool neg = t_val[0] == '-'; + const auto pref = neg?std::string(t_val.begin()+1,t_val.end()):t_val; + const auto val = prefixed?std::string(pref.begin() + 2, pref.end()):pref; #ifdef __GNUC__ #pragma GCC diagnostic push @@ -739,17 +742,17 @@ namespace chaiscript if (!unsigned_ && !long_ && u >= std::numeric_limits::min() && u <= std::numeric_limits::max()) { - return const_var(static_cast(u)); + return const_var(static_cast(u) * (neg?-1:1)); } else if ((unsigned_ || base != 10) && !long_ && u >= std::numeric_limits::min() && u <= std::numeric_limits::max()) { - return const_var(static_cast(u)); + return const_var(static_cast(u) * (neg?-1:1)); } else if (!unsigned_ && !longlong_ && u >= std::numeric_limits::min() && u <= std::numeric_limits::max()) { - return const_var(static_cast(u)); + return const_var(static_cast(u) * (neg?-1:1)); } else if ((unsigned_ || base != 10) && !longlong_ && u >= std::numeric_limits::min() && u <= std::numeric_limits::max()) { - return const_var(static_cast(u)); + return const_var(static_cast(u) * (neg?-1:1)); } else if (!unsigned_ && u >= std::numeric_limits::min() && u <= std::numeric_limits::max()) { - return const_var(static_cast(u)); + return const_var(static_cast(u) * (neg?-1:1)); } else { - return const_var(static_cast(u)); + return const_var(static_cast(u) * (neg?-1:1)); } } catch (const std::out_of_range &) { @@ -758,13 +761,13 @@ namespace chaiscript auto u = std::stoull(val,nullptr,base); if (u >= std::numeric_limits::min() && u <= std::numeric_limits::max()) { - return const_var(static_cast(u)); + return const_var(static_cast(u) * (neg?-1:1)); } else { - return const_var(static_cast(u)); + return const_var(static_cast(u) * (neg?-1:1)); } } catch (const std::out_of_range &) { // it's just simply too big - return const_var(std::numeric_limits::max()); + return const_var(neg?std::numeric_limits::min():std::numeric_limits::max()); } } @@ -785,6 +788,7 @@ namespace chaiscript SkipWS(); const auto start = m_position; + const bool neg = Char_('-'); if (m_position.has_more() && char_in_alphabet(*m_position, detail::float_alphabet) ) { try { if (Hex_()) { @@ -809,7 +813,7 @@ namespace chaiscript else { IntSuffix_(); auto match = Position::str(start, m_position); - if (!match.empty() && (match[0] == '0')) { + if (!match.empty() && (match[neg?1:0] == '0')) { auto bv = buildInt(8, match, false); m_match_stack.push_back(make_node>(std::move(match), start.line, start.col, std::move(bv))); } @@ -827,6 +831,7 @@ namespace chaiscript } } else { + if (neg) { --m_position; } return false; } } diff --git a/include/chaiscript/utility/json.hpp b/include/chaiscript/utility/json.hpp index 96decc0..73a0c98 100644 --- a/include/chaiscript/utility/json.hpp +++ b/include/chaiscript/utility/json.hpp @@ -600,7 +600,7 @@ struct JSONParser { break; } } - exp = chaiscript::parse_num( exp_str ); + exp = std::stol( exp_str ); } else if( offset < str.size() && (!isspace( c ) && c != ',' && c != ']' && c != '}' )) { throw std::runtime_error(std::string("JSON ERROR: Number: unexpected character '") + c + "'"); @@ -611,9 +611,9 @@ struct JSONParser { return JSON(chaiscript::parse_num( val ) * std::pow( 10, exp )); } else { if( !exp_str.empty() ) { - return JSON(static_cast(chaiscript::parse_num( val )) * std::pow( 10, exp )); + return JSON(static_cast(std::stol( val )) * std::pow( 10, exp )); } else { - return JSON(chaiscript::parse_num( val )); + return JSON(std::stol( val )); } } }