Moved from Value::from constructor to Value constructor

This commit is contained in:
Robert Bendun 2022-09-25 00:40:49 +02:00
parent 6a98178690
commit 5a7c204ceb
7 changed files with 112 additions and 140 deletions

View File

@ -72,7 +72,7 @@ static Result<Value> ctx_read_write_property(Interpreter &interpreter, std::vect
using Member_Type = std::remove_cvref_t<decltype(std::declval<Context>().*(Mem_Ptr))>; using Member_Type = std::remove_cvref_t<decltype(std::declval<Context>().*(Mem_Ptr))>;
if (args.size() == 0) { if (args.size() == 0) {
return Value::from(Number(interpreter.context_stack.back().*(Mem_Ptr))); return Number(interpreter.context_stack.back().*(Mem_Ptr));
} }
assert(std::holds_alternative<Number>(args.front().data), "Ctx only holds numeric values"); assert(std::holds_alternative<Number>(args.front().data), "Ctx only holds numeric values");
@ -130,7 +130,7 @@ static Result<Value> apply_numeric_transform(Interpreter &i, std::vector<Value>
{ {
if (args.size()) { if (args.size()) {
if (auto number = get_if<Number>(args.front().data)) { if (auto number = get_if<Number>(args.front().data)) {
return Value::from((number->*Method)()); return (number->*Method)();
} }
} }
@ -142,7 +142,7 @@ static Result<Value> apply_numeric_transform(Interpreter &i, std::vector<Value>
goto invalid_argument_type; goto invalid_argument_type;
} }
} }
return Value::from(std::move(array)); return array;
invalid_argument_type: invalid_argument_type:
@ -185,14 +185,14 @@ static Result<Value> builtin_range(Interpreter&, std::vector<Value> args)
Array array; Array array;
if constexpr (dir == Range_Direction::Up) { if constexpr (dir == Range_Direction::Up) {
for (; start < stop; start += step) { for (; start < stop; start += step) {
array.elements.push_back(Value::from(start)); array.elements.push_back(start);
} }
} else { } else {
for (; start < stop; start += step) { for (; start < stop; start += step) {
array.elements.push_back(Value::from(stop - start - Number(1))); array.elements.push_back(stop - start - Number(1));
} }
} }
return Value::from(std::move(array)); return array;
} }
/// Send MIDI Program Change message /// Send MIDI Program Change message
@ -444,7 +444,7 @@ static Result<Value> builtin_primes(Interpreter&, std::vector<Value> args)
// Better sieve could be Sieve of Atkin, but it's more complicated // Better sieve could be Sieve of Atkin, but it's more complicated
// so for now we would use Eratosthenes one. // so for now we would use Eratosthenes one.
if (n_frac.simplify_inplace(); n_frac.num <= 1) { if (n_frac.simplify_inplace(); n_frac.num <= 1) {
return Value::from(Array{}); return Array{};
} }
size_t n = n_frac.floor().as_int(); size_t n = n_frac.floor().as_int();
@ -468,10 +468,10 @@ static Result<Value> builtin_primes(Interpreter&, std::vector<Value> args)
for (uint i = 2; i < sieve.size() && results.size() != n; ++i) { for (uint i = 2; i < sieve.size() && results.size() != n; ++i) {
if (!sieve[i]) { if (!sieve[i]) {
results.push_back(Value::from(Number(i))); results.push_back(Number(i));
} }
} }
return Value::from(Array(std::move(results))); return results;
} }
return Error { return Error {
@ -613,14 +613,14 @@ static Result<Value> builtin_update(Interpreter &i, std::vector<Value> args)
if (auto a = match<Array, Number, Value>(args)) { if (auto a = match<Array, Number, Value>(args)) {
auto& [v, index, value] = *a; auto& [v, index, value] = *a;
v.elements[index.as_int()] = std::move(std::move(value)); v.elements[index.as_int()] = std::move(std::move(value));
return Value::from(std::move(v)); return std::move(v);
} }
if (auto a = match<Block, Number, Value>(args)) { if (auto a = match<Block, Number, Value>(args)) {
auto& [v, index, value] = *a; auto& [v, index, value] = *a;
auto array = Try(flatten(i, { Value::from(std::move(v)) })); auto array = Try(flatten(i, { std::move(v) }));
array[index.as_int()] = std::move(args.back()); array[index.as_int()] = std::move(args.back());
return Value::from(std::move(array)); return array;
} }
return guard.yield_error(); return guard.yield_error();
@ -630,7 +630,7 @@ static Result<Value> builtin_update(Interpreter &i, std::vector<Value> args)
static Result<Value> builtin_typeof(Interpreter&, std::vector<Value> args) static Result<Value> builtin_typeof(Interpreter&, std::vector<Value> args)
{ {
assert(args.size() == 1, "typeof expects only one argument"); // TODO(assert) assert(args.size() == 1, "typeof expects only one argument"); // TODO(assert)
return Value::from(Symbol(type_name(args.front()))); return Symbol(type_name(args.front()));
} }
/// Return length of container or set/get default length to play /// Return length of container or set/get default length to play
@ -638,7 +638,7 @@ static Result<Value> builtin_len(Interpreter &i, std::vector<Value> args)
{ {
if (args.size() == 1) { if (args.size() == 1) {
if (auto coll = get_if<Collection>(args.front())) { if (auto coll = get_if<Collection>(args.front())) {
return Value::from(Number(coll->size())); return Number(coll->size());
} }
} }
// TODO Add overload that tells length of array to error reporting // TODO Add overload that tells length of array to error reporting
@ -648,7 +648,7 @@ static Result<Value> builtin_len(Interpreter &i, std::vector<Value> args)
/// Join arguments into flat array /// Join arguments into flat array
static Result<Value> builtin_flat(Interpreter &i, std::vector<Value> args) static Result<Value> builtin_flat(Interpreter &i, std::vector<Value> args)
{ {
return Value::from(Try(into_flat_array(i, std::move(args)))); return Try(into_flat_array(i, std::move(args)));
} }
/// Shuffle arguments /// Shuffle arguments
@ -657,7 +657,7 @@ static Result<Value> builtin_shuffle(Interpreter &i, std::vector<Value> args)
static std::mt19937 rnd{std::random_device{}()}; static std::mt19937 rnd{std::random_device{}()};
auto array = Try(flatten(i, std::move(args))); auto array = Try(flatten(i, std::move(args)));
std::shuffle(array.begin(), array.end(), rnd); std::shuffle(array.begin(), array.end(), rnd);
return Value::from(std::move(array)); return array;
} }
/// Permute arguments /// Permute arguments
@ -665,7 +665,7 @@ static Result<Value> builtin_permute(Interpreter &i, std::vector<Value> args)
{ {
auto array = Try(flatten(i, std::move(args))); auto array = Try(flatten(i, std::move(args)));
std::next_permutation(array.begin(), array.end()); std::next_permutation(array.begin(), array.end());
return Value::from(std::move(array)); return array;
} }
/// Sort arguments /// Sort arguments
@ -673,7 +673,7 @@ static Result<Value> builtin_sort(Interpreter &i, std::vector<Value> args)
{ {
auto array = Try(flatten(i, std::move(args))); auto array = Try(flatten(i, std::move(args)));
std::sort(array.begin(), array.end()); std::sort(array.begin(), array.end());
return Value::from(std::move(array)); return array;
} }
/// Reverse arguments /// Reverse arguments
@ -681,7 +681,7 @@ static Result<Value> builtin_reverse(Interpreter &i, std::vector<Value> args)
{ {
auto array = Try(flatten(i, std::move(args))); auto array = Try(flatten(i, std::move(args)));
std::reverse(array.begin(), array.end()); std::reverse(array.begin(), array.end());
return Value::from(std::move(array)); return array;
} }
/// Get minimum of arguments /// Get minimum of arguments
@ -724,10 +724,10 @@ static Result<Value> builtin_partition(Interpreter &i, std::vector<Value> args)
tuple[Try(predicate(i, { std::move(value) })).truthy()].elements.push_back(std::move(value)); tuple[Try(predicate(i, { std::move(value) })).truthy()].elements.push_back(std::move(value));
} }
return Value::from(Array {{ return Array {{
Value::from(std::move(tuple[true])), std::move(tuple[true]),
Value::from(std::move(tuple[false])) std::move(tuple[false])
}}); }};
} }
/// Rotate arguments by n steps /// Rotate arguments by n steps
@ -750,7 +750,7 @@ static Result<Value> builtin_rotate(Interpreter &i, std::vector<Value> args)
offset = -offset % array.size(); offset = -offset % array.size();
std::rotate(array.rbegin(), array.rbegin() + offset, array.rend()); std::rotate(array.rbegin(), array.rbegin() + offset, array.rend());
} }
return Value::from(std::move(array)); return array;
} }
} }
@ -770,7 +770,7 @@ static Result<Value> builtin_unique(Interpreter &i, std::vector<Value> args)
result.push_back(std::move(el)); result.push_back(std::move(el));
} }
} }
return Value::from(std::move(result)); return result;
} }
/// Returns arguments with all successive copies eliminated /// Returns arguments with all successive copies eliminated
@ -787,16 +787,16 @@ static Result<Value> builtin_uniq(Interpreter &i, std::vector<Value> args)
result.push_back(el); result.push_back(el);
previous = std::move(el); previous = std::move(el);
} }
return Value::from(std::move(result)); return result;
} }
static Result<Value> builtin_hash(Interpreter&, std::vector<Value> args) static Result<Value> builtin_hash(Interpreter&, std::vector<Value> args)
{ {
return Value::from(Number( return Number(
std::accumulate(args.cbegin(), args.cend(), size_t(0), [](size_t h, Value const& v) { std::accumulate(args.cbegin(), args.cend(), size_t(0), [](size_t h, Value const& v) {
return hash_combine(h, std::hash<Value>{}(v)); return hash_combine(h, std::hash<Value>{}(v));
}) })
)); );
} }
/// Build chord from arguments /// Build chord from arguments
@ -804,7 +804,7 @@ static Result<Value> builtin_chord(Interpreter &i, std::vector<Value> args)
{ {
Chord chord; Chord chord;
Try(create_chord(chord.notes, i, std::move(args))); Try(create_chord(chord.notes, i, std::move(args)));
return Value::from(std::move(chord)); return chord;
} }
/// Send MIDI message Note On /// Send MIDI message Note On
@ -918,7 +918,7 @@ static Result<Value> builtin_mix(Interpreter &i, std::vector<Value> args)
} }
} while (awaiting_containers); } while (awaiting_containers);
return Value::from(std::move(result)); return result;
} }
/// Call operator. Calls first argument with remaining arguments /// Call operator. Calls first argument with remaining arguments

