]> Untitled Git - axy/ft/c-cera.git/commitdiff
Some various function examples
authorAxy <gilliardmarthey.axel@gmail.com>
Wed, 27 May 2026 11:25:36 +0000 (13:25 +0200)
committerAxy <gilliardmarthey.axel@gmail.com>
Wed, 27 May 2026 11:25:36 +0000 (13:25 +0200)
14 files changed:
.deps
Makefile
conf.mk
src/arc.h
src/builtin_add.c [new file with mode: 0644]
src/builtin_list_get.c [new file with mode: 0644]
src/builtin_list_set.c [new file with mode: 0644]
src/builtin_list_set_drop.c [new file with mode: 0644]
src/builtin_sub.c [new file with mode: 0644]
src/value_debug.c
src/value_lifetime.c
src/value_new.c
src/value_types.h
test.c

diff --git a/.deps b/.deps
index 9c7d9d04b66eeae841b9aed9a518fe82ba41801f..9b8bb574f57705cb3fea88a53daa0151029921bf 100644 (file)
--- a/.deps
+++ b/.deps
@@ -1,7 +1,22 @@
 ${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_add.o: src/builtin_add.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.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_list_get.o: src/builtin_list_get.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_list_set.o: src/builtin_list_set.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_list_set_drop.o: src/builtin_list_set_drop.c src/value.h \
+  src/value_get.h src/value_types.h src/panic.h src/jmp.h \
+  src/value_new.h src/arc.h src/memutils.h src/arith.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 \
@@ -10,6 +25,10 @@ ${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}/builtin_sub.o: src/builtin_sub.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}/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 \
index e33b1557d7d4a12b43729652fef4d1b296c63575..c9333732899f24be6490c211c269d45578734a5d 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,6 @@
 NAME=ccera.a
 
-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
+SRCS=src/arc.c src/builtin_add.c src/builtin.c src/builtin_list_get.c src/builtin_list_set.c src/builtin_list_set_drop.c src/builtin_mul.c src/builtin_noop.c src/builtin_register.c src/builtin_sub.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/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
 
diff --git a/conf.mk b/conf.mk
index a3fd7af20be42a74dd6d47ba347e326580eb4cca..e464f4554a43b07b28fded866ebe9ede168a72df 100644 (file)
--- a/conf.mk
+++ b/conf.mk
@@ -1,4 +1,4 @@
-LTO=0
+#LTO=1
 OPT=0
 #CC=gcc
 #UBSAN=1
index 1af6e763947a897e325e9a03a56e064943ed4f2a..a44ebc11b8c67e843d136faeebb4aa2c8b8d3758 100644 (file)
--- a/src/arc.h
+++ b/src/arc.h
@@ -6,7 +6,7 @@
 /*   By: agilliar <agilliar@student.42mulhouse.fr>  +#+  +:+       +#+        */
 /*                                                +#+#+#+#+#+   +#+           */
 /*   Created: 2026/05/13 08:56:53 by agilliar          #+#    #+#             */
-/*   Updated: 2026/05/18 14:43:36 by agilliar         ###   ########.fr       */
+/*   Updated: 2026/05/25 17:14:55 by agilliar         ###   ########.fr       */
 /*                                                                            */
 /* ************************************************************************** */
 
@@ -36,7 +36,6 @@ static inline t_arc   arc_new_zeroed(size_t size)
        return ((void *) &res[1]);
 }
 
-t_arc  arc_new_zeroed(size_t size);
 void   noop(void *ptr);
 
 #endif
