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 |