#include #include #include #include #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] \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; }