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;
}
|