diff --git a/src/builtins.h b/src/builtins.h index 496a8907..20884ba5 100644 --- a/src/builtins.h +++ b/src/builtins.h @@ -78,7 +78,7 @@ def sorted(iterable, reverse=False): str.__mul__ = lambda self, n: ''.join([self for _ in range(n)]) -def __str4split(self, sep): +def str::split(self, sep): if sep == "": return list(self) res = [] @@ -92,18 +92,14 @@ def __str4split(self, sep): i += 1 res.append(self) return res -str.split = __str4split -del __str4split -def __str4index(self, sub): +def str::index(self, sub): for i in range(len(self)): if self[i:i+len(sub)] == sub: return i return -1 -str.index = __str4index -del __str4index -def __str4strip(self, chars=None): +def str::strip(self, chars=None): chars = chars or ' \t\n\r' i = 0 while i < len(self) and self[i] in chars: @@ -112,8 +108,6 @@ def __str4strip(self, chars=None): while j >= 0 and self[j] in chars: j -= 1 return self[i:j+1] -str.strip = __str4strip -del __str4strip ##### list ##### @@ -136,76 +130,59 @@ def __qsort(a: list, L: int, R: int): __qsort(a, L, j) __qsort(a, i, R) -def __list4sort(self, reverse=False): +def list::sort(self, reverse=False): __qsort(self, 0, len(self)-1) if reverse: self.reverse() -list.sort = __list4sort -del __list4sort - -def __list4extend(self, other): +def list::extend(self, other): for i in other: self.append(i) -list.extend = __list4extend -del __list4extend -def __list4remove(self, value): +def list::remove(self, value): for i in range(len(self)): if self[i] == value: del self[i] return True return False -list.remove = __list4remove -del __list4remove -def __list4index(self, value): +def list::index(self, value): for i in range(len(self)): if self[i] == value: return i return -1 -list.index = __list4index -del __list4index -def __list4pop(self, i=-1): +def list::pop(self, i=-1): res = self[i] del self[i] return res -list.pop = __list4pop -del __list4pop -def __iterable4__eq__(self, other): +def list::__eq__(self, other): if len(self) != len(other): return False for i in range(len(self)): if self[i] != other[i]: return False return True -list.__eq__ = __iterable4__eq__ -tuple.__eq__ = __iterable4__eq__ +tuple.__eq__ = list.__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): +def list::count(self, x): res = 0 for i in self: if i == x: res += 1 return res -list.count = __iterable4count -tuple.count = __iterable4count -del __iterable4count +tuple.count = list.count -def __iterable4__contains__(self, item): +def list::__contains__(self, item): for i in self: if i == item: return True return False -list.__contains__ = __iterable4__contains__ -tuple.__contains__ = __iterable4__contains__ -del __iterable4__contains__ +tuple.__contains__ = list.__contains__ list.__new__ = lambda obj: [i for i in obj] class dict: diff --git a/src/ceval.h b/src/ceval.h index 3c82a989..6fbdc466 100644 --- a/src/ceval.h +++ b/src/ceval.h @@ -54,6 +54,7 @@ PyVar VM::run_frame(Frame* frame){ if(byte.op == OP_FAST_INDEX) frame->push(ref.get(this, frame)); else frame->push(PyRef(ref)); } continue; + case OP_ROT_TWO: std::swap(frame->top(), frame->top_1()); continue; case OP_STORE_REF: { // PyVar obj = frame->pop_value(this); // PyVarRef r = frame->pop(); diff --git a/src/compiler.h b/src/compiler.h index 7b9b3d7c..1e3ea967 100644 --- a/src/compiler.h +++ b/src/compiler.h @@ -200,7 +200,7 @@ private: case '{': parser->set_next_token(TK("{")); return; case '}': parser->set_next_token(TK("}")); return; case ',': parser->set_next_token(TK(",")); return; - case ':': parser->set_next_token(TK(":")); return; + case ':': parser->set_next_token_2(':', TK(":"), TK("::")); return; case ';': parser->set_next_token(TK(";")); return; case '(': parser->set_next_token(TK("(")); return; case ')': parser->set_next_token(TK(")")); return; @@ -1025,8 +1025,14 @@ __LISTCOMP: consume(TK("def")); } pkpy::Function func; + StrName obj_name; consume(TK("@id")); func.name = parser->prev.str(); + if(!is_compiling_class && match(TK("::"))){ + consume(TK("@id")); + obj_name = func.name; + func.name = parser->prev.str(); + } consume(TK("(")); if (!match(TK(")"))) { _compile_f_args(func, true); @@ -1040,7 +1046,16 @@ __LISTCOMP: this->codes.pop(); emit(OP_LOAD_FUNCTION, co()->add_const(vm->PyFunction(func))); if(name_scope() == NAME_LOCAL) emit(OP_SETUP_CLOSURE); - if(!is_compiling_class) emit(OP_STORE_NAME, co()->add_name(func.name, name_scope())); + if(!is_compiling_class){ + if(obj_name.empty()) emit(OP_STORE_NAME, co()->add_name(func.name, name_scope())); + else { + emit(OP_LOAD_NAME, co()->add_name(obj_name, name_scope())); + int index = co()->add_name(func.name, NAME_ATTR); + emit(OP_BUILD_ATTR, (index<<1)+0); + emit(OP_ROT_TWO); + emit(OP_STORE_REF); + } + } } PyVarOrNull read_literal(){ diff --git a/src/opcodes.h b/src/opcodes.h index 4a44f38a..b900cd39 100644 --- a/src/opcodes.h +++ b/src/opcodes.h @@ -8,6 +8,7 @@ OPCODE(CALL_UNPACK) OPCODE(CALL_KWARGS) OPCODE(CALL_KWARGS_UNPACK) OPCODE(RETURN_VALUE) +OPCODE(ROT_TWO) OPCODE(BINARY_OP) OPCODE(COMPARE_OP) diff --git a/src/parser.h b/src/parser.h index f432583f..ddfa31f0 100644 --- a/src/parser.h +++ b/src/parser.h @@ -6,7 +6,7 @@ typedef uint8_t TokenIndex; constexpr const char* kTokens[] = { "@error", "@eof", "@eol", "@sof", - ".", ",", ":", ";", "#", "(", ")", "[", "]", "{", "}", "%", + ".", ",", ":", ";", "#", "(", ")", "[", "]", "{", "}", "%", "::", "+", "-", "*", "/", "//", "**", "=", ">", "<", "...", "->", "<<", ">>", "&", "|", "^", "?", "==", "!=", ">=", "<=",