This commit is contained in:
blueloveTH 2023-04-20 12:30:14 +08:00
parent 399170727c
commit efb2385f3e
4 changed files with 40 additions and 23 deletions

View File

@ -67,22 +67,43 @@
#endif
#if defined(__EMSCRIPTEN__) || defined(__arm__) || defined(__i386__)
typedef int32_t i64;
typedef float f64;
#define S_TO_INT(...) static_cast<i64>(std::stoi(__VA_ARGS__))
#define S_TO_FLOAT(...) static_cast<f64>(std::stof(__VA_ARGS__))
#else
typedef int64_t i64;
typedef double f64;
#define S_TO_INT(...) static_cast<i64>(std::stoll(__VA_ARGS__))
#define S_TO_FLOAT(...) static_cast<f64>(std::stod(__VA_ARGS__))
#endif
namespace pkpy{
namespace std = ::std;
template <size_t T>
struct NumberTraits;
template <>
struct NumberTraits<4> {
using int_t = int32_t;
using float_t = float;
template<typename... Args>
static int_t stoi(Args&&... args) { return std::stoi(std::forward<Args>(args)...); }
template<typename... Args>
static float_t stof(Args&&... args) { return std::stof(std::forward<Args>(args)...); }
};
template <>
struct NumberTraits<8> {
using int_t = int64_t;
using float_t = double;
template<typename... Args>
static int_t stoi(Args&&... args) { return std::stoll(std::forward<Args>(args)...); }
template<typename... Args>
static float_t stof(Args&&... args) { return std::stod(std::forward<Args>(args)...); }
};
using Number = NumberTraits<sizeof(void*)>;
using i64 = Number::int_t;
using f64 = Number::float_t;
static_assert(sizeof(i64) == sizeof(void*));
static_assert(sizeof(f64) == sizeof(void*));
static_assert(std::numeric_limits<f64>::is_iec559);
struct Dummy { };
struct DummyInstance { };
struct DummyModule { };
@ -110,11 +131,6 @@ struct Type {
inline const float kInstAttrLoadFactor = 0.67f;
inline const float kTypeAttrLoadFactor = 0.5f;
static_assert(sizeof(i64) == sizeof(int*));
static_assert(sizeof(f64) == sizeof(int*));
static_assert(std::numeric_limits<float>::is_iec559);
static_assert(std::numeric_limits<double>::is_iec559);
struct PyObject;
#define BITS(p) (reinterpret_cast<i64>(p))
inline bool is_tagged(PyObject* p) noexcept { return (BITS(p) & 0b11) != 0b00; }

View File

@ -347,9 +347,9 @@ struct Lexer {
if (m[1].matched) base = 16;
if (m[2].matched) {
if(base == 16) SyntaxError("hex literal should not contain a dot");
add_token(TK("@num"), S_TO_FLOAT(m[0], &size));
add_token(TK("@num"), Number::stof(m[0], &size));
} else {
add_token(TK("@num"), S_TO_INT(m[0], &size, base));
add_token(TK("@num"), Number::stoi(m[0], &size, base));
}
if (size != m.length()) FATAL_ERROR();
}

View File

@ -246,7 +246,7 @@ inline void init_builtins(VM* _vm) {
const Str& s = CAST(Str&, args[0]);
try{
size_t parsed = 0;
i64 val = S_TO_INT(s.str(), &parsed, 10);
i64 val = Number::stoi(s.str(), &parsed, 10);
if(parsed != s.length()) throw std::invalid_argument("<?>");
return VAR(val);
}catch(std::invalid_argument&){
@ -293,7 +293,7 @@ inline void init_builtins(VM* _vm) {
if(s == "inf") return VAR(INFINITY);
if(s == "-inf") return VAR(-INFINITY);
try{
f64 val = S_TO_FLOAT(s.str());
f64 val = Number::stof(s.str());
return VAR(val);
}catch(std::invalid_argument&){
vm->ValueError("invalid literal for float(): '" + s + "'");
@ -930,8 +930,8 @@ extern "C" {
return strdup(ss.str().c_str());
}
typedef i64 (*f_int_t)(char*);
typedef f64 (*f_float_t)(char*);
typedef pkpy::i64 (*f_int_t)(char*);
typedef pkpy::f64 (*f_float_t)(char*);
typedef bool (*f_bool_t)(char*);
typedef char* (*f_str_t)(char*);
typedef void (*f_None_t)(char*);

View File

@ -573,6 +573,7 @@ inline i64 VM::hash(PyObject* obj){
return x;
}
if (is_non_tagged_type(obj, tp_type)) return BITS(obj);
if (is_non_tagged_type(obj, tp_iterator)) return BITS(obj);
if (is_non_tagged_type(obj, tp_bool)) return _CAST(bool, obj) ? 1 : 0;
if (is_float(obj)){
f64 val = CAST(f64, obj);