From 8fbe804adccbe2d418dfe39030d6162e3524fe81 Mon Sep 17 00:00:00 2001
From: Ben Cumming <louncharf@gmail.com>
Date: Wed, 1 Nov 2017 14:02:59 +0100
Subject: [PATCH] Add support for NMODL files without INITIAL blocks [1] (#372)

Fixes #367.

* Add empty INITIAL block if NMODL file does not supply one.
---
 modcc/cprinter.cpp |  1 -
 modcc/modcc.cpp    |  2 --
 modcc/module.cpp   | 29 ++++++++++++++---------------
 3 files changed, 14 insertions(+), 18 deletions(-)

diff --git a/modcc/cprinter.cpp b/modcc/cprinter.cpp
index 3559e327..8e7ad9b0 100644
--- a/modcc/cprinter.cpp
+++ b/modcc/cprinter.cpp
@@ -827,7 +827,6 @@ void CPrinter::print_APIMethod_optimized(APIMethod* e) {
     decrease_indentation();
 
     aliased_output_ = false;
-    return;
 }
 
 void CPrinter::visit(CallExpression *e) {
diff --git a/modcc/modcc.cpp b/modcc/modcc.cpp
index 7ff7a0ac..d8caef1f 100644
--- a/modcc/modcc.cpp
+++ b/modcc/modcc.cpp
@@ -17,8 +17,6 @@
 
 using namespace arb;
 
-//#define VERBOSE
-
 int main(int argc, char **argv) {
 
     // parse command line arguments
diff --git a/modcc/module.cpp b/modcc/module.cpp
index ca4b0028..e4e8f4c6 100644
--- a/modcc/module.cpp
+++ b/modcc/module.cpp
@@ -267,27 +267,26 @@ bool Module::semantic() {
     //.........................................................................
     // nrn_init : based on the INITIAL block (i.e. the 'initial' procedure
     //.........................................................................
+
+    // insert an empty INITIAL block if none was defined in the .mod file.
+    if( !has_symbol("initial", symbolKind::procedure) ) {
+        symbols_["initial"] = make_symbol<ProcedureExpression>(
+                Location(), "initial",
+                std::vector<expression_ptr>(),
+                make_expression<BlockExpression>(Location(), expr_list_type(), false)
+        );
+    }
     auto initial_api = make_empty_api_method("nrn_init", "initial");
     auto api_init  = initial_api.first;
     auto proc_init = initial_api.second;
+    auto& init_body = api_init->body()->statements();
 
-    if(api_init)
-    {
-        auto& body = api_init->body()->statements();
-
-        for(auto& e : *proc_init->body()) {
-            body.emplace_back(e->clone());
-        }
-
-        api_init->semantic(symbols_);
-    }
-    else {
-        if(!proc_init) {
-            error("an INITIAL block is required", Location());
-        }
-        return false;
+    for(auto& e : *proc_init->body()) {
+        init_body.emplace_back(e->clone());
     }
 
+    api_init->semantic(symbols_);
+
     // Look in the symbol table for a procedure with the name "breakpoint".
     // This symbol corresponds to the BREAKPOINT block in the .mod file
     // There are two APIMethods generated from BREAKPOINT.
-- 
GitLab