66 lines
1.6 KiB
C++
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);
|
|
}
|
|
|
|
}
|