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/
|
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"
|
#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
|
typedef enum HYDROFORTH__WORD_TYPE
|
||||||
{
|
{
|
||||||
|
@ -18,7 +20,7 @@ typedef union HYDROFORTH__WORD_DATA
|
||||||
{
|
{
|
||||||
int number;
|
int number;
|
||||||
char char_word;
|
char char_word;
|
||||||
char *word;
|
unsigned int hash;
|
||||||
} HYDROFORTH__WORD_DATA;
|
} HYDROFORTH__WORD_DATA;
|
||||||
|
|
||||||
typedef struct HYDROFORTH__WORD
|
typedef struct HYDROFORTH__WORD
|
||||||
|
@ -75,6 +77,7 @@ typedef struct __HYDROFORTH
|
||||||
{
|
{
|
||||||
__HYDROFORTH__NUMBER number;
|
__HYDROFORTH__NUMBER number;
|
||||||
unsigned int (*hash_string)(const char *const key, unsigned char len);
|
unsigned int (*hash_string)(const char *const key, unsigned char len);
|
||||||
|
bool (*is_space)(char c);
|
||||||
bool (*parse)(HYDROFORTH__INTERPRETER *interpreter);
|
bool (*parse)(HYDROFORTH__INTERPRETER *interpreter);
|
||||||
bool (*run_call_stack)(HYDROFORTH__INTERPRETER *interpreter);
|
bool (*run_call_stack)(HYDROFORTH__INTERPRETER *interpreter);
|
||||||
bool (*run)(HYDROFORTH__INTERPRETER *interpreter);
|
bool (*run)(HYDROFORTH__INTERPRETER *interpreter);
|
||||||
|
@ -88,6 +91,7 @@ static const __HYDROFORTH hydroforth = {
|
||||||
.parse_number = hydroforth__number__parse_number,
|
.parse_number = hydroforth__number__parse_number,
|
||||||
},
|
},
|
||||||
.hash_string = hydroforth__hash_string,
|
.hash_string = hydroforth__hash_string,
|
||||||
|
.is_space = hydroforth__is_space,
|
||||||
.parse = hydroforth__parse,
|
.parse = hydroforth__parse,
|
||||||
.run_call_stack = hydroforth__run_call_stack,
|
.run_call_stack = hydroforth__run_call_stack,
|
||||||
.run = hydroforth__run,
|
.run = hydroforth__run,
|
||||||
|
|
|
@ -9,7 +9,7 @@ unsigned int hydroforth__hash_string(const char *const key, unsigned char len)
|
||||||
{
|
{
|
||||||
unsigned char i = 0;
|
unsigned char i = 0;
|
||||||
unsigned int hash = 0;
|
unsigned int hash = 0;
|
||||||
while (i != len)
|
while (i < len)
|
||||||
{
|
{
|
||||||
hash += key[i++];
|
hash += key[i++];
|
||||||
hash += hash << 10;
|
hash += hash << 10;
|
||||||
|
@ -22,31 +22,62 @@ unsigned int hydroforth__hash_string(const char *const key, unsigned char len)
|
||||||
return hash;
|
return hash;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline bool hydroforth__is_space(char c)
|
||||||
|
{
|
||||||
|
return c == ' ' || c == '\t';
|
||||||
|
}
|
||||||
|
|
||||||
bool hydroforth__parse(HYDROFORTH__INTERPRETER *interpreter)
|
bool hydroforth__parse(HYDROFORTH__INTERPRETER *interpreter)
|
||||||
{
|
{
|
||||||
const unsigned long start = interpreter->pos;
|
const unsigned long start = interpreter->pos;
|
||||||
unsigned char len = 0;
|
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++;
|
len++;
|
||||||
interpreter->pos++;
|
interpreter->pos++;
|
||||||
}
|
}
|
||||||
HYDROFORTH__WORD word;
|
|
||||||
if (len == 1)
|
if (len == 1)
|
||||||
{
|
{
|
||||||
if (hydroforth__number__is_digit(interpreter->src[start]))
|
if (hydroforth__number__is_digit(interpreter->src[start]))
|
||||||
{
|
{
|
||||||
word = (HYDROFORTH__WORD){
|
interpreter->call_stack[interpreter->call_stack_len++] = (HYDROFORTH__WORD){
|
||||||
.type = PUSH,
|
.type = PUSH,
|
||||||
.data = {.number = interpreter->src[start] - '0'},
|
.data = {.number = interpreter->src[start] - '0'},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
else
|
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,
|
.type = CHAR_WORD,
|
||||||
.data = {.char_word = interpreter->src[start]},
|
.data = {.char_word = interpreter->src[start]},
|
||||||
};
|
};
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -60,7 +91,7 @@ bool hydroforth__parse(HYDROFORTH__INTERPRETER *interpreter)
|
||||||
fputs("Error parsing number!", stderr);
|
fputs("Error parsing number!", stderr);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
word = (HYDROFORTH__WORD){
|
interpreter->call_stack[interpreter->call_stack_len++] = (HYDROFORTH__WORD){
|
||||||
.type = PUSH,
|
.type = PUSH,
|
||||||
.data = {.number = -n},
|
.data = {.number = -n},
|
||||||
};
|
};
|
||||||
|
@ -73,7 +104,7 @@ bool hydroforth__parse(HYDROFORTH__INTERPRETER *interpreter)
|
||||||
fputs("Error parsing number!", stderr);
|
fputs("Error parsing number!", stderr);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
word = (HYDROFORTH__WORD){
|
interpreter->call_stack[interpreter->call_stack_len++] = (HYDROFORTH__WORD){
|
||||||
.type = PUSH,
|
.type = PUSH,
|
||||||
.data = {.number = n},
|
.data = {.number = n},
|
||||||
};
|
};
|
||||||
|
@ -86,34 +117,40 @@ bool hydroforth__parse(HYDROFORTH__INTERPRETER *interpreter)
|
||||||
fputs("Error parsing number!", stderr);
|
fputs("Error parsing number!", stderr);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
word = (HYDROFORTH__WORD){
|
interpreter->call_stack[interpreter->call_stack_len++] = (HYDROFORTH__WORD){
|
||||||
.type = PUSH,
|
.type = PUSH,
|
||||||
.data = {.number = n},
|
.data = {.number = n},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
char *const s = malloc(sizeof(char) * (len + 1));
|
const unsigned int hash = hydroforth__hash_string(interpreter->src + start, len);
|
||||||
strncpy(s, interpreter->src + start, len);
|
switch (hash)
|
||||||
s[len] = '\0';
|
{
|
||||||
word = (HYDROFORTH__WORD){
|
case 0x4078cde9: // --
|
||||||
.type = WORD,
|
do
|
||||||
.data = {.word = s},
|
{
|
||||||
};
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool hydroforth__run_call_stack(HYDROFORTH__INTERPRETER *interpreter)
|
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--)
|
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;
|
const HYDROFORTH__WORD *word = interpreter->call_stack + i - 1;
|
||||||
switch (word->type)
|
switch (word->type)
|
||||||
{
|
{
|
||||||
|
@ -124,7 +161,28 @@ bool hydroforth__run_call_stack(HYDROFORTH__INTERPRETER *interpreter)
|
||||||
case CHAR_WORD:
|
case CHAR_WORD:
|
||||||
switch (word->data.char_word)
|
switch (word->data.char_word)
|
||||||
{
|
{
|
||||||
|
case ':':
|
||||||
|
printf("WORD DEFINITION\n");
|
||||||
|
break;
|
||||||
|
|
||||||
case '-':
|
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;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -133,6 +191,15 @@ bool hydroforth__run_call_stack(HYDROFORTH__INTERPRETER *interpreter)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case WORD:
|
case WORD:
|
||||||
|
printf("HASH: 0x%x\n", word->data.hash);
|
||||||
|
switch (word->data.hash)
|
||||||
|
{
|
||||||
|
case 0xaddd94c: // debug
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -144,10 +211,14 @@ bool hydroforth__run(HYDROFORTH__INTERPRETER *interpreter)
|
||||||
{
|
{
|
||||||
while (true)
|
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++;
|
interpreter->pos++;
|
||||||
}
|
}
|
||||||
|
if (interpreter->src[interpreter->pos] == '\0')
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
if (!interpreter->src[interpreter->pos])
|
if (!interpreter->src[interpreter->pos])
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -27,7 +27,7 @@ struct ReadSrcResult read_src(FILE *fp)
|
||||||
.success = false,
|
.success = false,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
char *const src = malloc(sizeof(char) * (bufsize + 1));
|
char *const src = malloc(sizeof(char) * bufsize);
|
||||||
if (fseek(fp, 0L, SEEK_SET) != 0)
|
if (fseek(fp, 0L, SEEK_SET) != 0)
|
||||||
{
|
{
|
||||||
fputs("Error rewinding file to start!", stderr);
|
fputs("Error rewinding file to start!", stderr);
|
||||||
|
@ -35,7 +35,7 @@ struct ReadSrcResult read_src(FILE *fp)
|
||||||
.success = false,
|
.success = false,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
const unsigned long new_len = fread(src, sizeof(char), bufsize, fp);
|
fread(src, sizeof(char), bufsize, fp);
|
||||||
if (ferror(fp) != 0)
|
if (ferror(fp) != 0)
|
||||||
{
|
{
|
||||||
fputs("Error reading file!", stderr);
|
fputs("Error reading file!", stderr);
|
||||||
|
@ -43,7 +43,6 @@ struct ReadSrcResult read_src(FILE *fp)
|
||||||
.success = false,
|
.success = false,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
src[new_len + 1] = '\0';
|
|
||||||
|
|
||||||
return (struct ReadSrcResult){
|
return (struct ReadSrcResult){
|
||||||
.success = true,
|
.success = true,
|
||||||
|
|
Loading…
Reference in a new issue