From 630828f6e99385913d4833e3964bc27b1cee7eab Mon Sep 17 00:00:00 2001 From: blueloveTH Date: Mon, 7 Nov 2022 22:07:15 +0800 Subject: [PATCH] fix eq problem --- src/builtins.h | 16 +++++----------- src/compiler.h | 1 - src/pocketpy.h | 13 +++---------- src/str.h | 2 +- src/vm.h | 18 +++++++++++++++--- 5 files changed, 24 insertions(+), 26 deletions(-) diff --git a/src/builtins.h b/src/builtins.h index c325c2d2..eb55dd81 100644 --- a/src/builtins.h +++ b/src/builtins.h @@ -73,12 +73,10 @@ tuple.__contains__ = __iterable4__contains__ # https://github.com/python/cpython/blob/main/Objects/dictobject.c class dict: - def __init__(self, tuples): + def __init__(self): self._capacity = 8 self._a = [None] * self._capacity self._len = 0 - for i in tuples: - self[i[0]] = i[1] def __len__(self): return self._len @@ -92,20 +90,17 @@ class dict: return False,i def __getitem__(self, key): - ret = self.__probe(key) - ok = ret[0]; i = ret[1] + ok, i = self.__probe(key) if not ok: raise KeyError(key) return self._a[i][1] def __contains__(self, key): - ret = self.__probe(key) - ok = ret[0]; i = ret[1] + ok, i = self.__probe(key) return ok def __setitem__(self, key, value): - ret = self.__probe(key) - ok = ret[0]; i = ret[1] + ok, i = self.__probe(key) if ok: self._a[i][1] = value else: @@ -115,8 +110,7 @@ class dict: self.__resize_2x() def __delitem__(self, key): - ret = self.__probe(key) - ok = ret[0]; i = ret[1] + ok, i = self.__probe(key) if not ok: raise KeyError(key) self._a[i] = None diff --git a/src/compiler.h b/src/compiler.h index 93813aa7..89c604da 100644 --- a/src/compiler.h +++ b/src/compiler.h @@ -400,7 +400,6 @@ public: matchNewLines(); if (peek() == TK("}")) break; EXPR();consume(TK(":"));EXPR(); - emitCode(OP_BUILD_SMART_TUPLE, 2); size++; matchNewLines(); } while (match(TK(","))); diff --git a/src/pocketpy.h b/src/pocketpy.h index 3fd416f3..f1571377 100644 --- a/src/pocketpy.h +++ b/src/pocketpy.h @@ -39,7 +39,6 @@ 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 @@ -200,15 +199,9 @@ void __initializeBuiltinFunctions(VM* _vm) { }); _vm->bindMethod("str", "__eq__", [](VM* vm, PyVarList args) { - const _Str& _self = vm->PyStr_AS_C(args[0]); - const _Str& _other = vm->PyStr_AS_C(args[1]); - return vm->PyBool(_self == _other); - }); - - _vm->bindMethod("str", "__ne__", [](VM* vm, PyVarList args) { - const _Str& _self = vm->PyStr_AS_C(args[0]); - const _Str& _other = vm->PyStr_AS_C(args[1]); - return vm->PyBool(_self != _other); + 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(args[0] == args[1]); // fallback }); _vm->bindMethod("str", "__getitem__", [](VM* vm, PyVarList args) { diff --git a/src/str.h b/src/str.h index 7b8bc0f4..8a93ac1b 100644 --- a/src/str.h +++ b/src/str.h @@ -147,7 +147,7 @@ const _Str& __init__ = _Str("__init__"); const _Str CMP_SPECIAL_METHODS[] = { "__lt__", "__le__", "__eq__", "__ne__", "__gt__", "__ge__" -}; +}; // __ne__ should not be used const _Str BIN_SPECIAL_METHODS[] = { "__add__", "__sub__", "__mul__", "__truediv__", "__floordiv__", "__mod__", "__pow__" diff --git a/src/vm.h b/src/vm.h index 8aec3c4c..d0192af0 100644 --- a/src/vm.h +++ b/src/vm.h @@ -240,7 +240,16 @@ public: } break; case OP_POP_TOP: frame->popValue(this); break; case OP_BINARY_OP: BINARY_XXX(byte.arg) break; - case OP_COMPARE_OP: COMPARE_XXX(byte.arg) break; + case OP_COMPARE_OP: + { + PyVar rhs = frame->popValue(this); + PyVar lhs = frame->popValue(this); + // for __ne__ we use the negation of __eq__ + int op = byte.arg == 3 ? 2 : byte.arg; + PyVar res = fastCall(lhs, CMP_SPECIAL_METHODS[op], {lhs,rhs}); + if(op != byte.arg) res = PyBool(!PyBool_AS_C(res)); + frame->push(res); + } break; case OP_IS_OP: { bool ret_c = frame->popValue(this) == frame->popValue(this); @@ -290,8 +299,11 @@ public: } break; case OP_BUILD_MAP: { - PyVarList items = frame->popNValuesReversed(this, byte.arg); - PyVar obj = call(builtins->attribs["dict"], {PyList(items)}); + PyVarList items = frame->popNValuesReversed(this, byte.arg*2); + PyVar obj = call(builtins->attribs["dict"], {}); + for(int i=0; ipush(obj); } break; case OP_DUP_TOP: frame->push(frame->topValue(this)); break;