aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/main.c
blob: 57b542c16a95da89f06a8752e89f60fb0d8ebb33 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
#include <stdlib.h>
#include <string.h>
#include "ast.h"
#include "cli.h"
#include "codegen.h"
#include "common.h"
#include "fs.h"
#include "io.h"
#include "parse.h"
#include "preprocess.h"
#include "tokenize.h"

int main(int argc, char** argv) {
    CliArgs* cli_args = parse_cli_args(argc, argv);

    if (cli_args->totally_deligate_to_gcc) {
        return system(cli_args->gcc_command);
    }

    InFile* source = infile_open(cli_args->input_filename);

    StrArray included_files;
    strings_init(&included_files);

    TokenArray* pp_tokens = preprocess(source, &included_files, &cli_args->include_dirs);

    if (cli_args->preprocess_only) {
        FILE* output_file = cli_args->output_filename ? fopen(cli_args->output_filename, "w") : stdout;
        if (!output_file) {
            fatal_error("Cannot open output file: %s", cli_args->output_filename);
        }
        print_token_to_file(output_file, pp_tokens);
        return 0;
    }

    TokenArray* tokens = convert_pp_tokens_to_tokens(pp_tokens);
    Program* prog = parse(tokens);

    const char* assembly_filename;
    if (cli_args->output_assembly) {
        assembly_filename = cli_args->output_filename;
    } else {
        char* temp_filename = calloc(19, sizeof(char));
        temp_filename = strdup("/tmp/ducc-XXXXXX.s");
        mkstemps(temp_filename, strlen(".s"));
        assembly_filename = temp_filename;
    }
    FILE* assembly_file = assembly_filename ? fopen(assembly_filename, "wb") : stdout;
    codegen(prog, assembly_file);
    fclose(assembly_file);

    if (!cli_args->output_assembly) {
        char cmd_buf[256];
        if (cli_args->only_compile) {
            sprintf(cmd_buf, "gcc -c -s -o '%s' '%s'", cli_args->output_filename, assembly_filename);
        } else {
            sprintf(cmd_buf, "gcc -s -o '%s' '%s'", cli_args->output_filename, assembly_filename);
        }
        int result = system(cmd_buf);
        if (result != 0) {
            fatal_error("gcc failed: %d", result);
        }
    }

    if (cli_args->generate_deps && cli_args->only_compile && cli_args->output_filename) {
        const char* dep_filename = replace_extension(cli_args->output_filename, ".d");

        FILE* dep_file = fopen(dep_filename, "w");
        if (!dep_file) {
            fatal_error("Cannot open dependency file: %s", dep_filename);
        }
        fprintf(dep_file, "%s:", cli_args->output_filename);
        for (size_t i = 0; i < included_files.len; ++i) {
            fprintf(dep_file, " \\\n    %s", included_files.data[i]);
        }
        fprintf(dep_file, "\n");
    }
}