diff --git a/include/chaiscript/chaiscript_defines.hpp b/include/chaiscript/chaiscript_defines.hpp index cf2a5a61..98fbf4ac 100644 --- a/include/chaiscript/chaiscript_defines.hpp +++ b/include/chaiscript/chaiscript_defines.hpp @@ -93,6 +93,8 @@ #endif #include +#include +#include namespace chaiscript { static const int version_major = 5; @@ -119,6 +121,71 @@ namespace chaiscript { return iter; } + + 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); ++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 + { + T t = 0; + T base = 0; + T decimal_place = 0; + bool exponent = false; + bool neg_exponent = false; + + const auto final_value = [](const T val, const T baseval, const bool hasexp, const bool negexp) -> T { + if (!hasexp) { + return val; + } else { + return baseval * std::pow(T(10), val*T(negexp?-1:1)); + } + }; + + for(char c = *t_str; (c = *t_str); ++t_str) { + if (c == '.') { + decimal_place = 10; + } else if (c == 'e' || c == 'E') { + exponent = true; + decimal_place = 0; + base = t; + t = 0; + } else if (c == '-' && exponent) { + neg_exponent = true; + } else if (c == '+' && exponent) { + neg_exponent = false; + } else if (c < '0' || c > '9') { + return final_value(t, base, exponent, neg_exponent); + } else if (decimal_place == 0) { + t *= T(10); + t += T(c - '0'); + } else { + t += (T(c - '0') / (T(decimal_place))); + decimal_place *= 10; + } + } + + return final_value(t, base, exponent, neg_exponent); + } + + template + T parse_num(const std::string &t_str) + { + return parse_num(t_str.c_str()); + } + } #endif diff --git a/include/chaiscript/language/chaiscript_parser.hpp b/include/chaiscript/language/chaiscript_parser.hpp index 684b766f..8fc9827e 100644 --- a/include/chaiscript/language/chaiscript_parser.hpp +++ b/include/chaiscript/language/chaiscript_parser.hpp @@ -621,11 +621,11 @@ namespace chaiscript if (float_) { - return const_var(std::stof(t_val.substr(0,i))); + return const_var(parse_num(t_val.substr(0,i))); } else if (long_) { - return const_var(std::stold(t_val.substr(0,i))); + return const_var(parse_num(t_val.substr(0,i))); } else { - return const_var(std::stod(t_val.substr(0,i))); + return const_var(parse_num(t_val.substr(0,i))); } }