]> Untitled Git - axy/ft/c-cera.git/commitdiff
Epic makefile
authorAxy <gilliardmarthey.axel@gmail.com>
Wed, 13 May 2026 08:50:49 +0000 (10:50 +0200)
committerAxy <gilliardmarthey.axel@gmail.com>
Wed, 13 May 2026 08:50:49 +0000 (10:50 +0200)
14 files changed:
.gitignore
Makefile
src/arc.c
src/arc.h [moved from src/value_readf.c with 59% similarity]
src/arith.h [new file with mode: 0644]
src/ccera.h
src/defer.h
src/framealloc.h
src/panic.c
src/value.h [new file with mode: 0644]
src/value_destroy.c [deleted file]
src/value_get.c [deleted file]
src/value_lifetime.c
src/value_new.c

index a9c38b71889fe14bfc955ec70859af0677f00452..f4283ee03608a09e783957461235b2c899fa8e33 100644 (file)
@@ -5,3 +5,6 @@ a.out
 vgcore.*
 .direnv
 .norm_fail
+Makefile.tmp
+.deps
+.deps.tmp
index e09a1fce6b89614aac494a363a8dbce863f11a32..2ae7dde4d0d450505caa78951ef824e64497a4ab 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,13 +1,15 @@
 NAME=ccera.a
 
-SRCS=src/arc.c src/defer.c src/eval.c src/framealloc.c src/panic.c src/value_destroy.c src/value_get.c src/value_lifetime.c src/value_new.c src/value_readf.c
+SRCS=src/arc.c src/defer.c src/eval.c src/framealloc.c src/panic.c src/value_lifetime.c src/value_new.c
 
-HEADERS=src/align.h src/ccera.h src/defer.h src/framealloc.h src/jmp.h src/panic.h src/return_patch.h
+HEADERS=src/align.h src/arc.h src/arith.h src/ccera.h src/defer.h src/framealloc.h src/jmp.h src/panic.h src/return_patch.h src/value.h
 
 BUILDDIR=.build
 
 THIS=Makefile
 
+DEPSFILE=.deps
+
 OBJS=${SRCS:src/%.c=${BUILDDIR}/%.o}
 
 CFLAGS=-Wall -Wextra -Werror -pthread -std=gnu23
@@ -24,7 +26,7 @@ MAKEFLAGS += --no-print-directory
 
 all: ${NAME}
 
-${BUILDDIR}/%.o: src/%.c ${HEADERS} ${THIS} | ${BUILDDIR}
+${BUILDDIR}/%.o: src/%.c ${THIS} | ${BUILDDIR}
        ${CC} ${CFLAGS} -c -o $@ $<
 
 ${BUILDDIR}:
@@ -42,9 +44,28 @@ fclean: clean
 
 re: fclean all
 
-remakefile: clean
-       sed -i "s?^SRCS=.*?$$(echo -n SRCS=; echo -n src/*.c)?" ${THIS}
-       sed -i "s?^HEADERS=.*?$$(echo -n HEADERS=; echo -n src/*.h)?" ${THIS}
+${THIS}.tmp: ${SRCS} ${HEADERS} ${THIS}
+       @sed "s?^SRCS=.*?$$(echo -n SRCS=; echo -n src/*.c)?" ${THIS} \
+       | sed "s?^HEADERS=.*?$$(echo -n HEADERS=; echo -n src/*.h)?" \
+       >  ${THIS}.tmp
+
+${DEPSFILE}.tmp: ${SRCS} ${HEADERS} ${THIS}
+       ${CC} -MM ${SRCS} | sed "s/^\([^ ]\)/\$${BUILDDIR}\/\1/" > $@
+
+redeps: ${DEPSFILE}.tmp
+       @echo Rebuilding deps
+       @if ! cmp -s $< ${DEPSFILE}; then \
+               cp $< ${DEPSFILE}; \
+               echo Deps modified; \
+       fi
+
+remakefile: ${THIS}.tmp
+       @echo Rebuilding makefile
+       @if ! cmp -s $< ${THIS}; then \
+               make fclean; \
+               cp $< ${THIS}; \
+               echo Makefile modified; \
+       fi
 
 .norm: ${SRCS} ${HEADERS} ${THIS}
        @rm -f .norm_fail
@@ -54,6 +75,15 @@ norm: .norm
        @cat .norm | sed "s/.*OK!$$//" | grep .
        @test ! -e .norm_fail
 
