#include "all.h" static void emit_prelude(str *out) { str_append(out, "void _start(void){" "uint8_t tape[30000]={0};" "uint8_t*ptr=tape+15000;"); } static void emit_runtime(str *out) { str_append(out, "typedef unsigned long size_t;" "typedef unsigned char uint8_t;"); str_append(out, "static inline long syscall3(long n, long a1, void *a2, long a3){" "long ret;" "__asm__ volatile (" "\"syscall\"" ":\"=a\"(ret)" ":\"a\"(n),\"D\"(a1),\"S\"(a2),\"d\"(a3)" ":\"rcx\",\"r11\",\"memory\"" ");" "return ret;" "}"); } static void emit_epilogue(str *out) { str_append(out, "syscall3(60,0,0,0);}"); } void emit_node(str *out, ast_node_t *node, int indent) { for (; node; node = node->next) { switch (node->type) { case AST_INC: str_appendf(out, "*ptr+=%d;", node->val); break; case AST_DEC: str_appendf(out, "*ptr-=%d;", node->val); break; case AST_PTR_INC: str_appendf(out, "ptr+=%d;", node->val); break; case AST_PTR_DEC: str_appendf(out, "ptr-=%d;", node->val); break; case AST_OUT: str_appendf(out, "syscall3(1,1,ptr,1);"); break; case AST_IN: str_appendf(out, "syscall3(0,0,ptr,1);"); break; case AST_LOOP: str_append(out, "while(*ptr){"); for (size_t i = 0; i < node->children.len; i++) { emit_node(out, node->children._data[i], indent + 1); } str_append(out, "}"); break; } } } str gen_code(ast_node_t *ast) { str out = {0}; emit_runtime(&out); emit_prelude(&out); emit_node(&out, ast, 1); emit_epilogue(&out); return out; }