This commit is contained in:
Dominic Grimm 2022-12-23 17:16:29 +01:00
parent 4e8c187050
commit bd9b51be9a
No known key found for this signature in database
GPG Key ID: 6F294212DEAAC530
8 changed files with 142 additions and 85 deletions

View File

@ -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,

View File

@ -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;

View File

@ -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

View File

@ -1,6 +1,5 @@
#include <stdbool.h>
#include <stdio.h>
#include <malloc.h>
#include <string.h>
#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;
}
}
}

View File

@ -1,6 +1,5 @@
#include <stdbool.h>
#include <stddef.h>
#include <malloc.h>
#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;
}
}

View File

@ -1,8 +1,10 @@
#include <malloc.h>
#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;
}

View File

@ -2,6 +2,9 @@
#include <stdio.h>
#include <stdbool.h>
#define UNW_LOCAL_ONLY
#include <libunwind.h>
#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

View File

@ -1,2 +1,2 @@
: test 42 ;
\ : test 42 ;
40 2 + debug