From 28cf9ff211b0f561202d78d20f5bdc6b5f96ab6c Mon Sep 17 00:00:00 2001 From: =?utf8?q?J=C3=A9r=C3=A9mie=20Astor?= Date: Thu, 21 Apr 2022 16:49:33 +0200 Subject: [PATCH] lfo ctrl (#248) * :art: Add lfo ctrl * :white_check_mark: Add lfo ctrl testing --- include/lang_private.h | 2 ++ src/lib/ctrl.c | 68 +++++++++++++++++++++++++++++++++++++++++ src/lib/engine.c | 28 ++--------------- src/lib/locale.c | 40 ++++++++++++++++++++++++ tests/tree/ctrl_test.gw | 12 ++++++++ 5 files changed, 124 insertions(+), 26 deletions(-) create mode 100644 src/lib/ctrl.c create mode 100644 src/lib/locale.c create mode 100644 tests/tree/ctrl_test.gw diff --git a/include/lang_private.h b/include/lang_private.h index c60954a6..ef049894 100644 --- a/include/lang_private.h +++ b/include/lang_private.h @@ -19,4 +19,6 @@ ANN m_bool import_ref(const Gwi gwi); ANN m_bool import_deep_equal(const Gwi gwi); ANN m_bool import_dict(const Gwi gwi); ANN m_bool import_gack(const Gwi gwi); +ANN m_bool import_ctrl(const Gwi gwi); +ANN m_bool import_locale(const Gwi gwi); #endif diff --git a/src/lib/ctrl.c b/src/lib/ctrl.c new file mode 100644 index 00000000..42006ae1 --- /dev/null +++ b/src/lib/ctrl.c @@ -0,0 +1,68 @@ +#include "gwion_util.h" +#include "gwion_ast.h" +#include "gwion_env.h" +#include "vm.h" +#include "instr.h" +#include "gwion.h" +#include "object.h" +#include "operator.h" +#include "import.h" +#include "traverse.h" +#include "gwi.h" + +static OP_CHECK(opck_ctrl) { + + Exp_Binary *bin = (Exp_Binary*)data; + MemPool mp = env->gwion->mp; + + const Symbol chuck = insert_symbol(env->gwion->st, "=>"); + Exp exp = exp_self(data); + Exp func = cpy_exp(mp, exp); // set operator + +const Exp dot = new_exp_dot(mp, func->d.exp_binary.lhs, insert_symbol(env->gwion->st, "last"), func->pos); +const Exp call = new_exp_call(mp, dot, NULL, func->pos); +func->d.exp_binary.lhs = call; + + func->d.exp_binary.op = chuck; +traverse_exp(env, func); + + struct Stmt_ one = { .d = { .stmt_exp = { .val = func }}, .stmt_type = ae_stmt_exp, .pos = func->pos }; + + Exp samp = new_prim_id(mp, insert_symbol(env->gwion->st, "samp"), func->pos); + Exp _now = new_prim_id(mp, insert_symbol(env->gwion->st, "now"), func->pos); + Exp time = new_exp_binary(mp, samp, chuck, _now, func->pos); + struct Stmt_ two = { .d = { .stmt_exp = { .val = time }}, .stmt_type = ae_stmt_exp, .pos = func->pos }; +traverse_exp(env, time); + + Stmt_List slist = new_mp_vector(mp, sizeof(struct Stmt_), 2); + mp_vector_set(slist, struct Stmt_, 0, one); + mp_vector_set(slist, struct Stmt_, 1, two); + + const Stmt stmt = new_stmt_code(mp, slist, func->pos); + free_exp(mp, bin->lhs); + free_exp(mp, bin->rhs); + + const Exp cond = new_prim_id(mp, insert_symbol(env->gwion->st, "true"), func->pos); + check_exp(env, cond); + + const Stmt loop = new_stmt_flow(mp, ae_stmt_while, cond, stmt, false, func->pos); + exp->exp_type = ae_exp_unary; + exp->d.exp_unary.unary_type = unary_code; + exp->d.exp_unary.code = loop; + exp->d.exp_unary.op = insert_symbol(env->gwion->st, "spork"); + return env->gwion->type[et_shred]; +} + +GWION_IMPORT(ctrl) { + gwidoc(gwi, "This operator expands too\n" + "#!- spork {{\n" + "#!- while(true) {{\n" + "#!- lhs.last() => rhs;\n" + "#!- samp => now;\n" + "#!- }\n" + "#!- }"); + GWI_BB(gwi_oper_ini(gwi, "UGen", "@function", NULL)) + GWI_BB(gwi_oper_add(gwi, opck_ctrl)) + GWI_BB(gwi_oper_end(gwi, "|>", NULL)) + return GW_OK; +} diff --git a/src/lib/engine.c b/src/lib/engine.c index adab057e..93f3d6c8 100644 --- a/src/lib/engine.c +++ b/src/lib/engine.c @@ -56,28 +56,6 @@ static FREEARG(freearg_release) { vector_release(&v); } -ANN static m_float basic_locale(m_str str) { - const char base = str[0]; - str++; - if(base < 'A' || base > 'G') return -1; - m_int bnote = base - 'A'; - if(*str == '#') { bnote++; str++; } - else if(*str == 'b') { bnote--; str++; } - char *remainder; - const long octave = strtol(str, &remainder, 10); - if(*remainder != '\0') return -1; - const int note = bnote + 12 * octave + 21; - return (pow(2, (note - 69) / 12.0) * 440.0); -} - -static SFUN(BasicLocale) { - const M_Object arg = *(M_Object*)MEM(0); - const m_float ret = basic_locale(STRING(arg)); - if(ret == -1.0) - handle(shred, "invalid value for locale"); - *(m_float*)RETURN = ret; -} - ANN static m_bool import_core_libs(const Gwi gwi) { gwidoc(gwi, "one type to rule them all."); const Type t_class = gwi_mk_type(gwi, "Class", SZ_INT, NULL); @@ -203,12 +181,10 @@ ANN static m_bool import_core_libs(const Gwi gwi) { GWI_BB(import_dict(gwi)); GWI_BB(import_gack(gwi)); + GWI_BB(import_ctrl(gwi)); + GWI_BB(import_locale(gwi)); -gwi_func_ini(gwi, "float", "BasicLocale"); -gwi_func_arg(gwi, "string", "str"); -gwi_func_end(gwi, BasicLocale, ae_flag_none); - // seemed need at a point to ease liking gwi_enum_ini(gwi, "@hidden_enum"); gwi_enum_add(gwi, "@hidden_enum", 0); diff --git a/src/lib/locale.c b/src/lib/locale.c new file mode 100644 index 00000000..712e3f14 --- /dev/null +++ b/src/lib/locale.c @@ -0,0 +1,40 @@ +#include "gwion_util.h" +#include "gwion_ast.h" +#include "gwion_env.h" +#include "vm.h" +#include "instr.h" +#include "gwion.h" +#include "object.h" +#include "operator.h" +#include "import.h" +#include "gwi.h" + +ANN static m_float basic_locale(m_str str) { + const char base = str[0]; + str++; + if(base < 'A' || base > 'G') return -1; + m_int bnote = base - 'A'; + if(*str == '#') { bnote++; str++; } + else if(*str == 'b') { bnote--; str++; } + char *remainder; + const long octave = strtol(str, &remainder, 10); + if(*remainder != '\0') return -1; + const int note = bnote + 12 * octave + 21; + return (pow(2, (note - 69) / 12.0) * 440.0); +} + +static SFUN(BasicLocale) { + const M_Object arg = *(M_Object*)MEM(0); + const m_float ret = basic_locale(STRING(arg)); + if(ret == -1.0) + handle(shred, "invalid value for locale"); + *(m_float*)RETURN = ret; +} + +GWION_IMPORT(locale) { + gwidoc(gwi, "Definition of the basic locale"); + GWI_BB(gwi_func_ini(gwi, "float", "BasicLocale")); + GWI_BB(gwi_func_arg(gwi, "string", "str")); + GWI_BB(gwi_func_end(gwi, BasicLocale, ae_flag_none)); + return GW_OK; +} diff --git a/tests/tree/ctrl_test.gw b/tests/tree/ctrl_test.gw new file mode 100644 index 00000000..323bd4f7 --- /dev/null +++ b/tests/tree/ctrl_test.gw @@ -0,0 +1,12 @@ +#! [contains] 1.0 + +fun void foo(float f) { + <<< f >>>; +} + +var Impulse imp ~> dac; +imp |> foo; +1 => imp.next; + +2::samp => now; + -- 2.43.0