+watch-step:
+       make remakefile
+       make redeps
+       make norm
+       make
+
+watch:
+       watch -c -n 1 make watch-step
+
 norm-watch:
        watch -c -n 1 make norm
 
@@ -66,4 +96,6 @@ a.out: test.c ${NAME} ${THIS}
 test: a.out
        valgrind ./a.out
 
-.PHONY: all clean fclean re remakefile norm norm-watch build-watch test
+.PHONY: all clean fclean re remakefile redeps norm watch-step watch test
+
+${BUILDDIR}/arc.o: src/arc.c src/arc.h
index af02b810e39325686223b2e4e47ef0d3c23b4cb4..83329fdeb5f7ac454308bb1fae511513707bc9b6 100644 (file)
--- a/src/arc.c
+++ b/src/arc.c
@@ -6,18 +6,19 @@
 /*   By: agilliar <agilliar@student.42mulhouse.fr>  +#+  +:+       +#+        */
 /*                                                +#+#+#+#+#+   +#+           */
 /*   Created: 2026/04/29 16:40:27 by agilliar          #+#    #+#             */
-/*   Updated: 2026/05/05 20:40:03 by agilliar         ###   ########.fr       */
+/*   Updated: 2026/05/13 09:00:47 by agilliar         ###   ########.fr       */
 /*                                                                            */
 /* ************************************************************************** */
 
-#include "ccera.h"
+#include "arc.h"
+#include "panic.h"
 #include <stdlib.h>
 
-t_arc  arc_create(t_usize size)
+t_arc  arc_new(uintptr_t size)
 {
-       t_usize *res;
+       uintptr_t       *res;
 
-       if (__builtin_add_overflow(size, sizeof(t_usize), &size))
+       if (__builtin_add_overflow(size, sizeof(uintptr_t), &size))
                panic("Arc alloc too big to create");
        res = malloc(size);
        if (!res)
@@ -26,27 +27,29 @@ t_arc       arc_create(t_usize size)
        return ((void *) &res[1]);
 }
 
+// Relaxed sub as we own a copy, and as such ultimately sync
 void   arc_copy(t_arc arc)
 {
-       if (__atomic_add_fetch(((t_usize *)arc) - 1, 1, __ATOMIC_RELAXED)
-               >= ((t_usize) 1) << (sizeof(t_usize) * 8 - 1))
-               panic("Arc counter overflowed");
+       if (__atomic_add_fetch(((uintptr_t *)arc) - 1, 1, __ATOMIC_RELAXED)
+               >= ((uintptr_t) 1) << (sizeof(uintptr_t) * 8 - 1))
+       {
+               __atomic_sub_fetch(((uintptr_t *)arc) - 1, 1, __ATOMIC_RELAXED);
+               panic("Arc counter near overflowing");
+       }
 }
 
-void   arc_destroy(t_arc arc, t_drop destructor)
+void   arc_drop(t_arc arc, t_drop destructor)
 {
-       if (!arc)
-               return ;
-       if (__atomic_sub_fetch(((t_usize *)arc) - 1, 1, __ATOMIC_RELEASE) != 0)
+       if (__atomic_sub_fetch(((uintptr_t *)arc) - 1, 1, __ATOMIC_RELEASE) != 0)
                return ;
        __atomic_thread_fence(__ATOMIC_ACQUIRE);
-       destructor(arc);
+       ((void (*)(void *))destructor)(arc);
        free(((char *)arc) - 8);
 }
 
 bool   arc_is_unique(t_arc arc)
 {
-       return (__atomic_load_n(((t_usize *)arc) - 1, __ATOMIC_ACQUIRE) == 1);
+       return (__atomic_load_n(((uintptr_t *)arc) - 1, __ATOMIC_ACQUIRE) == 1);
 }
 
 void   noop(void *ptr)
similarity index 59%
rename from src/value_readf.c
rename to src/arc.h
index aa6cc566679e88f9454ccc2f8d42edd21391d78d..600dca1cde727c5f1dd0b78bf377322821b0b4a5 100644 (file)
+++ b/src/arc.h
@@ -1,26 +1,29 @@
 /* ************************************************************************** */
 /*                                                                            */
 /*                                                        :::      ::::::::   */
