18 for (std::size_t i = 0, end = types.size(); i < end; ++i)
29 auto displayArg = [](
const Typedef& td,
bool correct) {
32 std::cout <<
" -> " << (td.
variadic ?
"variadic " :
"")
33 << (correct ? termcolor::green : termcolor::magenta) << td.
name << termcolor::reset <<
" (" << arg_str <<
") ";
36 for (std::size_t i = 0, end = contract.
arguments.size(); i < end; ++i)
43 std::size_t bad_type = 0;
44 for (std::size_t j = i, args_end = args.size(); j < args_end; ++j)
52 displayArg(td,
false);
53 std::cout << termcolor::red << bad_type << termcolor::reset
54 <<
" argument" << (bad_type > 1 ?
"s" :
"") <<
" do not match";
64 displayArg(td,
false);
65 std::cout <<
"was of type " << termcolor::red << types_to_str[static_cast<std::size_t>(args[i].valueType())];
68 else if (i >= args.size())
70 displayArg(td,
false);
71 std::cout << termcolor::red <<
"was not provided";
76 std::cout << termcolor::reset <<
"\n";
80 [[noreturn]]
void generateError(std::string_view funcname,
const std::vector<Contract>& contracts,
const std::vector<Value>& args)
82 std::cout <<
"Function " << termcolor::blue << funcname << termcolor::reset <<
" expected ";
84 std::vector<Value> sanitizedArgs;
85 std::ranges::copy_if(args, std::back_inserter(sanitizedArgs), [](
const Value& value) ->
bool {
90 std::size_t min_argc = std::numeric_limits<std::size_t>::max(), max_argc = 0;
91 for (
const auto& [arguments] : contracts)
93 if (arguments.size() < min_argc)
94 min_argc = arguments.size();
95 if (arguments.size() > max_argc)
96 max_argc = arguments.size();
99 bool correct_argcount =
true;
101 if (min_argc != max_argc)
103 std::cout <<
"between "
104 << termcolor::yellow << min_argc << termcolor::reset
105 <<
" argument" << (min_argc > 1 ?
"s" :
"") <<
" and "
106 << termcolor::yellow << max_argc << termcolor::reset
107 <<
" argument" << (max_argc > 1 ?
"s" :
"");
109 if (sanitizedArgs.size() < min_argc || sanitizedArgs.size() > max_argc)
110 correct_argcount =
false;
114 std::cout << termcolor::yellow << min_argc << termcolor::reset
115 <<
" argument" << (min_argc > 1 ?
"s" :
"");
117 if (sanitizedArgs.size() != min_argc)
118 correct_argcount =
false;
121 if (!correct_argcount)
122 std::cout <<
" but got " << termcolor::red << sanitizedArgs.size();
124 std::cout << termcolor::reset <<
"\n";
127 for (std::size_t i = 1, end = contracts.size(); i < end; ++i)
129 std::cout <<
"Alternative " << (i + 1) <<
":\n";
ArkScript homemade exceptions.
A type error triggered when types don't match.
ValueType valueType() const noexcept
ARK_API void generateError(std::string_view funcname, const std::vector< Contract > &contracts, const std::vector< Value > &args)
Generate an error message based on a given set of types contracts provided argument list.
void displayContract(const Contract &contract, const std::vector< Value > &args)
std::string typeListToString(const std::vector< ValueType > &types)
@ Any
Used only for typechecking.
const std::array< std::string, 13 > types_to_str
A contract is a list of typed arguments that a function can follow.
std::vector< Typedef > arguments
A type definition within a contract.
std::vector< ValueType > types