From: Axy Date: Mon, 4 May 2026 01:22:04 +0000 (+0200) Subject: Arc make unique among others X-Git-Url: https://git.uwuaxy.net/animations_scrolling.mp4?a=commitdiff_plain;h=d501e0294c9a7a1fbbfad8e51e3419b2048bb98e;p=axy%2Fft%2Fc-cera.git Arc make unique among others --- diff --git a/.gitignore b/.gitignore index c181c9d..e6c1414 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,5 @@ .build *.a .norm +a.out +a.out diff --git a/Makefile b/Makefile index 2ab5fa8..7c584c5 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ NAME=ccera.a -SRCS=src/arc.c src/value_get.c src/value_new.c +SRCS=src/arc.c src/eval.c src/value_destroy.c src/value_get.c src/value_lifetime.c src/value_new.c HEADERS=src/ccera.h @@ -10,22 +10,25 @@ THIS=Makefile OBJS=${SRCS:src/%.c=${BUILDDIR}/%.o} -CFLAGS=-Wall -Wextra -Werror -g -pthread -O3 +CFLAGS=-Wall -Wextra -Werror -g -pthread -flto -ffat-lto-objects +#CFLAGS=-Wall -Wextra -Werror -g -pthread -O3 -flto -ffat-lto-objects -CC=cc +CC=gcc + +AR=ar MAKEFLAGS += --no-print-directory all : ${NAME} -${BUILDDIR}/%.o : src/%.c ${HEADERS} | ${BUILDDIR} +${BUILDDIR}/%.o : src/%.c ${HEADERS} ${THIS} | ${BUILDDIR} ${CC} ${CFLAGS} -c -o $@ $< ${BUILDDIR} : mkdir ${BUILDDIR} -${NAME} : ${OBJS} - ar rcs $@ $^ +${NAME} : ${OBJS} ${THIS} + ${AR} rcs $@ ${OBJS} clean : rm -f ${OBJS} diff --git a/a.out b/a.out deleted file mode 100755 index 96b9661..0000000 Binary files a/a.out and /dev/null differ diff --git a/src/arc.c b/src/arc.c index bc811e1..e453239 100644 --- a/src/arc.c +++ b/src/arc.c @@ -6,7 +6,7 @@ /* By: agilliar +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2026/04/29 16:40:27 by agilliar #+# #+# */ -/* Updated: 2026/04/30 15:04:33 by agilliar ### ########.fr */ +/* Updated: 2026/05/04 02:01:19 by agilliar ### ########.fr */ /* */ /* ************************************************************************** */ @@ -37,7 +37,7 @@ t_arc arc_copy(t_arc arc) return (NULL); } -void arc_destroy(t_arc arc, void (*destructor)(void *)) +void arc_destroy(t_arc arc, t_drop destructor) { if (!arc) return ; diff --git a/src/ccera.h b/src/ccera.h index 8c8a077..3445dd2 100644 --- a/src/ccera.h +++ b/src/ccera.h @@ -6,7 +6,7 @@ /* By: agilliar +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2026/04/29 16:08:57 by agilliar #+# #+# */ -/* Updated: 2026/04/30 17:48:05 by agilliar ### ########.fr */ +/* Updated: 2026/05/04 02:35:51 by agilliar ### ########.fr */ /* */ /* ************************************************************************** */ @@ -16,37 +16,24 @@ # include # include -# if UINTPTR_MAX == 0xFFFFFFFFFFFFFFFF +# if UINTPTR_MAX != 0xFFFFFFFFFFFFFFFF +# error "Platform's pointers are not 64 bits" +# endif typedef uintptr_t t_usize; typedef intptr_t t_isize; -typedef uint8_t t_u8; typedef union u_value t_value; -typedef struct s_expr -{ - t_usize fn; - t_usize arg; -} t_expr; - typedef t_value (*t_builtin)(t_value); -typedef struct s_func -{ - t_usize consts_cnt; - t_value *consts; - t_usize exprs_count; - t_expr *exprs; -} t_func; - enum e_value: t_usize { VALUE_PTR = 0, VALUE_INT = 1, }; -# define VALUE_MASK 0x1 +# define VALUE_MASK 0x1 typedef union u_value { @@ -58,7 +45,6 @@ typedef union u_value enum e_value_ptr: t_usize { VALUE_PTR_BUILTIN, - VALUE_PTR_FUNC, VALUE_PTR_LIST, VALUE_PTR_BYTES, }; @@ -69,12 +55,6 @@ struct s_value_builtin t_builtin builtin; }; -struct s_value_func -{ - enum e_value_ptr discrim; - t_func func; -}; - struct s_value_list { t_usize len; @@ -86,25 +66,32 @@ struct s_value_bytes { t_usize len; enum e_value_ptr discrim; - t_u8 bytes[0]; + char bytes[0]; }; t_value value_builtin_new(t_builtin builtin); -t_value value_func_new(t_func func); t_value value_list_new(t_usize len); t_value value_bytes_new(t_usize len); +t_value value_undefined_new(void); t_value value_int_new(t_isize n); -t_builtin *value_builtin_get(t_value value); -t_func *value_func_get(t_value value); +struct s_value_builtin *value_builtin_get(t_value value); struct s_value_list *value_list_get(t_value value); struct s_value_bytes *value_bytes_get(t_value value); t_isize value_int_get(t_value value); -void t_value_destroy(t_value value); -t_value t_value_copy(t_value value); +void value_destroy(t_value value); + +t_value value_copy(t_value value); +struct s_value_list *value_list_unique(t_value *value); +struct s_value_bytes *value_bytes_unique(t_value *value); + +t_value value_list_new(t_usize len); +t_value value_list_new(t_usize len); typedef void *t_arc; +typedef void *(*t_unpack)(t_value); +typedef void (*t_drop)(void *); t_arc arc_create(t_usize size); t_arc arc_copy(t_arc arc); @@ -113,5 +100,33 @@ bool arc_is_unique(t_arc arc); void noop(void *ptr); -# endif +struct s_exec_context; + +typedef struct s_eval_ctx +{ + struct s_eval_ctx *parent; + struct s_value_list *state; + t_usize pos; +} t_eval_ctx; + +// The expression value is a tuple of an evaluatable and the argument to give it +// +// Value-evaluatables are laid out as follows: +// ( +// ((values | nil)* .. (exprs | nil)*), +// current_pos +// ) +// The nil values are considered to have been moved out, and it is an error for +// them to be used +// The nil expressions are locations where an argument is expected, halting +// evaluation +// An expression is as follows: +// (eval_idx, arg_idx, move) +// eval_idx is the index of the function to be evaluated +// arg_idx is the index of the argument to said function +// move is whether said value shall be moved out +// +// This function takes ownership +t_value expr_eval(t_value expr); + #endif diff --git a/src/eval.c b/src/eval.c new file mode 100644 index 0000000..98e5dd9 --- /dev/null +++ b/src/eval.c @@ -0,0 +1,32 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* eval.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: agilliar +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2026/05/04 01:21:34 by agilliar #+# #+# */ +/* Updated: 2026/05/04 02:51:20 by agilliar ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "ccera.h" +#include + +static t_value ctx_eval(t_eval_ctx *ctx) +{ + (void) ctx; + return (value_undefined_new()); +} + +t_value expr_eval(t_value expr) +{ + t_eval_ctx *ctx; + + (void) expr; + ctx = malloc(sizeof(t_eval_ctx)); + if (!ctx) + return (value_undefined_new()); + ctx->parent = NULL; + return (ctx_eval(ctx)); +} diff --git a/src/value_destroy.c b/src/value_destroy.c new file mode 100644 index 0000000..b67f20d --- /dev/null +++ b/src/value_destroy.c @@ -0,0 +1,41 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* value_destroy.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: agilliar +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2026/04/30 19:40:43 by agilliar #+# #+# */ +/* Updated: 2026/05/04 01:17:51 by agilliar ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "ccera.h" +#include + +static void value_drop_arc(t_value *value, t_unpack unpack, t_drop drop) +{ + void *unpacked; + + unpacked = unpack(*value); + if (!unpacked) + return ; + *value = value_int_new(0); + arc_destroy(unpacked, drop); +} + +static void value_list_del(struct s_value_list *list) +{ + t_usize i; + + i = 0; + while (i < list->len) + value_destroy(list->list[i++]); +} + +void value_destroy(t_value value) +{ + value_drop_arc(&value, (t_unpack) value_builtin_get, noop); + value_drop_arc(&value, (t_unpack) value_list_get, (t_drop) value_list_del); + value_drop_arc(&value, (t_unpack) value_bytes_get, noop); +} diff --git a/src/value_get.c b/src/value_get.c index 6f76a46..7b79dc7 100644 --- a/src/value_get.c +++ b/src/value_get.c @@ -6,14 +6,14 @@ /* By: agilliar +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2026/04/30 17:27:40 by agilliar #+# #+# */ -/* Updated: 2026/04/30 17:48:45 by agilliar ### ########.fr */ +/* Updated: 2026/05/04 01:18:03 by agilliar ### ########.fr */ /* */ /* ************************************************************************** */ #include "ccera.h" #include -t_builtin *value_builtin_get(t_value value) +struct s_value_builtin *value_builtin_get(t_value value) { struct s_value_builtin *res; @@ -22,19 +22,7 @@ t_builtin *value_builtin_get(t_value value) res = value.ptr - offsetof(struct s_value_builtin, builtin); if (res->discrim != VALUE_PTR_BUILTIN) return (NULL); - return (&res->builtin); -} - -t_func *value_func_get(t_value value) -{ - struct s_value_func *res; - - if ((value.discrim & VALUE_MASK) != VALUE_PTR) - return (NULL); - res = value.ptr - offsetof(struct s_value_func, func); - if (res->discrim != VALUE_PTR_FUNC) - return (NULL); - return (&res->func); + return (res); } struct s_value_list *value_list_get(t_value value) diff --git a/src/value_lifetime.c b/src/value_lifetime.c new file mode 100644 index 0000000..77b8725 --- /dev/null +++ b/src/value_lifetime.c @@ -0,0 +1,88 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* value_lifetime.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: agilliar +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2026/05/04 02:05:48 by agilliar #+# #+# */ +/* Updated: 2026/05/04 03:21:18 by agilliar ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "ccera.h" +#include +#include + +t_value value_copy(t_value value) +{ + void *ptr; + + ptr = value_list_get(value); + if (ptr) + { + arc_copy(ptr); + return (value); + } + ptr = value_bytes_get(value); + if (ptr) + { + arc_copy(ptr); + return (value); + } + ptr = value_builtin_get(value); + if (ptr) + { + arc_copy(ptr); + return (value); + } + return (value_int_new(value_int_get(value))); +} + +struct s_value_list *value_list_unique(t_value *value) +{ + struct s_value_list *list; + t_value new; + struct s_value_list *new_list; + t_usize i; + + list = value_list_get(*value); + if (!list) + return (NULL); + if (arc_is_unique(list)) + return (list); + new = value_list_new(list->len); + new_list = value_list_get(new); + if (!new_list) + return (NULL); + i = 0; + while (i < list->len) + { + new_list->list[i] = value_copy(list->list[i]); + i++; + } + value_destroy(*value); + *value = new; + return (new_list); +} + +struct s_value_bytes *value_bytes_unique(t_value *value) +{ + struct s_value_bytes *bytes; + t_value new; + struct s_value_bytes *new_bytes; + + bytes = value_bytes_get(*value); + if (!bytes) + return (NULL); + if (arc_is_unique(bytes)) + return (bytes); + new = value_bytes_new(bytes->len); + new_bytes = value_bytes_get(new); + if (!new_bytes) + return (NULL); + memcpy(new_bytes->bytes, bytes->bytes, bytes->len); + value_destroy(*value); + *value = new; + return (new_bytes); +} diff --git a/src/value_new.c b/src/value_new.c index b461a2c..7dd45ad 100644 --- a/src/value_new.c +++ b/src/value_new.c @@ -6,7 +6,7 @@ /* By: agilliar +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2026/04/30 16:25:42 by agilliar #+# #+# */ -/* Updated: 2026/04/30 17:48:17 by agilliar ### ########.fr */ +/* Updated: 2026/05/04 01:49:28 by agilliar ### ########.fr */ /* */ /* ************************************************************************** */ @@ -20,7 +20,7 @@ t_value value_builtin_new(t_builtin builtin) res = arc_create(sizeof(struct s_value_builtin)); if (!res) - return (value_int_new(0)); + return (value_undefined_new()); res->discrim = VALUE_PTR_BUILTIN; res->builtin = builtin; res_raw.ptr = &res->builtin; @@ -28,21 +28,6 @@ t_value value_builtin_new(t_builtin builtin) return (res_raw); } -t_value value_func_new(t_func func) -{ - struct s_value_func *res; - t_value res_raw; - - res = arc_create(sizeof(struct s_value_func)); - if (!res) - return (value_int_new(0)); - res->discrim = VALUE_PTR_FUNC; - res->func = func; - res_raw.ptr = &res->func; - res_raw.discrim |= VALUE_PTR; - return (res_raw); -} - t_value value_list_new(t_usize len) { struct s_value_list *res; @@ -51,15 +36,15 @@ t_value value_list_new(t_usize len) if (__builtin_mul_overflow(len, sizeof(t_value), &n) || __builtin_add_overflow(n, sizeof(struct s_value_list), &n)) - return (value_int_new(0)); + return (value_undefined_new()); res = arc_create(n); if (!res) - return (value_int_new(0)); + return (value_undefined_new()); res->discrim = VALUE_PTR_LIST; res->len = len; n = 0; while (n < len) - res->list[n++] = value_int_new(0); + res->list[n++] = value_undefined_new(); res_raw.ptr = &res->list; res_raw.discrim |= VALUE_PTR; return (res_raw); @@ -72,10 +57,10 @@ t_value value_bytes_new(t_usize len) t_usize n; if (__builtin_add_overflow(len, sizeof(struct s_value_bytes), &n)) - return (value_int_new(0)); + return (value_undefined_new()); res = arc_create(n); if (!res) - return (value_int_new(0)); + return (value_undefined_new()); res->discrim = VALUE_PTR_BYTES; res->len = len; memset(&res->bytes, 0, len); @@ -84,6 +69,14 @@ t_value value_bytes_new(t_usize len) return (res_raw); } +t_value value_undefined_new(void) +{ + t_value res; + + res.ptr = NULL; + return (res); +} + t_value value_int_new(t_isize n) { t_value res; diff --git a/test.c b/test.c index 162a8e6..a45042f 100644 --- a/test.c +++ b/test.c @@ -6,7 +6,7 @@ /* By: agilliar +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2026/04/30 17:19:58 by agilliar #+# #+# */ -/* Updated: 2026/04/30 17:53:30 by agilliar ### ########.fr */ +/* Updated: 2026/05/04 03:20:35 by agilliar ### ########.fr */ /* */ /* ************************************************************************** */ @@ -19,9 +19,17 @@ int main(void) char *s = "Hello cera!"; t_value value = value_bytes_new(strlen(s) + 1); strcpy(&value_bytes_get(value)->bytes[0], s); - printf("%s\n", &value_bytes_get(value)->bytes); + printf("%s\n", &value_bytes_get(value)->bytes[0]); printf("%p\n", value_bytes_get(value)); printf("%p\n", value_list_get(value)); + char c = value_bytes_get(value)->bytes[1]; + (void) c; + t_value value_2 = value_copy(value); + value_bytes_unique(&value_2)->bytes[1] = 'f'; + printf("%s\n", &value_bytes_get(value_2)->bytes[0]); + printf("%s\n", &value_bytes_get(value)->bytes[0]); + value_destroy(value); + value_destroy(value_2); value = value_int_new(128); printf("%li\n", value_int_get(value)); }