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,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;
}