From fda7baea7f5b8fb08c482d296ba4cadfa31c4555 Mon Sep 17 00:00:00 2001 From: cannoli-fruit Date: Sat, 25 Jul 2026 18:36:08 -0400 Subject: [PATCH] Extended VM and fp compiler, now an actually good hello world program --- flagpole/src/main.c | 72 ++++++++++++++++++++++++++++++++++++++-- flagpole/tests/hwgood.fp | 19 +++++++++++ src/interp.c | 13 ++++++++ tests/fvm.inc | 15 +++++++++ 4 files changed, 116 insertions(+), 3 deletions(-) create mode 100644 flagpole/tests/hwgood.fp diff --git a/flagpole/src/main.c b/flagpole/src/main.c index 6a4326d..2a56dcc 100644 --- a/flagpole/src/main.c +++ b/flagpole/src/main.c @@ -74,6 +74,16 @@ static inline bool isKW(Lz_SB *sb) { || SBeq(sb, "ld8") || SBeq(sb, "st8") || SBeq(sb, "dup") + || SBeq(sb, "while") + || SBeq(sb, "do") + || SBeq(sb, "endwhile") + || SBeq(sb, "==") + || SBeq(sb, "not") + || SBeq(sb, "u+") + || SBeq(sb, "u-") + || SBeq(sb, "u*") + || SBeq(sb, "u/") + || SBeq(sb, "pop") ; } @@ -164,8 +174,8 @@ int main(uint argc, char **argv) { continue; codegen: //printf("I must gen code i am now Amista Azozin\n"); - //printf("Token type: %d\n", currTokenKind); - //printf("Tok: "LZ_STR_FMT"\n", LZ_STR_PRINTF(tokenAccumulator)); + //fprintf(stderr,"Token type: %d\n", currTokenKind); + //fprintf(stderr,"Tok: "LZ_STR_FMT"\n", LZ_STR_PRINTF(tokenAccumulator)); switch (currTokenKind) { case TOKEN_KEYWORD: { if (SBeq(&tokenAccumulator, "proc")) { @@ -195,7 +205,57 @@ codegen: printf(" pushstack 106\n"); break; } - printf("Unknown keyword: "LZ_STR_FMT"\n", + if (SBeq(&tokenAccumulator, "while")) { + lz_da_append(labelStack, counter); + printf("__whilehead_%d:\n", counter); + break; + } + if (SBeq(&tokenAccumulator, "do")) { + int lbl = lz_da_pop(labelStack); + lz_da_append(labelStack, lbl); + printf(" popstack 108\n"); + printf(" RSetF 108\n"); + printf(" JmpIE __whiletail_%d\n", lbl); + break; + } + if (SBeq(&tokenAccumulator, "endwhile")) { + int lbl = lz_da_pop(labelStack); + printf(" Jmp __whilehead_%d\n", lbl); + printf("__whiletail_%d:\n", lbl); + break; + } + if (SBeq(&tokenAccumulator, "==")) { + // Hacked like crazy... + printf(" popstack 110\n"); + printf(" popstack 111\n"); + printf(" Cmp64 110, 111\n"); + printf(" JmpIZ __Eq%d\n", counter); + printf(" MovI64 112, 0\n"); + printf(" Jmp __DoneEqCheck%d\n", counter); + printf("__Eq%d:\n", counter); + printf(" MovI64 112, 1\n"); + printf("__DoneEqCheck%d:\n", counter); + printf(" pushstack 112\n"); + break; + } + if (SBeq(&tokenAccumulator, "not")) { + printf(" popstack 96\n"); + printf(" Not64 96\n"); + printf(" pushstack 96\n"); + break; + } + if (SBeq(&tokenAccumulator, "u+")) { + printf(" popstack 97\n"); + printf(" popstack 98\n"); + printf(" AddR64 98, 97\n"); + printf(" pushstack 98\n"); + break; + } + if (SBeq(&tokenAccumulator, "pop")) { + printf(" popstack 113\n"); + break; + } + printf("Unimplemented keyword: "LZ_STR_FMT"\n", LZ_STR_PRINTF(tokenAccumulator)); exit(1); } @@ -206,6 +266,12 @@ codegen: isProc = false; break; } + if (tokenAccumulator.data[0] == ':') { + printf(" Call __fp_user_"LZ_STR_FMT"\n", + tokenAccumulator.cnt-1, + tokenAccumulator.data+1); + break; + } // Iirc there's not a general thing for identifiers so just fail? fprintf(stderr, "Useless Identifier: "LZ_STR_FMT"\n", LZ_STR_PRINTF(tokenAccumulator)); diff --git a/flagpole/tests/hwgood.fp b/flagpole/tests/hwgood.fp new file mode 100644 index 0000000..75972ef --- /dev/null +++ b/flagpole/tests/hwgood.fp @@ -0,0 +1,19 @@ +proc putchar + 0xCFFFFFFFFFFFFFFD st8 +endproc + +proc puts + while dup ld8 0 == not do + dup ld8 :putchar + 1 u+ + endwhile + pop +endproc + +proc newline + 10 :putchar +endproc + +proc main + "Hello World!" :puts :newline +endproc diff --git a/src/interp.c b/src/interp.c index 6fd5430..f7994cd 100644 --- a/src/interp.c +++ b/src/interp.c @@ -219,6 +219,11 @@ int main(int argc, char **argv) { negativeFlag = (valA < valB); break; } + case 0x41: { // Not64 + unsigned char reg = inputs[0]; + registers[reg] = ~registers[reg]; + break; + } case 0x94: { // Mov64 unsigned char dst = inputs[0]; unsigned char src = inputs[1]; @@ -276,6 +281,14 @@ int main(int argc, char **argv) { } break; } + case 0xC8: { // JmpIE + unsigned char addr = inputs[0]; + if (!parityFlag) { + if (DEBUG) printf("Jump!\n"); + xPc = registers[addr]; + } + break; + } case 0x46: { // Call unsigned char addr = inputs[0]; xSp -= 8; diff --git a/tests/fvm.inc b/tests/fvm.inc index 5ff80cc..0d5af39 100644 --- a/tests/fvm.inc +++ b/tests/fvm.inc @@ -284,6 +284,11 @@ macro Cmp64 A, B db B end macro +macro Not64 reg + db 0x41 + db reg +end macro + macro RSetF reg db 0x42 db reg @@ -319,6 +324,16 @@ macro JmpIP addr JmpRIP 127 end macro +macro JmpRIE addr + db 0xC8 + db addr +end macro + +macro JmpIE addr + MovI64 127, addr + JmpRIE 127 +end macro + macro CallR addr db 0x46 db addr