From bd9b51be9af32014bbe7b125ec836a303990a6f4 Mon Sep 17 00:00:00 2001 From: Dominic Grimm Date: Fri, 23 Dec 2022 17:16:29 +0100 Subject: [PATCH] Update --- include/hydroforth/hydroforth.h | 13 ++++--- include/hydroforth/number.h | 12 +++--- include/hydroforth/result.h | 14 +++++-- src/hydroforth/hydroforth.c | 66 ++++++++++++++++++--------------- src/hydroforth/number.c | 62 ++++++++++++++----------------- src/hydroforth/result.c | 47 ++++++++++++++++++++++- src/main.c | 11 ++++-- test.fth | 2 +- 8 files changed, 142 insertions(+), 85 deletions(-) diff --git a/include/hydroforth/hydroforth.h b/include/hydroforth/hydroforth.h index 1201029..8cfee80 100644 --- a/include/hydroforth/hydroforth.h +++ b/include/hydroforth/hydroforth.h @@ -76,11 +76,11 @@ typedef struct HYDROFORTH__SCAN_NEXT_WORD_RESULT extern HYDROFORTH__SCAN_NEXT_WORD_RESULT hydroforth__scan_next_word(HYDROFORTH__INTERPRETER *interpreter); -extern bool hydroforth__parse(HYDROFORTH__INTERPRETER *interpreter); +extern void hydroforth__parse(HYDROFORTH__RESULT *const result, HYDROFORTH__INTERPRETER *interpreter); -extern bool hydroforth__run_call_stack(HYDROFORTH__INTERPRETER *interpreter); +extern void hydroforth__run_call_stack(HYDROFORTH__RESULT *const result, HYDROFORTH__INTERPRETER *interpreter); -extern bool hydroforth__run(HYDROFORTH__INTERPRETER *interpreter); +extern void hydroforth__run(HYDROFORTH__RESULT *const result, HYDROFORTH__INTERPRETER *interpreter); typedef struct __HYDROFORTH { @@ -90,15 +90,16 @@ typedef struct __HYDROFORTH bool (*is_space)(char c); HYDROFORTH__SCAN_NEXT_WORD_RESULT(*scan_next_word) (HYDROFORTH__INTERPRETER *interpreter); - bool (*parse)(HYDROFORTH__INTERPRETER *interpreter); - bool (*run_call_stack)(HYDROFORTH__INTERPRETER *interpreter); - bool (*run)(HYDROFORTH__INTERPRETER *interpreter); + void (*parse)(HYDROFORTH__RESULT *const result, HYDROFORTH__INTERPRETER *interpreter); + void (*run_call_stack)(HYDROFORTH__RESULT *const result, HYDROFORTH__INTERPRETER *interpreter); + void (*run)(HYDROFORTH__RESULT *const result, HYDROFORTH__INTERPRETER *interpreter); } __HYDROFORTH; static const __HYDROFORTH hydroforth = { .result = { .add_backtrace = hydroforth__result__add_backtrace, .get_error_message = hydroforth__result__get_error_message, + .unwrap = hydroforth__result__unwrap, }, .number = { .is_digit = hydroforth__number__is_digit, diff --git a/include/hydroforth/number.h b/include/hydroforth/number.h index cb8773e..891c528 100644 --- a/include/hydroforth/number.h +++ b/include/hydroforth/number.h @@ -3,20 +3,20 @@ extern bool hydroforth__number__is_digit(char c); -extern void hydroforth__number__convert_hex_digit(HYDROFORTH__RESULT *const result, char c, unsigned char *const val); +extern unsigned char hydroforth__number__convert_hex_digit(HYDROFORTH__RESULT *const result, char c); -extern void hydroforth__number__parse_number_hex(HYDROFORTH__RESULT *const result, const char *const start, unsigned char len, int *const val); +extern int hydroforth__number__parse_number_hex(HYDROFORTH__RESULT *const result, const char *const start, unsigned char len); -extern void hydroforth__number__parse_number(HYDROFORTH__RESULT *const result, const char *const start, unsigned char len, int *const val); +extern int hydroforth__number__parse_number(HYDROFORTH__RESULT *const result, const char *const start, unsigned char len); extern unsigned char hydroforth__number__count_digits(int n); typedef struct __HYDROFORTH__NUMBER { bool (*is_digit)(char c); - void (*convert_hex_digit)(HYDROFORTH__RESULT *const result, char c, unsigned char *const val); - void (*parse_number_hex)(HYDROFORTH__RESULT *const result, const char *const start, unsigned char len, int *const val); - void (*parse_number)(HYDROFORTH__RESULT *const result, const char *const start, unsigned char len, int *const val); + unsigned char (*convert_hex_digit)(HYDROFORTH__RESULT *const result, char c); + int (*parse_number_hex)(HYDROFORTH__RESULT *const result, const char *const start, unsigned char len); + int (*parse_number)(HYDROFORTH__RESULT *const result, const char *const start, unsigned char len); unsigned char (*count_digits)(int n); } __HYDROFORTH__NUMBER; diff --git a/include/hydroforth/result.h b/include/hydroforth/result.h index 0d0adf6..0a9191d 100644 --- a/include/hydroforth/result.h +++ b/include/hydroforth/result.h @@ -3,10 +3,15 @@ typedef enum HYDROFORTH__RESULT__ERROR { - OK, + OK = 0, ERR_UNKNOWN, + ERR_INVALID_HEX_CHAR, + ERR_UNKNOWN_SINGLE_CHAR_WORD, + ERR_UNKNOWN_WORD, + ERR_UNTERMINATED_WORD_DEFINITION, + ERR_WORD_NAME_CANT_BE_NUMBER, } HYDROFORTH__RESULT__ERROR; typedef HYDROFORTH__RESULT__ERROR HYDROFORTH__ERROR; @@ -14,8 +19,8 @@ typedef HYDROFORTH__RESULT__ERROR HYDROFORTH__ERROR; typedef struct HYDROFORTH__RESULT__RESULT { HYDROFORTH__ERROR error; - char **const backtrace; - unsigned backtrace_len; + const char **backtrace; + unsigned short backtrace_len; } HYDROFORTH__RESULT__RESULT; typedef HYDROFORTH__RESULT__RESULT HYDROFORTH__RESULT; @@ -30,11 +35,14 @@ extern const char *hydroforth__result__get_error_message(HYDROFORTH__ERROR error #define hydroforth__add_func_backtrace(result) hydroforth__result__add_backtrace(result, __func__); +extern int hydroforth__result__unwrap(HYDROFORTH__RESULT *const result, int code); + typedef struct __HYDROFORTH__RESULT { void (*add_backtrace)(HYDROFORTH__RESULT *const result, const char *const s); void (*set)(HYDROFORTH__RESULT *const result, HYDROFORTH__ERROR error, const char *const s); const char *(*get_error_message)(HYDROFORTH__ERROR error); + int (*unwrap)(HYDROFORTH__RESULT *const result, int code); } __HYDROFORTH__RESULT; #endif diff --git a/src/hydroforth/hydroforth.c b/src/hydroforth/hydroforth.c index 2cde17c..1d6dc19 100644 --- a/src/hydroforth/hydroforth.c +++ b/src/hydroforth/hydroforth.c @@ -1,6 +1,5 @@ #include #include -#include #include #include "hydroforth/hydroforth.h" @@ -43,7 +42,7 @@ HYDROFORTH__SCAN_NEXT_WORD_RESULT hydroforth__scan_next_word(HYDROFORTH__INTERPR }; } -bool hydroforth__parse(HYDROFORTH__INTERPRETER *interpreter) +void hydroforth__parse(HYDROFORTH__RESULT *const result, HYDROFORTH__INTERPRETER *interpreter) { // const unsigned long start = interpreter->pos; // unsigned char len = 0; @@ -96,13 +95,17 @@ bool hydroforth__parse(HYDROFORTH__INTERPRETER *interpreter) } while (hydroforth__is_space(interpreter->src[interpreter->pos]) || interpreter->src[interpreter->pos] == '\n'); if (!interpreter->src[interpreter->pos]) { - fputs("Unterminated word definition!\n", stderr); - return false; + // fputs("Unterminated word definition!\n", stderr); + // return false; + hydroforth__set_func_result(result, ERR_UNTERMINATED_WORD_DEFINITION); + return; } if (hydroforth__number__is_digit(interpreter->src[interpreter->pos])) { - fputs("Word name cannot be a number!\n", stderr); - return false; + // fputs("Word name cannot be a number!\n", stderr); + // return false; + hydroforth__set_func_result(result, ERR_WORD_NAME_CANT_BE_NUMBER); + return; } const HYDROFORTH__SCAN_NEXT_WORD_RESULT name_scan_res = hydroforth__scan_next_word(interpreter); @@ -122,11 +125,12 @@ bool hydroforth__parse(HYDROFORTH__INTERPRETER *interpreter) const bool next_is_digit = hydroforth__number__is_digit(interpreter->src[res.start + 1]); if (next_is_digit && interpreter->src[res.start] == '-') { - int n; - if (!hydroforth__number__parse_number(interpreter->src + res.start + 1, res.len - 1, &n)) + int n = hydroforth__number__parse_number(result, interpreter->src + res.start + 1, res.len - 1); + if (result->error) { + hydroforth__add_func_backtrace(result); fputs("Error parsing number!\n", stderr); - return false; + return; } interpreter->call_stack[interpreter->call_stack_len++] = (HYDROFORTH__WORD){ .type = PUSH, @@ -135,11 +139,12 @@ bool hydroforth__parse(HYDROFORTH__INTERPRETER *interpreter) } else if (next_is_digit && interpreter->src[res.start] == '+') { - int n; - if (!hydroforth__number__parse_number(interpreter->src + res.start + 1, res.len - 1, &n)) + int n = hydroforth__number__parse_number(result, interpreter->src + res.start + 1, res.len - 1); + if (result->error) { + hydroforth__add_func_backtrace(result); fputs("Error parsing number!\n", stderr); - return false; + return; } interpreter->call_stack[interpreter->call_stack_len++] = (HYDROFORTH__WORD){ .type = PUSH, @@ -148,11 +153,12 @@ bool hydroforth__parse(HYDROFORTH__INTERPRETER *interpreter) } else if (hydroforth__number__is_digit(interpreter->src[res.start])) { - int n; - if (!hydroforth__number__parse_number(interpreter->src + res.start, res.len, &n)) + int n = hydroforth__number__parse_number(result, interpreter->src + res.start, res.len); + if (result->error) { + hydroforth__add_func_backtrace(result); fputs("Error parsing number!\n", stderr); - return false; + return; } interpreter->call_stack[interpreter->call_stack_len++] = (HYDROFORTH__WORD){ .type = PUSH, @@ -180,11 +186,9 @@ bool hydroforth__parse(HYDROFORTH__INTERPRETER *interpreter) } } } - - return true; } -bool hydroforth__run_call_stack(HYDROFORTH__INTERPRETER *interpreter) +void hydroforth__run_call_stack(HYDROFORTH__RESULT *const result, HYDROFORTH__INTERPRETER *interpreter) { for (unsigned char i = interpreter->call_stack_len; i > 0; interpreter->call_stack_len--, i--) { @@ -219,8 +223,8 @@ bool hydroforth__run_call_stack(HYDROFORTH__INTERPRETER *interpreter) break; default: - fprintf(stderr, "Unknown word: '%c'\n", word->data.char_word); - return false; + hydroforth__set_func_result(result, ERR_UNKNOWN_SINGLE_CHAR_WORD); + return; } break; @@ -268,17 +272,15 @@ bool hydroforth__run_call_stack(HYDROFORTH__INTERPRETER *interpreter) break; default: - fprintf(stderr, "Unknown word with hash: 0x%x\n", word->data.hash); - return false; + hydroforth__set_func_result(result, ERR_UNKNOWN_WORD); + return; } break; } } - - return true; } -bool hydroforth__run(HYDROFORTH__INTERPRETER *interpreter) +void hydroforth__run(HYDROFORTH__RESULT *const result, HYDROFORTH__INTERPRETER *interpreter) { while (true) { @@ -288,15 +290,19 @@ bool hydroforth__run(HYDROFORTH__INTERPRETER *interpreter) } if (!interpreter->src[interpreter->pos]) { - return true; + return; } - if (!hydroforth__parse(interpreter)) + hydroforth__parse(result, interpreter); + if (result->error) { - return false; + hydroforth__add_func_backtrace(result); + return; } - if (!hydroforth__run_call_stack(interpreter)) + hydroforth__run_call_stack(result, interpreter); + if (result->error) { - return false; + hydroforth__add_func_backtrace(result); + return; } } } diff --git a/src/hydroforth/number.c b/src/hydroforth/number.c index 8ce0d41..71d7df7 100644 --- a/src/hydroforth/number.c +++ b/src/hydroforth/number.c @@ -1,6 +1,5 @@ #include #include -#include #include "hydroforth/hydroforth.h" @@ -9,11 +8,11 @@ bool hydroforth__number__is_digit(char c) return '0' <= c && c <= '9'; } -void hydroforth__number__convert_hex_digit(HYDROFORTH__RESULT *const result, char c, unsigned char *const val) +unsigned char hydroforth__number__convert_hex_digit(HYDROFORTH__RESULT *const result, char c) { if (hydroforth__number__is_digit(c)) { - *val = c - '0'; + return c - '0'; } else { @@ -21,33 +20,27 @@ void hydroforth__number__convert_hex_digit(HYDROFORTH__RESULT *const result, cha { case 'A': case 'a': - *val = 0xa; - break; + return 0xa; case 'B': case 'b': - *val = 0xb; - break; + return 0xb; case 'C': case 'c': - *val = 0xc; - break; + return 0xc; case 'D': case 'd': - *val = 0xd; - break; + return 0xd; case 'E': case 'e': - *val = 0xe; - break; + return 0xe; case 'F': case 'f': - *val = 0xf; - break; + return 0xf; default: // hydroforth__result__set(result, ERR_INVALID_HEX_CHAR, __func__); @@ -57,30 +50,25 @@ void hydroforth__number__convert_hex_digit(HYDROFORTH__RESULT *const result, cha } } -void hydroforth__number__parse_number_hex(HYDROFORTH__RESULT *const result, const char *const start, unsigned char len, int *const val) +int hydroforth__number__parse_number_hex(HYDROFORTH__RESULT *const result, const char *const start, unsigned char len) { - int n; + int n = 0; for (unsigned char i = 0; i < len; i++) { - unsigned char m; - // if (!hydroforth__number__convert_hex_digit(result, start[i], &m)) - // { - // return false; - // } - hydroforth__number__convert_hex_digit(result, start[i], &m); - if (result->error != OK) + unsigned char m = hydroforth__number__convert_hex_digit(result, start[i]); + if (result->error) { hydroforth__add_func_backtrace(result); - return; + return 0; } n *= 16; n += m; } - return true; + return n; } -void hydroforth__number__parse_number(HYDROFORTH__RESULT *const result, const char *const start, unsigned char len, int *const val) +int hydroforth__number__parse_number(HYDROFORTH__RESULT *const result, const char *const start, unsigned char len) { if (start[0] == '0') { @@ -90,25 +78,29 @@ void hydroforth__number__parse_number(HYDROFORTH__RESULT *const result, const ch { case 'X': case 'x': - hydroforth__number__parse_number_hex(result, start + 2, len - 2, val); - if (result->error != OK) + { + int n = hydroforth__number__parse_number_hex(result, start + 2, len - 2); + if (result->error) { hydroforth__add_func_backtrace(result); } - break; + return n; + } default: - hydroforth__number__parse_number(result, start + 1, len - 1, val); - if (result->error != OK) + { + int n = hydroforth__number__parse_number(result, start + 1, len - 1); + if (result->error) { hydroforth__add_func_backtrace(result); } - break; + return n; + } } } else { - *val = 0; + return 0; } } else @@ -119,7 +111,7 @@ void hydroforth__number__parse_number(HYDROFORTH__RESULT *const result, const ch n *= 10; n += start[i] - '0'; } - *val = n; + return n; } } diff --git a/src/hydroforth/result.c b/src/hydroforth/result.c index fc702f4..55f5ef9 100644 --- a/src/hydroforth/result.c +++ b/src/hydroforth/result.c @@ -1,8 +1,10 @@ +#include + #include "hydroforth/hydroforth.h" void hydroforth__result__add_backtrace(HYDROFORTH__RESULT *const result, const char *const s) { - realloc(result->backtrace, sizeof(char *) * (result->backtrace_len + 1)); + result->backtrace = realloc(result->backtrace, sizeof(char *) * (result->backtrace_len + 1)); result->backtrace[result->backtrace_len++] = s; } @@ -11,3 +13,46 @@ void hydroforth__result__set(HYDROFORTH__RESULT *const result, HYDROFORTH__ERROR result->error = error; hydroforth__result__add_backtrace(result, s); } + +const char *hydroforth__result__get_error_message(HYDROFORTH__ERROR error) +{ + switch (error) + { + case OK: + return "OK"; + + case ERR_UNKNOWN: + return "Unknown error"; + + case ERR_INVALID_HEX_CHAR: + return "Invalid hexadecimal char in number"; + + case ERR_UNKNOWN_SINGLE_CHAR_WORD: + case ERR_UNKNOWN_WORD: + return "Unknown word"; + + case ERR_UNTERMINATED_WORD_DEFINITION: + return "Unterminated word definition"; + + case ERR_WORD_NAME_CANT_BE_NUMBER: + return "Word name can't be a number"; + + default: + return "???"; + } +} + +int hydroforth__result__unwrap(HYDROFORTH__RESULT *const result, int code) +{ + printf("BACKTRACE LEN: %u\n", result->backtrace_len); + puts("ERROR! Backtrace:"); + printf("Error: %u -> \"%s\"\n", result->error, hydroforth__result__get_error_message(result->error)); + for (unsigned short i = 0; i < result->backtrace_len; i++) + { + printf("%u: %s\n", result->backtrace_len - i - 1, result->backtrace[i]); + } + printf("EXITING with code: %u!\n", code); + free(result->backtrace); + + return code; +} diff --git a/src/main.c b/src/main.c index 3f5759c..9dcb77f 100644 --- a/src/main.c +++ b/src/main.c @@ -2,6 +2,9 @@ #include #include +#define UNW_LOCAL_ONLY +#include + #include "hydroforth/hydroforth.h" struct ReadSrcResult @@ -74,11 +77,13 @@ int main(int argc, char *argv[]) .word_keys_len = 0, .word_keys_max_len = 0, }; - const bool run_res = hydroforth.run(&interpreter); + HYDROFORTH__RESULT result = {.error = OK, .backtrace_len = 0}; + hydroforth.run(&result, &interpreter); free(res.src); - if (!run_res) + if (result.error) { - return 1; + hydroforth__add_func_backtrace(&result); + return hydroforth.result.unwrap(&result, 1); } } else diff --git a/test.fth b/test.fth index 08597e0..94b0723 100644 --- a/test.fth +++ b/test.fth @@ -1,2 +1,2 @@ -: test 42 ; +\ : test 42 ; 40 2 + debug