]> Untitled Git - axy/ft/c-cera.git/commitdiff
Exceptions and defer
authorAxy <gilliardmarthey.axel@gmail.com>
Wed, 6 May 2026 00:34:07 +0000 (02:34 +0200)
committerAxy <gilliardmarthey.axel@gmail.com>
Wed, 6 May 2026 00:34:07 +0000 (02:34 +0200)
14 files changed:
Makefile
src/arc.c
src/ccera.h
src/defer.c [new file with mode: 0644]
src/defer2.c [new file with mode: 0644]
src/eval.c
src/panic.c [new file with mode: 0644]
src/value_destroy.c
src/value_get.c
src/value_lifetime.c
src/value_new.c
src/value_readf.c [new file with mode: 0644]
test.c
vgcore.2443515 [new file with mode: 0644]

index 7c584c51b4eb09ae37c9687f3a66daf862f43154..16315615ec28daf72f975abb8ecea937b4920f93 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,6 @@
 NAME=ccera.a
 
-SRCS=src/arc.c src/eval.c src/value_destroy.c src/value_get.c src/value_lifetime.c src/value_new.c
+SRCS=src/arc.c src/defer2.c src/defer.c src/eval.c src/panic.c src/value_destroy.c src/value_get.c src/value_lifetime.c src/value_new.c src/value_readf.c
 
 HEADERS=src/ccera.h
 
@@ -10,8 +10,9 @@ THIS=Makefile
 
 OBJS=${SRCS:src/%.c=${BUILDDIR}/%.o}
 
-CFLAGS=-Wall -Wextra -Werror -g -pthread -flto -ffat-lto-objects
-#CFLAGS=-Wall -Wextra -Werror -g -pthread -O3 -flto -ffat-lto-objects
+# no malloc leak detection as our union shenanigans trigger false positives
+CFLAGS=-Wall -Wextra -Werror -g -pthread -flto -ffat-lto-objects -fanalyzer -Wno-analyzer-malloc-leak
+CFLAGS += -O3
 
 CC=gcc
 
@@ -19,27 +20,27 @@ AR=ar
 
 MAKEFLAGS += --no-print-directory
 
-all : ${NAME}
+all: ${NAME}
 
-${BUILDDIR}/%.o : src/%.c ${HEADERS} ${THIS} | ${BUILDDIR}
+${BUILDDIR}/%.o: src/%.c ${HEADERS} ${THIS} | ${BUILDDIR}
        ${CC} ${CFLAGS} -c -o $@ $<
 
-${BUILDDIR} :
+${BUILDDIR}:
        mkdir ${BUILDDIR}
 
-${NAME} : ${OBJS} ${THIS}
+${NAME}: ${OBJS} ${THIS}
        ${AR} rcs $@ ${OBJS}
 
-clean 
+clean: 
        rm -f ${OBJS}
 
-fclean : clean
+fclean: clean
        rm -f ${NAME}
        rm -fd ${BUILDDIR}
 
-re : fclean all
+re: fclean all
 
-remakefile : clean
+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}
 
@@ -48,7 +49,7 @@ remakefile : clean
        @norminette ${SRCS} ${HEADERS} > .norm || touch .norm_fail
 
 norm: .norm
-       @cat .norm
+       @cat .norm | sed "s/.*OK!$$//" | grep .
        @test ! -e .norm_fail
 
 norm-watch:
@@ -57,4 +58,10 @@ norm-watch:
 build-watch:
        watch -c -n 1 make
 
-.PHONY : all clean fclean re remakefile norm norm-watch build-watch
+a.out: test.c ${NAME} ${THIS} 
+       ${CC} ${CFLAGS} test.c ccera.a
+
+test: a.out
+       valgrind ./a.out
+
+.PHONY: all clean fclean re remakefile norm norm-watch build-watch test
index e4532398609d66ea243824f119656b221ff9428e..af02b810e39325686223b2e4e47ef0d3c23b4cb4 100644 (file)
--- a/src/arc.c
+++ b/src/arc.c
@@ -6,7 +6,7 @@
 /*   By: agilliar <agilliar@student.42mulhouse.fr>  +#+  +:+       +#+        */
 /*                                                +#+#+#+#+#+   +#+           */
 /*   Created: 2026/04/29 16:40:27 by agilliar          #+#    #+#             */
