]> Untitled Git - axy/ft/c-cera.git/commitdiff
Borked but about to make big changes
authorAxy <gilliardmarthey.axel@gmail.com>
Thu, 14 May 2026 11:16:41 +0000 (13:16 +0200)
committerAxy <gilliardmarthey.axel@gmail.com>
Thu, 14 May 2026 11:16:41 +0000 (13:16 +0200)
23 files changed:
.editorconfig
Makefile
src/align.h
src/arc.c
src/arc.h
src/arith.h
src/ccera.h
src/defer.h
src/eval.c
src/framealloc.h
src/jmp.h
src/memutils.h [new file with mode: 0644]
src/panic.c
src/panic.h
src/stacktrack.c [new file with mode: 0644]
src/value.h
src/value_get.h [new file with mode: 0644]
src/value_lifetime.c
src/value_list.c [new file with mode: 0644]
src/value_move.c [new file with mode: 0644]
src/value_new.c
src/value_new.h [new file with mode: 0644]
src/value_types.h [new file with mode: 0644]

index 0b225afd480190043c933ae31f27399f831d6745..5643d90f82aa93487b144ba82b77e6097ad82dad 100644 (file)
@@ -1,2 +1,5 @@
-[*]
+[*.{c,h}]
+indent_style = tab
+
+[Makefile]
 indent_style = tab
index 86736534e76fcdc6941420ce757be2b51519e0b6..6f1899c99c3efb8d5ec787b8261dcb843310dce5 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,8 +1,8 @@
 NAME=ccera.a
 
-SRCS=src/arc.c src/defer.c src/eval.c src/framealloc.c src/panic.c src/value_lifetime.c src/value_new.c
+SRCS=src/arc.c src/defer.c src/eval.c src/framealloc.c src/panic.c src/stacktrack.c src/value_lifetime.c src/value_list.c src/value_move.c src/value_new.c
 
-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
+HEADERS=src/align.h src/arc.h src/arith.h src/ccera.h src/defer.h src/framealloc.h src/jmp.h src/memutils.h src/panic.h src/return_patch.h src/value_get.h src/value.h src/value_new.h src/value_types.h
 
 BUILDDIR=.build
 
@@ -13,9 +13,12 @@ DEPSFILE=.deps
 OBJS=${SRCS:src/%.c=${BUILDDIR}/%.o}
 
 CFLAGS=-Wall -Wextra -Werror -pthread -std=gnu23
+# IMPORTANT: We use this to properly keep track of stack frames at a source level
+CFLAGS += -finstrument-functions
 CFLAGS += -g
-#CFLAGS += -O3
-#CFLAGS += -flto -ffat-lto-objects
+CFLAGS += -O3
+CFLAGS += -flto -ffat-lto-objects
+CFLAGS += -fdiagnostics-color
 
 #CC=clang
 CC=gcc
@@ -46,13 +49,13 @@ fclean: clean
 
 re: fclean all
 
