diff --git a/.gitignore b/.gitignore index 567609b..6f31401 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ build/ +.vscode/ diff --git a/.vscode/settings.json b/.vscode/settings.json deleted file mode 100644 index 0ca8ea8..0000000 --- a/.vscode/settings.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "files.associations": { - "*.lock": "yarnlock", - ".shards.info": "yaml", - ".graphqlconfig": "json", - "stdbool.h": "c" - } -} diff --git a/include/hydroforth/hydroforth.h b/include/hydroforth/hydroforth.h index 4f3edba..f5fc772 100644 --- a/include/hydroforth/hydroforth.h +++ b/include/hydroforth/hydroforth.h @@ -5,7 +5,9 @@ #include "number.h" -extern unsigned int hydroforth__hash_string(const char *const key, unsigned char length); +extern unsigned int hydroforth__hash_string(const char *const key, unsigned char len); + +extern bool hydroforth__is_space(char c); typedef enum HYDROFORTH__WORD_TYPE { @@ -18,7 +20,7 @@ typedef union HYDROFORTH__WORD_DATA { int number; char char_word; - char *word; + unsigned int hash; } HYDROFORTH__WORD_DATA; typedef struct HYDROFORTH__WORD @@ -75,6 +77,7 @@ typedef struct __HYDROFORTH { __HYDROFORTH__NUMBER number; unsigned int (*hash_string)(const char *const key, unsigned char len); + bool (*is_space)(char c); bool (*parse)(HYDROFORTH__INTERPRETER *interpreter); bool (*run_call_stack)(HYDROFORTH__INTERPRETER *interpreter); bool (*run)(HYDROFORTH__INTERPRETER *interpreter); @@ -88,6 +91,7 @@ static const __HYDROFORTH hydroforth = { .parse_number = hydroforth__number__parse_number, }, .hash_string = hydroforth__hash_string, + .is_space = hydroforth__is_space, .parse = hydroforth__parse, .run_call_stack = hydroforth__run_call_stack, .run = hydroforth__run, diff --git a/src/hydroforth/hydroforth.c b/src/hydroforth/hydroforth.c index c72d654..7ec2fc0 100644 --- a/src/hydroforth/hydroforth.c +++ b/src/hydroforth/hydroforth.c @@ -9,7 +9,7 @@ unsigned int hydroforth__hash_string(const char *const key, unsigned char len) { unsigned char i = 0; unsigned int hash = 0; - while (i != len) + while (i < len) { hash += key[i++]; hash += hash << 10; @@ -22,31 +22,62 @@ unsigned int hydroforth__hash_string(const char *const key, unsigned char len) return hash; } +inline bool hydroforth__is_space(char c) +{ + return c == ' ' || c == '\t'; +} + bool hydroforth__parse(HYDROFORTH__INTERPRETER *interpreter) { const unsigned long start = interpreter->pos; unsigned char len = 0; - while (interpreter->src[interpreter->pos] != ' ' && interpreter->src[interpreter->pos] != '\n' && interpreter->src[interpreter->pos]) + while (!hydroforth__is_space(interpreter->src[interpreter->pos]) && interpreter->src[interpreter->pos] != '\n' && interpreter->src[interpreter->pos]) { len++; interpreter->pos++; } - HYDROFORTH__WORD word; if (len == 1) { if (hydroforth__number__is_digit(interpreter->src[start])) { - word = (HYDROFORTH__WORD){ + interpreter->call_stack[interpreter->call_stack_len++] = (HYDROFORTH__WORD){ .type = PUSH, .data = {.number = interpreter->src[start] - '0'}, }; } else { - word = (HYDROFORTH__WORD){ - .type = CHAR_WORD, - .data = {.char_word = interpreter->src[start]}, - }; + switch (interpreter->src[start]) + { + case '\\': + do + { + interpreter->pos++; + } while (interpreter->src[interpreter->pos] != '\n' && interpreter->src[interpreter->pos]); + break; + + case '(': + while (true) + { + interpreter->pos++; + if (interpreter->src[interpreter->pos] == ')' && + (hydroforth__is_space(interpreter->src[interpreter->pos + 1]) || + interpreter->src[interpreter->pos + 1] == '\n' || + interpreter->src[interpreter->pos + 1] == '\0') || + interpreter->src[interpreter->pos] == '\n' || + interpreter->src[interpreter->pos] == '\0') + { + break; + } + } + + default: + interpreter->call_stack[interpreter->call_stack_len++] = (HYDROFORTH__WORD){ + .type = CHAR_WORD, + .data = {.char_word = interpreter->src[start]}, + }; + break; + } } } else @@ -60,7 +91,7 @@ bool hydroforth__parse(HYDROFORTH__INTERPRETER *interpreter) fputs("Error parsing number!", stderr); return false; } - word = (HYDROFORTH__WORD){ + interpreter->call_stack[interpreter->call_stack_len++] = (HYDROFORTH__WORD){ .type = PUSH, .data = {.number = -n}, }; @@ -73,7 +104,7 @@ bool hydroforth__parse(HYDROFORTH__INTERPRETER *interpreter) fputs("Error parsing number!", stderr); return false; } - word = (HYDROFORTH__WORD){ + interpreter->call_stack[interpreter->call_stack_len++] = (HYDROFORTH__WORD){ .type = PUSH, .data = {.number = n}, }; @@ -86,34 +117,40 @@ bool hydroforth__parse(HYDROFORTH__INTERPRETER *interpreter) fputs("Error parsing number!", stderr); return false; } - word = (HYDROFORTH__WORD){ + interpreter->call_stack[interpreter->call_stack_len++] = (HYDROFORTH__WORD){ .type = PUSH, .data = {.number = n}, }; } else { - char *const s = malloc(sizeof(char) * (len + 1)); - strncpy(s, interpreter->src + start, len); - s[len] = '\0'; - word = (HYDROFORTH__WORD){ - .type = WORD, - .data = {.word = s}, - }; + const unsigned int hash = hydroforth__hash_string(interpreter->src + start, len); + switch (hash) + { + case 0x4078cde9: // -- + do + { + interpreter->pos++; + } while (interpreter->src[interpreter->pos] != '\n' && interpreter->src[interpreter->pos]); + break; + + default: + interpreter->call_stack[interpreter->call_stack_len++] = (HYDROFORTH__WORD){ + .type = WORD, + .data = {.hash = hash}, + }; + break; + } } } - interpreter->call_stack[interpreter->call_stack_len++] = word; - return true; } bool hydroforth__run_call_stack(HYDROFORTH__INTERPRETER *interpreter) { - printf("CALL STACK LEN: %u\n", interpreter->call_stack_len); for (unsigned char i = interpreter->call_stack_len; i > 0; interpreter->call_stack_len--, i--) { - printf("TYPE: %u\n", interpreter->call_stack[i - 1].type); const HYDROFORTH__WORD *word = interpreter->call_stack + i - 1; switch (word->type) { @@ -124,7 +161,28 @@ bool hydroforth__run_call_stack(HYDROFORTH__INTERPRETER *interpreter) case CHAR_WORD: switch (word->data.char_word) { + case ':': + printf("WORD DEFINITION\n"); + break; + case '-': + interpreter->stack[interpreter->stack_len - 2] -= interpreter->stack[interpreter->stack_len - 1]; + interpreter->stack_len--; + break; + + case '+': + interpreter->stack[interpreter->stack_len - 2] += interpreter->stack[interpreter->stack_len - 1]; + interpreter->stack_len--; + break; + + case '*': + interpreter->stack[interpreter->stack_len - 2] *= interpreter->stack[interpreter->stack_len - 1]; + interpreter->stack_len--; + break; + + case '/': + interpreter->stack[interpreter->stack_len - 2] /= interpreter->stack[interpreter->stack_len - 1]; + interpreter->stack_len--; break; default: @@ -133,6 +191,15 @@ bool hydroforth__run_call_stack(HYDROFORTH__INTERPRETER *interpreter) break; case WORD: + printf("HASH: 0x%x\n", word->data.hash); + switch (word->data.hash) + { + case 0xaddd94c: // debug + break; + + default: + break; + } break; } } @@ -144,10 +211,14 @@ bool hydroforth__run(HYDROFORTH__INTERPRETER *interpreter) { while (true) { - while (interpreter->src[interpreter->pos] == ' ' || interpreter->src[interpreter->pos] == '\n') + while (hydroforth__is_space(interpreter->src[interpreter->pos]) || interpreter->src[interpreter->pos] == '\n') { interpreter->pos++; } + if (interpreter->src[interpreter->pos] == '\0') + { + return true; + } if (!interpreter->src[interpreter->pos]) { return true; diff --git a/src/main.c b/src/main.c index 28cdb37..fb34790 100644 --- a/src/main.c +++ b/src/main.c @@ -27,7 +27,7 @@ struct ReadSrcResult read_src(FILE *fp) .success = false, }; } - char *const src = malloc(sizeof(char) * (bufsize + 1)); + char *const src = malloc(sizeof(char) * bufsize); if (fseek(fp, 0L, SEEK_SET) != 0) { fputs("Error rewinding file to start!", stderr); @@ -35,7 +35,7 @@ struct ReadSrcResult read_src(FILE *fp) .success = false, }; } - const unsigned long new_len = fread(src, sizeof(char), bufsize, fp); + fread(src, sizeof(char), bufsize, fp); if (ferror(fp) != 0) { fputs("Error reading file!", stderr); @@ -43,7 +43,6 @@ struct ReadSrcResult read_src(FILE *fp) .success = false, }; } - src[new_len + 1] = '\0'; return (struct ReadSrcResult){ .success = true,