This commit is contained in:
blueloveTH 2023-04-27 19:11:46 +08:00
parent de16324601
commit f240d0e9f4
3 changed files with 27 additions and 10 deletions

View File

@ -549,7 +549,7 @@ __NEXT_STEP:;
TARGET(FORMAT_STRING) { TARGET(FORMAT_STRING) {
_0 = POPX(); _0 = POPX();
const Str& spec = CAST(Str&, co_consts[byte.arg]); const Str& spec = CAST(Str&, co_consts[byte.arg]);
PUSH(VAR(format(spec, _0))); PUSH(format(spec, _0));
} DISPATCH(); } DISPATCH();
#if !PK_ENABLE_COMPUTED_GOTO #if !PK_ENABLE_COMPUTED_GOTO
#if DEBUG_EXTRA_CHECK #if DEBUG_EXTRA_CHECK

View File

@ -395,7 +395,7 @@ public:
PyObject* getattr(PyObject* obj, StrName name, bool throw_err=true); PyObject* getattr(PyObject* obj, StrName name, bool throw_err=true);
PyObject* get_unbound_method(PyObject* obj, StrName name, PyObject** self, bool throw_err=true, bool fallback=false); PyObject* get_unbound_method(PyObject* obj, StrName name, PyObject** self, bool throw_err=true, bool fallback=false);
void parse_int_slice(const Slice& s, int length, int& start, int& stop, int& step); void parse_int_slice(const Slice& s, int length, int& start, int& stop, int& step);
Str format(Str, PyObject*); PyObject* format(Str, PyObject*);
void setattr(PyObject* obj, StrName name, PyObject* value); void setattr(PyObject* obj, StrName name, PyObject* value);
template<int ARGC> template<int ARGC>
void bind_method(PyObject*, Str, NativeFuncC); void bind_method(PyObject*, Str, NativeFuncC);
@ -642,24 +642,36 @@ inline PyObject* VM::asRepr(PyObject* obj){
return call_method(obj, __repr__); return call_method(obj, __repr__);
} }
inline Str VM::format(Str spec, PyObject* obj){ inline PyObject* VM::format(Str spec, PyObject* obj){
char type = spec.end()[-1]; if(spec.empty()) return asStr(obj);
int dot = -1; char type;
int width, precision; switch(spec.end()[-1]){
case 'f': case 'd': case 's':
type = spec.end()[-1];
spec = spec.substr(0, spec.length() - 1);
break;
default: type = ' '; break;
}
char pad_c = ' ';
if(spec[0] == '0'){
pad_c = '0';
spec = spec.substr(1);
}
char align; char align;
if(spec[0] == '>'){ if(spec[0] == '>'){
align = '>'; align = '>';
spec = spec.substr(1); spec = spec.substr(1);
dot = spec.index(".");
}else if(spec[0] == '<'){ }else if(spec[0] == '<'){
align = '<'; align = '<';
spec = spec.substr(1); spec = spec.substr(1);
dot = spec.index(".");
}else{ }else{
if(is_int(obj) || is_float(obj)) align = '>'; if(is_int(obj) || is_float(obj)) align = '>';
else align = '<'; else align = '<';
} }
int dot = spec.index(".");
int width, precision;
try{ try{
if(dot >= 0){ if(dot >= 0){
width = Number::stoi(spec.substr(0, dot).str()); width = Number::stoi(spec.substr(0, dot).str());
@ -689,11 +701,11 @@ inline Str VM::format(Str spec, PyObject* obj){
} }
if(width > ret.length()){ if(width > ret.length()){
int pad = width - ret.length(); int pad = width - ret.length();
std::string padding(pad, ' '); std::string padding(pad, pad_c);
if(align == '>') ret = padding.c_str() + ret; if(align == '>') ret = padding.c_str() + ret;
else ret = ret + padding.c_str(); else ret = ret + padding.c_str();
} }
return ret; return VAR(ret);
} }
inline PyObject* VM::new_module(StrName name) { inline PyObject* VM::new_module(StrName name) {

View File

@ -38,6 +38,11 @@ assert f'{a:>10.2f}' == ' 10.00'
assert f'{a:3d}' == ' 10' assert f'{a:3d}' == ' 10'
assert f'{a:10d}' == ' 10' assert f'{a:10d}' == ' 10'
assert f'{a:1d}' == '10' assert f'{a:1d}' == '10'
assert f'{a:010}' == '0000000010'
assert f'{a:010d}' == '0000000010'
assert f'{a:010f}' == '010.000000'
assert f'{a:010.2f}' == '0000010.00'
b = '123' b = '123'
assert f'{b:10}' == '123 ' assert f'{b:10}' == '123 '
assert f'{b:>10}' == ' 123' assert f'{b:>10}' == ' 123'