blueloveTH пре 2 година
родитељ
комит
f240d0e9f4
3 измењених фајлова са 27 додато и 10 уклоњено
  1. 1 1
      src/ceval.h
  2. 21 9
      src/vm.h
  3. 5 0
      tests/25_rawstring.py

+ 1 - 1
src/ceval.h

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

+ 21 - 9
src/vm.h

@@ -395,7 +395,7 @@ public:
     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);
     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);
     template<int ARGC>
     void bind_method(PyObject*, Str, NativeFuncC);
@@ -642,24 +642,36 @@ inline PyObject* VM::asRepr(PyObject* obj){
     return call_method(obj, __repr__);
 }
 
-inline Str VM::format(Str spec, PyObject* obj){
-    char type = spec.end()[-1];
-    int dot = -1;
-    int width, precision;
+inline PyObject* VM::format(Str spec, PyObject* obj){
+    if(spec.empty()) return asStr(obj);
+    char type;
+    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;
     if(spec[0] == '>'){
         align = '>';
         spec = spec.substr(1);
-        dot = spec.index(".");
     }else if(spec[0] == '<'){
         align = '<';
         spec = spec.substr(1);
-        dot = spec.index(".");
     }else{
         if(is_int(obj) || is_float(obj)) align = '>';
         else align = '<';
     }
 
+    int dot = spec.index(".");
+    int width, precision;
     try{
         if(dot >= 0){
             width = Number::stoi(spec.substr(0, dot).str());
@@ -689,11 +701,11 @@ inline Str VM::format(Str spec, PyObject* obj){
     }
     if(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;
         else ret = ret + padding.c_str();
     }
-    return ret;
+    return VAR(ret);
 }
 
 inline PyObject* VM::new_module(StrName name) {

+ 5 - 0
tests/25_rawstring.py

@@ -38,6 +38,11 @@ assert f'{a:>10.2f}' == '     10.00'
 assert f'{a:3d}' == ' 10'
 assert f'{a:10d}' == '        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'
 assert f'{b:10}' == '123       '
 assert f'{b:>10}' == '       123'