1
1
mirror of https://github.com/anoma/juvix.git synced 2024-12-12 04:43:18 +03:00
juvix/tests/runtime/positive/test015.c

266 lines
8.2 KiB
C
Raw Normal View History

2022-11-03 11:38:09 +03:00
/* Branching, matching and recursion on lists */
#include <juvix/api.h>
#define CONSTRS_NUM (BUILTIN_UIDS_NUM + 2)
static constr_info_t juvix_constr_info_array[CONSTRS_NUM] = {
BUILTIN_UIDS_INFO, {"nil", 0, APP_FIXITY}, {"cons", 0, APP_FIXITY}};
2022-11-03 11:38:09 +03:00
#define UID_NIL FIRST_USER_UID
#define UID_CONS (FIRST_USER_UID + 1)
#define CONSTR_NIL MAKE_HEADER(UID_NIL, 0)
int main() {
DECL_REG_ARG(0);
DECL_REG_ARG(1);
JUVIX_PROLOGUE(3);
2022-11-03 11:38:09 +03:00
juvix_constrs_num = CONSTRS_NUM;
juvix_constr_info = juvix_constr_info_array;
CALL(0, juvix_function_main, juvix_label_0);
goto juvix_program_end;
JUVIX_FUNCTION_NS(juvix_function_hd);
{
juvix_result = CONSTR_ARG(ARG(0), 0);
RETURN_NS;
}
JUVIX_FUNCTION_NS(juvix_function_tl);
{
juvix_result = CONSTR_ARG(ARG(0), 1);
RETURN_NS;
}
JUVIX_FUNCTION_NS(juvix_function_null);
{
switch (ARG(0)) {
case CONSTR_NIL:
juvix_result = BOOL_TRUE;
break;
default: // cons
juvix_result = BOOL_FALSE;
break;
}
RETURN_NS;
}
JUVIX_FUNCTION(juvix_function_map, 3);
{
switch (ARG(1)) {
case CONSTR_NIL:
juvix_result = CONSTR_NIL;
RETURN;
default: {
DECL_TMP(0);
DECL_TMP(1);
TMP(0) = ARG(0);
TMP(1) = ARG(1);
STACK_PUSH(TMP(0));
STACK_PUSH(TMP(1));
ARG(0) = TMP(0);
ARG(1) = CONSTR_ARG(TMP(1), 1);
CALL(0, juvix_function_map, juvix_label_1);
STACK_POP(TMP(1));
STACK_POP(TMP(0));
STACK_PUSH(juvix_result);
ASSIGN_CARGS(TMP(0), {
CARG(juvix_closure_nargs) = CONSTR_ARG(TMP(1), 0);
});
CALL_CLOSURE(TMP(0), juvix_label_2);
STACK_POP(TMP(0));
TMP(1) = juvix_result;
PREALLOC(
3,
{
STACK_PUSH(TMP(0));
STACK_PUSH(TMP(1));
},
{
STACK_POP(TMP(1));
STACK_POP(TMP(0));
});
ALLOC_CONSTR_BOXED(juvix_result, UID_CONS, 2);
CONSTR_ARG(juvix_result, 0) = TMP(1);
CONSTR_ARG(juvix_result, 1) = TMP(0);
RETURN;
}
}
}
JUVIX_FUNCTION(juvix_function_map_1, 3);
{
STACK_PUSH(ARG(0));
STACK_PUSH(ARG(1));
ARG(0) = ARG(1);
CALL(0, juvix_function_null, juvix_label_3);
STACK_POP(ARG(1));
STACK_POP(ARG(0));
JUVIX_BRANCH(
juvix_result, { juvix_result = CONSTR_NIL; },
{
DECL_TMP(0);
DECL_TMP(1);
STACK_PUSH(ARG(0));
ARG(0) = ARG(1);
CALL(0, juvix_function_tl, juvix_label_4);
ARG(0) = STACK_TOP;
STACK_PUSH(ARG(1));
ARG(1) = juvix_result;
CALL(0, juvix_function_map_1, juvix_label_5);
STACK_POP(TMP(1));
STACK_POP(TMP(0));
STACK_PUSH(TMP(0));
STACK_PUSH(juvix_result);
ARG(0) = TMP(1);
CALL(0, juvix_function_hd, juvix_label_6);
STACK_POP(TMP(1)); // TMP(1) = map tail
STACK_POP(TMP(0)); // TMP(0) = function
STACK_PUSH(TMP(1));
ASSIGN_CARGS(TMP(0),
{ CARG(juvix_closure_nargs) = juvix_result; });
CALL_CLOSURE(TMP(0), juvix_label_7);
STACK_POP(TMP(1));
PREALLOC(3, { STACK_PUSH(TMP(1)); }, { STACK_POP(TMP(1)); });
2022-11-03 11:38:09 +03:00
ALLOC_CONSTR_BOXED(TMP(0), UID_CONS, 2);
CONSTR_ARG(TMP(0), 0) = juvix_result;
CONSTR_ARG(TMP(0), 1) = TMP(1);
juvix_result = TMP(0);
});
RETURN;
}
juvix_closure_add_one:
ARG(0) = CARG(0);
JUVIX_FUNCTION_NS(juvix_function_add_one);
{
JUVIX_INT_ADD(juvix_result, ARG(0), make_smallint(1));
RETURN_NS;
}
JUVIX_FUNCTION(juvix_function_gen, 2);
{
DECL_TMP(0);
JUVIX_VAL_EQ(TMP(0), ARG(0), make_smallint(0));
JUVIX_BRANCH(
TMP(0),
{
juvix_result = CONSTR_NIL;
RETURN;
},
{
JUVIX_INT_SUB(TMP(0), ARG(0), make_smallint(1));
STACK_PUSH(ARG(0));
ARG(0) = TMP(0);
CALL(0, juvix_function_gen, juvix_label_gen_1);
STACK_POP(ARG(0));
PREALLOC(3, { STACK_PUSH(ARG(0)); }, { STACK_POP(ARG(0)); });
2022-11-03 11:38:09 +03:00
ALLOC_CONSTR_BOXED(TMP(0), UID_CONS, 2);
CONSTR_ARG(TMP(0), 0) = ARG(0);
CONSTR_ARG(TMP(0), 1) = juvix_result;
juvix_result = TMP(0);
RETURN;
});
}
JUVIX_FUNCTION(juvix_function_sum, 2);
{
switch (ARG(0)) {
case CONSTR_NIL:
juvix_result = make_smallint(0);
RETURN;
default: {
DECL_TMP(0);
DECL_TMP(1);
TMP(0) = CONSTR_ARG(ARG(0), 0);
STACK_PUSH(TMP(0));
ARG(0) = CONSTR_ARG(ARG(0), 1);
CALL(0, juvix_function_sum, juvix_label_sum_1);
STACK_POP(TMP(0));
JUVIX_INT_ADD(TMP(1), TMP(0), juvix_result);
juvix_result = TMP(1);
RETURN;
}
}
}
JUVIX_FUNCTION(juvix_function_length, 1);
{
switch (ARG(0)) {
case CONSTR_NIL:
juvix_result = make_smallint(0);
RETURN;
default: {
DECL_TMP(0);
ARG(0) = CONSTR_ARG(ARG(0), 1);
CALL(0, juvix_function_length, juvix_label_length_1);
JUVIX_INT_ADD(TMP(0), juvix_result, make_smallint(1));
juvix_result = TMP(0);
RETURN;
}
}
}
JUVIX_FUNCTION_NS(juvix_function_length_tail);
{
switch (ARG(0)) {
case CONSTR_NIL:
juvix_result = ARG(1);
RETURN_NS;
default: {
ARG(0) = CONSTR_ARG(ARG(0), 1);
JUVIX_INT_ADD(ARG(1), ARG(1), make_smallint(1));
TAIL_CALL_NS(0, juvix_function_length_tail);
}
}
}
JUVIX_FUNCTION(juvix_function_main, MAX_STACK_DELTA);
{
DECL_TMP(0); // cons 0 (cons 1 nil)
DECL_TMP(1); // cons 1 nil
DECL_TMP(2); // calloc add_one 0
ALLOC_CONSTR_BOXED(TMP(1), UID_CONS, 2);
CONSTR_ARG(TMP(1), 0) = make_smallint(1);
CONSTR_ARG(TMP(1), 1) = CONSTR_NIL;
ALLOC_CONSTR_BOXED(TMP(0), UID_CONS, 2);
CONSTR_ARG(TMP(0), 0) = make_smallint(0);
CONSTR_ARG(TMP(0), 1) = TMP(1);
ALLOC_CLOSURE(TMP(2), 0, LABEL_ADDR(juvix_closure_add_one), 0, 1);
ARG(0) = TMP(2);
ARG(1) = TMP(0);
CALL(0, juvix_function_map, juvix_label_8);
JUVIX_TRACE(juvix_result);
ARG(0) = TMP(2);
ARG(1) = TMP(0);
CALL(0, juvix_function_map_1, juvix_label_9);
JUVIX_TRACE(juvix_result);
ARG(0) = make_smallint(10000);
CALL(0, juvix_function_gen, juvix_label_10);
ARG(0) = TMP(2);
ARG(1) = juvix_result;
CALL(0, juvix_function_map, juvix_label_11);
ARG(0) = juvix_result;
CALL(0, juvix_function_sum, juvix_label_12);
JUVIX_TRACE(juvix_result);
ARG(0) = make_smallint(1000000);
CALL(0, juvix_function_gen, juvix_label_13);
STACK_PUSH(juvix_result);
ARG(0) = TMP(2);
ARG(1) = juvix_result;
CALL(0, juvix_function_map, juvix_label_14);
ARG(0) = juvix_result;
CALL(0, juvix_function_length, juvix_label_15);
JUVIX_TRACE(juvix_result);
STACK_POP(ARG(0));
ARG(1) = make_smallint(0);
TAIL_CALL(0, juvix_function_length_tail);
}
JUVIX_EPILOGUE;
return 0;
}