Update
This commit is contained in:
parent
0019e3278e
commit
4e8c187050
8 changed files with 228 additions and 54 deletions
|
@ -3,6 +3,7 @@
|
||||||
|
|
||||||
#include <stdbool.h>
|
#include <stdbool.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 int hydroforth__hash_string(const char *const key, unsigned char len);
|
||||||
|
@ -67,6 +68,14 @@ typedef struct HYDROFORTH__INTERPRETER
|
||||||
unsigned char stack_len;
|
unsigned char stack_len;
|
||||||
} HYDROFORTH__INTERPRETER;
|
} HYDROFORTH__INTERPRETER;
|
||||||
|
|
||||||
|
typedef struct HYDROFORTH__SCAN_NEXT_WORD_RESULT
|
||||||
|
{
|
||||||
|
unsigned long start;
|
||||||
|
unsigned char len;
|
||||||
|
} HYDROFORTH__SCAN_NEXT_WORD_RESULT;
|
||||||
|
|
||||||
|
extern HYDROFORTH__SCAN_NEXT_WORD_RESULT hydroforth__scan_next_word(HYDROFORTH__INTERPRETER *interpreter);
|
||||||
|
|
||||||
extern bool hydroforth__parse(HYDROFORTH__INTERPRETER *interpreter);
|
extern bool hydroforth__parse(HYDROFORTH__INTERPRETER *interpreter);
|
||||||
|
|
||||||
extern bool hydroforth__run_call_stack(HYDROFORTH__INTERPRETER *interpreter);
|
extern bool hydroforth__run_call_stack(HYDROFORTH__INTERPRETER *interpreter);
|
||||||
|
@ -75,23 +84,32 @@ extern bool hydroforth__run(HYDROFORTH__INTERPRETER *interpreter);
|
||||||
|
|
||||||
typedef struct __HYDROFORTH
|
typedef struct __HYDROFORTH
|
||||||
{
|
{
|
||||||
|
__HYDROFORTH__RESULT result;
|
||||||
__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 (*is_space)(char c);
|
||||||
|
HYDROFORTH__SCAN_NEXT_WORD_RESULT(*scan_next_word)
|
||||||
|
(HYDROFORTH__INTERPRETER *interpreter);
|
||||||
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);
|
||||||
} __HYDROFORTH;
|
} __HYDROFORTH;
|
||||||
|
|
||||||
static const __HYDROFORTH hydroforth = {
|
static const __HYDROFORTH hydroforth = {
|
||||||
|
.result = {
|
||||||
|
.add_backtrace = hydroforth__result__add_backtrace,
|
||||||
|
.get_error_message = hydroforth__result__get_error_message,
|
||||||
|
},
|
||||||
.number = {
|
.number = {
|
||||||
.is_digit = hydroforth__number__is_digit,
|
.is_digit = hydroforth__number__is_digit,
|
||||||
.convert_hex_digit = hydroforth__number__convert_hex_digit,
|
.convert_hex_digit = hydroforth__number__convert_hex_digit,
|
||||||
.parse_number_hex = hydroforth__number__parse_number_hex,
|
.parse_number_hex = hydroforth__number__parse_number_hex,
|
||||||
.parse_number = hydroforth__number__parse_number,
|
.parse_number = hydroforth__number__parse_number,
|
||||||
|
.count_digits = hydroforth__number__count_digits,
|
||||||
},
|
},
|
||||||
.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,
|
||||||
.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,
|
||||||
|
|
|
@ -1,22 +1,23 @@
|
||||||
#ifndef __HYDROFORTH__NUMBER_H__
|
#ifndef __HYDROFORTH__NUMBER_H__
|
||||||
#define __HYDROFORTH__NUMBER_H__
|
#define __HYDROFORTH__NUMBER_H__
|
||||||
|
|
||||||
#include <stdbool.h>
|
|
||||||
|
|
||||||
extern bool hydroforth__number__is_digit(char c);
|
extern bool hydroforth__number__is_digit(char c);
|
||||||
|
|
||||||
extern bool hydroforth__number__convert_hex_digit(char c, unsigned char *const val);
|
extern void hydroforth__number__convert_hex_digit(HYDROFORTH__RESULT *const result, char c, unsigned char *const val);
|
||||||
|
|
||||||
extern bool hydroforth__number__parse_number_hex(const char *const start, unsigned char len, int *const val);
|
extern void hydroforth__number__parse_number_hex(HYDROFORTH__RESULT *const result, const char *const start, unsigned char len, int *const val);
|
||||||
|
|
||||||
extern bool hydroforth__number__parse_number(const char *const start, unsigned char len, int *const val);
|
extern void hydroforth__number__parse_number(HYDROFORTH__RESULT *const result, const char *const start, unsigned char len, int *const val);
|
||||||
|
|
||||||
|
extern unsigned char hydroforth__number__count_digits(int n);
|
||||||
|
|
||||||
typedef struct __HYDROFORTH__NUMBER
|
typedef struct __HYDROFORTH__NUMBER
|
||||||
{
|
{
|
||||||
bool (*is_digit)(char c);
|
bool (*is_digit)(char c);
|
||||||
bool (*convert_hex_digit)(char c, unsigned char *const val);
|
void (*convert_hex_digit)(HYDROFORTH__RESULT *const result, char c, unsigned char *const val);
|
||||||
bool (*parse_number_hex)(const char *const start, unsigned char len, int *const val);
|
void (*parse_number_hex)(HYDROFORTH__RESULT *const result, const char *const start, unsigned char len, int *const val);
|
||||||
bool (*parse_number)(const char *const start, unsigned char len, int *const val);
|
void (*parse_number)(HYDROFORTH__RESULT *const result, const char *const start, unsigned char len, int *const val);
|
||||||
|
unsigned char (*count_digits)(int n);
|
||||||
} __HYDROFORTH__NUMBER;
|
} __HYDROFORTH__NUMBER;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
40
include/hydroforth/result.h
Normal file
40
include/hydroforth/result.h
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
#ifndef __HYDROFORTH__RESULT_H__
|
||||||
|
#define __HYDROFORTH__RESULT_H__
|
||||||
|
|
||||||
|
typedef enum HYDROFORTH__RESULT__ERROR
|
||||||
|
{
|
||||||
|
OK,
|
||||||
|
|
||||||
|
ERR_UNKNOWN,
|
||||||
|
ERR_INVALID_HEX_CHAR,
|
||||||
|
} HYDROFORTH__RESULT__ERROR;
|
||||||
|
|
||||||
|
typedef HYDROFORTH__RESULT__ERROR HYDROFORTH__ERROR;
|
||||||
|
|
||||||
|
typedef struct HYDROFORTH__RESULT__RESULT
|
||||||
|
{
|
||||||
|
HYDROFORTH__ERROR error;
|
||||||
|
char **const backtrace;
|
||||||
|
unsigned backtrace_len;
|
||||||
|
} HYDROFORTH__RESULT__RESULT;
|
||||||
|
|
||||||
|
typedef HYDROFORTH__RESULT__RESULT HYDROFORTH__RESULT;
|
||||||
|
|
||||||
|
extern void hydroforth__result__add_backtrace(HYDROFORTH__RESULT *const result, const char *const s);
|
||||||
|
|
||||||
|
extern void hydroforth__result__set(HYDROFORTH__RESULT *const result, HYDROFORTH__ERROR error, const char *const s);
|
||||||
|
|
||||||
|
extern const char *hydroforth__result__get_error_message(HYDROFORTH__ERROR error);
|
||||||
|
|
||||||
|
#define hydroforth__set_func_result(result, error) hydroforth__result__set(result, error, __func__);
|
||||||
|
|
||||||
|
#define hydroforth__add_func_backtrace(result) hydroforth__result__add_backtrace(result, __func__);
|
||||||
|
|
||||||
|
typedef struct __HYDROFORTH__RESULT
|
||||||
|
{
|
||||||
|
void (*add_backtrace)(HYDROFORTH__RESULT *const result, const char *const s);
|
||||||
|
void (*set)(HYDROFORTH__RESULT *const result, HYDROFORTH__ERROR error, const char *const s);
|
||||||
|
const char *(*get_error_message)(HYDROFORTH__ERROR error);
|
||||||
|
} __HYDROFORTH__RESULT;
|
||||||
|
|
||||||
|
#endif
|
|
@ -27,7 +27,7 @@ inline bool hydroforth__is_space(char c)
|
||||||
return c == ' ' || c == '\t';
|
return c == ' ' || c == '\t';
|
||||||
}
|
}
|
||||||
|
|
||||||
bool hydroforth__parse(HYDROFORTH__INTERPRETER *interpreter)
|
HYDROFORTH__SCAN_NEXT_WORD_RESULT hydroforth__scan_next_word(HYDROFORTH__INTERPRETER *interpreter)
|
||||||
{
|
{
|
||||||
const unsigned long start = interpreter->pos;
|
const unsigned long start = interpreter->pos;
|
||||||
unsigned char len = 0;
|
unsigned char len = 0;
|
||||||
|
@ -36,18 +36,35 @@ bool hydroforth__parse(HYDROFORTH__INTERPRETER *interpreter)
|
||||||
len++;
|
len++;
|
||||||
interpreter->pos++;
|
interpreter->pos++;
|
||||||
}
|
}
|
||||||
if (len == 1)
|
|
||||||
|
return (HYDROFORTH__SCAN_NEXT_WORD_RESULT){
|
||||||
|
.start = start,
|
||||||
|
.len = len,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
bool hydroforth__parse(HYDROFORTH__INTERPRETER *interpreter)
|
||||||
{
|
{
|
||||||
if (hydroforth__number__is_digit(interpreter->src[start]))
|
// 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);
|
||||||
|
if (res.len == 1)
|
||||||
|
{
|
||||||
|
if (hydroforth__number__is_digit(interpreter->src[res.start]))
|
||||||
{
|
{
|
||||||
interpreter->call_stack[interpreter->call_stack_len++] = (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[res.start] - '0'},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
switch (interpreter->src[start])
|
switch (interpreter->src[res.start])
|
||||||
{
|
{
|
||||||
case '\\':
|
case '\\':
|
||||||
do
|
do
|
||||||
|
@ -71,10 +88,30 @@ bool hydroforth__parse(HYDROFORTH__INTERPRETER *interpreter)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case ':':
|
||||||
|
printf("WORD DEFINITION\n");
|
||||||
|
do
|
||||||
|
{
|
||||||
|
interpreter->pos++;
|
||||||
|
} while (hydroforth__is_space(interpreter->src[interpreter->pos]) || interpreter->src[interpreter->pos] == '\n');
|
||||||
|
if (!interpreter->src[interpreter->pos])
|
||||||
|
{
|
||||||
|
fputs("Unterminated word definition!\n", stderr);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (hydroforth__number__is_digit(interpreter->src[interpreter->pos]))
|
||||||
|
{
|
||||||
|
fputs("Word name cannot be a number!\n", stderr);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
const HYDROFORTH__SCAN_NEXT_WORD_RESULT name_scan_res = hydroforth__scan_next_word(interpreter);
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
interpreter->call_stack[interpreter->call_stack_len++] = (HYDROFORTH__WORD){
|
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[res.start]},
|
||||||
};
|
};
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -82,13 +119,13 @@ bool hydroforth__parse(HYDROFORTH__INTERPRETER *interpreter)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
const bool next_is_digit = hydroforth__number__is_digit(interpreter->src[start + 1]);
|
const bool next_is_digit = hydroforth__number__is_digit(interpreter->src[res.start + 1]);
|
||||||
if (next_is_digit && interpreter->src[start] == '-')
|
if (next_is_digit && interpreter->src[res.start] == '-')
|
||||||
{
|
{
|
||||||
int n;
|
int n;
|
||||||
if (!hydroforth__number__parse_number(interpreter->src + start + 1, len - 1, &n))
|
if (!hydroforth__number__parse_number(interpreter->src + res.start + 1, res.len - 1, &n))
|
||||||
{
|
{
|
||||||
fputs("Error parsing number!", stderr);
|
fputs("Error parsing number!\n", stderr);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
interpreter->call_stack[interpreter->call_stack_len++] = (HYDROFORTH__WORD){
|
interpreter->call_stack[interpreter->call_stack_len++] = (HYDROFORTH__WORD){
|
||||||
|
@ -96,12 +133,12 @@ bool hydroforth__parse(HYDROFORTH__INTERPRETER *interpreter)
|
||||||
.data = {.number = -n},
|
.data = {.number = -n},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
else if (next_is_digit && interpreter->src[start] == '+')
|
else if (next_is_digit && interpreter->src[res.start] == '+')
|
||||||
{
|
{
|
||||||
int n;
|
int n;
|
||||||
if (!hydroforth__number__parse_number(interpreter->src + start + 1, len - 1, &n))
|
if (!hydroforth__number__parse_number(interpreter->src + res.start + 1, res.len - 1, &n))
|
||||||
{
|
{
|
||||||
fputs("Error parsing number!", stderr);
|
fputs("Error parsing number!\n", stderr);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
interpreter->call_stack[interpreter->call_stack_len++] = (HYDROFORTH__WORD){
|
interpreter->call_stack[interpreter->call_stack_len++] = (HYDROFORTH__WORD){
|
||||||
|
@ -109,12 +146,12 @@ bool hydroforth__parse(HYDROFORTH__INTERPRETER *interpreter)
|
||||||
.data = {.number = n},
|
.data = {.number = n},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
else if (hydroforth__number__is_digit(interpreter->src[start]))
|
else if (hydroforth__number__is_digit(interpreter->src[res.start]))
|
||||||
{
|
{
|
||||||
int n;
|
int n;
|
||||||
if (!hydroforth__number__parse_number(interpreter->src + start, len, &n))
|
if (!hydroforth__number__parse_number(interpreter->src + res.start, res.len, &n))
|
||||||
{
|
{
|
||||||
fputs("Error parsing number!", stderr);
|
fputs("Error parsing number!\n", stderr);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
interpreter->call_stack[interpreter->call_stack_len++] = (HYDROFORTH__WORD){
|
interpreter->call_stack[interpreter->call_stack_len++] = (HYDROFORTH__WORD){
|
||||||
|
@ -124,7 +161,7 @@ bool hydroforth__parse(HYDROFORTH__INTERPRETER *interpreter)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
const unsigned int hash = hydroforth__hash_string(interpreter->src + start, len);
|
const unsigned int hash = hydroforth__hash_string(interpreter->src + res.start, res.len);
|
||||||
switch (hash)
|
switch (hash)
|
||||||
{
|
{
|
||||||
case 0x4078cde9: // --
|
case 0x4078cde9: // --
|
||||||
|
@ -161,10 +198,6 @@ 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[interpreter->stack_len - 2] -= interpreter->stack[interpreter->stack_len - 1];
|
||||||
interpreter->stack_len--;
|
interpreter->stack_len--;
|
||||||
|
@ -186,7 +219,8 @@ bool hydroforth__run_call_stack(HYDROFORTH__INTERPRETER *interpreter)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
fprintf(stderr, "Unknown word: '%c'\n", word->data.char_word);
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -195,10 +229,47 @@ bool hydroforth__run_call_stack(HYDROFORTH__INTERPRETER *interpreter)
|
||||||
switch (word->data.hash)
|
switch (word->data.hash)
|
||||||
{
|
{
|
||||||
case 0xaddd94c: // debug
|
case 0xaddd94c: // debug
|
||||||
|
const unsigned char left_width = hydroforth__number__count_digits(interpreter->stack_len);
|
||||||
|
unsigned char right_width = 0;
|
||||||
|
for (unsigned char i = 0; i < interpreter->stack_len; i++)
|
||||||
|
{
|
||||||
|
const unsigned char tmp = hydroforth__number__count_digits(interpreter->stack[i]);
|
||||||
|
if (tmp > right_width)
|
||||||
|
{
|
||||||
|
right_width = tmp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (unsigned char i = 0; i < (2 + left_width + 3 + right_width + 2); i++)
|
||||||
|
{
|
||||||
|
putchar('-');
|
||||||
|
}
|
||||||
|
putchar('\n');
|
||||||
|
for (unsigned char i = interpreter->stack_len - 1; i != 0xff; i--)
|
||||||
|
{
|
||||||
|
printf("| ");
|
||||||
|
const unsigned char left_index_width = left_width - hydroforth__number__count_digits(i);
|
||||||
|
for (unsigned char j = 0; j < left_index_width; j++)
|
||||||
|
{
|
||||||
|
putchar(' ');
|
||||||
|
}
|
||||||
|
printf("%u | ", i);
|
||||||
|
const unsigned char right_index_width = right_width - hydroforth__number__count_digits(interpreter->stack[i]);
|
||||||
|
for (unsigned char j = 0; j < right_index_width; j++)
|
||||||
|
{
|
||||||
|
putchar(' ');
|
||||||
|
}
|
||||||
|
printf("%i |\n", interpreter->stack[i]);
|
||||||
|
}
|
||||||
|
for (unsigned char i = 0; i < (2 + left_width + 3 + right_width + 2); i++)
|
||||||
|
{
|
||||||
|
putchar('-');
|
||||||
|
}
|
||||||
|
putchar('\n');
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
fprintf(stderr, "Unknown word with hash: 0x%x\n", word->data.hash);
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -215,10 +286,6 @@ bool hydroforth__run(HYDROFORTH__INTERPRETER *interpreter)
|
||||||
{
|
{
|
||||||
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;
|
||||||
|
|
|
@ -1,14 +1,15 @@
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
#include <malloc.h>
|
||||||
|
|
||||||
#include "hydroforth/number.h"
|
#include "hydroforth/hydroforth.h"
|
||||||
|
|
||||||
bool hydroforth__number__is_digit(char c)
|
bool hydroforth__number__is_digit(char c)
|
||||||
{
|
{
|
||||||
return '0' <= c && c <= '9';
|
return '0' <= c && c <= '9';
|
||||||
}
|
}
|
||||||
|
|
||||||
bool hydroforth__number__convert_hex_digit(char c, unsigned char *const val)
|
void hydroforth__number__convert_hex_digit(HYDROFORTH__RESULT *const result, char c, unsigned char *const val)
|
||||||
{
|
{
|
||||||
if (hydroforth__number__is_digit(c))
|
if (hydroforth__number__is_digit(c))
|
||||||
{
|
{
|
||||||
|
@ -49,22 +50,28 @@ bool hydroforth__number__convert_hex_digit(char c, unsigned char *const val)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return false;
|
// hydroforth__result__set(result, ERR_INVALID_HEX_CHAR, __func__);
|
||||||
|
hydroforth__set_func_result(result, ERR_INVALID_HEX_CHAR);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
void hydroforth__number__parse_number_hex(HYDROFORTH__RESULT *const result, const char *const start, unsigned char len, int *const val)
|
||||||
}
|
|
||||||
|
|
||||||
bool hydroforth__number__parse_number_hex(const char *const start, unsigned char len, int *const val)
|
|
||||||
{
|
{
|
||||||
int n;
|
int n;
|
||||||
for (unsigned char i = 0; i < len; i++)
|
for (unsigned char i = 0; i < len; i++)
|
||||||
{
|
{
|
||||||
unsigned char m;
|
unsigned char m;
|
||||||
if (!hydroforth__number__convert_hex_digit(start[i], &m))
|
// if (!hydroforth__number__convert_hex_digit(result, start[i], &m))
|
||||||
|
// {
|
||||||
|
// return false;
|
||||||
|
// }
|
||||||
|
hydroforth__number__convert_hex_digit(result, start[i], &m);
|
||||||
|
if (result->error != OK)
|
||||||
{
|
{
|
||||||
return false;
|
hydroforth__add_func_backtrace(result);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
n *= 16;
|
n *= 16;
|
||||||
n += m;
|
n += m;
|
||||||
|
@ -73,7 +80,7 @@ bool hydroforth__number__parse_number_hex(const char *const start, unsigned char
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool hydroforth__number__parse_number(const char *const start, unsigned char len, int *const val)
|
void hydroforth__number__parse_number(HYDROFORTH__RESULT *const result, const char *const start, unsigned char len, int *const val)
|
||||||
{
|
{
|
||||||
if (start[0] == '0')
|
if (start[0] == '0')
|
||||||
{
|
{
|
||||||
|
@ -83,16 +90,25 @@ bool hydroforth__number__parse_number(const char *const start, unsigned char len
|
||||||
{
|
{
|
||||||
case 'X':
|
case 'X':
|
||||||
case 'x':
|
case 'x':
|
||||||
return hydroforth__number__parse_number_hex(start + 2, len - 2, val);
|
hydroforth__number__parse_number_hex(result, start + 2, len - 2, val);
|
||||||
|
if (result->error != OK)
|
||||||
|
{
|
||||||
|
hydroforth__add_func_backtrace(result);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return hydroforth__number__parse_number(start + 1, len - 1, val);
|
hydroforth__number__parse_number(result, start + 1, len - 1, val);
|
||||||
|
if (result->error != OK)
|
||||||
|
{
|
||||||
|
hydroforth__add_func_backtrace(result);
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
*val = 0;
|
*val = 0;
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -104,6 +120,24 @@ bool hydroforth__number__parse_number(const char *const start, unsigned char len
|
||||||
n += start[i] - '0';
|
n += start[i] - '0';
|
||||||
}
|
}
|
||||||
*val = n;
|
*val = n;
|
||||||
return true;
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned char hydroforth__number__count_digits(int n)
|
||||||
|
{
|
||||||
|
if (n == 0)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
unsigned char res = 0;
|
||||||
|
while (n != 0)
|
||||||
|
{
|
||||||
|
n /= 10;
|
||||||
|
res++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
13
src/hydroforth/result.c
Normal file
13
src/hydroforth/result.c
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
#include "hydroforth/hydroforth.h"
|
||||||
|
|
||||||
|
void hydroforth__result__add_backtrace(HYDROFORTH__RESULT *const result, const char *const s)
|
||||||
|
{
|
||||||
|
realloc(result->backtrace, sizeof(char *) * (result->backtrace_len + 1));
|
||||||
|
result->backtrace[result->backtrace_len++] = s;
|
||||||
|
}
|
||||||
|
|
||||||
|
void hydroforth__result__set(HYDROFORTH__RESULT *const result, HYDROFORTH__ERROR error, const char *const s)
|
||||||
|
{
|
||||||
|
result->error = error;
|
||||||
|
hydroforth__result__add_backtrace(result, s);
|
||||||
|
}
|
12
src/main.c
12
src/main.c
|
@ -14,7 +14,7 @@ struct ReadSrcResult read_src(FILE *fp)
|
||||||
{
|
{
|
||||||
if (fseek(fp, 0L, SEEK_END) != 0)
|
if (fseek(fp, 0L, SEEK_END) != 0)
|
||||||
{
|
{
|
||||||
fputs("Error seeking to file end!", stderr);
|
fputs("Error seeking to file end!\n", stderr);
|
||||||
return (struct ReadSrcResult){
|
return (struct ReadSrcResult){
|
||||||
.success = false,
|
.success = false,
|
||||||
};
|
};
|
||||||
|
@ -22,7 +22,7 @@ struct ReadSrcResult read_src(FILE *fp)
|
||||||
const long bufsize = ftell(fp);
|
const long bufsize = ftell(fp);
|
||||||
if (bufsize == -1)
|
if (bufsize == -1)
|
||||||
{
|
{
|
||||||
fputs("Error getting file size!", stderr);
|
fputs("Error getting file size!\n", stderr);
|
||||||
return (struct ReadSrcResult){
|
return (struct ReadSrcResult){
|
||||||
.success = false,
|
.success = false,
|
||||||
};
|
};
|
||||||
|
@ -30,7 +30,7 @@ struct ReadSrcResult read_src(FILE *fp)
|
||||||
char *const src = malloc(sizeof(char) * bufsize);
|
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!\n", stderr);
|
||||||
return (struct ReadSrcResult){
|
return (struct ReadSrcResult){
|
||||||
.success = false,
|
.success = false,
|
||||||
};
|
};
|
||||||
|
@ -38,7 +38,7 @@ struct ReadSrcResult read_src(FILE *fp)
|
||||||
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!\n", stderr);
|
||||||
return (struct ReadSrcResult){
|
return (struct ReadSrcResult){
|
||||||
.success = false,
|
.success = false,
|
||||||
};
|
};
|
||||||
|
@ -54,13 +54,13 @@ int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
if (argc < 2)
|
if (argc < 2)
|
||||||
{
|
{
|
||||||
fputs("No source file specified!", stderr);
|
fputs("No source file specified!\n", stderr);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
FILE *fp = fopen(argv[1], "rb");
|
FILE *fp = fopen(argv[1], "rb");
|
||||||
if (fp == NULL)
|
if (fp == NULL)
|
||||||
{
|
{
|
||||||
fputs("Error opening file!", stderr);
|
fputs("Error opening file!\n", stderr);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
const struct ReadSrcResult res = read_src(fp);
|
const struct ReadSrcResult res = read_src(fp);
|
||||||
|
|
1
test.fth
1
test.fth
|
@ -1 +1,2 @@
|
||||||
|
: test 42 ;
|
||||||
40 2 + debug
|
40 2 + debug
|
||||||
|
|
Loading…
Reference in a new issue