Did some work today, including function parsing

This commit is contained in:
VegOwOtenks 2024-10-01 21:37:26 +02:00
parent 85192bb4c1
commit 3bf4a73c2e
4 changed files with 275 additions and 6 deletions

View file

@ -1 +1,8 @@
gcc `find src/ -name '*.c'` lib/utilitiec/libargumentc.a lib/utilitiec/libdynamicarray.a lib/utilitiec/libpointers.a lib/utilitiec/liballocator-interface.a lib/utilitiec/libStringView.a -lm -ggdb -o bin/flup
gcc `find src/ -name '*.c'` \
submodules/utilitiec/build/lib/libargumentc.a \
submodules/utilitiec/build/lib/libdynamicarray.a \
submodules/utilitiec/build/lib/libpointers.a \
submodules/utilitiec/build/lib/liballocator-interface.a \
submodules/utilitiec/build/lib/libStringView.a \
submodules/utilitiec/build/lib/libScratchpad.a \
-lm -ggdb -Wall -o bin/flup

View file

@ -1,16 +1,28 @@
#include "interpreter.h"
#include <stdalign.h>
static int CallFrame_Create(CallFrame* self, FlupFunctionAlternative* f)
{
if (DynamicArray_Create(&self->stack, sizeof(Value), 8, NULL)) {
return ENOMEM;
}
self->memory_pad.memory = NULL;
self->function = f;
self->instruction_pointer = f->body_token_start;
return EXIT_SUCCESS;
}
static void* CallFrame_Reserve(CallFrame* self, size_t amount, size_t alignment)
{
if (self->memory_pad.memory == NULL) {
if (Scratchpad_Create(&self->memory_pad, 1024, NULL)) return NULL;
}
return Scratchpad_ReserveAligned(&self->memory_pad, amount, alignment);
}
static FlupFunctionAlternative* FlupFunctionAlternative_Malloc(size_t condition_token_start, size_t condition_token_end, size_t body_token_start, size_t body_token_end)
{
FlupFunctionAlternative* a = malloc(sizeof(FlupFunctionAlternative));
@ -33,14 +45,257 @@ int Interpreter_Create(Interpreter* self, DynamicArray* tokens)
return EXIT_SUCCESS;
}
Token* Interpreter_GetToken(Interpreter* self, size_t index)
{
return DynamicArray_GetPointer(self->tokens, index);
}
Token* Interpreter_ExpectToken(Interpreter* self, CallFrame* top_frame, size_t stop_index)
{
if (top_frame->instruction_pointer > stop_index) {
return NULL;
}
return Interpreter_GetToken(self, top_frame->instruction_pointer);
}
int Interpreter_ParseFunction(Interpreter* self, CallFrame* top_frame, size_t stop_index)
{
FlupFunction* f = CallFrame_Reserve(top_frame, sizeof(FlupFunction), alignof(FlupFunction));
if (f == NULL) return ENOMEM;
Token* function_name = Interpreter_GetToken(self, top_frame->instruction_pointer);
f->name = function_name->get.identifier;
top_frame->instruction_pointer++;
// one token colon
top_frame->instruction_pointer++;
Token* parameter_type = Interpreter_ExpectToken(self, top_frame, stop_index);
ParameterDefinition** pdef = &f->parameters;
while (parameter_type->type != TOKENTYPE_ARROW) {
top_frame->instruction_pointer++;
Token* parameter_name = Interpreter_ExpectToken(self, top_frame, stop_index);
top_frame->instruction_pointer++;
if (parameter_type->type != TOKENTYPE_IDENTIFIER) {
// TODO: Error message
return EXIT_FAILURE;
}
if (parameter_name->type != TOKENTYPE_IDENTIFIER) {
// TODO: Error message
return EXIT_FAILURE;
}
*pdef = CallFrame_Reserve(top_frame, sizeof(**pdef), alignof(**pdef));
if (*pdef == NULL) {
return ENOMEM;
}
(*pdef)->type = parameter_type->get.identifier;
(*pdef)->name = parameter_name->get.identifier;
pdef = &((*pdef)->next);
parameter_type = Interpreter_ExpectToken(self, top_frame, stop_index);
}
// one arrow token
top_frame->instruction_pointer++;
{
Token* return_type = Interpreter_ExpectToken(self, top_frame, stop_index);
if (return_type == NULL) {
return EXIT_FAILURE;
}
if (return_type->type != TOKENTYPE_IDENTIFIER) {
return EXIT_FAILURE;
}
top_frame->instruction_pointer++;
f->return_type = return_type->get.identifier;
}
// pipe token
Token* alternative_start = Interpreter_ExpectToken(self, top_frame, stop_index);
if (alternative_start == NULL) {
return EXIT_FAILURE;
}
FlupFunctionAlternative** fdef = &f->alternative;
while (alternative_start->type == TOKENTYPE_PIPE) {
top_frame->instruction_pointer++;
size_t condition_start = top_frame->instruction_pointer;
Token* current;
do {
current = Interpreter_ExpectToken(self, top_frame, stop_index);
top_frame->instruction_pointer++;
if (current == NULL) {
return EXIT_FAILURE;
}
} while (current->type != TOKENTYPE_ARROW);
size_t condition_end = top_frame->instruction_pointer - 1;
size_t body_start = top_frame->instruction_pointer + 1;
do {
current = Interpreter_ExpectToken(self, top_frame, stop_index);
top_frame->instruction_pointer++;
if (current == NULL) {
return EXIT_FAILURE;
}
} while (current->type != TOKENTYPE_PIPE && current->type != TOKENTYPE_COLON);
top_frame->instruction_pointer--;
size_t body_end = top_frame->instruction_pointer;
*fdef = CallFrame_Reserve(top_frame, sizeof(**pdef), alignof(**pdef));
if (*fdef == NULL) {
return ENOMEM;
}
(*fdef)->condition_token_start = condition_start;
(*fdef)->condition_token_end = condition_end;
(*fdef)->body_token_start = body_start;
(*fdef)->body_token_end = body_end;
fdef = &((*fdef)->next);
alternative_start = Interpreter_ExpectToken(self, top_frame, stop_index);
if (alternative_start == NULL) {
return EXIT_FAILURE;
}
}
// one token colon
top_frame->instruction_pointer++;
return EXIT_SUCCESS;
}
int Interpreter_ExecuteNext(Interpreter* self, size_t stop_token)
{
size_t frame_count = DynamicArray_GetLength(&self->call_frames);
CallFrame* top_frame = DynamicArray_GetPointer(&self->call_frames, frame_count - 1);
Token* t = Interpreter_GetToken(self, top_frame->instruction_pointer);
switch (t->type) {
case TOKENTYPE_INTEGER:
{
Value* v;
DynamicArray_AppendEmpty(&top_frame->stack, (void**) &v);
if (v == NULL) return ENOMEM;
v->type = VALUETYPE_INT64;
v->get.i64 = t->get.integer;
top_frame->instruction_pointer++;
break;
}
case TOKENTYPE_DOUBLE:
{
Value* v;
DynamicArray_AppendEmpty(&top_frame->stack, (void**) &v);
if (v == NULL) return ENOMEM;
v->type = VALUETYPE_DOUBLE;
v->get.f64 = t->get.decimal;
top_frame->instruction_pointer++;
break;
}
case TOKENTYPE_IDENTIFIER:
{
Token* next = Interpreter_GetToken(self, top_frame->instruction_pointer + 1);
if (next != NULL && next->type == TOKENTYPE_COLON) {
// function definition
return Interpreter_ParseFunction(self, top_frame, stop_token);
} else {
// regular call
}
}
case TOKENTYPE_LEFT_BRACE:
case TOKENTYPE_RIGHT_BRACE:
case TOKENTYPE_AMPERSAND:
case TOKENTYPE_PLUS:
case TOKENTYPE_MINUS:
case TOKENTYPE_MULTIPLY:
case TOKENTYPE_DIVIDE:
case TOKENTYPE_PIPE:
case TOKENTYPE_ARROW:
case TOKENTYPE_COLON:
case TOKENTYPE_EQUALITY:
case TOKENTYPE_INEQUALITY:
case TOKENTYPE_LESSTHAN:
case TOKENTYPE_LESSEQUAL:
case TOKENTYPE_GREATERTHAN:
case TOKENTYPE_GREATEREQUAL:
case TOKENTYPE_COMMA:
break;
case TOKENTYPE_NONE:
case TOKENTYPE_ERROR:
default:
return EXIT_FAILURE;
}
}
#define RPN(a,b,c) a c b
int Interpreter_RunFrame(Interpreter* self)
{
size_t frame_count = DynamicArray_GetLength(&self->call_frames);
CallFrame* top_frame = DynamicArray_GetPointer(&self->call_frames, frame_count - 1);
if (
top_frame->instruction_pointer >= top_frame->function->condition_token_start
&& top_frame->instruction_pointer <= top_frame->function->condition_token_end
) {
// alternative executing
while (top_frame->instruction_pointer <= top_frame->function->condition_token_end) {
Interpreter_ExecuteNext(self, top_frame->function->condition_token_end);
if (RPN(frame_count, DynamicArray_GetLength(&self->call_frames), !=)) {
return EXIT_SUCCESS;
}
}
} else {
// function executing
while (top_frame->instruction_pointer <= top_frame->function->body_token_end) {
Interpreter_ExecuteNext(self, top_frame->function->body_token_end);
if (RPN(frame_count, DynamicArray_GetLength(&self->call_frames), !=)) {
return EXIT_SUCCESS;
}
}
}
return EXIT_SUCCESS;
}
int Interpreter_Run(Interpreter* self)
{
size_t frame_count;
do {
frame_count = DynamicArray_GetLength(&self->call_frames);
if (Interpreter_RunFrame(self)) {
// TODO: Return the error code
return EXIT_FAILURE;
}
} while (frame_count != 0);
return EXIT_SUCCESS;
}
int Interpreter_Interpret(Interpreter* self)
{
CallFrame* first_frame;
DynamicArray_AppendEmpty(&self->call_frames, (void**) &first_frame);
if (CallFrame_Create(first_frame, )) {
FlupFunctionAlternative* file_function = FlupFunctionAlternative_Malloc(SIZE_MAX, SIZE_MAX, 0, DynamicArray_GetLength(self->tokens));
if (file_function == NULL) {
return ENOMEM;
}
DynamicArray_AppendEmpty(&self->call_frames, (void**) &first_frame);
if (CallFrame_Create(first_frame, file_function)) {
return ENOMEM;
}
Interpreter_Run(self);
return EXIT_SUCCESS;
}

View file

@ -2,6 +2,7 @@
#define FLUP_INTERPRETER_H
#include "../submodules/utilitiec/src/dynamicarray/dynamicarray.h"
#include "../submodules/utilitiec/src/Scratchpad/Scratchpad.h"
#include "tokenizer.h"
#include <stdint.h>
@ -15,13 +16,14 @@ typedef struct FlupFunctionAlternative_s {
} FlupFunctionAlternative;
typedef struct ParameterDefinition_s {
StringView name;
StringView type;
StringView name;
struct ParameterDefinition_s* next;
} ParameterDefinition;
typedef struct FlupFunction_s {
StringView name;
DynamicArray argument_defs; // ParameterDefinition
ParameterDefinition* parameters;
StringView return_type;
FlupFunctionAlternative* alternative;
} FlupFunction;
@ -43,8 +45,13 @@ typedef struct Value_s {
typedef struct CallFrame_s {
size_t instruction_pointer;
/* ip = condition start : start
* ip = condition_end + 1 : done
*
*/
FlupFunctionAlternative* function;
DynamicArray stack; // Value
Scratchpad memory_pad;
} CallFrame;
typedef struct Interpreter_s {

@ -1 +1 @@
Subproject commit 7d8ba6fc28487901a6f73d75eb59dabe416fe391
Subproject commit c2c3c2d96e6296b439e901c89d868185cdc82960