Skip to content

Commit

Permalink
SemanticAnalysisVisitor: detect if several solve blocks are given (#1094
Browse files Browse the repository at this point in the history
)


This fixes #1092
  • Loading branch information
alkino committed Nov 16, 2023
1 parent 40a3fa7 commit f57d0d7
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 0 deletions.
21 changes: 21 additions & 0 deletions src/visitors/semantic_analysis_visitor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
*/

#include "visitors/semantic_analysis_visitor.hpp"
#include "ast/breakpoint_block.hpp"
#include "ast/function_block.hpp"
#include "ast/function_table_block.hpp"
#include "ast/independent_block.hpp"
Expand Down Expand Up @@ -170,5 +171,25 @@ void SemanticAnalysisVisitor::visit_mutex_unlock(const ast::MutexUnlock& /* node
/// -->
}

void SemanticAnalysisVisitor::visit_breakpoint_block(const ast::BreakpointBlock& node) {
/// <-- This code is for check 8
solve_block_found_in_this_breakpoint_block = false;
node.visit_children(*this);
solve_block_found_in_this_breakpoint_block = false;
/// -->
}

void SemanticAnalysisVisitor::visit_solve_block(const ast::SolveBlock& /* node */) {
/// <-- This code is for check 8
if (solve_block_found_in_this_breakpoint_block) {
logger->critical(
"It is not allowed to have several solve blocks in the same breakpoint block");
check_fail = true;
} else {
solve_block_found_in_this_breakpoint_block = true;
}
/// -->
}

} // namespace visitor
} // namespace nmodl
8 changes: 8 additions & 0 deletions src/visitors/semantic_analysis_visitor.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
* 5. Check if an independent variable is not 't'.
* 6. Check that mutex are not badly use
* 7. Check than function table got at least one argument.
* 8. Check that at most one solve block is present per breakpoint block.
*/
#include "ast/ast.hpp"
#include "visitors/ast_visitor.hpp"
Expand All @@ -54,6 +55,8 @@ class SemanticAnalysisVisitor: public ConstAstVisitor {
bool is_point_process = false;
/// true if we are inside a mutex locked part
bool in_mutex = false;
/// true if we already found a solve block
bool solve_block_found_in_this_breakpoint_block = false;

/// Store if we are in a procedure and if the arity of this is 1
void visit_procedure_block(const ast::ProcedureBlock& node) override;
Expand Down Expand Up @@ -82,6 +85,11 @@ class SemanticAnalysisVisitor: public ConstAstVisitor {
/// Look if MUTEXUNLOCK is outside a locked block
void visit_mutex_unlock(const ast::MutexUnlock& node) override;

void visit_breakpoint_block(const ast::BreakpointBlock& node) override;

/// Check how many solve block we got
void visit_solve_block(const ast::SolveBlock& node) override;

public:
SemanticAnalysisVisitor(bool accel_backend = false)
: accel_backend(accel_backend) {}
Expand Down
38 changes: 38 additions & 0 deletions test/unit/visitor/semantic_analysis.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -165,3 +165,41 @@ SCENARIO("FUNCTION_TABLE block", "[visitor][semantic_analysis]") {
}
}
}


SCENARIO("At most one solve block per breakpoint block", "[visitor][semantic_analysis]") {
GIVEN("A breakpoint block with only one solve block") {
std::string nmodl_text = R"(
BREAKPOINT {
SOLVE dX METHOD cnexp
}
)";
THEN("Semantic analysis should success") {
REQUIRE_FALSE(run_semantic_analysis_visitor(nmodl_text));
}
}
GIVEN("2 breakpoints block with one solve block each") {
std::string nmodl_text = R"(
PROCEDURE foo() {
SOLVE dX METHOD cnexp
}
BREAKPOINT {
SOLVE dY METHOD cnexp
}
)";
THEN("Semantic analysis should success") {
REQUIRE_FALSE(run_semantic_analysis_visitor(nmodl_text));
}
}
GIVEN("A breakpoint block with two solve blocks") {
std::string nmodl_text = R"(
BREAKPOINT {
SOLVE dX METHOD cnexp
SOLVE dY METHOD cnexp
}
)";
THEN("Semantic analysis should fail") {
REQUIRE(run_semantic_analysis_visitor(nmodl_text));
}
}
}

0 comments on commit f57d0d7

Please sign in to comment.