#include #include #include #define LAZY_IMPL #include "lazy.h" #include "token.h" #include "var.h" #include "ir.h" bool is_int_literal(Lz_SB *sb) { for (int i = 0; i < sb->cnt; ++i) { char c = sb->data[i]; if (!(isdigit(c) || (i == 0 && c == '-'))) { return false; } } return true; } bool is_float_literal(Lz_SB *sb) { for (int i = 0; i < sb->cnt-1; ++i) { char c = sb->data[i]; if (!(isdigit(c) || (i == 0 && c == '-') || c == '.')) { return false; } } return sb->data[sb->cnt-1] == 'f'; } bool is_double_literal(Lz_SB *sb) { for (int i = 0; i < sb->cnt; ++i) { char c = sb->data[i]; if (!(isdigit(c) || (i == 0 && c == '-') || c == '.')) { return false; } } return true; } bool is_hex_literal(Lz_SB *sb) { if (sb->data[0] != '0' || sb->data[1] != 'x') { return false; } for (int i = 2; i < sb->cnt; ++i) { char c = sb->data[i]; if (c >= '0' && c <= '9') continue; if (c >= 'a' && c <= 'f') continue; if (c >= 'A' && c <= 'F') continue; return false; } return true; } bool is_bin_literal(Lz_SB *sb) { if (sb->data[0] != '0' || sb->data[1] != 'b') { return false; } for (int i = 2; i < sb->cnt; ++i) { char c = sb->data[i]; if (c == '0' && c == '1') continue; return false; } return true; } bool SBeq(Lz_SB *sb, const char *cstr) { size_t l = strlen(cstr); if (l != sb->cnt) return false; return !memcmp(sb->data, cstr, l); } void commentStack(void *stack) { typedef Lz_DA(int) intstack; intstack *s = stack; printf(" ; Stack:"); lz_da_foreach(int, x, *s) { printf(" %d", *x); } printf("\n"); } static inline uint64_t lz_sb_readhex(Lz_SB *sb) { Lz_SB clone = *sb; clone.data += 2; clone.cnt -= 2; uint64_t val = 0; lz_da_foreach(char, c, clone) { val *= 0x10; if (*c >= '0' && *c <= '9') { val += *c - '0'; } else if (*c >= 'A' && *c <= 'F') { val += *c - 'A' + 10; } else if (*c >= 'a' && *c <= 'f') { val += *c - 'a' + 10; } } return val; } static inline bool isKW(Lz_SB *sb) { return SBeq(sb, "proc") || SBeq(sb, "endproc") || SBeq(sb, "return") || SBeq(sb, "ld8") || SBeq(sb, "st8") || SBeq(sb, "dup") || SBeq(sb, "swap") || SBeq(sb, "drop") || SBeq(sb, "while") || SBeq(sb, "do") || SBeq(sb, "if") || SBeq(sb, "then") || SBeq(sb, "endif") || SBeq(sb, "endwhile") || SBeq(sb, "break") || SBeq(sb, "continue") || SBeq(sb, "==") || SBeq(sb, "not") || SBeq(sb, "bor") || SBeq(sb, "band") || SBeq(sb, "u+") || SBeq(sb, "u-") || SBeq(sb, "u*") || SBeq(sb, "u/") || SBeq(sb, "u%") || SBeq(sb, "u>") || SBeq(sb, "u<") || SBeq(sb, "i+") || SBeq(sb, "i-") || SBeq(sb, "i*") || SBeq(sb, "i/") || SBeq(sb, "i%") || SBeq(sb, "i>") || SBeq(sb, "i<") || SBeq(sb, "pop") || SBeq(sb, "$inc") ; } #define IR_GET_2_ARGS \ IRValue x1, x2; \ if (irVStack.cnt >= 2) { \ x1 = lz_da_pop(irVStack); \ x2 = lz_da_pop(irVStack); \ } else if (irVStack.cnt == 1) { \ x1 = lz_da_pop(irVStack); \ x2 = (IRValue) { \ .typ = IRVAL_STACK, \ .val = ++vstackUnderflows \ }; \ } else if (irVStack.cnt == 0) { \ x1 = (IRValue) { \ .typ = IRVAL_STACK, \ .val = ++vstackUnderflows \ }; \ x2 = (IRValue) { \ .typ = IRVAL_STACK, \ .val = ++vstackUnderflows \ }; \ } typedef enum { LABEL_WHILE, LABEL_IF, } LabelKind; typedef struct { LabelKind typ; int num; } AsmLabel; int main(uint argc, char **argv) { int opt; Lz_DA(FILE *) inpfiles = {}; while ((opt = getopt(argc, argv, "f:")) != -1) { switch(opt) { case 'f': { FILE *inpfile = fopen(optarg, "r"); if (!inpfile) { printf("Failed to open file %s\n", optarg); exit(1); } lz_da_append(inpfiles, inpfile); break; } default: break; } } if (inpfiles.cnt == 0) { printf("No file requested\n"); exit(1); } FILE *currFile = lz_da_pop(inpfiles); TokenKind currTokenKind; Lz_SB tokenAccumulator = {0}; int counter = 0; bool isQuote = false; bool isProc = false; bool isInclude = false; bool isComment = false; Lz_DA(AsmLabel) labelStack = {0}; uint64_t allocHead = 0x7000000000000000; char funcName[128]; Lz_DA(Variable) vars = {0}; char newchar; Lz_DA(IRStatement) irStatements = {0}; Lz_DA(IRValue) irVStack = {0}; int irVCount = 0; int vstackUnderflows = 0; printf("include 'fvm.inc'\n"); printf("define STACK_START 0x6000000000000000\n"); printf("define STACK_SP 125\n"); printf("define STACK_INC 126\n"); printf("org 0x4000000000000000\n"); printf(" MovI64 STACK_SP, STACK_START\n"); printf(" MovI64 STACK_INC, 8\n"); printf(" Call __fp_user_main\n"); printf(" Halt\n"); printf("macro pushstack reg\n"); printf(" SubR64 STACK_SP, STACK_INC\n"); printf(" St64 reg, STACK_SP\n"); printf("end macro\n\n"); printf("macro popstack reg\n"); printf(" Ld64 reg, STACK_SP\n"); printf(" AddR64 STACK_SP, STACK_INC\n"); printf("end macro\n\n"); // Genuinely idk why goto is possessing me today compileStart: while ((newchar = fgetc(currFile)) != EOF) { ++counter; if (isComment && newchar == '\n') isComment = false; if (!isComment && newchar == '#') isComment = true; if (isComment) continue; if (isspace(newchar) && !isQuote) { if (tokenAccumulator.cnt == 0) continue; if (is_int_literal(&tokenAccumulator)) { currTokenKind = TOKEN_INTLIT; goto codegenIR; } else if (is_float_literal(&tokenAccumulator)) { currTokenKind = TOKEN_FLOATLIT; goto codegenIR; } else if (is_double_literal(&tokenAccumulator)) { currTokenKind = TOKEN_DOUBLELIT; goto codegenIR; } else if (is_hex_literal(&tokenAccumulator)) { currTokenKind = TOKEN_HEXLIT; goto codegenIR; } else if (is_bin_literal(&tokenAccumulator)) { currTokenKind = TOKEN_BINLIT; goto codegenIR; } else { currTokenKind = TOKEN_IDENTIFIER; if (isKW(&tokenAccumulator)) { currTokenKind = TOKEN_KEYWORD; } goto codegenIR; } } if (newchar == '"') { if (isQuote) { currTokenKind = TOKEN_STRINGLIT; isQuote = false; goto codegenIR; } else { if (tokenAccumulator.cnt != 0) { fprintf(stderr, "error %d\n", __LINE__); exit(1); } else { isQuote = true; } continue; } } lz_da_append(tokenAccumulator, newchar); continue; // Names suck but this also generates some asm for blocks codegenIR: //printf("I must gen code i am now Amista Azozin\n"); //fprintf(stderr,"Token type: %d\n", currTokenKind); //fprintf(stderr,"Tok: "LZ_STR_FMT"\n", LZ_STR_PRINTF(tokenAccumulator)); printf(" ; "LZ_STR_FMT"\n", LZ_STR_PRINTF(tokenAccumulator)); switch (currTokenKind) { case TOKEN_KEYWORD: { if (SBeq(&tokenAccumulator, "proc")) { isProc = true; break; } if (SBeq(&tokenAccumulator, "endproc")) { IRComplete(&irStatements, &irVStack); vstackUnderflows = 0; printf(" Ret\n"); printf("\n\n"); if (labelStack.cnt != 0) { fprintf(stderr, "Unmatched statement in function %s\n", funcName); exit(1); } funcName[0] = 0; break; } if (SBeq(&tokenAccumulator, "return")) { IRComplete(&irStatements, &irVStack); vstackUnderflows = 0; printf(" Ret\n"); break; } if (SBeq(&tokenAccumulator, "ld8")) { IRValue x1; if (irVStack.cnt >= 1) { x1 = lz_da_pop(irVStack); } else if (irVStack.cnt == 0) { x1 = (IRValue) { .typ = IRVAL_STACK, .val = 1 }; } IRValue dstReg = (IRValue) { .typ = IRVAL_VIRTUAL, .val = ++irVCount }; IRStatement s = (IRStatement) { .dst = dstReg, .op = IR_LD8, .arg1 = x1 }; lz_da_append(irVStack, dstReg); lz_da_append(irStatements, s); break; } if (SBeq(&tokenAccumulator, "st8")) { IR_GET_2_ARGS IRValue dstReg = (IRValue) { .typ = IRVAL_CONSTANT, }; IRStatement s = (IRStatement) { .dst = dstReg, .op = IR_ST8, .arg1 = x1, .arg2 = x2 }; lz_da_append(irStatements, s); break; } if (SBeq(&tokenAccumulator, "dup")) { if (irVStack.cnt != 0) { IRValue v = lz_da_pop(irVStack); lz_da_append(irVStack, v); lz_da_append(irVStack, v); } else { printf(" popstack 106\n"); printf(" pushstack 106\n"); printf(" pushstack 106\n"); } break; } if (SBeq(&tokenAccumulator, "swap")) { IRValue x1, x2; if (irVStack.cnt >= 2) { x1 = lz_da_pop(irVStack); x2 = lz_da_pop(irVStack); } else if (irVStack.cnt == 1) { x1 = lz_da_pop(irVStack); x2 = (IRValue) { .typ = IRVAL_STACK, .val = ++vstackUnderflows }; } else if (irVStack.cnt == 0) { x1 = (IRValue) { .typ = IRVAL_STACK, .val = ++vstackUnderflows }; x2 = (IRValue) { .typ = IRVAL_STACK, .val = ++vstackUnderflows }; } lz_da_append(irVStack, x1); lz_da_append(irVStack, x2); break; } if (SBeq(&tokenAccumulator, "drop")) { if (irVStack.cnt != 0) lz_da_pop(irVStack); else printf(" popstack 118\n"); break; } if (SBeq(&tokenAccumulator, "while")) { IRComplete(&irStatements, &irVStack); AsmLabel lbl = (AsmLabel) { .num = counter, .typ = LABEL_WHILE }; lz_da_append(labelStack, lbl); commentStack(&labelStack); printf("__whilehead_%d:\n", lbl.num); break; } if (SBeq(&tokenAccumulator, "do")) { IRComplete(&irStatements, &irVStack); vstackUnderflows = 0; 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); // TODO: Change flag setting to IR's job printf(" popstack 108\n"); printf(" RSetF 108\n"); printf(" JmpIE __whiletail_%d\n", lbl.num); break; } if (SBeq(&tokenAccumulator, "endwhile")) { IRComplete(&irStatements, &irVStack); vstackUnderflows = 0; AsmLabel lbl = lz_da_pop(labelStack); if (lbl.typ != LABEL_WHILE) { fprintf(stderr, "Unmatched endwhile without while\n"); exit(1); } commentStack(&labelStack); printf(" Jmp __whilehead_%d\n", lbl.num); 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; } if (SBeq(&tokenAccumulator, "if")) { break; } if (SBeq(&tokenAccumulator, "then")) { IRComplete(&irStatements, &irVStack); AsmLabel lbl = (AsmLabel) { .num = counter, .typ = LABEL_IF }; lz_da_append(labelStack, lbl); commentStack(&labelStack); vstackUnderflows = 0; printf(" popstack 123\n"); printf(" RSetF 123\n"); printf(" JmpIE __iftail_%d\n", lbl.num); break; } if (SBeq(&tokenAccumulator, "endif")) { IRComplete(&irStatements, &irVStack); vstackUnderflows = 0; commentStack(&labelStack); AsmLabel lbl = lz_da_pop(labelStack); if (lbl.typ != LABEL_IF) { fprintf(stderr, "Unmatched endif without an if\n"); exit(1); } printf("__iftail_%d:\n", lbl.num); break; } if (SBeq(&tokenAccumulator, "==")) { IR_GET_2_ARGS IRValue dstReg = (IRValue) { .typ = IRVAL_VIRTUAL, .val = ++irVCount }; IRStatement s = (IRStatement) { .dst = dstReg, .op = IR_EQ, .arg1 = x1, .arg2 = x2 }; lz_da_append(irVStack, dstReg); lz_da_append(irStatements, s); break; } if (SBeq(&tokenAccumulator, "not")) { IRValue x1; if (irVStack.cnt >= 1) { x1 = lz_da_pop(irVStack); } else if (irVStack.cnt == 0) { x1 = (IRValue) { .typ = IRVAL_STACK, .val = ++vstackUnderflows }; } IRValue dstReg = (IRValue) { .typ = IRVAL_VIRTUAL, .val = ++irVCount }; IRStatement s = (IRStatement) { .dst = dstReg, .op = IR_NOT, .arg1 = x1 }; lz_da_append(irVStack, dstReg); lz_da_append(irStatements, s); break; } if (SBeq(&tokenAccumulator, "band")) { IR_GET_2_ARGS IRValue dstReg = (IRValue) { .typ = IRVAL_VIRTUAL, .val = ++irVCount }; IRStatement s = (IRStatement) { .dst = dstReg, .op = IR_AND, .arg1 = x1, .arg2 = x2 }; lz_da_append(irVStack, dstReg); lz_da_append(irStatements, s); break; } if (SBeq(&tokenAccumulator, "bor")) { IR_GET_2_ARGS IRValue dstReg = (IRValue) { .typ = IRVAL_VIRTUAL, .val = ++irVCount }; IRStatement s = (IRStatement) { .dst = dstReg, .op = IR_OR, .arg1 = x1, .arg2 = x2 }; lz_da_append(irVStack, dstReg); lz_da_append(irStatements, s); break; } if (SBeq(&tokenAccumulator, "xor")) { IR_GET_2_ARGS IRValue dstReg = (IRValue) { .typ = IRVAL_VIRTUAL, .val = ++irVCount }; IRStatement s = (IRStatement) { .dst = dstReg, .op = IR_XOR, .arg1 = x1, .arg2 = x2 }; lz_da_append(irVStack, dstReg); lz_da_append(irStatements, s); break; } if (SBeq(&tokenAccumulator, "u+")) { IR_GET_2_ARGS IRValue dstReg = (IRValue) { .typ = IRVAL_VIRTUAL, .val = ++irVCount }; IRStatement s = (IRStatement) { .dst = dstReg, .op = IR_UADD, .arg1 = x1, .arg2 = x2 }; lz_da_append(irVStack, dstReg); lz_da_append(irStatements, s); break; } if (SBeq(&tokenAccumulator, "u-")) { IR_GET_2_ARGS IRValue dstReg = (IRValue) { .typ = IRVAL_VIRTUAL, .val = ++irVCount }; IRStatement s = (IRStatement) { .dst = dstReg, .op = IR_USUB, .arg1 = x1, .arg2 = x2 }; lz_da_append(irVStack, dstReg); lz_da_append(irStatements, s); break; } if (SBeq(&tokenAccumulator, "u*")) { IR_GET_2_ARGS IRValue dstReg = (IRValue) { .typ = IRVAL_VIRTUAL, .val = ++irVCount }; IRStatement s = (IRStatement) { .dst = dstReg, .op = IR_UMUL, .arg1 = x1, .arg2 = x2 }; lz_da_append(irVStack, dstReg); lz_da_append(irStatements, s); break; } if (SBeq(&tokenAccumulator, "u/")) { IR_GET_2_ARGS IRValue dstReg = (IRValue) { .typ = IRVAL_VIRTUAL, .val = ++irVCount }; IRStatement s = (IRStatement) { .dst = dstReg, .op = IR_UDIV, .arg1 = x1, .arg2 = x2 }; lz_da_append(irVStack, dstReg); lz_da_append(irStatements, s); break; } if (SBeq(&tokenAccumulator, "u%")) { IR_GET_2_ARGS IRValue dstReg = (IRValue) { .typ = IRVAL_VIRTUAL, .val = ++irVCount }; IRStatement s = (IRStatement) { .dst = dstReg, .op = IR_UMOD, .arg1 = x1, .arg2 = x2 }; lz_da_append(irVStack, dstReg); lz_da_append(irStatements, s); break; } if (SBeq(&tokenAccumulator, "u>")) { IR_GET_2_ARGS IRValue dstReg = (IRValue) { .typ = IRVAL_VIRTUAL, .val = ++irVCount }; IRStatement s = (IRStatement) { .dst = dstReg, .op = IR_UGT, .arg1 = x1, .arg2 = x2 }; lz_da_append(irVStack, dstReg); lz_da_append(irStatements, s); break; } if (SBeq(&tokenAccumulator, "u<")) { IR_GET_2_ARGS IRValue dstReg = (IRValue) { .typ = IRVAL_VIRTUAL, .val = ++irVCount }; IRStatement s = (IRStatement) { .dst = dstReg, .op = IR_ULT, .arg1 = x1, .arg2 = x2 }; lz_da_append(irVStack, dstReg); lz_da_append(irStatements, s); break; } if (SBeq(&tokenAccumulator, "i+")) { IR_GET_2_ARGS IRValue dstReg = (IRValue) { .typ = IRVAL_VIRTUAL, .val = ++irVCount }; IRStatement s = (IRStatement) { .dst = dstReg, .op = IR_UADD, .arg1 = x1, .arg2 = x2 }; lz_da_append(irVStack, dstReg); lz_da_append(irStatements, s); break; } if (SBeq(&tokenAccumulator, "i-")) { IR_GET_2_ARGS IRValue dstReg = (IRValue) { .typ = IRVAL_VIRTUAL, .val = ++irVCount }; IRStatement s = (IRStatement) { .dst = dstReg, .op = IR_USUB, .arg1 = x1, .arg2 = x2 }; lz_da_append(irVStack, dstReg); lz_da_append(irStatements, s); break; } if (SBeq(&tokenAccumulator, "i*")) { IR_GET_2_ARGS IRValue dstReg = (IRValue) { .typ = IRVAL_VIRTUAL, .val = ++irVCount }; IRStatement s = (IRStatement) { .dst = dstReg, .op = IR_IMUL, .arg1 = x1, .arg2 = x2 }; lz_da_append(irVStack, dstReg); lz_da_append(irStatements, s); break; } if (SBeq(&tokenAccumulator, "i/")) { IR_GET_2_ARGS IRValue dstReg = (IRValue) { .typ = IRVAL_VIRTUAL, .val = ++irVCount }; IRStatement s = (IRStatement) { .dst = dstReg, .op = IR_IDIV, .arg1 = x1, .arg2 = x2 }; lz_da_append(irVStack, dstReg); lz_da_append(irStatements, s); break; } if (SBeq(&tokenAccumulator, "i%")) { IR_GET_2_ARGS IRValue dstReg = (IRValue) { .typ = IRVAL_VIRTUAL, .val = ++irVCount }; IRStatement s = (IRStatement) { .dst = dstReg, .op = IR_IMOD, .arg1 = x1, .arg2 = x2 }; lz_da_append(irVStack, dstReg); lz_da_append(irStatements, s); break; } if (SBeq(&tokenAccumulator, "i>")) { IR_GET_2_ARGS IRValue dstReg = (IRValue) { .typ = IRVAL_VIRTUAL, .val = ++irVCount }; IRStatement s = (IRStatement) { .dst = dstReg, .op = IR_IGT, .arg1 = x1, .arg2 = x2 }; lz_da_append(irVStack, dstReg); lz_da_append(irStatements, s); break; } if (SBeq(&tokenAccumulator, "i<")) { IR_GET_2_ARGS IRValue dstReg = (IRValue) { .typ = IRVAL_VIRTUAL, .val = ++irVCount }; IRStatement s = (IRStatement) { .dst = dstReg, .op = IR_ILT, .arg1 = x1, .arg2 = x2 }; lz_da_append(irVStack, dstReg); lz_da_append(irStatements, s); break; } if (SBeq(&tokenAccumulator, "$inc")) { isInclude = true; break; } printf("Unimplemented keyword: "LZ_STR_FMT"\n", LZ_STR_PRINTF(tokenAccumulator)); exit(1); } 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, "r"); if (!f) { fprintf(stderr, "Could not open file %s or doesn't exist\n", fname); } lz_da_append(inpfiles, f); isInclude = false; break; } if (isProc) { printf("__fp_user_"LZ_STR_FMT":\n", LZ_STR_PRINTF(tokenAccumulator)); isProc = false; IRValue arg = (IRValue) { .typ = IRVAL_ARG, .val = 0 }; 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] == ':') { IRComplete(&irStatements, &irVStack); vstackUnderflows = 0; printf(" Call __fp_user_"LZ_STR_FMT"\n", tokenAccumulator.cnt-1, 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-1] = 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; } IRValue x1; if (irVStack.cnt >= 1) { x1 = lz_da_pop(irVStack); } else if (irVStack.cnt == 0) { x1 = (IRValue) { .typ = IRVAL_STACK, .val = ++vstackUnderflows }; } IRValue dstReg = (IRValue) { .typ = IRVAL_MEMORY, .val = addr }; IRStatement s = (IRStatement) { .dst = dstReg, .op = IR_NOP, .arg1 = x1 }; lz_da_append(irStatements, s); break; } if (tokenAccumulator.data[0] == '&') { char varName[128]; if (tokenAccumulator.cnt < 128) { memcpy(varName, tokenAccumulator.data+1, tokenAccumulator.cnt-1); varName[tokenAccumulator.cnt-1] = 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\n", varName, funcName); exit(1); } IRValue dstReg = (IRValue) { .typ = IRVAL_VIRTUAL, .val = ++irVCount }; IRValue x1 = (IRValue) { .typ = IRVAL_MEMORY, .val = addr }; IRStatement s = (IRStatement) { .dst = dstReg, .op = IR_NOP, .arg1 = x1 }; lz_da_append(irStatements, s); lz_da_append(irVStack, dstReg); 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)); exit(0); } case TOKEN_INTLIT: { uint64_t x = lz_sb_atoll(&tokenAccumulator); IRValue v = (IRValue) { .typ = IRVAL_CONSTANT, .val = x }; lz_da_append(irVStack, v); break; } case TOKEN_HEXLIT: { uint64_t x = lz_sb_readhex(&tokenAccumulator); IRValue v = (IRValue) { .typ = IRVAL_CONSTANT, .val = x }; lz_da_append(irVStack, v); break; } case TOKEN_STRINGLIT: { IRValue dstReg = (IRValue) { .typ = IRVAL_VIRTUAL, .val = ++irVCount }; // This is a bad way of doing strings tbh printf(" Jmp endstring%d\n", counter); printf("string%d db \""LZ_STR_FMT"\", 0\n", counter, LZ_STR_PRINTF(tokenAccumulator)); printf("endstring%d:\n", counter); printf(" MovI64 100, string%d\n", counter); IRStatement s = (IRStatement) { .dst = dstReg, .op = IR_NOP, .arg1 = IR_STR }; lz_da_append(irVStack, dstReg); lz_da_append(irStatements, s); break; //IRComplete(&irStatements, &irVStack); //vstackUnderflows = 0; //printf(" Jmp endstring%d\n", counter); //printf("string%d db \""LZ_STR_FMT"\", 0\n", // counter, // LZ_STR_PRINTF(tokenAccumulator)); //printf("endstring%d:\n", counter); //printf(" MovI64 100, string%d\n", counter); //printf(" pushstack 100\n", counter); // IRValue v = (IRValue) { // .typ = IRVAL_STACK, // .val = 1 // }; // lz_da_append(irVStack, v); break; } default: { printf("Bad: %d\n", currTokenKind); exit(1); } } 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; } }