165 lines
3.7 KiB
C
165 lines
3.7 KiB
C
#include <stdbool.h>
|
|
#include <stdio.h>
|
|
#include <malloc.h>
|
|
#include <string.h>
|
|
|
|
#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;
|
|
}
|
|
|
|
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])
|
|
{
|
|
len++;
|
|
interpreter->pos++;
|
|
}
|
|
HYDROFORTH__WORD word;
|
|
if (len == 1)
|
|
{
|
|
if (hydroforth__number__is_digit(interpreter->src[start]))
|
|
{
|
|
word = (HYDROFORTH__WORD){
|
|
.type = PUSH,
|
|
.data = {.number = interpreter->src[start] - '0'},
|
|
};
|
|
}
|
|
else
|
|
{
|
|
word = (HYDROFORTH__WORD){
|
|
.type = CHAR_WORD,
|
|
.data = {.char_word = interpreter->src[start]},
|
|
};
|
|
}
|
|
}
|
|
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;
|
|
}
|
|
word = (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;
|
|
}
|
|
word = (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;
|
|
}
|
|
word = (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},
|
|
};
|
|
}
|
|
}
|
|
|
|
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)
|
|
{
|
|
case PUSH:
|
|
interpreter->stack[interpreter->stack_len++] = word->data.number;
|
|
break;
|
|
|
|
case CHAR_WORD:
|
|
switch (word->data.char_word)
|
|
{
|
|
case '-':
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
break;
|
|
|
|
case WORD:
|
|
break;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
bool hydroforth__run(HYDROFORTH__INTERPRETER *interpreter)
|
|
{
|
|
while (true)
|
|
{
|
|
while (interpreter->src[interpreter->pos] == ' ' || interpreter->src[interpreter->pos] == '\n')
|
|
{
|
|
interpreter->pos++;
|
|
}
|
|
if (!interpreter->src[interpreter->pos])
|
|
{
|
|
return true;
|
|
}
|
|
if (!hydroforth__parse(interpreter))
|
|
{
|
|
return false;
|
|
}
|
|
if (!hydroforth__run_call_stack(interpreter))
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
}
|