From eeff5e273f22aa28e81ab080e9ffdce85ac394b8 Mon Sep 17 00:00:00 2001 From: Bad Diode Date: Fri, 22 Oct 2021 09:59:31 +0200 Subject: Prepare skeleton for bytecode interpreter --- src/bytecode/main.c | 197 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 197 insertions(+) create mode 100644 src/bytecode/main.c (limited to 'src/bytecode/main.c') diff --git a/src/bytecode/main.c b/src/bytecode/main.c new file mode 100644 index 0000000..78fdfd3 --- /dev/null +++ b/src/bytecode/main.c @@ -0,0 +1,197 @@ +#include +#include +#include +#include +#include + +#include "types.h" +#include "darray.h" +#include "ops.h" +#include "debug.h" +#include "errors.c" +#include "lexer.c" +#include "read_line.c" +#include "string_view.c" + +void +init(void) { + // STUB +} + +void +process_source(const StringView *source) { + Token *tokens = tokenize(source); + if (errors_n != 0) { + array_free(tokens); + return; + } + + // Test chunks and debugging utilities. + u8 *chunk = NULL; + array_init(chunk, 0); + array_push(chunk, OP_RETURN); + array_push(chunk, OP_RETURN); + array_push(chunk, OP_RETURN); + array_push(chunk, OP_RETURN); + disassemble_chunk(chunk, "test chunk"); + + array_free(chunk); + array_free(tokens); +} + +#define REPL_PROMPT "bdl> " + +void +run_repl(void) { + printf("BDL REPL (Press Ctrl-D or Ctrl-C to exit)\n"); + while (true) { + printf(REPL_PROMPT); + StringView sv = read_line(); + if (sv.start == NULL) { + return; + } + process_source(&sv); + + // Check if there were any errors. + if (errors_n != 0 && !supress_errors) { + for (size_t i = 0; i < errors_n; i++) { + Error err = errors[i]; + for (size_t j = 0; j < err.col + sizeof(REPL_PROMPT) - 2; j++) { + putchar(' '); + } + printf("|\n"); + for (size_t j = 0; j < err.col + sizeof(REPL_PROMPT) - 2; j++) { + putchar(' '); + } + printf("%s\n", error_msgs[err.value]); + } + errors_n = 0; + continue; + } + } +} + +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); + + // Check if there were any errors. + if (errors_n != 0 && !supress_errors) { + for (size_t i = 0; i < errors_n; i++) { + Error err = errors[i]; + fprintf(stderr, "%s", file_name); + if (err.line != 0) { + fprintf(stderr, ":%ld:%ld", err.line, err.col); + } + fprintf(stderr, ": %s\n", error_msgs[err.value]); + } + errors_n = 0; + } + + free(source); + fclose(file); +} + +#define STDIN_BUF_CAP 16 + +void +run_stdin(void) { + size_t buf_size = 0; + char *source = NULL; + array_init(source, STDIN_BUF_CAP); + + char c; + while ((c = getchar()) != EOF) { + array_push(source, c); + buf_size++; + } + + StringView sv = (StringView){ + .start = source, + .n = buf_size, + }; + + process_source(&sv); + + // Check if there were any errors. + if (errors_n != 0 && !supress_errors) { + for (size_t i = 0; i < errors_n; i++) { + Error err = errors[i]; + fprintf(stderr, "stdin"); + if (err.line != 0) { + fprintf(stderr, ":%ld:%ld", err.line, err.col); + } + fprintf(stderr, ": %s\n", error_msgs[err.value]); + } + errors_n = 0; + } + + array_free(source); +} + +#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[]) { + init(); + + 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) { + run_stdin(); + return EXIT_SUCCESS; + } + + // Run from file. + while (optind < argc) { + char *file_name = argv[optind]; + run_file(file_name); + optind++; + } + + return EXIT_SUCCESS; +} -- cgit v1.2.1