This commit is contained in:
Dominic Grimm 2022-12-22 18:05:42 +01:00
parent d8cff2488a
commit 0019e3278e
No known key found for this signature in database
GPG Key ID: 6F294212DEAAC530
5 changed files with 103 additions and 36 deletions

1
.gitignore vendored
View File

@ -1 +1,2 @@
build/
.vscode/

View File

@ -1,8 +0,0 @@
{
"files.associations": {
"*.lock": "yarnlock",
".shards.info": "yaml",
".graphqlconfig": "json",
"stdbool.h": "c"
}
}

View File

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

View File

@ -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){
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;
interpreter->call_stack[interpreter->call_stack_len++] = word;
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)
{
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;

View File

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