${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 \
${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
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
CFLAGS += -g
CFLAGS += -fdiagnostics-color
+OPT ?= 1
+ifeq (${OPT}, 1)
CFLAGS += -O3
+endif
LTO ?= 0
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
-LTO=1
+LTO=0
+OPT=0
#CC=gcc
#UBSAN=1
#TSAN=1
--- /dev/null
+/* ************************************************************************** */
+/* */
+/* ::: :::::::: */
+/* builtin.c :+: :+: :+: */
+/* +:+ +:+ +:+ */
+/* By: agilliar <agilliar@student.42mulhouse.fr> +#+ +:+ +#+ */
+/* +#+#+#+#+#+ +#+ */
+/* 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]);
+}
--- /dev/null
+/* ************************************************************************** */
+/* */
+/* ::: :::::::: */
+/* builtin_mul.c :+: :+: :+: */
+/* +:+ +:+ +:+ */
+/* By: agilliar <agilliar@student.42mulhouse.fr> +#+ +:+ +#+ */
+/* +#+#+#+#+#+ +#+ */
+/* 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");
+}
/* By: agilliar <agilliar@student.42mulhouse.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* 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 <stdio.h>
-
-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");
}
--- /dev/null
+/* ************************************************************************** */
+/* */
+/* ::: :::::::: */
+/* builtin_register.c :+: :+: :+: */
+/* +:+ +:+ +:+ */
+/* By: agilliar <agilliar@student.42mulhouse.fr> +#+ +:+ +#+ */
+/* +#+#+#+#+#+ +#+ */
+/* Created: 2026/05/20 14:00:14 by agilliar #+# #+# */
+/* Updated: 2026/05/20 14:51:10 by agilliar ### ########.fr */
+/* */
+/* ************************************************************************** */
+
+#include "builtin_register.h"
+#include <stdio.h>
+
+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);
+}
--- /dev/null
+/* ************************************************************************** */
+/* */
+/* ::: :::::::: */
+/* builtin_register.h :+: :+: :+: */
+/* +:+ +:+ +:+ */
+/* By: agilliar <agilliar@student.42mulhouse.fr> +#+ +:+ +#+ */
+/* +#+#+#+#+#+ +#+ */
+/* 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
/* By: agilliar <agilliar@student.42mulhouse.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* 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 */
/* */
/* ************************************************************************** */
# 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
//
//
// This function takes ownership
t_value expr_eval(t_value eval, t_value arg);
-t_value builtin_noop(void);
#endif
/* By: agilliar <agilliar@student.42mulhouse.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* 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)
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:
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");
}
/* By: agilliar <agilliar@student.42mulhouse.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* 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 */
/* */
/* ************************************************************************** */
__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);
}
/* By: agilliar <agilliar@student.42mulhouse.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* 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 */
/* */
/* ************************************************************************** */
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
--- /dev/null
+/* ************************************************************************** */
+/* */
+/* ::: :::::::: */
+/* value_debug.c :+: :+: :+: */
+/* +:+ +:+ +:+ */
+/* By: agilliar <agilliar@student.42mulhouse.fr> +#+ +:+ +#+ */
+/* +#+#+#+#+#+ +#+ */
+/* Created: 2026/05/20 11:23:55 by agilliar #+# #+# */
+/* Updated: 2026/05/20 14:48:04 by agilliar ### ########.fr */
+/* */
+/* ************************************************************************** */
+
+#include <stdio.h>
+#include <stddef.h>
+#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, "", "<unknown>");
+}
/* By: agilliar <agilliar@student.42mulhouse.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* 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 */
/* */
/* ************************************************************************** */
__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
/* By: agilliar <agilliar@student.42mulhouse.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* 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 */
/* */
/* ************************************************************************** */
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);
}
{
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)
/* By: agilliar <agilliar@student.42mulhouse.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* 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 */
/* */
/* ************************************************************************** */
/* By: agilliar <agilliar@student.42mulhouse.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* 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 */
/* */
/* ************************************************************************** */
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);
}
/* By: agilliar <agilliar@student.42mulhouse.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* 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 */
/* */
/* ************************************************************************** */
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
--- /dev/null
+/* ************************************************************************** */
+/* */
+/* ::: :::::::: */
+/* value_new_utils.c :+: :+: :+: */
+/* +:+ +:+ +:+ */
+/* By: agilliar <agilliar@student.42mulhouse.fr> +#+ +:+ +#+ */
+/* +#+#+#+#+#+ +#+ */
+/* 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 <stdarg.h>
+
+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)));
+}
/* By: agilliar <agilliar@student.42mulhouse.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* 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 <stddef.h>
+# include <stdint.h>
+
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
{
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,
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
{
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
/* By: agilliar <agilliar@student.42mulhouse.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* 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 */
/* */
/* ************************************************************************** */
#include <stdio.h>
#include <stdlib.h>
+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;
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)