From: Axy Date: Wed, 13 May 2026 08:50:49 +0000 (+0200) Subject: Epic makefile X-Git-Url: https://git.uwuaxy.net/?a=commitdiff_plain;h=128a21060fb257ce4ce56b64a225012754f45307;p=axy%2Fft%2Fc-cera.git Epic makefile --- diff --git a/.gitignore b/.gitignore index a9c38b7..f4283ee 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,6 @@ a.out vgcore.* .direnv .norm_fail +Makefile.tmp +.deps +.deps.tmp diff --git a/Makefile b/Makefile index e09a1fc..2ae7dde 100644 --- a/Makefile +++ b/Makefile @@ -1,13 +1,15 @@ NAME=ccera.a -SRCS=src/arc.c src/defer.c src/eval.c src/framealloc.c src/panic.c src/value_destroy.c src/value_get.c src/value_lifetime.c src/value_new.c src/value_readf.c +SRCS=src/arc.c src/defer.c src/eval.c src/framealloc.c src/panic.c src/value_lifetime.c src/value_new.c -HEADERS=src/align.h src/ccera.h src/defer.h src/framealloc.h src/jmp.h src/panic.h src/return_patch.h +HEADERS=src/align.h src/arc.h src/arith.h src/ccera.h src/defer.h src/framealloc.h src/jmp.h src/panic.h src/return_patch.h src/value.h BUILDDIR=.build THIS=Makefile +DEPSFILE=.deps + OBJS=${SRCS:src/%.c=${BUILDDIR}/%.o} CFLAGS=-Wall -Wextra -Werror -pthread -std=gnu23 @@ -24,7 +26,7 @@ MAKEFLAGS += --no-print-directory all: ${NAME} -${BUILDDIR}/%.o: src/%.c ${HEADERS} ${THIS} | ${BUILDDIR} +${BUILDDIR}/%.o: src/%.c ${THIS} | ${BUILDDIR} ${CC} ${CFLAGS} -c -o $@ $< ${BUILDDIR}: @@ -42,9 +44,28 @@ fclean: clean re: fclean all -remakefile: clean - sed -i "s?^SRCS=.*?$$(echo -n SRCS=; echo -n src/*.c)?" ${THIS} - sed -i "s?^HEADERS=.*?$$(echo -n HEADERS=; echo -n src/*.h)?" ${THIS} +${THIS}.tmp: ${SRCS} ${HEADERS} ${THIS} + @sed "s?^SRCS=.*?$$(echo -n SRCS=; echo -n src/*.c)?" ${THIS} \ + | sed "s?^HEADERS=.*?$$(echo -n HEADERS=; echo -n src/*.h)?" \ + > ${THIS}.tmp + +${DEPSFILE}.tmp: ${SRCS} ${HEADERS} ${THIS} + ${CC} -MM ${SRCS} | sed "s/^\([^ ]\)/\$${BUILDDIR}\/\1/" > $@ + +redeps: ${DEPSFILE}.tmp + @echo Rebuilding deps + @if ! cmp -s $< ${DEPSFILE}; then \ + cp $< ${DEPSFILE}; \ + echo Deps modified; \ + fi + +remakefile: ${THIS}.tmp + @echo Rebuilding makefile + @if ! cmp -s $< ${THIS}; then \ + make fclean; \ + cp $< ${THIS}; \ + echo Makefile modified; \ + fi .norm: ${SRCS} ${HEADERS} ${THIS} @rm -f .norm_fail @@ -54,6 +75,15 @@ norm: .norm @cat .norm | sed "s/.*OK!$$//" | grep . @test ! -e .norm_fail +watch-step: + make remakefile + make redeps + make norm + make + +watch: + watch -c -n 1 make watch-step + norm-watch: watch -c -n 1 make norm @@ -66,4 +96,6 @@ a.out: test.c ${NAME} ${THIS} test: a.out valgrind ./a.out -.PHONY: all clean fclean re remakefile norm norm-watch build-watch test +.PHONY: all clean fclean re remakefile redeps norm watch-step watch test + +${BUILDDIR}/arc.o: src/arc.c src/arc.h diff --git a/src/arc.c b/src/arc.c index af02b81..83329fd 100644 --- a/src/arc.c +++ b/src/arc.c @@ -6,18 +6,19 @@ /* By: agilliar +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* 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 -t_arc arc_create(t_usize size) +t_arc arc_new(uintptr_t size) { - t_usize *res; + uintptr_t *res; - if (__builtin_add_overflow(size, sizeof(t_usize), &size)) + if (__builtin_add_overflow(size, sizeof(uintptr_t), &size)) panic("Arc alloc too big to create"); res = malloc(size); if (!res) @@ -26,27 +27,29 @@ t_arc arc_create(t_usize size) return ((void *) &res[1]); } +// Relaxed sub as we own a copy, and as such ultimately sync void arc_copy(t_arc arc) { - if (__atomic_add_fetch(((t_usize *)arc) - 1, 1, __ATOMIC_RELAXED) - >= ((t_usize) 1) << (sizeof(t_usize) * 8 - 1)) - panic("Arc counter overflowed"); + if (__atomic_add_fetch(((uintptr_t *)arc) - 1, 1, __ATOMIC_RELAXED) + >= ((uintptr_t) 1) << (sizeof(uintptr_t) * 8 - 1)) + { + __atomic_sub_fetch(((uintptr_t *)arc) - 1, 1, __ATOMIC_RELAXED); + panic("Arc counter near overflowing"); + } } -void arc_destroy(t_arc arc, t_drop destructor) +void arc_drop(t_arc arc, t_drop destructor) { - if (!arc) - return ; - if (__atomic_sub_fetch(((t_usize *)arc) - 1, 1, __ATOMIC_RELEASE) != 0) + if (__atomic_sub_fetch(((uintptr_t *)arc) - 1, 1, __ATOMIC_RELEASE) != 0) return ; __atomic_thread_fence(__ATOMIC_ACQUIRE); - destructor(arc); + ((void (*)(void *))destructor)(arc); free(((char *)arc) - 8); } bool arc_is_unique(t_arc arc) { - return (__atomic_load_n(((t_usize *)arc) - 1, __ATOMIC_ACQUIRE) == 1); + return (__atomic_load_n(((uintptr_t *)arc) - 1, __ATOMIC_ACQUIRE) == 1); } void noop(void *ptr) diff --git a/src/value_readf.c b/src/arc.h similarity index 59% rename from src/value_readf.c rename to src/arc.h index aa6cc56..600dca1 100644 --- a/src/value_readf.c +++ b/src/arc.h @@ -1,26 +1,29 @@ /* ************************************************************************** */ /* */ /* ::: :::::::: */ -/* value_readf.c :+: :+: :+: */ +/* arc.h :+: :+: :+: */ /* +:+ +:+ +:+ */ /* By: agilliar +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ -/* 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 +# include + +typedef void *t_arc; +typedef void *t_drop; + +t_arc arc_new(uintptr_t size); +void arc_copy(t_arc arc); +void arc_drop(t_arc arc, t_drop destructor); +bool arc_is_unique(t_arc arc); + +void noop(void *ptr); + +#endif diff --git a/src/arith.h b/src/arith.h new file mode 100644 index 0000000..baccaa5 --- /dev/null +++ b/src/arith.h @@ -0,0 +1,43 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* arith.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: agilliar +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* 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 +# 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 diff --git a/src/ccera.h b/src/ccera.h index dd5e495..edaab42 100644 --- a/src/ccera.h +++ b/src/ccera.h @@ -6,7 +6,7 @@ /* By: agilliar +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* 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 */ /* */ /* ************************************************************************** */ @@ -21,90 +21,9 @@ # 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 // diff --git a/src/defer.h b/src/defer.h index 25f5225..b3a272b 100644 --- a/src/defer.h +++ b/src/defer.h @@ -6,7 +6,7 @@ /* By: agilliar +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2026/05/10 22:08:53 by agilliar #+# #+# */ -/* Updated: 2026/05/12 14:01:36 by agilliar ### ########.fr */ +/* Updated: 2026/05/12 16:58:46 by agilliar ### ########.fr */ /* */ /* ************************************************************************** */ @@ -14,6 +14,7 @@ # define DEFER_H # include +# include # include "framealloc.h" # include "return_patch.h" @@ -87,4 +88,24 @@ static inline void errdefer(void *f, void *dat) defer_store()->frame = curr; } +__attribute__((always_inline)) +static inline void deferc(void *f, void *dat, uintptr_t size) +{ + void *b; + + b = cera_alloca(size); + memcpy(b, dat, size); + defer(f, b); +} + +__attribute__((always_inline)) +static inline void errdeferc(void *f, void *dat, uintptr_t size) +{ + void *b; + + b = cera_alloca(size); + memcpy(b, dat, size); + errdefer(f, b); +} + #endif diff --git a/src/framealloc.h b/src/framealloc.h index a97b755..2538eea 100644 --- a/src/framealloc.h +++ b/src/framealloc.h @@ -6,7 +6,7 @@ /* By: agilliar +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2026/05/11 19:17:56 by agilliar #+# #+# */ -/* Updated: 2026/05/12 13:35:45 by agilliar ### ########.fr */ +/* Updated: 2026/05/12 16:58:56 by agilliar ### ########.fr */ /* */ /* ************************************************************************** */ @@ -84,4 +84,10 @@ static inline void *cera_alloca_align(uintptr_t len, uintptr_t align) return (cera_alloca_align_nopatch(len, align)); } +__attribute__((always_inline, malloc, alloc_size(1))) +static inline void *cera_alloca(uintptr_t len) +{ + return (cera_alloca_align(len, 8)); +} + #endif diff --git a/src/panic.c b/src/panic.c index be74604..f3e0640 100644 --- a/src/panic.c +++ b/src/panic.c @@ -6,11 +6,12 @@ /* By: agilliar +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2026/05/05 15:38:33 by agilliar #+# #+# */ -/* Updated: 2026/05/12 13:13:03 by agilliar ### ########.fr */ +/* Updated: 2026/05/13 09:36:19 by agilliar ### ########.fr */ /* */ /* ************************************************************************** */ -#include "ccera.h" +#include "panic.h" +#include "defer.h" t_panic_info *panic_store(void) { @@ -39,7 +40,7 @@ void *catch(void *f, void *dat) return (NULL); } -__attribute__((noreturn, nonnull(1))) +__attribute__((noreturn, nonnull(1), cold)) void panic(void *err) { while (defer_store()->frame_ptr != panic_store()->frame_ptr) diff --git a/src/value.h b/src/value.h new file mode 100644 index 0000000..458f6dc --- /dev/null +++ b/src/value.h @@ -0,0 +1,60 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* value.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: agilliar +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* 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 + +typedef struct s_bytes t_bytes; +typedef struct s_list t_list; + +union u_value +{ + intptr_t v_int; + uintptr_t v_uint; + t_bytes *v_bytes; + t_list *v_list; +}; + +enum e_value: uint8_t +{ + VALUE_UNDEF, + VALUE_INT, + VALUE_UINT, + VALUE_BYTES, + VALUE_LIST, +}; + +typedef struct s_value +{ + union u_value val; + enum e_value tag; +} t_value; + +typedef struct s_bytes +{ + uintptr_t len; + uint8_t buf[]; +} t_bytes; + +typedef struct s_list +{ + uintptr_t len; + t_value buf[]; +} t_list; + +t_value value_copy(t_value val); +t_value value_clone(t_value val); +void value_drop(t_value *value); + +#endif diff --git a/src/value_destroy.c b/src/value_destroy.c deleted file mode 100644 index 1e05c9a..0000000 --- a/src/value_destroy.c +++ /dev/null @@ -1,42 +0,0 @@ -/* ************************************************************************** */ -/* */ -/* ::: :::::::: */ -/* value_destroy.c :+: :+: :+: */ -/* +:+ +:+ +:+ */ -/* By: agilliar +#+ +:+ +#+ */ -/* +#+#+#+#+#+ +#+ */ -/* Created: 2026/04/30 19:40:43 by agilliar #+# #+# */ -/* Updated: 2026/05/05 20:54:09 by agilliar ### ########.fr */ -/* */ -/* ************************************************************************** */ - -#include "ccera.h" -#include - -static void value_drop_arc(t_value *value, t_unpack unpack, t_drop drop) -{ - void *unpacked; - - unpacked = unpack(*value); - if (!unpacked) - return ; - *value = value_int_new(0); - arc_destroy(unpacked, drop); -} - -static void value_list_del(struct s_value_list *list) -{ - t_usize i; - - i = 0; - while (i < list->len) - value_destroy(&list->list[i++]); -} - -void value_destroy(t_value *value) -{ - value_drop_arc(value, (t_unpack) value_builtin_get, noop); - value_drop_arc(value, (t_unpack) value_list_get, (t_drop) value_list_del); - value_drop_arc(value, (t_unpack) value_bytes_get, noop); - *value = value_undefined_new(); -} diff --git a/src/value_get.c b/src/value_get.c deleted file mode 100644 index 7583e39..0000000 --- a/src/value_get.c +++ /dev/null @@ -1,54 +0,0 @@ -/* ************************************************************************** */ -/* */ -/* ::: :::::::: */ -/* value_get.c :+: :+: :+: */ -/* +:+ +:+ +:+ */ -/* By: agilliar +#+ +:+ +#+ */ -/* +#+#+#+#+#+ +#+ */ -/* 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); -} diff --git a/src/value_lifetime.c b/src/value_lifetime.c index 08927c3..2bbf6e4 100644 --- a/src/value_lifetime.c +++ b/src/value_lifetime.c @@ -5,83 +5,74 @@ /* +:+ +:+ +:+ */ /* By: agilliar +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ -/* 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 -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); } diff --git a/src/value_new.c b/src/value_new.c index 589cabd..cbf9f29 100644 --- a/src/value_new.c +++ b/src/value_new.c @@ -5,77 +5,22 @@ /* +:+ +:+ +:+ */ /* By: agilliar +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ -/* 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 -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); }