Skip to content

Commit 7e15e5e

Browse files
committed
support __add__() for list
1 parent b694a68 commit 7e15e5e

File tree

12 files changed

+178
-8
lines changed

12 files changed

+178
-8
lines changed

package/PikaStdLib/PikaStdData.pyi

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,9 @@ class List(Tuple):
3838

3939
def __str__(self) -> str: ...
4040

41+
def __add__(self, others: List) -> List:
42+
""" support list + list"""
43+
4144

4245
class Dict:
4346
def __init__(self): ...

package/PikaStdLib/PikaStdData_List.c

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,3 +60,20 @@ void PikaStdData_List_reverse(PikaObj* self) {
6060
PikaList* list = obj_getPtr(self, "list");
6161
list_reverse(list);
6262
}
63+
64+
PikaObj* PikaStdData_List___add__(PikaObj* self, PikaObj* others) {
65+
PikaObj* res = newNormalObj(New_PikaStdData_List);
66+
PikaStdData_List___init__(res);
67+
PikaList* list_res = obj_getPtr(res, "list");
68+
PikaList* list1 = obj_getPtr(self, "list");
69+
PikaList* list2 = obj_getPtr(others, "list");
70+
for (size_t i = 0; i < list_getSize(list1); i++) {
71+
Arg* arg = list_getArg(list1, i);
72+
list_append(list_res, arg);
73+
}
74+
for (size_t i = 0; i < list_getSize(list2); i++) {
75+
Arg* arg = list_getArg(list2, i);
76+
list_append(list_res, arg);
77+
}
78+
return res;
79+
}

port/linux/.vscode/launch.json

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,7 @@
1111
"program": "${workspaceFolder}/build/test/pikascript_test",
1212
// "program": "${workspaceFolder}/build/boot/demo06-pikamain/pikascript_demo06-pikamain",
1313
"args": [
14-
"--gtest_filter=VM.vars_runtime"
15-
// "--gtest_filter=parser.*"
14+
// "--gtest_filter=parser.issues_I5MIFO"
1615
],
1716
"stopAtEntry": false,
1817
"cwd": "${workspaceFolder}",

port/linux/package/pikascript/PikaStdData.pyi

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,9 @@ class List(Tuple):
3838

3939
def __str__(self) -> str: ...
4040

41+
def __add__(self, others: List) -> List:
42+
""" support list + list"""
43+
4144

4245
class Dict:
4346
def __init__(self): ...

port/linux/package/pikascript/pikascript-lib/PikaStdLib/PikaStdData_List.c

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,3 +60,20 @@ void PikaStdData_List_reverse(PikaObj* self) {
6060
PikaList* list = obj_getPtr(self, "list");
6161
list_reverse(list);
6262
}
63+
64+
PikaObj* PikaStdData_List___add__(PikaObj* self, PikaObj* others) {
65+
PikaObj* res = newNormalObj(New_PikaStdData_List);
66+
PikaStdData_List___init__(res);
67+
PikaList* list_res = obj_getPtr(res, "list");
68+
PikaList* list1 = obj_getPtr(self, "list");
69+
PikaList* list2 = obj_getPtr(others, "list");
70+
for (size_t i = 0; i < list_getSize(list1); i++) {
71+
Arg* arg = list_getArg(list1, i);
72+
list_append(list_res, arg);
73+
}
74+
for (size_t i = 0; i < list_getSize(list2); i++) {
75+
Arg* arg = list_getArg(list2, i);
76+
list_append(list_res, arg);
77+
}
78+
return res;
79+
}

port/linux/test/VM-test.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1160,3 +1160,16 @@ TEST(VM, vars_runtime) {
11601160
obj_deinit(self);
11611161
EXPECT_EQ(pikaMemNow(), 0);
11621162
}
1163+
1164+
#if PIKA_BUILTIN_STRUCT_ENABLE
1165+
TEST(VM, list_add) {
1166+
char* line = "[1, 2, 3] + [4, 5, 6]";
1167+
PikaObj* self = newRootObj("root", New_PikaStdLib_SysObj);
1168+
obj_run(self, line);
1169+
/* collect */
1170+
/* assert */
1171+
/* deinit */
1172+
obj_deinit(self);
1173+
EXPECT_EQ(pikaMemNow(), 0);
1174+
}
1175+
#endif

