diff --git a/musique/interpreter/builtin_functions.cc b/musique/interpreter/builtin_functions.cc index edc150b..62b07c3 100644 --- a/musique/interpreter/builtin_functions.cc +++ b/musique/interpreter/builtin_functions.cc @@ -72,7 +72,7 @@ static Result ctx_read_write_property(Interpreter &interpreter, std::vect using Member_Type = std::remove_cvref_t().*(Mem_Ptr))>; 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(args.front().data), "Ctx only holds numeric values"); @@ -130,7 +130,7 @@ static Result apply_numeric_transform(Interpreter &i, std::vector { if (args.size()) { if (auto number = get_if(args.front().data)) { - return Value::from((number->*Method)()); + return (number->*Method)(); } } @@ -142,7 +142,7 @@ static Result apply_numeric_transform(Interpreter &i, std::vector goto invalid_argument_type; } } - return Value::from(std::move(array)); + return array; invalid_argument_type: @@ -185,14 +185,14 @@ static Result builtin_range(Interpreter&, std::vector args) Array array; if constexpr (dir == Range_Direction::Up) { for (; start < stop; start += step) { - array.elements.push_back(Value::from(start)); + array.elements.push_back(start); } } else { 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 @@ -444,7 +444,7 @@ static Result builtin_primes(Interpreter&, std::vector args) // Better sieve could be Sieve of Atkin, but it's more complicated // so for now we would use Eratosthenes one. if (n_frac.simplify_inplace(); n_frac.num <= 1) { - return Value::from(Array{}); + return Array{}; } size_t n = n_frac.floor().as_int(); @@ -468,10 +468,10 @@ static Result builtin_primes(Interpreter&, std::vector args) for (uint i = 2; i < sieve.size() && results.size() != n; ++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 { @@ -613,14 +613,14 @@ static Result builtin_update(Interpreter &i, std::vector args) if (auto a = match(args)) { auto& [v, index, value] = *a; v.elements[index.as_int()] = std::move(std::move(value)); - return Value::from(std::move(v)); + return std::move(v); } if (auto a = match(args)) { 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()); - return Value::from(std::move(array)); + return array; } return guard.yield_error(); @@ -630,7 +630,7 @@ static Result builtin_update(Interpreter &i, std::vector args) static Result builtin_typeof(Interpreter&, std::vector args) { 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 @@ -638,7 +638,7 @@ static Result builtin_len(Interpreter &i, std::vector args) { if (args.size() == 1) { if (auto coll = get_if(args.front())) { - return Value::from(Number(coll->size())); + return Number(coll->size()); } } // TODO Add overload that tells length of array to error reporting @@ -648,7 +648,7 @@ static Result builtin_len(Interpreter &i, std::vector args) /// Join arguments into flat array static Result builtin_flat(Interpreter &i, std::vector args) { - return Value::from(Try(into_flat_array(i, std::move(args)))); + return Try(into_flat_array(i, std::move(args))); } /// Shuffle arguments @@ -657,7 +657,7 @@ static Result builtin_shuffle(Interpreter &i, std::vector args) static std::mt19937 rnd{std::random_device{}()}; auto array = Try(flatten(i, std::move(args))); std::shuffle(array.begin(), array.end(), rnd); - return Value::from(std::move(array)); + return array; } /// Permute arguments @@ -665,7 +665,7 @@ static Result builtin_permute(Interpreter &i, std::vector args) { auto array = Try(flatten(i, std::move(args))); std::next_permutation(array.begin(), array.end()); - return Value::from(std::move(array)); + return array; } /// Sort arguments @@ -673,7 +673,7 @@ static Result builtin_sort(Interpreter &i, std::vector args) { auto array = Try(flatten(i, std::move(args))); std::sort(array.begin(), array.end()); - return Value::from(std::move(array)); + return array; } /// Reverse arguments @@ -681,7 +681,7 @@ static Result builtin_reverse(Interpreter &i, std::vector args) { auto array = Try(flatten(i, std::move(args))); std::reverse(array.begin(), array.end()); - return Value::from(std::move(array)); + return array; } /// Get minimum of arguments @@ -724,10 +724,10 @@ static Result builtin_partition(Interpreter &i, std::vector args) tuple[Try(predicate(i, { std::move(value) })).truthy()].elements.push_back(std::move(value)); } - return Value::from(Array {{ - Value::from(std::move(tuple[true])), - Value::from(std::move(tuple[false])) - }}); + return Array {{ + std::move(tuple[true]), + std::move(tuple[false]) + }}; } /// Rotate arguments by n steps @@ -750,7 +750,7 @@ static Result builtin_rotate(Interpreter &i, std::vector args) offset = -offset % array.size(); std::rotate(array.rbegin(), array.rbegin() + offset, array.rend()); } - return Value::from(std::move(array)); + return array; } } @@ -770,7 +770,7 @@ static Result builtin_unique(Interpreter &i, std::vector args) result.push_back(std::move(el)); } } - return Value::from(std::move(result)); + return result; } /// Returns arguments with all successive copies eliminated @@ -787,16 +787,16 @@ static Result builtin_uniq(Interpreter &i, std::vector args) result.push_back(el); previous = std::move(el); } - return Value::from(std::move(result)); + return result; } static Result builtin_hash(Interpreter&, std::vector args) { - return Value::from(Number( + return Number( std::accumulate(args.cbegin(), args.cend(), size_t(0), [](size_t h, Value const& v) { return hash_combine(h, std::hash{}(v)); }) - )); + ); } /// Build chord from arguments @@ -804,7 +804,7 @@ static Result builtin_chord(Interpreter &i, std::vector args) { Chord chord; Try(create_chord(chord.notes, i, std::move(args))); - return Value::from(std::move(chord)); + return chord; } /// Send MIDI message Note On @@ -918,7 +918,7 @@ static Result builtin_mix(Interpreter &i, std::vector args) } } while (awaiting_containers); - return Value::from(std::move(result)); + return result; } /// Call operator. Calls first argument with remaining arguments diff --git a/musique/interpreter/builtin_operators.cc b/musique/interpreter/builtin_operators.cc index 0ba68fb..d5df891 100644 --- a/musique/interpreter/builtin_operators.cc +++ b/musique/interpreter/builtin_operators.cc @@ -17,7 +17,7 @@ static Result vectorize(auto &&operation, Interpreter &interpreter, Value array.elements.push_back( 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"); @@ -27,7 +27,7 @@ static Result vectorize(auto &&operation, Interpreter &interpreter, Value array.elements.push_back( 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 @@ -61,13 +61,13 @@ template static Result plus_minus_operator(Interpreter &interpreter, std::vector args) { if (args.empty()) { - return Value::from(Number(0)); + return Number(0); } Value init = args.front(); return algo::fold(std::span(args).subspan(1), std::move(init), [&interpreter](Value lhs, Value &rhs) -> Result { if (auto a = match(lhs, rhs)) { - return Value::from(std::apply(Binary_Operation{}, *a)); + return std::apply(Binary_Operation{}, *a); } auto result = symetric(lhs, rhs, [](Chord &lhs, Number rhs) { @@ -77,7 +77,7 @@ static Result plus_minus_operator(Interpreter &interpreter, std::vector binary_operator(Interpreter& interpreter, std::vector Result { if (auto a = match(lhs, rhs)) { - return wrap_value(std::apply(Binary_Operation{}, *a)); + return std::apply(Binary_Operation{}, *a); } if (holds_alternative(lhs) != holds_alternative(rhs)) { @@ -140,7 +140,7 @@ template static Result comparison_operator(Interpreter &interpreter, std::vector args) { 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(args.front()); @@ -153,32 +153,30 @@ static Result comparison_operator(Interpreter &interpreter, std::vector result; result.reserve(coll->size()); for (auto i = 0u; i < coll->size(); ++i) { - result.push_back( - Value::from( - Binary_Predicate{}( - Try(coll->index(interpreter, i)), - *element - ) - ) + result.push_back(Value( + Binary_Predicate{}( + Try(coll->index(interpreter, i)), + *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 multiplication_operator(Interpreter &i, std::vector args) { if (args.empty()) { - return Value::from(Number(1)); + return Number(1); } auto init = std::move(args.front()); return algo::fold(std::span(args).subspan(1), std::move(init), [&i](Value lhs, Value &rhs) -> Result { { auto result = symetric(lhs, rhs, [](Number lhs, Chord &rhs) { - return Value::from(Array { std::vector(lhs.floor().as_int(), Value::from(std::move(rhs))) }); + return Array { std::vector(lhs.floor().as_int(), std::move(rhs)) }; }); if (result.has_value()) { @@ -250,7 +248,7 @@ static constexpr auto Operators = std::array { result.push_back(Try(source.index(interpreter, *index))); } } - return Value::from(Array(std::move(result))); + return Array(std::move(result)); } return Error { @@ -290,7 +288,7 @@ static constexpr auto Operators = std::array { l.reserve(l.size() + r.size()); std::move(r.begin(), r.end(), std::back_inserter(l)); - return Value::from(lhs); + return lhs; } auto result = Array {}; @@ -300,7 +298,7 @@ static constexpr auto Operators = std::array { result.elements.push_back(Try(array.index(i, n))); } } - return Value::from(std::move(result)); + return result; } }, }; diff --git a/musique/interpreter/incoming_midi.hh b/musique/interpreter/incoming_midi.hh index 14d8482..b068f3d 100644 --- a/musique/interpreter/incoming_midi.hh +++ b/musique/interpreter/incoming_midi.hh @@ -32,11 +32,11 @@ struct Interpreter::Incoming_Midi_Callbacks target = [interpreter = &i, callback = &callback](T ...source_args) { if (!std::holds_alternative(callback->data)) { - std::vector args { Value::from(Number(source_args))... }; - args[1] = Value::from(Chord { { Note { + std::vector args { Number(source_args)... }; + args[1] = Note { .base = i32(std::get(args[1].data).num % 12), .octave = std::get(args[1].data).num / 12 - }}}); + }; auto result = (*callback)(*interpreter, std::move(args)); // We discard this since callback is running in another thread. (void) result; @@ -47,7 +47,7 @@ struct Interpreter::Incoming_Midi_Callbacks target = [interpreter = &i, callback = &callback](T ...source_args) { if (!std::holds_alternative(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. (void) result; } diff --git a/musique/interpreter/interpreter.cc b/musique/interpreter/interpreter.cc index 05fdba9..ac8f7dc 100644 --- a/musique/interpreter/interpreter.cc +++ b/musique/interpreter/interpreter.cc @@ -12,21 +12,21 @@ static inline void register_note_length_constants() { auto &global = *Env::global; - global.force_define("fn", Value::from(Number(1, 1))); - global.force_define("dfn", Value::from(Number(3, 2))); - global.force_define("hn", Value::from(Number(1, 2))); - global.force_define("dhn", Value::from(Number(3, 4))); - global.force_define("ddhn", Value::from(Number(7, 8))); - global.force_define("qn", Value::from(Number(1, 4))); - global.force_define("dqn", Value::from(Number(3, 8))); - global.force_define("ddqn", Value::from(Number(7, 16))); - global.force_define("en", Value::from(Number(1, 8))); - global.force_define("den", Value::from(Number(3, 16))); - global.force_define("dden", Value::from(Number(7, 32))); - global.force_define("sn", Value::from(Number(1, 16))); - global.force_define("dsn", Value::from(Number(3, 32))); - global.force_define("tn", Value::from(Number(1, 32))); - global.force_define("dtn", Value::from(Number(3, 64))); + global.force_define("fn", Number(1, 1)); + global.force_define("dfn", Number(3, 2)); + global.force_define("hn", Number(1, 2)); + global.force_define("dhn", Number(3, 4)); + global.force_define("ddhn", Number(7, 8)); + global.force_define("qn", Number(1, 4)); + global.force_define("dqn", Number(3, 8)); + global.force_define("ddqn", Number(7, 16)); + global.force_define("en", Number(1, 8)); + global.force_define("den", Number(3, 16)); + global.force_define("dden", Number(7, 32)); + global.force_define("sn", Number(1, 16)); + global.force_define("dsn", Number(3, 32)); + global.force_define("tn", Number(1, 32)); + global.force_define("dtn", Number(3, 64)); } Interpreter::Interpreter() @@ -60,7 +60,7 @@ Result Interpreter::eval(Ast &&ast) if (auto op = operators.find(std::string(ast.token.source.substr(1))); op != operators.end()) { return Value(op->second); } else { - return Value::from(std::move(ast.token.source).substr(1)); + return std::move(ast.token.source).substr(1); } } @@ -201,7 +201,7 @@ Result Interpreter::eval(Ast &&ast) block.context = env; block.body = std::move(ast.arguments.back()); - return Value::from(std::move(block)); + return block; } } diff --git a/musique/value/chord.cc b/musique/value/chord.cc index 738fb6c..abdcc64 100644 --- a/musique/value/chord.cc +++ b/musique/value/chord.cc @@ -111,18 +111,17 @@ Result Chord::operator()(Interpreter& interpreter, std::vector arg if (auto chord = get_if(arg)) { 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.push_back(std::move(*chord)); state = Waiting_For_Octave; } } - std::transform(current.begin(), current.end(), std::back_inserter(array), - [](Chord &c) { return Value::from(std::move(c)); }); + std::move(current.begin(), current.end(), std::back_inserter(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) diff --git a/musique/value/value.cc b/musique/value/value.cc index bf0a5e2..355bccd 100644 --- a/musique/value/value.cc +++ b/musique/value/value.cc @@ -14,99 +14,79 @@ Result Value::from(Token t) { switch (t.type) { case Token::Type::Numeric: - return Value::from(Try(Number::from(std::move(t)))); + return Try(Number::from(std::move(t))); case Token::Type::Symbol: - return Value::from(std::string(t.source)); + return t.source; case Token::Type::Keyword: - if (t.source == "false") return Value::from(false); - if (t.source == "nil") return Value{}; - if (t.source == "true") return Value::from(true); + if (t.source == "false") return false; + if (t.source == "nil") return {}; + if (t.source == "true") return true; unreachable(); case Token::Type::Chord: if (t.source.size() == 1 || (t.source.size() == 2 && t.source.back() == '#')) { auto maybe_note = Note::from(t.source); 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: 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 &&array) +Value::Value(std::vector &&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::operator()(Interpreter &i, std::vector args) const diff --git a/musique/value/value.hh b/musique/value/value.hh index 8cb83c0..61210b1 100644 --- a/musique/value/value.hh +++ b/musique/value/value.hh @@ -28,17 +28,17 @@ struct Value /// Create value holding provided boolean /// /// 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 - static Value from(Block &&l); ///< Create value of type block holding provided block - static Value from(Chord chord); ///< Create value of type music holding provided chord - static Value from(Note n); ///< Create value of type music holding provided note - static Value from(Number n); ///< Create value of type number holding provided number - static Value from(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 - static Value from(std::string_view s); ///< Create value of type symbol holding provided symbol - static Value from(std::vector &&array); ///< Create value of type array holding provided array + Value(Array &&array); ///< Create value of type array holding provided array + Value(Block &&l); ///< Create value of type block holding provided block + Value(Chord chord); ///< Create value of type music holding provided chord + Value(Note n); ///< Create value of type music holding provided note + Value(Number n); ///< Create value of type number holding provided number + Value(char const* s); ///< Create value of type symbol holding provided symbol + Value(std::string s); ///< Create value of type symbol holding provided symbol + Value(std::string_view s); ///< Create value of type symbol holding provided symbol + Value(std::vector &&array); ///< Create value of type array holding provided array // 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: @@ -107,12 +107,7 @@ template<> struct std::hash { std::size_t operator()(Value const&) cons template Result wrap_value(Result &&value) { - return std::move(value).map([](auto &&value) { return Value::from(std::move(value)); }); -} - -Value wrap_value(auto &&value) -{ - return Value::from(std::move(value)); + return std::move(value).map([](auto &&value) { return Value(std::move(value)); }); } template