support __add__() for list

This commit is contained in:
pikastech 2022-08-16 17:40:11 +08:00
parent b694a68a9c
commit 7e15e5e202
12 changed files with 178 additions and 8 deletions

View File

@ -38,6 +38,9 @@ class List(Tuple):
def __str__(self) -> str: ...
def __add__(self, others: List) -> List:
""" support list + list"""
class Dict:
def __init__(self): ...

View File

@ -60,3 +60,20 @@ void PikaStdData_List_reverse(PikaObj* self) {
PikaList* list = obj_getPtr(self, "list");
list_reverse(list);
}
PikaObj* PikaStdData_List___add__(PikaObj* self, PikaObj* others) {
PikaObj* res = newNormalObj(New_PikaStdData_List);
PikaStdData_List___init__(res);
PikaList* list_res = obj_getPtr(res, "list");
PikaList* list1 = obj_getPtr(self, "list");
PikaList* list2 = obj_getPtr(others, "list");
for (size_t i = 0; i < list_getSize(list1); i++) {
Arg* arg = list_getArg(list1, i);
list_append(list_res, arg);
}
for (size_t i = 0; i < list_getSize(list2); i++) {
Arg* arg = list_getArg(list2, i);
list_append(list_res, arg);
}
return res;
}

View File

@ -11,8 +11,7 @@
"program": "${workspaceFolder}/build/test/pikascript_test",
// "program": "${workspaceFolder}/build/boot/demo06-pikamain/pikascript_demo06-pikamain",
"args": [
"--gtest_filter=VM.vars_runtime"
// "--gtest_filter=parser.*"
// "--gtest_filter=parser.issues_I5MIFO"
],
"stopAtEntry": false,
"cwd": "${workspaceFolder}",

View File

@ -38,6 +38,9 @@ class List(Tuple):
def __str__(self) -> str: ...
def __add__(self, others: List) -> List:
""" support list + list"""
class Dict:
def __init__(self): ...

View File

@ -60,3 +60,20 @@ void PikaStdData_List_reverse(PikaObj* self) {
PikaList* list = obj_getPtr(self, "list");
list_reverse(list);
}
PikaObj* PikaStdData_List___add__(PikaObj* self, PikaObj* others) {
PikaObj* res = newNormalObj(New_PikaStdData_List);
PikaStdData_List___init__(res);
PikaList* list_res = obj_getPtr(res, "list");
PikaList* list1 = obj_getPtr(self, "list");
PikaList* list2 = obj_getPtr(others, "list");
for (size_t i = 0; i < list_getSize(list1); i++) {
Arg* arg = list_getArg(list1, i);
list_append(list_res, arg);
}
for (size_t i = 0; i < list_getSize(list2); i++) {
Arg* arg = list_getArg(list2, i);
list_append(list_res, arg);
}
return res;
}

View File

@ -1160,3 +1160,16 @@ TEST(VM, vars_runtime) {
obj_deinit(self);
EXPECT_EQ(pikaMemNow(), 0);
}
#if PIKA_BUILTIN_STRUCT_ENABLE
TEST(VM, list_add) {
char* line = "[1, 2, 3] + [4, 5, 6]";
PikaObj* self = newRootObj("root", New_PikaStdLib_SysObj);
obj_run(self, line);
/* collect */
/* assert */
/* deinit */
obj_deinit(self);
EXPECT_EQ(pikaMemNow(), 0);
}
#endif

View File

@ -588,3 +588,15 @@ TEST(compiler, __getitem__) {
Parser_linesToArray(lines);
EXPECT_EQ(pikaMemNow(), 0);
}
TEST(compiler, __add__) {
char* lines = "__res = __add__(__others)";
Parser_linesToArray(lines);
EXPECT_EQ(pikaMemNow(), 0);
}
TEST(compiler, __sub__) {
char* lines = "__res = __sub__(__others)";
Parser_linesToArray(lines);
EXPECT_EQ(pikaMemNow(), 0);
}

View File

@ -3921,3 +3921,28 @@ TEST(parser, vars_runtime) {
args_deinit(buffs);
EXPECT_EQ(pikaMemNow(), 0);
}
#if PIKA_BUILTIN_STRUCT_ENABLE
TEST(parser, issues_I5MIFO) {
pikaMemInfo.heapUsedMax = 0;
Args* buffs = New_strBuff();
char* lines = "[1, 2, 3] + [4, 5, 6]";
__platform_printf("%s\n", lines);
char* pikaAsm = Parser_linesToAsm(buffs, lines);
__platform_printf("%s", pikaAsm);
EXPECT_STREQ(pikaAsm,
"B0\n"
"2 NUM 1\n"
"2 NUM 2\n"
"2 NUM 3\n"
"1 LST \n"
"2 NUM 4\n"
"2 NUM 5\n"
"2 NUM 6\n"
"1 LST \n"
"0 OPT +\n"
"B0\n");
args_deinit(buffs);
EXPECT_EQ(pikaMemNow(), 0);
}
#endif

View File

