#include "ast/ast.hpp" #include "lexer/lexer.hpp" #include "parser/parser.hpp" #include #include #include #include #include void check_parser_errors(const std::vector&); namespace { std::string demangle(const char* name) { int status = 0; std::unique_ptr demangled( abi::__cxa_demangle(name, nullptr, nullptr, &status), &std::free ); return (status == 0 && demangled) ? demangled.get() : name; } template T* cast_impl(Base* base) { static_assert( std::is_base_of_v, "T must be derived from Base" ); T* t; REQUIRE_NOTHROW(t = dynamic_cast(base)); REQUIRE_MESSAGE( t != nullptr, "Couldn't cast " * demangle(typeid(*base).name()) * " (given as " * demangle(typeid(Base).name()) * ")" * " to a " * demangle(typeid(T).name()) ); return t; } } // namespace // Overloads for your known base types template T* cast(ast::node* stmt) { return cast_impl(stmt); } template T* cast(ast::error::error* err) { return cast_impl(err); } struct ParserFixture { std::stringstream input; std::unique_ptr lexer; std::unique_ptr parser; std::unique_ptr program; ParserFixture() = default; void setup(std::string); }; void test_identifier(ast::expression*, std::string); void test_integer_literal(ast::expression*, int); void test_boolean_literal(ast::expression*, bool); void test_literal_expression(ast::expression*, std::any&); void test_infix_expression(ast::expression*, std::any, std::string, std::any); void test_failing_parsing(std::string, std::vector, int = 0);