aboutsummaryrefslogtreecommitdiff
path: root/src/bfc.c
diff options
context:
space:
mode:
authorElis Eriksson <spelis@spelis.li>2026-06-20 20:12:29 +0200
committerElis Eriksson <spelis@spelis.li>2026-06-20 20:12:29 +0200
commit38942c34a497a4c6edf080dc64440c1bc486fc46 (patch)
tree8fd3c891dff03f649b21aeb02c594e3e50f3160c /src/bfc.c
parentde91ec0542aea5959376ee0d2c9d486268dd9392 (diff)
downloadbfc-38942c34a497a4c6edf080dc64440c1bc486fc46.tar
bfc-38942c34a497a4c6edf080dc64440c1bc486fc46.tar.gz
bfc-38942c34a497a4c6edf080dc64440c1bc486fc46.tar.bz2
bfc-38942c34a497a4c6edf080dc64440c1bc486fc46.tar.lz
bfc-38942c34a497a4c6edf080dc64440c1bc486fc46.tar.xz
bfc-38942c34a497a4c6edf080dc64440c1bc486fc46.tar.zst
bfc-38942c34a497a4c6edf080dc64440c1bc486fc46.zip
Pattern matching optimizer and more
it's not the best optimizer but it works. Also added a -ast_dump flag which dumps the AST to stderr. Also input is now done in raw mode just because it can be.
Diffstat (limited to 'src/bfc.c')
-rw-r--r--src/bfc.c61
1 files changed, 51 insertions, 10 deletions
diff --git a/src/bfc.c b/src/bfc.c
index fc7d29d..8ef8d3d 100644
--- a/src/bfc.c
+++ b/src/bfc.c
@@ -1,12 +1,25 @@
#include "all.h"
#include "str.h"
+#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
-int main(void) {
+int main(int argc, char *argv[]) {
+ bool dump_c = false;
+ bool dump_ast = false;
+
+ for (int i = 1; i < argc; i++) {
+ if (strcmp("-cdump", argv[i]) == 0) {
+ dump_c = true;
+ }
+ if (strcmp("-ast_dump", argv[i]) == 0) {
+ dump_ast = true;
+ }
+ }
+
str input = {0};
str_append_fread(&input, stdin);
@@ -18,8 +31,14 @@ int main(void) {
// Run the parser and turn tokens into an AST representation
parser_t p = parser_init(&lexer);
ast_node_t *ast = parse_program(&p);
+ ast = optimize_ast(ast);
+ if (dump_ast)
+ ast_dump(ast, 0);
str c_code = gen_code(ast);
+ if (dump_c)
+ fprintf(stderr, "%s\n", c_code.data);
+
// Run gcc
int fd[2];
pipe(fd);
@@ -29,14 +48,23 @@ int main(void) {
close(fd[0]);
close(fd[1]);
- char *argv[] = {"gcc", "-Os",
- "-flto", "-fuse-linker-plugin",
- "-DNDEBUG", "-fomit-frame-pointer",
- "-nostdlib", "-nostartfiles",
- "-no-pie", "-fno-stack-protector",
- "-o", "/proc/self/fd/1",
- "-x", "c",
- "-", NULL};
+ char *argv[] = {"gcc",
+ "-Os",
+ "-flto",
+ "-fuse-linker-plugin",
+ "-DNDEBUG",
+ "-fomit-frame-pointer",
+ "-nostdlib",
+ "-nostartfiles",
+ "-ffreestanding",
+ "-no-pie",
+ "-fno-stack-protector",
+ "-o",
+ "/proc/self/fd/1",
+ "-x",
+ "c",
+ "-",
+ NULL};
execvp("gcc", argv);
perror("execvp");
@@ -47,7 +75,20 @@ int main(void) {
close(fd[0]);
write(fd[1], c_code.data, strlen(c_code.data));
close(fd[1]);
- wait(NULL);
+ int status;
+ wait(&status);
+
+ if (WIFEXITED(status)) {
+ int code = WEXITSTATUS(status);
+ if (code != 0) {
+ fprintf(stderr, "GCC failed with exit code %d\n", code);
+ fprintf(stderr, "Dumping C code:\n%s\n", c_code.data);
+ }
+ } else if (WIFSIGNALED(status)) {
+ fprintf(stderr, "GCC killed by signal %d\n", WTERMSIG(status));
+ } else {
+ fprintf(stderr, "GCC died in an unknown and mysterious way\n");
+ }
ast_free(ast);
free_str(&input);