From 75ef01508fafd768b7448ea978086d35d93072c9 Mon Sep 17 00:00:00 2001 From: Axy Date: Wed, 20 May 2026 15:33:54 +0200 Subject: [PATCH] Working builtins prototype woa --- .deps | 21 ++++++++++--- Makefile | 9 ++++-- conf.mk | 3 +- src/builtin.c | 25 +++++++++++++++ src/builtin_mul.c | 70 ++++++++++++++++++++++++++++++++++++++++++ src/builtin_noop.c | 20 +++++------- src/builtin_register.c | 30 ++++++++++++++++++ src/builtin_register.h | 33 ++++++++++++++++++++ src/ccera.h | 4 +-- src/eval.c | 45 +++++++++++++++------------ src/panic.c | 4 +-- src/value.h | 4 ++- src/value_debug.c | 42 +++++++++++++++++++++++++ src/value_get.h | 6 ++-- src/value_lifetime.c | 10 +++--- src/value_list.c | 2 +- src/value_new.c | 16 +++++----- src/value_new.h | 8 +++-- src/value_new_utils.c | 45 +++++++++++++++++++++++++++ src/value_types.h | 62 ++++++++++++++++++++++++++++--------- test.c | 20 +++++++++--- 21 files changed, 396 insertions(+), 83 deletions(-) create mode 100644 src/builtin.c create mode 100644 src/builtin_mul.c create mode 100644 src/builtin_register.c create mode 100644 src/builtin_register.h create mode 100644 src/value_debug.c create mode 100644 src/value_new_utils.c diff --git a/.deps b/.deps index 9126ff5..9c7d9d0 100644 --- a/.deps +++ b/.deps @@ -1,19 +1,28 @@ ${BUILDDIR}/arc.o: src/arc.c src/arc.h src/memutils.h src/panic.h src/jmp.h \ src/arith.h src/atomic.h -${BUILDDIR}/builtin_noop.o: src/builtin_noop.c src/memutils.h src/panic.h src/jmp.h \ - src/value.h src/value_get.h src/value_types.h src/value_new.h \ - src/arc.h src/arith.h +${BUILDDIR}/builtin.o: src/builtin.c src/value.h src/value_get.h src/value_types.h \ + src/panic.h src/jmp.h src/value_new.h +${BUILDDIR}/builtin_mul.o: src/builtin_mul.c src/builtin_register.h src/value_types.h \ + src/value.h src/value_get.h src/panic.h src/jmp.h src/value_new.h \ + src/defer.h src/framealloc.h src/align.h src/stacktrack.h \ + src/memutils.h +${BUILDDIR}/builtin_noop.o: src/builtin_noop.c src/builtin_register.h \ + src/value_types.h +${BUILDDIR}/builtin_register.o: src/builtin_register.c src/builtin_register.h \ + src/value_types.h ${BUILDDIR}/defer.o: src/defer.c src/defer.h src/framealloc.h src/align.h \ src/stacktrack.h src/memutils.h src/panic.h src/jmp.h ${BUILDDIR}/eval.o: src/eval.c src/ccera.h src/jmp.h src/defer.h src/framealloc.h \ src/align.h src/stacktrack.h src/memutils.h src/panic.h src/value.h \ src/value_get.h src/value_types.h src/value_new.h src/arith.h \ - src/arc.h src/atomic.h + src/arc.h src/atomic.h src/builtin_register.h ${BUILDDIR}/framealloc.o: src/framealloc.c src/framealloc.h src/align.h \ src/stacktrack.h ${BUILDDIR}/panic.o: src/panic.c src/panic.h src/jmp.h src/defer.h src/framealloc.h \ src/align.h src/stacktrack.h src/memutils.h ${BUILDDIR}/stacktrack.o: src/stacktrack.c src/stacktrack.h +${BUILDDIR}/value_debug.o: src/value_debug.c src/value.h src/value_get.h \ + src/value_types.h src/panic.h src/jmp.h src/value_new.h ${BUILDDIR}/value_lifetime.o: src/value_lifetime.c src/arc.h src/memutils.h \ src/panic.h src/jmp.h src/arith.h src/defer.h src/framealloc.h \ src/align.h src/stacktrack.h src/value.h src/value_get.h \ @@ -25,3 +34,7 @@ ${BUILDDIR}/value_move.o: src/value_move.c src/value.h src/value_get.h \ ${BUILDDIR}/value_new.o: src/value_new.c src/value.h src/value_get.h \ src/value_types.h src/panic.h src/jmp.h src/value_new.h src/arith.h \ src/arc.h src/memutils.h +${BUILDDIR}/value_new_utils.o: src/value_new_utils.c src/value.h src/value_get.h \ + src/value_types.h src/panic.h src/jmp.h src/value_new.h \ + src/framealloc.h src/align.h src/stacktrack.h src/memutils.h \ + src/defer.h diff --git a/Makefile b/Makefile index 332ebf2..e33b155 100644 --- a/Makefile +++ b/Makefile @@ -1,8 +1,8 @@ NAME=ccera.a -SRCS=src/arc.c src/builtin_noop.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 +SRCS=src/arc.c src/builtin.c src/builtin_mul.c src/builtin_noop.c src/builtin_register.c src/defer.c src/eval.c src/framealloc.c src/panic.c src/stacktrack.c src/value_debug.c src/value_lifetime.c src/value_list.c src/value_move.c src/value_new.c src/value_new_utils.c -HEADERS=src/align.h src/arc.h src/arith.h src/atomic.h src/ccera.h src/defer.h src/framealloc.h src/jmp.h src/memutils.h src/panic.h src/stacktrack.h src/value_get.h src/value.h src/value_new.h src/value_types.h +HEADERS=src/align.h src/arc.h src/arith.h src/atomic.h src/builtin_register.h src/ccera.h src/defer.h src/framealloc.h src/jmp.h src/memutils.h src/panic.h src/stacktrack.h src/value_get.h src/value.h src/value_new.h src/value_types.h CC = cc @@ -26,7 +26,10 @@ CFLAGS += -std=gnu99 CFLAGS += -g CFLAGS += -fdiagnostics-color +OPT ?= 1 +ifeq (${OPT}, 1) CFLAGS += -O3 +endif LTO ?= 0 @@ -141,7 +144,7 @@ watch: watch -c -n 1 ${MAKE_CMD} watch-step a.out: test.c ${NAME} - ${CC} ${CFLAGS} $^ + ${CC} ${CFLAGS} -Wl,--whole-archive ${NAME} -Wl,--no-whole-archive test.c test: a.out ./a.out diff --git a/conf.mk b/conf.mk index 3ee296e..a3fd7af 100644 --- a/conf.mk +++ b/conf.mk @@ -1,4 +1,5 @@ -LTO=1 +LTO=0 +OPT=0 #CC=gcc #UBSAN=1 #TSAN=1 diff --git a/src/builtin.c b/src/builtin.c new file mode 100644 index 0000000..dc2a2db --- /dev/null +++ b/src/builtin.c @@ -0,0 +1,25 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* builtin.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: agilliar +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2026/05/20 13:02:36 by agilliar #+# #+# */ +/* Updated: 2026/05/20 13:23:54 by agilliar ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "value.h" + +t_builtin *builtin_store(void) +{ + static t_builtin store[_BUILTIN_MAX]; + + return (store); +} + +t_builtin *builtin_get(enum e_builtin tag) +{ + return (&builtin_store()[tag]); +} diff --git a/src/builtin_mul.c b/src/builtin_mul.c new file mode 100644 index 0000000..dacd776 --- /dev/null +++ b/src/builtin_mul.c @@ -0,0 +1,70 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* builtin_mul.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: agilliar +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2026/05/20 14:53:21 by agilliar #+# #+# */ +/* Updated: 2026/05/20 15:23:05 by agilliar ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "builtin_register.h" +#include "value.h" +#include "defer.h" + +t_value builtin_imul_impl(t_value self, t_value arg) +{ + t_value res; + + (void) self; + errdefer(value_drop, &arg); + res = value_new_builtin(BUILTIN_IMUL1); + res.val.v_int = *value_int(&arg); + return (res); +} + +t_value builtin_imul1_impl(t_value self, t_value arg) +{ + t_value res; + + (void) self; + errdefer(value_drop, &arg); + res = value_new_int(*value_int(&arg)); + __builtin_mul_overflow(res.val.v_int, + self.val.v_int, &res.val.v_int); + return (res); +} + +t_value builtin_umul_impl(t_value self, t_value arg) +{ + t_value res; + + (void) self; + errdefer(value_drop, &arg); + res = value_new_builtin(BUILTIN_UMUL1); + res.val.v_uint = *value_uint(&arg); + return (res); +} + +t_value builtin_umul1_impl(t_value self, t_value arg) +{ + t_value res; + + (void) self; + errdefer(value_drop, &arg); + res = value_new_uint(*value_uint(&arg)); + __builtin_mul_overflow(res.val.v_uint, + self.val.v_uint, &res.val.v_uint); + return (res); +} + +__attribute__((constructor)) +void builtin_mul_register(void) +{ + builtin_register(BUILTIN_IMUL, &builtin_imul_impl, "imul"); + builtin_register(BUILTIN_IMUL1, &builtin_imul1_impl, "imul1"); + builtin_register(BUILTIN_UMUL, &builtin_umul_impl, "umul"); + builtin_register(BUILTIN_UMUL1, &builtin_umul1_impl, "umul1"); +} diff --git a/src/builtin_noop.c b/src/builtin_noop.c index 71cb146..ee88bb6 100644 --- a/src/builtin_noop.c +++ b/src/builtin_noop.c @@ -6,24 +6,20 @@ /* By: agilliar +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2026/05/18 14:35:11 by agilliar #+# #+# */ -/* Updated: 2026/05/18 15:01:29 by agilliar ### ########.fr */ +/* Updated: 2026/05/20 14:50:25 by agilliar ### ########.fr */ /* */ /* ************************************************************************** */ -#include "memutils.h" -#include "value.h" -#include "arc.h" +#include "builtin_register.h" -#include - -static t_value builtin_noop_impl(t_value self, t_value val) +t_value builtin_noop_impl(t_value self, t_value arg) { - value_drop(&self); - printf("In noop!\n"); - return (val); + (void) self; + return (arg); } -t_value builtin_noop(void) +__attribute__((constructor)) +void builtin_noop_register(void) { - return (value_new_builtin(&builtin_noop_impl, &noop, 0)); + builtin_register(BUILTIN_NOOP, &builtin_noop_impl, "noop"); } diff --git a/src/builtin_register.c b/src/builtin_register.c new file mode 100644 index 0000000..ada0ebe --- /dev/null +++ b/src/builtin_register.c @@ -0,0 +1,30 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* builtin_register.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: agilliar +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2026/05/20 14:00:14 by agilliar #+# #+# */ +/* Updated: 2026/05/20 14:51:10 by agilliar ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "builtin_register.h" +#include + +t_value builtin_copy_noop(t_value *val) +{ + return (*val); +} + +void builtin_drop_noop(t_value *val) +{ + (void) val; +} + +void builtin_debug_basic(size_t indent, t_value *val) +{ + printf("%*s<%s>\n", (int)indent, "", + builtin_get(val->extra.v_builtin)->name); +} diff --git a/src/builtin_register.h b/src/builtin_register.h new file mode 100644 index 0000000..5285d4e --- /dev/null +++ b/src/builtin_register.h @@ -0,0 +1,33 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* builtin_register.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: agilliar +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2026/05/20 13:34:47 by agilliar #+# #+# */ +/* Updated: 2026/05/20 14:10:40 by agilliar ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef BUILTIN_REGISTER_H +# define BUILTIN_REGISTER_H + +# include "value_types.h" + +t_value builtin_copy_noop(t_value *val); +void builtin_drop_noop(t_value *val); +void builtin_debug_basic(size_t indent, t_value *val); + +static inline t_builtin *builtin_register(enum e_builtin tag, + t_value (*f)(t_value, t_value), const char *name) +{ + builtin_get(tag)->f = f; + builtin_get(tag)->name = name; + builtin_get(tag)->copy = NULL; + builtin_get(tag)->drop = NULL; + builtin_get(tag)->debug = &builtin_debug_basic; + return (builtin_get(tag)); +} + +#endif diff --git a/src/ccera.h b/src/ccera.h index cc1d745..14487eb 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/18 14:47:29 by agilliar ### ########.fr */ +/* Updated: 2026/05/20 14:06:31 by agilliar ### ########.fr */ /* */ /* ************************************************************************** */ @@ -22,6 +22,7 @@ # include "arc.h" # include "stacktrack.h" # include "atomic.h" +# include "builtin_register.h" // The expression value is a tuple of an evaluatable and the argument to give it // @@ -42,6 +43,5 @@ // // This function takes ownership t_value expr_eval(t_value eval, t_value arg); -t_value builtin_noop(void); #endif diff --git a/src/eval.c b/src/eval.c index 0db5e30..4ecfc2c 100644 --- a/src/eval.c +++ b/src/eval.c @@ -6,29 +6,37 @@ /* By: agilliar +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2026/05/04 01:21:34 by agilliar #+# #+# */ -/* Updated: 2026/05/18 15:00:10 by agilliar ### ########.fr */ +/* Updated: 2026/05/20 15:18:00 by agilliar ### ########.fr */ /* */ /* ************************************************************************** */ #include "ccera.h" -void step_extract(t_value *exprs, uintptr_t *i, t_value *eval, t_value *arg) +bool step_extract(t_value *exprs, uintptr_t *i, t_value *eval, t_value *arg) { uintptr_t pos; uintptr_t mov; + value_put(value_list_getu(exprs, (*i)++), value_take_nil(arg)); + if (value_list_get(*exprs, *i)->tag == VALUE_NIL) + return (false); pos = *value_uint(value_list_get(*value_list_get(*exprs, *i), 0)); mov = *value_uint(value_list_get(*value_list_get(*exprs, *i), 1)); + if (pos >= *i) + panic("Function accessed value at or beyond the current instruction"); if (mov) - value_swap(value_list_getu(exprs, pos), eval); + value_put(eval, value_take_nil(value_list_getu(exprs, pos))); else value_put(eval, value_copy(*value_list_getu(exprs, pos))); pos = *value_uint(value_list_get(*value_list_get(*exprs, *i), 2)); mov = *value_uint(value_list_get(*value_list_get(*exprs, *i), 3)); + if (pos >= *i) + panic("Function accessed value at or beyond the current instruction"); if (mov) - value_swap(value_list_getu(exprs, pos), arg); + value_put(arg, value_take_nil(value_list_getu(exprs, pos))); else value_put(arg, value_copy(*value_list_getu(exprs, pos))); + return (true); } void compound_eval(t_value *eval, t_value *arg) @@ -36,25 +44,24 @@ void compound_eval(t_value *eval, t_value *arg) t_value *exprs; uintptr_t *i; t_value step_eval; - t_value step_arg; step_eval = value_new_nil(); defer(value_drop, &step_eval); - step_arg = value_new_nil(); - defer(value_drop, &step_arg); exprs = value_list_getu(eval, 0); i = value_uint(value_list_getu(eval, 1)); - value_swap(value_list_getu(exprs, (*i)++), arg); - step_extract(exprs, i, &step_eval, &step_arg); - if (value_list_len(*exprs) + 1 == *i) - return (value_swap(eval, &step_eval), value_swap(arg, &step_arg)); - value_put(arg, expr_eval( - value_take_nil(&step_eval), value_take_nil(&step_arg))); + while (step_extract(exprs, i, &step_eval, arg)) + { + if (*i + 1 == value_list_len(*exprs)) + return (value_swap(eval, &step_eval)); + value_put(arg, expr_eval( + value_take_nil(&step_eval), value_take_nil(arg))); + } + value_swap(arg, eval); } -void builtin_eval(t_value eval, t_value *arg) +void builtin_eval(t_value *eval, t_value *arg) { - value_put(arg, value_builtin(&eval)->f(eval, value_take_nil(arg))); + *arg = (value_builtin(eval)->f)(value_take_nil(eval), value_take_nil(arg)); } // Value-evaluatables are laid out as follows: @@ -79,12 +86,12 @@ t_value expr_eval(t_value eval, t_value arg) errdefer(value_drop, &arg); while (true) { - if (eval.tag == VALUE_BUILTIN) - { - return (builtin_eval(value_take_nil(&eval), &arg), arg); - } + if (eval.tag == VALUE_BUILTIN || eval.tag == VALUE_BUILTIN_COMPLEX) + return (builtin_eval(&eval, &arg), arg); else if (eval.tag == VALUE_LIST) compound_eval(&eval, &arg); + else if (eval.tag == VALUE_NIL) + return (arg); else panic("Invalid type for evaluatable"); } diff --git a/src/panic.c b/src/panic.c index 90496f5..857064e 100644 --- a/src/panic.c +++ b/src/panic.c @@ -6,7 +6,7 @@ /* By: agilliar +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2026/05/05 15:38:33 by agilliar #+# #+# */ -/* Updated: 2026/05/18 15:36:28 by agilliar ### ########.fr */ +/* Updated: 2026/05/20 11:14:53 by agilliar ### ########.fr */ /* */ /* ************************************************************************** */ @@ -49,9 +49,9 @@ void *catch(void *f, void *dat) __attribute__((noreturn, nonnull(1), cold)) void panic(void *err) { + panic_store()->data = err; while (stacktrack_pos() != panic_store()->stacktrack_pos) stacktrack_pop(); - panic_store()->data = err; __builtin_longjmp((void *)&panic_store()->jmp, 1); } diff --git a/src/value.h b/src/value.h index 971422b..9f7df3a 100644 --- a/src/value.h +++ b/src/value.h @@ -6,7 +6,7 @@ /* By: agilliar +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2026/05/12 16:14:16 by agilliar #+# #+# */ -/* Updated: 2026/05/18 12:48:22 by agilliar ### ########.fr */ +/* Updated: 2026/05/20 11:36:21 by agilliar ### ########.fr */ /* */ /* ************************************************************************** */ @@ -34,4 +34,6 @@ t_value value_take(t_value *a, t_value b); t_value value_take_nil(t_value *a); void value_put(t_value *a, t_value b); +void value_debug(size_t indent, t_value *value); + #endif diff --git a/src/value_debug.c b/src/value_debug.c new file mode 100644 index 0000000..b1ab0dd --- /dev/null +++ b/src/value_debug.c @@ -0,0 +1,42 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* value_debug.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: agilliar +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2026/05/20 11:23:55 by agilliar #+# #+# */ +/* Updated: 2026/05/20 14:48:04 by agilliar ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include +#include +#include "value.h" + +static void value_debug_list(size_t indent, t_list *lst) +{ + size_t i; + + printf("%*s%s\n", (int)indent, "", "["); + i = 0; + while (i < lst->len) + value_debug(indent + 4, &lst->buf[i++]); + printf("%*s%s\n", (int)indent, "", "]"); +} + +void value_debug(size_t indent, t_value *value) +{ + if (value->tag == VALUE_INT) + printf("%*s%li\n", (int)indent, "", value->val.v_int); + else if (value->tag == VALUE_UINT) + printf("%*s%lu\n", (int)indent, "", value->val.v_uint); + else if (value->tag == VALUE_BUILTIN || value->tag == VALUE_BUILTIN_COMPLEX) + (value_builtin(value)->debug)(indent, value); + else if (value->tag == VALUE_LIST) + value_debug_list(indent, value->val.v_list); + else if (value->tag == VALUE_NIL) + printf("%*s%s\n", (int)indent, "", "nil"); + else + printf("%*s%s\n", (int)indent, "", ""); +} diff --git a/src/value_get.h b/src/value_get.h index 445fcea..76ca4aa 100644 --- a/src/value_get.h +++ b/src/value_get.h @@ -6,7 +6,7 @@ /* By: agilliar +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2026/05/13 22:01:24 by agilliar #+# #+# */ -/* Updated: 2026/05/18 14:49:16 by agilliar ### ########.fr */ +/* Updated: 2026/05/20 13:24:13 by agilliar ### ########.fr */ /* */ /* ************************************************************************** */ @@ -51,9 +51,9 @@ static inline t_bytes *value_bytes(t_value *value) __attribute__((always_inline)) static inline t_builtin *value_builtin(t_value *value) { - if (value->tag != VALUE_BUILTIN) + if (value->tag != VALUE_BUILTIN && value->tag != VALUE_BUILTIN_COMPLEX) panic("Expected value to be builtin"); - return (value->val.v_builtin); + return (&builtin_store()[value->extra.v_builtin]); } #endif diff --git a/src/value_lifetime.c b/src/value_lifetime.c index fe8396e..993b08b 100644 --- a/src/value_lifetime.c +++ b/src/value_lifetime.c @@ -6,7 +6,7 @@ /* By: agilliar +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2026/05/12 17:42:10 by agilliar #+# #+# */ -/* Updated: 2026/05/18 14:34:35 by agilliar ### ########.fr */ +/* Updated: 2026/05/20 13:33:49 by agilliar ### ########.fr */ /* */ /* ************************************************************************** */ @@ -22,8 +22,8 @@ t_value value_copy(t_value val) arc_copy(val.val.v_bytes); else if (val.tag == VALUE_LIST) arc_copy(val.val.v_list); - else if (val.tag == VALUE_BUILTIN) - arc_copy(val.val.v_builtin); + else if (val.tag == VALUE_BUILTIN_COMPLEX) + return (value_builtin(&val)->copy(&val)); return (val); } @@ -68,10 +68,10 @@ void value_drop(t_value *value) { if (value->tag == VALUE_LIST) arc_drop(value->val.v_list, list_drop); - else if (value->tag == VALUE_BUILTIN) - arc_drop(value->val.v_builtin, value->val.v_builtin->drop); else if (value->tag == VALUE_BYTES) arc_drop(value->val.v_bytes, noop); + else if (value->tag == VALUE_BUILTIN_COMPLEX) + value_builtin(value)->drop(value); } t_value value_unique(t_value *val) diff --git a/src/value_list.c b/src/value_list.c index 2dc8ee0..817d793 100644 --- a/src/value_list.c +++ b/src/value_list.c @@ -6,7 +6,7 @@ /* By: agilliar +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2026/05/13 12:51:13 by agilliar #+# #+# */ -/* Updated: 2026/05/18 12:47:53 by agilliar ### ########.fr */ +/* Updated: 2026/05/20 10:29:49 by agilliar ### ########.fr */ /* */ /* ************************************************************************** */ diff --git a/src/value_new.c b/src/value_new.c index 03bb098..4282135 100644 --- a/src/value_new.c +++ b/src/value_new.c @@ -6,7 +6,7 @@ /* By: agilliar +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2026/05/13 08:40:13 by agilliar #+# #+# */ -/* Updated: 2026/05/18 14:56:45 by agilliar ### ########.fr */ +/* Updated: 2026/05/20 14:14:05 by agilliar ### ########.fr */ /* */ /* ************************************************************************** */ @@ -55,15 +55,15 @@ t_value value_new_list(size_t len) return (res); } -t_value value_new_builtin(t_value (*f)(t_value, t_value), - void *drop, size_t len) +t_value value_new_builtin(enum e_builtin tag) { - t_value res; + t_builtin *builtin; + t_value res; + builtin = builtin_get(tag); res.tag = VALUE_BUILTIN; - res.val.v_list = arc_new( - uadd(sizeof(t_builtin), len)); - res.val.v_builtin->f = f; - res.val.v_builtin->drop = drop; + if (builtin->drop || builtin->copy) + res.tag = VALUE_BUILTIN_COMPLEX; + res.extra.v_builtin = tag; return (res); } diff --git a/src/value_new.h b/src/value_new.h index 5cb33f8..8dc8619 100644 --- a/src/value_new.h +++ b/src/value_new.h @@ -6,7 +6,7 @@ /* By: agilliar +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2026/05/13 22:05:40 by agilliar #+# #+# */ -/* Updated: 2026/05/18 14:57:37 by agilliar ### ########.fr */ +/* Updated: 2026/05/20 13:30:34 by agilliar ### ########.fr */ /* */ /* ************************************************************************** */ @@ -45,7 +45,9 @@ static inline t_value value_new_uint(uintptr_t n) t_value value_new_bytes(size_t len); t_value value_new_str(const char *s); t_value value_new_list(size_t len); -t_value value_new_builtin(t_value (*f)(t_value, t_value), - void *drop, size_t len); +t_value value_new_builtin(enum e_builtin tag); +t_value value_new_va(size_t count, ...); +t_value value_new_step(uintptr_t expr_pos, bool expr_mov, + uintptr_t arg_pos, bool arg_mov); #endif diff --git a/src/value_new_utils.c b/src/value_new_utils.c new file mode 100644 index 0000000..5bfbff0 --- /dev/null +++ b/src/value_new_utils.c @@ -0,0 +1,45 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* value_new_utils.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: agilliar +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2026/05/20 10:29:41 by agilliar #+# #+# */ +/* Updated: 2026/05/20 10:54:22 by agilliar ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "value.h" +#include "framealloc.h" +#include "memutils.h" +#include "defer.h" +#include + +t_value value_new_va(size_t count, ...) +{ + t_value res; + t_value *buf; + va_list ap; + size_t i; + + buf = cera_alloca(sizeof(t_value) * count); + va_start(ap, count); + i = 0; + while (i < count) + buf[i++] = va_arg(ap, t_value); + va_end(ap); + i = 0; + while (i < count) + errdefer(value_drop, &buf[i++]); + res = value_new_list(count); + cera_memcpy(res.val.v_list->buf, buf, sizeof(t_value) * count); + return (res); +} + +t_value value_new_step(uintptr_t expr_pos, bool expr_mov, + uintptr_t arg_pos, bool arg_mov) +{ + return (value_new_va(4, value_new_uint(expr_pos), value_new_uint(expr_mov), + value_new_uint(arg_pos), value_new_uint(arg_mov))); +} diff --git a/src/value_types.h b/src/value_types.h index 9bb3481..86e9cf5 100644 --- a/src/value_types.h +++ b/src/value_types.h @@ -6,16 +6,19 @@ /* By: agilliar +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2026/05/13 22:04:36 by agilliar #+# #+# */ -/* Updated: 2026/05/18 14:57:06 by agilliar ### ########.fr */ +/* Updated: 2026/05/20 14:03:21 by agilliar ### ########.fr */ /* */ /* ************************************************************************** */ #ifndef VALUE_TYPES_H # define VALUE_TYPES_H +# include +# include + typedef struct s_bytes t_bytes; typedef struct s_list t_list; -typedef struct s_builtin t_builtin; +typedef struct s_value t_value; union u_value { @@ -23,10 +26,42 @@ union u_value intptr_t v_int; t_bytes *v_bytes; t_list *v_list; - t_builtin *v_builtin; }; -enum e_value: uint8_t +enum e_builtin: uint16_t +{ + BUILTIN_NOOP, + BUILTIN_IADD, + BUILTIN_IADD1, + BUILTIN_UADD, + BUILTIN_UADD1, + BUILTIN_IMUL, + BUILTIN_IMUL1, + BUILTIN_UMUL, + BUILTIN_UMUL1, + BUILTIN_ISUB, + BUILTIN_ISUB1, + BUILTIN_USUB, + BUILTIN_USUB1, + _BUILTIN_MAX, +}; + +// f: self, arg -> res +typedef struct s_builtin +{ + t_value (*f)(t_value, t_value); + void (*drop)(t_value *); + t_value (*copy)(t_value *); + void (*debug)(size_t indent, t_value *); + const char *name; +} t_builtin; + +union u_value_extra +{ + enum e_builtin v_builtin; +}; + +enum e_value: uint16_t { VALUE_NIL, VALUE_INT, @@ -34,13 +69,15 @@ enum e_value: uint8_t VALUE_BYTES, VALUE_LIST, VALUE_BUILTIN, + VALUE_BUILTIN_COMPLEX, }; -typedef struct s_value +struct s_value { - union u_value val; - enum e_value tag; -} t_value; + union u_value val; + union u_value_extra extra; + enum e_value tag; +}; struct s_bytes { @@ -54,12 +91,7 @@ struct s_list t_value buf[]; }; -// F: self, arg -> res -struct s_builtin -{ - t_value (*f)(t_value, t_value); - void (*drop)(t_builtin *); - char buf[]; -}; +t_builtin *builtin_store(void); +t_builtin *builtin_get(enum e_builtin tag); #endif diff --git a/test.c b/test.c index df2c8b7..fdf3c11 100644 --- a/test.c +++ b/test.c @@ -6,7 +6,7 @@ /* By: agilliar +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2026/04/30 17:19:58 by agilliar #+# #+# */ -/* Updated: 2026/05/18 15:03:08 by agilliar ### ########.fr */ +/* Updated: 2026/05/20 15:33:15 by agilliar ### ########.fr */ /* */ /* ************************************************************************** */ @@ -15,6 +15,19 @@ #include #include +t_value test_expr(void) +{ + t_value exprs = value_new_va( + 5, + value_new_builtin(BUILTIN_UMUL), + value_new_uint(8), + value_new_nil(), + value_new_step(0, false, 1, true), + value_new_step(3, false, 2, true) + ); + return (value_new_va(2, exprs, value_new_uint(2))); +} + void main2(void *_orig) { char *orig = _orig; @@ -23,11 +36,10 @@ void main2(void *_orig) char *s2 = malloc(strlen(orig) + 1); defer(free, s2); strcpy(s2, orig); - t_value res = expr_eval(builtin_noop(), value_new_uint(7)); + t_value res = expr_eval(test_expr(), value_new_uint(7)); + value_debug(0, &res); defer(value_drop, &res); printf("%s\n", s2); - panic("error!"); - printf("%s\n", s2); } int main(void) -- 2.53.0