This commit is contained in:
Dominic Grimm 2022-12-22 13:19:33 +01:00
commit 2a9968c4ce
No known key found for this signature in database
GPG key ID: 6F294212DEAAC530
8 changed files with 302 additions and 0 deletions

1
.gitignore vendored Normal file
View file

@ -0,0 +1 @@
build/

8
CMakeLists.txt Normal file
View file

@ -0,0 +1,8 @@
cmake_minimum_required(VERSION 3.22.1)
project(hydroforth)
file(GLOB_RECURSE SOURCES ${PROJECT_SOURCE_DIR}/src/*.c)
add_executable(hydroforth ${SOURCES})
target_include_directories(hydroforth PRIVATE ${PROJECT_SOURCE_DIR}/include)

View file

@ -0,0 +1,59 @@
#ifndef __HYDROFORTH_H__
#define __HYDROFORTH_H__
#include <stdbool.h>
#include "number.h"
typedef enum HYDROFORTH__WORD_TYPE
{
PUSH,
CHAR_WORD,
WORD,
} HYDROFORTH__WORD_TYPE;
typedef union HYDROFORTH__WORD_DATA
{
int number;
char char_word;
char *word;
} HYDROFORTH__WORD_DATA;
typedef struct HYDROFORTH__WORD
{
HYDROFORTH__WORD_TYPE type;
HYDROFORTH__WORD_DATA data;
} HYDROFORTH__WORD;
typedef struct HYDROFORTH__INTERPRETER
{
char *src;
unsigned long pos;
HYDROFORTH__WORD call_stack[256];
unsigned char call_stack_len;
int stack[256];
unsigned char stack_len;
} HYDROFORTH__INTERPRETER;
extern bool hydroforth__step(HYDROFORTH__INTERPRETER *interpreter);
extern bool hydroforth__run(HYDROFORTH__INTERPRETER *interpreter);
typedef struct __HYDROFORTH
{
__HYDROFORTH__NUMBER number;
bool (*step)(HYDROFORTH__INTERPRETER *interpreter);
bool (*run)(HYDROFORTH__INTERPRETER *interpreter);
} __HYDROFORTH;
static const __HYDROFORTH hydroforth = {
.number = {
.is_digit = hydroforth__number__is_digit,
.parse_number = hydroforth__number__parse_number,
.parse_number_with_sign = hydroforth__number__parse_number_with_sign,
},
.step = hydroforth__step,
.run = hydroforth__run,
};
#endif

View file

@ -0,0 +1,19 @@
#ifndef __HYDROFORTH__NUMBER_H__
#define __HYDROFORTH__NUMBER_H__
#include <stdbool.h>
extern bool hydroforth__number__is_digit(char c);
extern bool hydroforth__number__parse_number(const char *const start, unsigned char len, int *const val);
extern bool hydroforth__number__parse_number_with_sign(const char *const start, unsigned char len, int *const val);
typedef struct __HYDROFORTH__NUMBER
{
bool (*is_digit)(char c);
bool (*parse_number)(const char *const start, unsigned char len, int *const val);
bool (*parse_number_with_sign)(const char *const start, unsigned char len, int *const val);
} __HYDROFORTH__NUMBER;
#endif

View file

@ -0,0 +1,76 @@
#include <stdbool.h>
#include <stdio.h>
#include "hydroforth/hydroforth.h"
bool hydroforth__step(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++;
}
printf("START: %lu\nLEN: %u\n", start, len);
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
{
if ((interpreter->src[start] == '-' || interpreter->src[start] == '+') &&
hydroforth__number__is_digit(interpreter->src[start + 1]))
{
}
else if (hydroforth__number__is_digit(interpreter->src[start]))
{
int n;
if (!hydroforth__number__parse_number(interpreter->src + start, len, &n))
{
printf("RESULT IS FALSE!!!\nNUMBER: %i\n", n);
return false;
}
printf("NUMBER: %i\n", n);
}
else
{
}
}
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])
{
puts("END REACHED!");
return true;
}
if (!hydroforth__step(interpreter))
{
return false;
}
}
}

49
src/hydroforth/number.c Normal file
View file

@ -0,0 +1,49 @@
#include <stdbool.h>
#include <stddef.h>
#include "hydroforth/number.h"
bool hydroforth__number__is_digit(char c)
{
return '0' <= c && c <= '9';
}
bool hydroforth__number__parse_number(const char *const start, unsigned char len, int *const val)
{
int num;
if (start[0] == '0')
{
if (len > 1)
{
switch (start[1])
{
case 'X':
case 'x':
return false;
default:
return hydroforth__number__parse_number(start + 1, len - 1, val);
}
}
else
{
*val = 0;
return true;
}
}
else
{
int n = start[0] - '0';
for (unsigned char i = 1; i < len; i++)
{
n *= 10;
n += start[i] - '0';
}
*val = n;
return true;
}
}
bool hydroforth__number__parse_number_with_sign(const char *const start, unsigned char len, int *const val)
{
}

89
src/main.c Normal file
View file

@ -0,0 +1,89 @@
#include <stdlib.h>
#include <stdio.h>
#include <stdbool.h>
#include "hydroforth/hydroforth.h"
struct ReadSrcResult
{
bool success;
char *const src;
};
struct ReadSrcResult read_src(FILE *fp)
{
if (fseek(fp, 0L, SEEK_END) != 0)
{
fputs("Error seeking to file end!", stderr);
return (struct ReadSrcResult){
.success = false,
};
}
const long bufsize = ftell(fp);
if (bufsize == -1)
{
fputs("Error getting file size!", stderr);
return (struct ReadSrcResult){
.success = false,
};
}
char *const src = malloc(sizeof(char) * (bufsize + 1));
if (fseek(fp, 0L, SEEK_SET) != 0)
{
fputs("Error rewinding file to start!", stderr);
return (struct ReadSrcResult){
.success = false,
};
}
const unsigned long new_len = fread(src, sizeof(char), bufsize, fp);
if (ferror(fp) != 0)
{
fputs("Error reading file!", stderr);
return (struct ReadSrcResult){
.success = false,
};
}
src[new_len + 1] = '\0';
return (struct ReadSrcResult){
.success = true,
.src = src,
};
}
int main(int argc, char *argv[])
{
if (argc < 2)
{
fputs("No source file specified!", stderr);
return 1;
}
FILE *fp = fopen(argv[1], "rb");
if (fp == NULL)
{
fputs("Error opening file!", stderr);
return 1;
}
const struct ReadSrcResult res = read_src(fp);
fclose(fp);
if (res.success)
{
HYDROFORTH__INTERPRETER interpreter = {
.src = res.src,
.pos = 0,
};
const bool run_res = hydroforth.run(&interpreter);
free(res.src);
if (!run_res)
{
return 1;
}
}
else
{
free(res.src);
return 1;
}
return 0;
}

1
test.fth Normal file
View file

@ -0,0 +1 @@
40 2 + debug