-/*   Updated: 2026/05/04 02:01:19 by agilliar         ###   ########.fr       */
+/*   Updated: 2026/05/05 20:40:03 by agilliar         ###   ########.fr       */
 /*                                                                            */
 /* ************************************************************************** */
 
@@ -18,23 +18,19 @@ t_arc       arc_create(t_usize size)
        t_usize *res;
 
        if (__builtin_add_overflow(size, sizeof(t_usize), &size))
-               return (NULL);
+               panic("Arc alloc too big to create");
        res = malloc(size);
        if (!res)
-               return (NULL);
+               panic("Malloc failed while creating arc");
        res[0] = 1;
        return ((void *) &res[1]);
 }
 
-t_arc  arc_copy(t_arc arc)
+void   arc_copy(t_arc arc)
 {
-       if (!arc)
-               return (NULL);
        if (__atomic_add_fetch(((t_usize *)arc) - 1, 1, __ATOMIC_RELAXED)
-               < ((t_usize) 1) << (sizeof(t_usize) * 8 - 1))
-               return (arc);
-       arc_destroy(arc, noop);
-       return (NULL);
+               >= ((t_usize) 1) << (sizeof(t_usize) * 8 - 1))
+               panic("Arc counter overflowed");
 }
 
 void   arc_destroy(t_arc arc, t_drop destructor)
@@ -45,7 +41,7 @@ void  arc_destroy(t_arc arc, t_drop destructor)
                return ;
        __atomic_thread_fence(__ATOMIC_ACQUIRE);
        destructor(arc);
-       free(arc - 8);
+       free(((char *)arc) - 8);
 }
 
 bool   arc_is_unique(t_arc arc)
index 9465c6eda34e9046770a105a5b1864fc2c37c7f6..7f3fc3564cf1a597f1f899f84bbd82beff150b1c 100644 (file)
@@ -6,7 +6,7 @@
 /*   By: agilliar <agilliar@student.42mulhouse.fr>  +#+  +:+       +#+        */
 /*                                                +#+#+#+#+#+   +#+           */
 /*   Created: 2026/04/29 16:08:57 by agilliar          #+#    #+#             */
-/*   Updated: 2026/05/04 03:58:26 by agilliar         ###   ########.fr       */
+/*   Updated: 2026/05/06 02:32:20 by agilliar         ###   ########.fr       */
 /*                                                                            */
 /* ************************************************************************** */
 
 typedef uintptr_t              t_usize;
 typedef intptr_t               t_isize;
 
+struct s_defer_pair
+{
+       void    (*f)(void *);
+       void    *dat;
+       bool    err;
+};
+
+# define MAX_DEFERS 8
+
+typedef struct s_defer
+{
+       struct s_defer          *prev;
+       struct s_defer          *next;
+       t_usize                         len;
+       struct s_defer_pair     defers[MAX_DEFERS];
+}      t_defer;
+
+void                   defer_new(t_defer *store);
+void                   defer_delete(t_defer *store);
+void                   defer_re(t_defer *store);
+
+void                   defer(void *f, void *dat);
+void                   errdefer(void *f, void *dat);
+void                   defer_exit(t_defer *until);
+
+typedef struct s_panic_info
+{
+       void            *data;
+       intptr_t        jmp[5];
+       t_defer         *defer;
+}      t_panic_info;
+
+void                   *catch(void (f)(void *), void *dat);
+
+void                   panic(void *err)
+                               __attribute__((noreturn, nonnull(1)));
+bool                   panicking(void);
+
 typedef union u_value  t_value;
 
 typedef t_value                        (*t_builtin)(t_value);
@@ -59,14 +97,14 @@ typedef struct s_value_list
 {
        t_usize                         len;
        enum e_value_ptr        discrim;
-       t_value                         list[0];
+       t_value                         list[];
 }      t_value_list;
 
 typedef struct s_value_bytes
 {
        t_usize                         len;
        enum e_value_ptr        discrim;
-       char                            bytes[0];
+       char                            bytes[];
 }      t_value_bytes;
 
 t_value                        value_builtin_new(t_builtin builtin);
@@ -80,7 +118,7 @@ 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);
+void                   value_destroy(t_value *value);
 
 t_value                        value_copy(t_value value);
 t_value_list   *value_list_unique(t_value *value);