-/*   value_readf.c                                      :+:      :+:    :+:   */
+/*   arc.h                                              :+:      :+:    :+:   */
 /*                                                    +:+ +:+         +:+     */
 /*   By: agilliar <agilliar@student.42mulhouse.fr>  +#+  +:+       +#+        */
 /*                                                +#+#+#+#+#+   +#+           */
-/*   Created: 2026/05/05 15:21:41 by agilliar          #+#    #+#             */
-/*   Updated: 2026/05/05 16:58:28 by agilliar         ###   ########.fr       */
+/*   Created: 2026/05/13 08:56:53 by agilliar          #+#    #+#             */
+/*   Updated: 2026/05/13 10:02:51 by agilliar         ###   ########.fr       */
 /*                                                                            */
 /* ************************************************************************** */
 
-#include "ccera.h"
+#ifndef ARC_H
+# define ARC_H
 
-// i: int
-// (: list
-// ): end list
-// .: list rem discard
-// _: skip
-// b: bytes
-// l: list
-// v: value
-// value_readf("((li)v)")
-//bool value_readf(const char *f, void **out, bool move)
-//{
-//}
+# include <stdint.h>
+# include <stdbool.h>
+
+typedef void   *t_arc;
+typedef void   *t_drop;
+
+t_arc  arc_new(uintptr_t size);
+void   arc_copy(t_arc arc);
+void   arc_drop(t_arc arc, t_drop destructor);
+bool   arc_is_unique(t_arc arc);
+
+void   noop(void *ptr);
+
+#endif
diff --git a/src/arith.h b/src/arith.h
new file mode 100644 (file)
index 0000000..baccaa5
--- /dev/null
@@ -0,0 +1,43 @@
+/* ************************************************************************** */
+/*                                                                            */
+/*                                                        :::      ::::::::   */
+/*   arith.h                                            :+:      :+:    :+:   */
+/*                                                    +:+ +:+         +:+     */
+/*   By: agilliar <agilliar@student.42mulhouse.fr>  +#+  +:+       +#+        */
+/*                                                +#+#+#+#+#+   +#+           */
+/*   Created: 2026/05/13 08:42:44 by agilliar          #+#    #+#             */
+/*   Updated: 2026/05/13 08:54:14 by agilliar         ###   ########.fr       */
+/*                                                                            */
+/* ************************************************************************** */
+
+#ifndef ARITH_H
+# define ARITH_H
+
+# include <stdint.h>
+# include "panic.h"
+
+__attribute__((always_inline))
+static inline uintptr_t        uadd(uintptr_t a, uintptr_t b)
+{
+       if (__builtin_add_overflow(a, b, &a))
+               panic("Addition overflowed");
+       return (a);
+}
+
+__attribute__((always_inline))
+static inline uintptr_t        usub(uintptr_t a, uintptr_t b)
+{
+       if (__builtin_sub_overflow(a, b, &a))
+               panic("Substraction overflowed");
+       return (a);
+}
+
+__attribute__((always_inline))
+static inline uintptr_t        umul(uintptr_t a, uintptr_t b)
+{
+       if (__builtin_mul_overflow(a, b, &a))
+               panic("Multiplication overflowed");
+       return (a);
+}
+
+#endif
index dd5e495a6e3fbd7593b2956fffaa98493bb13975..edaab4241d9b0308ae0bbd3c76b6557c3d6d8a92 100644 (file)
@@ -6,7 +6,7 @@
 /*   By: agilliar <agilliar@student.42mulhouse.fr>  +#+  +:+       +#+        */
 /*                                                +#+#+#+#+#+   +#+           */
 /*   Created: 2026/04/29 16:08:57 by agilliar          #+#    #+#             */
-/*   Updated: 2026/05/11 19:26:32 by agilliar         ###   ########.fr       */
+/*   Updated: 2026/05/13 08:57:19 by agilliar         ###   ########.fr       */
 /*                                                                            */
 /* ************************************************************************** */
 
 # include "defer.h"
 # include "panic.h"
 # include "framealloc.h"
