From 0811f23b711b855e1788170811d720f937ee03f2 Mon Sep 17 00:00:00 2001 From: blueloveTH Date: Thu, 13 Jun 2024 13:08:19 +0800 Subject: [PATCH] some more move --- compile_flags.txt | 3 +- include/pocketpy/common/sstream.h | 16 +++--- include/pocketpy/common/str.h | 4 -- include/pocketpy/common/str.hpp | 87 +++++++++++++++++++++++++------ src/common/sstream.c | 47 ++++++++++++++--- src/common/str.cpp | 82 ----------------------------- src/interpreter/vm.cpp | 8 ++- tests/99_builtin_func.py | 9 ++-- 8 files changed, 130 insertions(+), 126 deletions(-) diff --git a/compile_flags.txt b/compile_flags.txt index ac20b509..cc06ba37 100644 --- a/compile_flags.txt +++ b/compile_flags.txt @@ -1,9 +1,8 @@ -Wall -W* --std=c++17 --std=c11 -stdlib=libc++ +-std=c++17 -Iinclude/ -I3rd/cjson/include/ diff --git a/include/pocketpy/common/sstream.h b/include/pocketpy/common/sstream.h index 5f66d97d..e2e119a3 100644 --- a/include/pocketpy/common/sstream.h +++ b/include/pocketpy/common/sstream.h @@ -22,7 +22,6 @@ typedef struct pkpy_AnyStr { float _float; double _double; char _char; - unsigned char _hex; const pkpy_Str* _str; c11_string _sv; const char* _cstr; @@ -35,17 +34,19 @@ inline pkpy_AnyStr pkpy_AnyStr__int64(int64_t x) { return (pkpy_AnyStr){.type = inline pkpy_AnyStr pkpy_AnyStr__float(float x) { return (pkpy_AnyStr){.type = 3, ._float = x}; } inline pkpy_AnyStr pkpy_AnyStr__double(double x) { return (pkpy_AnyStr){.type = 4, ._double = x}; } inline pkpy_AnyStr pkpy_AnyStr__char(char x) { return (pkpy_AnyStr){.type = 5, ._char = x}; } -inline pkpy_AnyStr pkpy_AnyStr__hex(unsigned char x) { return (pkpy_AnyStr){.type = 6, ._hex = x}; } -inline pkpy_AnyStr pkpy_AnyStr__str(const pkpy_Str* x) { return (pkpy_AnyStr){.type = 7, ._str = x}; } -inline pkpy_AnyStr pkpy_AnyStr__sv(c11_string x) { return (pkpy_AnyStr){.type = 8, ._sv = x}; } -inline pkpy_AnyStr pkpy_AnyStr__cstr(const char* x) { return (pkpy_AnyStr){.type = 9, ._cstr = x}; } -inline pkpy_AnyStr pkpy_AnyStr__ptr(void* x) { return (pkpy_AnyStr){.type = 10, ._ptr = x}; } +inline pkpy_AnyStr pkpy_AnyStr__str(const pkpy_Str* x) { return (pkpy_AnyStr){.type = 6, ._str = x}; } +inline pkpy_AnyStr pkpy_AnyStr__sv(c11_string x) { return (pkpy_AnyStr){.type = 7, ._sv = x}; } +inline pkpy_AnyStr pkpy_AnyStr__cstr(const char* x) { return (pkpy_AnyStr){.type = 8, ._cstr = x}; } +inline pkpy_AnyStr pkpy_AnyStr__ptr(void* x) { return (pkpy_AnyStr){.type = 9, ._ptr = x}; } void pkpy_SStream__ctor(pkpy_SStream* self); void pkpy_SStream__dtor(pkpy_SStream* self); -void pkpy_SStream__write_char(pkpy_SStream* self, char); + void pkpy_SStream__write_int(pkpy_SStream* self, int); void pkpy_SStream__write_int64(pkpy_SStream* self, int64_t); +void pkpy_SStream__write_float(pkpy_SStream* self, float, int precision); +void pkpy_SStream__write_double(pkpy_SStream* self, double, int precision); +void pkpy_SStream__write_char(pkpy_SStream* self, char); void pkpy_SStream__write_Str(pkpy_SStream* self, const pkpy_Str*); void pkpy_SStream__write_sv(pkpy_SStream* self, c11_string); void pkpy_SStream__write_cstr(pkpy_SStream* self, const char*); @@ -61,7 +62,6 @@ pkpy_Str pkpy_SStream__submit(pkpy_SStream* self); float: pkpy_AnyStr__float, \ double: pkpy_AnyStr__double, \ char: pkpy_AnyStr__char, \ - unsigned char: pkpy_AnyStr__hex, \ const pkpy_Str*: pkpy_AnyStr__str, \ c11_string: pkpy_AnyStr__sv, \ const char*: pkpy_AnyStr__cstr, \ diff --git a/include/pocketpy/common/str.h b/include/pocketpy/common/str.h index 7fb2ca6b..9469fafc 100644 --- a/include/pocketpy/common/str.h +++ b/include/pocketpy/common/str.h @@ -27,10 +27,6 @@ inline const char* pkpy_Str__data(const pkpy_Str* self){ return self->is_sso ? self->_inlined : self->_ptr; } -inline int pkpy_Str__size(const pkpy_Str* self){ - return self->size; -} - int pkpy_utils__u8_header(unsigned char c, bool suppress); void pkpy_Str__ctor(pkpy_Str* self, const char* data); void pkpy_Str__ctor2(pkpy_Str* self, const char* data, int size); diff --git a/include/pocketpy/common/str.hpp b/include/pocketpy/common/str.hpp index ed0f7004..25dbee7a 100644 --- a/include/pocketpy/common/str.hpp +++ b/include/pocketpy/common/str.hpp @@ -1,11 +1,13 @@ #pragma once +#include "pocketpy/common/sstream.h" #include "pocketpy/common/utils.h" #include "pocketpy/common/memorypool.hpp" #include "pocketpy/common/vector.h" #include "pocketpy/common/vector.hpp" #include "pocketpy/common/str.h" +#include #include #include @@ -273,32 +275,83 @@ struct StrName { static uint32_t _pesudo_random_index; }; -struct SStream { +struct SStream: pkpy_SStream { PK_ALWAYS_PASS_BY_POINTER(SStream) - vector buffer; int _precision = -1; - - bool empty() const { return buffer.empty(); } + bool _submited = false; + bool empty() const { return data.count == 0; } void setprecision(int precision) { _precision = precision; } - SStream() {} + SStream() { + pkpy_SStream__ctor(this); + } - SStream(int guess_size) { buffer.reserve(guess_size); } + SStream(int guess_size) { c11_vector__reserve(&data, guess_size); } - Str str(); + ~SStream() { + // in case of error + if(!_submited) pkpy_SStream__dtor(this); + } - SStream& operator<< (const Str&); - SStream& operator<< (const char*); - SStream& operator<< (int); - SStream& operator<< (size_t); - SStream& operator<< (i64); - SStream& operator<< (f64); - SStream& operator<< (const std::string&); - SStream& operator<< (std::string_view); - SStream& operator<< (char); - SStream& operator<< (StrName); + Str str(){ + assert(!_submited); + _submited = true; + return pkpy_SStream__submit(this); + } + + SStream& operator<< (const Str& val){ + pkpy_SStream__write_Str(this, &val); + return *this; + } + + SStream& operator<< (const char* val){ + pkpy_SStream__write_cstr(this, val); + return *this; + } + + SStream& operator<< (int val){ + pkpy_SStream__write_int(this, val); + return *this; + } + + SStream& operator<< (size_t val){ + // size_t could overflow int64, but nevermind... + pkpy_SStream__write_int64(this, val); + return *this; + } + + SStream& operator<< (i64 val){ + pkpy_SStream__write_int64(this, val); + return *this; + } + + SStream& operator<< (f64 val){ + pkpy_SStream__write_double(this, val, _precision); + return *this; + } + + SStream& operator<< (const std::string& val){ + pkpy_SStream__write_cstrn(this, val.data(), val.size()); + return *this; + } + + SStream& operator<< (std::string_view val){ + pkpy_SStream__write_cstrn(this, val.data(), val.size()); + return *this; + } + + SStream& operator<< (char val){ + pkpy_SStream__write_char(this, val); + return *this; + } + + SStream& operator<< (StrName name){ + std::string_view sv = name.sv(); + pkpy_SStream__write_cstrn(this, sv.data(), sv.size()); + return *this; + } void write_hex(unsigned char, bool non_zero = false); void write_hex(void*); diff --git a/src/common/sstream.c b/src/common/sstream.c index 6ba3a7ba..df20c129 100644 --- a/src/common/sstream.c +++ b/src/common/sstream.c @@ -3,6 +3,8 @@ #include #include +#include +#include void pkpy_SStream__ctor(pkpy_SStream* self) { c11_vector__ctor(&self->data, sizeof(char)); @@ -28,8 +30,38 @@ void pkpy_SStream__write_int64(pkpy_SStream* self, int64_t i) { pkpy_SStream__write_cstr(self, buf); } +void pkpy_SStream__write_float(pkpy_SStream* self, float val, int precision){ + return pkpy_SStream__write_double(self, val, precision); +} + +void pkpy_SStream__write_double(pkpy_SStream* self, double val, int precision){ + if(val == INFINITY) { + pkpy_SStream__write_cstr(self, val > 0 ? "inf" : "-inf"); + return; + } + if(val == NAN) { + pkpy_SStream__write_cstr(self, "nan"); + return; + } + char b[32]; + int size; + if(precision < 0) { + int prec = 17 - 1; // std::numeric_limits::max_digits10 == 17 + size = snprintf(b, sizeof(b), "%.*g", prec, val); + } else { + int prec = precision; + size = snprintf(b, sizeof(b), "%.*f", prec, val); + } + pkpy_SStream__write_cstr(self, b); + bool all_is_digit = true; + for(int i = 1; i < size; i++){ + if(!isdigit(b[i])){ all_is_digit = false; break; } + } + if(all_is_digit) pkpy_SStream__write_cstr(self, ".0"); +} + void pkpy_SStream__write_Str(pkpy_SStream* self, const pkpy_Str* str) { - pkpy_SStream__write_cstr(self, pkpy_Str__data(str)); + pkpy_SStream__write_cstrn(self, pkpy_Str__data(str), str->size); } void pkpy_SStream__write_sv(pkpy_SStream* self, c11_string sv) { @@ -52,14 +84,13 @@ void pkpy_SStream__write_any(pkpy_SStream* self, const char* fmt, const pkpy_Any switch(args[i].type){ case 1: pkpy_SStream__write_int(self, args[i]._int); break; case 2: pkpy_SStream__write_int64(self, args[i]._int64); break; - case 3: assert(0); break; - case 4: assert(0); break; + case 3: pkpy_SStream__write_float(self, args[i]._float, -1); break; + case 4: pkpy_SStream__write_double(self, args[i]._double, -1); break; case 5: pkpy_SStream__write_char(self, args[i]._char); break; - case 6: assert(0); break; - case 7: pkpy_SStream__write_Str(self, args[i]._str); break; - case 8: pkpy_SStream__write_sv(self, args[i]._sv); break; - case 9: pkpy_SStream__write_cstr(self, args[i]._cstr); break; - case 10: assert(0); break; + case 6: pkpy_SStream__write_Str(self, args[i]._str); break; + case 7: pkpy_SStream__write_sv(self, args[i]._sv); break; + case 8: pkpy_SStream__write_cstr(self, args[i]._cstr); break; + case 9: assert(0); break; default: assert(0); break; } fmt += 2; diff --git a/src/common/str.cpp b/src/common/str.cpp index f9f14fab..451f5818 100644 --- a/src/common/str.cpp +++ b/src/common/str.cpp @@ -54,88 +54,6 @@ StrName StrName::get(std::string_view s) { return StrName(index); } -Str SStream::str() { - // after this call, the buffer is no longer valid - buffer.push_back('\0'); - auto detached = buffer.detach(); - detached.second--; // remove the last '\0' - return Str(detached); -} - -SStream& SStream::operator<< (const Str& s) { - for(char c: s) - buffer.push_back(c); - return *this; -} - -SStream& SStream::operator<< (const char* s) { - while(*s) - buffer.push_back(*s++); - return *this; -} - -SStream& SStream::operator<< (const std::string& s) { - for(char c: s) - buffer.push_back(c); - return *this; -} - -SStream& SStream::operator<< (std::string_view s) { - for(char c: s) - buffer.push_back(c); - return *this; -} - -SStream& SStream::operator<< (char c) { - buffer.push_back(c); - return *this; -} - -SStream& SStream::operator<< (StrName sn) { return *this << sn.sv(); } - -SStream& SStream::operator<< (size_t val) { - // size_t could be out of range of `i64`, use `std::to_string` instead - return (*this) << std::to_string(val); -} - -SStream& SStream::operator<< (int val) { return (*this) << static_cast(val); } - -SStream& SStream::operator<< (i64 val) { - // str(-2**64).__len__() == 21 - buffer.reserve(buffer.size() + 24); - if(val == 0) { - buffer.push_back('0'); - return *this; - } - if(val < 0) { - buffer.push_back('-'); - val = -val; - } - auto begin = buffer.end(); - while(val) { - buffer.push_back('0' + val % 10); - val /= 10; - } - std::reverse(begin, buffer.end()); - return *this; -} - -SStream& SStream::operator<< (f64 val) { - if(std::isinf(val)) { return (*this) << (val > 0 ? "inf" : "-inf"); } - if(std::isnan(val)) { return (*this) << "nan"; } - char b[32]; - if(_precision == -1) { - int prec = std::numeric_limits::max_digits10 - 1; - snprintf(b, sizeof(b), "%.*g", prec, val); - } else { - int prec = _precision; - snprintf(b, sizeof(b), "%.*f", prec, val); - } - (*this) << b; - if(std::all_of(b + 1, b + strlen(b), isdigit)) (*this) << ".0"; - return *this; -} - void SStream::write_hex(unsigned char c, bool non_zero) { unsigned char high = c >> 4; unsigned char low = c & 0xf; diff --git a/src/interpreter/vm.cpp b/src/interpreter/vm.cpp index 898b2850..10ad986c 100644 --- a/src/interpreter/vm.cpp +++ b/src/interpreter/vm.cpp @@ -4,6 +4,10 @@ #include #include +#if PK_DEBUG_CEVAL_STEP +#include +#endif + const static char* OP_NAMES[] = { #define OPCODE(name) #name, #include "pocketpy/opcodes.h" @@ -117,7 +121,7 @@ Str VM::py_repr(PyVar obj) { } Str VM::py_json(PyVar obj) { - auto j = JsonSerializer(this, obj); + JsonSerializer j(this, obj); return j.serialize(); } @@ -808,7 +812,7 @@ Str VM::disassemble(CodeObject_ co) { #if PK_DEBUG_CEVAL_STEP void VM::__log_s_data(const char* title) { - if(_main == nullptr) return; + // if(_main == nullptr) return; if(callstack.empty()) return; SStream ss; if(title) ss << title << " | "; diff --git a/tests/99_builtin_func.py b/tests/99_builtin_func.py index d44eb5f1..5ff315f1 100644 --- a/tests/99_builtin_func.py +++ b/tests/99_builtin_func.py @@ -146,10 +146,13 @@ except: pass # test chr -l = [] +actual = [] for i in range(128): - l.append(f'{i} {chr(i)}') -assert l == ['0 \x00', '1 \x01', '2 \x02', '3 \x03', '4 \x04', '5 \x05', '6 \x06', '7 \x07', '8 \x08', '9 \t', '10 \n', '11 \x0b', '12 \x0c', '13 \r', '14 \x0e', '15 \x0f', '16 \x10', '17 \x11', '18 \x12', '19 \x13', '20 \x14', '21 \x15', '22 \x16', '23 \x17', '24 \x18', '25 \x19', '26 \x1a', '27 \x1b', '28 \x1c', '29 \x1d', '30 \x1e', '31 \x1f', '32 ', '33 !', '34 "', '35 #', '36 $', '37 %', '38 &', "39 '", '40 (', '41 )', '42 *', '43 +', '44 ,', '45 -', '46 .', '47 /', '48 0', '49 1', '50 2', '51 3', '52 4', '53 5', '54 6', '55 7', '56 8', '57 9', '58 :', '59 ;', '60 <', '61 =', '62 >', '63 ?', '64 @', '65 A', '66 B', '67 C', '68 D', '69 E', '70 F', '71 G', '72 H', '73 I', '74 J', '75 K', '76 L', '77 M', '78 N', '79 O', '80 P', '81 Q', '82 R', '83 S', '84 T', '85 U', '86 V', '87 W', '88 X', '89 Y', '90 Z', '91 [', '92 \\', '93 ]', '94 ^', '95 _', '96 `', '97 a', '98 b', '99 c', '100 d', '101 e', '102 f', '103 g', '104 h', '105 i', '106 j', '107 k', '108 l', '109 m', '110 n', '111 o', '112 p', '113 q', '114 r', '115 s', '116 t', '117 u', '118 v', '119 w', '120 x', '121 y', '122 z', '123 {', '124 |', '125 }', '126 ~', '127 \x7f'] + actual.append(f'{i} {chr(i)}') +expected = ['0 \x00', '1 \x01', '2 \x02', '3 \x03', '4 \x04', '5 \x05', '6 \x06', '7 \x07', '8 \x08', '9 \t', '10 \n', '11 \x0b', '12 \x0c', '13 \r', '14 \x0e', '15 \x0f', '16 \x10', '17 \x11', '18 \x12', '19 \x13', '20 \x14', '21 \x15', '22 \x16', '23 \x17', '24 \x18', '25 \x19', '26 \x1a', '27 \x1b', '28 \x1c', '29 \x1d', '30 \x1e', '31 \x1f', '32 ', '33 !', '34 "', '35 #', '36 $', '37 %', '38 &', "39 '", '40 (', '41 )', '42 *', '43 +', '44 ,', '45 -', '46 .', '47 /', '48 0', '49 1', '50 2', '51 3', '52 4', '53 5', '54 6', '55 7', '56 8', '57 9', '58 :', '59 ;', '60 <', '61 =', '62 >', '63 ?', '64 @', '65 A', '66 B', '67 C', '68 D', '69 E', '70 F', '71 G', '72 H', '73 I', '74 J', '75 K', '76 L', '77 M', '78 N', '79 O', '80 P', '81 Q', '82 R', '83 S', '84 T', '85 U', '86 V', '87 W', '88 X', '89 Y', '90 Z', '91 [', '92 \\', '93 ]', '94 ^', '95 _', '96 `', '97 a', '98 b', '99 c', '100 d', '101 e', '102 f', '103 g', '104 h', '105 i', '106 j', '107 k', '108 l', '109 m', '110 n', '111 o', '112 p', '113 q', '114 r', '115 s', '116 t', '117 u', '118 v', '119 w', '120 x', '121 y', '122 z', '123 {', '124 |', '125 }', '126 ~', '127 \x7f'] +assert len(actual) == len(expected) +for i in range(len(actual)): + assert (actual[i] == expected[i]), (actual[i], expected[i]) assert type(bin(1234)) is str