Value printing improved
This commit is contained in:
parent
857f8f3b52
commit
d9c0468729
1
Makefile
1
Makefile
@ -6,6 +6,7 @@ Obj= \
|
|||||||
context.o \
|
context.o \
|
||||||
environment.o \
|
environment.o \
|
||||||
errors.o \
|
errors.o \
|
||||||
|
format.o \
|
||||||
interpreter.o \
|
interpreter.o \
|
||||||
lexer.o \
|
lexer.o \
|
||||||
lines.o \
|
lines.o \
|
||||||
|
@ -6,9 +6,9 @@
|
|||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
#include <iostream>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <optional>
|
#include <optional>
|
||||||
#include <ostream>
|
|
||||||
#include <span>
|
#include <span>
|
||||||
#include <string_view>
|
#include <string_view>
|
||||||
#include <variant>
|
#include <variant>
|
||||||
@ -784,7 +784,7 @@ struct Block
|
|||||||
Result<Value> operator()(Interpreter &i, std::vector<Value> params);
|
Result<Value> operator()(Interpreter &i, std::vector<Value> params);
|
||||||
|
|
||||||
/// Indexing block
|
/// Indexing block
|
||||||
Result<Value> index(Interpreter &i, unsigned position);
|
Result<Value> index(Interpreter &i, unsigned position) const;
|
||||||
|
|
||||||
/// Count of elements in block
|
/// Count of elements in block
|
||||||
usize size() const;
|
usize size() const;
|
||||||
@ -845,7 +845,7 @@ struct Array
|
|||||||
std::vector<Value> elements;
|
std::vector<Value> elements;
|
||||||
|
|
||||||
/// Index element of an array
|
/// Index element of an array
|
||||||
Result<Value> index(Interpreter &i, unsigned position);
|
Result<Value> index(Interpreter &i, unsigned position) const;
|
||||||
|
|
||||||
/// Count of elements
|
/// Count of elements
|
||||||
usize size() const;
|
usize size() const;
|
||||||
@ -923,7 +923,7 @@ struct Value
|
|||||||
Result<Value> operator()(Interpreter &i, std::vector<Value> args);
|
Result<Value> operator()(Interpreter &i, std::vector<Value> args);
|
||||||
|
|
||||||
/// Index contained value if it can be called
|
/// Index contained value if it can be called
|
||||||
Result<Value> index(Interpreter &i, unsigned position);
|
Result<Value> index(Interpreter &i, unsigned position) const;
|
||||||
|
|
||||||
/// Return elements count of contained value if it can be measured
|
/// Return elements count of contained value if it can be measured
|
||||||
usize size() const;
|
usize size() const;
|
||||||
@ -1137,4 +1137,22 @@ template<> struct std::hash<Ast> { std::size_t operator()(Ast const&) cons
|
|||||||
template<> struct std::hash<Number> { std::size_t operator()(Number const&) const; };
|
template<> struct std::hash<Number> { std::size_t operator()(Number const&) const; };
|
||||||
template<> struct std::hash<Value> { std::size_t operator()(Value const&) const; };
|
template<> struct std::hash<Value> { std::size_t operator()(Value const&) const; };
|
||||||
|
|
||||||
|
struct Value_Formatter
|
||||||
|
{
|
||||||
|
enum Context
|
||||||
|
{
|
||||||
|
Free,
|
||||||
|
Inside_Block
|
||||||
|
};
|
||||||
|
|
||||||
|
Context context = Free;
|
||||||
|
unsigned indent = 0;
|
||||||
|
|
||||||
|
Value_Formatter nest(Context nested = Free) const;
|
||||||
|
|
||||||
|
Result<void> format(std::ostream& os, Interpreter &interpreter, Value const& value);
|
||||||
|
};
|
||||||
|
|
||||||
|
Result<std::string> format(Interpreter &i, Value const& value);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
70
src/format.cc
Normal file
70
src/format.cc
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
#include <musique.hh>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
|
Result<std::string> format(Interpreter &i, Value const& value)
|
||||||
|
{
|
||||||
|
std::stringstream ss;
|
||||||
|
Try(Value_Formatter{}.format(ss, i, value));
|
||||||
|
return ss.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
Value_Formatter Value_Formatter::nest(Context nested) const
|
||||||
|
{
|
||||||
|
return Value_Formatter { .context = nested, .indent = indent + 2 };
|
||||||
|
}
|
||||||
|
|
||||||
|
std::optional<Error> Value_Formatter::format(std::ostream& os, Interpreter &interpreter, Value const& value)
|
||||||
|
{
|
||||||
|
switch (value.type) {
|
||||||
|
break; case Value::Type::Nil:
|
||||||
|
os << "nil";
|
||||||
|
|
||||||
|
break; case Value::Type::Symbol:
|
||||||
|
os << value.s;
|
||||||
|
|
||||||
|
break; case Value::Type::Bool:
|
||||||
|
os << std::boolalpha << value.b;
|
||||||
|
|
||||||
|
break; case Value::Type::Number:
|
||||||
|
if (auto n = value.n.simplify(); n.den == 1) {
|
||||||
|
os << n.num << '/' << n.den;
|
||||||
|
} else {
|
||||||
|
os << n.num;
|
||||||
|
}
|
||||||
|
|
||||||
|
break; case Value::Type::Intrinsic:
|
||||||
|
for (auto const& [key, val] : Env::global->variables) {
|
||||||
|
if (val.type == Value::Type::Intrinsic && val.intr == value.intr) {
|
||||||
|
os << "<intrinsic '" << key << "'>";
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
os << "<intrinsic>";
|
||||||
|
|
||||||
|
|
||||||
|
break; case Value::Type::Array:
|
||||||
|
os << '[';
|
||||||
|
for (auto i = 0u; i < value.array.elements.size(); ++i) {
|
||||||
|
if (i > 0) {
|
||||||
|
os << "; ";
|
||||||
|
}
|
||||||
|
Try(nest(Inside_Block).format(os, interpreter, value.array.elements[i]));
|
||||||
|
}
|
||||||
|
os << ']';
|
||||||
|
|
||||||
|
break; case Value::Type::Block:
|
||||||
|
os << '[';
|
||||||
|
for (auto i = 0u; i < value.blk.size(); ++i) {
|
||||||
|
if (i > 0) {
|
||||||
|
os << "; ";
|
||||||
|
}
|
||||||
|
Try(nest(Inside_Block).format(os, interpreter, Try(value.index(interpreter, i))));
|
||||||
|
}
|
||||||
|
os << ']';
|
||||||
|
|
||||||
|
break; case Value::Type::Music:
|
||||||
|
os << value.chord;
|
||||||
|
}
|
||||||
|
|
||||||
|
return {};
|
||||||
|
}
|
@ -126,9 +126,9 @@ struct Runner
|
|||||||
midi_input_event_loop.detach();
|
midi_input_event_loop.detach();
|
||||||
}
|
}
|
||||||
|
|
||||||
Env::global->force_define("say", +[](Interpreter&, std::vector<Value> args) -> Result<Value> {
|
Env::global->force_define("say", +[](Interpreter &interpreter, std::vector<Value> args) -> Result<Value> {
|
||||||
for (auto it = args.begin(); it != args.end(); ++it) {
|
for (auto it = args.begin(); it != args.end(); ++it) {
|
||||||
std::cout << *it;
|
Try(format(interpreter, *it));
|
||||||
if (std::next(it) != args.end())
|
if (std::next(it) != args.end())
|
||||||
std::cout << ' ';
|
std::cout << ' ';
|
||||||
}
|
}
|
||||||
@ -162,7 +162,7 @@ struct Runner
|
|||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
if (auto result = Try(interpreter.eval(std::move(ast))); output && result.type != Value::Type::Nil) {
|
if (auto result = Try(interpreter.eval(std::move(ast))); output && result.type != Value::Type::Nil) {
|
||||||
std::cout << result << std::endl;
|
std::cout << Try(format(interpreter, result)) << std::endl;
|
||||||
}
|
}
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
@ -169,7 +169,7 @@ Result<Value> Value::operator()(Interpreter &i, std::vector<Value> args)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Result<Value> Value::index(Interpreter &i, unsigned position)
|
Result<Value> Value::index(Interpreter &i, unsigned position) const
|
||||||
{
|
{
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case Type::Block:
|
case Type::Block:
|
||||||
@ -361,7 +361,7 @@ static inline Result<void> guard_index(unsigned index, unsigned size)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TODO Add memoization
|
// TODO Add memoization
|
||||||
Result<Value> Block::index(Interpreter &i, unsigned position)
|
Result<Value> Block::index(Interpreter &i, unsigned position) const
|
||||||
{
|
{
|
||||||
assert(parameters.size() == 0, "cannot index into block with parameters (for now)");
|
assert(parameters.size() == 0, "cannot index into block with parameters (for now)");
|
||||||
if (body.type != Ast::Type::Sequence) {
|
if (body.type != Ast::Type::Sequence) {
|
||||||
@ -378,7 +378,7 @@ usize Block::size() const
|
|||||||
return body.type == Ast::Type::Sequence ? body.arguments.size() : 1;
|
return body.type == Ast::Type::Sequence ? body.arguments.size() : 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
Result<Value> Array::index(Interpreter &, unsigned position)
|
Result<Value> Array::index(Interpreter &, unsigned position) const
|
||||||
{
|
{
|
||||||
Try(guard_index(position, elements.size()));
|
Try(guard_index(position, elements.size()));
|
||||||
return elements[position];
|
return elements[position];
|
||||||
|
Loading…
Reference in New Issue
Block a user