port/linux/test/compile-test.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -588,3 +588,15 @@ TEST(compiler, __getitem__) {
588588
Parser_linesToArray(lines);
589589
EXPECT_EQ(pikaMemNow(), 0);
590590
}
591+
592+
TEST(compiler, __add__) {
593+
char* lines = "__res = __add__(__others)";
594+
Parser_linesToArray(lines);
595+
EXPECT_EQ(pikaMemNow(), 0);
596+
}
597+
598+
TEST(compiler, __sub__) {
599+
char* lines = "__res = __sub__(__others)";
600+
Parser_linesToArray(lines);
601+
EXPECT_EQ(pikaMemNow(), 0);
602+
}

port/linux/test/parse-test.cpp

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3921,3 +3921,28 @@ TEST(parser, vars_runtime) {
39213921
args_deinit(buffs);
39223922
EXPECT_EQ(pikaMemNow(), 0);
39233923
}
3924+
3925+
#if PIKA_BUILTIN_STRUCT_ENABLE
3926+
TEST(parser, issues_I5MIFO) {
3927+
pikaMemInfo.heapUsedMax = 0;
3928+
Args* buffs = New_strBuff();
3929+
char* lines = "[1, 2, 3] + [4, 5, 6]";
3930+
__platform_printf("%s\n", lines);
3931+
char* pikaAsm = Parser_linesToAsm(buffs, lines);
3932+
__platform_printf("%s", pikaAsm);
3933+
EXPECT_STREQ(pikaAsm,
3934+
"B0\n"
3935+
"2 NUM 1\n"
3936+
"2 NUM 2\n"
3937+
"2 NUM 3\n"
3938+
"1 LST \n"
3939+
"2 NUM 4\n"
3940+
"2 NUM 5\n"
3941+
"2 NUM 6\n"
3942+
"1 LST \n"
3943+
"0 OPT +\n"
3944+
"B0\n");
3945+
args_deinit(buffs);
3946+
EXPECT_EQ(pikaMemNow(), 0);
3947+
}
3948+
#endif