-
-# if UINTPTR_MAX != 0xFFFFFFFFFFFFFFFF
-#  error "Platform's pointers are not 64 bits"
-# endif
-
-typedef uintptr_t              t_usize;
-typedef intptr_t               t_isize;
-
-typedef union u_value  t_value;
-
-typedef t_value                        (*t_builtin)(t_value);
-
-enum e_value: t_usize
-{
-       VALUE_PTR = 0,
-       VALUE_INT = 1,
-};
-
-# define VALUE_MASK 0x1
-
-typedef union u_value
-{
-       void                    *ptr;
-       t_isize                 integral;
-       enum e_value    discrim;
-}      t_value;
-
-enum e_value_ptr: t_usize
-{
-       VALUE_PTR_BUILTIN,
-       VALUE_PTR_LIST,
-       VALUE_PTR_BYTES,
-};
-
-typedef struct s_value_builtin
-{
-       enum e_value_ptr        discrim;
-       t_builtin                       builtin;
-}      t_value_builtin;
-
-typedef struct s_value_list
-{
-       t_usize                         len;
-       enum e_value_ptr        discrim;
-       t_value                         list[];
-}      t_value_list;
-
-typedef struct s_value_bytes
-{
-       t_usize                         len;
-       enum e_value_ptr        discrim;
-       char                            bytes[];
-}      t_value_bytes;
-
-t_value                        value_builtin_new(t_builtin builtin);
-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_value_builtin        *value_builtin_get(t_value value);
-t_value_list   *value_list_get(t_value value);
-t_value_bytes  *value_bytes_get(t_value value);
-t_isize                        value_int_get(t_value value);
-
-void                   value_destroy(t_value *value);
-
-t_value                        value_copy(t_value value);
-t_value_list   *value_list_unique(t_value *value);
-t_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);
-void                   arc_copy(t_arc arc);
-void                   arc_destroy(t_arc arc, void (*destructor)(void *));
-bool                   arc_is_unique(t_arc arc);
-
-void                   noop(void *ptr);
+# include "value.h"
+# include "arith.h"
+# include "arc.h"
 
 // The expression value is a tuple of an evaluatable and the argument to give it
 //
index 25f5225a1686f2631f0ccba3d7a09d52f6582a89..b3a272bc565e7a272f14e835fa9efdc6f608a244 100644 (file)
@@ -6,7 +6,7 @@
 /*   By: agilliar <agilliar@student.42mulhouse.fr>  +#+  +:+       +#+        */
 /*                                                +#+#+#+#+#+   +#+           */
 /*   Created: 2026/05/10 22:08:53 by agilliar          #+#    #+#             */
-/*   Updated: 2026/05/12 14:01:36 by agilliar         ###   ########.fr       */
+/*   Updated: 2026/05/12 16:58:46 by agilliar         ###   ########.fr       */
 /*                                                                            */
 /* ************************************************************************** */
 
@@ -14,6 +14,7 @@
 # define DEFER_H
 
 # include <stddef.h>
+# include <string.h>
 # include "framealloc.h"
 # include "return_patch.h"
 
@@ -87,4 +88,24 @@ static inline void   errdefer(void *f, void *dat)
        defer_store()->frame = curr;
 }
 
+__attribute__((always_inline))
+static inline void     deferc(void *f, void *dat, uintptr_t size)
+{
+       void    *b;
+
+       b = cera_alloca(size);
+       memcpy(b, dat, size);
+       defer(f, b);
+}
+
+__attribute__((always_inline))
+static inline void     errdeferc(void *f, void *dat, uintptr_t size)
+{
+       void    *b;
+
+       b = cera_alloca(size);
+       memcpy(b, dat, size);
+       errdefer(f, b);
+}
+
 #endif
index a97b755a857de305bd9bfdb60f229ec99fa7fbe3..2538eea8dccdc856da7327fe7167425663e4ce09 100644 (file)
@@ -6,7 +6,7 @@
 /*   By: agilliar <agilliar@student.42mulhouse.fr>  +#+  +:+       +#+        */
 /*                                                +#+#+#+#+#+   +#+           */
 /*   Created: 2026/05/11 19:17:56 by agilliar          #+#    #+#             */
-/*   Updated: 2026/05/12 13:35:45 by agilliar         ###   ########.fr       */
+/*   Updated: 2026/05/12 16:58:56 by agilliar         ###   ########.fr       */
 /*                                                                            */
 /* ************************************************************************** */
 
@@ -84,4 +84,10 @@ static inline void   *cera_alloca_align(uintptr_t len, uintptr_t align)
        return (cera_alloca_align_nopatch(len, align));
 }
 
+__attribute__((always_inline, malloc, alloc_size(1)))
+static inline void     *cera_alloca(uintptr_t len)
+{
+       return (cera_alloca_align(len, 8));
+}
+
 #endif
