From 3621e6772b73b499d9d59a2e3b17cbf285ed97fd Mon Sep 17 00:00:00 2001 From: sam Date: Mon, 22 Jul 2024 13:02:37 +1200 Subject: [PATCH] cleanup and add run and build commands --- .vscode/settings.json | 7 ++++++- Makefile | 7 +++++-- include/binary.h | 8 ++++++++ include/helpers.h | 7 +++++++ include/slibs | 2 +- include/tokenizer.h | 1 + src/binary.c | 29 +++++++++++++++++++++++++++++ src/codegen.c | 2 +- src/helpers.c | 16 ++++++++++++++++ src/main.c | 28 ++++++++++------------------ src/tokenizer.c | 7 +++++++ 11 files changed, 91 insertions(+), 23 deletions(-) create mode 100644 include/binary.h create mode 100644 src/binary.c diff --git a/.vscode/settings.json b/.vscode/settings.json index 4217d5b..a8a37f1 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,5 +1,10 @@ { "files.associations": { - "string.h": "c" + "string.h": "c", + "bitset": "c", + "initializer_list": "c", + "string": "c", + "string_view": "c", + "assert.h": "c" } } \ No newline at end of file diff --git a/Makefile b/Makefile index ddbe134..362b6c9 100644 --- a/Makefile +++ b/Makefile @@ -14,11 +14,14 @@ $(BINARY): $(OBJ) Makefile tcc/libtcc1.a $(CC) $(CFLAGS) -c $< -o $@ run: $(BINARY) - ./$(BINARY) example.lisp example + ./$(BINARY) run example.lisp + +run-build: $(BINARY) + ./$(BINARY) build example.lisp example ./example tcc/libtcc1.a: - cd tcc && ./configure + cd tcc && ./configure --cc=$(CC) make -C tcc clean: diff --git a/include/binary.h b/include/binary.h new file mode 100644 index 0000000..fca9211 --- /dev/null +++ b/include/binary.h @@ -0,0 +1,8 @@ +#include + +#ifndef __BINARY_H__ +#define __BINARY_H__ + +int binary_produce(const char* code, Args args); + +#endif \ No newline at end of file diff --git a/include/helpers.h b/include/helpers.h index 1c1073f..706246f 100644 --- a/include/helpers.h +++ b/include/helpers.h @@ -1,6 +1,13 @@ #ifndef __HELPERS_H__ #define __HELPERS_H__ +typedef struct Args { + const char* input; + const char* output; + int build; +} Args; + char* gen_ident(int indent); +Args parse_args(int argc, char* argv[]); #endif \ No newline at end of file diff --git a/include/slibs b/include/slibs index ce1c05c..1de5b35 160000 --- a/include/slibs +++ b/include/slibs @@ -1 +1 @@ -Subproject commit ce1c05c6e6fdc00ccc381ad3ba621edcaa80469e +Subproject commit 1de5b35258cffda13d4bcf505e83c976e448e750 diff --git a/include/tokenizer.h b/include/tokenizer.h index 2f99ba6..e961f5f 100644 --- a/include/tokenizer.h +++ b/include/tokenizer.h @@ -21,5 +21,6 @@ Token* tokenize(char* input); Token* token_create(char* value, TokenType type, Token* root); Token* token_append(Token* root, Token* new_token); +void tokens_print(Token* root); #endif \ No newline at end of file diff --git a/src/binary.c b/src/binary.c new file mode 100644 index 0000000..a34c322 --- /dev/null +++ b/src/binary.c @@ -0,0 +1,29 @@ +#include +#include +#include +#include +#include + +int binary_produce(const char* code, Args args) { + TCCState* state = tcc_new(); + tcc_set_lib_path(state, "tcc"); + if(args.build) { + assert(tcc_set_output_type(state, TCC_OUTPUT_EXE) == 0); + } else { + assert(tcc_set_output_type(state, TCC_OUTPUT_MEMORY) == 0); + } + + assert(tcc_add_include_path(state, "std") == 0); + assert(tcc_add_file(state, "std/std.c") == 0); + assert(tcc_compile_string(state, code) == 0); + + int ret = -1; + if(args.build) { + ret = tcc_output_file(state, args.output); + printf("Binary produced: %s\n", args.output); + } else { + ret = tcc_run(state, 0, NULL); + } + + return ret; +} \ No newline at end of file diff --git a/src/codegen.c b/src/codegen.c index 9d30b9b..f3136f5 100644 --- a/src/codegen.c +++ b/src/codegen.c @@ -36,5 +36,5 @@ const char* codegen(ASTNode* node) { return sl_c_str(code); } - return ""; + return NULL; } \ No newline at end of file diff --git a/src/helpers.c b/src/helpers.c index 1ffcae8..7fce2fe 100644 --- a/src/helpers.c +++ b/src/helpers.c @@ -1,10 +1,26 @@ #include #include #include +#include char* gen_ident(int indent) { char* text = malloc(sizeof(char) * (indent + 1)); memset(text, ' ', indent); text[indent] = '\0'; return text; +} + +Args parse_args(int argc, char* argv[]) { + assert(argc > 2); + int build = 0; + if(strcmp(argv[1], "build") == 0) { + build = 1; + assert(argc > 3 && "Build needs an input and output filename."); + } else assert(strcmp(argv[1], "run") == 0 && "You must specify to either build or run."); + + return (Args){ + .input = argv[2], + .output = build ? argv[3] : NULL, + .build = build + }; } \ No newline at end of file diff --git a/src/main.c b/src/main.c index cdbf371..3cb9dda 100644 --- a/src/main.c +++ b/src/main.c @@ -1,27 +1,25 @@ #define SL_IMPLEMENTATION #include + #include #include #include -#include +#include +#include int main(int argc, char* argv[]) { - assert(argc > 2); + Args args = parse_args(argc, argv); sl_string buffer = { 0 }; - sl_read_file(argv[1], &buffer); + sl_read_file(args.input, &buffer); - Token* root = tokenize(sl_c_str(buffer)); printf("Tokens:\n"); - Token* curr = root; - while(curr != NULL) { - printf("%s: %s\n", TokenTypeText[curr->type], curr->value); - curr = curr->next; - } + Token* tokens = tokenize(sl_c_str(buffer)); + tokens_print(tokens); printf("\n"); printf("AST:\n"); - ASTNode* program = ast_parse(&root); + ASTNode* program = ast_parse(&tokens); ast_print(program, 0); printf("\n"); @@ -29,13 +27,7 @@ int main(int argc, char* argv[]) { const char* code = codegen(program); printf("%s\n\n", code); - TCCState* state = tcc_new(); - tcc_set_lib_path(state, "tcc"); - assert(tcc_set_output_type(state, TCC_OUTPUT_EXE) == 0); - assert(tcc_add_include_path(state, "std") == 0); - assert(tcc_add_file(state, "std/std.c") == 0); - assert(tcc_compile_string(state, code) == 0); - assert(tcc_output_file(state, argv[2]) == 0); + binary_produce(code, args); - printf("Binary produced: %s\n", argv[2]); + return 0; } \ No newline at end of file diff --git a/src/tokenizer.c b/src/tokenizer.c index 62243f6..239f19b 100644 --- a/src/tokenizer.c +++ b/src/tokenizer.c @@ -74,4 +74,11 @@ Token* token_append(Token* root, Token* new_token) { } current->next = new_token; return root; +} + +void tokens_print(Token* root) { + while(root != NULL) { + printf("%s: %s\n", TokenTypeText[root->type], root->value); + root = root->next; + } } \ No newline at end of file