pslang/libs/parser/source/finalize.cpp

57 lines
1.7 KiB
C++

#include <pslang/parser/finalize.hpp>
#include <pslang/parser/error.hpp>
#include <pslang/ast/statement.hpp>
#include <pslang/ast/statement_visitor.hpp>
namespace pslang::parser
{
namespace
{
void validate(ast::statement_list_ptr statements, ast::function_definition * in_function, bool in_loop)
{
for (auto & statement : statements->statements)
{
if (auto if_chain = std::get_if<ast::if_chain>(statement.get()))
{
for (auto const & block : if_chain->blocks)
{
validate(block.statements, in_function, in_loop);
}
}
else if (auto while_block = std::get_if<ast::while_block>(statement.get()))
{
validate(while_block->statements, in_function, true);
}
else if (auto function_definition = std::get_if<ast::function_definition>(statement.get()))
{
validate(function_definition->statements, function_definition, in_loop);
}
else if (auto return_statement = std::get_if<ast::return_statement>(statement.get()))
{
if (!in_function)
throw parse_error("Return statement outside of function scope", return_statement->location);
return_statement->node = in_function;
}
else if (auto break_statement = std::get_if<ast::break_statement>(statement.get()))
{
if (!in_loop)
throw parse_error("Break without an enclosing loop", break_statement->location);
}
else if (auto continue_statement = std::get_if<ast::continue_statement>(statement.get()))
{
if (!in_loop)
throw parse_error("Continue without an enclosing loop", continue_statement->location);
}
}
}
}
void finalize(ast::statement_list_ptr statements)
{
validate(statements, nullptr, false);
}
}