@@ -94,14 +132,12 @@ 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);
+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);
 
-struct                                 s_exec_context;
-
 // The expression value is a tuple of an evaluatable and the argument to give it
 //
 // Value-evaluatables are laid out as follows:
diff --git a/src/defer.c b/src/defer.c
new file mode 100644 (file)
index 0000000..25320ba
--- /dev/null
@@ -0,0 +1,72 @@
+/* ************************************************************************** */
+/*                                                                            */
+/*                                                        :::      ::::::::   */
+/*   defer.c                                            :+:      :+:    :+:   */
+/*                                                    +:+ +:+         +:+     */
+/*   By: agilliar <agilliar@student.42mulhouse.fr>  +#+  +:+       +#+        */
+/*                                                +#+#+#+#+#+   +#+           */
+/*   Created: 2026/05/05 17:31:36 by agilliar          #+#    #+#             */
+/*   Updated: 2026/05/06 02:31:46 by agilliar         ###   ########.fr       */
+/*                                                                            */
+/* ************************************************************************** */
+
+#include "ccera.h"
+#include <stddef.h>
+
+t_defer        **defer_store(void);
+
+void   defer(void *f, void *dat)
+{
+       t_defer *store;
+
+       store = *defer_store();
+       if (store->len == MAX_DEFERS)
+       {
+               ((void (*)(void *))f)(dat);
+               panic("Maximum defers exeeded in scope");
+       }
+       store->defers[store->len].f = f;
+       store->defers[store->len].dat = dat;
+       store->defers[store->len].err = false;
+       store->len++;
+}
+
+void   errdefer(void *f, void *dat)
+{
+       t_defer *store;
+
+       store = *defer_store();
+       if (store->len == MAX_DEFERS)
+       {
+               ((void (*)(void *))f)(dat);
+               panic("Maximum defers exeeded in scope");
+       }
+       store->defers[store->len].f = f;
+       store->defers[store->len].dat = dat;
+       store->defers[store->len].err = true;
+       store->len++;
+}
+
+void   defer_exit(t_defer *until)
+{
+       t_usize                         i;
+       t_defer                         *store;
+       struct s_defer_pair     curr;
+
+       store = *defer_store();
+       while (store)
+       {
+               i = 0;
+               while (i < store->len)
+               {
+                       curr = store->defers[i++];
+                       if (!panicking() && curr.err)
+                               continue ;
+                       curr.f(curr.dat);
+               }
+               if (store == until)
+                       break ;
+               store = store->prev;
+       }
+       *defer_store() = store;
+}
diff --git a/src/defer2.c b/src/defer2.c
new file mode 100644 (file)
index 0000000..9a85883
--- /dev/null
@@ -0,0 +1,47 @@
+/* ************************************************************************** */
+/*                                                                            */
+/*                                                        :::      ::::::::   */
+/*   defer2.c                                           :+:      :+:    :+:   */
+/*                                                    +:+ +:+         +:+     */
+/*   By: agilliar <agilliar@student.42mulhouse.fr>  +#+  +:+       +#+        */
+/*                                                +#+#+#+#+#+   +#+           */
+/*   Created: 2026/05/06 02:23:38 by agilliar          #+#    #+#             */
+/*   Updated: 2026/05/06 02:32:07 by agilliar         ###   ########.fr       */
+/*                                                                            */
+/* ************************************************************************** */
+
+#include "ccera.h"
+#include <stddef.h>
+
+t_defer        **defer_store(void)
+{
+       static __thread t_defer *store = NULL;
+
+       return (&store);
+}
+
+void   defer_new(t_defer *store)
+{
+       store->len = 0;
+       store->prev = *defer_store();
+       if (store->prev)
+               store->prev->next = store;
+       store->next = NULL;
+       *defer_store() = store;
+}
+
+void   defer_delete(t_defer *store)
+{
+       if (store == *defer_store())
+               *defer_store() = store->prev;
+       if (store->next)
+               store->next->prev = store->prev;
+       if (store->prev)
+               store->prev->next = store->next;
+}
+
+void   defer_re(t_defer *store)
+{
+       defer_delete(store);
+       defer_new(store);
+}
index 597e6ceda1fd791194edd42b8377f34536ce9cb7..2636220923e449da25fea23eaeb9dc75b5a051ec 100644 (file)
@@ -6,32 +6,9 @@
 /*   By: agilliar <agilliar@student.42mulhouse.fr>  +#+  +:+       +#+        */
 /*                                                +#+#+#+#+#+   +#+           */
 /*   Created: 2026/05/04 01:21:34 by agilliar          #+#    #+#             */
