mirror of
https://gitee.com/Lyon1998/pikapython.git
synced 2025-01-15 17:02:53 +08:00
support __add__()
for list
This commit is contained in:
parent
b694a68a9c
commit
7e15e5e202
@ -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): ...
|
||||
|
@ -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;
|
||||
}
|
||||
|
3
port/linux/.vscode/launch.json
vendored
3
port/linux/.vscode/launch.json
vendored
@ -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}",
|
||||
|
@ -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): ...
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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) {
|
||||
|
81
src/PikaVM.c
81
src/PikaVM.c
@ -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);
|
||||
|
@ -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");
|
||||
}
|
||||
|
@ -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");
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user