cleanup and add run and build commands

This commit is contained in:
sam 2024-07-22 13:02:37 +12:00
parent d5290ad483
commit 3621e6772b
11 changed files with 91 additions and 23 deletions

View file

@ -1,5 +1,10 @@
{ {
"files.associations": { "files.associations": {
"string.h": "c" "string.h": "c",
"bitset": "c",
"initializer_list": "c",
"string": "c",
"string_view": "c",
"assert.h": "c"
} }
} }

View file

@ -14,11 +14,14 @@ $(BINARY): $(OBJ) Makefile tcc/libtcc1.a
$(CC) $(CFLAGS) -c $< -o $@ $(CC) $(CFLAGS) -c $< -o $@
run: $(BINARY) run: $(BINARY)
./$(BINARY) example.lisp example ./$(BINARY) run example.lisp
run-build: $(BINARY)
./$(BINARY) build example.lisp example
./example ./example
tcc/libtcc1.a: tcc/libtcc1.a:
cd tcc && ./configure cd tcc && ./configure --cc=$(CC)
make -C tcc make -C tcc
clean: clean:

8
include/binary.h Normal file
View file

@ -0,0 +1,8 @@
#include <helpers.h>
#ifndef __BINARY_H__
#define __BINARY_H__
int binary_produce(const char* code, Args args);
#endif

View file

@ -1,6 +1,13 @@
#ifndef __HELPERS_H__ #ifndef __HELPERS_H__
#define __HELPERS_H__ #define __HELPERS_H__
typedef struct Args {
const char* input;
const char* output;
int build;
} Args;
char* gen_ident(int indent); char* gen_ident(int indent);
Args parse_args(int argc, char* argv[]);
#endif #endif

@ -1 +1 @@
Subproject commit ce1c05c6e6fdc00ccc381ad3ba621edcaa80469e Subproject commit 1de5b35258cffda13d4bcf505e83c976e448e750

View file

@ -21,5 +21,6 @@ Token* tokenize(char* input);
Token* token_create(char* value, TokenType type, Token* root); Token* token_create(char* value, TokenType type, Token* root);
Token* token_append(Token* root, Token* new_token); Token* token_append(Token* root, Token* new_token);
void tokens_print(Token* root);
#endif #endif

29
src/binary.c Normal file
View file

@ -0,0 +1,29 @@
#include <binary.h>
#include <libtcc.h>
#include <stddef.h>
#include <stdio.h>
#include <assert.h>
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;
}

View file

@ -36,5 +36,5 @@ const char* codegen(ASTNode* node) {
return sl_c_str(code); return sl_c_str(code);
} }
return ""; return NULL;
} }

View file

@ -1,10 +1,26 @@
#include <helpers.h> #include <helpers.h>
#include <string.h> #include <string.h>
#include <stdlib.h> #include <stdlib.h>
#include <assert.h>
char* gen_ident(int indent) { char* gen_ident(int indent) {
char* text = malloc(sizeof(char) * (indent + 1)); char* text = malloc(sizeof(char) * (indent + 1));
memset(text, ' ', indent); memset(text, ' ', indent);
text[indent] = '\0'; text[indent] = '\0';
return text; 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
};
} }

View file

@ -1,27 +1,25 @@
#define SL_IMPLEMENTATION #define SL_IMPLEMENTATION
#include <slibs/slibs.h> #include <slibs/slibs.h>
#include <tokenizer.h> #include <tokenizer.h>
#include <ast.h> #include <ast.h>
#include <codegen.h> #include <codegen.h>
#include <libtcc.h> #include <binary.h>
#include <helpers.h>
int main(int argc, char* argv[]) { int main(int argc, char* argv[]) {
assert(argc > 2); Args args = parse_args(argc, argv);
sl_string buffer = { 0 }; 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"); printf("Tokens:\n");
Token* curr = root; Token* tokens = tokenize(sl_c_str(buffer));
while(curr != NULL) { tokens_print(tokens);
printf("%s: %s\n", TokenTypeText[curr->type], curr->value);
curr = curr->next;
}
printf("\n"); printf("\n");
printf("AST:\n"); printf("AST:\n");
ASTNode* program = ast_parse(&root); ASTNode* program = ast_parse(&tokens);
ast_print(program, 0); ast_print(program, 0);
printf("\n"); printf("\n");
@ -29,13 +27,7 @@ int main(int argc, char* argv[]) {
const char* code = codegen(program); const char* code = codegen(program);
printf("%s\n\n", code); printf("%s\n\n", code);
TCCState* state = tcc_new(); binary_produce(code, args);
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);
printf("Binary produced: %s\n", argv[2]); return 0;
} }

View file

@ -74,4 +74,11 @@ Token* token_append(Token* root, Token* new_token) {
} }
current->next = new_token; current->next = new_token;
return root; return root;
}
void tokens_print(Token* root) {
while(root != NULL) {
printf("%s: %s\n", TokenTypeText[root->type], root->value);
root = root->next;
}
} }