View File

@ -17,7 +17,7 @@ static Result<Value> vectorize(auto &&operation, Interpreter &interpreter, Value
array.elements.push_back( array.elements.push_back(
Try(operation(interpreter, { Try(lhs_coll->index(interpreter, i)), rhs }))); Try(operation(interpreter, { Try(lhs_coll->index(interpreter, i)), rhs })));
} }
return Value::from(std::move(array)); return array;
} }
assert(rhs_coll != nullptr, "Trying to vectorize two non-collections"); assert(rhs_coll != nullptr, "Trying to vectorize two non-collections");
@ -27,7 +27,7 @@ static Result<Value> vectorize(auto &&operation, Interpreter &interpreter, Value
array.elements.push_back( array.elements.push_back(
Try(operation(interpreter, { lhs, Try(rhs_coll->index(interpreter, i)) }))); Try(operation(interpreter, { lhs, Try(rhs_coll->index(interpreter, i)) })));
} }
return Value::from(std::move(array)); return array;
} }
/// Intrinsic implementation primitive to ease operation vectorization /// Intrinsic implementation primitive to ease operation vectorization
@ -61,13 +61,13 @@ template<typename Binary_Operation>
static Result<Value> plus_minus_operator(Interpreter &interpreter, std::vector<Value> args) static Result<Value> plus_minus_operator(Interpreter &interpreter, std::vector<Value> args)
{ {
if (args.empty()) { if (args.empty()) {
return Value::from(Number(0)); return Number(0);
} }
Value init = args.front(); Value init = args.front();
return algo::fold(std::span(args).subspan(1), std::move(init), [&interpreter](Value lhs, Value &rhs) -> Result<Value> { return algo::fold(std::span(args).subspan(1), std::move(init), [&interpreter](Value lhs, Value &rhs) -> Result<Value> {
if (auto a = match<Number, Number>(lhs, rhs)) { if (auto a = match<Number, Number>(lhs, rhs)) {
return Value::from(std::apply(Binary_Operation{}, *a)); return std::apply(Binary_Operation{}, *a);
} }
auto result = symetric<Chord, Number>(lhs, rhs, [](Chord &lhs, Number rhs) { auto result = symetric<Chord, Number>(lhs, rhs, [](Chord &lhs, Number rhs) {
@ -77,7 +77,7 @@ static Result<Value> plus_minus_operator(Interpreter &interpreter, std::vector<V
note.simplify_inplace(); note.simplify_inplace();
} }
} }
return Value::from(lhs); return lhs;
}); });
if (result.has_value()) { if (result.has_value()) {
return *std::move(result); return *std::move(result);
@ -110,13 +110,13 @@ static Result<Value> binary_operator(Interpreter& interpreter, std::vector<Value
{ {
static constexpr char Name[] = { Chars..., '\0' }; static constexpr char Name[] = { Chars..., '\0' };
if (args.empty()) { if (args.empty()) {
return Value::from(Number(1)); return Number(1);
} }
auto init = std::move(args.front()); auto init = std::move(args.front());
return algo::fold(std::span(args).subspan(1), std::move(init), return algo::fold(std::span(args).subspan(1), std::move(init),
[&interpreter](Value lhs, Value &rhs) -> Result<Value> { [&interpreter](Value lhs, Value &rhs) -> Result<Value> {
if (auto a = match<Number, Number>(lhs, rhs)) { if (auto a = match<Number, Number>(lhs, rhs)) {
return wrap_value(std::apply(Binary_Operation{}, *a)); return std::apply(Binary_Operation{}, *a);
} }
if (holds_alternative<Collection>(lhs) != holds_alternative<Collection>(rhs)) { if (holds_alternative<Collection>(lhs) != holds_alternative<Collection>(rhs)) {
@ -140,7 +140,7 @@ template<typename Binary_Predicate>
static Result<Value> comparison_operator(Interpreter &interpreter, std::vector<Value> args) static Result<Value> comparison_operator(Interpreter &interpreter, std::vector<Value> args)
{ {
if (args.size() != 2) { if (args.size() != 2) {
return Value::from(algo::pairwise_all(std::move(args), Binary_Predicate{})); return algo::pairwise_all(std::move(args), Binary_Predicate{});
} }
auto lhs_coll = get_if<Collection>(args.front()); auto lhs_coll = get_if<Collection>(args.front());
@ -153,32 +153,30 @@ static Result<Value> comparison_operator(Interpreter &interpreter, std::vector<V
std::vector<Value> result; std::vector<Value> result;
result.reserve(coll->size()); result.reserve(coll->size());
for (auto i = 0u; i < coll->size(); ++i) { for (auto i = 0u; i < coll->size(); ++i) {
result.push_back( result.push_back(Value(
Value::from( Binary_Predicate{}(
Binary_Predicate{}( Try(coll->index(interpreter, i)),
Try(coll->index(interpreter, i)), *element
*element ))
)
)
); );
} }
return Value::from(Array { std::move(result) }); return Array { std::move(result) };
} }
return Value::from(Binary_Predicate{}(std::move(args.front()), std::move(args.back()))); return Binary_Predicate{}(std::move(args.front()), std::move(args.back()));
} }
static Result<Value> multiplication_operator(Interpreter &i, std::vector<Value> args) static Result<Value> multiplication_operator(Interpreter &i, std::vector<Value> args)
{ {
if (args.empty()) { if (args.empty()) {
return Value::from(Number(1)); return Number(1);
} }
auto init = std::move(args.front()); auto init = std::move(args.front());
return algo::fold(std::span(args).subspan(1), std::move(init), [&i](Value lhs, Value &rhs) -> Result<Value> { return algo::fold(std::span(args).subspan(1), std::move(init), [&i](Value lhs, Value &rhs) -> Result<Value> {
{ {
auto result = symetric<Number, Chord>(lhs, rhs, [](Number lhs, Chord &rhs) { auto result = symetric<Number, Chord>(lhs, rhs, [](Number lhs, Chord &rhs) {
return Value::from(Array { std::vector<Value>(lhs.floor().as_int(), Value::from(std::move(rhs))) }); return Array { std::vector<Value>(lhs.floor().as_int(), std::move(rhs)) };
}); });
if (result.has_value()) { if (result.has_value()) {
@ -250,7 +248,7 @@ static constexpr auto Operators = std::array {
result.push_back(Try(source.index(interpreter, *index))); result.push_back(Try(source.index(interpreter, *index)));
} }
} }
return Value::from(Array(std::move(result))); return Array(std::move(result));
} }
return Error { return Error {
@ -290,7 +288,7 @@ static constexpr auto Operators = std::array {
l.reserve(l.size() + r.size()); l.reserve(l.size() + r.size());
std::move(r.begin(), r.end(), std::back_inserter(l)); std::move(r.begin(), r.end(), std::back_inserter(l));
return Value::from(lhs); return lhs;
} }
auto result = Array {}; auto result = Array {};
@ -300,7 +298,7 @@ static constexpr auto Operators = std::array {
result.elements.push_back(Try(array.index(i, n))); result.elements.push_back(Try(array.index(i, n)));
} }
} }
return Value::from(std::move(result)); return result;
} }
}, },
}; };

View File

@ -32,11 +32,11 @@ struct Interpreter::Incoming_Midi_Callbacks
target = [interpreter = &i, callback = &callback](T ...source_args) target = [interpreter = &i, callback = &callback](T ...source_args)
{ {
if (!std::holds_alternative<Nil>(callback->data)) { if (!std::holds_alternative<Nil>(callback->data)) {
std::vector<Value> args { Value::from(Number(source_args))... }; std::vector<Value> args { Number(source_args)... };
args[1] = Value::from(Chord { { Note { args[1] = Note {
.base = i32(std::get<Number>(args[1].data).num % 12), .base = i32(std::get<Number>(args[1].data).num % 12),
.octave = std::get<Number>(args[1].data).num / 12 .octave = std::get<Number>(args[1].data).num / 12
}}}); };
auto result = (*callback)(*interpreter, std::move(args)); auto result = (*callback)(*interpreter, std::move(args));
// We discard this since callback is running in another thread. // We discard this since callback is running in another thread.
(void) result; (void) result;
@ -47,7 +47,7 @@ struct Interpreter::Incoming_Midi_Callbacks
target = [interpreter = &i, callback = &callback](T ...source_args) target = [interpreter = &i, callback = &callback](T ...source_args)
{ {
if (!std::holds_alternative<Nil>(callback->data)) { if (!std::holds_alternative<Nil>(callback->data)) {
auto result = (*callback)(*interpreter, { Value::from(Number(source_args))... }); auto result = (*callback)(*interpreter, { Number(source_args)... });
// We discard this since callback is running in another thread. // We discard this since callback is running in another thread.
(void) result; (void) result;
} }

View File

@ -12,21 +12,21 @@
static inline void register_note_length_constants() static inline void register_note_length_constants()
{ {
auto &global = *Env::global; auto &global = *Env::global;
global.force_define("fn", Value::from(Number(1, 1))); global.force_define("fn", Number(1, 1));
global.force_define("dfn", Value::from(Number(3, 2))); global.force_define("dfn", Number(3, 2));
global.force_define("hn", Value::from(Number(1, 2))); global.force_define("hn", Number(1, 2));
global.force_define("dhn", Value::from(Number(3, 4))); global.force_define("dhn", Number(3, 4));
global.force_define("ddhn", Value::from(Number(7, 8))); global.force_define("ddhn", Number(7, 8));
global.force_define("qn", Value::from(Number(1, 4))); global.force_define("qn", Number(1, 4));
global.force_define("dqn", Value::from(Number(3, 8))); global.force_define("dqn", Number(3, 8));
global.force_define("ddqn", Value::from(Number(7, 16))); global.force_define("ddqn", Number(7, 16));
global.force_define("en", Value::from(Number(1, 8))); global.force_define("en", Number(1, 8));
global.force_define("den", Value::from(Number(3, 16))); global.force_define("den", Number(3, 16));
global.force_define("dden", Value::from(Number(7, 32))); global.force_define("dden", Number(7, 32));
global.force_define("sn", Value::from(Number(1, 16))); global.force_define("sn", Number(1, 16));
global.force_define("dsn", Value::from(Number(3, 32))); global.force_define("dsn", Number(3, 32));
global.force_define("tn", Value::from(Number(1, 32))); global.force_define("tn", Number(1, 32));
global.force_define("dtn", Value::from(Number(3, 64))); global.force_define("dtn", Number(3, 64));
} }
Interpreter::Interpreter() Interpreter::Interpreter()
@ -60,7 +60,7 @@ Result<Value> Interpreter::eval(Ast &&ast)
if (auto op = operators.find(std::string(ast.token.source.substr(1))); op != operators.end()) { if (auto op = operators.find(std::string(ast.token.source.substr(1))); op != operators.end()) {
return Value(op->second); return Value(op->second);
} else { } else {
return Value::from(std::move(ast.token.source).substr(1)); return std::move(ast.token.source).substr(1);
} }
} }
@ -201,7 +201,7 @@ Result<Value> Interpreter::eval(Ast &&ast)
block.context = env; block.context = env;
block.body = std::move(ast.arguments.back()); block.body = std::move(ast.arguments.back());
return Value::from(std::move(block)); return block;
} }
} }

View File

@ -111,18 +111,17 @@ Result<Value> Chord::operator()(Interpreter& interpreter, std::vector<Value> arg
if (auto chord = get_if<Chord>(arg)) { if (auto chord = get_if<Chord>(arg)) {
std::transform(current.begin(), current.end(), std::back_inserter(array), std::transform(current.begin(), current.end(), std::back_inserter(array),
[](Chord &c) { return Value::from(std::move(c)); }); [](Chord &c) { return std::move(c); });
current.clear(); current.clear();
current.push_back(std::move(*chord)); current.push_back(std::move(*chord));
state = Waiting_For_Octave; state = Waiting_For_Octave;
} }
} }
std::transform(current.begin(), current.end(), std::back_inserter(array), std::move(current.begin(), current.end(), std::back_inserter(array));
[](Chord &c) { return Value::from(std::move(c)); });
assert(not array.empty(), "At least *this should be in this array"); assert(not array.empty(), "At least *this should be in this array");
return Value::from(Array{std::move(array)}); return array;
} }
std::ostream& operator<<(std::ostream& os, Chord const& chord) std::ostream& operator<<(std::ostream& os, Chord const& chord)

View File

@ -14,99 +14,79 @@ Result<Value> Value::from(Token t)
{ {
switch (t.type) { switch (t.type) {
case Token::Type::Numeric: case Token::Type::Numeric:
return Value::from(Try(Number::from(std::move(t)))); return Try(Number::from(std::move(t)));
case Token::Type::Symbol: case Token::Type::Symbol:
return Value::from(std::string(t.source)); return t.source;
case Token::Type::Keyword: case Token::Type::Keyword:
if (t.source == "false") return Value::from(false); if (t.source == "false") return false;
if (t.source == "nil") return Value{}; if (t.source == "nil") return {};
if (t.source == "true") return Value::from(true); if (t.source == "true") return true;
unreachable(); unreachable();
case Token::Type::Chord: case Token::Type::Chord:
if (t.source.size() == 1 || (t.source.size() == 2 && t.source.back() == '#')) { if (t.source.size() == 1 || (t.source.size() == 2 && t.source.back() == '#')) {
auto maybe_note = Note::from(t.source); auto maybe_note = Note::from(t.source);
assert(maybe_note.has_value(), "Somehow parser passed invalid note literal"); assert(maybe_note.has_value(), "Somehow parser passed invalid note literal");
return Value::from(*maybe_note); return *maybe_note;
} }
return Value::from(Chord::from(t.source)); return Chord::from(t.source);
default: default:
unreachable(); unreachable();
} }
} }
Value Value::from(Explicit_Bool b) Value::Value(Explicit_Bool b)
: data{b.value}
{ {
Value v;
v.data = b.value;
return v;
} }
Value Value::from(Number n) Value::Value(Number n)
: data(n.simplify())
{ {
Value v;
v.data = std::move(n).simplify();
return v;
} }
Value Value::from(std::string s) Value::Value(std::string s)
: data(Symbol(std::move(s)))
{ {
Value v;
v.data = Symbol(std::move(s));
return v;
} }
Value Value::from(std::string_view s) Value::Value(std::string_view s)
: data(Symbol(s))
{ {
Value v;
v.data = Symbol(std::move(s));
return v;
} }
Value Value::from(char const* s) Value::Value(char const* s)
: data(Symbol(s))
{ {
Value v;
v.data = Symbol(s);
return v;
} }
Value Value::from(Block &&block) Value::Value(Block &&block)
: data{std::move(block)}
{ {
Value v;
v.data = std::move(block);
return v;
} }
Value Value::from(Array &&array) Value::Value(Array &&array)
: data{std::move(array)}
{ {
Value v;
v.data = std::move(array);
return v;
} }
Value Value::from(std::vector<Value> &&array) Value::Value(std::vector<Value> &&array)
: data(Array(std::move(array)))
{ {
Value v;
v.data = Array(std::move(array));
return v;
} }
Value Value::from(Note n) Value::Value(Note n)
: data(Chord(n))
{ {
Value v;
v.data = Chord(n);
return v;
} }
Value Value::from(Chord chord) Value::Value(Chord chord)
: data(std::move(chord))
{ {
Value v;
v.data = std::move(chord);
return v;
} }
Result<Value> Value::operator()(Interpreter &i, std::vector<Value> args) const Result<Value> Value::operator()(Interpreter &i, std::vector<Value> args) const

View File

@ -28,17 +28,17 @@ struct Value
/// Create value holding provided boolean /// Create value holding provided boolean
/// ///
/// Using Explicit_Bool to prevent from implicit casts /// Using Explicit_Bool to prevent from implicit casts
static Value from(Explicit_Bool b); Value(Explicit_Bool b);
static Value from(Array &&array); ///< Create value of type array holding provided array Value(Array &&array); ///< Create value of type array holding provided array
static Value from(Block &&l); ///< Create value of type block holding provided block Value(Block &&l); ///< Create value of type block holding provided block
static Value from(Chord chord); ///< Create value of type music holding provided chord Value(Chord chord); ///< Create value of type music holding provided chord
static Value from(Note n); ///< Create value of type music holding provided note Value(Note n); ///< Create value of type music holding provided note
static Value from(Number n); ///< Create value of type number holding provided number Value(Number n); ///< Create value of type number holding provided number
static Value from(char const* s); ///< Create value of type symbol holding provided symbol Value(char const* s); ///< Create value of type symbol holding provided symbol
static Value from(std::string s); ///< Create value of type symbol holding provided symbol Value(std::string s); ///< Create value of type symbol holding provided symbol
static Value from(std::string_view s); ///< Create value of type symbol holding provided symbol Value(std::string_view s); ///< Create value of type symbol holding provided symbol
static Value from(std::vector<Value> &&array); ///< Create value of type array holding provided array Value(std::vector<Value> &&array); ///< Create value of type array holding provided array
// TODO Most strings should not be allocated by Value, but reference to string allocated previously // TODO Most strings should not be allocated by Value, but reference to string allocated previously
// Wrapper for std::string is needed that will allocate only when needed, middle ground between: // Wrapper for std::string is needed that will allocate only when needed, middle ground between:
@ -107,12 +107,7 @@ template<> struct std::hash<Value> { std::size_t operator()(Value const&) cons
template<typename T> template<typename T>
Result<Value> wrap_value(Result<T> &&value) Result<Value> wrap_value(Result<T> &&value)
{ {
return std::move(value).map([](auto &&value) { return Value::from(std::move(value)); }); return std::move(value).map([](auto &&value) { return Value(std::move(value)); });
}
Value wrap_value(auto &&value)
{
return Value::from(std::move(value));
} }
template<typename Desired> template<typename Desired>