src/PikaParser.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -216,7 +216,6 @@ static enum StmtType Lexer_matchStmtType(char* right) {
216216
}
217217
/* ( <,> | <=> ) + <[> */
218218
is_get_list = PIKA_TRUE;
219-
goto iter_continue;
220219
}
221220
if (strEqu(ps.token1.pyload, "[") && ps.iter_index == 1) {
222221
/* VOID + <[> */
@@ -1472,6 +1471,7 @@ AST* AST_parseStmt(AST* ast, char* stmt) {
14721471
char* laststmt = Parser_popLastSubStmt(&buffs, &stmt, "[");
14731472
AST_parseSubStmt(ast, stmt);
14741473
char* slice_list = strsCut(&buffs, laststmt, '[', ']');
1474+
pika_assert(slice_list != NULL);
14751475
slice_list = strsAppend(&buffs, slice_list, ":");
14761476
int index = 0;
14771477
while (1) {

src/PikaVM.c

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1272,6 +1272,47 @@ void operatorInfo_init(OperatorInfo* info,
12721272
}
12731273

12741274
static void _OPT_ADD(OperatorInfo* op) {
1275+
if (argType_isObject(op->t1)) {
1276+
if (!argType_isObject(op->t2)) {
1277+
VMState_setErrorCode(op->vm, PIKA_RES_ERR_OPERATION_FAILED);
1278+
__platform_printf("TypeError: unsupported operand +\n");
1279+
op->res = NULL;
1280+
return;
1281+
}
1282+
PikaObj* obj1 = arg_getPtr(op->a1);
1283+
Arg* method_add = obj_getMethodArg(obj1, "__add__");
1284+
if (NULL == method_add) {
1285+
VMState_setErrorCode(op->vm, PIKA_RES_ERR_OPERATION_FAILED);
1286+
__platform_printf("TypeError: unsupported operand +\n");
1287+
op->res = NULL;
1288+
return;
1289+
}
1290+
arg_deinit(method_add);
1291+
PikaObj* obj2 = arg_getPtr(op->a2);
1292+
obj_setPtr(obj1, "__others", obj2);
1293+
/* clang-format off */
1294+
PIKA_PYTHON(
1295+
__res = __add__(__others)
1296+
)
1297+
/* clang-format on */
1298+
const uint8_t bytes[] = {
1299+
0x0c, 0x00, /* instruct array size */
1300+
0x10, 0x81, 0x01, 0x00, 0x00, 0x02, 0x0a, 0x00, 0x00, 0x04, 0x12,
1301+
0x00,
1302+
/* instruct array */
1303+
0x18, 0x00, /* const pool size */
1304+
0x00, 0x5f, 0x5f, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x73, 0x00, 0x5f,
1305+
0x5f, 0x61, 0x64, 0x64, 0x5f, 0x5f, 0x00, 0x5f, 0x5f, 0x72, 0x65,
1306+
0x73, 0x00, /* const pool */
1307+
};
1308+
pikaVM_runByteCode(obj1, (uint8_t*)bytes);
1309+
Arg* __res = arg_copy(obj_getArg(obj1, "__res"));
1310+
op->res = __res;
1311+
obj_removeArg(obj1, "__others");
1312+
obj_removeArg(obj1, "__res");
1313+
return;
1314+
}
1315+
12751316
if ((op->t1 == ARG_TYPE_STRING) && (op->t2 == ARG_TYPE_STRING)) {
12761317
char* num1_s = NULL;
12771318
char* num2_s = NULL;
@@ -1294,6 +1335,46 @@ static void _OPT_ADD(OperatorInfo* op) {
12941335
}
12951336

12961337
static void _OPT_SUB(OperatorInfo* op) {
1338+
if (argType_isObject(op->t1)) {
1339+
if (!argType_isObject(op->t2)) {
1340+
VMState_setErrorCode(op->vm, PIKA_RES_ERR_OPERATION_FAILED);
1341+
__platform_printf("TypeError: unsupported operand +\n");
1342+
op->res = NULL;
1343+
return;
1344+
}
1345+
PikaObj* obj1 = arg_getPtr(op->a1);
1346+
Arg* method_sub = obj_getMethodArg(obj1, "__sub__");
1347+
if (NULL == method_sub) {
1348+
VMState_setErrorCode(op->vm, PIKA_RES_ERR_OPERATION_FAILED);
1349+
__platform_printf("TypeError: unsupported operand +\n");
1350+
op->res = NULL;
1351+
return;
1352+
}
1353+
arg_deinit(method_sub);
1354+
PikaObj* obj2 = arg_getPtr(op->a2);
1355+
obj_setPtr(obj1, "__others", obj2);
1356+
/* clang-format off */
1357+
PIKA_PYTHON(
1358+
__res = __sub__(__others)
1359+
)
1360+
/* clang-format on */
1361+
const uint8_t bytes[] = {
1362+
0x0c, 0x00, /* instruct array size */
1363+
0x10, 0x81, 0x01, 0x00, 0x00, 0x02, 0x0a, 0x00, 0x00, 0x04, 0x12,
1364+
0x00,
1365+
/* instruct array */
1366+
0x18, 0x00, /* const pool size */
1367+
0x00, 0x5f, 0x5f, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x73, 0x00, 0x5f,
1368+
0x5f, 0x73, 0x75, 0x62, 0x5f, 0x5f, 0x00, 0x5f, 0x5f, 0x72, 0x65,
1369+
0x73, 0x00, /* const pool */
1370+
};
1371+
pikaVM_runByteCode(obj1, (uint8_t*)bytes);
1372+
Arg* __res = arg_copy(obj_getArg(obj1, "__res"));
1373+
op->res = __res;
1374+
obj_removeArg(obj1, "__others");
1375+
obj_removeArg(obj1, "__res");
1376+
return;
1377+
}
12971378
if (op->t2 == ARG_TYPE_NONE) {
12981379
if (op->t1 == ARG_TYPE_INT) {
12991380
op->res = arg_setInt(op->res, "", -op->i1);

0 commit comments

Comments
 (0)