index be746043f978de82389f12bbfe09d5044ab0b57c..f3e0640d2c7ca5b1701cfb244f47a2b2369f0de0 100644 (file)
@@ -6,11 +6,12 @@
 /*   By: agilliar <agilliar@student.42mulhouse.fr>  +#+  +:+       +#+        */
 /*                                                +#+#+#+#+#+   +#+           */
 /*   Created: 2026/05/05 15:38:33 by agilliar          #+#    #+#             */
-/*   Updated: 2026/05/12 13:13:03 by agilliar         ###   ########.fr       */
+/*   Updated: 2026/05/13 09:36:19 by agilliar         ###   ########.fr       */
 /*                                                                            */
 /* ************************************************************************** */
 
-#include "ccera.h"
+#include "panic.h"
+#include "defer.h"
 
 t_panic_info   *panic_store(void)
 {
@@ -39,7 +40,7 @@ void  *catch(void *f, void *dat)
        return (NULL);
 }
 
-__attribute__((noreturn, nonnull(1)))
+__attribute__((noreturn, nonnull(1), cold))
 void   panic(void *err)
 {
        while (defer_store()->frame_ptr != panic_store()->frame_ptr)
diff --git a/src/value.h b/src/value.h
new file mode 100644 (file)
index 0000000..458f6dc
--- /dev/null
@@ -0,0 +1,60 @@
+/* ************************************************************************** */
+/*                                                                            */
+/*                                                        :::      ::::::::   */
+/*   value.h                                            :+:      :+:    :+:   */
+/*                                                    +:+ +:+         +:+     */
+/*   By: agilliar <agilliar@student.42mulhouse.fr>  +#+  +:+       +#+        */
+/*                                                +#+#+#+#+#+   +#+           */
+/*   Created: 2026/05/12 16:14:16 by agilliar          #+#    #+#             */
+/*   Updated: 2026/05/13 09:08:29 by agilliar         ###   ########.fr       */
+/*                                                                            */
+/* ************************************************************************** */
+
+#ifndef VALUE_H
+# define VALUE_H
+
+# include <stdint.h>
+
+typedef struct s_bytes t_bytes;
+typedef struct s_list  t_list;
+
+union u_value
+{
+       intptr_t        v_int;
+       uintptr_t       v_uint;
+       t_bytes         *v_bytes;
+       t_list          *v_list;
+};
+
+enum e_value: uint8_t
+{
+       VALUE_UNDEF,
+       VALUE_INT,
+       VALUE_UINT,
+       VALUE_BYTES,
+       VALUE_LIST,
+};
+
+typedef struct s_value
+{
+       union u_value   val;
+       enum e_value    tag;
+}      t_value;
+
+typedef struct s_bytes
+{
+       uintptr_t       len;
+       uint8_t         buf[];
+}      t_bytes;
+
+typedef struct s_list
+{
+       uintptr_t               len;
+       t_value                 buf[];
+}      t_list;
+
+t_value        value_copy(t_value val);
+t_value        value_clone(t_value val);
+void   value_drop(t_value      *value);
+
+#endif
diff --git a/src/value_destroy.c b/src/value_destroy.c
deleted file mode 100644 (file)
index 1e05c9a..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-/* ************************************************************************** */
-/*                                                                            */
-/*                                                        :::      ::::::::   */
-/*   value_destroy.c                                    :+:      :+:    :+:   */
-/*                                                    +:+ +:+         +:+     */
-/*   By: agilliar <agilliar@student.42mulhouse.fr>  +#+  +:+       +#+        */
-/*                                                +#+#+#+#+#+   +#+           */
-/*   Created: 2026/04/30 19:40:43 by agilliar          #+#    #+#             */
-/*   Updated: 2026/05/05 20:54:09 by agilliar         ###   ########.fr       */
-/*                                                                            */
-/* ************************************************************************** */
-
-#include "ccera.h"
-#include <stdlib.h>
-
-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);
-       *value = value_undefined_new();
-}
diff --git a/src/value_get.c b/src/value_get.c
deleted file mode 100644 (file)
index 7583e39..0000000
+++ /dev/null
@@ -1,54 +0,0 @@
-/* ************************************************************************** */
-/*                                                                            */
-/*                                                        :::      ::::::::   */
-/*   value_get.c                                        :+:      :+:    :+:   */
-/*                                                    +:+ +:+         +:+     */
-/*   By: agilliar <agilliar@student.42mulhouse.fr>  +#+  +:+       +#+        */
-/*                                                +#+#+#+#+#+   +#+           */
-/*   Created: 2026/04/30 17:27:40 by agilliar          #+#    #+#             */
-/*   Updated: 2026/05/06 19:28:43 by agilliar         ###   ########.fr       */
-/*                                                                            */
-/* ************************************************************************** */
-
-#include "ccera.h"
-
-struct s_value_builtin *value_builtin_get(t_value value)
-{
-       struct s_value_builtin  *res;
-
-       if ((value.discrim & VALUE_MASK) != VALUE_PTR)
-               return (NULL);
-       res = value.ptr - offsetof(struct s_value_builtin, builtin);
-       if (!value.ptr || res->discrim != VALUE_PTR_BUILTIN)
-               return (NULL);
-       return (res);
-}
-
-struct s_value_list    *value_list_get(t_value value)
-{
-       struct s_value_list     *res;
-
-       if ((value.discrim & VALUE_MASK) != VALUE_PTR)
-               return (NULL);
-       res = value.ptr - offsetof(struct s_value_list, list);
-       if (!value.ptr || res->discrim != VALUE_PTR_LIST)
-               return (NULL);
-       return (res);
-}
-
-struct s_value_bytes   *value_bytes_get(t_value value)
-{
-       struct s_value_bytes    *res;
-
-       if ((value.discrim & VALUE_MASK) != VALUE_PTR)
-               return (NULL);
-       res = value.ptr - offsetof(struct s_value_bytes, bytes);
-       if (!value.ptr || res->discrim != VALUE_PTR_BYTES)
-               return (NULL);
-       return (res);
-}
-
-t_isize        value_int_get(t_value value)
-{
-       return (value.integral >> 1);
-}
index 08927c346d73a7b98b752b7efe1f5e65142af909..2bbf6e451aefe1e5c8e56c118cc3b9f9c9761217 100644 (file)
@@ -5,83 +5,74 @@
 /*                                                    +:+ +:+         +:+     */
 /*   By: agilliar <agilliar@student.42mulhouse.fr>  +#+  +:+       +#+        */
 /*                                                +#+#+#+#+#+   +#+           */
