1
1
mirror of https://github.com/anoma/juvix.git synced 2024-12-28 18:11:49 +03:00
juvix/tests/runtime/positive/test020.c
2022-12-06 11:33:20 +01:00

184 lines
5.2 KiB
C

/* Higher-order function composition */
#include <juvix/api.h>
#define JUVIX_DECL_ARGS \
DECL_REG_ARG(0); \
DECL_REG_ARG(1); \
DECL_REG_ARG(2)
static constr_info_t juvix_constr_info_array[BUILTIN_UIDS_NUM] = {
BUILTIN_UIDS_INFO};
#define FUIDS_NUM 5
#define FUID_UNKNOWN 0
#define FUID_COMPOSE 1
#define FUID_PLUS 2
#define FUID_INC 3
#define FUID_ID 4
static function_info_t juvix_function_info_array[FUIDS_NUM] = {
{"<closure>"}, {"compose"}, {"plus"}, {"inc"}, {"id"}};
int main() {
JUVIX_DECL_ARGS;
JUVIX_PROLOGUE(3);
DECL_ZEROARG_CLOSURE(id, FUID_ID, 1);
DECL_ZEROARG_CLOSURE(inc, FUID_INC, 1);
juvix_constrs_num = BUILTIN_UIDS_NUM;
juvix_constr_info = juvix_constr_info_array;
juvix_functions_num = FUIDS_NUM;
juvix_function_info = juvix_function_info_array;
CALL(0, juvix_function_main, juvix_label_0);
goto juvix_program_end;
juvix_closure_compose:
ARG(0) = CARG(0);
ARG(1) = CARG(1);
ARG(2) = CARG(2);
JUVIX_FUNCTION(juvix_function_compose, 2);
{
STACK_PUSH(ARG(0));
ASSIGN_CARGS(ARG(1), { CARG(juvix_closure_nargs) = ARG(2); });
CALL_CLOSURE(ARG(1), juvix_label_compose_1);
STACK_POP(ARG(0));
ASSIGN_CARGS(ARG(0), { CARG(juvix_closure_nargs) = juvix_result; });
TAIL_CALL_CLOSURE(ARG(0));
}
juvix_closure_id:
ARG(0) = CARG(0);
JUVIX_FUNCTION_NS(juvix_function_id);
{
juvix_result = ARG(0);
RETURN_NS;
}
JUVIX_FUNCTION(juvix_function_iterate, 2);
{
DECL_TMP(0);
JUVIX_VAL_EQ(TMP(0), ARG(1), make_smallint(0));
JUVIX_BRANCH(
TMP(0),
{
juvix_result = juvix_zeroarg_closure_id;
RETURN;
},
{
STACK_PUSH(ARG(0));
JUVIX_INT_SUB(TMP(0), ARG(1), make_smallint(1));
ARG(1) = TMP(0);
CALL(0, juvix_function_iterate, juvix_label_iterate_1);
STACK_POP(ARG(0));
PREALLOC(
CLOSURE_HEAD_SIZE + 2,
{
STACK_PUSH(ARG(0));
STACK_PUSH(juvix_result);
},
{
STACK_POP(juvix_result);
STACK_POP(ARG(0));
});
ALLOC_CLOSURE(TMP(0), FUID_COMPOSE,
LABEL_ADDR(juvix_closure_compose), 2, 1);
CLOSURE_ARG(TMP(0), 0) = ARG(0);
CLOSURE_ARG(TMP(0), 1) = juvix_result;
juvix_result = TMP(0);
RETURN;
});
}
juvix_closure_inc:
ARG(0) = CARG(0);
JUVIX_FUNCTION_NS(juvix_function_inc);
{
JUVIX_INT_ADD(juvix_result, ARG(0), make_smallint(1));
RETURN_NS;
}
juvix_closure_plus:
ARG(0) = CARG(0);
ARG(1) = CARG(1);
JUVIX_FUNCTION(juvix_function_plus, 2);
{
STACK_PUSH(ARG(1));
ARG(1) = ARG(0);
ARG(0) = juvix_zeroarg_closure_inc;
CALL(0, juvix_function_iterate, juvix_label_plus_1);
STACK_POP(ARG(1));
ASSIGN_CARGS(juvix_result, { CARG(juvix_closure_nargs) = ARG(1); });
TAIL_CALL_CLOSURE(juvix_result);
}
juvix_closure_mult:
ARG(0) = CARG(0);
ARG(1) = CARG(1);
JUVIX_FUNCTION(juvix_function_mult, 1);
{
DECL_TMP(0);
STACK_PUSH(ARG(1));
PREALLOC(
CLOSURE_HEAD_SIZE + 1, { STACK_PUSH(ARG(0)); },
{ STACK_POP(ARG(0)); });
ALLOC_CLOSURE(TMP(0), FUID_PLUS, LABEL_ADDR(juvix_closure_plus), 1, 1);
CLOSURE_ARG(TMP(0), 0) = ARG(0);
STACK_POP(ARG(1));
ARG(0) = TMP(0);
CALL(0, juvix_function_iterate, juvix_label_mult_1);
ASSIGN_CARGS(juvix_result,
{ CARG(juvix_closure_nargs) = make_smallint(0); });
TAIL_CALL_CLOSURE(juvix_result);
}
JUVIX_FUNCTION(juvix_function_exp, 1);
{
DECL_TMP(0);
STACK_PUSH(ARG(1));
PREALLOC(
CLOSURE_HEAD_SIZE + 1, { STACK_PUSH(ARG(0)); },
{ STACK_POP(ARG(0)); });
ALLOC_CLOSURE(TMP(0), 0, LABEL_ADDR(juvix_closure_mult), 1, 1);
CLOSURE_ARG(TMP(0), 0) = ARG(0);
STACK_POP(ARG(1));
ARG(0) = TMP(0);
CALL(0, juvix_function_iterate, juvix_label_exp_1);
ASSIGN_CARGS(juvix_result,
{ CARG(juvix_closure_nargs) = make_smallint(1); });
TAIL_CALL_CLOSURE(juvix_result);
}
JUVIX_FUNCTION(juvix_function_main, MAX_STACK_DELTA);
{
ARG(1) = make_smallint(7);
ARG(0) = make_smallint(3);
CALL(0, juvix_function_plus, juvix_label_1);
JUVIX_TRACE(juvix_result);
ARG(1) = make_smallint(7);
ARG(0) = make_smallint(3);
CALL(0, juvix_function_mult, juvix_label_2);
JUVIX_TRACE(juvix_result);
ARG(1) = make_smallint(7);
ARG(0) = make_smallint(3);
CALL(0, juvix_function_exp, juvix_label_3);
JUVIX_TRACE(juvix_result);
ARG(1) = make_smallint(10);
ARG(0) = make_smallint(3);
CALL(0, juvix_function_exp, juvix_label_4);
JUVIX_TRACE(juvix_result);
juvix_result = OBJ_VOID;
RETURN;
}
JUVIX_EPILOGUE;
return 0;
}