vgcore.*
.direnv
.norm_fail
+Makefile.tmp
+.deps
+.deps.tmp
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
all: ${NAME}
-${BUILDDIR}/%.o: src/%.c ${HEADERS} ${THIS} | ${BUILDDIR}
+${BUILDDIR}/%.o: src/%.c ${THIS} | ${BUILDDIR}
${CC} ${CFLAGS} -c -o $@ $<
${BUILDDIR}:
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
@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
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
/* 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)
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)
/* ************************************************************************** */
/* */
/* ::: :::::::: */
-/* 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
--- /dev/null
+/* ************************************************************************** */
+/* */
+/* ::: :::::::: */
+/* 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
/* 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
//
/* 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 */
/* */
/* ************************************************************************** */
# define DEFER_H
# include <stddef.h>
+# include <string.h>
# include "framealloc.h"
# include "return_patch.h"
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
/* 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 */
/* */
/* ************************************************************************** */
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
/* 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)
{
return (NULL);
}
-__attribute__((noreturn, nonnull(1)))
+__attribute__((noreturn, nonnull(1), cold))
void panic(void *err)
{
while (defer_store()->frame_ptr != panic_store()->frame_ptr)
--- /dev/null
+/* ************************************************************************** */
+/* */
+/* ::: :::::::: */
+/* 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
+++ /dev/null
-/* ************************************************************************** */
-/* */
-/* ::: :::::::: */
-/* 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();
-}
+++ /dev/null
-/* ************************************************************************** */
-/* */
-/* ::: :::::::: */
-/* 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);
-}
/* +:+ +:+ +:+ */
/* 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);
}
/* +:+ +:+ +:+ */
/* 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);
}