From 376b83e6a44271599ed563e3510b2411beab5921 Mon Sep 17 00:00:00 2001 From: Bad Diode Date: Sat, 9 Oct 2021 13:46:54 +0200 Subject: Enable eval expressions from stdin and small cleanup --- src/bootstrap/main.c | 108 +++++++++++++++++++++------------------------------ 1 file changed, 45 insertions(+), 63 deletions(-) diff --git a/src/bootstrap/main.c b/src/bootstrap/main.c index e0012eb..f5653d6 100755 --- a/src/bootstrap/main.c +++ b/src/bootstrap/main.c @@ -36,8 +36,10 @@ sv_equal(StringView a, StringView b) { return false; } +#define READLINE_VALID_CHAR(C) (((u8)(C) >= 0x20 && (u8)(C) < 0x7F) || (C) == '\n') + StringView -read_line(void) { +read_line(FILE *fd, char delimiter) { #define RL_BUF_SIZE 1024 static char readline_buf[RL_BUF_SIZE]; @@ -49,11 +51,11 @@ read_line(void) { // Barebones readline implementation. size_t n = 0; char c; - while ((c = getchar()) != '\n') { + while ((c = getc(fd)) != delimiter) { if (c == '\b') { readline_buf[n] = '\0'; n--; - } else if (((u8)c >= 0x20 && (u8)c <= 0x7F) && n < RL_BUF_SIZE) { + } else if (READLINE_VALID_CHAR(c) && n < RL_BUF_SIZE) { readline_buf[n] = c; n++; } @@ -697,30 +699,20 @@ eval(Object *root) { } void -print_usage(void) { - printf("Usage: %s [options] \n", BIN_NAME); - printf("\n"); - printf("\t-i\tInteractive mode (REPL).\n"); - printf("\n"); -} - -void -run_repl(void) { - printf("BDL REPL (Press Ctrl-C to exit)\n"); - while (true) { - printf(REPL_PROMPT); - StringView line = read_line(); - Tokens tokens = tokenize(line); +eval_line(FILE *fd, char delimiter) { + StringView line = read_line(fd, delimiter); + Tokens tokens = tokenize(line); #if DEBUG - printf("N_TOKENS: %ld\n", tokens.n); - for (size_t i = 0; i < tokens.n; i++) { - printf("\tTYPE: %3d ", tokens.start[i].type); - printf("N: %3ld ", tokens.start[i].value.n); - printf("VALUE: "); - sv_write(tokens.start[i].value); - printf("\n"); - } + printf("N_TOKENS: %ld\n", tokens.n); + for (size_t i = 0; i < tokens.n; i++) { + printf("\tTYPE: %3d ", tokens.start[i].type); + printf("N: %3ld ", tokens.start[i].value.n); + printf("VALUE: "); + sv_write(tokens.start[i].value); + printf("\n"); + } #endif + while (tokens.n > 0) { Object *ast = parse(&tokens); if (ast) { #if DEBUG @@ -735,53 +727,36 @@ run_repl(void) { } } +void +run_repl(void) { + printf("BDL REPL (Press Ctrl-C to exit)\n"); + while (true) { + printf(REPL_PROMPT); + eval_line(stdin, '\n'); + } +} + void run_file(char *file_name) { #if DEBUG printf("Executing file: %s\n", file_name); #endif - - // Load entire file into memory. - char * src = NULL; FILE *fd = fopen(file_name, "r"); if (!fd) { fprintf(stderr, "couldn't open file: %s\n", file_name); - exit(-1); - } - fseek(fd, 0, SEEK_END); - size_t file_size = ftell(fd); - fseek(fd, 0, SEEK_SET); - src = malloc(file_size + 1); - fread(src, 1, file_size, fd); - src[file_size] = '\0'; - fclose(fd); - - Tokens tokens = tokenize((StringView){.start = src, .n = file_size}); -#if DEBUG - printf("N_TOKENS: %ld\n", tokens.n); - for (size_t i = 0; i < tokens.n; i++) { - printf("\tTYPE: %3d ", tokens.start[i].type); - printf("N: %3ld ", tokens.start[i].value.n); - printf("VALUE: "); - sv_write(tokens.start[i].value); - printf("\n"); - } -#endif - while (tokens.n) { - Object *ast = parse(&tokens); - if (ast) { -#if DEBUG - printf("AST: "); - display(ast); - printf("\n"); - printf("EVAL: "); -#endif - display(eval(ast)); - printf("\n"); - } + exit(EXIT_FAILURE); } + eval_line(fd, EOF); + fclose(fd); +} - free(src); +void +print_usage(void) { + printf("Usage: %s [options] \n", BIN_NAME); + printf("\n"); + printf("\t-i\tInteractive mode (REPL).\n"); + printf("\t-x\tExecute expression from stdin.\n"); + printf("\n"); } int @@ -789,12 +764,18 @@ main(int argc, char *argv[]) { init(); int option; - while ((option = getopt(argc, argv, "i")) != -1) { + while ((option = getopt(argc, argv, "ix")) != -1) { switch (option) { case 'i': { + // Interactive mode. run_repl(); return EXIT_SUCCESS; } break; + case 'x': { + // Execute expression from stdin. + eval_line(stdin, EOF); + return EXIT_SUCCESS; + } break; default: { print_usage(); return EXIT_FAILURE; @@ -802,6 +783,7 @@ main(int argc, char *argv[]) { } } + // Run from file. if (optind != argc - 1) { fprintf(stderr, "%s: No input file given.\n", BIN_NAME); print_usage(); -- cgit v1.2.1