aboutsummaryrefslogtreecommitdiffstats
path: root/src/bootstrap/main.c
blob: 28473975464a6d2a59eefb705af78fd6ddb28d13 (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
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
#include <getopt.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>

#include "string_view.c"

void
process_source(const StringView *source) {
    sv_write(source, stdout);
}

#define REPL_PROMPT "bdl> "

void
run_repl(void) {
    printf("BDL REPL (Press Ctrl-C to exit)\n");
    while (true) {
        printf(REPL_PROMPT);
        getchar();
        process_source(NULL);
    }
}

void
run_file(char *file_name) {
    FILE *file = fopen(file_name, "r");
    if (!file) {
        fprintf(stderr, "error: couldn't open input file: %s\n", file_name);
        exit(EXIT_FAILURE);
    }

    // Read entire file into memory.
    fseek(file, 0, SEEK_END);
    size_t file_size = ftell(file);
    fseek(file, 0, SEEK_SET);

    char *source = malloc(file_size + 1);
    fread(source, 1, file_size, file);
    source[file_size] = 0;

    StringView sv = (StringView){
        .start = source,
        .n = file_size,
    };

    process_source(&sv);

    free(source);
    fclose(file);
}

#ifndef BIN_NAME
#define BIN_NAME "bdl"
#endif

void
print_usage(void) {
    printf("Usage: %s [options] <filename filename ...>\n", BIN_NAME);
    printf("\n");
    printf("\t-i\tInteractive mode (REPL).\n");
    printf("\n");
}

int
main(int argc, char *argv[]) {
    int option;
    while ((option = getopt(argc, argv, "i")) != -1) {
        switch (option) {
            case 'i': {
                // Interactive mode.
                run_repl();
                return EXIT_SUCCESS;
            } break;
            default: {
                print_usage();
                return EXIT_FAILURE;
            } break;
        }
    }

    // Run from stdin.
    if (optind == argc) {
        // TODO: Run from stdin if no file is given.
        return EXIT_SUCCESS;
    }

    // Run from file.
    while (optind < argc) {
        char *file_name = argv[optind];
        run_file(file_name);
        optind++;
    }

    return EXIT_SUCCESS;
}