diff --git a/src/builtin_add.c b/src/builtin_add.c
new file mode 100644 (file)
index 0000000..d668180
--- /dev/null
@@ -0,0 +1,70 @@
+/* ************************************************************************** */
+/*                                                                            */
+/*                                                        :::      ::::::::   */
+/*   builtin_add.c                                      :+:      :+:    :+:   */
+/*                                                    +:+ +:+         +:+     */
+/*   By: agilliar <agilliar@student.42mulhouse.fr>  +#+  +:+       +#+        */
+/*                                                +#+#+#+#+#+   +#+           */
+/*   Created: 2026/05/25 14:49:44 by agilliar          #+#    #+#             */
+/*   Updated: 2026/05/25 14:50:50 by agilliar         ###   ########.fr       */
+/*                                                                            */
+/* ************************************************************************** */
+
+#include "builtin_register.h"
+#include "value.h"
+#include "defer.h"
+
+t_value        builtin_iadd_impl(t_value self, t_value arg)
+{
+       t_value         res;
+
+       (void) self;
+       errdefer(value_drop, &arg);
+       res = value_new_builtin(BUILTIN_IADD1);
+       res.val.v_int = *value_int(&arg);
+       return (res);
+}
+
+t_value        builtin_iadd1_impl(t_value self, t_value arg)
+{
+       t_value         res;
+
+       (void) self;
+       errdefer(value_drop, &arg);
+       res = value_new_int(*value_int(&arg));
+       __builtin_add_overflow(res.val.v_int,
+               self.val.v_int, &res.val.v_int);
+       return (res);
+}
+
+t_value        builtin_uadd_impl(t_value self, t_value arg)
+{
+       t_value         res;
+
+       (void) self;
+       errdefer(value_drop, &arg);
+       res = value_new_builtin(BUILTIN_UADD1);
+       res.val.v_uint = *value_uint(&arg);
+       return (res);
+}
+
+t_value        builtin_uadd1_impl(t_value self, t_value arg)
+{
+       t_value         res;
+
+       (void) self;
+       errdefer(value_drop, &arg);
+       res = value_new_uint(*value_uint(&arg));
+       __builtin_add_overflow(res.val.v_uint,
+               self.val.v_uint, &res.val.v_uint);
+       return (res);
+}
+
+__attribute__((constructor))
+void   builtin_add_register(void)
+{
+       builtin_register(BUILTIN_IADD, &builtin_iadd_impl, "iadd");
+       builtin_register(BUILTIN_IADD1, &builtin_iadd1_impl, "iadd1");
+       builtin_register(BUILTIN_UADD, &builtin_uadd_impl, "uadd");
+       builtin_register(BUILTIN_UADD1, &builtin_uadd1_impl, "uadd1");
+}
diff --git a/src/builtin_list_get.c b/src/builtin_list_get.c
new file mode 100644 (file)
index 0000000..02362d6
--- /dev/null
@@ -0,0 +1,40 @@
+/* ************************************************************************** */
+/*                                                                            */
+/*                                                        :::      ::::::::   */
+/*   builtin_list_get.c                                 :+:      :+:    :+:   */
+/*                                                    +:+ +:+         +:+     */
+/*   By: agilliar <agilliar@student.42mulhouse.fr>  +#+  +:+       +#+        */
+/*                                                +#+#+#+#+#+   +#+           */
+/*   Created: 2026/05/25 15:18:16 by agilliar          #+#    #+#             */
+/*   Updated: 2026/05/25 15:58:14 by agilliar         ###   ########.fr       */
+/*                                                                            */
+/* ************************************************************************** */
+
+#include "builtin_register.h"
+#include "value.h"
+#include "defer.h"
+
+t_value        builtin_list_get_impl(t_value self, t_value arg)
+{
+       t_value         res;
+
+       (void) self;
+       errdefer(value_drop, &arg);
+       res = value_new_builtin(BUILTIN_LIST_GET1);
+       res.val.v_uint = *value_uint(&arg);
+       return (res);
+}
+
+t_value        builtin_list_get1_impl(t_value self, t_value arg)
+{
+       (void) self;
+       defer(value_drop, &arg);
+       return (value_copy(*value_list_get(arg, self.val.v_uint)));
+}
+
+__attribute__((constructor))
+void   builtin_list_get_register(void)
+{
+       builtin_register(BUILTIN_LIST_GET, &builtin_list_get_impl, "list_get");
+       builtin_register(BUILTIN_LIST_GET1, &builtin_list_get1_impl, "list_get1");
+}
diff --git a/src/builtin_list_set.c b/src/builtin_list_set.c
new file mode 100644 (file)
index 0000000..8d70353
--- /dev/null
@@ -0,0 +1,67 @@
+/* ************************************************************************** */
+/*                                                                            */
+/*                                                        :::      ::::::::   */
+/*   builtin_list_set.c                                 :+:      :+:    :+:   */
+/*                                                    +:+ +:+         +:+     */
+/*   By: agilliar <agilliar@student.42mulhouse.fr>  +#+  +:+       +#+        */
+/*                                                +#+#+#+#+#+   +#+           */
+/*   Created: 2026/05/25 16:25:55 by agilliar          #+#    #+#             */
+/*   Updated: 2026/05/25 17:33:13 by agilliar         ###   ########.fr       */
+/*                                                                            */
+/* ************************************************************************** */
+
+#include "builtin_register.h"
+#include "value.h"
+#include "defer.h"
+
+t_value        builtin_list_set1_get_val(t_value val);
+void   builtin_list_set1_drop(t_value *val);
+t_value        builtin_list_set1_copy(t_value *val);
+
+t_value        builtin_list_set_impl(t_value self, t_value arg)
+{
+       t_value res;
+
+       (void) self;
+       errdefer(value_drop, &arg);
+       res = value_new_builtin(BUILTIN_LIST_SET1);
+       res.val.v_uint = *value_uint(&arg);
+       return (res);
+}
+
+t_value        builtin_list_set1_impl(t_value self, t_value arg)
+{
+       t_value *slot;
+       t_value res;
+
+       errdefer(value_drop, &arg);
+       slot = value_list_getu(&arg, self.val.v_uint);
+       value_put(slot, value_new_uint(self.val.v_uint));
+       res = value_new_builtin(BUILTIN_LIST_SET2);
+       res.val.v_ptr = slot;
+       return (res);
+}
+
+t_value        builtin_list_set2_impl(t_value self, t_value arg)
+{
+       t_value res;
+
+       res = builtin_list_set1_get_val(self);
+       errdefer(value_drop, &self);
+       errdefer(value_drop, &arg);
+       value_put(value_list_getu(&res, *value_uint(self.val.v_ptr)), arg);
+       return (res);
+}
+
+__attribute__((constructor))
+void   builtin_list_set_register(void)
+{
+       t_builtin       *set1;
+
+       builtin_register(BUILTIN_LIST_SET, &builtin_list_set_impl, "list_set");
+       set1 = builtin_register(BUILTIN_LIST_SET1,
+                       &builtin_list_set1_impl, "list_set1");
+       set1->drop = &builtin_list_set1_drop;
+       set1->copy = &builtin_list_set1_copy;
+       builtin_register(BUILTIN_LIST_SET2, &builtin_list_set2_impl, "list_set2");
+}
diff --git a/src/builtin_list_set_drop.c b/src/builtin_list_set_drop.c
new file mode 100644 (file)
index 0000000..d7ed3bc
--- /dev/null
@@ -0,0 +1,41 @@
+/* ************************************************************************** */
+/*                                                                            */
+/*                                                        :::      ::::::::   */
+/*   builtin_list_set_drop.c                            :+:      :+:    :+:   */
+/*                                                    +:+ +:+         +:+     */
+/*   By: agilliar <agilliar@student.42mulhouse.fr>  +#+  +:+       +#+        */
+/*                                                +#+#+#+#+#+   +#+           */
+/*   Created: 2026/05/25 16:30:44 by agilliar          #+#    #+#             */
+/*   Updated: 2026/05/25 17:26:54 by agilliar         ###   ########.fr       */
+/*                                                                            */
+/* ************************************************************************** */
+
+#include "value.h"
+#include "arc.h"
+
+t_value        builtin_list_set1_get_val(t_value val)
+{
+       t_value         *slot;
+       uintptr_t       i;
+       t_value         res;
+
+       slot = val.val.v_ptr;
+       i = *value_uint(slot);
+       res.tag = VALUE_LIST;
+       res.val.v_list = (((void *) slot)
+                       - sizeof(t_value) * i - offsetof(t_list, buf));
+       return (res);
+}
+
+void   builtin_list_set1_drop(t_value *val)
+{
+       t_value lst;
+
+       lst = builtin_list_set1_get_val(*val);
+       value_drop(&lst);
+}
+
+t_value        builtin_list_set1_copy(t_value *val)
+{
+       return (value_copy(builtin_list_set1_get_val(*val)));
+}
diff --git a/src/builtin_sub.c b/src/builtin_sub.c
new file mode 100644 (file)
index 0000000..c86e9de
--- /dev/null
@@ -0,0 +1,70 @@
+/* ************************************************************************** */
+/*                                                                            */
+/*                                                        :::      ::::::::   */
+/*   builtin_sub.c                                      :+:      :+:    :+:   */
+/*                                                    +:+ +:+         +:+     */
+/*   By: agilliar <agilliar@student.42mulhouse.fr>  +#+  +:+       +#+        */
+/*                                                +#+#+#+#+#+   +#+           */
+/*   Created: 2026/05/25 14:59:29 by agilliar          #+#    #+#             */
+/*   Updated: 2026/05/25 15:02:24 by agilliar         ###   ########.fr       */
+/*                                                                            */
+/* ************************************************************************** */
+
+#include "builtin_register.h"
+#include "value.h"
+#include "defer.h"
+
+t_value        builtin_isub_impl(t_value self, t_value arg)
+{
+       t_value         res;
+
+       (void) self;
+       errdefer(value_drop, &arg);
+       res = value_new_builtin(BUILTIN_ISUB1);
+       res.val.v_int = *value_int(&arg);
+       return (res);
+}
+
+t_value        builtin_isub1_impl(t_value self, t_value arg)
+{
+       t_value         res;
+
+       (void) self;
+       errdefer(value_drop, &arg);
+       res = value_new_int(*value_int(&arg));
+       __builtin_sub_overflow(self.val.v_int,
+               res.val.v_int, &res.val.v_int);
+       return (res);
+}
+
+t_value        builtin_usub_impl(t_value self, t_value arg)
+{
+       t_value         res;
+
+       (void) self;
+       errdefer(value_drop, &arg);
+       res = value_new_builtin(BUILTIN_USUB1);
+       res.val.v_uint = *value_uint(&arg);
+       return (res);
+}
+
+t_value        builtin_usub1_impl(t_value self, t_value arg)
+{
+       t_value         res;
+
+       (void) self;
+       errdefer(value_drop, &arg);
+       res = value_new_uint(*value_uint(&arg));
+       __builtin_sub_overflow(self.val.v_uint,
+               res.val.v_uint, &res.val.v_uint);
+       return (res);
+}
+
+__attribute__((constructor))
+void   builtin_sub_register(void)
+{
+       builtin_register(BUILTIN_ISUB, &builtin_isub_impl, "isub");
+       builtin_register(BUILTIN_ISUB1, &builtin_isub1_impl, "isub1");
+       builtin_register(BUILTIN_USUB, &builtin_usub_impl, "usub");
+       builtin_register(BUILTIN_USUB1, &builtin_usub1_impl, "usub1");
+}
index b1ab0dd45620546c0ff825470068c133a8d39b6f..2bf18cdb8b3f938d1e22bf84fbeaa2daf8f08251 100644 (file)
@@ -6,7 +6,7 @@
 /*   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       */
