Geen omschrijving

bf.dasc 1.6KB

    #include <stdint.h> |.arch x64 |.actionlist actions | | // rbx is the pointer to the current cell | // (and it's preserved across calls to functions) | .define PTR, rbx | | // macro for calling a function. |.macro callp, addr | mov64 rax, (uintptr_t)addr | call rax |.endmacro #define Dst &state #define MAX_NESTING 256 void error(const char *msg) { fprintf(stderr, "%s\n", msg); exit(1); } int main(int argc, char *argv[]) { if (argc < 2) { error("Usage: bf <program>"); } dasm_State *state; initjit(&state, actions); unsigned int maxpc = 0; int pcstack[MAX_NESTING]; int *top = pcstack, *limit = pcstack + MAX_NESTING; // function prologue | push PTR | mov PTR, rdi for (char *p = argv[1]; *p; p++) { switch (*p) { case '>': | inc PTR break; case '<': | dec PTR break; case '+': | inc byte [PTR] break; case '-': | dec byte [PTR] break; case '.': | movzx edi, byte [PTR] | callp putchar break; case ',': | callp getchar | mov byte [PTR], al break; case '[': if (top == limit) { error("Nesting too deep."); } maxpc += 2; *top++ = maxpc; dasm_growpc(&state, maxpc); | cmp byte [PTR], 0 | je =>(maxpc-2) |=>(maxpc-1): break; case ']': if (top == pcstack) { error("Unmatched ']'"); } top--; | cmp byte [PTR], 0 | jne =>(*top-1) |=>(*top-2): break; } } // function epilogue | pop PTR | ret void (*bf_program)(char*) = jitcode(&state); char *mem = calloc(30000, 1); bf_program(mem); free(mem); free_jitcode(bf_program); return 0; }