Extended VM and fp compiler, now an actually good hello world program

This commit is contained in:
cannoli-fruit 2026-07-25 18:36:08 -04:00
commit fda7baea7f
4 changed files with 116 additions and 3 deletions

View file

@ -74,6 +74,16 @@ static inline bool isKW(Lz_SB *sb) {
|| SBeq(sb, "ld8") || SBeq(sb, "ld8")
|| SBeq(sb, "st8") || SBeq(sb, "st8")
|| SBeq(sb, "dup") || 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; continue;
codegen: codegen:
//printf("I must gen code i am now Amista Azozin\n"); //printf("I must gen code i am now Amista Azozin\n");
//printf("Token type: %d\n", currTokenKind); //fprintf(stderr,"Token type: %d\n", currTokenKind);
//printf("Tok: "LZ_STR_FMT"\n", LZ_STR_PRINTF(tokenAccumulator)); //fprintf(stderr,"Tok: "LZ_STR_FMT"\n", LZ_STR_PRINTF(tokenAccumulator));
switch (currTokenKind) { switch (currTokenKind) {
case TOKEN_KEYWORD: { case TOKEN_KEYWORD: {
if (SBeq(&tokenAccumulator, "proc")) { if (SBeq(&tokenAccumulator, "proc")) {
@ -195,7 +205,57 @@ codegen:
printf(" pushstack 106\n"); printf(" pushstack 106\n");
break; 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)); LZ_STR_PRINTF(tokenAccumulator));
exit(1); exit(1);
} }
@ -206,6 +266,12 @@ codegen:
isProc = false; isProc = false;
break; 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? // Iirc there's not a general thing for identifiers so just fail?
fprintf(stderr, "Useless Identifier: "LZ_STR_FMT"\n", fprintf(stderr, "Useless Identifier: "LZ_STR_FMT"\n",
LZ_STR_PRINTF(tokenAccumulator)); LZ_STR_PRINTF(tokenAccumulator));

19
flagpole/tests/hwgood.fp Normal file
View file

@ -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

View file

@ -219,6 +219,11 @@ int main(int argc, char **argv) {
negativeFlag = (valA < valB); negativeFlag = (valA < valB);
break; break;
} }
case 0x41: { // Not64
unsigned char reg = inputs[0];
registers[reg] = ~registers[reg];
break;
}
case 0x94: { // Mov64 case 0x94: { // Mov64
unsigned char dst = inputs[0]; unsigned char dst = inputs[0];
unsigned char src = inputs[1]; unsigned char src = inputs[1];
@ -276,6 +281,14 @@ int main(int argc, char **argv) {
} }
break; break;
} }
case 0xC8: { // JmpIE
unsigned char addr = inputs[0];
if (!parityFlag) {
if (DEBUG) printf("Jump!\n");
xPc = registers[addr];
}
break;
}
case 0x46: { // Call case 0x46: { // Call
unsigned char addr = inputs[0]; unsigned char addr = inputs[0];
xSp -= 8; xSp -= 8;

View file

@ -284,6 +284,11 @@ macro Cmp64 A, B
db B db B
end macro end macro
macro Not64 reg
db 0x41
db reg
end macro
macro RSetF reg macro RSetF reg
db 0x42 db 0x42
db reg db reg
@ -319,6 +324,16 @@ macro JmpIP addr
JmpRIP 127 JmpRIP 127
end macro end macro
macro JmpRIE addr
db 0xC8
db addr
end macro
macro JmpIE addr
MovI64 127, addr
JmpRIE 127
end macro
macro CallR addr macro CallR addr
db 0x46 db 0x46
db addr db addr