aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBruce Hill <bruce@bruce-hill.com>2024-02-12 00:18:55 -0500
committerBruce Hill <bruce@bruce-hill.com>2024-02-12 00:18:55 -0500
commit05f23c25078dc0d1661fe61a20d45e60ca9d83e8 (patch)
tree985185811f4ad8be28fb3d7ba110d2440ae062b0
parent8631776f2f45f594e828036415accd56c0bc1f1f (diff)
Initial working version of generic cord func
-rw-r--r--.gitignore1
-rw-r--r--Makefile5
-rw-r--r--metamethods/cord.c100
-rw-r--r--nextlang.c2
-rw-r--r--nextlang.h2
5 files changed, 108 insertions, 2 deletions
diff --git a/.gitignore b/.gitignore
index 0c13ec34..53d5ccbc 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,4 @@
*.o
+*.so
nextlang
tags
diff --git a/Makefile b/Makefile
index 4b183a68..1460ad5b 100644
--- a/Makefile
+++ b/Makefile
@@ -26,10 +26,13 @@ LDLIBS=-lgc -lgccjit -lcord -lm -lunistring
BUILTIN_OBJS=builtins/array.o builtins/bool.o builtins/builtins.o builtins/char.o builtins/floats.o builtins/functions.o builtins/integers.o \
builtins/memory.o builtins/string.o builtins/table.o builtins/types.o
-all: nextlang
+all: nextlang libnext.so
nextlang: nextlang.c parse.o files.o util.o ast.o compile.o types.o SipHash/halfsiphash.o $(BUILTIN_OBJS)
+libnext.so: metamethods/cord.o util.o SipHash/halfsiphash.o
+ $(CC) $^ $(CFLAGS) $(EXTRA) $(CWARN) $(G) $(O) $(OSFLAGS) $(LDLIBS) -Wl,-soname,libnext.so -shared -o $@
+
SipHash/halfsiphash.c:
git submodule update --init --recursive
diff --git a/metamethods/cord.c b/metamethods/cord.c
new file mode 100644
index 00000000..4243ffb6
--- /dev/null
+++ b/metamethods/cord.c
@@ -0,0 +1,100 @@
+#include <err.h>
+#include <gc/cord.h>
+#include <stdarg.h>
+#include <stdbool.h>
+#include <stdint.h>
+
+#include "../util.h"
+
+typedef CORD (*custom_cord_func)(void *x, void *userdata);
+
+typedef struct {
+ void *data;
+ int64_t length:42;
+ uint8_t free:4;
+ bool copy_on_write:1, atomic:1;
+ int16_t stride:16;
+} generic_array_t;
+
+static CORD vas_cord(void *x, const char **fmt, va_list args)
+{
+ char c = **fmt;
+ ++(*fmt);
+ switch (c) {
+ case '@': case '?': {
+ if (!x)
+ return CORD_asprintf("%c%r", vas_cord(NULL, fmt, args));
+ void *ptr = *(void**)x;
+ return CORD_cat(ptr ? (c == '@' ? "@" : "?") : "!", vas_cord(ptr, fmt, args));
+ }
+ case 'B': {
+ if (!x) return "Bool";
+ return *(bool*)x ? "yes" : "no";
+ }
+ case 'I': {
+ size_t bits = va_arg(args, size_t);
+ switch (bits) {
+ case 64:
+ return x ? CORD_asprintf("%ld", *(int64_t*)x) : "Int64";
+ case 32:
+ return x ? CORD_asprintf("%d", *(int32_t*)x) : "Int32";
+ case 16:
+ return x ? CORD_asprintf("%d", *(int16_t*)x) : "Int16";
+ case 8:
+ return x ? CORD_asprintf("%d", *(int8_t*)x) : "Int8";
+ default: errx(1, "Unsupported Int precision: %ld", bits);
+ }
+ }
+ case 'N': {
+ size_t bits = va_arg(args, size_t);
+ switch (bits) {
+ case 64:
+ return x ? CORD_asprintf("%g", *(double*)x) : "Num64";
+ case 32:
+ return x ? CORD_asprintf("%g", *(double*)x) : "Num32";
+ default: errx(1, "Unsupported Num precision: %ld", bits);
+ }
+ }
+ case 'S': {
+ return x ? *(CORD*)x : "Str";
+ }
+ case '[': {
+ if (!x) {
+ CORD cord = CORD_asprintf("[%r]", vas_cord(NULL, fmt, args));
+ if (**fmt == ']')
+ ++(*fmt);
+ return cord;
+ }
+ CORD cord = "[";
+ generic_array_t *arr = x;
+ for (int64_t i = 0; i < arr->length; i++) {
+ const char *item_fmt = *fmt;
+ va_list args_copy;
+ va_copy(args_copy, args);
+ if (i > 0) cord = CORD_cat(cord, ", ");
+ CORD item_cord = vas_cord(arr->data + i*arr->stride, &item_fmt, args_copy);
+ cord = CORD_cat(cord, item_cord);
+ va_end(args_copy);
+ }
+ (void)vas_cord(NULL, fmt, args);
+ if (**fmt == ']') ++(*fmt);
+ return CORD_cat(cord, "]");
+ }
+ case '_': {
+ custom_cord_func fn = va_arg(args, custom_cord_func);
+ void *arg = va_arg(args, void*);
+ return fn(x, arg);
+ }
+ default: errx(1, "Unsupported format specifier: '%c'", c);
+ }
+ errx(1, "Unreachable");
+}
+
+public CORD as_cord(void *x, const char *fmt, ...)
+{
+ va_list args;
+ va_start(args, fmt);
+ CORD ret = vas_cord(x, &fmt, args);
+ va_end(args);
+ return ret;
+}
diff --git a/nextlang.c b/nextlang.c
index aa1c1e92..92ec4111 100644
--- a/nextlang.c
+++ b/nextlang.c
@@ -116,7 +116,7 @@ int main(int argc, char *argv[])
if (!cflags)
cflags = "-std=c11";
- const char *ldlibs = "-lgc -lcord -lm";
+ const char *ldlibs = "-lgc -lcord -lm -L. -lnext";
if (getenv("LDLIBS"))
ldlibs = heap_strf("%s %s", ldlibs, getenv("LDLIBS"));
diff --git a/nextlang.h b/nextlang.h
index 4f4a3b28..39cc2c40 100644
--- a/nextlang.h
+++ b/nextlang.h
@@ -30,6 +30,8 @@
#define __Array(t) array_t
+CORD as_cord(void *x, const char *fmt, ...);
+
#define CORD_asprintf(...) ({ CORD __c; CORD_sprintf(&__c, __VA_ARGS__); __c; })
#define __declare(var, val) __typeof(val) var = val
#define __cord(x) _Generic(x, bool: x ? "yes" : "no", \