diff --git a/Makefile b/Makefile index 6832998..1bc47cb 100644 --- a/Makefile +++ b/Makefile @@ -2,8 +2,8 @@ MAKEFLAGS="-j $(grep -c ^processor /proc/cpuinfo)" CXXFLAGS=-std=c++20 -Wall -Wextra -O2 -Werror=switch CPPFLAGS=-Ilib/expected/ -Ilib/ut/ -Isrc/ -Obj=bin/lexer.o \ - bin/errors.o \ +Obj=bin/errors.o \ + bin/lexer.o \ bin/unicode.o all: bin/musique bin/unit-tests diff --git a/src/errors.cc b/src/errors.cc index 3dffd26..75dcf06 100644 --- a/src/errors.cc +++ b/src/errors.cc @@ -20,9 +20,30 @@ std::ostream& operator<<(std::ostream& os, Error const& err) return os << "end of file\n"; case errors::Unrecognized_Character: - return os << "unrecognized charater 0x" << std::hex << err.invalid_character - << "(char: '" << utf8::Print(err.invalid_character) << "')\n"; + if (err.invalid_character) { + return os << "unrecognized charater U+" << std::hex << err.invalid_character + << " (char: '" << utf8::Print{err.invalid_character} << "')\n"; + } else { + return os << "unrecognized character\n"; + } } return os << "unrecognized error type\n"; } + +Error errors::unrecognized_character(u32 invalid_character) +{ + Error err; + err.type = errors::Unrecognized_Character; + err.invalid_character = invalid_character; + return err; +} + +Error errors::unrecognized_character(u32 invalid_character, Location location) +{ + Error err; + err.type = errors::Unrecognized_Character; + err.invalid_character = invalid_character; + err.location = std::move(location); + return err; +} diff --git a/src/lexer.cc b/src/lexer.cc index 5eb3321..bc3d3b8 100644 --- a/src/lexer.cc +++ b/src/lexer.cc @@ -40,7 +40,7 @@ auto Lexer::next_token() -> Result return { Token::Type::Numeric, finish(), token_location }; } - return errors::Unrecognized_Character; + return errors::unrecognized_character(peek(), token_location); } auto Lexer::peek() const -> u32 diff --git a/src/main.cc b/src/main.cc index a0c9835..fc6fec5 100644 --- a/src/main.cc +++ b/src/main.cc @@ -9,6 +9,7 @@ std::string_view Source = R"musique( tl::expected Main() { Lexer lexer{Source}; + lexer.location.filename = "example.mq"; for (;;) { auto token = Try(lexer.next_token()); @@ -20,7 +21,7 @@ int main() { auto result = Main(); if (not result.has_value()) { - std::cerr << result.error() << std::endl; + std::cerr << result.error() << std::flush; return 1; } } diff --git a/src/musique.hh b/src/musique.hh index 6af9eab..89eebe3 100644 --- a/src/musique.hh +++ b/src/musique.hh @@ -61,18 +61,33 @@ struct Error bool operator==(errors::Type); }; +namespace errors +{ + Error unrecognized_character(u32 invalid_character); + Error unrecognized_character(u32 invalid_character, Location location); +} + + template struct Result : tl::expected { + using Storage = tl::expected; + constexpr Result() = default; - constexpr Result(errors::Type error) : tl::expected(tl::unexpected(Error { error })) + constexpr Result(errors::Type error) + : Storage(tl::unexpected(Error { error })) + { + } + + constexpr Result(Error error) + : Storage(tl::unexpected(std::move(error))) { } template constexpr Result(Args&& ...args) - : tl::expected( T{ std::forward(args)... } ) + : Storage( T{ std::forward(args)... } ) { } };