mirror of
https://gitee.com/Lyon1998/pikapython.git
synced 2025-01-29 17:22:56 +08:00
support max(), min() builtin
This commit is contained in:
parent
5965c0129b
commit
4e9816f9a1
@ -43,6 +43,9 @@ Arg* PikaStdData_Tuple___getitem__(PikaObj* self, Arg* __key) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void PikaStdData_Tuple___del__(PikaObj* self) {
|
void PikaStdData_Tuple___del__(PikaObj* self) {
|
||||||
|
if (0 == obj_getInt(self, "needfree")) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
Args* list = obj_getPtr(self, "list");
|
Args* list = obj_getPtr(self, "list");
|
||||||
args_deinit(list);
|
args_deinit(list);
|
||||||
}
|
}
|
||||||
|
@ -126,6 +126,14 @@ class SysObj:
|
|||||||
@PIKA_C_MACRO_IF("!PIKA_NANO_ENABLE")
|
@PIKA_C_MACRO_IF("!PIKA_NANO_ENABLE")
|
||||||
def abs(val: any) -> any: ...
|
def abs(val: any) -> any: ...
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
@PIKA_C_MACRO_IF("!PIKA_NANO_ENABLE")
|
||||||
|
def max(*val) -> any: ...
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
@PIKA_C_MACRO_IF("!PIKA_NANO_ENABLE")
|
||||||
|
def min(*val) -> any: ...
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
@PIKA_C_MACRO_IF("!PIKA_NANO_ENABLE")
|
@PIKA_C_MACRO_IF("!PIKA_NANO_ENABLE")
|
||||||
def help(name: str): ...
|
def help(name: str): ...
|
||||||
|
@ -707,3 +707,91 @@ Arg* PikaStdLib_SysObj_abs(PikaObj* self, Arg* val) {
|
|||||||
obj_setErrorCode(self, PIKA_RES_ERR_INVALID_PARAM);
|
obj_setErrorCode(self, PIKA_RES_ERR_INVALID_PARAM);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PikaObj* New_PikaStdData_Tuple(Args* args);
|
||||||
|
/* clang-format off */
|
||||||
|
PIKA_PYTHON(
|
||||||
|
@res_max = @list[0]
|
||||||
|
for @item in @list:
|
||||||
|
if @item > @res_max:
|
||||||
|
@res_max = @item
|
||||||
|
)
|
||||||
|
/* clang-format on */
|
||||||
|
const uint8_t bc_max[] = {
|
||||||
|
0x4c, 0x00, 0x00, 0x00, /* instruct array size */
|
||||||
|
0x10, 0x81, 0x01, 0x00, 0x10, 0x05, 0x07, 0x00, 0x00, 0x1d, 0x00, 0x00,
|
||||||
|
0x00, 0x04, 0x09, 0x00, 0x10, 0x81, 0x01, 0x00, 0x00, 0x02, 0x12, 0x00,
|
||||||
|
0x00, 0x04, 0x17, 0x00, 0x00, 0x82, 0x1b, 0x00, 0x00, 0x04, 0x28, 0x00,
|
||||||
|
0x00, 0x0d, 0x28, 0x00, 0x00, 0x07, 0x2e, 0x00, 0x11, 0x81, 0x28, 0x00,
|
||||||
|
0x11, 0x01, 0x09, 0x00, 0x01, 0x08, 0x30, 0x00, 0x01, 0x07, 0x32, 0x00,
|
||||||
|
0x02, 0x81, 0x28, 0x00, 0x02, 0x04, 0x09, 0x00, 0x00, 0x86, 0x34, 0x00,
|
||||||
|
0x00, 0x8c, 0x17, 0x00, /* instruct array */
|
||||||
|
0x37, 0x00, 0x00, 0x00, /* const pool size */
|
||||||
|
0x00, 0x40, 0x6c, 0x69, 0x73, 0x74, 0x00, 0x30, 0x00, 0x40, 0x72, 0x65,
|
||||||
|
0x73, 0x5f, 0x6d, 0x61, 0x78, 0x00, 0x69, 0x74, 0x65, 0x72, 0x00, 0x24,
|
||||||
|
0x6c, 0x30, 0x00, 0x24, 0x6c, 0x30, 0x2e, 0x5f, 0x5f, 0x6e, 0x65, 0x78,
|
||||||
|
0x74, 0x5f, 0x5f, 0x00, 0x40, 0x69, 0x74, 0x65, 0x6d, 0x00, 0x32, 0x00,
|
||||||
|
0x3e, 0x00, 0x31, 0x00, 0x2d, 0x31, 0x00, /* const pool */
|
||||||
|
};
|
||||||
|
|
||||||
|
/* clang-format off */
|
||||||
|
PIKA_PYTHON(
|
||||||
|
@res_max = @list[0]
|
||||||
|
for @item in @list:
|
||||||
|
if @item < @res_max:
|
||||||
|
@res_max = @item
|
||||||
|
|
||||||
|
)
|
||||||
|
/* clang-format on */
|
||||||
|
const uint8_t bc_min[] = {
|
||||||
|
0x4c, 0x00, 0x00, 0x00, /* instruct array size */
|
||||||
|
0x10, 0x81, 0x01, 0x00, 0x10, 0x05, 0x07, 0x00, 0x00, 0x1d, 0x00, 0x00,
|
||||||
|
0x00, 0x04, 0x09, 0x00, 0x10, 0x81, 0x01, 0x00, 0x00, 0x02, 0x12, 0x00,
|
||||||
|
0x00, 0x04, 0x17, 0x00, 0x00, 0x82, 0x1b, 0x00, 0x00, 0x04, 0x28, 0x00,
|
||||||
|
0x00, 0x0d, 0x28, 0x00, 0x00, 0x07, 0x2e, 0x00, 0x11, 0x81, 0x28, 0x00,
|
||||||
|
0x11, 0x01, 0x09, 0x00, 0x01, 0x08, 0x30, 0x00, 0x01, 0x07, 0x32, 0x00,
|
||||||
|
0x02, 0x81, 0x28, 0x00, 0x02, 0x04, 0x09, 0x00, 0x00, 0x86, 0x34, 0x00,
|
||||||
|
0x00, 0x8c, 0x17, 0x00, /* instruct array */
|
||||||
|
0x37, 0x00, 0x00, 0x00, /* const pool size */
|
||||||
|
0x00, 0x40, 0x6c, 0x69, 0x73, 0x74, 0x00, 0x30, 0x00, 0x40, 0x72, 0x65,
|
||||||
|
0x73, 0x5f, 0x6d, 0x61, 0x78, 0x00, 0x69, 0x74, 0x65, 0x72, 0x00, 0x24,
|
||||||
|
0x6c, 0x30, 0x00, 0x24, 0x6c, 0x30, 0x2e, 0x5f, 0x5f, 0x6e, 0x65, 0x78,
|
||||||
|
0x74, 0x5f, 0x5f, 0x00, 0x40, 0x69, 0x74, 0x65, 0x6d, 0x00, 0x32, 0x00,
|
||||||
|
0x3c, 0x00, 0x31, 0x00, 0x2d, 0x31, 0x00, /* const pool */
|
||||||
|
};
|
||||||
|
|
||||||
|
Arg* _max_min(PikaObj* self, PikaTuple* val, uint8_t* bc) {
|
||||||
|
int size = pikaTuple_getSize(val);
|
||||||
|
if (size == 0) {
|
||||||
|
obj_setSysOut(self, "TypeError: max expected 1 arguments, got 0");
|
||||||
|
obj_setErrorCode(self, PIKA_RES_ERR_INVALID_PARAM);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if (size == 1) {
|
||||||
|
ArgType type = arg_getType(pikaTuple_getArg(val, 0));
|
||||||
|
if ((!argType_isObject(type) && (type != ARG_TYPE_STRING) &&
|
||||||
|
(type != ARG_TYPE_BYTES))) {
|
||||||
|
obj_setSysOut(self, "TypeError: object is not iterable");
|
||||||
|
obj_setErrorCode(self, PIKA_RES_ERR_INVALID_PARAM);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
obj_setArg(self, "@list", pikaTuple_getArg(val, 0));
|
||||||
|
return pikaVM_runByteCodeReturn(self, (uint8_t*)bc, "@res_max");
|
||||||
|
}
|
||||||
|
PikaObj* oTuple = newNormalObj(New_PikaStdData_Tuple);
|
||||||
|
obj_setPtr(oTuple, "list", val);
|
||||||
|
obj_setInt(oTuple, "needfree", 0);
|
||||||
|
Arg* aTuple = arg_newObj(oTuple);
|
||||||
|
obj_setArg(self, "@list", aTuple);
|
||||||
|
Arg* aRet = pikaVM_runByteCodeReturn(self, (uint8_t*)bc, "@res_max");
|
||||||
|
arg_deinit(aTuple);
|
||||||
|
return aRet;
|
||||||
|
}
|
||||||
|
|
||||||
|
Arg* PikaStdLib_SysObj_max(PikaObj* self, PikaTuple* val) {
|
||||||
|
return _max_min(self, val, (uint8_t*)bc_max);
|
||||||
|
}
|
||||||
|
|
||||||
|
Arg* PikaStdLib_SysObj_min(PikaObj* self, PikaTuple* val) {
|
||||||
|
return _max_min(self, val, (uint8_t*)bc_min);
|
||||||
|
}
|
||||||
|
2
port/linux/.vscode/launch.json
vendored
2
port/linux/.vscode/launch.json
vendored
@ -20,7 +20,7 @@
|
|||||||
// "--gtest_filter=eventloop.test1"
|
// "--gtest_filter=eventloop.test1"
|
||||||
// "--gtest_filter=parser.tuple_single"
|
// "--gtest_filter=parser.tuple_single"
|
||||||
// "--gtest_filter=parser.*"
|
// "--gtest_filter=parser.*"
|
||||||
"--gtest_filter=pikaMain.REPL_key_down_over"
|
"--gtest_filter=builtin.max_min"
|
||||||
],
|
],
|
||||||
"stopAtEntry": false,
|
"stopAtEntry": false,
|
||||||
"cwd": "${workspaceFolder}",
|
"cwd": "${workspaceFolder}",
|
||||||
|
@ -126,6 +126,14 @@ class SysObj:
|
|||||||
@PIKA_C_MACRO_IF("!PIKA_NANO_ENABLE")
|
@PIKA_C_MACRO_IF("!PIKA_NANO_ENABLE")
|
||||||
def abs(val: any) -> any: ...
|
def abs(val: any) -> any: ...
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
@PIKA_C_MACRO_IF("!PIKA_NANO_ENABLE")
|
||||||
|
def max(*val) -> any: ...
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
@PIKA_C_MACRO_IF("!PIKA_NANO_ENABLE")
|
||||||
|
def min(*val) -> any: ...
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
@PIKA_C_MACRO_IF("!PIKA_NANO_ENABLE")
|
@PIKA_C_MACRO_IF("!PIKA_NANO_ENABLE")
|
||||||
def help(name: str): ...
|
def help(name: str): ...
|
||||||
|
@ -43,6 +43,9 @@ Arg* PikaStdData_Tuple___getitem__(PikaObj* self, Arg* __key) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void PikaStdData_Tuple___del__(PikaObj* self) {
|
void PikaStdData_Tuple___del__(PikaObj* self) {
|
||||||
|
if (0 == obj_getInt(self, "needfree")) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
Args* list = obj_getPtr(self, "list");
|
Args* list = obj_getPtr(self, "list");
|
||||||
args_deinit(list);
|
args_deinit(list);
|
||||||
}
|
}
|
||||||
|
@ -707,3 +707,91 @@ Arg* PikaStdLib_SysObj_abs(PikaObj* self, Arg* val) {
|
|||||||
obj_setErrorCode(self, PIKA_RES_ERR_INVALID_PARAM);
|
obj_setErrorCode(self, PIKA_RES_ERR_INVALID_PARAM);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PikaObj* New_PikaStdData_Tuple(Args* args);
|
||||||
|
/* clang-format off */
|
||||||
|
PIKA_PYTHON(
|
||||||
|
@res_max = @list[0]
|
||||||
|
for @item in @list:
|
||||||
|
if @item > @res_max:
|
||||||
|
@res_max = @item
|
||||||
|
)
|
||||||
|
/* clang-format on */
|
||||||
|
const uint8_t bc_max[] = {
|
||||||
|
0x4c, 0x00, 0x00, 0x00, /* instruct array size */
|
||||||
|
0x10, 0x81, 0x01, 0x00, 0x10, 0x05, 0x07, 0x00, 0x00, 0x1d, 0x00, 0x00,
|
||||||
|
0x00, 0x04, 0x09, 0x00, 0x10, 0x81, 0x01, 0x00, 0x00, 0x02, 0x12, 0x00,
|
||||||
|
0x00, 0x04, 0x17, 0x00, 0x00, 0x82, 0x1b, 0x00, 0x00, 0x04, 0x28, 0x00,
|
||||||
|
0x00, 0x0d, 0x28, 0x00, 0x00, 0x07, 0x2e, 0x00, 0x11, 0x81, 0x28, 0x00,
|
||||||
|
0x11, 0x01, 0x09, 0x00, 0x01, 0x08, 0x30, 0x00, 0x01, 0x07, 0x32, 0x00,
|
||||||
|
0x02, 0x81, 0x28, 0x00, 0x02, 0x04, 0x09, 0x00, 0x00, 0x86, 0x34, 0x00,
|
||||||
|
0x00, 0x8c, 0x17, 0x00, /* instruct array */
|
||||||
|
0x37, 0x00, 0x00, 0x00, /* const pool size */
|
||||||
|
0x00, 0x40, 0x6c, 0x69, 0x73, 0x74, 0x00, 0x30, 0x00, 0x40, 0x72, 0x65,
|
||||||
|
0x73, 0x5f, 0x6d, 0x61, 0x78, 0x00, 0x69, 0x74, 0x65, 0x72, 0x00, 0x24,
|
||||||
|
0x6c, 0x30, 0x00, 0x24, 0x6c, 0x30, 0x2e, 0x5f, 0x5f, 0x6e, 0x65, 0x78,
|
||||||
|
0x74, 0x5f, 0x5f, 0x00, 0x40, 0x69, 0x74, 0x65, 0x6d, 0x00, 0x32, 0x00,
|
||||||
|
0x3e, 0x00, 0x31, 0x00, 0x2d, 0x31, 0x00, /* const pool */
|
||||||
|
};
|
||||||
|
|
||||||
|
/* clang-format off */
|
||||||
|
PIKA_PYTHON(
|
||||||
|
@res_max = @list[0]
|
||||||
|
for @item in @list:
|
||||||
|
if @item < @res_max:
|
||||||
|
@res_max = @item
|
||||||
|
|
||||||
|
)
|
||||||
|
/* clang-format on */
|
||||||
|
const uint8_t bc_min[] = {
|
||||||
|
0x4c, 0x00, 0x00, 0x00, /* instruct array size */
|
||||||
|
0x10, 0x81, 0x01, 0x00, 0x10, 0x05, 0x07, 0x00, 0x00, 0x1d, 0x00, 0x00,
|
||||||
|
0x00, 0x04, 0x09, 0x00, 0x10, 0x81, 0x01, 0x00, 0x00, 0x02, 0x12, 0x00,
|
||||||
|
0x00, 0x04, 0x17, 0x00, 0x00, 0x82, 0x1b, 0x00, 0x00, 0x04, 0x28, 0x00,
|
||||||
|
0x00, 0x0d, 0x28, 0x00, 0x00, 0x07, 0x2e, 0x00, 0x11, 0x81, 0x28, 0x00,
|
||||||
|
0x11, 0x01, 0x09, 0x00, 0x01, 0x08, 0x30, 0x00, 0x01, 0x07, 0x32, 0x00,
|
||||||
|
0x02, 0x81, 0x28, 0x00, 0x02, 0x04, 0x09, 0x00, 0x00, 0x86, 0x34, 0x00,
|
||||||
|
0x00, 0x8c, 0x17, 0x00, /* instruct array */
|
||||||
|
0x37, 0x00, 0x00, 0x00, /* const pool size */
|
||||||
|
0x00, 0x40, 0x6c, 0x69, 0x73, 0x74, 0x00, 0x30, 0x00, 0x40, 0x72, 0x65,
|
||||||
|
0x73, 0x5f, 0x6d, 0x61, 0x78, 0x00, 0x69, 0x74, 0x65, 0x72, 0x00, 0x24,
|
||||||
|
0x6c, 0x30, 0x00, 0x24, 0x6c, 0x30, 0x2e, 0x5f, 0x5f, 0x6e, 0x65, 0x78,
|
||||||
|
0x74, 0x5f, 0x5f, 0x00, 0x40, 0x69, 0x74, 0x65, 0x6d, 0x00, 0x32, 0x00,
|
||||||
|
0x3c, 0x00, 0x31, 0x00, 0x2d, 0x31, 0x00, /* const pool */
|
||||||
|
};
|
||||||
|
|
||||||
|
Arg* _max_min(PikaObj* self, PikaTuple* val, uint8_t* bc) {
|
||||||
|
int size = pikaTuple_getSize(val);
|
||||||
|
if (size == 0) {
|
||||||
|
obj_setSysOut(self, "TypeError: max expected 1 arguments, got 0");
|
||||||
|
obj_setErrorCode(self, PIKA_RES_ERR_INVALID_PARAM);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if (size == 1) {
|
||||||
|
ArgType type = arg_getType(pikaTuple_getArg(val, 0));
|
||||||
|
if ((!argType_isObject(type) && (type != ARG_TYPE_STRING) &&
|
||||||
|
(type != ARG_TYPE_BYTES))) {
|
||||||
|
obj_setSysOut(self, "TypeError: object is not iterable");
|
||||||
|
obj_setErrorCode(self, PIKA_RES_ERR_INVALID_PARAM);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
obj_setArg(self, "@list", pikaTuple_getArg(val, 0));
|
||||||
|
return pikaVM_runByteCodeReturn(self, (uint8_t*)bc, "@res_max");
|
||||||
|
}
|
||||||
|
PikaObj* oTuple = newNormalObj(New_PikaStdData_Tuple);
|
||||||
|
obj_setPtr(oTuple, "list", val);
|
||||||
|
obj_setInt(oTuple, "needfree", 0);
|
||||||
|
Arg* aTuple = arg_newObj(oTuple);
|
||||||
|
obj_setArg(self, "@list", aTuple);
|
||||||
|
Arg* aRet = pikaVM_runByteCodeReturn(self, (uint8_t*)bc, "@res_max");
|
||||||
|
arg_deinit(aTuple);
|
||||||
|
return aRet;
|
||||||
|
}
|
||||||
|
|
||||||
|
Arg* PikaStdLib_SysObj_max(PikaObj* self, PikaTuple* val) {
|
||||||
|
return _max_min(self, val, (uint8_t*)bc_max);
|
||||||
|
}
|
||||||
|
|
||||||
|
Arg* PikaStdLib_SysObj_min(PikaObj* self, PikaTuple* val) {
|
||||||
|
return _max_min(self, val, (uint8_t*)bc_min);
|
||||||
|
}
|
||||||
|
@ -1344,6 +1344,7 @@ ShellHistory* shHistory_create(int max_size) {
|
|||||||
self->current = -1;
|
self->current = -1;
|
||||||
self->count = 0;
|
self->count = 0;
|
||||||
self->last_offset = 0;
|
self->last_offset = 0;
|
||||||
|
self->cached_current = 0;
|
||||||
self->history = (char**)pikaMalloc(max_size * sizeof(char*));
|
self->history = (char**)pikaMalloc(max_size * sizeof(char*));
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
@ -200,6 +200,8 @@ TEST_RUN_SINGLE_FILE_PASS(builtin,
|
|||||||
fn_default_tuple,
|
fn_default_tuple,
|
||||||
"test/python/builtin/fn_default_tuple.py")
|
"test/python/builtin/fn_default_tuple.py")
|
||||||
|
|
||||||
|
TEST_RUN_SINGLE_FILE_PASS(builtin, max_min, "test/python/builtin/max_min.py")
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
TEST_END
|
TEST_END
|
@ -755,11 +755,29 @@ TEST(compiler, str_join) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST(compiler, thread_void_arg) {
|
TEST(compiler, thread_void_arg) {
|
||||||
char* lines =
|
char* lines = "thread()";
|
||||||
"thread()";
|
|
||||||
pika_lines2Array(lines);
|
pika_lines2Array(lines);
|
||||||
EXPECT_EQ(pikaMemNow(), 0);
|
EXPECT_EQ(pikaMemNow(), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(compiler, max) {
|
||||||
|
char* lines =
|
||||||
|
"@res_max = @list[0]\n"
|
||||||
|
"for @item in @list:\n"
|
||||||
|
" if @item > @res_max:\n"
|
||||||
|
" @res_max = @item\n";
|
||||||
|
pika_lines2Array(lines);
|
||||||
|
EXPECT_EQ(pikaMemNow(), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(compiler, min) {
|
||||||
|
char* lines =
|
||||||
|
"@res_max = @list[0]\n"
|
||||||
|
"for @item in @list:\n"
|
||||||
|
" if @item < @res_max:\n"
|
||||||
|
" @res_max = @item\n";
|
||||||
|
pika_lines2Array(lines);
|
||||||
|
EXPECT_EQ(pikaMemNow(), 0);
|
||||||
|
}
|
||||||
|
|
||||||
TEST_END
|
TEST_END
|
13
test/python/builtin/max_min.py
Normal file
13
test/python/builtin/max_min.py
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
# 测试 max() 函数
|
||||||
|
assert max(1, 2, 3) == 3, "max() 函数错误: max(1, 2, 3) 应返回 3"
|
||||||
|
assert max(-1, -2, -3) == -1, "max() 函数错误: max(-1, -2, -3) 应返回 -1"
|
||||||
|
assert max(5, 5) == 5, "max() 函数错误: max(5, 5) 应返回 5"
|
||||||
|
assert max([1, 2, 3, 4]) == 4, "max() 函数错误: max([1, 2, 3, 4]) 应返回 4"
|
||||||
|
|
||||||
|
# 测试 min() 函数
|
||||||
|
assert min(1, 2, 3) == 1, "min() 函数错误: min(1, 2, 3) 应返回 1"
|
||||||
|
assert min(-1, -2, -3) == -3, "min() 函数错误: min(-1, -2, -3) 应返回 -3"
|
||||||
|
assert min(5, 5) == 5, "min() 函数错误: min(5, 5) 应返回 5"
|
||||||
|
assert min([1, 2, 3, 4]) == 1, "min() 函数错误: min([1, 2, 3, 4]) 应返回 1"
|
||||||
|
|
||||||
|
print('PASS')
|
Loading…
x
Reference in New Issue
Block a user