-/*   Created: 2026/05/04 02:05:48 by agilliar          #+#    #+#             */
-/*   Updated: 2026/05/06 19:29:20 by agilliar         ###   ########.fr       */
+/*   Created: 2026/05/12 17:42:10 by agilliar          #+#    #+#             */
+/*   Updated: 2026/05/13 09:36:40 by agilliar         ###   ########.fr       */
 /*                                                                            */
 /* ************************************************************************** */
 
-#include "ccera.h"
+#include "arc.h"
+#include "defer.h"
+#include "value.h"
 #include <string.h>
 
-t_value        value_copy(t_value value)
+t_value        value_copy(t_value val)
 {
-       void    *ptr;
+       if (val.tag == VALUE_BYTES)
+               arc_copy(val.val.v_bytes);
+       else if (val.tag == VALUE_LIST)
+               arc_copy(val.val.v_list);
+       return (val);
+}
 
-       ptr = value_list_get(value);
-       if (ptr)
-       {
-               arc_copy(ptr);
-               return (value);
-       }
-       ptr = value_bytes_get(value);
-       if (ptr)
+t_value        value_clone(t_value val)
+{
+       t_value         res;
+       t_list          *lst;
+
+       res = val;
+       if (val.tag == VALUE_LIST)
        {
-               arc_copy(ptr);
-               return (value);
+               res.val.v_bytes = arc_new(sizeof(t_bytes) + val.val.v_bytes->len);
+               memcpy(res.val.v_bytes->buf, val.val.v_bytes->buf,
+                       val.val.v_bytes->len);
        }
-       ptr = value_builtin_get(value);
-       if (ptr)
+       else if (val.tag == VALUE_BYTES)
        {
-               arc_copy(ptr);
-               return (value);
+               res.val.v_list = arc_new(sizeof(t_list)
+                               + sizeof(t_value) * val.val.v_list->len);
+               lst = res.val.v_list;
+               lst->len = 0;
+               errdeferc(value_drop, &res, sizeof(t_value));
+               while (lst->len < val.val.v_list->len)
+               {
+                       lst->buf[lst->len] = value_copy(val.val.v_list->buf[lst->len]);
+                       lst->len++;
+               }
        }
-       return (value_int_new(value_int_get(value)));
+       return (res);
 }
 