@ -216,7 +216,6 @@ static enum StmtType Lexer_matchStmtType(char* right) {
}
/* ( <,> | <=> ) + <[> */
is_get_list = PIKA_TRUE;
goto iter_continue;
}
if (strEqu(ps.token1.pyload, "[") && ps.iter_index == 1) {
/* VOID + <[> */
@ -1472,6 +1471,7 @@ AST* AST_parseStmt(AST* ast, char* stmt) {
char* laststmt = Parser_popLastSubStmt(&buffs, &stmt, "[");
AST_parseSubStmt(ast, stmt);
char* slice_list = strsCut(&buffs, laststmt, '[', ']');
pika_assert(slice_list != NULL);
slice_list = strsAppend(&buffs, slice_list, ":");
int index = 0;
while (1) {

View File

@ -1272,6 +1272,47 @@ void operatorInfo_init(OperatorInfo* info,
}
static void _OPT_ADD(OperatorInfo* op) {
if (argType_isObject(op->t1)) {
if (!argType_isObject(op->t2)) {
VMState_setErrorCode(op->vm, PIKA_RES_ERR_OPERATION_FAILED);
__platform_printf("TypeError: unsupported operand +\n");
op->res = NULL;
return;
}
PikaObj* obj1 = arg_getPtr(op->a1);
Arg* method_add = obj_getMethodArg(obj1, "__add__");
if (NULL == method_add) {
VMState_setErrorCode(op->vm, PIKA_RES_ERR_OPERATION_FAILED);
__platform_printf("TypeError: unsupported operand +\n");
op->res = NULL;
return;
}
arg_deinit(method_add);
PikaObj* obj2 = arg_getPtr(op->a2);
obj_setPtr(obj1, "__others", obj2);
/* clang-format off */
PIKA_PYTHON(
__res = __add__(__others)
)
/* clang-format on */
const uint8_t bytes[] = {
0x0c, 0x00, /* instruct array size */
0x10, 0x81, 0x01, 0x00, 0x00, 0x02, 0x0a, 0x00, 0x00, 0x04, 0x12,
0x00,
/* instruct array */
0x18, 0x00, /* const pool size */
0x00, 0x5f, 0x5f, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x73, 0x00, 0x5f,
0x5f, 0x61, 0x64, 0x64, 0x5f, 0x5f, 0x00, 0x5f, 0x5f, 0x72, 0x65,
0x73, 0x00, /* const pool */
};
pikaVM_runByteCode(obj1, (uint8_t*)bytes);
Arg* __res = arg_copy(obj_getArg(obj1, "__res"));
op->res = __res;
obj_removeArg(obj1, "__others");
obj_removeArg(obj1, "__res");
return;
}
if ((op->t1 == ARG_TYPE_STRING) && (op->t2 == ARG_TYPE_STRING)) {
char* num1_s = NULL;
char* num2_s = NULL;
@ -1294,6 +1335,46 @@ static void _OPT_ADD(OperatorInfo* op) {
}
static void _OPT_SUB(OperatorInfo* op) {
if (argType_isObject(op->t1)) {
if (!argType_isObject(op->t2)) {
VMState_setErrorCode(op->vm, PIKA_RES_ERR_OPERATION_FAILED);
__platform_printf("TypeError: unsupported operand +\n");
op->res = NULL;
return;
}
PikaObj* obj1 = arg_getPtr(op->a1);
Arg* method_sub = obj_getMethodArg(obj1, "__sub__");
if (NULL == method_sub) {
VMState_setErrorCode(op->vm, PIKA_RES_ERR_OPERATION_FAILED);
__platform_printf("TypeError: unsupported operand +\n");
op->res = NULL;
return;
}
arg_deinit(method_sub);
PikaObj* obj2 = arg_getPtr(op->a2);
obj_setPtr(obj1, "__others", obj2);
/* clang-format off */
PIKA_PYTHON(
__res = __sub__(__others)
)
/* clang-format on */
const uint8_t bytes[] = {
0x0c, 0x00, /* instruct array size */
0x10, 0x81, 0x01, 0x00, 0x00, 0x02, 0x0a, 0x00, 0x00, 0x04, 0x12,
0x00,
/* instruct array */
0x18, 0x00, /* const pool size */
0x00, 0x5f, 0x5f, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x73, 0x00, 0x5f,
0x5f, 0x73, 0x75, 0x62, 0x5f, 0x5f, 0x00, 0x5f, 0x5f, 0x72, 0x65,
0x73, 0x00, /* const pool */
};
pikaVM_runByteCode(obj1, (uint8_t*)bytes);
Arg* __res = arg_copy(obj_getArg(obj1, "__res"));
op->res = __res;
obj_removeArg(obj1, "__others");
obj_removeArg(obj1, "__res");
return;
}
if (op->t2 == ARG_TYPE_NONE) {
if (op->t1 == ARG_TYPE_INT) {
op->res = arg_setInt(op->res, "", -op->i1);

View File

@ -429,8 +429,3 @@ void arg_deinit(Arg* self) {
/* free the ref */
arg_freeContent(self);
}
PikaTuple* args_getTuple(Args* self, char* name) {
PikaObj* tuple_obj = args_getPtr(self, name);
return obj_getPtr(tuple_obj, "list");
}

View File

@ -694,3 +694,8 @@ exit:
arg_deinit(res_buff);
return res;
}
PikaTuple* args_getTuple(Args* self, char* name) {
PikaObj* tuple_obj = args_getPtr(self, name);
return obj_getPtr(tuple_obj, "list");
}