aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorElis Eriksson <spelis@spelis.li>2026-07-01 22:39:28 +0200
committerElis Eriksson <spelis@spelis.li>2026-07-01 22:43:49 +0200
commitb2a53020c9e19b6eb7c6b18afb940bdcf0b604cf (patch)
tree454deffc4365e9d17969d377f13231c06e0c4674
parent29766e048cabc8db71cb735c424e0fdfff468198 (diff)
downloadbfc-b2a53020c9e19b6eb7c6b18afb940bdcf0b604cf.tar
bfc-b2a53020c9e19b6eb7c6b18afb940bdcf0b604cf.tar.gz
bfc-b2a53020c9e19b6eb7c6b18afb940bdcf0b604cf.tar.bz2
bfc-b2a53020c9e19b6eb7c6b18afb940bdcf0b604cf.tar.lz
bfc-b2a53020c9e19b6eb7c6b18afb940bdcf0b604cf.tar.xz
bfc-b2a53020c9e19b6eb7c6b18afb940bdcf0b604cf.tar.zst
bfc-b2a53020c9e19b6eb7c6b18afb940bdcf0b604cf.zip
remove utility (ivec, node_vec, str) headersHEADmain
also omit the lexer entirely, plus the parser type.
-rw-r--r--src/all.h84
-rw-r--r--src/ast_dump.c4
-rw-r--r--src/bfc.c13
-rw-r--r--src/codegen.c1
-rw-r--r--src/ivec.c2
-rw-r--r--src/ivec.h18
-rw-r--r--src/lexer.c62
-rw-r--r--src/node_vec.c1
-rw-r--r--src/node_vec.h26
-rw-r--r--src/parser.c73
-rw-r--r--src/str.c2
-rw-r--r--src/str.h22
12 files changed, 92 insertions, 216 deletions
diff --git a/src/all.h b/src/all.h
index c35c8b7..7456824 100644
--- a/src/all.h
+++ b/src/all.h
@@ -1,33 +1,27 @@
#pragma once
-#include "ivec.h"
-#include "node_vec.h"
-#include "str.h"
#include <stdbool.h>
#include <stddef.h>
+#include <stdio.h>
-// Lexer
-
-typedef enum {
- LEX_PINC,
- LEX_PDEC,
- LEX_VINC,
- LEX_VDEC,
- LEX_OUT,
- LEX_IN,
- LEX_LB,
- LEX_RB,
- LEX_EOF
-} lex_tok_e;
+typedef struct {
+ long long *_data;
+ size_t _cap;
+ size_t len;
+} ivec;
typedef struct {
- str *src;
- size_t pos;
- ivec tokens;
-} lexer_t;
+ char *data;
+ size_t length;
+ size_t capacity;
+} str;
+
+typedef struct ast_node ast_node_t;
-lexer_t lex_init(str *src);
-void lex_run(lexer_t *lx);
-void lex_free(lexer_t *lx);
+typedef struct {
+ ast_node_t **_data;
+ size_t _cap;
+ size_t len;
+} node_vec;
// Parser/AST
@@ -52,13 +46,7 @@ struct ast_node {
ast_node_t *next;
};
-typedef struct {
- lexer_t *lx;
- size_t pos;
-} parser_t;
-
-parser_t parser_init(lexer_t *lx);
-ast_node_t *parse_program(parser_t *p);
+ast_node_t *parse(const char *src);
ast_node_t *optimize_ast(ast_node_t *ast);
void ast_free(ast_node_t *node);
void ast_dump(ast_node_t *node, int depth);
@@ -66,3 +54,39 @@ void ast_dump(ast_node_t *node, int depth);
// codegen
str gen_code(ast_node_t *ast);
+
+void iv_free(ivec *v);
+size_t iv_push(ivec *v, long long data);
+long long iv_get(ivec *v, size_t idx);
+long long iv_rem_shift(ivec *v, size_t idx);
+long long iv_rem(ivec *v, size_t idx);
+long long iv_has(ivec *v, long long x,
+ int (*comp)(const long long, const long long));
+void iv_shrink(ivec *v);
+
+void node_vec_free(node_vec *v);
+
+size_t node_vec_push(node_vec *v, ast_node_t *data);
+
+ast_node_t *node_vec_get(node_vec *v, size_t idx);
+
+ast_node_t *node_vec_rem_shift(node_vec *v, size_t idx);
+
+ast_node_t *node_vec_rem(node_vec *v, size_t idx);
+
+ast_node_t *node_vec_has(node_vec *v, ast_node_t *x,
+ int (*comp)(const ast_node_t *, const ast_node_t *));
+
+void node_vec_shrink(node_vec *v);
+
+void free_str(str *s);
+
+void str_append(str *s, const char *from);
+void str_append_c(str *s, char c);
+void str_append_len(str *s, const char *from, size_t len);
+
+void str_append_read(str *s, int fd);
+void str_append_fread(str *s, FILE *file);
+void str_append_fread_len(str *s, size_t size, FILE *file);
+
+void str_appendf(str *s, const char *fmt, ...);
diff --git a/src/ast_dump.c b/src/ast_dump.c
index 0224c09..0b3c2e2 100644
--- a/src/ast_dump.c
+++ b/src/ast_dump.c
@@ -54,10 +54,10 @@ void ast_dump(ast_node_t *node, int depth) {
fprintf(stderr, "{\n");
- for (int i = 0; i < node->children.len; i++)
+ for (size_t i = 0; i < node->children.len; i++)
ast_dump(node->children._data[i], depth + 1);
- for (size_t i = 0; i < depth; i++)
+ for (int i = 0; i < depth; i++)
fprintf(stderr, " ");
fprintf(stderr, "}\n");
diff --git a/src/bfc.c b/src/bfc.c
index 8ef8d3d..593698e 100644
--- a/src/bfc.c
+++ b/src/bfc.c
@@ -1,5 +1,4 @@
#include "all.h"
-#include "str.h"
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
@@ -12,10 +11,10 @@ int main(int argc, char *argv[]) {
bool dump_ast = false;
for (int i = 1; i < argc; i++) {
- if (strcmp("-cdump", argv[i]) == 0) {
+ if (strcmp("-cd", argv[i]) == 0) {
dump_c = true;
}
- if (strcmp("-ast_dump", argv[i]) == 0) {
+ if (strcmp("-ad", argv[i]) == 0) {
dump_ast = true;
}
}
@@ -23,14 +22,8 @@ int main(int argc, char *argv[]) {
str input = {0};
str_append_fread(&input, stdin);
- // Run the lexer to get tokens (honestly useless considering the simplicity of
- // BF)
- lexer_t lexer = lex_init(&input);
- lex_run(&lexer);
-
// Run the parser and turn tokens into an AST representation
- parser_t p = parser_init(&lexer);
- ast_node_t *ast = parse_program(&p);
+ ast_node_t *ast = parse(input.data);
ast = optimize_ast(ast);
if (dump_ast)
ast_dump(ast, 0);
diff --git a/src/codegen.c b/src/codegen.c
index 00a4e16..df89aa1 100644
--- a/src/codegen.c
+++ b/src/codegen.c
@@ -1,5 +1,4 @@
#include "all.h"
-#include "str.h"
static void emit_prelude(str *out) {
str_append(out, "void _start(void){"
diff --git a/src/ivec.c b/src/ivec.c
index 9c0dd95..5253a8e 100644
--- a/src/ivec.c
+++ b/src/ivec.c
@@ -1,4 +1,4 @@
-#include "ivec.h"
+#include "all.h"
#include <stdio.h>
#include <stdlib.h>
diff --git a/src/ivec.h b/src/ivec.h
deleted file mode 100644
index 8526171..0000000
--- a/src/ivec.h
+++ /dev/null
@@ -1,18 +0,0 @@
-#pragma once
-
-#include <stddef.h>
-
-typedef struct {
- long long *_data;
- size_t _cap;
- size_t len;
-} ivec;
-
-void iv_free(ivec *v);
-size_t iv_push(ivec *v, long long data);
-long long iv_get(ivec *v, size_t idx);
-long long iv_rem_shift(ivec *v, size_t idx);
-long long iv_rem(ivec *v, size_t idx);
-long long iv_has(ivec *v, long long x,
- int (*comp)(const long long, const long long));
-void iv_shrink(ivec *v);
diff --git a/src/lexer.c b/src/lexer.c
deleted file mode 100644
index b4d11eb..0000000
--- a/src/lexer.c
+++ /dev/null
@@ -1,62 +0,0 @@
-#include "all.h"
-#include "ivec.h"
-#include <stdlib.h>
-
-lexer_t lex_init(str *src) {
- lexer_t lx = {0};
-
- lx.src = src;
- lx.pos = 0;
- lx.tokens = (ivec){0};
-
- return lx;
-}
-
-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;
- break;
- case '-':
- tok = LEX_PDEC;
- break;
- case '>':
- tok = LEX_VINC;
- break;
- case '<':
- tok = LEX_VDEC;
- break;
- case '.':
- tok = LEX_OUT;
- break;
- case ',':
- tok = LEX_IN;
- break;
- case '[':
- tok = LEX_LB;
- break;
- case ']':
- tok = LEX_RB;
- break;
- 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/node_vec.c b/src/node_vec.c
index f327585..47bcdeb 100644
--- a/src/node_vec.c
+++ b/src/node_vec.c
@@ -1,4 +1,3 @@
-#include "node_vec.h"
#include "all.h"
#include <stdio.h>
#include <stdlib.h>
diff --git a/src/node_vec.h b/src/node_vec.h
deleted file mode 100644
index 8421d32..0000000
--- a/src/node_vec.h
+++ /dev/null
@@ -1,26 +0,0 @@
-#pragma once
-
-#include <stddef.h>
-
-typedef struct ast_node ast_node_t;
-
-typedef struct {
- ast_node_t **_data;
- size_t _cap;
- size_t len;
-} node_vec;
-
-void node_vec_free(node_vec *v);
-
-size_t node_vec_push(node_vec *v, ast_node_t *data);
-
-ast_node_t *node_vec_get(node_vec *v, size_t idx);
-
-ast_node_t *node_vec_rem_shift(node_vec *v, size_t idx);
-
-ast_node_t *node_vec_rem(node_vec *v, size_t idx);
-
-ast_node_t *node_vec_has(node_vec *v, ast_node_t *x,
- int (*comp)(const ast_node_t *, const ast_node_t *));
-
-void node_vec_shrink(node_vec *v);
diff --git a/src/parser.c b/src/parser.c
index b89f07d..a274cd8 100644
--- a/src/parser.c
+++ b/src/parser.c
@@ -1,13 +1,9 @@
#include "all.h"
#include <stdlib.h>
-static inline lex_tok_e peek(parser_t *p) {
- return iv_get(&p->lx->tokens, p->pos);
-}
+static inline char peek(const char **p) { return **p; }
-static inline lex_tok_e advance(parser_t *p) {
- return iv_get(&p->lx->tokens, p->pos++);
-}
+static inline char advance(const char **p) { return *(*p)++; }
static ast_node_t *new_node(ast_type_e type, int val) {
ast_node_t *n = malloc(sizeof(ast_node_t));
@@ -18,106 +14,99 @@ static ast_node_t *new_node(ast_type_e type, int val) {
return n;
}
-static ast_node_t *parse_block(parser_t *p);
+static ast_node_t *parse_block(const char **p);
-static ast_node_t *parse_single(parser_t *p) {
- lex_tok_e t = peek(p);
+static ast_node_t *parse_single(const char **p) {
+ char c = peek(p);
- switch (t) {
+ switch (c) {
- case LEX_PINC: {
+ case '+': {
int count = 0;
- while (peek(p) == LEX_PINC) {
+ while (peek(p) == '+') {
advance(p);
count++;
}
return new_node(AST_INC, count);
}
- case LEX_PDEC: {
+ case '-': {
int count = 0;
- while (peek(p) == LEX_PDEC) {
+ while (peek(p) == '-') {
advance(p);
count++;
}
return new_node(AST_DEC, count);
}
- case LEX_VINC: {
+ case '>': {
int count = 0;
- while (peek(p) == LEX_VINC) {
+ while (peek(p) == '>') {
advance(p);
count++;
}
return new_node(AST_PTR_INC, count);
}
- case LEX_VDEC: {
+ case '<': {
int count = 0;
- while (peek(p) == LEX_VDEC) {
+ while (peek(p) == '<') {
advance(p);
count++;
}
return new_node(AST_PTR_DEC, count);
}
- case LEX_OUT:
+ case '.':
advance(p);
return new_node(AST_OUT, 1);
- case LEX_IN:
+ case ',':
advance(p);
return new_node(AST_IN, 1);
- case LEX_LB:
- advance(p); // consume '['
+ case '[':
+ advance(p);
return parse_block(p);
- case LEX_RB:
- return NULL;
-
- case LEX_EOF:
+ case ']':
+ case '\0':
return NULL;
default:
- advance(p);
+ advance(p); // ignore garbage
return NULL;
}
}
-static ast_node_t *parse_block(parser_t *p) {
+static ast_node_t *parse_block(const char **p) {
ast_node_t *loop = new_node(AST_LOOP, 1);
- while (1) {
- lex_tok_e t = peek(p);
+ while (**p) {
- if (t == LEX_EOF) {
- break;
- }
-
- if (t == LEX_RB) {
- advance(p); // consume ']'
+ if (**p == ']') {
+ advance(p);
break;
}
ast_node_t *child = parse_single(p);
- if (child) {
+
+ if (child)
node_vec_push(&loop->children, child);
- }
}
return loop;
}
-parser_t parser_init(lexer_t *lx) { return (parser_t){.lx = lx, .pos = 0}; }
+ast_node_t *parse(const char *src) {
+ const char *p = src;
-ast_node_t *parse_program(parser_t *p) {
ast_node_t *head = NULL;
ast_node_t *tail = NULL;
- while (peek(p) != LEX_EOF) {
+ while (*p) {
- ast_node_t *node = parse_single(p);
+ ast_node_t *node = parse_single(&p);
if (!node)
continue;
diff --git a/src/str.c b/src/str.c
index ddca742..bfd892e 100644
--- a/src/str.c
+++ b/src/str.c
@@ -1,4 +1,4 @@
-#include "str.h"
+#include "all.h"
#include <stdarg.h>
#include <stdio.h>
diff --git a/src/str.h b/src/str.h
deleted file mode 100644
index 416a846..0000000
--- a/src/str.h
+++ /dev/null
@@ -1,22 +0,0 @@
-#pragma once
-
-#include <stddef.h>
-#include <stdio.h>
-
-typedef struct {
- char *data;
- size_t length;
- size_t capacity;
-} str;
-
-void free_str(str *s);
-
-void str_append(str *s, const char *from);
-void str_append_c(str *s, char c);
-void str_append_len(str *s, const char *from, size_t len);
-
-void str_append_read(str *s, int fd);
-void str_append_fread(str *s, FILE *file);
-void str_append_fread_len(str *s, size_t size, FILE *file);
-
-void str_appendf(str *s, const char *fmt, ...);