diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/all.h | 84 | ||||
| -rw-r--r-- | src/ast_dump.c | 4 | ||||
| -rw-r--r-- | src/bfc.c | 13 | ||||
| -rw-r--r-- | src/codegen.c | 1 | ||||
| -rw-r--r-- | src/ivec.c | 2 | ||||
| -rw-r--r-- | src/ivec.h | 18 | ||||
| -rw-r--r-- | src/lexer.c | 62 | ||||
| -rw-r--r-- | src/node_vec.c | 1 | ||||
| -rw-r--r-- | src/node_vec.h | 26 | ||||
| -rw-r--r-- | src/parser.c | 73 | ||||
| -rw-r--r-- | src/str.c | 2 | ||||
| -rw-r--r-- | src/str.h | 22 |
12 files changed, 92 insertions, 216 deletions
@@ -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"); @@ -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){" @@ -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; @@ -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, ...); |
