This commit is contained in:
Dominic Grimm 2022-12-23 20:52:25 +01:00
parent bd9b51be9a
commit 115dc530e1
No known key found for this signature in database
GPG key ID: 6F294212DEAAC530
6 changed files with 153 additions and 64 deletions

View file

@ -6,7 +6,7 @@
#include "result.h" #include "result.h"
#include "number.h" #include "number.h"
extern unsigned int hydroforth__hash_string(const char *const key, unsigned char len); extern unsigned hydroforth__hash_string(const char *const key, unsigned char len);
extern bool hydroforth__is_space(char c); extern bool hydroforth__is_space(char c);
@ -33,6 +33,7 @@ typedef struct HYDROFORTH__WORD
typedef struct HYDROFORTH__WORD_DEFINITION typedef struct HYDROFORTH__WORD_DEFINITION
{ {
HYDROFORTH__WORD *words; HYDROFORTH__WORD *words;
unsigned char words_len;
} HYDROFORTH__WORD_DEFINITION; } HYDROFORTH__WORD_DEFINITION;
typedef struct HYDROFORTH__WORD_DEFINITION_BASE_KEY typedef struct HYDROFORTH__WORD_DEFINITION_BASE_KEY
@ -58,10 +59,10 @@ typedef struct HYDROFORTH__INTERPRETER
unsigned long pos; unsigned long pos;
HYDROFORTH__WORD_DEFINITION_SINGLE_CHAR_WORD_KEY single_char_word_keys[32]; HYDROFORTH__WORD_DEFINITION_SINGLE_CHAR_WORD_KEY single_char_word_keys[32];
unsigned char single_char_word_keys_len; unsigned char single_char_word_keys_len;
HYDROFORTH__WORD_DEFINITION_WORD_KEY word_keys[256];
unsigned short word_keys_len; unsigned short word_keys_len;
unsigned short word_keys_max_len; HYDROFORTH__WORD_DEFINITION word_definitions[256 + 32];
HYDROFORTH__WORD_DEFINITION_WORD_KEY *word_keys; unsigned short word_definitions_len;
HYDROFORTH__WORD_DEFINITION word_definitions[256];
HYDROFORTH__WORD call_stack[256]; HYDROFORTH__WORD call_stack[256];
unsigned char call_stack_len; unsigned char call_stack_len;
int stack[256]; int stack[256];
@ -76,23 +77,26 @@ typedef struct HYDROFORTH__SCAN_NEXT_WORD_RESULT
extern HYDROFORTH__SCAN_NEXT_WORD_RESULT hydroforth__scan_next_word(HYDROFORTH__INTERPRETER *interpreter); extern HYDROFORTH__SCAN_NEXT_WORD_RESULT hydroforth__scan_next_word(HYDROFORTH__INTERPRETER *interpreter);
extern void hydroforth__parse(HYDROFORTH__RESULT *const result, HYDROFORTH__INTERPRETER *interpreter); extern void hydroforth__add_word_to_word_definition(HYDROFORTH__WORD_DEFINITION *word_def, HYDROFORTH__WORD word);
extern void hydroforth__run_call_stack(HYDROFORTH__RESULT *const result, HYDROFORTH__INTERPRETER *interpreter); extern void hydroforth__parse(HYDROFORTH__RESULT *result, HYDROFORTH__INTERPRETER *interpreter, HYDROFORTH__WORD_DEFINITION *word_def);
extern void hydroforth__run(HYDROFORTH__RESULT *const result, HYDROFORTH__INTERPRETER *interpreter); extern void hydroforth__run_call_stack(HYDROFORTH__RESULT *result, HYDROFORTH__INTERPRETER *interpreter);
extern void hydroforth__run(HYDROFORTH__RESULT *result, HYDROFORTH__INTERPRETER *interpreter);
typedef struct __HYDROFORTH typedef struct __HYDROFORTH
{ {
__HYDROFORTH__RESULT result; __HYDROFORTH__RESULT result;
__HYDROFORTH__NUMBER number; __HYDROFORTH__NUMBER number;
unsigned int (*hash_string)(const char *const key, unsigned char len); unsigned (*hash_string)(const char *const key, unsigned char len);
bool (*is_space)(char c); bool (*is_space)(char c);
HYDROFORTH__SCAN_NEXT_WORD_RESULT(*scan_next_word) HYDROFORTH__SCAN_NEXT_WORD_RESULT(*scan_next_word)
(HYDROFORTH__INTERPRETER *interpreter); (HYDROFORTH__INTERPRETER *interpreter);
void (*parse)(HYDROFORTH__RESULT *const result, HYDROFORTH__INTERPRETER *interpreter); void (*add_word_to_word_definition)(HYDROFORTH__WORD_DEFINITION *word_def, HYDROFORTH__WORD word);
void (*run_call_stack)(HYDROFORTH__RESULT *const result, HYDROFORTH__INTERPRETER *interpreter); void (*parse)(HYDROFORTH__RESULT *result, HYDROFORTH__INTERPRETER *interpreter, HYDROFORTH__WORD_DEFINITION *word_def);
void (*run)(HYDROFORTH__RESULT *const result, HYDROFORTH__INTERPRETER *interpreter); void (*run_call_stack)(HYDROFORTH__RESULT *result, HYDROFORTH__INTERPRETER *interpreter);
void (*run)(HYDROFORTH__RESULT *result, HYDROFORTH__INTERPRETER *interpreter);
} __HYDROFORTH; } __HYDROFORTH;
static const __HYDROFORTH hydroforth = { static const __HYDROFORTH hydroforth = {
@ -111,6 +115,7 @@ static const __HYDROFORTH hydroforth = {
.hash_string = hydroforth__hash_string, .hash_string = hydroforth__hash_string,
.is_space = hydroforth__is_space, .is_space = hydroforth__is_space,
.scan_next_word = hydroforth__scan_next_word, .scan_next_word = hydroforth__scan_next_word,
.add_word_to_word_definition = hydroforth__add_word_to_word_definition,
.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,

View file

@ -12,6 +12,7 @@ typedef enum HYDROFORTH__RESULT__ERROR
ERR_UNKNOWN_WORD, ERR_UNKNOWN_WORD,
ERR_UNTERMINATED_WORD_DEFINITION, ERR_UNTERMINATED_WORD_DEFINITION,
ERR_WORD_NAME_CANT_BE_NUMBER, ERR_WORD_NAME_CANT_BE_NUMBER,
ERR_WORD_DEF_INSIDE_WORD_DEF,
} HYDROFORTH__RESULT__ERROR; } HYDROFORTH__RESULT__ERROR;
typedef HYDROFORTH__RESULT__ERROR HYDROFORTH__ERROR; typedef HYDROFORTH__RESULT__ERROR HYDROFORTH__ERROR;

View file

@ -1,13 +1,14 @@
#include <stdbool.h> #include <stdbool.h>
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <malloc.h>
#include "hydroforth/hydroforth.h" #include "hydroforth/hydroforth.h"
unsigned int hydroforth__hash_string(const char *const key, unsigned char len) unsigned hydroforth__hash_string(const char *const key, unsigned char len)
{ {
unsigned char i = 0; unsigned char i = 0;
unsigned int hash = 0; unsigned hash = 0;
while (i < len) while (i < len)
{ {
hash += key[i++]; hash += key[i++];
@ -42,24 +43,34 @@ HYDROFORTH__SCAN_NEXT_WORD_RESULT hydroforth__scan_next_word(HYDROFORTH__INTERPR
}; };
} }
void hydroforth__parse(HYDROFORTH__RESULT *const result, HYDROFORTH__INTERPRETER *interpreter) void hydroforth__add_word_to_word_definition(HYDROFORTH__WORD_DEFINITION *word_def, HYDROFORTH__WORD word)
{
word_def->words = realloc(word_def->words, sizeof(HYDROFORTH__WORD) * (word_def->words_len + 1));
word_def->words[word_def->words_len++] = word;
}
void hydroforth__parse(HYDROFORTH__RESULT *result, HYDROFORTH__INTERPRETER *interpreter, HYDROFORTH__WORD_DEFINITION *word_def)
{ {
// 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++;
// }
const HYDROFORTH__SCAN_NEXT_WORD_RESULT res = hydroforth__scan_next_word(interpreter); const HYDROFORTH__SCAN_NEXT_WORD_RESULT res = hydroforth__scan_next_word(interpreter);
if (res.len == 1) if (res.len == 1)
{ {
if (hydroforth__number__is_digit(interpreter->src[res.start])) if (hydroforth__number__is_digit(interpreter->src[res.start]))
{ {
interpreter->call_stack[interpreter->call_stack_len++] = (HYDROFORTH__WORD){ int n = interpreter->src[res.start] - '0';
.type = PUSH, if (word_def == NULL)
.data = {.number = interpreter->src[res.start] - '0'}, {
}; interpreter->call_stack[interpreter->call_stack_len++] = (HYDROFORTH__WORD){
.type = PUSH,
.data = {.number = n},
};
}
else
{
hydroforth__add_word_to_word_definition(word_def, (HYDROFORTH__WORD){
.type = PUSH,
.data = {.number = n},
});
}
} }
else else
{ {
@ -88,6 +99,13 @@ void hydroforth__parse(HYDROFORTH__RESULT *const result, HYDROFORTH__INTERPRETER
} }
case ':': case ':':
{
if (word_def != NULL)
{
hydroforth__set_func_result(result, ERR_WORD_DEF_INSIDE_WORD_DEF);
return;
}
printf("WORD DEFINITION\n"); printf("WORD DEFINITION\n");
do do
{ {
@ -95,27 +113,55 @@ void hydroforth__parse(HYDROFORTH__RESULT *const result, HYDROFORTH__INTERPRETER
} while (hydroforth__is_space(interpreter->src[interpreter->pos]) || interpreter->src[interpreter->pos] == '\n'); } while (hydroforth__is_space(interpreter->src[interpreter->pos]) || interpreter->src[interpreter->pos] == '\n');
if (!interpreter->src[interpreter->pos]) if (!interpreter->src[interpreter->pos])
{ {
// fputs("Unterminated word definition!\n", stderr);
// return false;
hydroforth__set_func_result(result, ERR_UNTERMINATED_WORD_DEFINITION); hydroforth__set_func_result(result, ERR_UNTERMINATED_WORD_DEFINITION);
return; return;
} }
if (hydroforth__number__is_digit(interpreter->src[interpreter->pos])) if (hydroforth__number__is_digit(interpreter->src[interpreter->pos]))
{ {
// fputs("Word name cannot be a number!\n", stderr);
// return false;
hydroforth__set_func_result(result, ERR_WORD_NAME_CANT_BE_NUMBER); hydroforth__set_func_result(result, ERR_WORD_NAME_CANT_BE_NUMBER);
return; return;
} }
const HYDROFORTH__SCAN_NEXT_WORD_RESULT name_scan_res = hydroforth__scan_next_word(interpreter); const HYDROFORTH__SCAN_NEXT_WORD_RESULT name_scan_res = hydroforth__scan_next_word(interpreter);
for (unsigned char i = 0; i < name_scan_res.len; i++)
{
putchar(interpreter->src[name_scan_res.start + i]);
}
putchar('\n');
if (name_scan_res.len == 1)
{
}
else
{
unsigned hash = hydroforth__hash_string(interpreter->src + name_scan_res.start, name_scan_res.len);
printf("HASH: 0x%x\n", hash);
interpreter->word_definitions[interpreter->word_definitions_len] = (HYDROFORTH__WORD_DEFINITION){
.words = malloc(0),
.words_len = 0,
};
interpreter->word_keys[interpreter->word_keys_len++] = (HYDROFORTH__WORD_DEFINITION_WORD_KEY){
.hash = hash,
.key = {.word_definition_index = interpreter->word_definitions_len++},
};
}
break; break;
}
default: default:
interpreter->call_stack[interpreter->call_stack_len++] = (HYDROFORTH__WORD){ if (word_def == NULL)
.type = CHAR_WORD, {
.data = {.char_word = interpreter->src[res.start]}, interpreter->call_stack[interpreter->call_stack_len++] = (HYDROFORTH__WORD){
}; .type = CHAR_WORD,
.data = {.char_word = interpreter->src[res.start]},
};
}
else
{
hydroforth__add_word_to_word_definition(word_def, (HYDROFORTH__WORD){
.type = CHAR_WORD,
.data = {.char_word = interpreter->src[res.start]},
});
}
break; break;
} }
} }
@ -129,13 +175,22 @@ void hydroforth__parse(HYDROFORTH__RESULT *const result, HYDROFORTH__INTERPRETER
if (result->error) if (result->error)
{ {
hydroforth__add_func_backtrace(result); hydroforth__add_func_backtrace(result);
fputs("Error parsing number!\n", stderr);
return; return;
} }
interpreter->call_stack[interpreter->call_stack_len++] = (HYDROFORTH__WORD){ if (word_def == NULL)
.type = PUSH, {
.data = {.number = -n}, interpreter->call_stack[interpreter->call_stack_len++] = (HYDROFORTH__WORD){
}; .type = PUSH,
.data = {.number = -n},
};
}
else
{
hydroforth__add_word_to_word_definition(word_def, (HYDROFORTH__WORD){
.type = PUSH,
.data = {.number = -n},
});
}
} }
else if (next_is_digit && interpreter->src[res.start] == '+') else if (next_is_digit && interpreter->src[res.start] == '+')
{ {
@ -143,13 +198,22 @@ void hydroforth__parse(HYDROFORTH__RESULT *const result, HYDROFORTH__INTERPRETER
if (result->error) if (result->error)
{ {
hydroforth__add_func_backtrace(result); hydroforth__add_func_backtrace(result);
fputs("Error parsing number!\n", stderr);
return; return;
} }
interpreter->call_stack[interpreter->call_stack_len++] = (HYDROFORTH__WORD){ if (word_def == NULL)
.type = PUSH, {
.data = {.number = n}, interpreter->call_stack[interpreter->call_stack_len++] = (HYDROFORTH__WORD){
}; .type = PUSH,
.data = {.number = n},
};
}
else
{
hydroforth__add_word_to_word_definition(word_def, (HYDROFORTH__WORD){
.type = PUSH,
.data = {.number = n},
});
}
} }
else if (hydroforth__number__is_digit(interpreter->src[res.start])) else if (hydroforth__number__is_digit(interpreter->src[res.start]))
{ {
@ -157,17 +221,26 @@ void hydroforth__parse(HYDROFORTH__RESULT *const result, HYDROFORTH__INTERPRETER
if (result->error) if (result->error)
{ {
hydroforth__add_func_backtrace(result); hydroforth__add_func_backtrace(result);
fputs("Error parsing number!\n", stderr);
return; return;
} }
interpreter->call_stack[interpreter->call_stack_len++] = (HYDROFORTH__WORD){ if (word_def == NULL)
.type = PUSH, {
.data = {.number = n}, interpreter->call_stack[interpreter->call_stack_len++] = (HYDROFORTH__WORD){
}; .type = PUSH,
.data = {.number = n},
};
}
else
{
hydroforth__add_word_to_word_definition(word_def, (HYDROFORTH__WORD){
.type = PUSH,
.data = {.number = n},
});
}
} }
else else
{ {
const unsigned int hash = hydroforth__hash_string(interpreter->src + res.start, res.len); const unsigned hash = hydroforth__hash_string(interpreter->src + res.start, res.len);
switch (hash) switch (hash)
{ {
case 0x4078cde9: // -- case 0x4078cde9: // --
@ -178,17 +251,27 @@ void hydroforth__parse(HYDROFORTH__RESULT *const result, HYDROFORTH__INTERPRETER
break; break;
default: default:
interpreter->call_stack[interpreter->call_stack_len++] = (HYDROFORTH__WORD){ if (word_def == NULL)
.type = WORD, {
.data = {.hash = hash}, interpreter->call_stack[interpreter->call_stack_len++] = (HYDROFORTH__WORD){
}; .type = WORD,
.data = {.hash = hash},
};
}
else
{
hydroforth__add_word_to_word_definition(word_def, (HYDROFORTH__WORD){
.type = WORD,
.data = {.hash = hash},
});
}
break; break;
} }
} }
} }
} }
void hydroforth__run_call_stack(HYDROFORTH__RESULT *const result, HYDROFORTH__INTERPRETER *interpreter) void hydroforth__run_call_stack(HYDROFORTH__RESULT *result, HYDROFORTH__INTERPRETER *interpreter)
{ {
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--)
{ {
@ -280,7 +363,7 @@ void hydroforth__run_call_stack(HYDROFORTH__RESULT *const result, HYDROFORTH__IN
} }
} }
void hydroforth__run(HYDROFORTH__RESULT *const result, HYDROFORTH__INTERPRETER *interpreter) void hydroforth__run(HYDROFORTH__RESULT *result, HYDROFORTH__INTERPRETER *interpreter)
{ {
while (true) while (true)
{ {
@ -292,7 +375,7 @@ void hydroforth__run(HYDROFORTH__RESULT *const result, HYDROFORTH__INTERPRETER *
{ {
return; return;
} }
hydroforth__parse(result, interpreter); hydroforth__parse(result, interpreter, NULL);
if (result->error) if (result->error)
{ {
hydroforth__add_func_backtrace(result); hydroforth__add_func_backtrace(result);

View file

@ -37,6 +37,9 @@ const char *hydroforth__result__get_error_message(HYDROFORTH__ERROR error)
case ERR_WORD_NAME_CANT_BE_NUMBER: case ERR_WORD_NAME_CANT_BE_NUMBER:
return "Word name can't be a number"; return "Word name can't be a number";
case ERR_WORD_DEF_INSIDE_WORD_DEF:
return "Can't define a word inside a word definition";
default: default:
return "???"; return "???";
} }

View file

@ -1,9 +1,6 @@
#include <stdlib.h>
#include <stdio.h> #include <stdio.h>
#include <stdbool.h> #include <stdbool.h>
#include <malloc.h>
#define UNW_LOCAL_ONLY
#include <libunwind.h>
#include "hydroforth/hydroforth.h" #include "hydroforth/hydroforth.h"
@ -60,7 +57,7 @@ int main(int argc, char *argv[])
fputs("No source file specified!\n", stderr); fputs("No source file specified!\n", stderr);
return 1; return 1;
} }
FILE *fp = fopen(argv[1], "rb"); FILE *fp = fopen(argv[1], "r");
if (fp == NULL) if (fp == NULL)
{ {
fputs("Error opening file!\n", stderr); fputs("Error opening file!\n", stderr);
@ -75,11 +72,11 @@ int main(int argc, char *argv[])
.pos = 0, .pos = 0,
.single_char_word_keys_len = 0, .single_char_word_keys_len = 0,
.word_keys_len = 0, .word_keys_len = 0,
.word_keys_max_len = 0, .word_definitions_len = 0,
}; };
HYDROFORTH__RESULT result = {.error = OK, .backtrace_len = 0}; HYDROFORTH__RESULT result = {.error = OK, .backtrace_len = 0};
hydroforth.run(&result, &interpreter); hydroforth.run(&result, &interpreter);
free(res.src); free(interpreter.src);
if (result.error) if (result.error)
{ {
hydroforth__add_func_backtrace(&result); hydroforth__add_func_backtrace(&result);

View file

@ -1,2 +1,2 @@
\ : test 42 ; : test 42 ;
40 2 + debug 40 2 + debug