mirror of
https://gitee.com/Lyon1998/pikapython.git
synced 2025-01-15 17:02:53 +08:00
support elif and else
This commit is contained in:
parent
b6bb611d17
commit
484b6a1860
@ -522,3 +522,52 @@ TEST(VM, equ) {
|
||||
ASSERT_FLOAT_EQ(c, 1);
|
||||
EXPECT_EQ(pikaMemNow(), 0);
|
||||
}
|
||||
|
||||
TEST(VM, if_elif) {
|
||||
char* line = (char*)
|
||||
"a = 2\n"
|
||||
"b = 0\n"
|
||||
"if a > 1:\n"
|
||||
" b = 1\n"
|
||||
"elif a > 0:\n"
|
||||
" b = 2\n"
|
||||
"\n"
|
||||
;
|
||||
Args* buffs = New_strBuff();
|
||||
char* pikaAsm = Parser_multiLineToAsm(buffs, line);
|
||||
printf("%s", pikaAsm);
|
||||
PikaObj* self = newRootObj((char*)"root", New_PikaStdLib_SysObj);
|
||||
Parameters* globals = pikaVM_runAsm(self, pikaAsm);
|
||||
|
||||
int b = args_getInt(globals->list, (char*)"b");
|
||||
obj_deinit(self);
|
||||
args_deinit(buffs);
|
||||
// obj_deinit(globals);
|
||||
ASSERT_FLOAT_EQ(b, 1);
|
||||
EXPECT_EQ(pikaMemNow(), 0);
|
||||
}
|
||||
|
||||
TEST(VM, if_else) {
|
||||
char* line = (char*)
|
||||
"a = 0\n"
|
||||
"b = 0\n"
|
||||
"if a > 1:\n"
|
||||
" b = 1\n"
|
||||
"else:\n"
|
||||
" b = 2\n"
|
||||
"\n"
|
||||
;
|
||||
Args* buffs = New_strBuff();
|
||||
char* pikaAsm = Parser_multiLineToAsm(buffs, line);
|
||||
printf("%s", pikaAsm);
|
||||
PikaObj* self = newRootObj((char*)"root", New_PikaStdLib_SysObj);
|
||||
Parameters* globals = pikaVM_runAsm(self, pikaAsm);
|
||||
|
||||
int b = args_getInt(globals->list, (char*)"b");
|
||||
obj_deinit(self);
|
||||
args_deinit(buffs);
|
||||
// obj_deinit(globals);
|
||||
ASSERT_FLOAT_EQ(b, 2);
|
||||
EXPECT_EQ(pikaMemNow(), 0);
|
||||
}
|
||||
|
||||
|
@ -1300,3 +1300,77 @@ TEST(parser, annotation_block) {
|
||||
args_deinit(buffs);
|
||||
EXPECT_EQ(pikaMemNow(), 0);
|
||||
}
|
||||
|
||||
TEST(parser, if_elif_else) {
|
||||
pikaMemInfo.heapUsedMax = 0;
|
||||
Args* buffs = New_strBuff();
|
||||
char* lines = (char*)
|
||||
"if a > 1:\n"
|
||||
" b = 1\n"
|
||||
"elif a > 2:\n"
|
||||
" b = 2\n"
|
||||
" if a > 1:\n"
|
||||
" b = 1\n"
|
||||
" elif a > 2:\n"
|
||||
" b = 2\n"
|
||||
" else:\n"
|
||||
" b = 3\n"
|
||||
"\n"
|
||||
"else:\n"
|
||||
" b = 3\n"
|
||||
"\n"
|
||||
;
|
||||
printf("%s", lines);
|
||||
char* pikaAsm = Parser_multiLineToAsm(buffs, (char*)lines);
|
||||
printf("%s", pikaAsm);
|
||||
EXPECT_STREQ(pikaAsm,(char *)
|
||||
"B0\n"
|
||||
"1 REF a\n"
|
||||
"1 NUM 1\n"
|
||||
"0 OPT >\n"
|
||||
"0 JEZ 1\n"
|
||||
"B1\n"
|
||||
"0 NUM 1\n"
|
||||
"0 OUT b\n"
|
||||
"B0\n"
|
||||
"0 NEL 1\n"
|
||||
"1 REF a\n"
|
||||
"1 NUM 2\n"
|
||||
"0 OPT >\n"
|
||||
"0 JEZ 1\n"
|
||||
"B1\n"
|
||||
"0 NUM 2\n"
|
||||
"0 OUT b\n"
|
||||
"B1\n"
|
||||
"1 REF a\n"
|
||||
"1 NUM 1\n"
|
||||
"0 OPT >\n"
|
||||
"0 JEZ 1\n"
|
||||
"B2\n"
|
||||
"0 NUM 1\n"
|
||||
"0 OUT b\n"
|
||||
"B1\n"
|
||||
"0 NEL 1\n"
|
||||
"1 REF a\n"
|
||||
"1 NUM 2\n"
|
||||
"0 OPT >\n"
|
||||
"0 JEZ 1\n"
|
||||
"B2\n"
|
||||
"0 NUM 2\n"
|
||||
"0 OUT b\n"
|
||||
"B1\n"
|
||||
"0 NEL 1\n"
|
||||
"B2\n"
|
||||
"0 NUM 3\n"
|
||||
"0 OUT b\n"
|
||||
"B0\n"
|
||||
"B0\n"
|
||||
"0 NEL 1\n"
|
||||
"B1\n"
|
||||
"0 NUM 3\n"
|
||||
"0 OUT b\n"
|
||||
"B0\n"
|
||||
);
|
||||
args_deinit(buffs);
|
||||
EXPECT_EQ(pikaMemNow(), 0);
|
||||
}
|
@ -984,50 +984,57 @@ char* AST_toPikaAsm(AST* ast, Args* buffs) {
|
||||
/* "deepth" is invoke deepth, not the blockDeepth */
|
||||
obj_setInt(ast, "deepth", 0);
|
||||
|
||||
/* parse ast to asm main process */
|
||||
pikaAsm = AST_appandPikaAsm(ast, ast, runBuffs, pikaAsm);
|
||||
|
||||
/* match block */
|
||||
uint8_t is_block_matched = 0;
|
||||
if (strEqu(obj_getStr(ast, "block"), "while")) {
|
||||
/* parse stmt ast */
|
||||
pikaAsm = AST_appandPikaAsm(ast, ast, runBuffs, pikaAsm);
|
||||
pikaAsm = strsAppend(runBuffs, pikaAsm, "0 JEZ 2\n");
|
||||
goto block_matched;
|
||||
is_block_matched = 1;
|
||||
goto exit;
|
||||
}
|
||||
if (strEqu(obj_getStr(ast, "block"), "if")) {
|
||||
/* parse stmt ast */
|
||||
pikaAsm = AST_appandPikaAsm(ast, ast, runBuffs, pikaAsm);
|
||||
pikaAsm = strsAppend(runBuffs, pikaAsm, "0 JEZ 1\n");
|
||||
goto block_matched;
|
||||
is_block_matched = 1;
|
||||
goto exit;
|
||||
}
|
||||
if (strEqu(obj_getStr(ast, "block"), "else")) {
|
||||
uint8_t blockDeepth = obj_getInt(ast, "blockDeepth");
|
||||
char __REF_else[] = "0 REF __else0\n";
|
||||
__REF_else[12] = blockDeepth + '0';
|
||||
/* skip if __else is 0 */
|
||||
pikaAsm = strsAppend(runBuffs, pikaAsm, __REF_else);
|
||||
pikaAsm = strsAppend(runBuffs, pikaAsm, "0 JEZ 1\n");
|
||||
goto block_matched;
|
||||
pikaAsm = strsAppend(runBuffs, pikaAsm, "0 NEL 1\n");
|
||||
goto exit;
|
||||
}
|
||||
if (strEqu(obj_getStr(ast, "block"), "elif")) {
|
||||
uint8_t blockDeepth = obj_getInt(ast, "blockDeepth");
|
||||
char __REF_else[] = "0 REF __else0\n";
|
||||
__REF_else[12] = blockDeepth + '0';
|
||||
/* skip if __else is 0 */
|
||||
pikaAsm = strsAppend(runBuffs, pikaAsm, "0 NEL 1\n");
|
||||
/* parse stmt ast */
|
||||
pikaAsm = AST_appandPikaAsm(ast, ast, runBuffs, pikaAsm);
|
||||
/* skip if stmt is 0 */
|
||||
pikaAsm = strsAppend(runBuffs, pikaAsm, "0 JEZ 1\n");
|
||||
/* skip if __else is 0 */
|
||||
pikaAsm = strsAppend(runBuffs, pikaAsm, __REF_else);
|
||||
pikaAsm = strsAppend(runBuffs, pikaAsm, "0 JEZ 1\n");
|
||||
goto block_matched;
|
||||
is_block_matched = 1;
|
||||
goto exit;
|
||||
}
|
||||
if (strEqu(obj_getStr(ast, "block"), "def")) {
|
||||
pikaAsm = strsAppend(runBuffs, pikaAsm, "0 DEF ");
|
||||
pikaAsm = strsAppend(runBuffs, pikaAsm, obj_getStr(ast, "declear"));
|
||||
pikaAsm = strsAppend(runBuffs, pikaAsm, "\n");
|
||||
pikaAsm = strsAppend(runBuffs, pikaAsm, "0 JMP 1\n");
|
||||
goto block_matched;
|
||||
is_block_matched = 1;
|
||||
goto exit;
|
||||
}
|
||||
if (obj_isArgExist(ast, "return")) {
|
||||
/* parse stmt ast */
|
||||
pikaAsm = AST_appandPikaAsm(ast, ast, runBuffs, pikaAsm);
|
||||
pikaAsm = strsAppend(runBuffs, pikaAsm, "0 RET\n");
|
||||
goto block_matched;
|
||||
is_block_matched = 1;
|
||||
goto exit;
|
||||
}
|
||||
block_matched:
|
||||
exit:
|
||||
if (!is_block_matched) {
|
||||
/* parse stmt ast */
|
||||
pikaAsm = AST_appandPikaAsm(ast, ast, runBuffs, pikaAsm);
|
||||
}
|
||||
|
||||
/* output pikaAsm */
|
||||
pikaAsm = strsCopy(buffs, pikaAsm);
|
||||
args_deinit(runBuffs);
|
||||
|
23
src/PikaVM.c
23
src/PikaVM.c
@ -43,7 +43,7 @@ static int32_t getLineSize(char* str) {
|
||||
i++;
|
||||
}
|
||||
}
|
||||
enum Instruct { NON, REF, RUN, STR, OUT, NUM, JMP, JEZ, OPT, DEF, RET };
|
||||
enum Instruct { NON, REF, RUN, STR, OUT, NUM, JMP, JEZ, OPT, DEF, RET, NEL };
|
||||
|
||||
static char* strs_getLine(Args* buffs, char* code) {
|
||||
int32_t lineSize = getLineSize(code);
|
||||
@ -94,6 +94,10 @@ static enum Instruct getInstruct(char* line) {
|
||||
/* return */
|
||||
return RET;
|
||||
}
|
||||
if (0 == strncmp(line + 2, "NEL", 3)) {
|
||||
/* not else */
|
||||
return NEL;
|
||||
}
|
||||
return NON;
|
||||
}
|
||||
|
||||
@ -174,13 +178,24 @@ Arg* pikaVM_runInstruct(PikaObj* self,
|
||||
arg_deinit(assertArg);
|
||||
char __else[] = "__else0";
|
||||
__else[6] = '0' + thisBlockDeepth;
|
||||
args_setInt(self->list, __else, !assert);
|
||||
if (0 == assert) {
|
||||
/* set __else flag */
|
||||
args_setInt(self->list, __else, 1);
|
||||
*jmp = fast_atoi(data);
|
||||
}
|
||||
/* set __else flag to ezro */
|
||||
args_setInt(self->list, __else, 0);
|
||||
return NULL;
|
||||
}
|
||||
if (instruct == NEL) {
|
||||
int offset = 0;
|
||||
int thisBlockDeepth =
|
||||
getThisBlockDeepth(asmStart, programConter, &offset);
|
||||
char __else[] = "__else0";
|
||||
__else[6] = '0' + thisBlockDeepth;
|
||||
if (0 == args_getInt(self->list, __else)) {
|
||||
/* set __else flag */
|
||||
*jmp = fast_atoi(data);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
if (instruct == OPT) {
|
||||
Arg* outArg = NULL;
|
||||
|
Loading…
x
Reference in New Issue
Block a user