From 3444b5b58a78c12a79365bb35e54cfa029fccd99 Mon Sep 17 00:00:00 2001 From: Bad Diode Date: Tue, 12 Oct 2021 10:53:20 +0200 Subject: Add error dispatch procedure --- src/bootstrap/errors.c | 33 ++++++++++++++++++++++++++++++ src/bootstrap/lexer.c | 52 ++++++++++++++++++++++++++--------------------- src/bootstrap/main.c | 55 +++++++++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 116 insertions(+), 24 deletions(-) create mode 100644 src/bootstrap/errors.c diff --git a/src/bootstrap/errors.c b/src/bootstrap/errors.c new file mode 100644 index 0000000..fcb629a --- /dev/null +++ b/src/bootstrap/errors.c @@ -0,0 +1,33 @@ +typedef enum ErrorType { + ERR_TYPE_LEXER, + ERR_TYPE_PARSER, + ERR_TYPE_RUNTIME, +} ErrorType; + +typedef enum ErrorValue { + ERR_UNKNOWN = 0, + ERR_UNMATCHED_STRING, +} ErrorValue; + +typedef struct Error { + ErrorType type; + ErrorValue value; + size_t line; + size_t col; +} Error; + +static const char* error_msgs[] = { + [ERR_UNKNOWN] = "error: something unexpected happened", + [ERR_UNMATCHED_STRING] = "error: unmatched string delimiter", +}; + +#define ERR_MAX_NUMBER 16 +static Error errors[ERR_MAX_NUMBER]; +static size_t errors_n = 0; + +void +error_push(Error error) { + if (errors_n < ERR_MAX_NUMBER) { + errors[errors_n++] = error; + } +} diff --git a/src/bootstrap/lexer.c b/src/bootstrap/lexer.c index 1add4dc..49431d0 100644 --- a/src/bootstrap/lexer.c +++ b/src/bootstrap/lexer.c @@ -134,6 +134,28 @@ skip_whitespace(Scanner *scanner) { } } +bool +is_delimiter(char c) { + switch (c) { + case EOF: + case '\0': + case ';': + case '"': + case '\'': + case '(': + case ')': + case ' ': + case '\f': + case '\n': + case '\r': + case '\t': + case '\v': { + return true; + } break; + } + return false; +} + TokenType find_primitive_type(StringView value) { bool is_fixnum = true; @@ -159,28 +181,6 @@ find_primitive_type(StringView value) { return TOKEN_SYMBOL; } -bool -is_delimiter(char c) { - switch (c) { - case EOF: - case '\0': - case ';': - case '"': - case '\'': - case '(': - case ')': - case ' ': - case '\f': - case '\n': - case '\r': - case '\t': - case '\v': { - return true; - } break; - } - return false; -} - Tokens tokenize(const StringView *sv) { Tokens tokens = (Tokens){0}; @@ -214,7 +214,13 @@ tokenize(const StringView *sv) { n++; } if (!found) { - // TODO: Report error: couldn't find the closing quotes. + error_push((Error){ + .type = ERR_TYPE_LEXER, + .value = ERR_UNMATCHED_STRING, + .line = line, + .col = col, + }); + return tokens; } Token token = (Token){ .value = (StringView){ diff --git a/src/bootstrap/main.c b/src/bootstrap/main.c index 113ee48..dadc887 100755 --- a/src/bootstrap/main.c +++ b/src/bootstrap/main.c @@ -5,11 +5,18 @@ #include "string_view.c" #include "read_line.c" +#include "errors.c" #include "lexer.c" void process_source(const StringView *source) { Tokens tokens = tokenize(source); + if (errors_n != 0) { + if (tokens.buf != NULL) { + free(tokens.buf); + } + return; + } // Print tokens. for (size_t i = 0; i < tokens.size; i++) { @@ -17,7 +24,9 @@ process_source(const StringView *source) { print_token(tok); } - free(tokens.buf); + if (tokens.buf != NULL) { + free(tokens.buf); + } } #define REPL_PROMPT "bdl> " @@ -32,6 +41,24 @@ run_repl(void) { return; } process_source(&sv); + + // Check if there were any errors. + if (errors_n != 0) { + 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; + } + if (sv.n != 0) { printf("\n"); } @@ -62,6 +89,19 @@ run_file(char *file_name) { process_source(&sv); + // Check if there were any errors. + if (errors_n != 0) { + for (size_t i = 0; i < errors_n; i++) { + Error err = errors[i]; + printf("%s", file_name); + if (err.line != 0) { + printf(":%ld:%ld", err.line, err.col); + } + printf("%s\n", error_msgs[err.value]); + } + errors_n = 0; + } + free(source); fclose(file); } @@ -91,6 +131,19 @@ run_stdin(void) { process_source(&sv); + // Check if there were any errors. + if (errors_n != 0) { + for (size_t i = 0; i < errors_n; i++) { + Error err = errors[i]; + printf("stdin"); + if (err.line != 0) { + printf(":%ld:%ld: ", err.line, err.col); + } + printf("%s\n", error_msgs[err.value]); + } + errors_n = 0; + } + free(source); } -- cgit v1.2.1