From 95875703a6d5c75a35ac38989572466cda2c3e6b Mon Sep 17 00:00:00 2001 From: Ludovic 'Archivist' Lagouardette Date: Thu, 9 Oct 2025 21:34:22 +0200 Subject: [PATCH] Make it possible to redefine functions --- lib.c | 177 ++++++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 117 insertions(+), 60 deletions(-) diff --git a/lib.c b/lib.c index ab15cbb..4891cf0 100644 --- a/lib.c +++ b/lib.c @@ -241,54 +241,89 @@ int ink_add_native(struct context* ctx, const char* name, void(*value)(struct co } static int ink_add_indigenous(struct context* ctx, char* name, struct elem* m, size_t count) { - int tid; - struct elem e; - int i; - struct ink_array ary; - const char* name_it; - struct elem character; - tid = get_type_by_name(ctx, "array"); - ary.elements = NULL; - ary.top = 0; - ary.capacity = 0; - ary.flags = 0; - - if(ctx->words == NULL) { - ctx->words = ctx->malloc(ctx, sizeof(struct fn) * 8); - ctx->words_top = 0; - ctx->words_capacity = 8; - } else if(ctx->words_top == ctx->words_capacity) { - int new_count; - void* renewed; - new_count = (ctx->words_capacity + ctx->words_capacity/2); - renewed = ctx->realloc(ctx, ctx->words, sizeof(struct fn) * new_count); - if(renewed == NULL) { - return -1; - } else { - ctx->words = renewed; - ctx->words_capacity = new_count; - } - } - name_it = name; - while (utf8_consume(&name_it, &character)) { - array_push_s(ctx, &ary, character); - } - e = ink_make_native(ctx, tid, &ary); - for(i = 0; i < ctx->words_top; ++i) { - struct ink_array* inner_name = ink_get_value(ctx, ctx->words[i].name); - if(ary.top == inner_name->top && memcmp(ary.elements, inner_name->elements, sizeof(struct elem)*ary.top) == 0) { - if(ctx->words[i].things != NULL) ctx->free(ctx, ctx->words[i].things); - ctx->words[i].things = ctx->malloc(ctx, sizeof(struct elem) * count); - memcpy(ctx->words[i].things, m, sizeof(struct elem) * count); - ctx->words[i].size = count; - return i; - } - } - ctx->words[ctx->words_top].things = ctx->malloc(ctx, sizeof(struct elem) * count); - memcpy(ctx->words[ctx->words_top].things, m, sizeof(struct elem) * count); - ctx->words[ctx->words_top].size = count; - ctx->words[ctx->words_top].name = e; - return ctx->words_top++; + int tid; + struct elem e; + int i; + struct ink_array ary; + const char* name_it; + struct elem character; + tid = get_type_by_name(ctx, "array"); + ary.elements = NULL; + ary.top = 0; + ary.capacity = 0; + ary.flags = 0; + + if(ctx->words == NULL) { + ctx->words = ctx->malloc(ctx, sizeof(struct fn) * 8); + ctx->words_top = 0; + ctx->words_capacity = 8; + } else if(ctx->words_top == ctx->words_capacity) { + int new_count; + void* renewed; + new_count = (ctx->words_capacity + ctx->words_capacity/2); + renewed = ctx->realloc(ctx, ctx->words, sizeof(struct fn) * new_count); + if(renewed == NULL) { + return -1; + } else { + ctx->words = renewed; + ctx->words_capacity = new_count; + } + } + name_it = name; + while (utf8_consume(&name_it, &character)) { + array_push_s(ctx, &ary, character); + } + e = ink_make_native(ctx, tid, &ary); + for(i = 0; i < ctx->words_top; ++i) { + struct ink_array* inner_name = ink_get_value(ctx, ctx->words[i].name); + if(ary.top == inner_name->top && memcmp(ary.elements, inner_name->elements, sizeof(struct elem)*ary.top) == 0) { + if(ctx->words[i].things != NULL) ctx->free(ctx, ctx->words[i].things); + ctx->words[i].things = ctx->malloc(ctx, sizeof(struct elem) * count); + memcpy(ctx->words[i].things, m, sizeof(struct elem) * count); + ctx->words[i].size = count; + return i; + } + } + ctx->words[ctx->words_top].things = ctx->malloc(ctx, sizeof(struct elem) * count); + memcpy(ctx->words[ctx->words_top].things, m, sizeof(struct elem) * count); + ctx->words[ctx->words_top].size = count; + ctx->words[ctx->words_top].name = e; + return ctx->words_top++; +} + +static int ink_add_indigenous_already_array(struct context* ctx, struct elem e, struct elem* m, size_t count) { + int i; + + if(ctx->words == NULL) { + ctx->words = ctx->malloc(ctx, sizeof(struct fn) * 8); + ctx->words_top = 0; + ctx->words_capacity = 8; + } else if(ctx->words_top == ctx->words_capacity) { + int new_count; + void* renewed; + new_count = (ctx->words_capacity + ctx->words_capacity/2); + renewed = ctx->realloc(ctx, ctx->words, sizeof(struct fn) * new_count); + if(renewed == NULL) { + return -1; + } else { + ctx->words = renewed; + ctx->words_capacity = new_count; + } + } + for(i = 0; i < ctx->words_top; ++i) { + if(e.value == ctx->words[i].name.value) { + if(ctx->words[i].things != NULL) ctx->free(ctx, ctx->words[i].things); + ctx->words[i].things = ctx->malloc(ctx, sizeof(struct elem) * count); + memcpy(ctx->words[i].things, m, sizeof(struct elem) * count); + ctx->words[i].size = count; + return i; + } + } + ctx->words[ctx->words_top].things = ctx->malloc(ctx, sizeof(struct elem) * count); + memcpy(ctx->words[ctx->words_top].things, m, sizeof(struct elem) * count); + ctx->words[ctx->words_top].size = count; + ctx->words[ctx->words_top].name = e; + return ctx->words_top++; } /** @@ -578,11 +613,13 @@ static int ink_consume_one(int* end, struct context* pContext, char* r, int is_s } #endif for(;it != *end;++it) { - struct elem character; + const char* iterator; character.type = INK_INTEGER; /* TODO: codepoint conversion and coalescence is required here */ - character.value = r[it]; + iterator = r + it; + utf8_consume(&iterator, &character); array_push(pContext, routine, ary, character); + it += (iterator - (r + it)) - 1; } *end = 0; return 0; @@ -888,7 +925,8 @@ int ink_kill_routine(struct context* ctx, int routine){ */ static int ink_parse(struct context* pContext, struct elem* executable_buffer, int* executable_buffer_top) { struct ink_routine* currentRoutine; - int i, function_buffer_top, function_name, mode; + int i, function_buffer_top, mode; + struct elem function_name; int func_is_macro = 0; #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wunused-parameter" @@ -902,7 +940,8 @@ static int ink_parse(struct context* pContext, struct elem* executable_buffer, i /* TODO: add checks for overflows in these arrays */ currentRoutine = pContext->routines + pContext->routine_current; function_buffer_top = 0; - function_name = -1; + function_name.type = INK_RESERVED; + function_name.value = -1; #define MODE_EXECUTABLE 0 #define MODE_FUNCTION 1 #define MODE_DO 2 @@ -918,13 +957,13 @@ static int ink_parse(struct context* pContext, struct elem* executable_buffer, i switch(current.type) { case INK_FUNCTION_KW: mode = MODE_FUNCTION; - function_name = -1; + function_name.value = -1; func_is_macro = 0; goto next_token; case INK_MACRO_KW: mode = MODE_FUNCTION; func_is_macro = 1; - function_name = -1; + function_name.value = -1; goto next_token; #ifndef NOEXTRACHECKS case INK_DO_KW: @@ -946,7 +985,7 @@ static int ink_parse(struct context* pContext, struct elem* executable_buffer, i case MODE_FUNCTION: if(current.type == INK_DO_KW) { #ifndef NOEXTRACHECKS - if(function_name == -1) { + if(function_name.value == -1) { currentRoutine->parse_error.is_set = 1; currentRoutine->parse_error.error_message = "Found start of function body before the name of the function was provided"; currentRoutine->parse_error.offset= i; @@ -958,20 +997,20 @@ static int ink_parse(struct context* pContext, struct elem* executable_buffer, i goto next_token; } #ifndef NOEXTRACHECKS - if(function_name != -1) { + if(function_name.value != -1) { currentRoutine->parse_error.is_set = 1; currentRoutine->parse_error.error_message = "Function name was not found"; currentRoutine->parse_error.offset= i; return -28; } - if(current.type != INK_RESERVED) { + if(current.type != INK_RESERVED && current.type != INK_FUNCTION && current.type != INK_NATIVE_FUNCTION) { currentRoutine->parse_error.is_set = 1; currentRoutine->parse_error.error_message = "Expected special token"; currentRoutine->parse_error.offset= i; return -29; } #endif - function_name = current.value; + function_name = current; break; case MODE_DO: if(current.type == INK_END_KW) { @@ -1025,7 +1064,15 @@ static int ink_parse(struct context* pContext, struct elem* executable_buffer, i } } } - err = ink_add_indigenous(pContext, pContext->lex_reserved_words[function_name], function_buffer, function_buffer_top); + if(function_name.type == INK_RESERVED) { + err = ink_add_indigenous(pContext, pContext->lex_reserved_words[function_name.value], function_buffer, function_buffer_top); + } else { + if(function_name.type == INK_NATIVE_FUNCTION) { + err = ink_add_indigenous_already_array(pContext, pContext->native_words[function_name.value].name,function_buffer, function_buffer_top); + } else if(function_name.type == INK_FUNCTION) { + err = ink_add_indigenous_already_array(pContext, pContext->words[function_name.value].name,function_buffer, function_buffer_top); + } + } #ifndef NOEXTRACHECKS if(err < 0) { pContext->panic = 1; @@ -1064,7 +1111,17 @@ static int ink_parse(struct context* pContext, struct elem* executable_buffer, i } #endif pContext->routine_current = parser_routine_index; - err = ink_add_indigenous(pContext, pContext->lex_reserved_words[function_name], macro_cooking_routine->stack, macro_cooking_routine->top); + + if(function_name.type == INK_RESERVED) { + err = ink_add_indigenous(pContext, pContext->lex_reserved_words[function_name.value], function_buffer, function_buffer_top); + } else { + if(function_name.type == INK_NATIVE_FUNCTION) { + err = ink_add_indigenous_already_array(pContext, pContext->native_words[function_name.value].name,function_buffer, function_buffer_top); + } else if(function_name.type == INK_FUNCTION) { + err = ink_add_indigenous_already_array(pContext, pContext->words[function_name.value].name,function_buffer, function_buffer_top); + } + } + macro_cooking_routine->panic = INK_ROUTINE_SUCCESS; #ifndef NOEXTRACHECKS if(err < 0) {