Implemented break and continue and improved label stack handling
This commit is contained in:
parent
ace8222b7e
commit
1606150450
3 changed files with 97 additions and 14 deletions
|
|
@ -113,6 +113,8 @@ static inline bool isKW(Lz_SB *sb) {
|
|||
|| SBeq(sb, "then")
|
||||
|| SBeq(sb, "endif")
|
||||
|| SBeq(sb, "endwhile")
|
||||
|| SBeq(sb, "break")
|
||||
|| SBeq(sb, "continue")
|
||||
|| SBeq(sb, "==")
|
||||
|| SBeq(sb, "not")
|
||||
|| SBeq(sb, "bor")
|
||||
|
|
@ -158,6 +160,16 @@ static inline bool isKW(Lz_SB *sb) {
|
|||
}; \
|
||||
}
|
||||
|
||||
typedef enum {
|
||||
LABEL_WHILE,
|
||||
LABEL_IF,
|
||||
} LabelKind;
|
||||
|
||||
typedef struct {
|
||||
LabelKind typ;
|
||||
int num;
|
||||
} AsmLabel;
|
||||
|
||||
int main(uint argc, char **argv) {
|
||||
int opt;
|
||||
Lz_DA(FILE *) inpfiles = {};
|
||||
|
|
@ -190,7 +202,7 @@ int main(uint argc, char **argv) {
|
|||
bool isProc = false;
|
||||
bool isInclude = false;
|
||||
bool isComment = false;
|
||||
Lz_DA(int) labelStack = {0};
|
||||
Lz_DA(AsmLabel) labelStack = {0};
|
||||
uint64_t allocHead = 0x7000000000000000;
|
||||
char funcName[128];
|
||||
Lz_DA(Variable) vars = {0};
|
||||
|
|
@ -379,29 +391,63 @@ codegenIR:
|
|||
}
|
||||
if (SBeq(&tokenAccumulator, "while")) {
|
||||
IRComplete(&irStatements, &irVStack);
|
||||
lz_da_append(labelStack, counter);
|
||||
AsmLabel lbl = (AsmLabel) {
|
||||
.num = counter,
|
||||
.typ = LABEL_WHILE
|
||||
};
|
||||
lz_da_append(labelStack, lbl);
|
||||
commentStack(&labelStack);
|
||||
printf("__whilehead_%d:\n", counter);
|
||||
printf("__whilehead_%d:\n", lbl.num);
|
||||
break;
|
||||
}
|
||||
if (SBeq(&tokenAccumulator, "do")) {
|
||||
IRComplete(&irStatements, &irVStack);
|
||||
vstackUnderflows = 0;
|
||||
int lbl = lz_da_pop(labelStack);
|
||||
AsmLabel lbl = lz_da_pop(labelStack);
|
||||
if (lbl.typ != LABEL_WHILE) {
|
||||
fprintf(stderr, "Unmatched do without a while\n");
|
||||
exit(1);
|
||||
}
|
||||
lz_da_append(labelStack, lbl);
|
||||
// TODO: Change flag setting to IR's job
|
||||
printf(" popstack 108\n");
|
||||
printf(" RSetF 108\n");
|
||||
printf(" JmpIE __whiletail_%d\n", lbl);
|
||||
printf(" JmpIE __whiletail_%d\n", lbl.num);
|
||||
break;
|
||||
}
|
||||
if (SBeq(&tokenAccumulator, "endwhile")) {
|
||||
IRComplete(&irStatements, &irVStack);
|
||||
vstackUnderflows = 0;
|
||||
int lbl = lz_da_pop(labelStack);
|
||||
AsmLabel lbl = lz_da_pop(labelStack);
|
||||
if (lbl.typ != LABEL_WHILE) {
|
||||
fprintf(stderr, "Unmatched endwhile without while\n");
|
||||
exit(1);
|
||||
}
|
||||
commentStack(&labelStack);
|
||||
printf(" Jmp __whilehead_%d\n", lbl);
|
||||
printf("__whiletail_%d:\n", lbl);
|
||||
printf(" Jmp __whilehead_%d\n", lbl.num);
|
||||
printf("__whiletail_%d:\n", lbl.num);
|
||||
break;
|
||||
}
|
||||
if (SBeq(&tokenAccumulator, "break")) {
|
||||
IRComplete(&irStatements, &irVStack);
|
||||
AsmLabel lbl;
|
||||
for (int i = labelStack.cnt; i >= 0; --i) {
|
||||
if (labelStack.data[i].typ == LABEL_WHILE) {
|
||||
lbl = labelStack.data[i];
|
||||
}
|
||||
}
|
||||
printf(" Jmp __whiletail_%d\n", lbl.num);
|
||||
break;
|
||||
}
|
||||
if (SBeq(&tokenAccumulator, "continue")) {
|
||||
IRComplete(&irStatements, &irVStack);
|
||||
AsmLabel lbl;
|
||||
for (int i = labelStack.cnt; i >= 0; --i) {
|
||||
if (labelStack.data[i].typ == LABEL_WHILE) {
|
||||
lbl = labelStack.data[i];
|
||||
}
|
||||
}
|
||||
printf(" Jmp __whilehead_%d\n", lbl.num);
|
||||
break;
|
||||
}
|
||||
if (SBeq(&tokenAccumulator, "if")) {
|
||||
|
|
@ -410,14 +456,16 @@ codegenIR:
|
|||
if (SBeq(&tokenAccumulator, "then")) {
|
||||
IRComplete(&irStatements, &irVStack);
|
||||
|
||||
lz_da_append(labelStack, counter);
|
||||
AsmLabel lbl = (AsmLabel) {
|
||||
.num = counter,
|
||||
.typ = LABEL_IF
|
||||
};
|
||||
lz_da_append(labelStack, lbl);
|
||||
commentStack(&labelStack);
|
||||
vstackUnderflows = 0;
|
||||
int lbl = lz_da_pop(labelStack);
|
||||
lz_da_append(labelStack, lbl);
|
||||
printf(" popstack 123\n");
|
||||
printf(" RSetF 123\n");
|
||||
printf(" JmpIE __iftail_%d\n", lbl);
|
||||
printf(" JmpIE __iftail_%d\n", lbl.num);
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -425,8 +473,12 @@ codegenIR:
|
|||
IRComplete(&irStatements, &irVStack);
|
||||
vstackUnderflows = 0;
|
||||
commentStack(&labelStack);
|
||||
int lbl = lz_da_pop(labelStack);
|
||||
printf("__iftail_%d:\n", lbl);
|
||||
AsmLabel lbl = lz_da_pop(labelStack);
|
||||
if (lbl.typ != LABEL_IF) {
|
||||
fprintf(stderr, "Unmatched endif without an if\n");
|
||||
exit(1);
|
||||
}
|
||||
printf("__iftail_%d:\n", lbl.num);
|
||||
break;
|
||||
}
|
||||
if (SBeq(&tokenAccumulator, "==")) {
|
||||
|
|
|
|||
11
flagpole/tests/break.fp
Normal file
11
flagpole/tests/break.fp
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
$inc fvmstd.fp
|
||||
|
||||
proc main
|
||||
while 1 do
|
||||
if :getuint 37 == then
|
||||
break
|
||||
endif
|
||||
"Try again" :puts :newline
|
||||
endwhile
|
||||
"You got it!" :puts :newline
|
||||
endproc
|
||||
20
flagpole/tests/continue.fp
Normal file
20
flagpole/tests/continue.fp
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
$inc fvmstd.fp
|
||||
|
||||
proc main
|
||||
while 1 do
|
||||
if :getuint 37 == not then
|
||||
"Number 1 incorrect" :puts :newline
|
||||
continue
|
||||
endif
|
||||
if :getuint 42 == not then
|
||||
"Number 2 incorrect" :puts :newline
|
||||
continue
|
||||
endif
|
||||
if :getuint 69 == not then
|
||||
"Number 3 incorrect" :puts :newline
|
||||
continue
|
||||
endif
|
||||
break
|
||||
endwhile
|
||||
"You've logged in" :puts :newline
|
||||
endproc
|
||||
Loading…
Add table
Add a link
Reference in a new issue