Eliminated unimplemented() that ware missing error reporting
This commit is contained in:
parent
3ed11fd33b
commit
1384e5f96e
@ -122,6 +122,22 @@ namespace errors
|
||||
std::string_view op;
|
||||
};
|
||||
|
||||
/// When user tries to use operator with wrong arity of arguments
|
||||
struct Wrong_Arity_Of
|
||||
{
|
||||
/// Type of operation
|
||||
enum Type { Operator, Function } type;
|
||||
|
||||
/// Name of operation
|
||||
std::string_view name;
|
||||
|
||||
/// Arity that was expected by given operation
|
||||
size_t expected_arity;
|
||||
|
||||
/// Arit that user provided
|
||||
size_t actual_arity;
|
||||
};
|
||||
|
||||
/// When user tried to call something that can't be called
|
||||
struct Not_Callable
|
||||
{
|
||||
@ -227,6 +243,7 @@ namespace errors
|
||||
Unexpected_Keyword,
|
||||
Unrecognized_Character,
|
||||
Unsupported_Types_For,
|
||||
Wrong_Arity_Of,
|
||||
internal::Unexpected_Token
|
||||
>;
|
||||
}
|
||||
|
@ -350,7 +350,14 @@ static Result<Value> builtin_sim(Interpreter &interpreter, std::vector<Value> ar
|
||||
return {};
|
||||
}
|
||||
|
||||
unimplemented();
|
||||
// Invalid type for sim function
|
||||
return errors::Unsupported_Types_For {
|
||||
.type = errors::Unsupported_Types_For::Function,
|
||||
.name = "sim",
|
||||
.possibilities = {
|
||||
"(music | array of music)+"
|
||||
},
|
||||
};
|
||||
}
|
||||
} append { interpreter };
|
||||
|
||||
@ -600,7 +607,17 @@ static Result<Value> builtin_try(Interpreter &interpreter, std::vector<Value> ar
|
||||
/// Update value inside of array
|
||||
static Result<Value> builtin_update(Interpreter &i, std::vector<Value> args)
|
||||
{
|
||||
assert(args.size() == 3, "Update requires 3 arguments"); // TODO(assert)
|
||||
auto const guard = Guard<1> {
|
||||
.name = "update",
|
||||
.possibilities = {
|
||||
"array index:number new_value"
|
||||
}
|
||||
};
|
||||
|
||||
if (args.size() != 3) {
|
||||
return guard.yield_error();
|
||||
}
|
||||
|
||||
using Eager_And_Number = Shape<Value::Type::Array, Value::Type::Number>;
|
||||
using Lazy_And_Number = Shape<Value::Type::Block, Value::Type::Number>;
|
||||
|
||||
@ -617,7 +634,7 @@ static Result<Value> builtin_update(Interpreter &i, std::vector<Value> args)
|
||||
return Value::from(std::move(array));
|
||||
}
|
||||
|
||||
unimplemented("Wrong shape of update function");
|
||||
return guard.yield_error();
|
||||
}
|
||||
|
||||
/// Return typeof variable
|
||||
|
@ -134,18 +134,19 @@ void unreachable(Location loc)
|
||||
std::ostream& operator<<(std::ostream& os, Error const& err)
|
||||
{
|
||||
std::string_view short_description = visit(Overloaded {
|
||||
[](errors::Operation_Requires_Midi_Connection const&) { return "Operation requires MIDI connection"; },
|
||||
[](errors::Missing_Variable const&) { return "Cannot find variable"; },
|
||||
[](errors::Expected_Expression_Separator_Before const&) { return "Missing semicolon"; },
|
||||
[](errors::Failed_Numeric_Parsing const&) { return "Failed to parse a number"; },
|
||||
[](errors::Literal_As_Identifier const&) { return "Literal used in place of an identifier"; },
|
||||
[](errors::Missing_Variable const&) { return "Cannot find variable"; },
|
||||
[](errors::Not_Callable const&) { return "Value not callable"; },
|
||||
[](errors::Operation_Requires_Midi_Connection const&) { return "Operation requires MIDI connection"; },
|
||||
[](errors::Out_Of_Range const&) { return "Index out of range"; },
|
||||
[](errors::Undefined_Operator const&) { return "Undefined operator"; },
|
||||
[](errors::Unexpected_Empty_Source const&) { return "Unexpected end of file"; },
|
||||
[](errors::Unexpected_Keyword const&) { return "Unexpected keyword"; },
|
||||
[](errors::Unrecognized_Character const&) { return "Unrecognized character"; },
|
||||
[](errors::Wrong_Arity_Of const&) { return "Different arity then expected"; },
|
||||
[](errors::internal::Unexpected_Token const&) { return "Unexpected token"; },
|
||||
[](errors::Expected_Expression_Separator_Before const&) { return "Missing semicolon"; },
|
||||
[](errors::Literal_As_Identifier const&) { return "Literal used in place of an identifier"; },
|
||||
[](errors::Out_Of_Range const&) { return "Index out of range"; },
|
||||
[](errors::Arithmetic const& err) {
|
||||
switch (err.type) {
|
||||
case errors::Arithmetic::Division_By_Zero: return "Division by 0";
|
||||
@ -296,6 +297,19 @@ std::ostream& operator<<(std::ostream& os, Error const& err)
|
||||
}
|
||||
},
|
||||
|
||||
[&](errors::Wrong_Arity_Of const& err) {
|
||||
switch (err.type) {
|
||||
break; case errors::Wrong_Arity_Of::Function:
|
||||
os << "Function " << err.name << " expects " << err.expected_arity << " arguments but you provided " << err.actual_arity << "\n";
|
||||
os << "\n";
|
||||
print_error_line(loc);
|
||||
break; case errors::Wrong_Arity_Of::Operator:
|
||||
os << "Operator " << err.name << " expects " << err.expected_arity << " arguments but you provided " << err.actual_arity << "\n";
|
||||
os << "\n";
|
||||
print_error_line(loc);
|
||||
}
|
||||
},
|
||||
|
||||
[&](errors::Not_Callable const& err) {
|
||||
os << "Value of type " << err.type << " cannot be called.\n";
|
||||
os << "\n";
|
||||
@ -403,7 +417,11 @@ std::ostream& operator<<(std::ostream& os, Error const& err)
|
||||
}
|
||||
},
|
||||
|
||||
[&](errors::Unexpected_Keyword const&) { unimplemented(); },
|
||||
[&](errors::Unexpected_Keyword const& err) {
|
||||
os << "Keyword " << err.keyword << " should not be used here\n\n";
|
||||
|
||||
print_error_line(loc);
|
||||
},
|
||||
}, err.details);
|
||||
|
||||
return os;
|
||||
|
@ -201,10 +201,9 @@ Result<Value> Interpreter::eval(Ast &&ast)
|
||||
block.body = std::move(ast.arguments.back());
|
||||
return Value::from(std::move(block));
|
||||
}
|
||||
|
||||
default:
|
||||
unimplemented();
|
||||
}
|
||||
|
||||
unreachable();
|
||||
}
|
||||
|
||||
void Interpreter::enter_scope()
|
||||
|
@ -332,7 +332,7 @@ Result<Number> Number::pow(Number n) const
|
||||
// Hard case, we raise this to fractional power.
|
||||
// Essentialy finding n.den root of (x to n.num power).
|
||||
// We need to protect ourselfs against even roots of negative numbers.
|
||||
unimplemented();
|
||||
unimplemented("nth root calculation is not implemented yet");
|
||||
}
|
||||
|
||||
std::size_t std::hash<Number>::operator()(Number const& value) const
|
||||
|
@ -310,6 +310,18 @@ Result<Ast> Parser::parse_atomic_expression()
|
||||
return ast;
|
||||
}
|
||||
|
||||
break; case Token::Type::Operator:
|
||||
return Error {
|
||||
.details = errors::Wrong_Arity_Of {
|
||||
.type = errors::Wrong_Arity_Of::Operator,
|
||||
.name = peek()->source,
|
||||
.expected_arity = 2, // TODO This should be resolved based on operator
|
||||
.actual_arity = 0,
|
||||
},
|
||||
.location = peek()->location,
|
||||
};
|
||||
|
||||
|
||||
default:
|
||||
return Error {
|
||||
.details = errors::internal::Unexpected_Token {
|
||||
|
21
src/value.cc
21
src/value.cc
@ -71,7 +71,7 @@ Result<Value> Value::from(Token t)
|
||||
return Value::from(Chord::from(t.source));
|
||||
|
||||
default:
|
||||
unimplemented();
|
||||
unreachable();
|
||||
}
|
||||
}
|
||||
|
||||
@ -329,7 +329,16 @@ Result<Value> Block::operator()(Interpreter &i, std::vector<Value> arguments)
|
||||
auto old_scope = std::exchange(i.env, context);
|
||||
i.enter_scope();
|
||||
|
||||
assert(parameters.size() == arguments.size(), "wrong number of arguments");
|
||||
if (parameters.size() != arguments.size()) {
|
||||
return errors::Wrong_Arity_Of {
|
||||
.type = errors::Wrong_Arity_Of::Function,
|
||||
// TODO Let user defined functions have name of their first assigment (Zig like)
|
||||
// or from place of definition like <block at file:line:column>
|
||||
.name = "<block>",
|
||||
.expected_arity = parameters.size(),
|
||||
.actual_arity = arguments.size(),
|
||||
};
|
||||
}
|
||||
|
||||
for (usize j = 0; j < parameters.size(); ++j) {
|
||||
i.env->force_define(parameters[j], std::move(arguments[j]));
|
||||
@ -521,7 +530,13 @@ Result<Value> Chord::operator()(Interpreter&, std::vector<Value> args)
|
||||
continue;
|
||||
|
||||
default:
|
||||
unimplemented();
|
||||
return errors::Unsupported_Types_For {
|
||||
.type = errors::Unsupported_Types_For::Function,
|
||||
.name = "note creation",
|
||||
.possibilities = {
|
||||
"(note:music [octave:number [duration:number]])+"
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user