From 471cf679cdb7d79fde2b4c224c7a66800d8d82c9 Mon Sep 17 00:00:00 2001 From: VegOwOtenks Date: Thu, 10 Oct 2024 18:53:40 +0200 Subject: [PATCH] List type and generic base type, char wrapper type --- src/callframe.c | 15 +++++++++++++++ src/callframe.h | 8 ++++++++ src/interpreter.c | 41 ++++++++++++++++++++++++++++++++++++++++- src/interpreter.h | 4 ++++ src/object-type.c | 45 +++++++++++++++++++++++++++++++++++++++++++++ src/object-type.h | 16 ++++++++++++---- 6 files changed, 124 insertions(+), 5 deletions(-) create mode 100644 src/object-type.c diff --git a/src/callframe.c b/src/callframe.c index 608e2be..f8a4972 100644 --- a/src/callframe.c +++ b/src/callframe.c @@ -53,6 +53,21 @@ int CallFrame_DefineVariable(CallFrame* self, StringView name, Value value) return EXIT_SUCCESS; } +int CallFrame_DefineObjectType(CallFrame* self, ObjectType* type) +{ + FlupType* t = CallFrame_Reserve(self, sizeof(FlupType), alignof(FlupType)); + if (t == NULL) { + return ENOMEM; + } + + t->type = type; + + // prepend to linked list + t->next = self->types; + self->types = t; + + return EXIT_SUCCESS; +} int CallFrame_StackPop(CallFrame* self, Value* dest) { diff --git a/src/callframe.h b/src/callframe.h index 37b023a..2d54e39 100644 --- a/src/callframe.h +++ b/src/callframe.h @@ -27,6 +27,11 @@ #include "../submodules/utilitiec/src/StringView/StringView.h" #include "../submodules/utilitiec/src/Scratchpad/Scratchpad.h" +typedef struct FlupType_s { + ObjectType* type; + struct FlupType_s* next; +} FlupType; + typedef struct CallFrame_s { size_t instruction_pointer; /* ip = condition start : start @@ -34,9 +39,11 @@ typedef struct CallFrame_s { * */ FlupFunction* self_function; + FlupFunctionAlternative* alternative; FlupFunction* functions; // functions defined in this callframe FlupVariable* variables; // variables defined in this callframe + FlupType* types; // types defined in this callframe DynamicArray stack; // Value Scratchpad memory_pad; } CallFrame; @@ -45,6 +52,7 @@ int CallFrame_Create(CallFrame* self, FlupFunction* self_function); void CallFrame_Destroy(CallFrame* self); int CallFrame_DefineVariable(CallFrame* self, StringView name, Value value); +int CallFrame_DefineObjectType(CallFrame* self, ObjectType* type); int CallFrame_StackPop(CallFrame* self, Value* dest); int CallFrame_StackPush(CallFrame* self, Value* value); FlupVariable* CallFrame_FindVariable(CallFrame* self, StringView name); diff --git a/src/interpreter.c b/src/interpreter.c index 936bd41..a66e8f5 100644 --- a/src/interpreter.c +++ b/src/interpreter.c @@ -1,5 +1,6 @@ #include "interpreter.h" #include "builtin-functions.h" +#include "object-type.h" #include #include @@ -484,6 +485,11 @@ int Interpreter_ExecuteNext(Interpreter* self, size_t stop_token) top_frame->instruction_pointer++; break; + case TOKENTYPE_STRING: + { + } + break; + case TOKENTYPE_PIPE: case TOKENTYPE_SEMICOLON: case TOKENTYPE_LEFT_BRACE: @@ -500,7 +506,6 @@ int Interpreter_ExecuteNext(Interpreter* self, size_t stop_token) case TOKENTYPE_COMMA: case TOKENTYPE_LEFT_PAREN: case TOKENTYPE_RIGHT_PAREN: - case TOKENTYPE_STRING: fprintf(stderr, "Unexpected token with type: %s, continuing with next token...\n", TokenType_ToString(t->type)); top_frame->instruction_pointer++; break; @@ -620,6 +625,40 @@ int Interpreter_Run(Interpreter* self) return EXIT_SUCCESS; } +int Interpreter_Startup(Interpreter* self, CallFrame* root_frame) +{ + ObjectType* base_type = CallFrame_Reserve(root_frame, sizeof(ObjectType), alignof(ObjectType)); + if (ObjectType_Create(base_type, StringView_FromString("Base"), base_type, 0, NULL)) { + return ENOMEM; + } + + ObjectType* list_type = CallFrame_Reserve(root_frame, sizeof(ObjectType), alignof(ObjectType)); + if (ObjectType_Create(list_type, StringView_FromString("List"), base_type, 2, NULL)) { + return ENOMEM; + } + if (ObjectType_DefineObjectAttribute(list_type, base_type, StringView_FromString("value"))) { + return ENOMEM; + } + if (ObjectType_DefineObjectAttribute(list_type, list_type, StringView_FromString("tail"))) { + return ENOMEM; + } + if (CallFrame_DefineObjectType(root_frame, list_type)) { + return ENOMEM; + } + + ObjectType* char_type = CallFrame_Reserve(root_frame, sizeof(ObjectType), alignof(ObjectType)); + if (ObjectType_Create(char_type, StringView_FromString("Char"), base_type, 2, NULL)) { + return ENOMEM; + } + if (ObjectType_DefinePrimitiveAttribute(list_type, VALUETYPE_BYTE, StringView_FromString("char"))) { + return ENOMEM; + } + + self->implicit_char_type = char_type; + self->implicit_base_type = base_type; + return EXIT_SUCCESS; +} + int Interpreter_Interpret(Interpreter* self) { CallFrame* first_frame; diff --git a/src/interpreter.h b/src/interpreter.h index 49f1b6a..4b48a25 100644 --- a/src/interpreter.h +++ b/src/interpreter.h @@ -19,6 +19,10 @@ struct Interpreter_s { DynamicArray* tokens; DynamicArray call_frames; // stores CallFrame + + // global stuff + ObjectType* implicit_char_type; + ObjectType* implicit_base_type; }; int Interpreter_Create(Interpreter* self, DynamicArray* tokens); diff --git a/src/object-type.c b/src/object-type.c new file mode 100644 index 0000000..cee326d --- /dev/null +++ b/src/object-type.c @@ -0,0 +1,45 @@ +#include "object-type.h" + +int ObjectType_Create(ObjectType* self, StringView name, ObjectType* supertype, size_t attribute_count_guess, allocator_t* allocator) +{ + struct HashMapConfig config = HashMap_DefaultConfig(); + config.allocator = allocator; + int hashmap_code = HashMap_Create(&self->attributes, &config, attribute_count_guess * (1 / config.load_factor) + 1); + if (hashmap_code) { + return hashmap_code; + } + self->name = name; + self->reference_count = 0; + supertype->reference_count++; + + return EXIT_SUCCESS; +} + +void ObjectType_Destroy(ObjectType* self) +{ + self->supertype->reference_count--; + // TODO: Emit a warning when there are still references? + HashMap_Destroy(&self->attributes); +} + +int ObjectType_DefineObjectAttribute(ObjectType* self, ObjectType* attribute_type, StringView attribute_name) +{ + ObjectTypeAttribute attribute = { + .name = attribute_name, + VALUETYPE_OBJECT, + attribute_type, + HashMap_Size(&self->attributes), + }; + return HashMap_Put(&self->attributes, attribute_name.source, attribute_name.length, &attribute); +} + +int ObjectType_DefinePrimitiveAttribute(ObjectType* self, enum ValueType attribute_type, StringView attribute_name) +{ + ObjectTypeAttribute attribute = { + .name = attribute_name, + attribute_type, + NULL, + HashMap_Size(&self->attributes), + }; + return HashMap_Put(&self->attributes, attribute_name.source, attribute_name.length, &attribute); +} diff --git a/src/object-type.h b/src/object-type.h index edc0350..a4dcdfc 100644 --- a/src/object-type.h +++ b/src/object-type.h @@ -1,5 +1,3 @@ - - /* * This code is part of the programming language flup * flup comes with ABSOLUTELY NO WARRANTY and is licensed under AGPL-3.0 or later. @@ -25,17 +23,27 @@ #include "../submodules/utilitiec/src/hashmap/hashmap.h" #include "../submodules/utilitiec/src/StringView/StringView.h" +typedef struct ObjectType_s ObjectType; + #include "value.h" typedef struct ObjectTypeAttribute_s { StringView name; enum ValueType type; + ObjectType* object_type; // only active if there type is VALUETYPE_OBJECT uint32_t index; } ObjectTypeAttribute; -typedef struct ObjectType_s { +struct ObjectType_s { hashmap_t attributes; // map of (char* name) -> (ObjectTypeAttribute entry) StringView name; -} ObjectType; + size_t reference_count; // count of references from subtypes and object instances + struct ObjectType_s* supertype; +}; + +void ObjectType_Destroy(ObjectType* self); +int ObjectType_Create(ObjectType* self, StringView name, ObjectType* supertype, size_t attribute_count_guess, allocator_t* allocator); +int ObjectType_DefineObjectAttribute(ObjectType* self, ObjectType* attribute_type, StringView attribute_name); +int ObjectType_DefinePrimitiveAttribute(ObjectType* self, enum ValueType attribute_type, StringView attribute_name); #endif