Implemented directive in flagpole compiler and added it into programs

This commit is contained in:
cannoli-fruit 2026-07-25 22:16:00 -04:00
commit d2f314622a
3 changed files with 48 additions and 28 deletions

View file

@ -69,7 +69,7 @@ bool SBeq(Lz_SB *sb, const char *cstr) {
static inline bool isKW(Lz_SB *sb) { static inline bool isKW(Lz_SB *sb) {
return return
SBeq(sb, "proc") SBeq(sb, "proc")
|| SBeq(sb, "endproc") || SBeq(sb, "endproc")
|| SBeq(sb, "ld8") || SBeq(sb, "ld8")
|| SBeq(sb, "st8") || SBeq(sb, "st8")
@ -84,31 +84,41 @@ static inline bool isKW(Lz_SB *sb) {
|| SBeq(sb, "u*") || SBeq(sb, "u*")
|| SBeq(sb, "u/") || SBeq(sb, "u/")
|| SBeq(sb, "pop") || SBeq(sb, "pop")
|| SBeq(sb, "$inc")
; ;
} }
int main(uint argc, char **argv) { int main(uint argc, char **argv) {
int opt; int opt;
FILE *inpfile = stdin; Lz_DA(FILE *) inpfiles = {};
while ((opt = getopt(argc, argv, "f:")) != -1) { while ((opt = getopt(argc, argv, "f:")) != -1) {
switch(opt) { switch(opt) {
case 'f': case 'f': {
inpfile = fopen(optarg, "r"); FILE *inpfile = fopen(optarg, "r");
if (!inpfile) { if (!inpfile) {
printf("Failed to open file %s\n", optarg); printf("Failed to open file %s\n", optarg);
exit(1); exit(1);
} }
lz_da_append(inpfiles, inpfile);
break; break;
default: }
break; default: break;
} }
} }
if (inpfiles.cnt == 0) {
printf("No file requested\n");
exit(1);
}
FILE *currFile = lz_da_pop(inpfiles);
TokenKind currTokenKind; TokenKind currTokenKind;
Lz_SB tokenAccumulator = {0}; Lz_SB tokenAccumulator = {0};
int counter = 0; int counter = 0;
bool isQuote = false; bool isQuote = false;
bool isProc = false; bool isProc = false;
bool isInclude = false;
Lz_DA(int) labelStack = {0}; Lz_DA(int) labelStack = {0};
char newchar; char newchar;
printf("include 'fvm.inc'\n"); printf("include 'fvm.inc'\n");
@ -128,7 +138,9 @@ int main(uint argc, char **argv) {
printf(" Ld64 reg, STACK_SP\n"); printf(" Ld64 reg, STACK_SP\n");
printf(" AddR64 STACK_SP, 124\n"); printf(" AddR64 STACK_SP, 124\n");
printf("end macro\n\n"); printf("end macro\n\n");
while ((newchar = fgetc(inpfile)) != EOF) { // Genuinely idk why goto is possessing me today
compileStart:
while ((newchar = fgetc(currFile)) != EOF) {
++counter; ++counter;
if (isspace(newchar) && !isQuote) { if (isspace(newchar) && !isQuote) {
if (tokenAccumulator.cnt == 0) continue; if (tokenAccumulator.cnt == 0) continue;
@ -255,11 +267,24 @@ codegen:
printf(" popstack 113\n"); printf(" popstack 113\n");
break; break;
} }
if (SBeq(&tokenAccumulator, "$inc")) {
isInclude = true;
break;
}
printf("Unimplemented keyword: "LZ_STR_FMT"\n", printf("Unimplemented keyword: "LZ_STR_FMT"\n",
LZ_STR_PRINTF(tokenAccumulator)); LZ_STR_PRINTF(tokenAccumulator));
exit(1); exit(1);
} }
case TOKEN_IDENTIFIER: { case TOKEN_IDENTIFIER: {
if (isInclude) {
char *fname = malloc(tokenAccumulator.cnt+1);
memcpy(fname, tokenAccumulator.data, tokenAccumulator.cnt);
fname[tokenAccumulator.cnt] = 0;
FILE *f = fopen(fname, "rb");
lz_da_append(inpfiles, f);
isInclude = false;
break;
}
if (isProc) { if (isProc) {
printf("__fp_user_"LZ_STR_FMT":\n", printf("__fp_user_"LZ_STR_FMT":\n",
LZ_STR_PRINTF(tokenAccumulator)); LZ_STR_PRINTF(tokenAccumulator));
@ -306,4 +331,13 @@ codegen:
} }
tokenAccumulator.cnt = 0; tokenAccumulator.cnt = 0;
} }
if (inpfiles.cnt != 0) {
currFile = lz_da_pop(inpfiles);
tokenAccumulator.cnt = 0;
isProc = false;
isQuote = false;
isInclude = false;
labelStack.cnt = 0;
goto compileStart;
}
} }

5
flagpole/tests/stdhw.fp Normal file
View file

@ -0,0 +1,5 @@
$inc fvmstd.fp
proc main
"Hello World!" :puts :newline
endproc

View file

@ -1,27 +1,8 @@
proc putchar $inc fvmstd.fp
0xCFFFFFFFFFFFFFFD st8
endproc
proc getchar
0xCFFFFFFFFFFFFFFE ld8
endproc
proc puts
while dup ld8 0 == not do
dup ld8 :putchar
1 u+
endwhile
pop
endproc
proc newline
10 :putchar
endproc
proc main proc main
:getchar :getchar
dup :putchar
while dup "1" ld8 == do while dup "1" ld8 == do
dup :putchar dup :putchar
endwhile endwhile
endproc endproc