-/*   Updated: 2026/05/04 04:12:32 by agilliar         ###   ########.fr       */
+/*   Updated: 2026/05/05 05:31:52 by agilliar         ###   ########.fr       */
 /*                                                                            */
 /* ************************************************************************** */
 
 #include "ccera.h"
 #include <stdlib.h>
-
-static bool    to_state(t_value *value)
-{
-       t_value_list    *expr;
-       t_value_list    *state;
-
-       expr = value_list_unique(value);
-       if (!expr || expr->len != 2)
-               return (false);
-       state = value_list_unique(&expr->list[0]);
-       if (!state || state->len != 2)
-               return (false);
-       if (!value_list_unique(&state->list[0]))
-               return (false);
-       return (true);
-}
-
-t_value        expr_eval(t_value expr)
-{
-       to_state(&expr);
-       value_destroy(expr);
-       return (value_undefined_new());
-}
diff --git a/src/panic.c b/src/panic.c
new file mode 100644 (file)
index 0000000..1b9fe7c
--- /dev/null
@@ -0,0 +1,56 @@
+/* ************************************************************************** */
+/*                                                                            */
+/*                                                        :::      ::::::::   */
+/*   panic.c                                            :+:      :+:    :+:   */
+/*                                                    +:+ +:+         +:+     */
+/*   By: agilliar <agilliar@student.42mulhouse.fr>  +#+  +:+       +#+        */
+/*                                                +#+#+#+#+#+   +#+           */
+/*   Created: 2026/05/05 15:38:33 by agilliar          #+#    #+#             */
+/*   Updated: 2026/05/05 21:25:00 by agilliar         ###   ########.fr       */
+/*                                                                            */
+/* ************************************************************************** */
+
+#include "ccera.h"
+#include <string.h>
+#include <stddef.h>
+#include <stdint.h>
+
+static t_panic_info    *panic_store(void)
+{
+       static __thread t_panic_info    store;
+
+       return (&store);
+}
+
+void   *catch(void (f)(void *), void *dat)
+{
+       void                    *res;
+       t_defer                 defer_store;
+       t_panic_info    prev;
+
+       prev = *panic_store();
+       panic_store()->defer = &defer_store;
+       defer_new(&defer_store);
+       if (__builtin_setjmp(panic_store()->jmp))
+       {
+               res = panic_store()->data;
+               *panic_store() = prev;
+               return (res);
+       }
+       f(dat);
+       *panic_store() = prev;
+       return (NULL);
+}
+
+__attribute__((noreturn, nonnull(1)))
+void   panic(void *err)
+{
+       defer_exit(panic_store()->defer);
+       panic_store()->data = err;
+       __builtin_longjmp(panic_store()->jmp, 1);
+}
+
+bool   panicking(void)
+{
+       return (panic_store()->data != NULL);
+}
index b67f20d9e2bcf27c244538137db6901fb6ef86e1..1e05c9a3640773146a19f3ac162996f210849d3b 100644 (file)
@@ -6,7 +6,7 @@
 /*   By: agilliar <agilliar@student.42mulhouse.fr>  +#+  +:+       +#+        */
 /*                                                +#+#+#+#+#+   +#+           */
 /*   Created: 2026/04/30 19:40:43 by agilliar          #+#    #+#             */
-/*   Updated: 2026/05/04 01:17:51 by agilliar         ###   ########.fr       */
+/*   Updated: 2026/05/05 20:54:09 by agilliar         ###   ########.fr       */
 /*                                                                            */
 /* ************************************************************************** */
 
@@ -30,12 +30,13 @@ static void value_list_del(struct s_value_list *list)
 
        i = 0;
        while (i < list->len)
-               value_destroy(list->list[i++]);
+               value_destroy(&list->list[i++]);
 }
 
-void   value_destroy(t_value value)
+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_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();
 }
