Improved examples; multiplication = repeat operator
This commit is contained in:
parent
b9eb3f957d
commit
99482d4c7c
@ -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
10
examples/rick.mq
Normal 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;
|
||||||
|
];
|
@ -1,9 +1,13 @@
|
|||||||
bpm 150;
|
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));
|
|
||||||
|
@ -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
|
/// Plays sequentialy notes walking into arrays and evaluation blocks
|
||||||
///
|
///
|
||||||
/// @invariant default_action is play one
|
/// @invariant default_action is play one
|
||||||
@ -241,6 +233,12 @@ static inline Result<void> sequential_play(Interpreter &i, Value v)
|
|||||||
return {};
|
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>>
|
template<With_Index_Operator Container = std::vector<Value>>
|
||||||
static inline Result<Value> builtin_play(Interpreter &i, Container args)
|
static inline Result<Value> builtin_play(Interpreter &i, Container args)
|
||||||
{
|
{
|
||||||
|
@ -132,13 +132,45 @@ static Result<Value> comparison_operator(Interpreter&, std::vector<Value> args)
|
|||||||
return Value::from(Binary_Predicate{}(args.front(), args.back()));
|
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>;
|
using Operator_Entry = std::tuple<char const*, Intrinsic>;
|
||||||
|
|
||||||
/// Operators definition table
|
/// Operators definition table
|
||||||
static constexpr auto Operators = std::array {
|
static constexpr auto Operators = std::array {
|
||||||
Operator_Entry { "+", plus_minus_operator<std::plus<>> },
|
Operator_Entry { "+", plus_minus_operator<std::plus<>> },
|
||||||
Operator_Entry { "-", plus_minus_operator<std::minus<>> },
|
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 { "/", binary_operator<std::divides<>, '/'> },
|
||||||
|
|
||||||
Operator_Entry { "<", comparison_operator<std::less<>> },
|
Operator_Entry { "<", comparison_operator<std::less<>> },
|
||||||
|
Loading…
Reference in New Issue
Block a user