Kaynağa Gözat

up

Update 2.py

Update 2.py

up
blueloveTH 3 yıl önce
ebeveyn
işleme
d1f12ee90c
6 değiştirilmiş dosya ile 32 ekleme ve 16 silme
  1. 2 0
      .github/workflows/main.yml
  2. 5 0
      src/builtins.h
  3. 9 2
      src/pocketpy.h
  4. 3 3
      src/str.h
  5. 9 11
      src/vm.h
  6. 4 0
      tests/2.py

+ 2 - 0
.github/workflows/main.yml

@@ -12,6 +12,7 @@ jobs:
         CL -std:c++17 -GR- -EHsc -O2 -Fe:pocketpy src/main.cpp
         python3 scripts/run_tests.py
         ./pocketpy tests/1.py
+        ./pocketpy tests/2.py
   build_linux:
     runs-on: ubuntu-latest
     steps:
@@ -21,6 +22,7 @@ jobs:
         bash build_cpp.sh
         python3 scripts/run_tests.py
         ./pocketpy tests/1.py
+        ./pocketpy tests/2.py
   build_web:
     runs-on: ubuntu-latest
     steps:

+ 5 - 0
src/builtins.h

@@ -155,6 +155,8 @@ def __iterable4__eq__(self, other):
     return True
 list.__eq__ = __iterable4__eq__
 tuple.__eq__ = __iterable4__eq__
+list.__ne__ = lambda self, other: not self.__eq__(other)
+tuple.__ne__ = lambda self, other: not self.__eq__(other)
 del __iterable4__eq__
 
 def __iterable4count(self, x):
@@ -396,6 +398,9 @@ class set:
     
     def __eq__(self, other):
         return self.__xor__(other).__len__() == 0
+
+    def __ne__(self, other):
+        return self.__xor__(other).__len__() != 0
     
     def isdisjoint(self, other):
         return self.__and__(other).__len__() == 0

+ 9 - 2
src/pocketpy.h

@@ -29,7 +29,7 @@ _Code VM::compile(_Str source, _Str filename, CompileMode mode) {
         bool _0 = args[0]->is_type(vm->_tp_int) || args[0]->is_type(vm->_tp_float);                     \
         bool _1 = args[1]->is_type(vm->_tp_int) || args[1]->is_type(vm->_tp_float);                     \
         if(!_0 || !_1){                                                                                 \
-            if constexpr(is_eq) return vm->PyBool(args[0] == args[1]);                                  \
+            if constexpr(is_eq) return vm->PyBool(args[0].get() op args[1].get());                      \
             vm->typeError("unsupported operand type(s) for " #op );                                     \
         }                                                                                               \
         return vm->PyBool(vm->num_to_float(args[0]) op vm->num_to_float(args[1]));                      \
@@ -46,6 +46,7 @@ void __initializeBuiltinFunctions(VM* _vm) {
     BIND_NUM_LOGICAL_OPT(__gt__, >, false)
     BIND_NUM_LOGICAL_OPT(__ge__, >=, false)
     BIND_NUM_LOGICAL_OPT(__eq__, ==, true)
+    BIND_NUM_LOGICAL_OPT(__ne__, !=, true)
 
 #undef BIND_NUM_ARITH_OPT
 #undef BIND_NUM_LOGICAL_OPT
@@ -133,7 +134,7 @@ void __initializeBuiltinFunctions(VM* _vm) {
     });
 
     _vm->bindMethod<1>("object", "__eq__", CPP_LAMBDA(vm->PyBool(args[0] == args[1])));
-
+    _vm->bindMethod<1>("object", "__ne__", CPP_LAMBDA(vm->PyBool(args[0] != args[1])));
     _vm->bindStaticMethod<1>("type", "__new__", CPP_LAMBDA(args[0]->_type));
 
     _vm->bindStaticMethod<-1>("range", "__new__", [](VM* vm, const pkpy::ArgList& args) {
@@ -299,6 +300,12 @@ void __initializeBuiltinFunctions(VM* _vm) {
         return vm->PyBool(args[0] == args[1]);
     });
 
+    _vm->bindMethod<1>("str", "__ne__", [](VM* vm, const pkpy::ArgList& args) {
+        if(args[0]->is_type(vm->_tp_str) && args[1]->is_type(vm->_tp_str))
+            return vm->PyBool(vm->PyStr_AS_C(args[0]) != vm->PyStr_AS_C(args[1]));
+        return vm->PyBool(args[0] != args[1]);
+    });
+
     _vm->bindMethod<1>("str", "__getitem__", [](VM* vm, const pkpy::ArgList& args) {
         const _Str& _self (vm->PyStr_AS_C(args[0]));
 

+ 3 - 3
src/str.h

@@ -44,7 +44,7 @@ public:
         }
     }
 
-    size_t hash() const{
+    inline size_t hash() const{
         if(!hash_initialized){
             _hash = std::hash<std::string>()(*this);
             hash_initialized = true;
@@ -141,7 +141,7 @@ public:
 namespace std {
     template<>
     struct hash<_Str> {
-        std::size_t operator()(const _Str& s) const {
+        inline std::size_t operator()(const _Str& s) const {
             return s.hash();
         }
     };
@@ -171,7 +171,7 @@ const _Str& __exit__ = _Str("__exit__");
 
 const _Str CMP_SPECIAL_METHODS[] = {
     "__lt__", "__le__", "__eq__", "__ne__", "__gt__", "__ge__"
-};  // __ne__ should not be used
+};
 
 const _Str BINARY_SPECIAL_METHODS[] = {
     "__add__", "__sub__", "__mul__", "__truediv__", "__floordiv__", "__mod__", "__pow__"

+ 9 - 11
src/vm.h

@@ -147,17 +147,17 @@ protected:
                 } break;
             case OP_COMPARE_OP:
                 {
-                    // for __ne__ we use the negation of __eq__
-                    int op = byte.arg == 3 ? 2 : byte.arg;
-                    PyVar res = fast_call(CMP_SPECIAL_METHODS[op], frame->pop_n_values_reversed(this, 2));
-                    if(op != byte.arg) res = PyBool(!PyBool_AS_C(res));
-                    frame->push(std::move(res));
+                    pkpy::ArgList args(2);
+                    args[1] = frame->pop_value(this);
+                    args[0] = frame->top_value(this);
+                    frame->top() = fast_call(CMP_SPECIAL_METHODS[byte.arg], std::move(args));
                 } break;
             case OP_IS_OP:
                 {
-                    bool ret_c = frame->pop_value(this) == frame->pop_value(this);
+                    PyVar rhs = frame->pop_value(this);
+                    bool ret_c = rhs == frame->top_value(this);
                     if(byte.arg == 1) ret_c = !ret_c;
-                    frame->push(PyBool(ret_c));
+                    frame->top() = PyBool(ret_c);
                 } break;
             case OP_CONTAINS_OP:
                 {
@@ -167,10 +167,8 @@ protected:
                     frame->push(PyBool(ret_c));
                 } break;
             case OP_UNARY_NEGATIVE:
-                {
-                    PyVar obj = frame->pop_value(this);
-                    frame->push(num_negated(obj));
-                } break;
+                frame->top() = num_negated(frame->top_value(this));
+                break;
             case OP_UNARY_NOT:
                 {
                     PyVar obj = frame->pop_value(this);

+ 4 - 0
tests/2.py

@@ -0,0 +1,4 @@
+import random
+
+a = [random.randint(-100000, 100000) for i in range(1500)]
+a = sorted(a)