+/*   Updated: 2026/05/25 18:13:32 by agilliar         ###   ########.fr       */
 /*                                                                            */
 /* ************************************************************************** */
 
@@ -37,6 +37,9 @@ void  value_debug(size_t indent, t_value *value)
                value_debug_list(indent, value->val.v_list);
        else if (value->tag == VALUE_NIL)
                printf("%*s%s\n", (int)indent, "", "nil");
+       else if (value->tag == VALUE_BYTES)
+               printf("%*s%.*s\n", (int)indent, "", value->val.v_bytes->len,
+                       value->val.v_bytes->buf);
        else
                printf("%*s%s\n", (int)indent, "", "<unknown>");
 }
index 993b08bc98f762a6ba905790c01f73fa12b1a7f6..d51ea742910defcaee8312d23a2f93af0553e95e 100644 (file)
@@ -6,7 +6,7 @@
 /*   By: agilliar <agilliar@student.42mulhouse.fr>  +#+  +:+       +#+        */
 /*                                                +#+#+#+#+#+   +#+           */
 /*   Created: 2026/05/12 17:42:10 by agilliar          #+#    #+#             */
-/*   Updated: 2026/05/20 13:33:49 by agilliar         ###   ########.fr       */
+/*   Updated: 2026/05/25 17:52:28 by agilliar         ###   ########.fr       */
 /*                                                                            */
 /* ************************************************************************** */
 
