aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorElis Eriksson <spelis@spelis.li>2026-06-19 21:39:16 +0200
committerElis Eriksson <spelis@spelis.li>2026-06-19 21:39:16 +0200
commitcbdca328495a772716f14b1e95a7ab7d6450cc27 (patch)
tree54b5c37a9a2d1b14e385e047980d7df99a56c331
parent7ccae1c362a45b28f4fbf96da4f479730e4b382b (diff)
downloadbfc-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-xbfc.sh5
-rw-r--r--src/bfc.c14
-rw-r--r--src/codegen.c125
-rw-r--r--src/lexer.c10
-rw-r--r--src/parser.c3
5 files changed, 31 insertions, 126 deletions
diff --git a/bfc.sh b/bfc.sh
index 4bc87c1..49c1370 100755
--- a/bfc.sh
+++ b/bfc.sh
@@ -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 -
diff --git a/src/bfc.c b/src/bfc.c
index 2e369cf..d567f88 100644
--- a/src/bfc.c
+++ b/src/bfc.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) {