From 3bf4a73c2e2b05e78620f97b8394988c29051de3 Mon Sep 17 00:00:00 2001 From: VegOwOtenks Date: Tue, 1 Oct 2024 21:37:26 +0200 Subject: [PATCH] Did some work today, including function parsing --- make.sh | 9 +- src/interpreter.c | 259 ++++++++++++++++++++++++++++++++++++++++++- src/interpreter.h | 11 +- submodules/utilitiec | 2 +- 4 files changed, 275 insertions(+), 6 deletions(-) diff --git a/make.sh b/make.sh index 9f07a21..80f8179 100644 --- a/make.sh +++ b/make.sh @@ -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 diff --git a/src/interpreter.c b/src/interpreter.c index 227bfc3..38832bd 100644 --- a/src/interpreter.c +++ b/src/interpreter.c @@ -1,16 +1,28 @@ #include "interpreter.h" +#include + 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; } diff --git a/src/interpreter.h b/src/interpreter.h index a1b7201..47a44da 100644 --- a/src/interpreter.h +++ b/src/interpreter.h @@ -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 @@ -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 { diff --git a/submodules/utilitiec b/submodules/utilitiec index 7d8ba6f..c2c3c2d 160000 --- a/submodules/utilitiec +++ b/submodules/utilitiec @@ -1 +1 @@ -Subproject commit 7d8ba6fc28487901a6f73d75eb59dabe416fe391 +Subproject commit c2c3c2d96e6296b439e901c89d868185cdc82960