Improved examples; multiplication = repeat operator

This commit is contained in:
Robert Bendun 2022-08-21 17:29:37 +02:00
parent b9eb3f957d
commit 99482d4c7c
5 changed files with 60 additions and 24 deletions

View File

@ -1,8 +0,0 @@
oct 2;
bpm 120;
par (f#) (c# 4 (1/2));
par (g#) [d# 4 (1/2); (g# 3 (5/16)];
par (f) (d# 4 (1/2));
par (a#) [f 4 (1/2); a# 4 (1/16); f# 4 (1/16); f 4 (1/16); c# 4 (1/16)];
par (f#) (c# 4 (1/2));
par (g#) (d# 4 (1/2));

10
examples/rick.mq Normal file
View File

@ -0,0 +1,10 @@
bpm 120; len hn; oct 2;
play [
f# & c# 4;
par g# [d# 4; g# 3 (5/16)];
f & d# 4;
par a# [oct 4; f; len sn; a#; f#; f; c#];
f# & c# 4;
g# & d# 4;
];

View File

@ -1,9 +1,13 @@
bpm 150;
len sn;
play [
oct 3; 4 * h; h 3 en;
oct 3; 6 * h; h 3 en;
oct 4; 7 * e;
oct 4; 6 * d;
oct 3; a; a; 5 * h;
oct 3; 7 * h;
oct 4; 2 * d; 4 * (h 3); h 3 en
];
play (h 3 (1/16)) (h 3 (1/16)) (h 3 (1/16)) (h 3 (1/16)) (h 3 (1/8));
play (h 3 (1/16)) (h 3 (1/16)) (h 3 (1/16)) (h 3 (1/16)) (h 3 (1/16)) (h 3 (1/16)) (h 3 (1/8));
play (e 4 (1/16)) (e 4 (1/16)) (e 4 (1/16)) (e 4 (1/16)) (e 4 (1/16)) (e 4 (1/16)) (e 4 (1/8));
play (d 4 (1/16)) (d 4 (1/16)) (d 4 (1/16)) (d 4 (1/16)) (d 4 (1/16)) (d 4 (1/16)) (d 4 (1/8));
play (a 3 (1/16)) (a 3 (1/16)) (h 3 (1/16)) (h 3 (1/16)) (h 3 (1/16)) (h 3 (1/16)) (h 3 (1/8));
play (h 3 (1/16)) (h 3 (1/16)) (h 3 (1/16)) (h 3 (1/16)) (h 3 (1/16)) (h 3 (1/16)) (h 3 (1/8));
play (d 4 (1/16)) (d 4 (1/16)) (h 3 (1/16)) (h 3 (1/16)) (h 3 (1/16)) (h 3 (1/16)) (h 3 (1/8));

View File

@ -210,14 +210,6 @@ static auto builtin_program_change(Interpreter &i, std::vector<Value> args) -> R
};
}
static Result<void> action_play(Interpreter &i, Value v)
{
if (v.type == Value::Type::Music) {
Try(i.play(std::move(v).chord));
}
return {};
}
/// Plays sequentialy notes walking into arrays and evaluation blocks
///
/// @invariant default_action is play one
@ -241,6 +233,12 @@ static inline Result<void> sequential_play(Interpreter &i, Value v)
return {};
}
static Result<void> action_play(Interpreter &i, Value v)
{
Try(sequential_play(i, std::move(v)));
return {};
}
template<With_Index_Operator Container = std::vector<Value>>
static inline Result<Value> builtin_play(Interpreter &i, Container args)
{

View File

@ -132,13 +132,45 @@ static Result<Value> comparison_operator(Interpreter&, std::vector<Value> args)
return Value::from(Binary_Predicate{}(args.front(), args.back()));
}
static Result<Value> multiplication_operator(Interpreter &i, std::vector<Value> args)
{
using MN = Shape<Value::Type::Music, Value::Type::Number>;
using NM = Shape<Value::Type::Number, Value::Type::Music>;
Number repeat; Chord what; bool typechecked = false;
// TODO add automatic symetry resolution for cases like this
if (NM::typecheck(args)) { typechecked = true; std::tie(repeat, what) = NM::move_from(args); }
else if (MN::typecheck(args)) { typechecked = true; std::tie(what, repeat) = MN::move_from(args); }
if (typechecked) {
return Value::from(Array {
.elements = std::vector<Value>(
repeat.floor().as_int(), Value::from(std::move(what))
)
});
}
// If binary_operator returns an error that lists all possible overloads
// of this operator we must inject overloads that we provided above
auto result = binary_operator<std::multiplies<>, '*'>(i, std::move(args));
if (!result.has_value()) {
auto &details = result.error().details;
if (auto p = std::get_if<errors::Unsupported_Types_For>(&details)) {
p->possibilities.push_back("(repeat: number, what: music) -> array of music");
p->possibilities.push_back("(what: music, repeat: number) -> array of music");
}
}
return result;
}
using Operator_Entry = std::tuple<char const*, Intrinsic>;
/// Operators definition table
static constexpr auto Operators = std::array {
Operator_Entry { "+", plus_minus_operator<std::plus<>> },
Operator_Entry { "-", plus_minus_operator<std::minus<>> },
Operator_Entry { "*", binary_operator<std::multiplies<>, '*'> },
Operator_Entry { "*", multiplication_operator },
Operator_Entry { "/", binary_operator<std::divides<>, '/'> },
Operator_Entry { "<", comparison_operator<std::less<>> },