diff options
Diffstat (limited to 'src')
| -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 |
4 files changed, 27 insertions, 125 deletions
@@ -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) { |