@@ -33,13 +33,12 @@ t_value     value_clone(t_value val)
        t_list          *lst;
 
        res = val;
-       if (val.tag == VALUE_LIST)
-       {
+       if (val.tag == VALUE_BYTES)
                res.val.v_bytes = arc_new(sizeof(t_bytes) + val.val.v_bytes->len);
+       if (val.tag == VALUE_BYTES)
                cera_memcpy(res.val.v_bytes->buf, val.val.v_bytes->buf,
                        val.val.v_bytes->len);
-       }
-       else if (val.tag == VALUE_BYTES)
+       else if (val.tag == VALUE_LIST)
        {
                res.val.v_list = arc_new(sizeof(t_list)
                                + sizeof(t_value) * val.val.v_list->len);
@@ -52,7 +51,9 @@ t_value       value_clone(t_value val)
                        lst->len++;
                }
        }
-       return (value_copy(res));
+       else
+               res = value_copy(res);
+       return (res);
 }
 
 static void    list_drop(t_list *lst)
@@ -78,6 +79,6 @@ 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);
+               value_put(val, value_clone(*val));
        return (*val);
 }
index 4282135439a39d5337a9e4ff5b4acdb59d14d4a8..b28a7c5beecbec69c180e845059d08e6481dbc96 100644 (file)
@@ -6,7 +6,7 @@
 /*   By: agilliar <agilliar@student.42mulhouse.fr>  +#+  +:+       +#+        */
 /*                                                +#+#+#+#+#+   +#+           */
 /*   Created: 2026/05/13 08:40:13 by agilliar          #+#    #+#             */
