blueloveTH 3 роки тому
батько
коміт
81516eafb5
4 змінених файлів з 33 додано та 16 видалено
  1. 8 8
      src/builtins.h
  2. 15 5
      src/pocketpy.h
  3. 1 0
      src/str.h
  4. 9 3
      src/vm.h

+ 8 - 8
src/builtins.h

@@ -27,19 +27,19 @@ def __str4split(self, sep):
     return res
     return res
 str.split = __str4split
 str.split = __str4split
 
 
-def __list4__str__(self):
+def __list4__repr__(self):
     a = []
     a = []
     for i in self:
     for i in self:
-        a.append(str(i))
+        a.append(repr(i))
     return '[' + ', '.join(a) + ']'
     return '[' + ', '.join(a) + ']'
-list.__str__ = __list4__str__
+list.__repr__ = __list4__repr__
 
 
-def __tuple4__str__(self):
+def __tuple4__repr__(self):
     a = []
     a = []
     for i in self:
     for i in self:
-        a.append(str(i))
+        a.append(repr(i))
     return '(' + ', '.join(a) + ')'
     return '(' + ', '.join(a) + ')'
-tuple.__str__ = __tuple4__str__
+tuple.__repr__ = __tuple4__repr__
 
 
 def __list4extend(self, other):
 def __list4extend(self, other):
     for i in other:
     for i in other:
@@ -146,10 +146,10 @@ class dict:
                 ret.append(kv)
                 ret.append(kv)
         return ret
         return ret
 
 
-    def __str__(self):
+    def __repr__(self):
         ret = '{'
         ret = '{'
         for kv in self.items():
         for kv in self.items():
-            ret += str(kv[0]) + ': ' + str(kv[1]) + ', '
+            ret += repr(kv[0]) + ': ' + repr(kv[1]) + ', '
         if ret[-2:] == ', ':
         if ret[-2:] == ', ':
             ret = ret[:-2]
             ret = ret[:-2]
         return ret + '}'
         return ret + '}'

+ 15 - 5
src/pocketpy.h

@@ -49,6 +49,10 @@ void __initializeBuiltinFunctions(VM* _vm) {
         return vm->None;
         return vm->None;
     });
     });
 
 
+    _vm->bindBuiltinFunc("repr", [](VM* vm, PyVarList args) {
+        return vm->asRepr(args.at(0));
+    });
+
     _vm->bindBuiltinFunc("hash", [](VM* vm, PyVarList args) {
     _vm->bindBuiltinFunc("hash", [](VM* vm, PyVarList args) {
         return vm->PyInt(vm->hash(args.at(0)));
         return vm->PyInt(vm->hash(args.at(0)));
     });
     });
@@ -83,7 +87,7 @@ void __initializeBuiltinFunctions(VM* _vm) {
         return obj;
         return obj;
     });
     });
 
 
-    _vm->bindMethod("object", "__str__", [](VM* vm, PyVarList args) {
+    _vm->bindMethod("object", "__repr__", [](VM* vm, PyVarList args) {
         PyVar _self = args[0];
         PyVar _self = args[0];
         _Str s = "<" + _self->getTypeName() + " object at " + std::to_string((uintptr_t)_self.get()) + ">";
         _Str s = "<" + _self->getTypeName() + " object at " + std::to_string((uintptr_t)_self.get()) + ">";
         return vm->PyStr(s);
         return vm->PyStr(s);
@@ -116,7 +120,7 @@ void __initializeBuiltinFunctions(VM* _vm) {
         return vm->PyIter(iter);
         return vm->PyIter(iter);
     });
     });
 
 
-    _vm->bindMethod("NoneType", "__str__", [](VM* vm, PyVarList args) {
+    _vm->bindMethod("NoneType", "__repr__", [](VM* vm, PyVarList args) {
         return vm->PyStr("None");
         return vm->PyStr("None");
     });
     });
 
 
@@ -155,7 +159,7 @@ void __initializeBuiltinFunctions(VM* _vm) {
         return vm->PyInt(-1 * vm->PyInt_AS_C(args[0]));
         return vm->PyInt(-1 * vm->PyInt_AS_C(args[0]));
     });
     });
 
 
-    _vm->bindMethod("int", "__str__", [](VM* vm, PyVarList args) {
+    _vm->bindMethod("int", "__repr__", [](VM* vm, PyVarList args) {
         return vm->PyStr(std::to_string(vm->PyInt_AS_C(args[0])));
         return vm->PyStr(std::to_string(vm->PyInt_AS_C(args[0])));
     });
     });
 
 
@@ -164,7 +168,7 @@ void __initializeBuiltinFunctions(VM* _vm) {
         return vm->PyFloat(-1.0f * vm->PyFloat_AS_C(args[0]));
         return vm->PyFloat(-1.0f * vm->PyFloat_AS_C(args[0]));
     });
     });
 
 
