From 7a6abd4f8eca56a2bba7e7d0b8dfa3011586a89c Mon Sep 17 00:00:00 2001 From: Bruce Hill Date: Fri, 21 Feb 2025 14:59:14 -0500 Subject: Tweak function registration API --- stdlib/functiontype.c | 70 +++++++++++++++++++++++++++++++++++++++++++++------ stdlib/functiontype.h | 8 ++++-- stdlib/stdlib.c | 1 + 3 files changed, 69 insertions(+), 10 deletions(-) (limited to 'stdlib') diff --git a/stdlib/functiontype.c b/stdlib/functiontype.c index b62ef2a7..dc4d0c94 100644 --- a/stdlib/functiontype.c +++ b/stdlib/functiontype.c @@ -4,21 +4,70 @@ #include "datatypes.h" #include "functiontype.h" +#include "optionals.h" +#include "structs.h" #include "tables.h" #include "text.h" #include "types.h" #include "util.h" -static Table_t function_names = {}; +typedef struct { + Text_t filename, name; + int64_t line_num; +} func_info_t; -public void register_function(void *fn, Text_t name) +static NamedType_t fields[] = { + {.name="filename", .type=&Text$info}, + {.name="name", .type=&Text$info}, + {.name="line_num", .type=&Int64$info}, +}; + +static const TypeInfo_t func_info_type = {.size=sizeof(func_info_t), .align=__alignof__(func_info_t), .metamethods=Struct$metamethods, + .tag=StructInfo, .StructInfo.name="FuncInfo", + .StructInfo.num_fields=3, .StructInfo.fields=fields}; +static Table_t function_info = {}; + +public void register_function(void *fn, Text_t filename, int64_t line_num, Text_t name) +{ + func_info_t info = { + .filename=filename, + .line_num=line_num, + .name=name, + }; + Table$set(&function_info, &fn, &info, Table$info(Function$info("???"), &func_info_type)); +} + +PUREFUNC static func_info_t *get_function_info(void *fn) +{ + func_info_t *info = Table$get(function_info, &fn, Table$info(Function$info("???"), &func_info_type)); + if (info) return info; + + void *closest_fn = NULL; + for (int64_t i = 0; i < function_info.entries.length; i++) { + struct { void *fn; func_info_t info; } *entry = function_info.entries.data + i*function_info.entries.stride; + if (entry->fn > fn || entry->fn < closest_fn) continue; + closest_fn = entry->fn; + info = &entry->info; + } + return info; +} + +PUREFUNC public Text_t get_function_name(void *fn) { - Table$set(&function_names, &fn, &name, Table$info(Function$info("???"), &Text$info)); + func_info_t *info = get_function_info(fn); + return info ? info->name : NONE_TEXT; } -PUREFUNC public Text_t *get_function_name(void *fn) +PUREFUNC public Text_t get_function_filename(void *fn) { - return Table$get(function_names, &fn, Table$info(Function$info("???"), &Text$info)); + func_info_t *info = get_function_info(fn); + return info ? info->filename : NONE_TEXT; +} + +PUREFUNC public int64_t get_function_line_num(void *fn) +{ + func_info_t *info = get_function_info(fn); + return info ? info->line_num : -1; } public Text_t Func$as_text(const void *fn, bool colorize, const TypeInfo_t *type) @@ -26,9 +75,14 @@ public Text_t Func$as_text(const void *fn, bool colorize, const TypeInfo_t *type (void)fn; Text_t text = Text$from_str(type->FunctionInfo.type_str); if (fn) { - Text_t *name = get_function_name(*(void**)fn); - if (name) - text = *name; + OptionalText_t name = get_function_name(*(void**)fn); + if (name.length >= 0) + text = name; + + OptionalText_t filename = get_function_filename(*(void**)fn); + int64_t line_num = get_function_line_num(*(void**)fn); + if (filename.length >= 0) + text = Text$format("%k [%k:%ld]", &text, &filename, line_num); } if (fn && colorize) text = Text$concat(Text("\x1b[32;1m"), text, Text("\x1b[m")); diff --git a/stdlib/functiontype.h b/stdlib/functiontype.h index 4dfef3b0..9252f5fc 100644 --- a/stdlib/functiontype.h +++ b/stdlib/functiontype.h @@ -1,15 +1,19 @@ #pragma once #include +#include #include "metamethods.h" +#include "optionals.h" #include "types.h" #include "util.h" // Logic for handling function type values -void register_function(void *fn, Text_t name); -Text_t *get_function_name(void *fn); +void register_function(void *fn, Text_t filename, int64_t line_num, Text_t name); +OptionalText_t get_function_name(void *fn); +OptionalText_t get_function_filename(void *fn); +int64_t get_function_line_num(void *fn); Text_t Func$as_text(const void *fn, bool colorize, const TypeInfo_t *type); PUREFUNC bool Func$is_none(const void *obj, const TypeInfo_t*); diff --git a/stdlib/stdlib.c b/stdlib/stdlib.c index 21102136..54275995 100644 --- a/stdlib/stdlib.c +++ b/stdlib/stdlib.c @@ -13,6 +13,7 @@ #include "bools.h" #include "files.h" +#include "functiontype.h" #include "integers.h" #include "optionals.h" #include "metamethods.h" -- cgit v1.2.3