replace std::stringstream with SStream

This commit is contained in:
blueloveTH 2023-10-15 21:58:33 +08:00
parent e4b6d566a7
commit 5e3572b32c
16 changed files with 71 additions and 66 deletions

View File

@ -46,7 +46,7 @@ struct VoidP{
bool operator>=(const VoidP& other) const { return ptr >= other.ptr; }
Str hex() const{
std::stringstream ss;
std::stringstream ss; // hex
ss << std::hex << reinterpret_cast<intptr_t>(ptr);
return "0x" + ss.str();
}

View File

@ -24,7 +24,7 @@ enum CompileMode {
};
struct SourceData {
std::string source;
Str source;
Str filename;
std::vector<const char*> line_starts;
CompileMode mode;

View File

@ -59,8 +59,8 @@ struct Token{
Str str() const { return Str(start, length);}
std::string_view sv() const { return std::string_view(start, length);}
std::string info() const {
std::stringstream ss;
Str info() const {
SStream ss;
ss << line << ": " << TK_STR(type) << " '" << (
sv()=="\n" ? "\\n" : sv()
) << "'";

View File

@ -291,7 +291,7 @@ struct NameDictImpl{
V operator[](StrName key) const {
V val = try_get_likely_found(key);
if(val == default_invalid_value<V>()){
throw std::runtime_error(fmt("NameDict key not found: ", key.escape()));
throw std::runtime_error(fmt("NameDict key not found: ", key.escape()).str());
}
return val;
}

View File

@ -7,6 +7,7 @@
namespace pkpy {
int utf8len(unsigned char c, bool suppress=false);
struct SStream;
struct Str{
int size;
@ -70,7 +71,7 @@ struct Str{
Str lower() const;
Str upper() const;
Str escape(bool single_quote=true) const;
void escape_(std::stringstream& ss, bool single_quote=true) const;
void escape_(SStream& ss, bool single_quote=true) const;
int index(const Str& sub, int start=0) const;
Str replace(char old, char new_) const;
Str replace(const Str& old, const Str& new_, int count=-1) const;

View File

@ -272,7 +272,7 @@ __NEXT_STEP:;
PUSH(VAR(Slice(_0, _1, _2)));
} DISPATCH();
TARGET(BUILD_STRING) {
std::stringstream ss;
SStream ss;
ArgsView view = STACK_VIEW(byte.arg);
for(PyObject* obj : view) ss << CAST(Str&, py_str(obj));
STACK_SHRINK(byte.arg);

View File

@ -46,7 +46,7 @@ namespace pkpy{
vm->bind__repr__(PK_OBJ_GET(Type, type), [](VM* vm, PyObject* obj){
C99Struct& self = _CAST(C99Struct&, obj);
std::stringstream ss;
SStream ss;
ss << "<struct object of " << self.size << " bytes>";
return VAR(ss.str());
});

View File

@ -548,25 +548,25 @@ __SUBSCR_END:
advance();
}
__EAT_DOTS_END:
std::stringstream ss;
SStream ss;
for(int i=0; i<dots; i++) ss << '.';
if(dots > 0){
// @id is optional if dots > 0
if(match(TK("@id"))){
ss << prev().str();
ss << prev().sv();
while (match(TK("."))) {
consume(TK("@id"));
ss << "." << prev().str();
ss << "." << prev().sv();
}
}
}else{
// @id is required if dots == 0
consume(TK("@id"));
ss << prev().str();
ss << prev().sv();
while (match(TK("."))) {
consume(TK("@id"));
ss << "." << prev().str();
ss << "." << prev().sv();
}
}
@ -679,7 +679,7 @@ __EAT_DOTS_END:
do {
consume(TK("except"));
if(match(TK("@id"))){
ctx()->emit(OP_EXCEPTION_MATCH, StrName(prev().str()).index, prev().line);
ctx()->emit(OP_EXCEPTION_MATCH, StrName(prev().sv()).index, prev().line);
}else{
ctx()->emit(OP_LOAD_TRUE, BC_NOARG, BC_KEEPLINE);
}
@ -864,7 +864,7 @@ __EAT_DOTS_END:
break;
case TK("raise"): {
consume(TK("@id"));
int dummy_t = StrName(prev().str()).index;
int dummy_t = StrName(prev().sv()).index;
if(match(TK("(")) && !match(TK(")"))){
EXPR(false); consume(TK(")"));
}else{
@ -905,7 +905,7 @@ __EAT_DOTS_END:
case TK("->"):
consume(TK("@id"));
if(mode()!=EXEC_MODE) SyntaxError("'goto' is only available in EXEC_MODE");
ctx()->emit(OP_GOTO, StrName(prev().str()).index, prev().line);
ctx()->emit(OP_GOTO, StrName(prev().sv()).index, prev().line);
consume_end_stmt();
break;
/*************************************************/
@ -950,7 +950,7 @@ __EAT_DOTS_END:
void Compiler::compile_class(){
consume(TK("@id"));
int namei = StrName(prev().str()).index;
int namei = StrName(prev().sv()).index;
Expr_ base = nullptr;
if(match(TK("("))){
if(is_expression()){

View File

@ -7,15 +7,15 @@ namespace pkpy{
// Skip utf8 BOM if there is any.
if (strncmp(source.begin(), "\xEF\xBB\xBF", 3) == 0) index += 3;
// Drop all '\r'
std::stringstream ss;
SStream ss;
while(index < source.length()){
if(source[index] != '\r') ss << source[index];
index++;
}
this->filename = filename;
this->source = ss.str();
line_starts.push_back(this->source.c_str());
this->source = std::move(ss.str());
line_starts.push_back(this->source.begin());
this->mode = mode;
}
@ -31,7 +31,7 @@ namespace pkpy{
}
Str SourceData::snapshot(int lineno, const char* cursor, std::string_view name) const{
std::stringstream ss;
SStream ss;
ss << " " << "File \"" << filename << "\", line " << lineno;
if(!name.empty()) ss << ", in " << name;
ss << '\n';
@ -53,7 +53,7 @@ namespace pkpy{
Str Exception::summary() const {
stack<ExceptionLine> st(stacktrace);
std::stringstream ss;
SStream ss;
if(is_re) ss << "Traceback (most recent call last):\n";
while(!st.empty()) {
ss << st.top().snapshot() << '\n';

View File

@ -44,7 +44,7 @@ namespace pkpy{
}
std::string CodeEmitContext::_log_s_expr(){
std::stringstream ss;
std::stringstream ss; // debug
for(auto& e: s_expr.data()) ss << e->str() << " ";
return ss.str();
}

View File

@ -57,7 +57,7 @@ namespace pkpy{
vm->bind__repr__(PK_OBJ_GET(Type, type), [](VM* vm, PyObject* obj){
PyVec2& self = _CAST(PyVec2&, obj);
std::stringstream ss;
SStream ss;
ss << "vec2(" << self.x << ", " << self.y << ")";
return VAR(ss.str());
});
@ -117,7 +117,7 @@ namespace pkpy{
vm->bind__repr__(PK_OBJ_GET(Type, type), [](VM* vm, PyObject* obj){
PyVec3& self = _CAST(PyVec3&, obj);
std::stringstream ss;
SStream ss;
ss << "vec3(" << self.x << ", " << self.y << ", " << self.z << ")";
return VAR(ss.str());
});
@ -155,7 +155,7 @@ namespace pkpy{
vm->bind__repr__(PK_OBJ_GET(Type, type), [](VM* vm, PyObject* obj){
PyVec4& self = _CAST(PyVec4&, obj);
std::stringstream ss;
SStream ss;
ss << "vec4(" << self.x << ", " << self.y << ", " << self.z << ", " << self.w << ")";
return VAR(ss.str());
});

View File

@ -319,7 +319,7 @@ void init_builtins(VM* _vm) {
});
_vm->bind_builtin_func<1>("hex", [](VM* vm, ArgsView args) {
std::stringstream ss;
std::stringstream ss; // hex
ss << std::hex << CAST(i64, args[0]);
return VAR("0x" + ss.str());
});
@ -333,7 +333,7 @@ void init_builtins(VM* _vm) {
});
_vm->bind_builtin_func<1>("bin", [](VM* vm, ArgsView args) {
std::stringstream ss;
SStream ss;
i64 x = CAST(i64, args[0]);
if(x < 0){ ss << "-"; x = -x; }
ss << "0b";
@ -364,7 +364,7 @@ void init_builtins(VM* _vm) {
_vm->bind__repr__(_vm->tp_object, [](VM* vm, PyObject* obj) {
if(is_tagged(obj)) FATAL_ERROR();
std::stringstream ss;
std::stringstream ss; // hex
ss << "<" << OBJ_NAME(vm->_t(obj)) << " object at 0x";
ss << std::hex << reinterpret_cast<intptr_t>(obj) << ">";
return VAR(ss.str());
@ -542,7 +542,7 @@ void init_builtins(VM* _vm) {
_vm->bind__repr__(_vm->tp_float, [](VM* vm, PyObject* obj) {
f64 val = _CAST(f64, obj);
if(std::isinf(val) || std::isnan(val)) return VAR(std::to_string(val));
std::stringstream ss;
std::stringstream ss; // float
ss << std::setprecision(std::numeric_limits<f64>::max_digits10-1) << val;
std::string s = ss.str();
if(std::all_of(s.begin()+1, s.end(), isdigit)) s += ".0";
@ -565,7 +565,7 @@ void init_builtins(VM* _vm) {
_vm->bind__mul__(_vm->tp_str, [](VM* vm, PyObject* lhs, PyObject* rhs) {
const Str& self = _CAST(Str&, lhs);
i64 n = CAST(i64, rhs);
std::stringstream ss;
SStream ss;
for(i64 i = 0; i < n; i++) ss << self.sv();
return VAR(ss.str());
});
@ -573,7 +573,7 @@ void init_builtins(VM* _vm) {
_vm->bind_method<1>("str", "__rmul__", [](VM* vm, ArgsView args) {
const Str& self = _CAST(Str&, args[0]);
i64 n = CAST(i64, args[1]);
std::stringstream ss;
SStream ss;
for(i64 i = 0; i < n; i++) ss << self.sv();
return VAR(ss.str());
});
@ -701,7 +701,7 @@ void init_builtins(VM* _vm) {
/************ list ************/
_vm->bind__repr__(_vm->tp_list, [](VM* vm, PyObject* _0){
List& iterable = _CAST(List&, _0);
std::stringstream ss;
SStream ss;
ss << '[';
for(int i=0; i<iterable.size(); i++){
ss << CAST(Str&, vm->py_repr(iterable[i]));
@ -713,7 +713,7 @@ void init_builtins(VM* _vm) {
_vm->bind__repr__(_vm->tp_tuple, [](VM* vm, PyObject* _0){
Tuple& iterable = _CAST(Tuple&, _0);
std::stringstream ss;
SStream ss;
ss << '(';
if(iterable.size() == 1){
ss << CAST(Str&, vm->py_repr(iterable[0]));
@ -1003,10 +1003,12 @@ void init_builtins(VM* _vm) {
_vm->bind__repr__(_vm->tp_bytes, [](VM* vm, PyObject* obj) {
const Bytes& self = _CAST(Bytes&, obj);
std::stringstream ss;
SStream ss;
ss << "b'";
for(int i=0; i<self.size(); i++){
ss << "\\x" << std::hex << std::setw(2) << std::setfill('0') << self[i];
ss << "\\x"; // << std::hex << std::setw(2) << std::setfill('0') << self[i];
ss << "0123456789ABCDEF"[self[i] >> 4];
ss << "0123456789ABCDEF"[self[i] & 0xf];
}
ss << "'";
return VAR(ss.str());
@ -1032,7 +1034,7 @@ void init_builtins(VM* _vm) {
_vm->bind__repr__(_vm->tp_slice, [](VM* vm, PyObject* obj) {
const Slice& self = _CAST(Slice&, obj);
std::stringstream ss;
SStream ss;
ss << "slice(";
ss << CAST(Str, vm->py_repr(self.start)) << ", ";
ss << CAST(Str, vm->py_repr(self.stop)) << ", ";
@ -1088,7 +1090,7 @@ void init_builtins(VM* _vm) {
_vm->bind__repr__(_vm->tp_mappingproxy, [](VM* vm, PyObject* obj) {
MappingProxy& self = _CAST(MappingProxy&, obj);
std::stringstream ss;
SStream ss;
ss << "mappingproxy({";
bool first = true;
for(auto& item : self.attr().items()){
@ -1171,7 +1173,7 @@ void init_builtins(VM* _vm) {
// _vm->bind_method<0>("dict", "_data", [](VM* vm, ArgsView args) {
// Dict& self = _CAST(Dict&, args[0]);
// std::stringstream ss;
// SStream ss;
// ss << "[\n";
// for(int i=0; i<self._capacity; i++){
// auto item = self._items[i];
@ -1257,7 +1259,7 @@ void init_builtins(VM* _vm) {
_vm->bind__repr__(_vm->tp_dict, [](VM* vm, PyObject* obj) {
Dict& self = _CAST(Dict&, obj);
std::stringstream ss;
SStream ss;
ss << "{";
bool first = true;

View File

@ -8,7 +8,7 @@ typedef int (*LuaStyleFuncC)(VM*);
#define PK_ASSERT_N_EXTRA_ELEMENTS(n) \
int __ex_count = count_extra_elements(vm, n); \
if(__ex_count < n){ \
std::string msg = fmt("expected at least ", n, " elements, got ", __ex_count); \
Str msg = fmt("expected at least ", n, " elements, got ", __ex_count); \
pkpy_error(vm_handle, "StackError", pkpy_string(msg.c_str())); \
return false; \
}

View File

@ -225,12 +225,12 @@ int utf8len(unsigned char c, bool suppress){
}
Str Str::escape(bool single_quote) const{
std::stringstream ss;
SStream ss;
escape_(ss, single_quote);
return ss.str();
}
void Str::escape_(std::stringstream& ss, bool single_quote) const {
void Str::escape_(SStream& ss, bool single_quote) const {
ss << (single_quote ? '\'' : '"');
for (int i=0; i<length(); i++) {
char c = this->operator[](i);
@ -249,7 +249,9 @@ int utf8len(unsigned char c, bool suppress){
case '\t': ss << "\\t"; break;
default:
if ('\x00' <= c && c <= '\x1f') {
ss << "\\x" << std::hex << std::setw(2) << std::setfill('0') << (int)c;
ss << "\\x"; // << std::hex << std::setw(2) << std::setfill('0') << (int)c;
ss << "0123456789abcdef"[c >> 4];
ss << "0123456789abcdef"[c & 0xf];
} else {
ss << c;
}
@ -273,7 +275,7 @@ int utf8len(unsigned char c, bool suppress){
}
Str Str::replace(const Str& old, const Str& new_, int count) const {
std::stringstream ss;
SStream ss;
int start = 0;
while(true){
int i = index(old, start);
@ -313,7 +315,7 @@ int utf8len(unsigned char c, bool suppress){
}
Str Str::u8_slice(int start, int stop, int step) const{
std::stringstream ss;
SStream ss;
if(is_ascii){
for(int i=start; step>0?i<stop:i>stop; i+=step) ss << data[i];
}else{

View File

@ -5,7 +5,7 @@ namespace pkpy{
struct JsonSerializer{
VM* vm;
PyObject* root;
std::stringstream ss;
SStream ss;
JsonSerializer(VM* vm, PyObject* root) : vm(vm), root(root) {}
@ -61,7 +61,7 @@ namespace pkpy{
}
}
std::string serialize(){
Str serialize(){
auto _lock = vm->heap.gc_scope_lock();
write_object(root);
return ss.str();
@ -218,7 +218,7 @@ namespace pkpy{
PyObject* obj = builtins->attr().try_get_likely_found(type);
if(obj == nullptr){
for(auto& t: _all_types) if(t.name == type) return t.obj;
throw std::runtime_error(fmt("type not found: ", type));
throw std::runtime_error(fmt("type not found: ", type).str());
}
check_non_tagged_type(obj, tp_type);
return obj;
@ -288,7 +288,7 @@ namespace pkpy{
PyObject* VM::py_import(Str path, bool throw_err){
if(path.empty()) vm->ValueError("empty module name");
auto f_join = [](const std::vector<std::string_view>& cpnts){
std::stringstream ss;
SStream ss;
for(int i=0; i<cpnts.size(); i++){
if(i != 0) ss << ".";
ss << cpnts[i];
@ -534,7 +534,7 @@ PyObject* VM::format(Str spec, PyObject* obj){
if(type == 'f'){
f64 val = CAST(f64, obj);
if(precision < 0) precision = 6;
std::stringstream ss;
std::stringstream ss; // float
ss << std::fixed << std::setprecision(precision) << val;
ret = ss.str();
}else if(type == 'd'){
@ -568,7 +568,7 @@ PyObject* VM::new_module(Str name, Str package) {
// we do not allow override in order to avoid memory leak
// it is because Module objects are not garbage collected
if(_modules.contains(name)){
throw std::runtime_error(fmt("module ", name.escape(), " already exists"));
throw std::runtime_error(fmt("module ", name.escape(), " already exists").str());
}
// convert to fullname and set it into _modules
if(!package.empty()) name = package + "." + name;
@ -582,20 +582,20 @@ static std::string _opcode_argstr(VM* vm, Bytecode byte, const CodeObject* co){
switch(byte.op){
case OP_LOAD_CONST: case OP_FORMAT_STRING: case OP_IMPORT_PATH:
if(vm != nullptr){
argStr += fmt(" (", CAST(Str, vm->py_repr(co->consts[byte.arg])), ")");
argStr += fmt(" (", CAST(Str, vm->py_repr(co->consts[byte.arg])), ")").sv();
}
break;
case OP_LOAD_NAME: case OP_LOAD_GLOBAL: case OP_LOAD_NONLOCAL: case OP_STORE_GLOBAL:
case OP_LOAD_ATTR: case OP_LOAD_METHOD: case OP_STORE_ATTR: case OP_DELETE_ATTR:
case OP_BEGIN_CLASS: case OP_RAISE: case OP_GOTO:
case OP_DELETE_GLOBAL: case OP_INC_GLOBAL: case OP_DEC_GLOBAL: case OP_STORE_CLASS_ATTR:
argStr += fmt(" (", StrName(byte.arg).sv(), ")");
argStr += fmt(" (", StrName(byte.arg).sv(), ")").sv();
break;
case OP_LOAD_FAST: case OP_STORE_FAST: case OP_DELETE_FAST: case OP_INC_FAST: case OP_DEC_FAST:
argStr += fmt(" (", co->varnames[byte.arg].sv(), ")");
argStr += fmt(" (", co->varnames[byte.arg].sv(), ")").sv();
break;
case OP_LOAD_FUNCTION:
argStr += fmt(" (", co->func_decls[byte.arg]->code->name, ")");
argStr += fmt(" (", co->func_decls[byte.arg]->code->name, ")").sv();
break;
}
return argStr;
@ -618,7 +618,7 @@ Str VM::disassemble(CodeObject_ co){
if(target != nullptr) jumpTargets.push_back(*target);
}
}
std::stringstream ss;
SStream ss;
int prev_line = -1;
for(int i=0; i<co->codes.size(); i++){
const Bytecode& byte = co->codes[i];
@ -657,7 +657,7 @@ Str VM::disassemble(CodeObject_ co){
void VM::_log_s_data(const char* title) {
if(_main == nullptr) return;
if(callstack.empty()) return;
std::stringstream ss;
SStream ss;
if(title) ss << title << " | ";
std::map<PyObject**, int> sp_bases;
for(Frame& f: callstack.data()){

View File

@ -21,12 +21,12 @@ min_num = -10.0
max_num = 10.0
test_vec2 = vec2(*tuple([random.uniform(min_num, max_num) for _ in range(2)]))
test_vec2_2 = vec2(*tuple([random.uniform(min_num, max_num) for _ in range(2)]))
static_test_vec2_float = vec2(3.1886954323, -1098399.59932453432)
static_test_vec2_int = vec2(278, -13919730938747)
static_test_vec2_float = vec2(3.18, -1.09)
static_test_vec2_int = vec2(278, -1391)
# test __repr__
assert str(static_test_vec2_float) == 'vec2(3.1887, -1.0984e+06)'
assert str(static_test_vec2_int) == 'vec2(278, -1.39197e+13)'
assert str(static_test_vec2_float).startswith('vec2(')
assert str(static_test_vec2_int).startswith('vec2(')
# test copy
element_name_list = [e for e in dir(test_vec2) if e in 'x,y,z,w']
@ -56,8 +56,8 @@ static_test_vec3_float = vec3(3.1886954323, -1098399.59932453432, 9.000000000000
static_test_vec3_int = vec3(278, -13919730938747, 1364223456756456)
# test __repr__
assert str(static_test_vec3_float) == 'vec3(3.1887, -1.0984e+06, 9)'
assert str(static_test_vec3_int) == 'vec3(278, -1.39197e+13, 1.36422e+15)'
assert str(static_test_vec3_float).startswith('vec3(')
assert str(static_test_vec3_int).startswith('vec3(')
# test __getnewargs__
element_name_list = ['x', 'y', 'z']
@ -79,8 +79,8 @@ static_test_vec4_float = vec4(3.1886954323, -1098399.59932453432, 9.000000000000
static_test_vec4_int = vec4(278, -13919730938747, 1364223456756456, -37)
# test __repr__
assert str(static_test_vec4_float) == 'vec4(3.1887, -1.0984e+06, 9, 4.5654e+12)'
assert str(static_test_vec4_int) == 'vec4(278, -1.39197e+13, 1.36422e+15, -37)'
assert str(static_test_vec4_float).startswith('vec4(')
assert str(static_test_vec4_int).startswith('vec4(')
# test __getnewargs__
element_name_list = ['x', 'y', 'z', 'w']