-    _vm->bindMethod("float", "__str__", [](VM* vm, PyVarList args) {
+    _vm->bindMethod("float", "__repr__", [](VM* vm, PyVarList args) {
         return vm->PyStr(std::to_string(vm->PyFloat_AS_C(args[0])));
         return vm->PyStr(std::to_string(vm->PyFloat_AS_C(args[0])));
     });
     });
 
 
@@ -198,6 +202,12 @@ void __initializeBuiltinFunctions(VM* _vm) {
         return args[0]; // str is immutable
         return args[0]; // str is immutable
     });
     });
 
 
+    _vm->bindMethod("str", "__repr__", [](VM* vm, PyVarList args) {
+        const _Str& _self = vm->PyStr_AS_C(args[0]);
+        // we just do a simple repr here, no escaping
+        return vm->PyStr("'" + _self.str() + "'");
+    });
+
     _vm->bindMethod("str", "__eq__", [](VM* vm, PyVarList args) {
     _vm->bindMethod("str", "__eq__", [](VM* vm, PyVarList args) {
         if(args.at(0)->isType(vm->_tp_str) && args.at(1)->isType(vm->_tp_str))
         if(args.at(0)->isType(vm->_tp_str) && args.at(1)->isType(vm->_tp_str))
             return vm->PyBool(vm->PyStr_AS_C(args[0]) == vm->PyStr_AS_C(args[1]));
             return vm->PyBool(vm->PyStr_AS_C(args[0]) == vm->PyStr_AS_C(args[1]));
@@ -385,7 +395,7 @@ void __initializeBuiltinFunctions(VM* _vm) {
     });
     });
 
 
     /************ PyBool ************/
     /************ PyBool ************/
-    _vm->bindMethod("bool", "__str__", [](VM* vm, PyVarList args) {
+    _vm->bindMethod("bool", "__repr__", [](VM* vm, PyVarList args) {
         bool val = vm->PyBool_AS_C(args[0]);
         bool val = vm->PyBool_AS_C(args[0]);
         return vm->PyStr(val ? "True" : "False");
         return vm->PyStr(val ? "True" : "False");
     });
     });

+ 1 - 0
src/str.h

@@ -138,6 +138,7 @@ const _Str& __base__ = _Str("__base__");
 const _Str& __new__ = _Str("__new__");
 const _Str& __new__ = _Str("__new__");
 const _Str& __iter__ = _Str("__iter__");
 const _Str& __iter__ = _Str("__iter__");
 const _Str& __str__ = _Str("__str__");
 const _Str& __str__ = _Str("__str__");
+const _Str& __repr__ = _Str("__repr__");
 const _Str& __neg__ = _Str("__neg__");
 const _Str& __neg__ = _Str("__neg__");
 const _Str& __getitem__ = _Str("__getitem__");
 const _Str& __getitem__ = _Str("__getitem__");
 const _Str& __setitem__ = _Str("__setitem__");
 const _Str& __setitem__ = _Str("__setitem__");

+ 9 - 3
src/vm.h

@@ -62,8 +62,14 @@ public:
     }
     }
 
 
     PyVar asStr(const PyVar& obj){
     PyVar asStr(const PyVar& obj){
+        PyVarOrNull str_fn = getAttr(obj, __str__, false);
+        if(str_fn != nullptr) return call(str_fn, {});
+        return asRepr(obj);
+    }
+
+    PyVar asRepr(const PyVar& obj){
         if(obj->isType(_tp_type)) return PyStr("<class '" + obj->getName() + "'>");
         if(obj->isType(_tp_type)) return PyStr("<class '" + obj->getName() + "'>");
-        return call(obj, __str__, {});
+        return call(obj, __repr__, {});
     }
     }
 
 
     PyVar asBool(const PyVar& obj){
     PyVar asBool(const PyVar& obj){
@@ -235,7 +241,7 @@ public:
                 {
                 {
                     const PyVar& expr = frame->topValue(this);
                     const PyVar& expr = frame->topValue(this);
                     if(expr == None) break;
                     if(expr == None) break;
-                    printFn(PyStr_AS_C(asStr(expr)));
+                    printFn(PyStr_AS_C(asRepr(expr)));
                     printFn("\n");
                     printFn("\n");
                 } break;
                 } break;
             case OP_POP_TOP: frame->popValue(this); break;
             case OP_POP_TOP: frame->popValue(this); break;
@@ -288,7 +294,7 @@ public:
                 } break;
                 } break;
             case OP_RAISE_ERROR:
             case OP_RAISE_ERROR:
                 {
                 {
-                    _Str msg = PyStr_AS_C(asStr(frame->popValue(this)));
+                    _Str msg = PyStr_AS_C(asRepr(frame->popValue(this)));
                     _Str type = PyStr_AS_C(frame->popValue(this));
                     _Str type = PyStr_AS_C(frame->popValue(this));
                     _error(type, msg);
                     _error(type, msg);
                 } break;
                 } break;