pslang/libs/semantic/source/validate.cpp

66 lines
1.6 KiB
C++

#include <pslang/semantic/preprocess.hpp>
#include <pslang/semantic/error.hpp>
#include <pslang/ast/statement_visitor.hpp>
#include <pslang/types/type.hpp>
namespace pslang::semantic
{
namespace
{
struct validate_visitor
: ast::const_statement_visitor<validate_visitor>
{
using const_statement_visitor::apply;
void apply(ast::expression_ptr const &) {}
void apply(ast::assignment const &) {}
void apply(ast::variable_declaration const &) {}
void apply(ast::if_chain const & node)
{
for (auto const & block : node.blocks)
apply(*block.statements);
}
void apply(ast::while_block const & node)
{
apply(*node.statements);
}
void apply(ast::break_statement const &)
{}
void apply(ast::continue_statement const &)
{}
void apply(ast::function_definition const & node)
{
apply(*node.statements);
if (!types::equal(*get_type(*node.return_type), types::unit_type{}))
if (node.statements->statements.empty() || (true
&& !std::get_if<ast::return_statement>(node.statements->statements.back().get())
&& !std::get_if<ast::if_chain>(node.statements->statements.back().get())
&& !std::get_if<ast::while_block>(node.statements->statements.back().get())
))
throw validation_error("Function returning non-unit is missing a return statement in the end", node.location);
}
void apply(ast::foreign_function_declaration const &) {}
void apply(ast::return_statement const &) {}
void apply(ast::struct_definition const &) {}
};
}
void validate(module & module)
{
validate_visitor{}.apply(*module.statements);
}
}