-/*   Updated: 2026/05/20 14:14:05 by agilliar         ###   ########.fr       */
+/*   Updated: 2026/05/25 18:14:32 by agilliar         ###   ########.fr       */
 /*                                                                            */
 /* ************************************************************************** */
 
@@ -35,6 +35,7 @@ t_value       value_new_str(const char *s)
        len = cera_strlen(s);
        res.val.v_bytes = arc_new(uadd(sizeof(t_bytes), len));
        cera_memcpy(res.val.v_bytes->buf, s, len);
+       res.val.v_bytes->len = len;
        return (res);
 }
 
index 86e9cf57078de5bcf6310ad60b75d497d7f3d961..83769b2e48ae7e781d340f1c998f5019fed3e1be 100644 (file)
@@ -6,7 +6,7 @@
 /*   By: agilliar <agilliar@student.42mulhouse.fr>  +#+  +:+       +#+        */
 /*                                                +#+#+#+#+#+   +#+           */
 /*   Created: 2026/05/13 22:04:36 by agilliar          #+#    #+#             */
-/*   Updated: 2026/05/20 14:03:21 by agilliar         ###   ########.fr       */
+/*   Updated: 2026/05/25 16:39:10 by agilliar         ###   ########.fr       */
 /*                                                                            */
 /* ************************************************************************** */
 
@@ -26,6 +26,7 @@ union u_value
        intptr_t        v_int;
        t_bytes         *v_bytes;
        t_list          *v_list;
+       void            *v_ptr;
 };
 
 enum e_builtin: uint16_t
@@ -43,6 +44,11 @@ enum e_builtin: uint16_t
        BUILTIN_ISUB1,
        BUILTIN_USUB,
        BUILTIN_USUB1,
+       BUILTIN_LIST_GET,
+       BUILTIN_LIST_GET1,
+       BUILTIN_LIST_SET,
+       BUILTIN_LIST_SET1,
+       BUILTIN_LIST_SET2,
        _BUILTIN_MAX,
 };
 
diff --git a/test.c b/test.c
index fdf3c113446e64f1d8a57b3bcfb6965dcad6f307..fa7c9b8df132aea4bc691359addfdf7c48e2211f 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/05/20 15:33:15 by agilliar         ###   ########.fr       */
+/*   Updated: 2026/05/27 13:23:35 by agilliar         ###   ########.fr       */
 /*                                                                            */
 /* ************************************************************************** */
 
 #include <stdio.h>
 #include <stdlib.h>
 
