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, "then")
|
||||||
|| SBeq(sb, "endif")
|
|| SBeq(sb, "endif")
|
||||||
|| SBeq(sb, "endwhile")
|
|| SBeq(sb, "endwhile")
|
||||||
|
|| SBeq(sb, "break")
|
||||||
|
|| SBeq(sb, "continue")
|
||||||
|| SBeq(sb, "==")
|
|| SBeq(sb, "==")
|
||||||
|| SBeq(sb, "not")
|
|| SBeq(sb, "not")
|
||||||
|| SBeq(sb, "bor")
|
|| 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 main(uint argc, char **argv) {
|
||||||
int opt;
|
int opt;
|
||||||
Lz_DA(FILE *) inpfiles = {};
|
Lz_DA(FILE *) inpfiles = {};
|
||||||
|
|
@ -190,7 +202,7 @@ int main(uint argc, char **argv) {
|
||||||
bool isProc = false;
|
bool isProc = false;
|
||||||
bool isInclude = false;
|
bool isInclude = false;
|
||||||
bool isComment = false;
|
bool isComment = false;
|
||||||
Lz_DA(int) labelStack = {0};
|
Lz_DA(AsmLabel) labelStack = {0};
|
||||||
uint64_t allocHead = 0x7000000000000000;
|
uint64_t allocHead = 0x7000000000000000;
|
||||||
char funcName[128];
|
char funcName[128];
|
||||||
Lz_DA(Variable) vars = {0};
|
Lz_DA(Variable) vars = {0};
|
||||||
|
|
@ -379,29 +391,63 @@ codegenIR:
|
||||||
}
|
}
|
||||||
if (SBeq(&tokenAccumulator, "while")) {
|
if (SBeq(&tokenAccumulator, "while")) {
|
||||||
IRComplete(&irStatements, &irVStack);
|
IRComplete(&irStatements, &irVStack);
|
||||||
lz_da_append(labelStack, counter);
|
AsmLabel lbl = (AsmLabel) {
|
||||||
|
.num = counter,
|
||||||
|
.typ = LABEL_WHILE
|
||||||
|
};
|
||||||
|
lz_da_append(labelStack, lbl);
|
||||||
commentStack(&labelStack);
|
commentStack(&labelStack);
|
||||||
printf("__whilehead_%d:\n", counter);
|
printf("__whilehead_%d:\n", lbl.num);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (SBeq(&tokenAccumulator, "do")) {
|
if (SBeq(&tokenAccumulator, "do")) {
|
||||||
IRComplete(&irStatements, &irVStack);
|
IRComplete(&irStatements, &irVStack);
|
||||||
vstackUnderflows = 0;
|
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);
|
lz_da_append(labelStack, lbl);
|
||||||
// TODO: Change flag setting to IR's job
|
// TODO: Change flag setting to IR's job
|
||||||
printf(" popstack 108\n");
|
printf(" popstack 108\n");
|
||||||
printf(" RSetF 108\n");
|
printf(" RSetF 108\n");
|
||||||
printf(" JmpIE __whiletail_%d\n", lbl);
|
printf(" JmpIE __whiletail_%d\n", lbl.num);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (SBeq(&tokenAccumulator, "endwhile")) {
|
if (SBeq(&tokenAccumulator, "endwhile")) {
|
||||||
IRComplete(&irStatements, &irVStack);
|
IRComplete(&irStatements, &irVStack);
|
||||||
vstackUnderflows = 0;
|
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);
|
commentStack(&labelStack);
|
||||||
printf(" Jmp __whilehead_%d\n", lbl);
|
printf(" Jmp __whilehead_%d\n", lbl.num);
|
||||||
printf("__whiletail_%d:\n", lbl);
|
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;
|
break;
|
||||||
}
|
}
|
||||||
if (SBeq(&tokenAccumulator, "if")) {
|
if (SBeq(&tokenAccumulator, "if")) {
|
||||||
|
|
@ -410,14 +456,16 @@ codegenIR:
|
||||||
if (SBeq(&tokenAccumulator, "then")) {
|
if (SBeq(&tokenAccumulator, "then")) {
|
||||||
IRComplete(&irStatements, &irVStack);
|
IRComplete(&irStatements, &irVStack);
|
||||||
|
|
||||||
lz_da_append(labelStack, counter);
|
AsmLabel lbl = (AsmLabel) {
|
||||||
|
.num = counter,
|
||||||
|
.typ = LABEL_IF
|
||||||
|
};
|
||||||
|
lz_da_append(labelStack, lbl);
|
||||||
commentStack(&labelStack);
|
commentStack(&labelStack);
|
||||||
vstackUnderflows = 0;
|
vstackUnderflows = 0;
|
||||||
int lbl = lz_da_pop(labelStack);
|
|
||||||
lz_da_append(labelStack, lbl);
|
|
||||||
printf(" popstack 123\n");
|
printf(" popstack 123\n");
|
||||||
printf(" RSetF 123\n");
|
printf(" RSetF 123\n");
|
||||||
printf(" JmpIE __iftail_%d\n", lbl);
|
printf(" JmpIE __iftail_%d\n", lbl.num);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -425,8 +473,12 @@ codegenIR:
|
||||||
IRComplete(&irStatements, &irVStack);
|
IRComplete(&irStatements, &irVStack);
|
||||||
vstackUnderflows = 0;
|
vstackUnderflows = 0;
|
||||||
commentStack(&labelStack);
|
commentStack(&labelStack);
|
||||||
int lbl = lz_da_pop(labelStack);
|
AsmLabel lbl = lz_da_pop(labelStack);
|
||||||
printf("__iftail_%d:\n", lbl);
|
if (lbl.typ != LABEL_IF) {
|
||||||
|
fprintf(stderr, "Unmatched endif without an if\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
printf("__iftail_%d:\n", lbl.num);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (SBeq(&tokenAccumulator, "==")) {
|
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