index 7b79dc750979c8922bc16803af728ece23327ea7..43e3a1939da9cc476cfe34adbd39841423c3b8fd 100644 (file)
@@ -6,7 +6,7 @@
 /*   By: agilliar <agilliar@student.42mulhouse.fr>  +#+  +:+       +#+        */
 /*                                                +#+#+#+#+#+   +#+           */
 /*   Created: 2026/04/30 17:27:40 by agilliar          #+#    #+#             */
-/*   Updated: 2026/05/04 01:18:03 by agilliar         ###   ########.fr       */
+/*   Updated: 2026/05/05 21:32:17 by agilliar         ###   ########.fr       */
 /*                                                                            */
 /* ************************************************************************** */
 
@@ -20,7 +20,7 @@ struct s_value_builtin        *value_builtin_get(t_value value)
        if ((value.discrim & VALUE_MASK) != VALUE_PTR)
                return (NULL);
        res = value.ptr - offsetof(struct s_value_builtin, builtin);
-       if (res->discrim != VALUE_PTR_BUILTIN)
+       if (!value.ptr || res->discrim != VALUE_PTR_BUILTIN)
                return (NULL);
        return (res);
 }
@@ -32,7 +32,7 @@ struct s_value_list   *value_list_get(t_value value)
        if ((value.discrim & VALUE_MASK) != VALUE_PTR)
                return (NULL);
        res = value.ptr - offsetof(struct s_value_list, list);
-       if (res->discrim != VALUE_PTR_LIST)
+       if (!value.ptr || res->discrim != VALUE_PTR_LIST)
                return (NULL);
        return (res);
 }
@@ -44,7 +44,7 @@ struct s_value_bytes  *value_bytes_get(t_value value)
        if ((value.discrim & VALUE_MASK) != VALUE_PTR)
                return (NULL);
        res = value.ptr - offsetof(struct s_value_bytes, bytes);
-       if (res->discrim != VALUE_PTR_BYTES)
+       if (!value.ptr || res->discrim != VALUE_PTR_BYTES)
                return (NULL);
        return (res);
 }
index c5ad951280b47e404f073e2a1d8783f9a3d361f3..c2850cb7e66241ef0923c7ca443a4f7ad01a36f2 100644 (file)
@@ -6,7 +6,7 @@
 /*   By: agilliar <agilliar@student.42mulhouse.fr>  +#+  +:+       +#+        */
 /*                                                +#+#+#+#+#+   +#+           */
 /*   Created: 2026/05/04 02:05:48 by agilliar          #+#    #+#             */
-/*   Updated: 2026/05/04 03:27:11 by agilliar         ###   ########.fr       */
+/*   Updated: 2026/05/05 20:37:17 by agilliar         ###   ########.fr       */
 /*                                                                            */
 /* ************************************************************************** */
 
@@ -61,7 +61,7 @@ t_value_list  *value_list_unique(t_value *value)
                new_list->list[i] = value_copy(list->list[i]);
                i++;
        }
-       value_destroy(*value);
+       value_destroy(value);
        *value = new;
        return (new_list);
 }
@@ -82,7 +82,7 @@ t_value_bytes *value_bytes_unique(t_value *value)
        if (!new_bytes)
                return (NULL);
        memcpy(new_bytes->bytes, bytes->bytes, bytes->len);
-       value_destroy(*value);
+       value_destroy(value);
        *value = new;
        return (new_bytes);
 }
index 7dd45addbabd7c492cf80227330cf9b6523fb15a..589cabd639dac28b6d2871279f87bb54fbd6a8f9 100644 (file)
@@ -6,7 +6,7 @@
 /*   By: agilliar <agilliar@student.42mulhouse.fr>  +#+  +:+       +#+        */
 /*                                                +#+#+#+#+#+   +#+           */
 /*   Created: 2026/04/30 16:25:42 by agilliar          #+#    #+#             */
-/*   Updated: 2026/05/04 01:49:28 by agilliar         ###   ########.fr       */
+/*   Updated: 2026/05/05 21:25:48 by agilliar         ###   ########.fr       */
 /*                                                                            */
 /* ************************************************************************** */
 
@@ -19,8 +19,6 @@ t_value       value_builtin_new(t_builtin builtin)
        t_value                                 res_raw;
 
        res = arc_create(sizeof(struct s_value_builtin));