-t_value_list   *value_list_unique(t_value *value)
+static void    list_drop(t_list *lst)
 {
-       t_value_list    *list;
-       t_value                 new;
-       t_value_list    *new_list;
-       t_usize                 i;
+       uintptr_t       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);
+       while (i < lst->len)
+               value_drop(&lst->buf[i++]);
 }
 
-t_value_bytes  *value_bytes_unique(t_value *value)
+void   value_drop(t_value      *value)
 {
-       t_value_bytes   *bytes;
-       t_value                 new;
-       t_value_bytes   *new_bytes;
+       if (value->tag == VALUE_BYTES)
+               arc_drop(value->val.v_bytes, noop);
+       else if (value->tag == VALUE_BYTES)
+               arc_drop(value->val.v_list, list_drop);
+}
 
-       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);
+t_value        value_unique(t_value *val)
+{
+       if ((val->tag == VALUE_BYTES && !arc_is_unique(val->val.v_bytes))
+               || (val->tag == VALUE_LIST && !arc_is_unique(val->val.v_list)))
+               *val = value_clone(*val);
+       return (*val);
 }
index 589cabd639dac28b6d2871279f87bb54fbd6a8f9..cbf9f295adb9b86df8613392b5ee4dee0aaf2717 100644 (file)
@@ -5,77 +5,22 @@
 /*                                                    +:+ +:+         +:+     */
 /*   By: agilliar <agilliar@student.42mulhouse.fr>  +#+  +:+       +#+        */
 /*                                                +#+#+#+#+#+   +#+           */
-/*   Created: 2026/04/30 16:25:42 by agilliar          #+#    #+#             */
-/*   Updated: 2026/05/05 21:25:48 by agilliar         ###   ########.fr       */
+/*   Created: 2026/05/13 08:40:13 by agilliar          #+#    #+#             */
+/*   Updated: 2026/05/13 09:02:48 by agilliar         ###   ########.fr       */
 /*                                                                            */
 /* ************************************************************************** */
 
-#include "ccera.h"
+#include "value.h"
+#include "arith.h"
+#include "arc.h"
 #include <string.h>
 
-t_value        value_builtin_new(t_builtin builtin)
-{
-       struct s_value_builtin  *res;
-       t_value                                 res_raw;
-
-       res = arc_create(sizeof(struct s_value_builtin));
-       res->discrim = VALUE_PTR_BUILTIN;
-       res->builtin = builtin;
-       res_raw.ptr = &res->builtin;
-       res_raw.discrim |= VALUE_PTR;
-       return (res_raw);
-}
-
-t_value        value_list_new(t_usize len)
-{
-       struct s_value_list     *res;
-       t_value                         res_raw;
-       t_usize                         n;
-
-       if (__builtin_mul_overflow(len, sizeof(t_value), &n)
-               || __builtin_add_overflow(n, sizeof(t_value_list), &n))
-               panic("List size overflowed");
-       res = arc_create(n);
-       res->discrim = VALUE_PTR_LIST;
-       res->len = len;
-       n = 0;
-       while (n < len)
-               res->list[n++] = value_undefined_new();
-       res_raw.ptr = &res->list;
-       res_raw.discrim |= VALUE_PTR;
-       return (res_raw);
-}
-
-t_value        value_bytes_new(t_usize len)
-{
-       struct s_value_bytes    *res;
-       t_value                                 res_raw;
-       t_usize                                 n;
-
-       if (__builtin_add_overflow(len, sizeof(struct s_value_bytes), &n))
-               panic("Bytes size overflowed");
-       res = arc_create(n);
-       res->discrim = VALUE_PTR_BYTES;
-       res->len = len;
-       memset(&res->bytes, 0, len);
-       res_raw.ptr = &res->bytes;
-       res_raw.discrim |= VALUE_PTR;
-       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        value_new_bytes(uintptr_t len)
 {
        t_value res;
 
-       res.integral = n << 1;
-       res.discrim |= VALUE_INT;
+       res.tag = VALUE_BYTES;
+       res.val.v_bytes = arc_new(uadd(sizeof(t_bytes), len));
+       res.val.v_bytes->len = len;
        return (res);
 }