diff options
| author | Elis Eriksson <spelis@spelis.li> | 2026-06-19 21:39:16 +0200 |
|---|---|---|
| committer | Elis Eriksson <spelis@spelis.li> | 2026-06-19 21:39:16 +0200 |
| commit | cbdca328495a772716f14b1e95a7ab7d6450cc27 (patch) | |
| tree | 54b5c37a9a2d1b14e385e047980d7df99a56c331 | |
| parent | 7ccae1c362a45b28f4fbf96da4f479730e4b382b (diff) | |
| download | bfc-cbdca328495a772716f14b1e95a7ab7d6450cc27.tar bfc-cbdca328495a772716f14b1e95a7ab7d6450cc27.tar.gz bfc-cbdca328495a772716f14b1e95a7ab7d6450cc27.tar.bz2 bfc-cbdca328495a772716f14b1e95a7ab7d6450cc27.tar.lz bfc-cbdca328495a772716f14b1e95a7ab7d6450cc27.tar.xz bfc-cbdca328495a772716f14b1e95a7ab7d6450cc27.tar.zst bfc-cbdca328495a772716f14b1e95a7ab7d6450cc27.zip | |
Improve the shit
No longer turing complete
No longer depends on libc (good thing)
Codegen is now unreadable (because i want it to be)
Remove a couple of unnecessary includes
Output C code to out.c when compiling
Why the fuck are you reading this?
| -rwxr-xr-x | bfc.sh | 5 | ||||
| -rw-r--r-- | src/bfc.c | 14 | ||||
| -rw-r--r-- | src/codegen.c | 125 | ||||
| -rw-r--r-- | src/lexer.c | 10 | ||||
| -rw-r--r-- | src/parser.c | 3 |
5 files changed, 31 insertions, 126 deletions
@@ -21,4 +21,7 @@ fi # compile pipeline OUT=$(cat "$SRC" | "$BFC") -echo "$OUT" | gcc -o ./bf.out -x c - +LDFLAGS="-Os -march=native -mtune=native -flto -fuse-linker-plugin -DNDEBUG -fomit-frame-pointer -nostdlib -nostartfiles -no-pie -fno-stack-protector" + +echo "$OUT" > out.c +echo "$OUT" | gcc $LDFLAGS -o ./bf.out -x c - @@ -1,30 +1,16 @@ #include "all.h" #include "str.h" -#include <stddef.h> -#include <stdint.h> -#include <stdio.h> -#include <stdlib.h> int main(void) { str input = {0}; str_append_fread(&input, stdin); - lexer_t lexer = lex_init(&input); lex_run(&lexer); - parser_t p = parser_init(&lexer); - ast_node_t *ast = parse_program(&p); - - // lex_free(&lexer); - // parser_free(&p); - str c_code = gen_code(ast); - ast_free(ast); - printf("%s", c_code.data); - free_str(&input); return 0; } diff --git a/src/codegen.c b/src/codegen.c index e4972db..a019af6 100644 --- a/src/codegen.c +++ b/src/codegen.c @@ -1,133 +1,65 @@ #include "all.h" -#include "str.h" -static void emit_includes(str *out) { - str_append(out, "#include <stdio.h>\n"); - str_append(out, "#include <stdlib.h>\n"); - str_append(out, "#include <string.h>\n\n"); +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 struct {\n" - " unsigned char *data;\n" - " size_t size;\n" - "} tape_t;\n\n" - - "static void tape_init(tape_t *t, size_t initial) {\n" - " t->data = calloc(initial, 1);\n" - " t->size = initial;\n" - "}\n\n" - - "static void tape_grow_right(tape_t *t, size_t needed) {\n" - " size_t new_size = t->size;\n" - " while (new_size <= needed) new_size *= 2;\n" - " unsigned char *new_data = calloc(new_size, 1);\n" - " memcpy(new_data, t->data, t->size);\n" - " free(t->data);\n" - " t->data = new_data;\n" - " t->size = new_size;\n" - "}\n\n" - - "static void tape_grow_left(tape_t *t, size_t add, size_t *ptr) {\n" - " size_t new_size = t->size + add;\n" - " unsigned char *new_data = calloc(new_size, 1);\n" - " memcpy(new_data + add, t->data, t->size);\n" - " free(t->data);\n" - " t->data = new_data;\n" - " t->size = new_size;\n" - " *ptr += add;\n" - "}\n\n" + str_append(out, "typedef unsigned long size_t;" + "typedef unsigned char uint8_t;"); - "static void tape_move_right(tape_t *t, size_t *ptr, size_t amount) {\n" - " *ptr += amount;\n" - " if (*ptr >= t->size)\n" - " tape_grow_right(t, *ptr);\n" - "}\n\n" - - "static void tape_move_left(tape_t *t, size_t *ptr, size_t amount) {\n" - " if (amount > *ptr) {\n" - " size_t need = amount - *ptr;\n" - " size_t add = t->size;\n" - " while (add <= need)\n" - " add *= 2;\n" - " tape_grow_left(t, add, ptr);\n" - " }\n" - " *ptr -= amount;\n" - "}\n\n"); + 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_prelude(str *out) { - str_append(out, "int main(void)\n" - "{\n" - " tape_t tape;\n" - " tape_init(&tape, 32);\n" - " size_t ptr = tape.size / 2;\n\n"); -} - -static void emit_epilogue(str *out) { - str_append(out, " free(tape.data);\n" - " return 0;\n" - "}\n"); -} - -static void emit_indent(str *out, int indent) { - for (int i = 0; i < indent; i++) - str_append(out, " "); -} +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: - emit_indent(out, indent); - str_append(out, "tape.data[ptr] += "); - str_appendf(out, "%d;\n", node->val); + str_appendf(out, "*ptr+=%d;", node->val); break; case AST_DEC: - emit_indent(out, indent); - str_append(out, "tape.data[ptr] -= "); - str_appendf(out, "%d;\n", node->val); + str_appendf(out, "*ptr-=%d;", node->val); break; case AST_PTR_INC: - emit_indent(out, indent); - str_append(out, "tape_move_right(&tape, &ptr, "); - str_appendf(out, "%d", node->val); - str_append(out, ");\n"); + str_appendf(out, "ptr+=%d;", node->val); break; case AST_PTR_DEC: - emit_indent(out, indent); - str_append(out, "tape_move_left(&tape, &ptr, "); - str_appendf(out, "%d", node->val); - str_append(out, ");\n"); + str_appendf(out, "ptr-=%d;", node->val); break; case AST_OUT: - emit_indent(out, indent); - str_append(out, "putchar((int)tape.data[ptr]);\n"); + str_appendf(out, "syscall3(1,1,ptr,1);"); break; case AST_IN: - emit_indent(out, indent); - str_append(out, - "{ int ch = getchar();\n" - " tape.data[ptr] = (ch == EOF) ? 0 : (unsigned char)ch; }\n"); + str_appendf(out, "syscall3(0,0,ptr,1);"); break; case AST_LOOP: - emit_indent(out, indent); - str_append(out, "while (tape.data[ptr]) {\n"); + str_append(out, "while(*ptr){"); - for (int i = 0; i < node->children.len; i++) { + for (size_t i = 0; i < node->children.len; i++) { emit_node(out, node->children._data[i], indent + 1); } - emit_indent(out, indent); - str_append(out, "}\n"); + str_append(out, "}"); break; } } @@ -136,12 +68,9 @@ void emit_node(str *out, ast_node_t *node, int indent) { str gen_code(ast_node_t *ast) { str out = {0}; - emit_includes(&out); emit_runtime(&out); emit_prelude(&out); - emit_node(&out, ast, 1); - emit_epilogue(&out); return out; diff --git a/src/lexer.c b/src/lexer.c index 4f1fcd0..b4d11eb 100644 --- a/src/lexer.c +++ b/src/lexer.c @@ -1,9 +1,6 @@ #include "all.h" #include "ivec.h" -#include <stdint.h> -#include <stdio.h> #include <stdlib.h> -#include <string.h> lexer_t lex_init(str *src) { lexer_t lx = {0}; @@ -17,10 +14,8 @@ lexer_t lex_init(str *src) { void lex_run(lexer_t *lx) { for (size_t i = 0; i < lx->src->length; i++) { - char c = lx->src->data[i]; lex_tok_e tok; - switch (c) { case '+': tok = LEX_PINC; @@ -49,24 +44,19 @@ void lex_run(lexer_t *lx) { default: continue; } - iv_push(&lx->tokens, tok); } - iv_push(&lx->tokens, LEX_EOF); } void lex_free(lexer_t *lx) { if (!lx) return; - iv_free(&lx->tokens); - if (lx->src) { free(lx->src->data); free(lx->src); } - lx->src = NULL; lx->pos = 0; } diff --git a/src/parser.c b/src/parser.c index 855b94e..b89f07d 100644 --- a/src/parser.c +++ b/src/parser.c @@ -1,7 +1,4 @@ #include "all.h" -#include "ivec.h" -#include "node_vec.h" -#include <stdint.h> #include <stdlib.h> static inline lex_tok_e peek(parser_t *p) { |
