| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | #include "gwion_util.h" | ||
| 2 | #include "gwion_ast.h" | ||
| 3 | #include "gwion_env.h" | ||
| 4 | #include "vm.h" | ||
| 5 | #include "instr.h" | ||
| 6 | #include "gwion.h" | ||
| 7 | #include "object.h" | ||
| 8 | #include "operator.h" | ||
| 9 | #include "import.h" | ||
| 10 | #include "traverse.h" | ||
| 11 | #include "gwi.h" | ||
| 12 | |||
| 13 | 1 | static OP_CHECK(opck_sift) { | |
| 14 | 1 | Exp_Binary *bin = (Exp_Binary*)data; | |
| 15 | 1 | const Exp lhs = bin->lhs; | |
| 16 | 1 | Stmt stmt = mp_vector_at(lhs->d.exp_unary.code, struct Stmt_, 0); | |
| 17 | 1 | Stmt fst = mp_vector_at(stmt->d.stmt_flow.body->d.stmt_code.stmt_list, struct Stmt_, 0); | |
| 18 | 1 | const Symbol chuck = insert_symbol(env->gwion->st, "=>"); | |
| 19 | 1 | Exp next = new_exp_binary(env->gwion->mp, fst->d.stmt_exp.val, chuck, bin->rhs, bin->rhs->pos); | |
| 20 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
|
1 | CHECK_BN(traverse_exp(env, next)); // how do we free it? |
| 21 | 1 | fst->d.stmt_exp.val = next; | |
| 22 | 1 | const Exp exp = exp_self(bin); | |
| 23 | 1 | exp->exp_type = lhs->exp_type; | |
| 24 | 1 | exp->d.exp_unary.code = lhs->d.exp_unary.code; | |
| 25 | 1 | exp->type = lhs->type; | |
| 26 | 1 | exp->d.exp_unary.unary_type = lhs->d.exp_unary.unary_type; | |
| 27 | 1 | exp->d.exp_unary.op = lhs->d.exp_unary.op; | |
| 28 | 1 | return NULL; | |
| 29 | } | ||
| 30 | |||
| 31 | 4 | static OP_CHECK(opck_ctrl) { | |
| 32 | 4 | Exp_Binary *bin = (Exp_Binary*)data; | |
| 33 | 4 | MemPool mp = env->gwion->mp; | |
| 34 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 3 times.
|
4 | if(bin->lhs->exp_type == ae_exp_decl) |
| 35 | 1 | ERR_N(bin->lhs->pos, _("can't use declaration to start sift `|>` operator")); | |
| 36 | 3 | const Symbol chuck = insert_symbol(env->gwion->st, "=>"); | |
| 37 | 3 | Exp exp = exp_self(data); | |
| 38 | |||
| 39 | 3 | Exp func = cpy_exp(mp, exp); | |
| 40 | 3 | const Exp dot = new_exp_dot(mp, func->d.exp_binary.lhs, insert_symbol(env->gwion->st, "last"), func->pos); | |
| 41 | 3 | const Exp call = new_exp_call(mp, dot, NULL, func->pos); | |
| 42 | 3 | func->d.exp_binary.lhs = call; | |
| 43 | 3 | func->d.exp_binary.op = chuck; | |
| 44 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
|
3 | CHECK_BN(traverse_exp(env, func)); |
| 45 | 3 | struct Stmt_ one = { .d = { .stmt_exp = { .val = func }}, .stmt_type = ae_stmt_exp, .pos = func->pos }; | |
| 46 | |||
| 47 | 3 | Exp samp = new_prim_id(mp, insert_symbol(env->gwion->st, "samp"), func->pos); | |
| 48 | 3 | Exp _now = new_prim_id(mp, insert_symbol(env->gwion->st, "now"), func->pos); | |
| 49 | 3 | Exp time = new_exp_binary(mp, samp, chuck, _now, func->pos); | |
| 50 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
|
3 | CHECK_BN(traverse_exp(env, time)); |
| 51 | 3 | struct Stmt_ two = { .d = { .stmt_exp = { .val = time }}, .stmt_type = ae_stmt_exp, .pos = func->pos }; | |
| 52 | |||
| 53 | 3 | free_exp(mp, bin->lhs); | |
| 54 | 3 | free_exp(mp, bin->rhs); | |
| 55 | 3 | Stmt_List slist = new_mp_vector(mp, struct Stmt_, 2); | |
| 56 | 3 | mp_vector_set(slist, struct Stmt_, 0, one); | |
| 57 | 3 | mp_vector_set(slist, struct Stmt_, 1, two); | |
| 58 | 3 | const Stmt stmt = new_stmt_code(mp, slist, func->pos); | |
| 59 | |||
| 60 | 3 | const Exp cond = new_prim_id(mp, insert_symbol(env->gwion->st, "true"), func->pos); | |
| 61 | 3 | check_exp(env, cond); | |
| 62 | |||
| 63 | 3 | const Stmt_List code = new_mp_vector(mp, struct Stmt_, 1); | |
| 64 | 3 | mp_vector_set(code, struct Stmt_, 0, ((struct Stmt_) { | |
| 65 | .stmt_type = ae_stmt_while, | ||
| 66 | .d = { | ||
| 67 | .stmt_flow = { | ||
| 68 | .cond = cond, | ||
| 69 | .body = stmt | ||
| 70 | } | ||
| 71 | }, | ||
| 72 | .pos = func->pos | ||
| 73 | })); | ||
| 74 | 3 | exp->exp_type = ae_exp_unary; | |
| 75 | 3 | exp->d.exp_unary.unary_type = unary_code; | |
| 76 | 3 | exp->d.exp_unary.code = code; | |
| 77 | 3 | exp->d.exp_unary.op = insert_symbol(env->gwion->st, "spork"); | |
| 78 | 3 | return NULL; | |
| 79 | } | ||
| 80 | |||
| 81 | 638 | GWION_IMPORT(sift) { | |
| 82 | 638 | const Type sift = gwi_class_ini(gwi, "Sift", "Shred"); | |
| 83 | 638 | SET_FLAG(sift, abstract | ae_flag_final); | |
| 84 | 638 | GWI_BB(gwi_class_end(gwi)); | |
| 85 | |||
| 86 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 638 times.
|
638 | gwidoc(gwi, "This operator expands too\n" |
| 87 | "#!- spork {{\n" | ||
| 88 | "#!- while(true) {{\n" | ||
| 89 | "#!- lhs.last() => rhs;\n" | ||
| 90 | "#!- samp => now;\n" | ||
| 91 | "#!- }\n" | ||
| 92 | "#!- }"); | ||
| 93 | 638 | GWI_BB(gwi_oper_ini(gwi, "UGen", "function", "Sift")); | |
| 94 | 638 | GWI_BB(gwi_oper_add(gwi, opck_ctrl)); | |
| 95 | 638 | GWI_BB(gwi_oper_end(gwi, "|>", NULL)); | |
| 96 | |||
| 97 | 638 | GWI_BB(gwi_oper_ini(gwi, "Sift", "function", "Sift")); | |
| 98 | 638 | GWI_BB(gwi_oper_add(gwi, opck_sift)); | |
| 99 | 638 | GWI_BB(gwi_oper_end(gwi, "|>", NULL)); | |
| 100 | |||
| 101 | 638 | GWI_BB(gwi_oper_ini(gwi, "UGen", "funptr", "Sift")); | |
| 102 | 638 | GWI_BB(gwi_oper_add(gwi, opck_ctrl)); | |
| 103 | 638 | GWI_BB(gwi_oper_end(gwi, "|>", NULL)); | |
| 104 | |||
| 105 | 638 | GWI_BB(gwi_oper_ini(gwi, "Sift", "funptr", "Sift")); | |
| 106 | 638 | GWI_BB(gwi_oper_add(gwi, opck_sift)); | |
| 107 | 638 | GWI_BB(gwi_oper_end(gwi, "|>", NULL)); | |
| 108 | 638 | return GW_OK; | |
| 109 | } | ||
| 110 |