Init
This commit is contained in:
parent
d8cff2488a
commit
0019e3278e
5 changed files with 103 additions and 36 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -1 +1,2 @@
|
|||
build/
|
||||
.vscode/
|
||||
|
|
8
.vscode/settings.json
vendored
8
.vscode/settings.json
vendored
|
@ -1,8 +0,0 @@
|
|||
{
|
||||
"files.associations": {
|
||||
"*.lock": "yarnlock",
|
||||
".shards.info": "yaml",
|
||||
".graphqlconfig": "json",
|
||||
"stdbool.h": "c"
|
||||
}
|
||||
}
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Reference in a new issue