diff --git a/flagpole/src/main.c b/flagpole/src/main.c index 6694ea1..4571b97 100644 --- a/flagpole/src/main.c +++ b/flagpole/src/main.c @@ -4,6 +4,7 @@ #define LAZY_IMPL #include "lazy.h" #include "token.h" +#include "var.h" bool is_int_literal(Lz_SB *sb) { for (int i = 0; i < sb->cnt; ++i) { @@ -74,6 +75,7 @@ static inline bool isKW(Lz_SB *sb) { || SBeq(sb, "ld8") || SBeq(sb, "st8") || SBeq(sb, "dup") + || SBeq(sb, "swap") || SBeq(sb, "while") || SBeq(sb, "do") || SBeq(sb, "endwhile") @@ -120,6 +122,9 @@ int main(uint argc, char **argv) { bool isProc = false; bool isInclude = false; Lz_DA(int) labelStack = {0}; + uint64_t allocHead = 0x7000000000000000; + char funcName[128]; + Lz_DA(Variable) vars; char newchar; printf("include 'fvm.inc'\n"); printf("define STACK_START 0x6000000000000000\n"); @@ -197,6 +202,7 @@ codegen: if (SBeq(&tokenAccumulator, "endproc")) { printf(" Ret\n"); printf("\n\n"); + funcName[0] = 0; break; } if (SBeq(&tokenAccumulator, "ld8")) { @@ -217,6 +223,13 @@ codegen: printf(" pushstack 106\n"); break; } + if (SBeq(&tokenAccumulator, "swap")) { + printf(" popstack 118\n"); + printf(" popstack 119\n"); + printf(" pushstack 118\n"); + printf(" pushstack 119\n"); + break; + } if (SBeq(&tokenAccumulator, "while")) { lz_da_append(labelStack, counter); printf("__whilehead_%d:\n", counter); @@ -289,6 +302,13 @@ codegen: printf("__fp_user_"LZ_STR_FMT":\n", LZ_STR_PRINTF(tokenAccumulator)); isProc = false; + if (tokenAccumulator.cnt < 127) { + memcpy(funcName, tokenAccumulator.data, tokenAccumulator.cnt); + funcName[tokenAccumulator.cnt] = 0; + } else { + memcpy(funcName, tokenAccumulator.data, 127); + funcName[127] = 0; + } break; } if (tokenAccumulator.data[0] == ':') { @@ -297,6 +317,65 @@ codegen: tokenAccumulator.data+1); break; } + if (tokenAccumulator.data[0] == '@') { + char varName[128]; + if (tokenAccumulator.cnt < 128) { + memcpy(varName, tokenAccumulator.data+1, + tokenAccumulator.cnt-1); + varName[tokenAccumulator.cnt] = 0; + } else { + memcpy(varName, tokenAccumulator.data+1, 127); + varName[127] = 0; + } + uint64_t addr = 0; + lz_da_foreach(Variable, v, vars) { + if (!strcmp(v->name, varName) && !strcmp(v->func, funcName)) { + addr = v->addr; + break; + } + } + if (addr == 0) { + addr = allocHead; + Variable v = (Variable) { + .addr = addr + }; + memcpy(&v.func, funcName, 128); + memcpy(&v.name, varName, 128); + lz_da_append(vars, v); + allocHead += 8; + } + printf(" popstack 120\n"); + printf(" MovI64 121, 0x%16lX\n", addr); + printf(" St64 120, 121\n"); + break; + } + if (tokenAccumulator.data[0] == '&') { + char varName[128]; + if (tokenAccumulator.cnt < 128) { + memcpy(varName, tokenAccumulator.data+1, + tokenAccumulator.cnt-1); + varName[tokenAccumulator.cnt] = 0; + } else { + memcpy(varName, tokenAccumulator.data+1, 127); + varName[127] = 0; + } + uint64_t addr = 0; + lz_da_foreach(Variable, v, vars) { + if (!strcmp(v->name, varName) && !strcmp(v->func, funcName)) { + addr = v->addr; + break; + } + } + if (addr == 0) { + fprintf(stderr, "Undeclared variable %s in function %s", + varName, funcName); + exit(1); + } + printf(" MovI64 121, 0x%16lX\n", addr); + printf(" Ld64 120, 121\n"); + printf(" pushstack 120\n"); + 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/src/var.h b/flagpole/src/var.h new file mode 100644 index 0000000..0183cec --- /dev/null +++ b/flagpole/src/var.h @@ -0,0 +1,5 @@ +typedef struct { + char func[128]; + char name[128]; + uint64_t addr; +} Variable; diff --git a/flagpole/tests/vars.fp b/flagpole/tests/vars.fp new file mode 100644 index 0000000..862453b --- /dev/null +++ b/flagpole/tests/vars.fp @@ -0,0 +1,14 @@ +$inc fvmstd.fp + +proc main + 2 @a + 3 @b + + &a 48 u+ @a + &b 48 u+ @b + + &a :putchar + :newline + &b :putchar + :newline +endproc