chord function

This commit is contained in:
Robert Bendun 2022-05-25 02:13:35 +02:00
parent 80bc4c039c
commit 611007a888
2 changed files with 56 additions and 0 deletions

View File

@ -16,6 +16,9 @@ Ustawianie oktawy i długości, a następnie modyfikacja
(c 8 fn) 4 zmienia oktawę na 4
(c 8 fn) 4 qn zmienia oktawę na 4 i długość na 1/4
Stworzenie akordu
c123 == chord[c; c#; d; d#]
Arytmetyka
(aktualnie brak wsparcia dla precedensji operatorów)
3 * (4 * 12 - 8)
@ -100,3 +103,6 @@ len : block -> number
play : music... -> nil
odtwarza sekwencyjnie otrzymane wartości muzyczne
chord : (collection | music)... -> music
tworzy akord z przekazanych wartości muzycznych

View File

@ -74,6 +74,50 @@ static inline void register_note_length_constants()
global.force_define("dtn", Value::from(Number(3, 64)));
}
template<typename T>
concept With_Index_Method = requires (T t, Interpreter interpreter, usize position) {
{ t.index(interpreter, position) } -> std::convertible_to<Result<Value>>;
};
template<typename T>
concept With_Index_Operator = requires (T t, unsigned i) {
{ t[i] } -> std::convertible_to<Value>;
};
template<typename T>
concept Iterable = (With_Index_Method<T> || With_Index_Operator<T>) && requires (T const t) {
{ t.size() } -> std::convertible_to<usize>;
};
template<Iterable T>
static inline Result<void> create_chord(std::vector<Note> &chord, Interpreter &interpreter, T args)
{
for (auto i = 0u; i < args.size(); ++i) {
Value arg;
if constexpr (With_Index_Method<T>) {
arg = Try(args.index(interpreter, i));
} else {
arg = std::move(args[i]);
}
switch (arg.type) {
case Value::Type::Array:
case Value::Type::Block:
Try(create_chord(chord, interpreter, std::move(arg)));
break;
case Value::Type::Music:
std::move(arg.chord.notes.begin(), arg.chord.notes.end(), std::back_inserter(chord));
break;
default:
assert(false, "this type is not supported inside chord");
}
}
return {};
}
Interpreter::Interpreter()
{
{ // Context initialization
@ -139,6 +183,12 @@ Interpreter::Interpreter()
return Value::from(std::move(array));
});
global.force_define("chord", +[](Interpreter &i, std::vector<Value> args) -> Result<Value> {
Chord chord;
Try(create_chord(chord.notes, i, std::move(args)));
return Value::from(std::move(chord));
});
operators["+"] = binary_operator<std::plus<>>();
operators["-"] = binary_operator<std::minus<>>();
operators["*"] = binary_operator<std::multiplies<>>();