Value printing improved
This commit is contained in:
parent
857f8f3b52
commit
d9c0468729
1
Makefile
1
Makefile
@ -6,6 +6,7 @@ Obj= \
|
||||
context.o \
|
||||
environment.o \
|
||||
errors.o \
|
||||
format.o \
|
||||
interpreter.o \
|
||||
lexer.o \
|
||||
lines.o \
|
||||
|
@ -6,9 +6,9 @@
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
#include <functional>
|
||||
#include <iostream>
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
#include <ostream>
|
||||
#include <span>
|
||||
#include <string_view>
|
||||
#include <variant>
|
||||
@ -784,7 +784,7 @@ struct Block
|
||||
Result<Value> operator()(Interpreter &i, std::vector<Value> params);
|
||||
|
||||
/// Indexing block
|
||||
Result<Value> index(Interpreter &i, unsigned position);
|
||||
Result<Value> index(Interpreter &i, unsigned position) const;
|
||||
|
||||
/// Count of elements in block
|
||||
usize size() const;
|
||||
@ -845,7 +845,7 @@ struct Array
|
||||
std::vector<Value> elements;
|
||||
|
||||
/// Index element of an array
|
||||
Result<Value> index(Interpreter &i, unsigned position);
|
||||
Result<Value> index(Interpreter &i, unsigned position) const;
|
||||
|
||||
/// Count of elements
|
||||
usize size() const;
|
||||
@ -923,7 +923,7 @@ struct Value
|
||||
Result<Value> operator()(Interpreter &i, std::vector<Value> args);
|
||||
|
||||
/// 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
|
||||
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<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
|
||||
|
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();
|
||||
}
|
||||
|
||||
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) {
|
||||
std::cout << *it;
|
||||
Try(format(interpreter, *it));
|
||||
if (std::next(it) != args.end())
|
||||
std::cout << ' ';
|
||||
}
|
||||
@ -162,7 +162,7 @@ struct Runner
|
||||
return {};
|
||||
}
|
||||
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 {};
|
||||
}
|
||||
|
@ -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) {
|
||||
case Type::Block:
|
||||
@ -361,7 +361,7 @@ static inline Result<void> guard_index(unsigned index, unsigned size)
|
||||
}
|
||||
|
||||
// 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)");
|
||||
if (body.type != Ast::Type::Sequence) {
|
||||
@ -378,7 +378,7 @@ usize Block::size() const
|
||||
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()));
|
||||
return elements[position];
|
||||
|
Loading…
Reference in New Issue
Block a user