Skip to content
Snippets Groups Projects
Unverified Commit cba38a35 authored by Nora Abi Akar's avatar Nora Abi Akar Committed by GitHub
Browse files

Modcc: solve statement (#1373)

- Allow SOLVE statement anywhere in the BREAKPOINT block.
- Add unit test.

Fixes #1384.
parent e9277301
No related branches found
No related tags found
No related merge requests found
...@@ -182,6 +182,23 @@ bool Module::semantic() { ...@@ -182,6 +182,23 @@ bool Module::semantic() {
// move functions and procedures to the symbol table // move functions and procedures to the symbol table
if(!move_symbols(callables_)) return false; if(!move_symbols(callables_)) return false;
// Before starting the inlining process, look for the BREAKPOINT block:
// if it includes a SOLVE statement, check that it is the first statement
// in the block.
if (has_symbol("breakpoint", symbolKind::procedure)) {
bool found_non_solve = false;
auto breakpoint = symbols_["breakpoint"]->is_procedure();
for (const auto& s: breakpoint->body()->statements()) {
if(!s->is_solve_statement()) {
found_non_solve = true;
}
else if (found_non_solve) {
error("SOLVE statements must come first in BREAKPOINT block", s->location());
return false;
}
}
}
// perform semantic analysis and inlining on function and procedure bodies // perform semantic analysis and inlining on function and procedure bodies
if(auto errors = semantic_func_proc()) { if(auto errors = semantic_func_proc()) {
error("There were "+std::to_string(errors)+" errors in the semantic analysis"); error("There were "+std::to_string(errors)+" errors in the semantic analysis");
...@@ -360,25 +377,13 @@ bool Module::semantic() { ...@@ -360,25 +377,13 @@ bool Module::semantic() {
// Grab SOLVE statements, put them in `nrn_state` after translation. // Grab SOLVE statements, put them in `nrn_state` after translation.
bool found_solve = false; bool found_solve = false;
bool found_non_solve = false;
std::set<std::string> solved_ids; std::set<std::string> solved_ids;
for(auto& e: (breakpoint->body()->statements())) { for(auto& e: (breakpoint->body()->statements())) {
SolveExpression* solve_expression = e->is_solve_statement(); SolveExpression* solve_expression = e->is_solve_statement();
LocalDeclaration* local_expression = e->is_local_declaration();
if(local_expression) {
continue;
}
if(!solve_expression) { if(!solve_expression) {
found_non_solve = true;
continue; continue;
} }
if(found_non_solve) {
error("SOLVE statements must come first in BREAKPOINT block",
e->location());
return false;
}
found_solve = true; found_solve = true;
std::unique_ptr<SolverVisitorBase> solver; std::unique_ptr<SolverVisitorBase> solver;
......
NEURON {
POINT_PROCESS expsyn
RANGE tau, e
NONSPECIFIC_CURRENT i
}
UNITS {
(mV) = (millivolt)
}
PARAMETER {
tau = 2.0 (ms) : the default for Neuron is 0.1
e = 0 (mV)
}
ASSIGNED {}
STATE {
g
}
INITIAL {
g=0
}
BREAKPOINT {
SOLVE state METHOD cnexp
i = foo(g)*(v - e)
}
DERIVATIVE state {
g' = -g/tau + tau
}
NET_RECEIVE(weight) {
g = g * weight
}
FUNCTION foo(g) {
foo = exp(g) + 5
}
...@@ -102,3 +102,14 @@ TEST(Module, linear_mechanisms) { ...@@ -102,3 +102,14 @@ TEST(Module, linear_mechanisms) {
} }
} }
} }
TEST(Module, breakpoint) {
// Test function call in BREAKPOINT block
Module m(io::read_all(DATADIR "/mod_files/test8.mod"), "test8.mod");
EXPECT_NE(m.buffer().size(), 0);
Parser p(m, false);
EXPECT_TRUE(p.parse());
EXPECT_TRUE(m.semantic());
}
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment