#include #include #include #include #include "hydroforth/hydroforth.h" unsigned int hydroforth__hash_string(const char *const key, unsigned char len) { unsigned char i = 0; unsigned int hash = 0; while (i < len) { hash += key[i++]; hash += hash << 10; hash ^= hash >> 6; } hash += hash << 3; hash ^= hash >> 11; hash += hash << 15; 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 (!hydroforth__is_space(interpreter->src[interpreter->pos]) && interpreter->src[interpreter->pos] != '\n' && interpreter->src[interpreter->pos]) { len++; interpreter->pos++; } if (len == 1) { if (hydroforth__number__is_digit(interpreter->src[start])) { interpreter->call_stack[interpreter->call_stack_len++] = (HYDROFORTH__WORD){ .type = PUSH, .data = {.number = interpreter->src[start] - '0'}, }; } else { 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 { const bool next_is_digit = hydroforth__number__is_digit(interpreter->src[start + 1]); if (next_is_digit && interpreter->src[start] == '-') { int n; if (!hydroforth__number__parse_number(interpreter->src + start + 1, len - 1, &n)) { fputs("Error parsing number!", stderr); return false; } interpreter->call_stack[interpreter->call_stack_len++] = (HYDROFORTH__WORD){ .type = PUSH, .data = {.number = -n}, }; } else if (next_is_digit && interpreter->src[start] == '+') { int n; if (!hydroforth__number__parse_number(interpreter->src + start + 1, len - 1, &n)) { fputs("Error parsing number!", stderr); return false; } interpreter->call_stack[interpreter->call_stack_len++] = (HYDROFORTH__WORD){ .type = PUSH, .data = {.number = n}, }; } else if (hydroforth__number__is_digit(interpreter->src[start])) { int n; if (!hydroforth__number__parse_number(interpreter->src + start, len, &n)) { fputs("Error parsing number!", stderr); return false; } interpreter->call_stack[interpreter->call_stack_len++] = (HYDROFORTH__WORD){ .type = PUSH, .data = {.number = n}, }; } else { 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; } } } return true; } bool hydroforth__run_call_stack(HYDROFORTH__INTERPRETER *interpreter) { for (unsigned char i = interpreter->call_stack_len; i > 0; interpreter->call_stack_len--, i--) { const HYDROFORTH__WORD *word = interpreter->call_stack + i - 1; switch (word->type) { case PUSH: interpreter->stack[interpreter->stack_len++] = word->data.number; break; 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: break; } break; case WORD: printf("HASH: 0x%x\n", word->data.hash); switch (word->data.hash) { case 0xaddd94c: // debug break; default: break; } break; } } return true; } bool hydroforth__run(HYDROFORTH__INTERPRETER *interpreter) { while (true) { 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; } if (!hydroforth__parse(interpreter)) { return false; } if (!hydroforth__run_call_stack(interpreter)) { return false; } } }