-t_value        test_expr(void)
+// a -> b -> a
+t_value        value_true(void)
 {
-       t_value exprs = value_new_va(
+       t_value res = value_new_va(
+               4,
+               value_new_builtin(BUILTIN_NOOP),
+               value_new_nil(),
+               value_new_nil(),
+               value_new_step(0, false, 1, false)
+       );
+       return (value_new_va(2, res, value_new_uint(1)));
+}
+
+// a -> b -> b
+t_value        value_false(void)
+{
+       t_value res = value_new_va(
+               4,
+               value_new_builtin(BUILTIN_NOOP),
+               value_new_nil(),
+               value_new_nil(),
+               value_new_step(0, false, 2, false)
+       );
+       return (value_new_va(2, res, value_new_uint(1)));
+}
+
+// bool -> a -> b -> a | b
+t_value        ite(void)
+{
+       t_value res = value_new_va(
                5,
-               value_new_builtin(BUILTIN_UMUL),
-               value_new_uint(8),
+               value_new_builtin(BUILTIN_LIST_GET),
+               value_new_va(2, value_false(), value_true()),
+               value_new_nil(),
+               value_new_step(0, true, 2, true),
+               value_new_step(3, true, 1, true)
+       );
+       return (value_new_va(2, res, value_new_uint(2)));
+}
+
+// (a -> b) -> a -> nil -> b
+t_value        lazy_eval(void)
+{
+       t_value res = value_new_va(
+               4,
+               value_new_nil(),
+               value_new_nil(),
+               value_new_nil(),
+               value_new_step(0, true, 1, true)
+       );
+       return (value_new_va(2, res, value_new_uint(0)));
+}
+
+// (a -> b) -> (b -> c) -> a -> c
+t_value        compose(void)
+{
+       t_value res = value_new_va(
+               5,
+               value_new_nil(),
+               value_new_nil(),
+               value_new_nil(),
+               value_new_step(0, true, 2, true),
+               value_new_step(3, true, 1, true)
+       );
+       return (value_new_va(2, res, value_new_uint(0)));
+}
+
+
+// (f: f -> a) -> a
+t_value        make_rec(void)
+{
+       t_value comb = value_new_va(
+               2,
+               value_new_nil(),
+               value_new_step(0, false, 0, true)
+               );
+       return (value_new_va(2, comb, value_new_uint(0)));
+}
+
+/*
+t_value        fib(void)
+{
+       t_value comb = value_new_va(
+               _,
+               make_rec(),
+               ite(),
+               value_new_builtin(BUILTIN_UADD),
+               value_new_builtin(BUILTIN_NOOP),
+               value_new_nil(),
+               value_new_nil(),
+               value_new_nil(),
+               );
+       return (expr_eval(make_rec(), value_new_va(2, comb, value_new_uint(0))));
+}
+*/
+
+t_value        test_expr(void)
+{      
+       t_value exprs = value_new_va(
+               7,
+               ite(),
+               value_new_uint(100),
+               value_new_uint(103),
                value_new_nil(),
-               value_new_step(0, false, 1, true),
-               value_new_step(3, false, 2, true)
+               value_new_step(0, true, 3, true),
+               value_new_step(4, true, 1, true),
+               value_new_step(5, true, 2, true)
                );
-       return (value_new_va(2, exprs, value_new_uint(2)));
+       return (value_new_va(2, exprs, value_new_uint(3)));
 }
 
 void main2(void        *_orig)
@@ -36,7 +134,8 @@ void main2(void      *_orig)
        char    *s2 = malloc(strlen(orig) + 1);
        defer(free, s2);
        strcpy(s2, orig);
-       t_value res = expr_eval(test_expr(), value_new_uint(7));
+       t_value res = expr_eval(test_expr(), value_new_uint(0));
+       //t_value       res = expr_eval(fib(), value_new_uint(10));
        value_debug(0, &res);
        defer(value_drop, &res);
        printf("%s\n", s2);