-       if (!res)
-               return (value_undefined_new());
        res->discrim = VALUE_PTR_BUILTIN;
        res->builtin = builtin;
        res_raw.ptr = &res->builtin;
@@ -35,11 +33,9 @@ t_value      value_list_new(t_usize len)
        t_usize                         n;
 
        if (__builtin_mul_overflow(len, sizeof(t_value), &n)
-               || __builtin_add_overflow(n, sizeof(struct s_value_list), &n))
-               return (value_undefined_new());
+               || __builtin_add_overflow(n, sizeof(t_value_list), &n))
+               panic("List size overflowed");
        res = arc_create(n);
-       if (!res)
-               return (value_undefined_new());
        res->discrim = VALUE_PTR_LIST;
        res->len = len;
        n = 0;
@@ -57,10 +53,8 @@ t_value      value_bytes_new(t_usize len)
        t_usize                                 n;
 
        if (__builtin_add_overflow(len, sizeof(struct s_value_bytes), &n))
-               return (value_undefined_new());
+               panic("Bytes size overflowed");
        res = arc_create(n);
-       if (!res)
-               return (value_undefined_new());
        res->discrim = VALUE_PTR_BYTES;
        res->len = len;
        memset(&res->bytes, 0, len);
diff --git a/src/value_readf.c b/src/value_readf.c
new file mode 100644 (file)
index 0000000..aa6cc56
--- /dev/null
@@ -0,0 +1,26 @@
+/* ************************************************************************** */
+/*                                                                            */
+/*                                                        :::      ::::::::   */
+/*   value_readf.c                                      :+:      :+:    :+:   */
+/*                                                    +:+ +:+         +:+     */
+/*   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       */
+/*                                                                            */
+/* ************************************************************************** */
+
+#include "ccera.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)
+//{
+//}
diff --git a/test.c b/test.c
index e15714d0ed9b2814f1524905bb9192f2030d82f3..ff6d963ce55c0a75e4fa639cf48b709278de2eab 100644 (file)
--- a/test.c
+++ b/test.c
@@ -6,7 +6,7 @@
 /*   By: agilliar <agilliar@student.42mulhouse.fr>  +#+  +:+       +#+        */
 /*                                                +#+#+#+#+#+   +#+           */
 /*   Created: 2026/04/30 17:19:58 by agilliar          #+#    #+#             */
-/*   Updated: 2026/05/04 04:13:07 by agilliar         ###   ########.fr       */
+/*   Updated: 2026/05/06 02:32:34 by agilliar         ###   ########.fr       */
 /*                                                                            */
 /* ************************************************************************** */
 
 #include <string.h>
 #include <stdio.h>
 
-int    main(void)
+void   main2(void *s)
 {
-       char    *s = "Hello cera!";
+       t_defer defer_store __attribute__((cleanup(defer_exit)));
+       defer_new(&defer_store);
+
        t_value arg = value_bytes_new(strlen(s) + 1);
+       defer(value_destroy, &arg);
+       //panic("A");
        t_value state = value_list_new(0);
+       defer(value_destroy, &state);
+       //panic("B");
        t_value idx = value_int_new(0);
        t_value fn = value_list_new(2);
+       defer(value_destroy, &fn);
+       //panic("C");
        t_value expr = value_list_new(2);
+       defer(value_destroy, &expr);
+       //panic("D");
+       defer_re(&defer_store);
        value_list_get(fn)->list[0] = state;
        value_list_get(fn)->list[1] = idx;
        value_list_get(expr)->list[0] = fn;
        value_list_get(expr)->list[1] = arg;
+       defer(value_destroy, &expr);
+       //panic("E");
        t_value val = value_copy(expr);
-       printf("%p\n", expr_eval(expr).ptr);
-       value_destroy(val);
+       defer(value_destroy, &val);
+       //panic("F");
+}
+
+int    main(void)
+{
+       if (char *err = catch(main2, "Hello cera!"))
+       {
+               printf("%s\n", err);
+               return (1);
+       }
 }
diff --git a/vgcore.2443515 b/vgcore.2443515
new file mode 100644 (file)
index 0000000..51ffaba
Binary files /dev/null and b/vgcore.2443515 differ