diff --git a/include/hydroforth/hydroforth.h b/include/hydroforth/hydroforth.h index 8cfee80..9ab96f2 100644 --- a/include/hydroforth/hydroforth.h +++ b/include/hydroforth/hydroforth.h @@ -6,7 +6,7 @@ #include "result.h" #include "number.h" -extern unsigned int hydroforth__hash_string(const char *const key, unsigned char len); +extern unsigned hydroforth__hash_string(const char *const key, unsigned char len); extern bool hydroforth__is_space(char c); @@ -33,6 +33,7 @@ typedef struct HYDROFORTH__WORD typedef struct HYDROFORTH__WORD_DEFINITION { HYDROFORTH__WORD *words; + unsigned char words_len; } HYDROFORTH__WORD_DEFINITION; typedef struct HYDROFORTH__WORD_DEFINITION_BASE_KEY @@ -58,10 +59,10 @@ typedef struct HYDROFORTH__INTERPRETER unsigned long pos; HYDROFORTH__WORD_DEFINITION_SINGLE_CHAR_WORD_KEY single_char_word_keys[32]; unsigned char single_char_word_keys_len; + HYDROFORTH__WORD_DEFINITION_WORD_KEY word_keys[256]; unsigned short word_keys_len; - unsigned short word_keys_max_len; - HYDROFORTH__WORD_DEFINITION_WORD_KEY *word_keys; - HYDROFORTH__WORD_DEFINITION word_definitions[256]; + HYDROFORTH__WORD_DEFINITION word_definitions[256 + 32]; + unsigned short word_definitions_len; HYDROFORTH__WORD call_stack[256]; unsigned char call_stack_len; int stack[256]; @@ -76,23 +77,26 @@ typedef struct HYDROFORTH__SCAN_NEXT_WORD_RESULT extern HYDROFORTH__SCAN_NEXT_WORD_RESULT hydroforth__scan_next_word(HYDROFORTH__INTERPRETER *interpreter); -extern void hydroforth__parse(HYDROFORTH__RESULT *const result, HYDROFORTH__INTERPRETER *interpreter); +extern void hydroforth__add_word_to_word_definition(HYDROFORTH__WORD_DEFINITION *word_def, HYDROFORTH__WORD word); -extern void hydroforth__run_call_stack(HYDROFORTH__RESULT *const result, HYDROFORTH__INTERPRETER *interpreter); +extern void hydroforth__parse(HYDROFORTH__RESULT *result, HYDROFORTH__INTERPRETER *interpreter, HYDROFORTH__WORD_DEFINITION *word_def); -extern void hydroforth__run(HYDROFORTH__RESULT *const result, HYDROFORTH__INTERPRETER *interpreter); +extern void hydroforth__run_call_stack(HYDROFORTH__RESULT *result, HYDROFORTH__INTERPRETER *interpreter); + +extern void hydroforth__run(HYDROFORTH__RESULT *result, HYDROFORTH__INTERPRETER *interpreter); typedef struct __HYDROFORTH { __HYDROFORTH__RESULT result; __HYDROFORTH__NUMBER number; - unsigned int (*hash_string)(const char *const key, unsigned char len); + unsigned (*hash_string)(const char *const key, unsigned char len); bool (*is_space)(char c); HYDROFORTH__SCAN_NEXT_WORD_RESULT(*scan_next_word) (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); + void (*add_word_to_word_definition)(HYDROFORTH__WORD_DEFINITION *word_def, HYDROFORTH__WORD word); + void (*parse)(HYDROFORTH__RESULT *result, HYDROFORTH__INTERPRETER *interpreter, HYDROFORTH__WORD_DEFINITION *word_def); + void (*run_call_stack)(HYDROFORTH__RESULT *result, HYDROFORTH__INTERPRETER *interpreter); + void (*run)(HYDROFORTH__RESULT *result, HYDROFORTH__INTERPRETER *interpreter); } __HYDROFORTH; static const __HYDROFORTH hydroforth = { @@ -111,6 +115,7 @@ static const __HYDROFORTH hydroforth = { .hash_string = hydroforth__hash_string, .is_space = hydroforth__is_space, .scan_next_word = hydroforth__scan_next_word, + .add_word_to_word_definition = hydroforth__add_word_to_word_definition, .parse = hydroforth__parse, .run_call_stack = hydroforth__run_call_stack, .run = hydroforth__run, diff --git a/include/hydroforth/result.h b/include/hydroforth/result.h index 0a9191d..5202727 100644 --- a/include/hydroforth/result.h +++ b/include/hydroforth/result.h @@ -12,6 +12,7 @@ typedef enum HYDROFORTH__RESULT__ERROR ERR_UNKNOWN_WORD, ERR_UNTERMINATED_WORD_DEFINITION, ERR_WORD_NAME_CANT_BE_NUMBER, + ERR_WORD_DEF_INSIDE_WORD_DEF, } HYDROFORTH__RESULT__ERROR; typedef HYDROFORTH__RESULT__ERROR HYDROFORTH__ERROR; diff --git a/src/hydroforth/hydroforth.c b/src/hydroforth/hydroforth.c index 1d6dc19..f927947 100644 --- a/src/hydroforth/hydroforth.c +++ b/src/hydroforth/hydroforth.c @@ -1,13 +1,14 @@ #include #include #include +#include #include "hydroforth/hydroforth.h" -unsigned int hydroforth__hash_string(const char *const key, unsigned char len) +unsigned hydroforth__hash_string(const char *const key, unsigned char len) { unsigned char i = 0; - unsigned int hash = 0; + unsigned hash = 0; while (i < len) { hash += key[i++]; @@ -42,24 +43,34 @@ HYDROFORTH__SCAN_NEXT_WORD_RESULT hydroforth__scan_next_word(HYDROFORTH__INTERPR }; } -void hydroforth__parse(HYDROFORTH__RESULT *const result, HYDROFORTH__INTERPRETER *interpreter) +void hydroforth__add_word_to_word_definition(HYDROFORTH__WORD_DEFINITION *word_def, HYDROFORTH__WORD word) +{ + word_def->words = realloc(word_def->words, sizeof(HYDROFORTH__WORD) * (word_def->words_len + 1)); + word_def->words[word_def->words_len++] = word; +} + +void hydroforth__parse(HYDROFORTH__RESULT *result, HYDROFORTH__INTERPRETER *interpreter, HYDROFORTH__WORD_DEFINITION *word_def) { - // const unsigned long start = interpreter->pos; - // unsigned char len = 0; - // while (!hydroforth__is_space(interpreter->src[interpreter->pos]) && interpreter->src[interpreter->pos] != '\n' && interpreter->src[interpreter->pos]) - // { - // len++; - // interpreter->pos++; - // } const HYDROFORTH__SCAN_NEXT_WORD_RESULT res = hydroforth__scan_next_word(interpreter); if (res.len == 1) { if (hydroforth__number__is_digit(interpreter->src[res.start])) { - interpreter->call_stack[interpreter->call_stack_len++] = (HYDROFORTH__WORD){ - .type = PUSH, - .data = {.number = interpreter->src[res.start] - '0'}, - }; + int n = interpreter->src[res.start] - '0'; + if (word_def == NULL) + { + interpreter->call_stack[interpreter->call_stack_len++] = (HYDROFORTH__WORD){ + .type = PUSH, + .data = {.number = n}, + }; + } + else + { + hydroforth__add_word_to_word_definition(word_def, (HYDROFORTH__WORD){ + .type = PUSH, + .data = {.number = n}, + }); + } } else { @@ -88,6 +99,13 @@ void hydroforth__parse(HYDROFORTH__RESULT *const result, HYDROFORTH__INTERPRETER } case ':': + { + if (word_def != NULL) + { + hydroforth__set_func_result(result, ERR_WORD_DEF_INSIDE_WORD_DEF); + return; + } + printf("WORD DEFINITION\n"); do { @@ -95,27 +113,55 @@ void hydroforth__parse(HYDROFORTH__RESULT *const result, HYDROFORTH__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; 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; 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); + for (unsigned char i = 0; i < name_scan_res.len; i++) + { + putchar(interpreter->src[name_scan_res.start + i]); + } + putchar('\n'); + if (name_scan_res.len == 1) + { + } + else + { + unsigned hash = hydroforth__hash_string(interpreter->src + name_scan_res.start, name_scan_res.len); + printf("HASH: 0x%x\n", hash); + interpreter->word_definitions[interpreter->word_definitions_len] = (HYDROFORTH__WORD_DEFINITION){ + .words = malloc(0), + .words_len = 0, + }; + interpreter->word_keys[interpreter->word_keys_len++] = (HYDROFORTH__WORD_DEFINITION_WORD_KEY){ + .hash = hash, + .key = {.word_definition_index = interpreter->word_definitions_len++}, + }; + } break; + } default: - interpreter->call_stack[interpreter->call_stack_len++] = (HYDROFORTH__WORD){ - .type = CHAR_WORD, - .data = {.char_word = interpreter->src[res.start]}, - }; + if (word_def == NULL) + { + interpreter->call_stack[interpreter->call_stack_len++] = (HYDROFORTH__WORD){ + .type = CHAR_WORD, + .data = {.char_word = interpreter->src[res.start]}, + }; + } + else + { + hydroforth__add_word_to_word_definition(word_def, (HYDROFORTH__WORD){ + .type = CHAR_WORD, + .data = {.char_word = interpreter->src[res.start]}, + }); + } break; } } @@ -129,13 +175,22 @@ void hydroforth__parse(HYDROFORTH__RESULT *const result, HYDROFORTH__INTERPRETER if (result->error) { hydroforth__add_func_backtrace(result); - fputs("Error parsing number!\n", stderr); return; } - interpreter->call_stack[interpreter->call_stack_len++] = (HYDROFORTH__WORD){ - .type = PUSH, - .data = {.number = -n}, - }; + if (word_def == NULL) + { + interpreter->call_stack[interpreter->call_stack_len++] = (HYDROFORTH__WORD){ + .type = PUSH, + .data = {.number = -n}, + }; + } + else + { + hydroforth__add_word_to_word_definition(word_def, (HYDROFORTH__WORD){ + .type = PUSH, + .data = {.number = -n}, + }); + } } else if (next_is_digit && interpreter->src[res.start] == '+') { @@ -143,13 +198,22 @@ void hydroforth__parse(HYDROFORTH__RESULT *const result, HYDROFORTH__INTERPRETER if (result->error) { hydroforth__add_func_backtrace(result); - fputs("Error parsing number!\n", stderr); return; } - interpreter->call_stack[interpreter->call_stack_len++] = (HYDROFORTH__WORD){ - .type = PUSH, - .data = {.number = n}, - }; + if (word_def == NULL) + { + interpreter->call_stack[interpreter->call_stack_len++] = (HYDROFORTH__WORD){ + .type = PUSH, + .data = {.number = n}, + }; + } + else + { + hydroforth__add_word_to_word_definition(word_def, (HYDROFORTH__WORD){ + .type = PUSH, + .data = {.number = n}, + }); + } } else if (hydroforth__number__is_digit(interpreter->src[res.start])) { @@ -157,17 +221,26 @@ void hydroforth__parse(HYDROFORTH__RESULT *const result, HYDROFORTH__INTERPRETER if (result->error) { hydroforth__add_func_backtrace(result); - fputs("Error parsing number!\n", stderr); return; } - interpreter->call_stack[interpreter->call_stack_len++] = (HYDROFORTH__WORD){ - .type = PUSH, - .data = {.number = n}, - }; + if (word_def == NULL) + { + interpreter->call_stack[interpreter->call_stack_len++] = (HYDROFORTH__WORD){ + .type = PUSH, + .data = {.number = n}, + }; + } + else + { + hydroforth__add_word_to_word_definition(word_def, (HYDROFORTH__WORD){ + .type = PUSH, + .data = {.number = n}, + }); + } } else { - const unsigned int hash = hydroforth__hash_string(interpreter->src + res.start, res.len); + const unsigned hash = hydroforth__hash_string(interpreter->src + res.start, res.len); switch (hash) { case 0x4078cde9: // -- @@ -178,17 +251,27 @@ void hydroforth__parse(HYDROFORTH__RESULT *const result, HYDROFORTH__INTERPRETER break; default: - interpreter->call_stack[interpreter->call_stack_len++] = (HYDROFORTH__WORD){ - .type = WORD, - .data = {.hash = hash}, - }; + if (word_def == NULL) + { + interpreter->call_stack[interpreter->call_stack_len++] = (HYDROFORTH__WORD){ + .type = WORD, + .data = {.hash = hash}, + }; + } + else + { + hydroforth__add_word_to_word_definition(word_def, (HYDROFORTH__WORD){ + .type = WORD, + .data = {.hash = hash}, + }); + } break; } } } } -void hydroforth__run_call_stack(HYDROFORTH__RESULT *const result, HYDROFORTH__INTERPRETER *interpreter) +void hydroforth__run_call_stack(HYDROFORTH__RESULT *result, HYDROFORTH__INTERPRETER *interpreter) { for (unsigned char i = interpreter->call_stack_len; i > 0; interpreter->call_stack_len--, i--) { @@ -280,7 +363,7 @@ void hydroforth__run_call_stack(HYDROFORTH__RESULT *const result, HYDROFORTH__IN } } -void hydroforth__run(HYDROFORTH__RESULT *const result, HYDROFORTH__INTERPRETER *interpreter) +void hydroforth__run(HYDROFORTH__RESULT *result, HYDROFORTH__INTERPRETER *interpreter) { while (true) { @@ -292,7 +375,7 @@ void hydroforth__run(HYDROFORTH__RESULT *const result, HYDROFORTH__INTERPRETER * { return; } - hydroforth__parse(result, interpreter); + hydroforth__parse(result, interpreter, NULL); if (result->error) { hydroforth__add_func_backtrace(result); diff --git a/src/hydroforth/result.c b/src/hydroforth/result.c index 55f5ef9..d963100 100644 --- a/src/hydroforth/result.c +++ b/src/hydroforth/result.c @@ -37,6 +37,9 @@ const char *hydroforth__result__get_error_message(HYDROFORTH__ERROR error) case ERR_WORD_NAME_CANT_BE_NUMBER: return "Word name can't be a number"; + case ERR_WORD_DEF_INSIDE_WORD_DEF: + return "Can't define a word inside a word definition"; + default: return "???"; } diff --git a/src/main.c b/src/main.c index 9dcb77f..384ca69 100644 --- a/src/main.c +++ b/src/main.c @@ -1,9 +1,6 @@ -#include #include #include - -#define UNW_LOCAL_ONLY -#include +#include #include "hydroforth/hydroforth.h" @@ -60,7 +57,7 @@ int main(int argc, char *argv[]) fputs("No source file specified!\n", stderr); return 1; } - FILE *fp = fopen(argv[1], "rb"); + FILE *fp = fopen(argv[1], "r"); if (fp == NULL) { fputs("Error opening file!\n", stderr); @@ -75,11 +72,11 @@ int main(int argc, char *argv[]) .pos = 0, .single_char_word_keys_len = 0, .word_keys_len = 0, - .word_keys_max_len = 0, + .word_definitions_len = 0, }; HYDROFORTH__RESULT result = {.error = OK, .backtrace_len = 0}; hydroforth.run(&result, &interpreter); - free(res.src); + free(interpreter.src); if (result.error) { hydroforth__add_func_backtrace(&result); diff --git a/test.fth b/test.fth index 94b0723..08597e0 100644 --- a/test.fth +++ b/test.fth @@ -1,2 +1,2 @@ -\ : test 42 ; +: test 42 ; 40 2 + debug