support len() for object and __len__().

* list, dict, dict_keys is ok
This commit is contained in:
pikastech 2022-06-24 18:18:06 +08:00
parent 410071a200
commit 865290df74
12 changed files with 108 additions and 2 deletions

View File

@ -21,6 +21,7 @@ class List(TinyObj):
def __get__(self, __key: any) -> any: ...
def __del__(self): ...
def __str__(self) -> str: ...
def __len__(self) -> int: ...
class Dict(TinyObj):
@ -40,12 +41,14 @@ class Dict(TinyObj):
def __del__(self): ...
def __str__(self) -> str: ...
def keys(self) -> dict_keys: ...
def __len__(self) -> int: ...
class dict_keys(TinyObj):
def __iter__(self) -> any: ...
def __next__(self) -> any: ...
def __str__(self) -> str: ...
def __len__(self) -> int: ...
class String(TinyObj):
@ -60,6 +63,7 @@ class String(TinyObj):
def __get__(self, __key: any) -> any: ...
# support str()
def __str__(self) -> str: ...
def __len__(self) -> int: ...
def startwith(self, prefix: str) -> int: ...
def endwith(self, suffix: str) -> int: ...

View File

@ -119,7 +119,7 @@ char* PikaStdData_dict_keys___str__(PikaObj* self) {
return obj_getStr(self, "_buf");
}
char* PikaStdData_Dict___str__(PikaObj *self){
char* PikaStdData_Dict___str__(PikaObj* self) {
Arg* str_arg = arg_setStr(NULL, "", "{");
PikaDict* keys = obj_getPtr(self, "_keys");
@ -151,3 +151,15 @@ char* PikaStdData_Dict___str__(PikaObj *self){
arg_deinit(str_arg);
return obj_getStr(self, "_buf");
}
int PikaStdData_Dict___len__(PikaObj* self) {
PikaDict* dict = obj_getPtr(self, "dict");
return args_getSize(&dict->super);
}
int PikaStdData_dict_keys___len__(PikaObj *self){
PikaObj* dictptr = obj_getPtr(self, "dictptr");
PikaDict* keys = obj_getPtr(dictptr, "_keys");
return args_getSize(&keys->super);
}

View File

@ -106,3 +106,7 @@ char* PikaStdData_List___str__(PikaObj* self) {
arg_deinit(str_arg);
return obj_getStr(self, "_buf");
}
int PikaStdData_List___len__(PikaObj *self){
return PikaStdData_List_len(self);
}

View File

@ -172,3 +172,8 @@ PikaObj* PikaStdData_String_split(PikaObj* self, char* s) {
strsDeinit(&buffs);
return list;
}
int PikaStdData_String___len__(PikaObj *self){
char* str = obj_getStr(self, "str");
return strGetSize(str);
}

View File

@ -285,6 +285,31 @@ int PikaStdLib_SysObj_len(PikaObj* self, Arg* arg) {
if (ARG_TYPE_BYTES == arg_getType(arg)) {
return arg_getBytesSize(arg);
}
if (argType_isObject(arg_getType(arg))) {
PikaObj* arg_obj = arg_getPtr(arg);
Arg* method_arg = obj_getMethodArg(arg_obj, "__len__");
if (NULL != method_arg) {
arg_deinit(method_arg);
/* clang-format off */
PIKA_PYTHON(
__res = __len__()
)
/* clang-format on */
const uint8_t bytes[] = {
0x08, 0x00, /* instruct array size */
0x00, 0x82, 0x01, 0x00, 0x00, 0x04, 0x09, 0x00, /* instruct
array */
0x0f, 0x00, /* const pool size */
0x00, 0x5f, 0x5f, 0x6c, 0x65, 0x6e, 0x5f, 0x5f, 0x00,
0x5f, 0x5f, 0x72, 0x65, 0x73, 0x00, /* const pool */
};
pikaVM_runByteCode(arg_obj, (uint8_t*)bytes);
return obj_getInt(arg_obj, "__res");
}
}
obj_setErrorCode(self, 1);
__platform_printf("[Error] len: arg type not support\r\n");
return -1;

View File

@ -21,6 +21,7 @@ class List(TinyObj):
def __get__(self, __key: any) -> any: ...
def __del__(self): ...
def __str__(self) -> str: ...
def __len__(self) -> int: ...
class Dict(TinyObj):
@ -40,12 +41,14 @@ class Dict(TinyObj):
def __del__(self): ...
def __str__(self) -> str: ...
def keys(self) -> dict_keys: ...
def __len__(self) -> int: ...
class dict_keys(TinyObj):
def __iter__(self) -> any: ...
def __next__(self) -> any: ...
def __str__(self) -> str: ...
def __len__(self) -> int: ...
class String(TinyObj):
@ -60,6 +63,7 @@ class String(TinyObj):
def __get__(self, __key: any) -> any: ...
# support str()
def __str__(self) -> str: ...
def __len__(self) -> int: ...
def startwith(self, prefix: str) -> int: ...
def endwith(self, suffix: str) -> int: ...

View File

@ -119,7 +119,7 @@ char* PikaStdData_dict_keys___str__(PikaObj* self) {
return obj_getStr(self, "_buf");
}
char* PikaStdData_Dict___str__(PikaObj *self){
char* PikaStdData_Dict___str__(PikaObj* self) {
Arg* str_arg = arg_setStr(NULL, "", "{");
PikaDict* keys = obj_getPtr(self, "_keys");
@ -151,3 +151,15 @@ char* PikaStdData_Dict___str__(PikaObj *self){
arg_deinit(str_arg);
return obj_getStr(self, "_buf");
}
int PikaStdData_Dict___len__(PikaObj* self) {
PikaDict* dict = obj_getPtr(self, "dict");
return args_getSize(&dict->super);
}
int PikaStdData_dict_keys___len__(PikaObj *self){
PikaObj* dictptr = obj_getPtr(self, "dictptr");
PikaDict* keys = obj_getPtr(dictptr, "_keys");
return args_getSize(&keys->super);
}

View File

@ -106,3 +106,7 @@ char* PikaStdData_List___str__(PikaObj* self) {
arg_deinit(str_arg);
return obj_getStr(self, "_buf");
}
int PikaStdData_List___len__(PikaObj *self){
return PikaStdData_List_len(self);
}

View File

@ -172,3 +172,8 @@ PikaObj* PikaStdData_String_split(PikaObj* self, char* s) {
strsDeinit(&buffs);
return list;
}
int PikaStdData_String___len__(PikaObj *self){
char* str = obj_getStr(self, "str");
return strGetSize(str);
}

View File

@ -285,6 +285,31 @@ int PikaStdLib_SysObj_len(PikaObj* self, Arg* arg) {
if (ARG_TYPE_BYTES == arg_getType(arg)) {
return arg_getBytesSize(arg);
}
if (argType_isObject(arg_getType(arg))) {
PikaObj* arg_obj = arg_getPtr(arg);
Arg* method_arg = obj_getMethodArg(arg_obj, "__len__");
if (NULL != method_arg) {
arg_deinit(method_arg);
/* clang-format off */
PIKA_PYTHON(
__res = __len__()
)
/* clang-format on */
const uint8_t bytes[] = {
0x08, 0x00, /* instruct array size */
0x00, 0x82, 0x01, 0x00, 0x00, 0x04, 0x09, 0x00, /* instruct
array */
0x0f, 0x00, /* const pool size */
0x00, 0x5f, 0x5f, 0x6c, 0x65, 0x6e, 0x5f, 0x5f, 0x00,
0x5f, 0x5f, 0x72, 0x65, 0x73, 0x00, /* const pool */
};
pikaVM_runByteCode(arg_obj, (uint8_t*)bytes);
return obj_getInt(arg_obj, "__res");
}
}
obj_setErrorCode(self, 1);
__platform_printf("[Error] len: arg type not support\r\n");
return -1;

View File

@ -552,6 +552,12 @@ TEST(compiler, __str__) {
EXPECT_EQ(pikaMemNow(), 0);
}
TEST(compiler, __len__) {
char* lines = "__res = __len__()";
Parser_compilePyToBytecodeArray(lines);
EXPECT_EQ(pikaMemNow(), 0);
}
TEST(compiler, __del__) {
char* lines = "__del__()";
Parser_compilePyToBytecodeArray(lines);