]> Untitled Git - axy/ft/c-cera.git/commitdiff
Arc make unique among others
authorAxy <gilliardmarthey.axel@gmail.com>
Mon, 4 May 2026 01:22:04 +0000 (03:22 +0200)
committerAxy <gilliardmarthey.axel@gmail.com>
Mon, 4 May 2026 01:22:04 +0000 (03:22 +0200)
.gitignore
Makefile
a.out [deleted file]
src/arc.c
src/ccera.h
src/eval.c [new file with mode: 0644]
src/value_destroy.c [new file with mode: 0644]
src/value_get.c
src/value_lifetime.c [new file with mode: 0644]
src/value_new.c
test.c

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