aboutsummaryrefslogtreecommitdiff
path: root/stdlib
diff options
context:
space:
mode:
authorBruce Hill <bruce@bruce-hill.com>2025-02-21 14:59:14 -0500
committerBruce Hill <bruce@bruce-hill.com>2025-02-21 14:59:14 -0500
commit7a6abd4f8eca56a2bba7e7d0b8dfa3011586a89c (patch)
tree31ac3b4f7ff8de64d455e7a5c003ffa77ca448c8 /stdlib
parentf8de9e4ae77e1b4d062caf10a3e354d4ef2e5213 (diff)
Tweak function registration API
Diffstat (limited to 'stdlib')
-rw-r--r--stdlib/functiontype.c70
-rw-r--r--stdlib/functiontype.h8
-rw-r--r--stdlib/stdlib.c1
3 files changed, 69 insertions, 10 deletions
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 <stdbool.h>
+#include <stdint.h>
#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"