-${THIS}.tmp: ${SRCS} ${HEADERS} ${THIS}
+${THIS}.tmp: src ${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/" > $@
+${DEPSFILE}.tmp: src ${THIS}
+       ${CC} ${CFLAGS} -MM ${SRCS} | sed "s/^\([^ ]\)/\$${BUILDDIR}\/\1/" > $@
 
 redeps: ${DEPSFILE}.tmp
        @echo Rebuilding deps
index 371cd3072dd05b8120400fd2ecc8da2e35fcb81e..05f9b39bac8542cb715d21aaf8e95e10f55c7e86 100644 (file)
@@ -6,34 +6,52 @@
 /*   By: agilliar <agilliar@student.42mulhouse.fr>  +#+  +:+       +#+        */
 /*                                                +#+#+#+#+#+   +#+           */
 /*   Created: 2026/05/12 10:03:30 by agilliar          #+#    #+#             */
-/*   Updated: 2026/05/12 13:36:28 by agilliar         ###   ########.fr       */
+/*   Updated: 2026/05/13 21:16:36 by agilliar         ###   ########.fr       */
 /*                                                                            */
 /* ************************************************************************** */
 
 #ifndef ALIGN_H
 # define ALIGN_H
 
-# include <stdint.h>
+# include <stddef.h>
 
 # ifdef __builtin_align_up
 
 __attribute__((always_inline))
-static inline void     *align_up(void *p, uintptr_t align)
+static inline void     *align_up(void *p, size_t align)
 {
        return (__builtin_align_up(p, align));
 }
 
+__attribute__((always_inline))
+static inline void     *align_down(void *p, size_t align)
+{
+       return (__builtin_align_down(p, align));
+}
+
 # else
 
 __attribute__((always_inline))
-static inline void     *align_up(void *p, uintptr_t align)
+static inline void     *align_up(void *p, size_t align)
+{
+       size_t  n;
+
+       n = (size_t) p;
+       n += align - 1;
+       n = (n / align) * align;
+       n -= (size_t) p;
+       p = &((char *) p)[n];
+       return (p);
+}
+
+__attribute__((always_inline))
+static inline void     *align_down(void *p, size_t align)
 {
-       uintptr_t       n;
+       size_t  n;
 
-       n = (intptr_t) p;
-       if (n % align)
-               n = ((n / align) + n % align) * align;
-       n -= (intptr_t) p;
+       n = (size_t) p;
+       n = (n / align) * align;
+       n -= (size_t) p;
        p = &((char *) p)[n];
        return (p);
 }
index 83329fdeb5f7ac454308bb1fae511513707bc9b6..76bbaed8e716fc54633ca765070b6826362f11ad 100644 (file)
--- a/src/arc.c
+++ b/src/arc.c
@@ -6,23 +6,21 @@
 /*   By: agilliar <agilliar@student.42mulhouse.fr>  +#+  +:+       +#+        */
 /*                                                +#+#+#+#+#+   +#+           */
 /*   Created: 2026/04/29 16:40:27 by agilliar          #+#    #+#             */
-/*   Updated: 2026/05/13 09:00:47 by agilliar         ###   ########.fr       */
+/*   Updated: 2026/05/13 16:42:04 by agilliar         ###   ########.fr       */
 /*                                                                            */
 /* ************************************************************************** */
 
+#include <stddef.h>
 #include "arc.h"
 #include "panic.h"
-#include <stdlib.h>
+#include "memutils.h"
+#include "arith.h"
 
-t_arc  arc_new(uintptr_t size)
+t_arc  arc_new(size_t size)
 {
-       uintptr_t       *res;
+       size_t  *res;
 
-       if (__builtin_add_overflow(size, sizeof(uintptr_t), &size))
-               panic("Arc alloc too big to create");
-       res = malloc(size);
-       if (!res)
-               panic("Malloc failed while creating arc");
+       res = cera_malloc(uadd(sizeof(size_t), size));
        res[0] = 1;
        return ((void *) &res[1]);
 }
@@ -30,17 +28,17 @@ t_arc       arc_new(uintptr_t size)
 // Relaxed sub as we own a copy, and as such ultimately sync
 void   arc_copy(t_arc arc)
 {
-       if (__atomic_add_fetch(((uintptr_t *)arc) - 1, 1, __ATOMIC_RELAXED)
-               >= ((uintptr_t) 1) << (sizeof(uintptr_t) * 8 - 1))
+       if (__atomic_add_fetch(((size_t *)arc) - 1, 1, __ATOMIC_RELAXED)
+               >= ((size_t) 1) << (sizeof(size_t) * 8 - 1))
        {
-               __atomic_sub_fetch(((uintptr_t *)arc) - 1, 1, __ATOMIC_RELAXED);
+               __atomic_sub_fetch(((size_t *)arc) - 1, 1, __ATOMIC_RELAXED);
                panic("Arc counter near overflowing");
        }
 }
 
 void   arc_drop(t_arc arc, t_drop destructor)
 {
-       if (__atomic_sub_fetch(((uintptr_t *)arc) - 1, 1, __ATOMIC_RELEASE) != 0)
+       if (__atomic_sub_fetch(((size_t *)arc) - 1, 1, __ATOMIC_RELEASE) != 0)
                return ;
        __atomic_thread_fence(__ATOMIC_ACQUIRE);
        ((void (*)(void *))destructor)(arc);
@@ -49,7 +47,7 @@ void  arc_drop(t_arc arc, t_drop destructor)
 
 bool   arc_is_unique(t_arc arc)
 {
-       return (__atomic_load_n(((uintptr_t *)arc) - 1, __ATOMIC_ACQUIRE) == 1);
+       return (__atomic_load_n(((size_t *)arc) - 1, __ATOMIC_ACQUIRE) == 1);
 }
 
 void   noop(void *ptr)
index 600dca1cde727c5f1dd0b78bf377322821b0b4a5..5ca8a82b3a470c386affc23e74c800764211c080 100644 (file)
--- a/src/arc.h
+++ b/src/arc.h
@@ -6,24 +6,37 @@
 /*   By: agilliar <agilliar@student.42mulhouse.fr>  +#+  +:+       +#+        */
 /*                                                +#+#+#+#+#+   +#+           */
 /*   Created: 2026/05/13 08:56:53 by agilliar          #+#    #+#             */
-/*   Updated: 2026/05/13 10:02:51 by agilliar         ###   ########.fr       */
+/*   Updated: 2026/05/13 12:55:03 by agilliar         ###   ########.fr       */
 /*                                                                            */
 /* ************************************************************************** */
 
 #ifndef ARC_H
 # define ARC_H
 
-# include <stdint.h>
+# include <stddef.h>
 # include <stdbool.h>
+# include "memutils.h"
+# include "arith.h"
 
 typedef void   *t_arc;
 typedef void   *t_drop;
 
-t_arc  arc_new(uintptr_t size);
+t_arc  arc_new(size_t size);
 void   arc_copy(t_arc arc);
 void   arc_drop(t_arc arc, t_drop destructor);
 bool   arc_is_unique(t_arc arc);
 
+__attribute__((always_inline))
+static inline t_arc    arc_new_zeroed(size_t size)
+{
+       size_t  *res;
+
+       res = cera_calloc(uadd(sizeof(size_t), size));
+       res[0] = 1;
+       return ((void *) &res[1]);
+}
+
+t_arc  arc_new_zeroed(size_t size);
 void   noop(void *ptr);
 
 #endif
index baccaa5fb02e5e0711490c091d4f171c97bc1205..cc86cc562534c54996ce75ae9763b98bf4612257 100644 (file)
@@ -6,7 +6,7 @@
 /*   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       */
+/*   Updated: 2026/05/13 11:59:31 by agilliar         ###   ########.fr       */
 /*                                                                            */
 /* ************************************************************************** */
 
@@ -17,7 +17,7 @@
 # include "panic.h"
 
 __attribute__((always_inline))
-static inline uintptr_t        uadd(uintptr_t a, uintptr_t b)
+static inline uint64_t uadd(uint64_t a, uint64_t b)
 {
        if (__builtin_add_overflow(a, b, &a))
                panic("Addition overflowed");
@@ -25,7 +25,7 @@ static inline uintptr_t       uadd(uintptr_t a, uintptr_t b)
 }
 
 __attribute__((always_inline))
-static inline uintptr_t        usub(uintptr_t a, uintptr_t b)
+static inline uint64_t usub(uint64_t a, uint64_t b)
 {
        if (__builtin_sub_overflow(a, b, &a))
                panic("Substraction overflowed");
@@ -33,7 +33,7 @@ static inline uintptr_t       usub(uintptr_t a, uintptr_t b)
 }
 
 __attribute__((always_inline))
-static inline uintptr_t        umul(uintptr_t a, uintptr_t b)
+static inline uint64_t umul(uint64_t a, uint64_t b)
 {
        if (__builtin_mul_overflow(a, b, &a))
                panic("Multiplication overflowed");
index edaab4241d9b0308ae0bbd3c76b6557c3d6d8a92..01226ed96533a7d6dfa0e018dcd56fc726680499 100644 (file)
@@ -6,17 +6,13 @@
 /*   By: agilliar <agilliar@student.42mulhouse.fr>  +#+  +:+       +#+        */
 /*                                                +#+#+#+#+#+   +#+           */
 /*   Created: 2026/04/29 16:08:57 by agilliar          #+#    #+#             */
-/*   Updated: 2026/05/13 08:57:19 by agilliar         ###   ########.fr       */
+/*   Updated: 2026/05/13 21:17:24 by agilliar         ###   ########.fr       */
 /*                                                                            */
 /* ************************************************************************** */
 
 #ifndef CCERA_H
 # define CCERA_H
 
-# include <stdint.h>
-# include <stdbool.h>
-# include <stddef.h>
-
 # include "jmp.h"
 # include "defer.h"
 # include "panic.h"
@@ -43,6 +39,6 @@
 // move is whether said value shall be moved out
 //
 // This function takes ownership
-t_value                        expr_eval(t_value expr);
+t_value                        expr_eval(t_value val);
 
 #endif
index b3a272bc565e7a272f14e835fa9efdc6f608a244..c15bad1d3c98a4c4681bbaf2703a2cb7d0113302 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 16:58:46 by agilliar         ###   ########.fr       */
+/*   Updated: 2026/05/13 20:54:16 by agilliar         ###   ########.fr       */
 /*                                                                            */
 /* ************************************************************************** */
 
@@ -17,6 +17,7 @@
 # include <string.h>
 # include "framealloc.h"
 # include "return_patch.h"
+# include "memutils.h"
 
 typedef struct s_defer
 {
@@ -88,24 +89,19 @@ static inline void  errdefer(void *f, void *dat)
        defer_store()->frame = curr;
 }
 
+// Defers the given function, alloca-ing size data from the pointer
+// Not necessary for errdefer as the stack variables are still live
+// on panic
+//
 __attribute__((always_inline))
-static inline void     deferc(void *f, void *dat, uintptr_t size)
+static inline void     *deferc(void *f, void *dat, size_t size)
 {
        void    *b;
 
        b = cera_alloca(size);
-       memcpy(b, dat, size);
+       cera_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);
+       return (b);
 }
 
 #endif
index 2636220923e449da25fea23eaeb9dc75b5a051ec..90499ceb93b47ca37bef7b36f8ac16d6cf55e86e 100644 (file)
@@ -6,9 +6,57 @@
 /*   By: agilliar <agilliar@student.42mulhouse.fr>  +#+  +:+       +#+        */
 /*                                                +#+#+#+#+#+   +#+           */
 /*   Created: 2026/05/04 01:21:34 by agilliar          #+#    #+#             */
-/*   Updated: 2026/05/05 05:31:52 by agilliar         ###   ########.fr       */
+/*   Updated: 2026/05/13 22:42:06 by agilliar         ###   ########.fr       */
 /*                                                                            */
 /* ************************************************************************** */
 
 #include "ccera.h"
-#include <stdlib.h>
+
+// Has ownership of the values given
+t_value        eval_step(t_value arg, t_value *exprs, uintptr_t *i)
+{
+       (void) arg;
+       (void) exprs;
+       (void) i;
+}
+
+// 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)
+{
+       t_value         *expr;
+       t_value         *eval;
+       t_value         arg;
+       t_value         *exprs;
+       uintptr_t       *i;
+
+       expr = deferc(value_drop, &_expr, sizeof(t_value));
+       eval = value_list_getu(expr, 0);
+       arg = value_take_nil(value_list_getu(expr, 1));
+       exprs = value_list_getu(eval, 0);
+       i = value_uint(value_list_getu(eval, 1));
+       (void) exprs;
+       (void) i;
+       while (*i < value_list(exprs)->len)
+       {
+               eval_step(arg, exprs, i);
+               (*i)++;
+       }
+       return (value_take_nil(value_list_getu(eval, (*i) - 1)));
+}
index 2538eea8dccdc856da7327fe7167425663e4ce09..a176e8f1c6c34a11829c47b6927b8f23664ecdb0 100644 (file)
@@ -6,14 +6,14 @@
 /*   By: agilliar <agilliar@student.42mulhouse.fr>  +#+  +:+       +#+        */
 /*                                                +#+#+#+#+#+   +#+           */
 /*   Created: 2026/05/11 19:17:56 by agilliar          #+#    #+#             */
-/*   Updated: 2026/05/12 16:58:56 by agilliar         ###   ########.fr       */
+/*   Updated: 2026/05/13 21:16:13 by agilliar         ###   ########.fr       */
 /*                                                                            */
 /* ************************************************************************** */
 
 #ifndef FRAMEALLOC_H
 # define FRAMEALLOC_H
 
-# include <stdint.h>
+# include <stddef.h>
 # include "return_patch.h"
 # include "align.h"
 
@@ -23,7 +23,7 @@
 
 typedef struct s_framealloc_frame
 {
-       uintptr_t                                       used;
+       size_t                                          used;
        struct s_framealloc_frame       *prev;
        void                                            *ret_ptr;
        void                                            *frame_ptr;
@@ -41,14 +41,14 @@ void                                framealloc_pop_shim(void)
 void                           framealloc_pop(void);
 
 __attribute__((always_inline, malloc, alloc_size(1), alloc_align(2)))
-static inline void     *cera_alloca_align_nopatch(uintptr_t len, uintptr_t align)
+static inline void     *cera_alloca_align_nopatch(size_t len, size_t align)
 {
        t_framealloc    *store;
        void                    *res;
 
        store = framealloc_store();
        res = &store->buf[store->frame.used];
-       store->frame.used += ((uintptr_t)(align_up(res, align) - res))
+       store->frame.used += ((size_t)(align_up(res, align) - res))
                + len;
        res = align_up(res, align);
        return (res);
@@ -78,14 +78,14 @@ static inline void  cera_alloca_patch(void)
 }
 
 __attribute__((always_inline, malloc, alloc_size(1), alloc_align(2)))
-static inline void     *cera_alloca_align(uintptr_t len, uintptr_t align)
+static inline void     *cera_alloca_align(size_t len, size_t align)
 {
        cera_alloca_patch();
        return (cera_alloca_align_nopatch(len, align));
 }
 
 __attribute__((always_inline, malloc, alloc_size(1)))
-static inline void     *cera_alloca(uintptr_t len)
+static inline void     *cera_alloca(size_t len)
 {
        return (cera_alloca_align(len, 8));
 }
index 45c24a516bb1e1018e3a94c537c489cdd2299f2a..0d422505fb8ae19fb60989c5f757a4a91a9dfe11 100644 (file)
--- a/src/jmp.h
+++ b/src/jmp.h
@@ -6,15 +6,16 @@
 /*   By: agilliar <agilliar@student.42mulhouse.fr>  +#+  +:+       +#+        */
 /*                                                +#+#+#+#+#+   +#+           */
 /*   Created: 2026/05/10 22:08:02 by agilliar          #+#    #+#             */
-/*   Updated: 2026/05/13 10:53:39 by agilliar         ###   ########.fr       */
+/*   Updated: 2026/05/13 16:43:56 by agilliar         ###   ########.fr       */
 /*                                                                            */
 /* ************************************************************************** */
 
 #ifndef JMP_H
+
 # define JMP_H
 
-# include <stdint.h>
+# include <stddef.h>
 
-typedef intptr_t       t_jmp[3];
+typedef size_t t_jmp[3];
 
 #endif
diff --git a/src/memutils.h b/src/memutils.h
new file mode 100644 (file)
index 0000000..18acaaa
--- /dev/null
@@ -0,0 +1,74 @@
+/* ************************************************************************** */
+/*                                                                            */
+/*                                                        :::      ::::::::   */
+/*   memutils.h                                         :+:      :+:    :+:   */
+/*                                                    +:+ +:+         +:+     */
+/*   By: agilliar <agilliar@student.42mulhouse.fr>  +#+  +:+       +#+        */
+/*                                                +#+#+#+#+#+   +#+           */
+/*   Created: 2026/05/13 11:08:38 by agilliar          #+#    #+#             */
+/*   Updated: 2026/05/13 12:28:33 by agilliar         ###   ########.fr       */
+/*                                                                            */
+/* ************************************************************************** */
+
+#ifndef MEMUTILS_H
+# define MEMUTILS_H
+
+# include <stddef.h>
+# include <stdlib.h>
+# include "panic.h"
+
+__attribute__((always_inline))
+static inline void
+       *cera_memcpy(void *restrict dst, const void *src, size_t len)
+{
+       size_t  i;
+
+       i = 0;
+       while (i < len)
+       {
+               ((char *restrict) dst)[i] = ((const char *) src)[i];
+               i++;
+       }
+       return (dst);
+}
+
+__attribute__((always_inline))
+static inline void     *cera_memset(void *dst, char c, size_t len)
+{
+       size_t  i;
+
+       i = 0;
+       while (i < len)
+               ((char *) dst)[i++] = c;
+       return (dst);
+}
+
+__attribute__((always_inline))
+static inline size_t   cera_strlen(const char *dst)
+{
+       size_t  i;
+
+       i = 0;
+       while (dst[i] != '\0')
+               i++;
+       return (i);
+}
+
+__attribute__((always_inline))
+static inline void     *cera_malloc(size_t len)
+{
+       void    *res;
+
+       res = malloc(len);
+       if (!res)
+               panic("Malloc error");
+       return (res);
+}
+
+__attribute__((always_inline))
+static inline void     *cera_calloc(size_t len)
+{
+       return (cera_memset(cera_malloc(len), 0, len));
+}
+
+#endif
index f3e0640d2c7ca5b1701cfb244f47a2b2369f0de0..699db6fc411621f6d530d7bf70b7960988cb05cb 100644 (file)
@@ -6,7 +6,7 @@
 /*   By: agilliar <agilliar@student.42mulhouse.fr>  +#+  +:+       +#+        */
 /*                                                +#+#+#+#+#+   +#+           */
 /*   Created: 2026/05/05 15:38:33 by agilliar          #+#    #+#             */
-/*   Updated: 2026/05/13 09:36:19 by agilliar         ###   ########.fr       */
+/*   Updated: 2026/05/13 11:34:46 by agilliar         ###   ########.fr       */
 /*                                                                            */
 /* ************************************************************************** */
 
@@ -20,6 +20,7 @@ t_panic_info  *panic_store(void)
        return (&store);
 }
 
+__attribute__((returns_nonnull))
 void   *catch(void *f, void *dat)
 {
        void                    *res;
index 213fbf5d14b7c005f9f015a74943dcd8d57a1464..85f7d07f0c33867752a8ba795dfe2e006cefe50a 100644 (file)
@@ -6,7 +6,7 @@
 /*   By: agilliar <agilliar@student.42mulhouse.fr>  +#+  +:+       +#+        */
 /*                                                +#+#+#+#+#+   +#+           */
 /*   Created: 2026/05/10 22:11:10 by agilliar          #+#    #+#             */
-/*   Updated: 2026/05/12 12:16:56 by agilliar         ###   ########.fr       */
+/*   Updated: 2026/05/13 11:34:25 by agilliar         ###   ########.fr       */
 /*                                                                            */
 /* ************************************************************************** */
 
@@ -26,7 +26,8 @@ t_panic_info          *panic_store(void);
 
 void                           panic(void *err)
                                        __attribute__((noreturn, nonnull(1)));
-void                           *catch(void *f, void *dat);
+void                           *catch(void *f, void *dat)
+                                       __attribute__((returns_nonnull));
 bool                           panicking(void);
 
 #endif
diff --git a/src/stacktrack.c b/src/stacktrack.c
new file mode 100644 (file)
index 0000000..b948404
--- /dev/null
@@ -0,0 +1,51 @@
+/* ************************************************************************** */
+/*                                                                            */
+/*                                                        :::      ::::::::   */
+/*   stacktrack.c                                       :+:      :+:    :+:   */
+/*                                                    +:+ +:+         +:+     */
+/*   By: agilliar <agilliar@student.42mulhouse.fr>  +#+  +:+       +#+        */
+/*                                                +#+#+#+#+#+   +#+           */
+/*   Created: 2026/05/14 12:00:36 by agilliar          #+#    #+#             */
+/*   Updated: 2026/05/14 13:11:24 by agilliar         ###   ########.fr       */
+/*                                                                            */
+/* ************************************************************************** */
+
+#include <stdbool.h>
+#include <stddef.h>
+
+#define RETFUNC_STACK_HEIGHT 1024
+
+void   ***retfunc_store(void)
+{
+       static __thread void    *stack[RETFUNC_STACK_HEIGHT];
+       static __thread void    **store = stack;
+
+       return (&store);
+}
+
+__attribute__((no_instrument_function))
+void   __cyg_profile_func_enter(void *this_fn, void *call_site)
+{
+       void    **store;
+
+       (void) this_fn;
+       (void) call_site;
+       store = retfunc_store();
+       (*store)++;
+       if (**store)
+               __builtin_unreachable();
+}
+
+__attribute__((no_instrument_function))
+void   __cyg_profile_func_exit(void *this_fn, void *call_site)
+{
+       void    **store;
+
+       (void) this_fn;
+       (void) call_site;
+       store = retfunc_store();
+       if (**store)
+               ((void (*)(void))**store)();
+       **store = NULL;
+       (*store)--;
+}
index 458f6dc168c933490dc599c80c20d6b56cfa7bb5..9c2cc859e2dd0a5c870dde5a5ee598d135fae462 100644 (file)
@@ -6,55 +6,30 @@
 /*   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       */
+/*   Updated: 2026/05/13 22:20:49 by agilliar         ###   ########.fr       */
 /*                                                                            */
 /* ************************************************************************** */
 
 #ifndef VALUE_H
 # define VALUE_H
 
+# include <stddef.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;
+# include "value_get.h"
+# include "value_types.h"
+# include "value_new.h"
 
 t_value        value_copy(t_value val);
 t_value        value_clone(t_value val);
 void   value_drop(t_value      *value);
+t_value        value_unique(t_value *val);
+
+t_value        *value_list_get(t_value lst, size_t i);
+t_value        *value_list_getu(t_value *lst, size_t i);
+
+void   value_swap(t_value *a, t_value *b);
+t_value        value_take(t_value *a, t_value b);
+t_value        value_take_nil(t_value *a);
 
 #endif
diff --git a/src/value_get.h b/src/value_get.h
new file mode 100644 (file)
index 0000000..a33c66f
--- /dev/null
@@ -0,0 +1,51 @@
+/* ************************************************************************** */
+/*                                                                            */
+/*                                                        :::      ::::::::   */
+/*   value_get.h                                        :+:      :+:    :+:   */
+/*                                                    +:+ +:+         +:+     */
+/*   By: agilliar <agilliar@student.42mulhouse.fr>  +#+  +:+       +#+        */
+/*                                                +#+#+#+#+#+   +#+           */
+/*   Created: 2026/05/13 22:01:24 by agilliar          #+#    #+#             */
+/*   Updated: 2026/05/13 22:29:29 by agilliar         ###   ########.fr       */
+/*                                                                            */
+/* ************************************************************************** */
+
+#ifndef VALUE_GET_H
+# define VALUE_GET_H
+
+# include "value_types.h"
+# include "panic.h"
+
+__attribute__((always_inline))
+static inline intptr_t *value_int(t_value *value)
+{
+       if (value->tag != VALUE_INT)
+               panic("Expected value to be int");
+       return (&value->val.v_int);
+}
+
+__attribute__((always_inline))
+static inline uintptr_t        *value_uint(t_value *value)
+{
+       if (value->tag != VALUE_UINT)
+               panic("Expected value to be uint");
+       return (&value->val.v_uint);
+}
+
+__attribute__((always_inline))
+static inline t_list   *value_list(t_value *value)
+{
+       if (value->tag != VALUE_LIST)
+               panic("Expected value to be list");
+       return (value->val.v_list);
+}
+
+__attribute__((always_inline))
+static inline t_bytes  *value_bytes(t_value *value)
+{
+       if (value->tag != VALUE_BYTES)
+               panic("Expected value to be bytes");
+       return (value->val.v_bytes);
+}
+
+#endif
index 2bbf6e451aefe1e5c8e56c118cc3b9f9c9761217..d37290fb8e5a83ff729debd5395f96e46bb290c4 100644 (file)
@@ -6,14 +6,15 @@
 /*   By: agilliar <agilliar@student.42mulhouse.fr>  +#+  +:+       +#+        */
 /*                                                +#+#+#+#+#+   +#+           */
 /*   Created: 2026/05/12 17:42:10 by agilliar          #+#    #+#             */
-/*   Updated: 2026/05/13 09:36:40 by agilliar         ###   ########.fr       */
+/*   Updated: 2026/05/13 22:29:20 by agilliar         ###   ########.fr       */
 /*                                                                            */
 /* ************************************************************************** */
 
+#include <stddef.h>
 #include "arc.h"
 #include "defer.h"
 #include "value.h"
-#include <string.h>
+#include "memutils.h"
 
 t_value        value_copy(t_value val)
 {
@@ -33,7 +34,7 @@ t_value       value_clone(t_value val)
        if (val.tag == VALUE_LIST)
        {
                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,
+               cera_memcpy(res.val.v_bytes->buf, val.val.v_bytes->buf,
                        val.val.v_bytes->len);
        }
        else if (val.tag == VALUE_BYTES)
@@ -42,7 +43,7 @@ t_value       value_clone(t_value val)
                                + sizeof(t_value) * val.val.v_list->len);
                lst = res.val.v_list;
                lst->len = 0;
-               errdeferc(value_drop, &res, sizeof(t_value));
+               errdefer(value_drop, &res);
                while (lst->len < val.val.v_list->len)
                {
                        lst->buf[lst->len] = value_copy(val.val.v_list->buf[lst->len]);
@@ -54,7 +55,7 @@ t_value       value_clone(t_value val)
 
 static void    list_drop(t_list *lst)
 {
-       uintptr_t       i;
+       size_t  i;
 
        i = 0;
        while (i < lst->len)
diff --git a/src/value_list.c b/src/value_list.c
new file mode 100644 (file)
index 0000000..45d5588
--- /dev/null
@@ -0,0 +1,31 @@
+/* ************************************************************************** */
+/*                                                                            */
+/*                                                        :::      ::::::::   */
+/*   value_list.c                                       :+:      :+:    :+:   */
+/*                                                    +:+ +:+         +:+     */
+/*   By: agilliar <agilliar@student.42mulhouse.fr>  +#+  +:+       +#+        */
+/*                                                +#+#+#+#+#+   +#+           */
+/*   Created: 2026/05/13 12:51:13 by agilliar          #+#    #+#             */
+/*   Updated: 2026/05/13 22:30:13 by agilliar         ###   ########.fr       */
+/*                                                                            */
+/* ************************************************************************** */
+
+#include <stddef.h>
+#include "value.h"
+#include "panic.h"
+
+// Borrows the value
+t_value        *value_list_get(t_value lst, size_t i)
+{
+       if (lst.tag != VALUE_LIST)
+               panic("List get on wrong type");
+       if (lst.val.v_list->len <= i)
+               panic("List get out of bounds");
+       return (&lst.val.v_list->buf[i]);
+}
+
+t_value        *value_list_getu(t_value *lst, size_t i)
+{
+       value_unique(lst);
+       return (value_list_get(*lst, i));
+}
diff --git a/src/value_move.c b/src/value_move.c
new file mode 100644 (file)
index 0000000..223208c
--- /dev/null
@@ -0,0 +1,33 @@
+/* ************************************************************************** */
+/*                                                                            */
+/*                                                        :::      ::::::::   */
+/*   value_move.c                                       :+:      :+:    :+:   */
+/*                                                    +:+ +:+         +:+     */
+/*   By: agilliar <agilliar@student.42mulhouse.fr>  +#+  +:+       +#+        */
+/*                                                +#+#+#+#+#+   +#+           */
+/*   Created: 2026/05/13 21:27:54 by agilliar          #+#    #+#             */
+/*   Updated: 2026/05/13 22:30:27 by agilliar         ###   ########.fr       */
+/*                                                                            */
+/* ************************************************************************** */
+
+#include "value.h"
+
+void   value_swap(t_value *a, t_value *b)
+{
+       t_value tmp;
+
+       tmp = *a;
+       *a = *b;
+       *b = tmp;
+}
+
+t_value        value_take(t_value *a, t_value b)
+{
+       value_swap(a, &b);
+       return (b);
+}
+
+t_value        value_take_nil(t_value *a)
+{
+       return (value_take(a, value_new_nil()));
+}
index cbf9f295adb9b86df8613392b5ee4dee0aaf2717..16b67aa5acf56a5da4a6d79a734197ae2b2e1a5b 100644 (file)
@@ -6,21 +6,49 @@
 /*   By: agilliar <agilliar@student.42mulhouse.fr>  +#+  +:+       +#+        */
 /*                                                +#+#+#+#+#+   +#+           */
 /*   Created: 2026/05/13 08:40:13 by agilliar          #+#    #+#             */
-/*   Updated: 2026/05/13 09:02:48 by agilliar         ###   ########.fr       */
+/*   Updated: 2026/05/13 18:17:10 by agilliar         ###   ########.fr       */
 /*                                                                            */
 /* ************************************************************************** */
 
+#include <stddef.h>
 #include "value.h"
 #include "arith.h"
 #include "arc.h"
-#include <string.h>
+#include "memutils.h"
 
-t_value        value_new_bytes(uintptr_t len)
+t_value        value_new_bytes(size_t len)
 {
        t_value res;
 
        res.tag = VALUE_BYTES;
-       res.val.v_bytes = arc_new(uadd(sizeof(t_bytes), len));
+       res.val.v_bytes = arc_new_zeroed(uadd(sizeof(t_bytes), len));
        res.val.v_bytes->len = len;
        return (res);
 }
+
+t_value        value_new_str(const char *s)
+{
+       t_value res;
+       size_t  len;
+
+       res.tag = VALUE_BYTES;
+       len = cera_strlen(s);
+       res.val.v_bytes = arc_new(uadd(sizeof(t_bytes), len));
+       cera_memcpy(res.val.v_bytes->buf, s, len);
+       return (res);
+}
+
+t_value        value_new_list(size_t len)
+{
+       t_value res;
+       size_t  i;
+
+       res.tag = VALUE_LIST;
+       res.val.v_list = arc_new_zeroed(
+                       uadd(sizeof(t_list), umul(sizeof(t_value), len)));
+       res.val.v_list->len = len;
+       i = 0;
+       while (i < len)
+               res.val.v_list->buf[i++] = value_new_nil();
+       return (res);
+}
diff --git a/src/value_new.h b/src/value_new.h
new file mode 100644 (file)
index 0000000..84fd3c1
--- /dev/null
@@ -0,0 +1,49 @@
+/* ************************************************************************** */
+/*                                                                            */
+/*                                                        :::      ::::::::   */
+/*   value_new.h                                        :+:      :+:    :+:   */
+/*                                                    +:+ +:+         +:+     */
+/*   By: agilliar <agilliar@student.42mulhouse.fr>  +#+  +:+       +#+        */
+/*                                                +#+#+#+#+#+   +#+           */
+/*   Created: 2026/05/13 22:05:40 by agilliar          #+#    #+#             */
+/*   Updated: 2026/05/13 22:06:22 by agilliar         ###   ########.fr       */
+/*                                                                            */
+/* ************************************************************************** */
+
+#ifndef VALUE_NEW_H
+# define VALUE_NEW_H
+
+__attribute__((always_inline))
+static inline t_value  value_new_nil(void)
+{
+       t_value res;
+
+       res.tag = VALUE_NIL;
+       return (res);
+}
+
+__attribute__((always_inline))
+static inline t_value  value_new_int(intptr_t n)
+{
+       t_value res;
+
+       res.tag = VALUE_INT;
+       res.val.v_int = n;
+       return (res);
+}
+
+__attribute__((always_inline))
+static inline t_value  value_new_uint(uintptr_t n)
+{
+       t_value res;
+
+       res.tag = VALUE_UINT;
+       res.val.v_uint = n;
+       return (res);
+}
+
+t_value        value_new_bytes(size_t len);
+t_value        value_new_str(const char *s);
+t_value        value_new_list(size_t len);
+
+#endif
diff --git a/src/value_types.h b/src/value_types.h
new file mode 100644 (file)
index 0000000..a80c8c7
--- /dev/null
@@ -0,0 +1,54 @@
+/* ************************************************************************** */
+/*                                                                            */
+/*                                                        :::      ::::::::   */
+/*   value_types.h                                      :+:      :+:    :+:   */
+/*                                                    +:+ +:+         +:+     */
+/*   By: agilliar <agilliar@student.42mulhouse.fr>  +#+  +:+       +#+        */
+/*                                                +#+#+#+#+#+   +#+           */
+/*   Created: 2026/05/13 22:04:36 by agilliar          #+#    #+#             */
+/*   Updated: 2026/05/13 22:08:57 by agilliar         ###   ########.fr       */
+/*                                                                            */
+/* ************************************************************************** */
+
+#ifndef VALUE_TYPES_H
+# define VALUE_TYPES_H
+
+typedef struct s_bytes t_bytes;
+typedef struct s_list  t_list;
+
+union u_value
+{
+       uintptr_t       v_uint;
+       intptr_t        v_int;
+       t_bytes         *v_bytes;
+       t_list          *v_list;
+};
+
+enum e_value: uint8_t
+{
+       VALUE_NIL,
+       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
+{
+       size_t  len;
+       char    buf[];
+}      t_bytes;
+
+typedef struct s_list
+{
+       size_t  len;
+       t_value buf[];
+}      t_list;
+
+#endif