add better args system:

This commit is contained in:
sam 2024-07-22 23:31:54 +12:00
parent f05fbf3e53
commit 5f1f937270
11 changed files with 90 additions and 41 deletions

View file

@ -16,8 +16,15 @@ $(BINARY): $(OBJ) Makefile tcc/libtcc1.a
run: $(BINARY)
./$(BINARY) run example.lisp
run-debug: $(BINARY)
./$(BINARY) run example.lisp -d yes
run-build: $(BINARY)
./$(BINARY) build example.lisp example
./$(BINARY) build example.lisp -o example
./example
run-build-debug: $(BINARY)
./$(BINARY) build example.lisp -o example -d yes
./example
tcc/libtcc1.a:

View file

@ -15,5 +15,5 @@ to run the example run `make run`, or to compile another file run either
```
or
```
./compiler build filename.lisp binaryname
./compiler build filename.lisp -o outputname
```

View file

@ -5,4 +5,3 @@
(printf "5 + (100 / 5) = %d\n"
(add 5
(divide 100 5)))

13
include/args.h Normal file
View file

@ -0,0 +1,13 @@
#ifndef __ARGS_H__
#define __ARGS_H__
typedef struct Args {
const char* input;
const char* output;
int build;
int comp_debug;
} Args;
Args parse_args(int argc, char** argv);
#endif

View file

@ -1,4 +1,4 @@
#include <helpers.h>
#include <args.h>
#ifndef __BINARY_H__
#define __BINARY_H__

View file

@ -1,13 +1,6 @@
#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

@ -1 +1 @@
Subproject commit b0b09f6fd9efd5367dbac19629caf0d027e657e2
Subproject commit 986006449d1586d9ae55e5696015aa67b0e33f4f

48
src/args.c Normal file
View file

@ -0,0 +1,48 @@
#include <args.h>
#include <string.h>
#include <assert.h>
char* arg_proceeding(int argc, char** argv, char* arg, char* default_return) {
for(int i = 0; i < argc - 1; i++) {
if(strcmp(argv[i], arg) == 0) {
return argv[i + 1];
}
}
return default_return;
}
char* find_flagless_arg(int argc, char** argv, char* default_return) {
for(int i = 1; i < argc; i++) {
if(argv[i - 1][0] != '-' && argv[i][0] != '-') {
return argv[i];
}
}
return default_return;
}
void skip_args(int* argc, char*** argv, int n) {
*argc -= n;
*argv += n;
}
Args parse_args(int argc, char** argv) {
assert(argc > 1);
skip_args(&argc, &argv, 1);
Args args = { 0 };
if(argc == 1) {
args.input = argv[0];
} else {
if(strcmp(argv[0], "build") == 0) {
args.build = 1;
args.output = arg_proceeding(argc, argv, "-o", "a.out");
}
args.input = find_flagless_arg(argc, argv, NULL);
args.comp_debug = arg_proceeding(argc, argv, "-d", NULL) != NULL;
}
return args;
}

View file

@ -18,7 +18,10 @@ int binary_produce(const char* code, Args args) {
assert(tcc_compile_string(state, code) == 0);
if(args.build) {
return tcc_output_file(state, args.output);
int ret = -1;
ret = tcc_output_file(state, args.output);
if(args.comp_debug) printf("Produced binary %s\n", args.output);
return ret;
} else {
return tcc_run(state, 0, NULL);
}

View file

@ -1,26 +1,10 @@
#include <helpers.h>
#include <string.h>
#include <stdlib.h>
#include <assert.h>
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
};
}

View file

@ -5,28 +5,30 @@
#include <ast.h>
#include <codegen.h>
#include <binary.h>
#include <helpers.h>
#include <args.h>
int main(int argc, char* argv[]) {
Args args = parse_args(argc, argv);
sl_string buffer = { 0 };
sl_read_file(args.input, &buffer);
sl_string* input_str = sl_read_file(args.input);
if(!input_str) return -1;
char* input = sl_c_str(*input_str);
printf("Tokens:\n");
int debug = args.comp_debug;
if(debug) printf("Tokens:\n");
TokenVec tokens = { 0 };
tokenize(sl_c_str(buffer), &tokens);
tokens_print(tokens);
printf("\n");
tokenize(input, &tokens);
if(debug) tokens_print(tokens);
if(debug) printf("\n");
printf("AST:\n");
if(debug) printf("AST:\n");
ASTNode* program = ast_parse(&tokens);
ast_print(program, 0);
printf("\n");
if(debug) ast_print(program, 0);
if(debug) printf("\n");
printf("Codegen:\n");
if(debug) printf("Codegen:\n");
const char* code = codegen(program);
printf("%s\n\n", code);
if(debug) printf("%s\n\n", code);
binary_produce(code, args);