From 2057f13ae1f397b9a7ecebca00188ccc16c225c0 Mon Sep 17 00:00:00 2001 From: Pooja Babu Date: Thu, 26 Sep 2024 14:49:48 +0200 Subject: [PATCH 01/25] Initial commit for include statement --- pynestml/generated/PyNestMLLexer.py | 667 +++---- pynestml/generated/PyNestMLParser.py | 1769 ++++++++++--------- pynestml/generated/PyNestMLParserVisitor.py | 12 +- pynestml/grammars/PyNestMLLexer.g4 | 1 + pynestml/grammars/PyNestMLParser.g4 | 10 +- tests/include_statement_test.py | 47 + tests/resources/IncludeStatementTest.nestml | 47 + tests/resources/ModelA.nestml | 35 + 8 files changed, 1437 insertions(+), 1151 deletions(-) create mode 100644 tests/include_statement_test.py create mode 100644 tests/resources/IncludeStatementTest.nestml create mode 100644 tests/resources/ModelA.nestml diff --git a/pynestml/generated/PyNestMLLexer.py b/pynestml/generated/PyNestMLLexer.py index d430d8556..3594f35cb 100644 --- a/pynestml/generated/PyNestMLLexer.py +++ b/pynestml/generated/PyNestMLLexer.py @@ -1,4 +1,4 @@ -# Generated from PyNestMLLexer.g4 by ANTLR 4.13.1 +# Generated from PyNestMLLexer.g4 by ANTLR 4.13.0 from antlr4 import * from io import StringIO import sys @@ -15,7 +15,7 @@ def serializedATN(): return [ - 4,0,90,702,6,-1,2,0,7,0,2,1,7,1,2,2,7,2,2,3,7,3,2,4,7,4,2,5,7,5, + 4,0,91,712,6,-1,2,0,7,0,2,1,7,1,2,2,7,2,2,3,7,3,2,4,7,4,2,5,7,5, 2,6,7,6,2,7,7,7,2,8,7,8,2,9,7,9,2,10,7,10,2,11,7,11,2,12,7,12,2, 13,7,13,2,14,7,14,2,15,7,15,2,16,7,16,2,17,7,17,2,18,7,18,2,19,7, 19,2,20,7,20,2,21,7,21,2,22,7,22,2,23,7,23,2,24,7,24,2,25,7,25,2, @@ -29,243 +29,246 @@ def serializedATN(): 71,2,72,7,72,2,73,7,73,2,74,7,74,2,75,7,75,2,76,7,76,2,77,7,77,2, 78,7,78,2,79,7,79,2,80,7,80,2,81,7,81,2,82,7,82,2,83,7,83,2,84,7, 84,2,85,7,85,2,86,7,86,2,87,7,87,2,88,7,88,2,89,7,89,2,90,7,90,2, - 91,7,91,1,0,1,0,1,0,1,0,1,1,3,1,191,8,1,1,1,1,1,1,2,1,2,1,2,3,2, - 198,8,2,1,3,4,3,201,8,3,11,3,12,3,202,1,3,1,3,1,4,1,4,1,4,1,4,1, - 4,1,5,1,5,5,5,214,8,5,10,5,12,5,217,9,5,1,5,1,5,4,5,221,8,5,11,5, - 12,5,222,1,5,1,5,1,6,1,6,5,6,229,8,6,10,6,12,6,232,9,6,1,6,1,6,1, - 7,1,7,1,7,3,7,239,8,7,1,7,1,7,1,7,3,7,244,8,7,3,7,246,8,7,1,7,1, - 7,1,8,1,8,1,8,1,8,1,8,1,8,1,8,1,8,1,9,1,9,1,9,1,9,1,9,1,10,1,10, - 1,10,1,10,1,10,1,10,1,10,1,11,1,11,1,11,1,11,1,11,1,11,1,11,1,11, - 1,12,1,12,1,12,1,12,1,12,1,13,1,13,1,13,1,13,1,13,1,13,1,13,1,13, - 1,13,1,14,1,14,1,14,1,14,1,14,1,14,1,14,1,15,1,15,1,15,1,15,1,15, - 1,15,1,15,1,16,1,16,1,16,1,17,1,17,1,17,1,17,1,17,1,18,1,18,1,18, - 1,18,1,18,1,19,1,19,1,19,1,19,1,20,1,20,1,20,1,20,1,20,1,20,1,21, - 1,21,1,21,1,22,1,22,1,22,1,22,1,22,1,23,1,23,1,23,1,23,1,24,1,24, - 1,24,1,24,1,25,1,25,1,25,1,26,1,26,1,26,1,26,1,27,1,27,1,27,1,27, - 1,27,1,27,1,27,1,27,1,27,1,27,1,27,1,28,1,28,1,28,1,28,1,28,1,28, - 1,28,1,29,1,29,1,29,1,29,1,29,1,29,1,30,1,30,1,30,1,30,1,30,1,30, - 1,31,1,31,1,31,1,31,1,31,1,31,1,31,1,31,1,31,1,31,1,31,1,32,1,32, + 91,7,91,2,92,7,92,1,0,1,0,1,0,1,0,1,1,3,1,193,8,1,1,1,1,1,1,2,1, + 2,1,2,3,2,200,8,2,1,3,4,3,203,8,3,11,3,12,3,204,1,3,1,3,1,4,1,4, + 1,4,1,4,1,4,1,5,1,5,5,5,216,8,5,10,5,12,5,219,9,5,1,5,1,5,4,5,223, + 8,5,11,5,12,5,224,1,5,1,5,1,6,1,6,5,6,231,8,6,10,6,12,6,234,9,6, + 1,6,1,6,1,7,1,7,1,7,3,7,241,8,7,1,7,1,7,1,7,3,7,246,8,7,3,7,248, + 8,7,1,7,1,7,1,8,1,8,1,8,1,8,1,8,1,8,1,8,1,8,1,9,1,9,1,9,1,9,1,9, + 1,10,1,10,1,10,1,10,1,10,1,10,1,10,1,11,1,11,1,11,1,11,1,11,1,11, + 1,11,1,11,1,12,1,12,1,12,1,12,1,12,1,13,1,13,1,13,1,13,1,13,1,13, + 1,13,1,13,1,13,1,14,1,14,1,14,1,14,1,14,1,14,1,14,1,15,1,15,1,15, + 1,15,1,15,1,15,1,15,1,16,1,16,1,16,1,17,1,17,1,17,1,17,1,17,1,18, + 1,18,1,18,1,18,1,18,1,19,1,19,1,19,1,19,1,20,1,20,1,20,1,20,1,20, + 1,20,1,21,1,21,1,21,1,22,1,22,1,22,1,22,1,22,1,23,1,23,1,23,1,23, + 1,24,1,24,1,24,1,24,1,25,1,25,1,25,1,26,1,26,1,26,1,26,1,27,1,27, + 1,27,1,27,1,27,1,27,1,27,1,27,1,28,1,28,1,28,1,28,1,28,1,28,1,28, + 1,28,1,28,1,28,1,28,1,29,1,29,1,29,1,29,1,29,1,29,1,29,1,30,1,30, + 1,30,1,30,1,30,1,30,1,31,1,31,1,31,1,31,1,31,1,31,1,32,1,32,1,32, 1,32,1,32,1,32,1,32,1,32,1,32,1,32,1,32,1,33,1,33,1,33,1,33,1,33, - 1,33,1,33,1,34,1,34,1,34,1,34,1,34,1,34,1,34,1,34,1,34,1,34,1,35, - 1,35,1,35,1,35,1,35,1,35,1,36,1,36,1,36,1,36,1,36,1,36,1,36,1,37, - 1,37,1,37,1,37,1,37,1,37,1,37,1,37,1,37,1,37,1,37,1,38,1,38,1,38, + 1,33,1,33,1,33,1,33,1,33,1,34,1,34,1,34,1,34,1,34,1,34,1,34,1,35, + 1,35,1,35,1,35,1,35,1,35,1,35,1,35,1,35,1,35,1,36,1,36,1,36,1,36, + 1,36,1,36,1,37,1,37,1,37,1,37,1,37,1,37,1,37,1,38,1,38,1,38,1,38, 1,38,1,38,1,38,1,38,1,38,1,38,1,38,1,39,1,39,1,39,1,39,1,39,1,39, - 1,39,1,39,1,39,1,39,1,39,1,39,1,40,1,40,1,40,1,40,1,40,1,40,1,41, - 1,41,1,41,1,41,1,41,1,41,1,41,1,41,1,41,1,41,1,41,1,42,1,42,1,42, - 1,42,1,42,1,42,1,42,1,42,1,42,1,42,1,42,1,43,1,43,1,43,1,43,1,43, - 1,43,1,43,1,43,1,43,1,43,1,43,1,43,1,43,1,44,1,44,1,44,1,44,1,44, - 1,44,1,44,1,44,1,44,1,44,1,44,1,44,1,44,1,44,1,44,1,45,1,45,1,46, - 1,46,1,46,1,46,1,47,1,47,1,48,1,48,1,49,1,49,1,50,1,50,1,51,1,51, - 1,52,1,52,1,53,1,53,1,54,1,54,1,55,1,55,1,55,1,56,1,56,1,57,1,57, - 1,57,1,58,1,58,1,58,1,59,1,59,1,59,1,60,1,60,1,60,1,61,1,61,1,62, - 1,62,1,63,1,63,1,63,1,64,1,64,1,64,1,65,1,65,1,65,1,66,1,66,1,66, - 1,67,1,67,1,67,1,68,1,68,1,68,1,69,1,69,1,69,1,70,1,70,1,70,1,71, - 1,71,1,71,1,72,1,72,1,73,1,73,1,74,1,74,1,75,1,75,1,76,1,76,1,76, - 1,77,1,77,1,78,1,78,1,79,1,79,1,80,1,80,1,81,1,81,1,81,1,82,1,82, - 1,83,1,83,1,84,1,84,1,84,1,84,1,84,1,84,1,84,1,84,1,84,1,84,1,84, - 1,84,1,84,1,84,1,84,1,84,1,84,1,84,3,84,636,8,84,1,85,1,85,1,85, - 4,85,641,8,85,11,85,12,85,642,1,85,3,85,646,8,85,1,85,3,85,649,8, - 85,1,85,3,85,652,8,85,1,85,5,85,655,8,85,10,85,12,85,658,9,85,1, - 85,1,85,1,86,3,86,663,8,86,1,86,5,86,666,8,86,10,86,12,86,669,9, - 86,1,87,4,87,672,8,87,11,87,12,87,673,1,88,1,88,3,88,678,8,88,1, - 89,3,89,681,8,89,1,89,1,89,1,89,1,89,1,89,3,89,688,8,89,1,90,1,90, - 3,90,692,8,90,1,90,1,90,1,90,1,91,1,91,3,91,699,8,91,1,91,1,91,2, - 215,222,0,92,1,3,3,0,5,4,7,5,9,6,11,7,13,8,15,9,17,10,19,11,21,12, - 23,13,25,14,27,15,29,16,31,17,33,18,35,19,37,20,39,21,41,22,43,23, - 45,24,47,25,49,26,51,27,53,28,55,29,57,30,59,31,61,32,63,33,65,34, - 67,35,69,36,71,37,73,38,75,39,77,40,79,41,81,42,83,43,85,44,87,45, - 89,46,91,47,93,48,95,49,97,50,99,51,101,52,103,53,105,54,107,55, - 109,56,111,57,113,58,115,59,117,60,119,61,121,62,123,63,125,64,127, - 65,129,66,131,67,133,68,135,69,137,70,139,71,141,72,143,73,145,74, - 147,75,149,76,151,77,153,78,155,79,157,80,159,81,161,82,163,83,165, - 84,167,85,169,86,171,87,173,88,175,89,177,90,179,0,181,0,183,0,1, - 0,7,2,0,9,9,32,32,2,0,10,10,13,13,4,0,10,10,13,13,34,34,92,92,4, - 0,36,36,65,90,95,95,97,122,5,0,36,36,48,57,65,90,95,95,97,122,1, - 0,48,57,2,0,69,69,101,101,723,0,1,1,0,0,0,0,5,1,0,0,0,0,7,1,0,0, - 0,0,9,1,0,0,0,0,11,1,0,0,0,0,13,1,0,0,0,0,15,1,0,0,0,0,17,1,0,0, - 0,0,19,1,0,0,0,0,21,1,0,0,0,0,23,1,0,0,0,0,25,1,0,0,0,0,27,1,0,0, - 0,0,29,1,0,0,0,0,31,1,0,0,0,0,33,1,0,0,0,0,35,1,0,0,0,0,37,1,0,0, - 0,0,39,1,0,0,0,0,41,1,0,0,0,0,43,1,0,0,0,0,45,1,0,0,0,0,47,1,0,0, - 0,0,49,1,0,0,0,0,51,1,0,0,0,0,53,1,0,0,0,0,55,1,0,0,0,0,57,1,0,0, - 0,0,59,1,0,0,0,0,61,1,0,0,0,0,63,1,0,0,0,0,65,1,0,0,0,0,67,1,0,0, - 0,0,69,1,0,0,0,0,71,1,0,0,0,0,73,1,0,0,0,0,75,1,0,0,0,0,77,1,0,0, - 0,0,79,1,0,0,0,0,81,1,0,0,0,0,83,1,0,0,0,0,85,1,0,0,0,0,87,1,0,0, - 0,0,89,1,0,0,0,0,91,1,0,0,0,0,93,1,0,0,0,0,95,1,0,0,0,0,97,1,0,0, - 0,0,99,1,0,0,0,0,101,1,0,0,0,0,103,1,0,0,0,0,105,1,0,0,0,0,107,1, - 0,0,0,0,109,1,0,0,0,0,111,1,0,0,0,0,113,1,0,0,0,0,115,1,0,0,0,0, - 117,1,0,0,0,0,119,1,0,0,0,0,121,1,0,0,0,0,123,1,0,0,0,0,125,1,0, - 0,0,0,127,1,0,0,0,0,129,1,0,0,0,0,131,1,0,0,0,0,133,1,0,0,0,0,135, - 1,0,0,0,0,137,1,0,0,0,0,139,1,0,0,0,0,141,1,0,0,0,0,143,1,0,0,0, - 0,145,1,0,0,0,0,147,1,0,0,0,0,149,1,0,0,0,0,151,1,0,0,0,0,153,1, - 0,0,0,0,155,1,0,0,0,0,157,1,0,0,0,0,159,1,0,0,0,0,161,1,0,0,0,0, - 163,1,0,0,0,0,165,1,0,0,0,0,167,1,0,0,0,0,169,1,0,0,0,0,171,1,0, - 0,0,0,173,1,0,0,0,0,175,1,0,0,0,0,177,1,0,0,0,1,185,1,0,0,0,3,190, - 1,0,0,0,5,194,1,0,0,0,7,200,1,0,0,0,9,206,1,0,0,0,11,211,1,0,0,0, - 13,226,1,0,0,0,15,245,1,0,0,0,17,249,1,0,0,0,19,257,1,0,0,0,21,262, - 1,0,0,0,23,269,1,0,0,0,25,277,1,0,0,0,27,282,1,0,0,0,29,291,1,0, - 0,0,31,298,1,0,0,0,33,305,1,0,0,0,35,308,1,0,0,0,37,313,1,0,0,0, - 39,318,1,0,0,0,41,322,1,0,0,0,43,328,1,0,0,0,45,331,1,0,0,0,47,336, - 1,0,0,0,49,340,1,0,0,0,51,344,1,0,0,0,53,347,1,0,0,0,55,351,1,0, - 0,0,57,362,1,0,0,0,59,369,1,0,0,0,61,375,1,0,0,0,63,381,1,0,0,0, - 65,392,1,0,0,0,67,402,1,0,0,0,69,409,1,0,0,0,71,419,1,0,0,0,73,425, - 1,0,0,0,75,432,1,0,0,0,77,443,1,0,0,0,79,453,1,0,0,0,81,465,1,0, - 0,0,83,471,1,0,0,0,85,482,1,0,0,0,87,493,1,0,0,0,89,506,1,0,0,0, - 91,521,1,0,0,0,93,523,1,0,0,0,95,527,1,0,0,0,97,529,1,0,0,0,99,531, - 1,0,0,0,101,533,1,0,0,0,103,535,1,0,0,0,105,537,1,0,0,0,107,539, - 1,0,0,0,109,541,1,0,0,0,111,543,1,0,0,0,113,546,1,0,0,0,115,548, - 1,0,0,0,117,551,1,0,0,0,119,554,1,0,0,0,121,557,1,0,0,0,123,560, - 1,0,0,0,125,562,1,0,0,0,127,564,1,0,0,0,129,567,1,0,0,0,131,570, - 1,0,0,0,133,573,1,0,0,0,135,576,1,0,0,0,137,579,1,0,0,0,139,582, - 1,0,0,0,141,585,1,0,0,0,143,588,1,0,0,0,145,591,1,0,0,0,147,593, - 1,0,0,0,149,595,1,0,0,0,151,597,1,0,0,0,153,599,1,0,0,0,155,602, - 1,0,0,0,157,604,1,0,0,0,159,606,1,0,0,0,161,608,1,0,0,0,163,610, - 1,0,0,0,165,613,1,0,0,0,167,615,1,0,0,0,169,635,1,0,0,0,171,637, - 1,0,0,0,173,662,1,0,0,0,175,671,1,0,0,0,177,677,1,0,0,0,179,687, - 1,0,0,0,181,691,1,0,0,0,183,698,1,0,0,0,185,186,5,34,0,0,186,187, - 5,34,0,0,187,188,5,34,0,0,188,2,1,0,0,0,189,191,5,13,0,0,190,189, - 1,0,0,0,190,191,1,0,0,0,191,192,1,0,0,0,192,193,5,10,0,0,193,4,1, - 0,0,0,194,195,3,145,72,0,195,197,3,3,1,0,196,198,3,7,3,0,197,196, - 1,0,0,0,197,198,1,0,0,0,198,6,1,0,0,0,199,201,7,0,0,0,200,199,1, - 0,0,0,201,202,1,0,0,0,202,200,1,0,0,0,202,203,1,0,0,0,203,204,1, - 0,0,0,204,205,6,3,0,0,205,8,1,0,0,0,206,207,5,92,0,0,207,208,3,3, - 1,0,208,209,1,0,0,0,209,210,6,4,0,0,210,10,1,0,0,0,211,215,3,1,0, - 0,212,214,9,0,0,0,213,212,1,0,0,0,214,217,1,0,0,0,215,216,1,0,0, - 0,215,213,1,0,0,0,216,218,1,0,0,0,217,215,1,0,0,0,218,220,3,1,0, - 0,219,221,3,3,1,0,220,219,1,0,0,0,221,222,1,0,0,0,222,223,1,0,0, - 0,222,220,1,0,0,0,223,224,1,0,0,0,224,225,6,5,1,0,225,12,1,0,0,0, - 226,230,5,35,0,0,227,229,8,1,0,0,228,227,1,0,0,0,229,232,1,0,0,0, - 230,228,1,0,0,0,230,231,1,0,0,0,231,233,1,0,0,0,232,230,1,0,0,0, - 233,234,6,6,1,0,234,14,1,0,0,0,235,236,4,7,0,0,236,246,3,7,3,0,237, - 239,5,13,0,0,238,237,1,0,0,0,238,239,1,0,0,0,239,240,1,0,0,0,240, - 241,5,10,0,0,241,243,1,0,0,0,242,244,3,7,3,0,243,242,1,0,0,0,243, - 244,1,0,0,0,244,246,1,0,0,0,245,235,1,0,0,0,245,238,1,0,0,0,246, - 247,1,0,0,0,247,248,6,7,2,0,248,16,1,0,0,0,249,250,5,105,0,0,250, - 251,5,110,0,0,251,252,5,116,0,0,252,253,5,101,0,0,253,254,5,103, - 0,0,254,255,5,101,0,0,255,256,5,114,0,0,256,18,1,0,0,0,257,258,5, - 114,0,0,258,259,5,101,0,0,259,260,5,97,0,0,260,261,5,108,0,0,261, - 20,1,0,0,0,262,263,5,115,0,0,263,264,5,116,0,0,264,265,5,114,0,0, - 265,266,5,105,0,0,266,267,5,110,0,0,267,268,5,103,0,0,268,22,1,0, - 0,0,269,270,5,98,0,0,270,271,5,111,0,0,271,272,5,111,0,0,272,273, - 5,108,0,0,273,274,5,101,0,0,274,275,5,97,0,0,275,276,5,110,0,0,276, - 24,1,0,0,0,277,278,5,118,0,0,278,279,5,111,0,0,279,280,5,105,0,0, - 280,281,5,100,0,0,281,26,1,0,0,0,282,283,5,102,0,0,283,284,5,117, - 0,0,284,285,5,110,0,0,285,286,5,99,0,0,286,287,5,116,0,0,287,288, - 5,105,0,0,288,289,5,111,0,0,289,290,5,110,0,0,290,28,1,0,0,0,291, - 292,5,105,0,0,292,293,5,110,0,0,293,294,5,108,0,0,294,295,5,105, - 0,0,295,296,5,110,0,0,296,297,5,101,0,0,297,30,1,0,0,0,298,299,5, - 114,0,0,299,300,5,101,0,0,300,301,5,116,0,0,301,302,5,117,0,0,302, - 303,5,114,0,0,303,304,5,110,0,0,304,32,1,0,0,0,305,306,5,105,0,0, - 306,307,5,102,0,0,307,34,1,0,0,0,308,309,5,101,0,0,309,310,5,108, - 0,0,310,311,5,105,0,0,311,312,5,102,0,0,312,36,1,0,0,0,313,314,5, - 101,0,0,314,315,5,108,0,0,315,316,5,115,0,0,316,317,5,101,0,0,317, - 38,1,0,0,0,318,319,5,102,0,0,319,320,5,111,0,0,320,321,5,114,0,0, - 321,40,1,0,0,0,322,323,5,119,0,0,323,324,5,104,0,0,324,325,5,105, - 0,0,325,326,5,108,0,0,326,327,5,101,0,0,327,42,1,0,0,0,328,329,5, - 105,0,0,329,330,5,110,0,0,330,44,1,0,0,0,331,332,5,115,0,0,332,333, - 5,116,0,0,333,334,5,101,0,0,334,335,5,112,0,0,335,46,1,0,0,0,336, - 337,5,105,0,0,337,338,5,110,0,0,338,339,5,102,0,0,339,48,1,0,0,0, - 340,341,5,97,0,0,341,342,5,110,0,0,342,343,5,100,0,0,343,50,1,0, - 0,0,344,345,5,111,0,0,345,346,5,114,0,0,346,52,1,0,0,0,347,348,5, - 110,0,0,348,349,5,111,0,0,349,350,5,116,0,0,350,54,1,0,0,0,351,352, - 5,114,0,0,352,353,5,101,0,0,353,354,5,99,0,0,354,355,5,111,0,0,355, - 356,5,114,0,0,356,357,5,100,0,0,357,358,5,97,0,0,358,359,5,98,0, - 0,359,360,5,108,0,0,360,361,5,101,0,0,361,56,1,0,0,0,362,363,5,107, - 0,0,363,364,5,101,0,0,364,365,5,114,0,0,365,366,5,110,0,0,366,367, - 5,101,0,0,367,368,5,108,0,0,368,58,1,0,0,0,369,370,5,109,0,0,370, - 371,5,111,0,0,371,372,5,100,0,0,372,373,5,101,0,0,373,374,5,108, - 0,0,374,60,1,0,0,0,375,376,5,115,0,0,376,377,5,116,0,0,377,378,5, - 97,0,0,378,379,5,116,0,0,379,380,5,101,0,0,380,62,1,0,0,0,381,382, - 5,112,0,0,382,383,5,97,0,0,383,384,5,114,0,0,384,385,5,97,0,0,385, - 386,5,109,0,0,386,387,5,101,0,0,387,388,5,116,0,0,388,389,5,101, - 0,0,389,390,5,114,0,0,390,391,5,115,0,0,391,64,1,0,0,0,392,393,5, - 105,0,0,393,394,5,110,0,0,394,395,5,116,0,0,395,396,5,101,0,0,396, - 397,5,114,0,0,397,398,5,110,0,0,398,399,5,97,0,0,399,400,5,108,0, - 0,400,401,5,115,0,0,401,66,1,0,0,0,402,403,5,117,0,0,403,404,5,112, - 0,0,404,405,5,100,0,0,405,406,5,97,0,0,406,407,5,116,0,0,407,408, - 5,101,0,0,408,68,1,0,0,0,409,410,5,101,0,0,410,411,5,113,0,0,411, - 412,5,117,0,0,412,413,5,97,0,0,413,414,5,116,0,0,414,415,5,105,0, - 0,415,416,5,111,0,0,416,417,5,110,0,0,417,418,5,115,0,0,418,70,1, - 0,0,0,419,420,5,105,0,0,420,421,5,110,0,0,421,422,5,112,0,0,422, - 423,5,117,0,0,423,424,5,116,0,0,424,72,1,0,0,0,425,426,5,111,0,0, - 426,427,5,117,0,0,427,428,5,116,0,0,428,429,5,112,0,0,429,430,5, - 117,0,0,430,431,5,116,0,0,431,74,1,0,0,0,432,433,5,99,0,0,433,434, - 5,111,0,0,434,435,5,110,0,0,435,436,5,116,0,0,436,437,5,105,0,0, - 437,438,5,110,0,0,438,439,5,117,0,0,439,440,5,111,0,0,440,441,5, - 117,0,0,441,442,5,115,0,0,442,76,1,0,0,0,443,444,5,111,0,0,444,445, - 5,110,0,0,445,446,5,82,0,0,446,447,5,101,0,0,447,448,5,99,0,0,448, - 449,5,101,0,0,449,450,5,105,0,0,450,451,5,118,0,0,451,452,5,101, - 0,0,452,78,1,0,0,0,453,454,5,111,0,0,454,455,5,110,0,0,455,456,5, - 67,0,0,456,457,5,111,0,0,457,458,5,110,0,0,458,459,5,100,0,0,459, - 460,5,105,0,0,460,461,5,116,0,0,461,462,5,105,0,0,462,463,5,111, - 0,0,463,464,5,110,0,0,464,80,1,0,0,0,465,466,5,115,0,0,466,467,5, - 112,0,0,467,468,5,105,0,0,468,469,5,107,0,0,469,470,5,101,0,0,470, - 82,1,0,0,0,471,472,5,105,0,0,472,473,5,110,0,0,473,474,5,104,0,0, - 474,475,5,105,0,0,475,476,5,98,0,0,476,477,5,105,0,0,477,478,5,116, - 0,0,478,479,5,111,0,0,479,480,5,114,0,0,480,481,5,121,0,0,481,84, - 1,0,0,0,482,483,5,101,0,0,483,484,5,120,0,0,484,485,5,99,0,0,485, - 486,5,105,0,0,486,487,5,116,0,0,487,488,5,97,0,0,488,489,5,116,0, - 0,489,490,5,111,0,0,490,491,5,114,0,0,491,492,5,121,0,0,492,86,1, - 0,0,0,493,494,5,64,0,0,494,495,5,104,0,0,495,496,5,111,0,0,496,497, - 5,109,0,0,497,498,5,111,0,0,498,499,5,103,0,0,499,500,5,101,0,0, - 500,501,5,110,0,0,501,502,5,101,0,0,502,503,5,111,0,0,503,504,5, - 117,0,0,504,505,5,115,0,0,505,88,1,0,0,0,506,507,5,64,0,0,507,508, - 5,104,0,0,508,509,5,101,0,0,509,510,5,116,0,0,510,511,5,101,0,0, - 511,512,5,114,0,0,512,513,5,111,0,0,513,514,5,103,0,0,514,515,5, - 101,0,0,515,516,5,110,0,0,516,517,5,101,0,0,517,518,5,111,0,0,518, - 519,5,117,0,0,519,520,5,115,0,0,520,90,1,0,0,0,521,522,5,64,0,0, - 522,92,1,0,0,0,523,524,5,46,0,0,524,525,5,46,0,0,525,526,5,46,0, - 0,526,94,1,0,0,0,527,528,5,40,0,0,528,96,1,0,0,0,529,530,5,41,0, - 0,530,98,1,0,0,0,531,532,5,43,0,0,532,100,1,0,0,0,533,534,5,126, - 0,0,534,102,1,0,0,0,535,536,5,124,0,0,536,104,1,0,0,0,537,538,5, - 94,0,0,538,106,1,0,0,0,539,540,5,38,0,0,540,108,1,0,0,0,541,542, - 5,91,0,0,542,110,1,0,0,0,543,544,5,60,0,0,544,545,5,45,0,0,545,112, - 1,0,0,0,546,547,5,93,0,0,547,114,1,0,0,0,548,549,5,91,0,0,549,550, - 5,91,0,0,550,116,1,0,0,0,551,552,5,93,0,0,552,553,5,93,0,0,553,118, - 1,0,0,0,554,555,5,60,0,0,555,556,5,60,0,0,556,120,1,0,0,0,557,558, - 5,62,0,0,558,559,5,62,0,0,559,122,1,0,0,0,560,561,5,60,0,0,561,124, - 1,0,0,0,562,563,5,62,0,0,563,126,1,0,0,0,564,565,5,60,0,0,565,566, - 5,61,0,0,566,128,1,0,0,0,567,568,5,43,0,0,568,569,5,61,0,0,569,130, - 1,0,0,0,570,571,5,45,0,0,571,572,5,61,0,0,572,132,1,0,0,0,573,574, - 5,42,0,0,574,575,5,61,0,0,575,134,1,0,0,0,576,577,5,47,0,0,577,578, - 5,61,0,0,578,136,1,0,0,0,579,580,5,61,0,0,580,581,5,61,0,0,581,138, - 1,0,0,0,582,583,5,33,0,0,583,584,5,61,0,0,584,140,1,0,0,0,585,586, - 5,60,0,0,586,587,5,62,0,0,587,142,1,0,0,0,588,589,5,62,0,0,589,590, - 5,61,0,0,590,144,1,0,0,0,591,592,5,44,0,0,592,146,1,0,0,0,593,594, - 5,45,0,0,594,148,1,0,0,0,595,596,5,61,0,0,596,150,1,0,0,0,597,598, - 5,42,0,0,598,152,1,0,0,0,599,600,5,42,0,0,600,601,5,42,0,0,601,154, - 1,0,0,0,602,603,5,47,0,0,603,156,1,0,0,0,604,605,5,37,0,0,605,158, - 1,0,0,0,606,607,5,63,0,0,607,160,1,0,0,0,608,609,5,58,0,0,609,162, - 1,0,0,0,610,611,5,58,0,0,611,612,5,58,0,0,612,164,1,0,0,0,613,614, - 5,59,0,0,614,166,1,0,0,0,615,616,5,39,0,0,616,168,1,0,0,0,617,618, - 5,116,0,0,618,619,5,114,0,0,619,620,5,117,0,0,620,636,5,101,0,0, - 621,622,5,84,0,0,622,623,5,114,0,0,623,624,5,117,0,0,624,636,5,101, - 0,0,625,626,5,102,0,0,626,627,5,97,0,0,627,628,5,108,0,0,628,629, - 5,115,0,0,629,636,5,101,0,0,630,631,5,70,0,0,631,632,5,97,0,0,632, - 633,5,108,0,0,633,634,5,115,0,0,634,636,5,101,0,0,635,617,1,0,0, - 0,635,621,1,0,0,0,635,625,1,0,0,0,635,630,1,0,0,0,636,170,1,0,0, - 0,637,656,5,34,0,0,638,651,5,92,0,0,639,641,7,0,0,0,640,639,1,0, - 0,0,641,642,1,0,0,0,642,640,1,0,0,0,642,643,1,0,0,0,643,648,1,0, - 0,0,644,646,5,13,0,0,645,644,1,0,0,0,645,646,1,0,0,0,646,647,1,0, - 0,0,647,649,5,10,0,0,648,645,1,0,0,0,648,649,1,0,0,0,649,652,1,0, - 0,0,650,652,9,0,0,0,651,640,1,0,0,0,651,650,1,0,0,0,652,655,1,0, - 0,0,653,655,8,2,0,0,654,638,1,0,0,0,654,653,1,0,0,0,655,658,1,0, - 0,0,656,654,1,0,0,0,656,657,1,0,0,0,657,659,1,0,0,0,658,656,1,0, - 0,0,659,660,5,34,0,0,660,172,1,0,0,0,661,663,7,3,0,0,662,661,1,0, - 0,0,663,667,1,0,0,0,664,666,7,4,0,0,665,664,1,0,0,0,666,669,1,0, - 0,0,667,665,1,0,0,0,667,668,1,0,0,0,668,174,1,0,0,0,669,667,1,0, - 0,0,670,672,7,5,0,0,671,670,1,0,0,0,672,673,1,0,0,0,673,671,1,0, - 0,0,673,674,1,0,0,0,674,176,1,0,0,0,675,678,3,179,89,0,676,678,3, - 181,90,0,677,675,1,0,0,0,677,676,1,0,0,0,678,178,1,0,0,0,679,681, - 3,175,87,0,680,679,1,0,0,0,680,681,1,0,0,0,681,682,1,0,0,0,682,683, - 5,46,0,0,683,688,3,175,87,0,684,685,3,175,87,0,685,686,5,46,0,0, - 686,688,1,0,0,0,687,680,1,0,0,0,687,684,1,0,0,0,688,180,1,0,0,0, - 689,692,3,175,87,0,690,692,3,179,89,0,691,689,1,0,0,0,691,690,1, - 0,0,0,692,693,1,0,0,0,693,694,7,6,0,0,694,695,3,183,91,0,695,182, - 1,0,0,0,696,699,3,99,49,0,697,699,3,147,73,0,698,696,1,0,0,0,698, - 697,1,0,0,0,698,699,1,0,0,0,699,700,1,0,0,0,700,701,3,175,87,0,701, - 184,1,0,0,0,26,0,190,197,202,215,222,230,238,243,245,635,642,645, - 648,651,654,656,662,665,667,673,677,680,687,691,698,3,0,1,0,0,2, - 0,1,7,0 + 1,39,1,39,1,39,1,39,1,40,1,40,1,40,1,40,1,40,1,40,1,40,1,40,1,40, + 1,40,1,40,1,40,1,41,1,41,1,41,1,41,1,41,1,41,1,42,1,42,1,42,1,42, + 1,42,1,42,1,42,1,42,1,42,1,42,1,42,1,43,1,43,1,43,1,43,1,43,1,43, + 1,43,1,43,1,43,1,43,1,43,1,44,1,44,1,44,1,44,1,44,1,44,1,44,1,44, + 1,44,1,44,1,44,1,44,1,44,1,45,1,45,1,45,1,45,1,45,1,45,1,45,1,45, + 1,45,1,45,1,45,1,45,1,45,1,45,1,45,1,46,1,46,1,47,1,47,1,47,1,47, + 1,48,1,48,1,49,1,49,1,50,1,50,1,51,1,51,1,52,1,52,1,53,1,53,1,54, + 1,54,1,55,1,55,1,56,1,56,1,56,1,57,1,57,1,58,1,58,1,58,1,59,1,59, + 1,59,1,60,1,60,1,60,1,61,1,61,1,61,1,62,1,62,1,63,1,63,1,64,1,64, + 1,64,1,65,1,65,1,65,1,66,1,66,1,66,1,67,1,67,1,67,1,68,1,68,1,68, + 1,69,1,69,1,69,1,70,1,70,1,70,1,71,1,71,1,71,1,72,1,72,1,72,1,73, + 1,73,1,74,1,74,1,75,1,75,1,76,1,76,1,77,1,77,1,77,1,78,1,78,1,79, + 1,79,1,80,1,80,1,81,1,81,1,82,1,82,1,82,1,83,1,83,1,84,1,84,1,85, + 1,85,1,85,1,85,1,85,1,85,1,85,1,85,1,85,1,85,1,85,1,85,1,85,1,85, + 1,85,1,85,1,85,1,85,3,85,646,8,85,1,86,1,86,1,86,4,86,651,8,86,11, + 86,12,86,652,1,86,3,86,656,8,86,1,86,3,86,659,8,86,1,86,3,86,662, + 8,86,1,86,5,86,665,8,86,10,86,12,86,668,9,86,1,86,1,86,1,87,3,87, + 673,8,87,1,87,5,87,676,8,87,10,87,12,87,679,9,87,1,88,4,88,682,8, + 88,11,88,12,88,683,1,89,1,89,3,89,688,8,89,1,90,3,90,691,8,90,1, + 90,1,90,1,90,1,90,1,90,3,90,698,8,90,1,91,1,91,3,91,702,8,91,1,91, + 1,91,1,91,1,92,1,92,3,92,709,8,92,1,92,1,92,2,217,224,0,93,1,3,3, + 0,5,4,7,5,9,6,11,7,13,8,15,9,17,10,19,11,21,12,23,13,25,14,27,15, + 29,16,31,17,33,18,35,19,37,20,39,21,41,22,43,23,45,24,47,25,49,26, + 51,27,53,28,55,29,57,30,59,31,61,32,63,33,65,34,67,35,69,36,71,37, + 73,38,75,39,77,40,79,41,81,42,83,43,85,44,87,45,89,46,91,47,93,48, + 95,49,97,50,99,51,101,52,103,53,105,54,107,55,109,56,111,57,113, + 58,115,59,117,60,119,61,121,62,123,63,125,64,127,65,129,66,131,67, + 133,68,135,69,137,70,139,71,141,72,143,73,145,74,147,75,149,76,151, + 77,153,78,155,79,157,80,159,81,161,82,163,83,165,84,167,85,169,86, + 171,87,173,88,175,89,177,90,179,91,181,0,183,0,185,0,1,0,7,2,0,9, + 9,32,32,2,0,10,10,13,13,4,0,10,10,13,13,34,34,92,92,4,0,36,36,65, + 90,95,95,97,122,5,0,36,36,48,57,65,90,95,95,97,122,1,0,48,57,2,0, + 69,69,101,101,733,0,1,1,0,0,0,0,5,1,0,0,0,0,7,1,0,0,0,0,9,1,0,0, + 0,0,11,1,0,0,0,0,13,1,0,0,0,0,15,1,0,0,0,0,17,1,0,0,0,0,19,1,0,0, + 0,0,21,1,0,0,0,0,23,1,0,0,0,0,25,1,0,0,0,0,27,1,0,0,0,0,29,1,0,0, + 0,0,31,1,0,0,0,0,33,1,0,0,0,0,35,1,0,0,0,0,37,1,0,0,0,0,39,1,0,0, + 0,0,41,1,0,0,0,0,43,1,0,0,0,0,45,1,0,0,0,0,47,1,0,0,0,0,49,1,0,0, + 0,0,51,1,0,0,0,0,53,1,0,0,0,0,55,1,0,0,0,0,57,1,0,0,0,0,59,1,0,0, + 0,0,61,1,0,0,0,0,63,1,0,0,0,0,65,1,0,0,0,0,67,1,0,0,0,0,69,1,0,0, + 0,0,71,1,0,0,0,0,73,1,0,0,0,0,75,1,0,0,0,0,77,1,0,0,0,0,79,1,0,0, + 0,0,81,1,0,0,0,0,83,1,0,0,0,0,85,1,0,0,0,0,87,1,0,0,0,0,89,1,0,0, + 0,0,91,1,0,0,0,0,93,1,0,0,0,0,95,1,0,0,0,0,97,1,0,0,0,0,99,1,0,0, + 0,0,101,1,0,0,0,0,103,1,0,0,0,0,105,1,0,0,0,0,107,1,0,0,0,0,109, + 1,0,0,0,0,111,1,0,0,0,0,113,1,0,0,0,0,115,1,0,0,0,0,117,1,0,0,0, + 0,119,1,0,0,0,0,121,1,0,0,0,0,123,1,0,0,0,0,125,1,0,0,0,0,127,1, + 0,0,0,0,129,1,0,0,0,0,131,1,0,0,0,0,133,1,0,0,0,0,135,1,0,0,0,0, + 137,1,0,0,0,0,139,1,0,0,0,0,141,1,0,0,0,0,143,1,0,0,0,0,145,1,0, + 0,0,0,147,1,0,0,0,0,149,1,0,0,0,0,151,1,0,0,0,0,153,1,0,0,0,0,155, + 1,0,0,0,0,157,1,0,0,0,0,159,1,0,0,0,0,161,1,0,0,0,0,163,1,0,0,0, + 0,165,1,0,0,0,0,167,1,0,0,0,0,169,1,0,0,0,0,171,1,0,0,0,0,173,1, + 0,0,0,0,175,1,0,0,0,0,177,1,0,0,0,0,179,1,0,0,0,1,187,1,0,0,0,3, + 192,1,0,0,0,5,196,1,0,0,0,7,202,1,0,0,0,9,208,1,0,0,0,11,213,1,0, + 0,0,13,228,1,0,0,0,15,247,1,0,0,0,17,251,1,0,0,0,19,259,1,0,0,0, + 21,264,1,0,0,0,23,271,1,0,0,0,25,279,1,0,0,0,27,284,1,0,0,0,29,293, + 1,0,0,0,31,300,1,0,0,0,33,307,1,0,0,0,35,310,1,0,0,0,37,315,1,0, + 0,0,39,320,1,0,0,0,41,324,1,0,0,0,43,330,1,0,0,0,45,333,1,0,0,0, + 47,338,1,0,0,0,49,342,1,0,0,0,51,346,1,0,0,0,53,349,1,0,0,0,55,353, + 1,0,0,0,57,361,1,0,0,0,59,372,1,0,0,0,61,379,1,0,0,0,63,385,1,0, + 0,0,65,391,1,0,0,0,67,402,1,0,0,0,69,412,1,0,0,0,71,419,1,0,0,0, + 73,429,1,0,0,0,75,435,1,0,0,0,77,442,1,0,0,0,79,453,1,0,0,0,81,463, + 1,0,0,0,83,475,1,0,0,0,85,481,1,0,0,0,87,492,1,0,0,0,89,503,1,0, + 0,0,91,516,1,0,0,0,93,531,1,0,0,0,95,533,1,0,0,0,97,537,1,0,0,0, + 99,539,1,0,0,0,101,541,1,0,0,0,103,543,1,0,0,0,105,545,1,0,0,0,107, + 547,1,0,0,0,109,549,1,0,0,0,111,551,1,0,0,0,113,553,1,0,0,0,115, + 556,1,0,0,0,117,558,1,0,0,0,119,561,1,0,0,0,121,564,1,0,0,0,123, + 567,1,0,0,0,125,570,1,0,0,0,127,572,1,0,0,0,129,574,1,0,0,0,131, + 577,1,0,0,0,133,580,1,0,0,0,135,583,1,0,0,0,137,586,1,0,0,0,139, + 589,1,0,0,0,141,592,1,0,0,0,143,595,1,0,0,0,145,598,1,0,0,0,147, + 601,1,0,0,0,149,603,1,0,0,0,151,605,1,0,0,0,153,607,1,0,0,0,155, + 609,1,0,0,0,157,612,1,0,0,0,159,614,1,0,0,0,161,616,1,0,0,0,163, + 618,1,0,0,0,165,620,1,0,0,0,167,623,1,0,0,0,169,625,1,0,0,0,171, + 645,1,0,0,0,173,647,1,0,0,0,175,672,1,0,0,0,177,681,1,0,0,0,179, + 687,1,0,0,0,181,697,1,0,0,0,183,701,1,0,0,0,185,708,1,0,0,0,187, + 188,5,34,0,0,188,189,5,34,0,0,189,190,5,34,0,0,190,2,1,0,0,0,191, + 193,5,13,0,0,192,191,1,0,0,0,192,193,1,0,0,0,193,194,1,0,0,0,194, + 195,5,10,0,0,195,4,1,0,0,0,196,197,3,147,73,0,197,199,3,3,1,0,198, + 200,3,7,3,0,199,198,1,0,0,0,199,200,1,0,0,0,200,6,1,0,0,0,201,203, + 7,0,0,0,202,201,1,0,0,0,203,204,1,0,0,0,204,202,1,0,0,0,204,205, + 1,0,0,0,205,206,1,0,0,0,206,207,6,3,0,0,207,8,1,0,0,0,208,209,5, + 92,0,0,209,210,3,3,1,0,210,211,1,0,0,0,211,212,6,4,0,0,212,10,1, + 0,0,0,213,217,3,1,0,0,214,216,9,0,0,0,215,214,1,0,0,0,216,219,1, + 0,0,0,217,218,1,0,0,0,217,215,1,0,0,0,218,220,1,0,0,0,219,217,1, + 0,0,0,220,222,3,1,0,0,221,223,3,3,1,0,222,221,1,0,0,0,223,224,1, + 0,0,0,224,225,1,0,0,0,224,222,1,0,0,0,225,226,1,0,0,0,226,227,6, + 5,1,0,227,12,1,0,0,0,228,232,5,35,0,0,229,231,8,1,0,0,230,229,1, + 0,0,0,231,234,1,0,0,0,232,230,1,0,0,0,232,233,1,0,0,0,233,235,1, + 0,0,0,234,232,1,0,0,0,235,236,6,6,1,0,236,14,1,0,0,0,237,238,4,7, + 0,0,238,248,3,7,3,0,239,241,5,13,0,0,240,239,1,0,0,0,240,241,1,0, + 0,0,241,242,1,0,0,0,242,243,5,10,0,0,243,245,1,0,0,0,244,246,3,7, + 3,0,245,244,1,0,0,0,245,246,1,0,0,0,246,248,1,0,0,0,247,237,1,0, + 0,0,247,240,1,0,0,0,248,249,1,0,0,0,249,250,6,7,2,0,250,16,1,0,0, + 0,251,252,5,105,0,0,252,253,5,110,0,0,253,254,5,116,0,0,254,255, + 5,101,0,0,255,256,5,103,0,0,256,257,5,101,0,0,257,258,5,114,0,0, + 258,18,1,0,0,0,259,260,5,114,0,0,260,261,5,101,0,0,261,262,5,97, + 0,0,262,263,5,108,0,0,263,20,1,0,0,0,264,265,5,115,0,0,265,266,5, + 116,0,0,266,267,5,114,0,0,267,268,5,105,0,0,268,269,5,110,0,0,269, + 270,5,103,0,0,270,22,1,0,0,0,271,272,5,98,0,0,272,273,5,111,0,0, + 273,274,5,111,0,0,274,275,5,108,0,0,275,276,5,101,0,0,276,277,5, + 97,0,0,277,278,5,110,0,0,278,24,1,0,0,0,279,280,5,118,0,0,280,281, + 5,111,0,0,281,282,5,105,0,0,282,283,5,100,0,0,283,26,1,0,0,0,284, + 285,5,102,0,0,285,286,5,117,0,0,286,287,5,110,0,0,287,288,5,99,0, + 0,288,289,5,116,0,0,289,290,5,105,0,0,290,291,5,111,0,0,291,292, + 5,110,0,0,292,28,1,0,0,0,293,294,5,105,0,0,294,295,5,110,0,0,295, + 296,5,108,0,0,296,297,5,105,0,0,297,298,5,110,0,0,298,299,5,101, + 0,0,299,30,1,0,0,0,300,301,5,114,0,0,301,302,5,101,0,0,302,303,5, + 116,0,0,303,304,5,117,0,0,304,305,5,114,0,0,305,306,5,110,0,0,306, + 32,1,0,0,0,307,308,5,105,0,0,308,309,5,102,0,0,309,34,1,0,0,0,310, + 311,5,101,0,0,311,312,5,108,0,0,312,313,5,105,0,0,313,314,5,102, + 0,0,314,36,1,0,0,0,315,316,5,101,0,0,316,317,5,108,0,0,317,318,5, + 115,0,0,318,319,5,101,0,0,319,38,1,0,0,0,320,321,5,102,0,0,321,322, + 5,111,0,0,322,323,5,114,0,0,323,40,1,0,0,0,324,325,5,119,0,0,325, + 326,5,104,0,0,326,327,5,105,0,0,327,328,5,108,0,0,328,329,5,101, + 0,0,329,42,1,0,0,0,330,331,5,105,0,0,331,332,5,110,0,0,332,44,1, + 0,0,0,333,334,5,115,0,0,334,335,5,116,0,0,335,336,5,101,0,0,336, + 337,5,112,0,0,337,46,1,0,0,0,338,339,5,105,0,0,339,340,5,110,0,0, + 340,341,5,102,0,0,341,48,1,0,0,0,342,343,5,97,0,0,343,344,5,110, + 0,0,344,345,5,100,0,0,345,50,1,0,0,0,346,347,5,111,0,0,347,348,5, + 114,0,0,348,52,1,0,0,0,349,350,5,110,0,0,350,351,5,111,0,0,351,352, + 5,116,0,0,352,54,1,0,0,0,353,354,5,105,0,0,354,355,5,110,0,0,355, + 356,5,99,0,0,356,357,5,108,0,0,357,358,5,117,0,0,358,359,5,100,0, + 0,359,360,5,101,0,0,360,56,1,0,0,0,361,362,5,114,0,0,362,363,5,101, + 0,0,363,364,5,99,0,0,364,365,5,111,0,0,365,366,5,114,0,0,366,367, + 5,100,0,0,367,368,5,97,0,0,368,369,5,98,0,0,369,370,5,108,0,0,370, + 371,5,101,0,0,371,58,1,0,0,0,372,373,5,107,0,0,373,374,5,101,0,0, + 374,375,5,114,0,0,375,376,5,110,0,0,376,377,5,101,0,0,377,378,5, + 108,0,0,378,60,1,0,0,0,379,380,5,109,0,0,380,381,5,111,0,0,381,382, + 5,100,0,0,382,383,5,101,0,0,383,384,5,108,0,0,384,62,1,0,0,0,385, + 386,5,115,0,0,386,387,5,116,0,0,387,388,5,97,0,0,388,389,5,116,0, + 0,389,390,5,101,0,0,390,64,1,0,0,0,391,392,5,112,0,0,392,393,5,97, + 0,0,393,394,5,114,0,0,394,395,5,97,0,0,395,396,5,109,0,0,396,397, + 5,101,0,0,397,398,5,116,0,0,398,399,5,101,0,0,399,400,5,114,0,0, + 400,401,5,115,0,0,401,66,1,0,0,0,402,403,5,105,0,0,403,404,5,110, + 0,0,404,405,5,116,0,0,405,406,5,101,0,0,406,407,5,114,0,0,407,408, + 5,110,0,0,408,409,5,97,0,0,409,410,5,108,0,0,410,411,5,115,0,0,411, + 68,1,0,0,0,412,413,5,117,0,0,413,414,5,112,0,0,414,415,5,100,0,0, + 415,416,5,97,0,0,416,417,5,116,0,0,417,418,5,101,0,0,418,70,1,0, + 0,0,419,420,5,101,0,0,420,421,5,113,0,0,421,422,5,117,0,0,422,423, + 5,97,0,0,423,424,5,116,0,0,424,425,5,105,0,0,425,426,5,111,0,0,426, + 427,5,110,0,0,427,428,5,115,0,0,428,72,1,0,0,0,429,430,5,105,0,0, + 430,431,5,110,0,0,431,432,5,112,0,0,432,433,5,117,0,0,433,434,5, + 116,0,0,434,74,1,0,0,0,435,436,5,111,0,0,436,437,5,117,0,0,437,438, + 5,116,0,0,438,439,5,112,0,0,439,440,5,117,0,0,440,441,5,116,0,0, + 441,76,1,0,0,0,442,443,5,99,0,0,443,444,5,111,0,0,444,445,5,110, + 0,0,445,446,5,116,0,0,446,447,5,105,0,0,447,448,5,110,0,0,448,449, + 5,117,0,0,449,450,5,111,0,0,450,451,5,117,0,0,451,452,5,115,0,0, + 452,78,1,0,0,0,453,454,5,111,0,0,454,455,5,110,0,0,455,456,5,82, + 0,0,456,457,5,101,0,0,457,458,5,99,0,0,458,459,5,101,0,0,459,460, + 5,105,0,0,460,461,5,118,0,0,461,462,5,101,0,0,462,80,1,0,0,0,463, + 464,5,111,0,0,464,465,5,110,0,0,465,466,5,67,0,0,466,467,5,111,0, + 0,467,468,5,110,0,0,468,469,5,100,0,0,469,470,5,105,0,0,470,471, + 5,116,0,0,471,472,5,105,0,0,472,473,5,111,0,0,473,474,5,110,0,0, + 474,82,1,0,0,0,475,476,5,115,0,0,476,477,5,112,0,0,477,478,5,105, + 0,0,478,479,5,107,0,0,479,480,5,101,0,0,480,84,1,0,0,0,481,482,5, + 105,0,0,482,483,5,110,0,0,483,484,5,104,0,0,484,485,5,105,0,0,485, + 486,5,98,0,0,486,487,5,105,0,0,487,488,5,116,0,0,488,489,5,111,0, + 0,489,490,5,114,0,0,490,491,5,121,0,0,491,86,1,0,0,0,492,493,5,101, + 0,0,493,494,5,120,0,0,494,495,5,99,0,0,495,496,5,105,0,0,496,497, + 5,116,0,0,497,498,5,97,0,0,498,499,5,116,0,0,499,500,5,111,0,0,500, + 501,5,114,0,0,501,502,5,121,0,0,502,88,1,0,0,0,503,504,5,64,0,0, + 504,505,5,104,0,0,505,506,5,111,0,0,506,507,5,109,0,0,507,508,5, + 111,0,0,508,509,5,103,0,0,509,510,5,101,0,0,510,511,5,110,0,0,511, + 512,5,101,0,0,512,513,5,111,0,0,513,514,5,117,0,0,514,515,5,115, + 0,0,515,90,1,0,0,0,516,517,5,64,0,0,517,518,5,104,0,0,518,519,5, + 101,0,0,519,520,5,116,0,0,520,521,5,101,0,0,521,522,5,114,0,0,522, + 523,5,111,0,0,523,524,5,103,0,0,524,525,5,101,0,0,525,526,5,110, + 0,0,526,527,5,101,0,0,527,528,5,111,0,0,528,529,5,117,0,0,529,530, + 5,115,0,0,530,92,1,0,0,0,531,532,5,64,0,0,532,94,1,0,0,0,533,534, + 5,46,0,0,534,535,5,46,0,0,535,536,5,46,0,0,536,96,1,0,0,0,537,538, + 5,40,0,0,538,98,1,0,0,0,539,540,5,41,0,0,540,100,1,0,0,0,541,542, + 5,43,0,0,542,102,1,0,0,0,543,544,5,126,0,0,544,104,1,0,0,0,545,546, + 5,124,0,0,546,106,1,0,0,0,547,548,5,94,0,0,548,108,1,0,0,0,549,550, + 5,38,0,0,550,110,1,0,0,0,551,552,5,91,0,0,552,112,1,0,0,0,553,554, + 5,60,0,0,554,555,5,45,0,0,555,114,1,0,0,0,556,557,5,93,0,0,557,116, + 1,0,0,0,558,559,5,91,0,0,559,560,5,91,0,0,560,118,1,0,0,0,561,562, + 5,93,0,0,562,563,5,93,0,0,563,120,1,0,0,0,564,565,5,60,0,0,565,566, + 5,60,0,0,566,122,1,0,0,0,567,568,5,62,0,0,568,569,5,62,0,0,569,124, + 1,0,0,0,570,571,5,60,0,0,571,126,1,0,0,0,572,573,5,62,0,0,573,128, + 1,0,0,0,574,575,5,60,0,0,575,576,5,61,0,0,576,130,1,0,0,0,577,578, + 5,43,0,0,578,579,5,61,0,0,579,132,1,0,0,0,580,581,5,45,0,0,581,582, + 5,61,0,0,582,134,1,0,0,0,583,584,5,42,0,0,584,585,5,61,0,0,585,136, + 1,0,0,0,586,587,5,47,0,0,587,588,5,61,0,0,588,138,1,0,0,0,589,590, + 5,61,0,0,590,591,5,61,0,0,591,140,1,0,0,0,592,593,5,33,0,0,593,594, + 5,61,0,0,594,142,1,0,0,0,595,596,5,60,0,0,596,597,5,62,0,0,597,144, + 1,0,0,0,598,599,5,62,0,0,599,600,5,61,0,0,600,146,1,0,0,0,601,602, + 5,44,0,0,602,148,1,0,0,0,603,604,5,45,0,0,604,150,1,0,0,0,605,606, + 5,61,0,0,606,152,1,0,0,0,607,608,5,42,0,0,608,154,1,0,0,0,609,610, + 5,42,0,0,610,611,5,42,0,0,611,156,1,0,0,0,612,613,5,47,0,0,613,158, + 1,0,0,0,614,615,5,37,0,0,615,160,1,0,0,0,616,617,5,63,0,0,617,162, + 1,0,0,0,618,619,5,58,0,0,619,164,1,0,0,0,620,621,5,58,0,0,621,622, + 5,58,0,0,622,166,1,0,0,0,623,624,5,59,0,0,624,168,1,0,0,0,625,626, + 5,39,0,0,626,170,1,0,0,0,627,628,5,116,0,0,628,629,5,114,0,0,629, + 630,5,117,0,0,630,646,5,101,0,0,631,632,5,84,0,0,632,633,5,114,0, + 0,633,634,5,117,0,0,634,646,5,101,0,0,635,636,5,102,0,0,636,637, + 5,97,0,0,637,638,5,108,0,0,638,639,5,115,0,0,639,646,5,101,0,0,640, + 641,5,70,0,0,641,642,5,97,0,0,642,643,5,108,0,0,643,644,5,115,0, + 0,644,646,5,101,0,0,645,627,1,0,0,0,645,631,1,0,0,0,645,635,1,0, + 0,0,645,640,1,0,0,0,646,172,1,0,0,0,647,666,5,34,0,0,648,661,5,92, + 0,0,649,651,7,0,0,0,650,649,1,0,0,0,651,652,1,0,0,0,652,650,1,0, + 0,0,652,653,1,0,0,0,653,658,1,0,0,0,654,656,5,13,0,0,655,654,1,0, + 0,0,655,656,1,0,0,0,656,657,1,0,0,0,657,659,5,10,0,0,658,655,1,0, + 0,0,658,659,1,0,0,0,659,662,1,0,0,0,660,662,9,0,0,0,661,650,1,0, + 0,0,661,660,1,0,0,0,662,665,1,0,0,0,663,665,8,2,0,0,664,648,1,0, + 0,0,664,663,1,0,0,0,665,668,1,0,0,0,666,664,1,0,0,0,666,667,1,0, + 0,0,667,669,1,0,0,0,668,666,1,0,0,0,669,670,5,34,0,0,670,174,1,0, + 0,0,671,673,7,3,0,0,672,671,1,0,0,0,673,677,1,0,0,0,674,676,7,4, + 0,0,675,674,1,0,0,0,676,679,1,0,0,0,677,675,1,0,0,0,677,678,1,0, + 0,0,678,176,1,0,0,0,679,677,1,0,0,0,680,682,7,5,0,0,681,680,1,0, + 0,0,682,683,1,0,0,0,683,681,1,0,0,0,683,684,1,0,0,0,684,178,1,0, + 0,0,685,688,3,181,90,0,686,688,3,183,91,0,687,685,1,0,0,0,687,686, + 1,0,0,0,688,180,1,0,0,0,689,691,3,177,88,0,690,689,1,0,0,0,690,691, + 1,0,0,0,691,692,1,0,0,0,692,693,5,46,0,0,693,698,3,177,88,0,694, + 695,3,177,88,0,695,696,5,46,0,0,696,698,1,0,0,0,697,690,1,0,0,0, + 697,694,1,0,0,0,698,182,1,0,0,0,699,702,3,177,88,0,700,702,3,181, + 90,0,701,699,1,0,0,0,701,700,1,0,0,0,702,703,1,0,0,0,703,704,7,6, + 0,0,704,705,3,185,92,0,705,184,1,0,0,0,706,709,3,101,50,0,707,709, + 3,149,74,0,708,706,1,0,0,0,708,707,1,0,0,0,708,709,1,0,0,0,709,710, + 1,0,0,0,710,711,3,177,88,0,711,186,1,0,0,0,26,0,192,199,204,217, + 224,232,240,245,247,645,652,655,658,661,664,666,672,675,677,683, + 687,690,697,701,708,3,0,1,0,0,2,0,1,7,0 ] class PyNestMLLexer(PyNestMLLexerBase): @@ -304,68 +307,69 @@ class PyNestMLLexer(PyNestMLLexerBase): AND_KEYWORD = 26 OR_KEYWORD = 27 NOT_KEYWORD = 28 - RECORDABLE_KEYWORD = 29 - KERNEL_KEYWORD = 30 - MODEL_KEYWORD = 31 - STATE_KEYWORD = 32 - PARAMETERS_KEYWORD = 33 - INTERNALS_KEYWORD = 34 - UPDATE_KEYWORD = 35 - EQUATIONS_KEYWORD = 36 - INPUT_KEYWORD = 37 - OUTPUT_KEYWORD = 38 - CONTINUOUS_KEYWORD = 39 - ON_RECEIVE_KEYWORD = 40 - ON_CONDITION_KEYWORD = 41 - SPIKE_KEYWORD = 42 - INHIBITORY_KEYWORD = 43 - EXCITATORY_KEYWORD = 44 - DECORATOR_HOMOGENEOUS = 45 - DECORATOR_HETEROGENEOUS = 46 - AT = 47 - ELLIPSIS = 48 - LEFT_PAREN = 49 - RIGHT_PAREN = 50 - PLUS = 51 - TILDE = 52 - PIPE = 53 - CARET = 54 - AMPERSAND = 55 - LEFT_SQUARE_BRACKET = 56 - LEFT_ANGLE_MINUS = 57 - RIGHT_SQUARE_BRACKET = 58 - LEFT_LEFT_SQUARE = 59 - RIGHT_RIGHT_SQUARE = 60 - LEFT_LEFT_ANGLE = 61 - RIGHT_RIGHT_ANGLE = 62 - LEFT_ANGLE = 63 - RIGHT_ANGLE = 64 - LEFT_ANGLE_EQUALS = 65 - PLUS_EQUALS = 66 - MINUS_EQUALS = 67 - STAR_EQUALS = 68 - FORWARD_SLASH_EQUALS = 69 - EQUALS_EQUALS = 70 - EXCLAMATION_EQUALS = 71 - LEFT_ANGLE_RIGHT_ANGLE = 72 - RIGHT_ANGLE_EQUALS = 73 - COMMA = 74 - MINUS = 75 - EQUALS = 76 - STAR = 77 - STAR_STAR = 78 - FORWARD_SLASH = 79 - PERCENT = 80 - QUESTION = 81 - COLON = 82 - DOUBLE_COLON = 83 - SEMICOLON = 84 - DIFFERENTIAL_ORDER = 85 - BOOLEAN_LITERAL = 86 - STRING_LITERAL = 87 - NAME = 88 - UNSIGNED_INTEGER = 89 - FLOAT = 90 + INCLUDE_KEYWORD = 29 + RECORDABLE_KEYWORD = 30 + KERNEL_KEYWORD = 31 + MODEL_KEYWORD = 32 + STATE_KEYWORD = 33 + PARAMETERS_KEYWORD = 34 + INTERNALS_KEYWORD = 35 + UPDATE_KEYWORD = 36 + EQUATIONS_KEYWORD = 37 + INPUT_KEYWORD = 38 + OUTPUT_KEYWORD = 39 + CONTINUOUS_KEYWORD = 40 + ON_RECEIVE_KEYWORD = 41 + ON_CONDITION_KEYWORD = 42 + SPIKE_KEYWORD = 43 + INHIBITORY_KEYWORD = 44 + EXCITATORY_KEYWORD = 45 + DECORATOR_HOMOGENEOUS = 46 + DECORATOR_HETEROGENEOUS = 47 + AT = 48 + ELLIPSIS = 49 + LEFT_PAREN = 50 + RIGHT_PAREN = 51 + PLUS = 52 + TILDE = 53 + PIPE = 54 + CARET = 55 + AMPERSAND = 56 + LEFT_SQUARE_BRACKET = 57 + LEFT_ANGLE_MINUS = 58 + RIGHT_SQUARE_BRACKET = 59 + LEFT_LEFT_SQUARE = 60 + RIGHT_RIGHT_SQUARE = 61 + LEFT_LEFT_ANGLE = 62 + RIGHT_RIGHT_ANGLE = 63 + LEFT_ANGLE = 64 + RIGHT_ANGLE = 65 + LEFT_ANGLE_EQUALS = 66 + PLUS_EQUALS = 67 + MINUS_EQUALS = 68 + STAR_EQUALS = 69 + FORWARD_SLASH_EQUALS = 70 + EQUALS_EQUALS = 71 + EXCLAMATION_EQUALS = 72 + LEFT_ANGLE_RIGHT_ANGLE = 73 + RIGHT_ANGLE_EQUALS = 74 + COMMA = 75 + MINUS = 76 + EQUALS = 77 + STAR = 78 + STAR_STAR = 79 + FORWARD_SLASH = 80 + PERCENT = 81 + QUESTION = 82 + COLON = 83 + DOUBLE_COLON = 84 + SEMICOLON = 85 + DIFFERENTIAL_ORDER = 86 + BOOLEAN_LITERAL = 87 + STRING_LITERAL = 88 + NAME = 89 + UNSIGNED_INTEGER = 90 + FLOAT = 91 channelNames = [ u"DEFAULT_TOKEN_CHANNEL", u"HIDDEN", u"COMMENT" ] @@ -375,9 +379,9 @@ class PyNestMLLexer(PyNestMLLexerBase): "'\"\"\"'", "'integer'", "'real'", "'string'", "'boolean'", "'void'", "'function'", "'inline'", "'return'", "'if'", "'elif'", "'else'", "'for'", "'while'", "'in'", "'step'", "'inf'", "'and'", - "'or'", "'not'", "'recordable'", "'kernel'", "'model'", "'state'", - "'parameters'", "'internals'", "'update'", "'equations'", "'input'", - "'output'", "'continuous'", "'onReceive'", "'onCondition'", + "'or'", "'not'", "'include'", "'recordable'", "'kernel'", "'model'", + "'state'", "'parameters'", "'internals'", "'update'", "'equations'", + "'input'", "'output'", "'continuous'", "'onReceive'", "'onCondition'", "'spike'", "'inhibitory'", "'excitatory'", "'@homogeneous'", "'@heterogeneous'", "'@'", "'...'", "'('", "')'", "'+'", "'~'", "'|'", "'^'", "'&'", "'['", "'<-'", "']'", "'[['", "']]'", "'<<'", @@ -392,22 +396,23 @@ class PyNestMLLexer(PyNestMLLexerBase): "FUNCTION_KEYWORD", "INLINE_KEYWORD", "RETURN_KEYWORD", "IF_KEYWORD", "ELIF_KEYWORD", "ELSE_KEYWORD", "FOR_KEYWORD", "WHILE_KEYWORD", "IN_KEYWORD", "STEP_KEYWORD", "INF_KEYWORD", "AND_KEYWORD", - "OR_KEYWORD", "NOT_KEYWORD", "RECORDABLE_KEYWORD", "KERNEL_KEYWORD", - "MODEL_KEYWORD", "STATE_KEYWORD", "PARAMETERS_KEYWORD", "INTERNALS_KEYWORD", - "UPDATE_KEYWORD", "EQUATIONS_KEYWORD", "INPUT_KEYWORD", "OUTPUT_KEYWORD", - "CONTINUOUS_KEYWORD", "ON_RECEIVE_KEYWORD", "ON_CONDITION_KEYWORD", - "SPIKE_KEYWORD", "INHIBITORY_KEYWORD", "EXCITATORY_KEYWORD", - "DECORATOR_HOMOGENEOUS", "DECORATOR_HETEROGENEOUS", "AT", "ELLIPSIS", - "LEFT_PAREN", "RIGHT_PAREN", "PLUS", "TILDE", "PIPE", "CARET", - "AMPERSAND", "LEFT_SQUARE_BRACKET", "LEFT_ANGLE_MINUS", "RIGHT_SQUARE_BRACKET", - "LEFT_LEFT_SQUARE", "RIGHT_RIGHT_SQUARE", "LEFT_LEFT_ANGLE", - "RIGHT_RIGHT_ANGLE", "LEFT_ANGLE", "RIGHT_ANGLE", "LEFT_ANGLE_EQUALS", - "PLUS_EQUALS", "MINUS_EQUALS", "STAR_EQUALS", "FORWARD_SLASH_EQUALS", - "EQUALS_EQUALS", "EXCLAMATION_EQUALS", "LEFT_ANGLE_RIGHT_ANGLE", - "RIGHT_ANGLE_EQUALS", "COMMA", "MINUS", "EQUALS", "STAR", "STAR_STAR", - "FORWARD_SLASH", "PERCENT", "QUESTION", "COLON", "DOUBLE_COLON", - "SEMICOLON", "DIFFERENTIAL_ORDER", "BOOLEAN_LITERAL", "STRING_LITERAL", - "NAME", "UNSIGNED_INTEGER", "FLOAT" ] + "OR_KEYWORD", "NOT_KEYWORD", "INCLUDE_KEYWORD", "RECORDABLE_KEYWORD", + "KERNEL_KEYWORD", "MODEL_KEYWORD", "STATE_KEYWORD", "PARAMETERS_KEYWORD", + "INTERNALS_KEYWORD", "UPDATE_KEYWORD", "EQUATIONS_KEYWORD", + "INPUT_KEYWORD", "OUTPUT_KEYWORD", "CONTINUOUS_KEYWORD", "ON_RECEIVE_KEYWORD", + "ON_CONDITION_KEYWORD", "SPIKE_KEYWORD", "INHIBITORY_KEYWORD", + "EXCITATORY_KEYWORD", "DECORATOR_HOMOGENEOUS", "DECORATOR_HETEROGENEOUS", + "AT", "ELLIPSIS", "LEFT_PAREN", "RIGHT_PAREN", "PLUS", "TILDE", + "PIPE", "CARET", "AMPERSAND", "LEFT_SQUARE_BRACKET", "LEFT_ANGLE_MINUS", + "RIGHT_SQUARE_BRACKET", "LEFT_LEFT_SQUARE", "RIGHT_RIGHT_SQUARE", + "LEFT_LEFT_ANGLE", "RIGHT_RIGHT_ANGLE", "LEFT_ANGLE", "RIGHT_ANGLE", + "LEFT_ANGLE_EQUALS", "PLUS_EQUALS", "MINUS_EQUALS", "STAR_EQUALS", + "FORWARD_SLASH_EQUALS", "EQUALS_EQUALS", "EXCLAMATION_EQUALS", + "LEFT_ANGLE_RIGHT_ANGLE", "RIGHT_ANGLE_EQUALS", "COMMA", "MINUS", + "EQUALS", "STAR", "STAR_STAR", "FORWARD_SLASH", "PERCENT", "QUESTION", + "COLON", "DOUBLE_COLON", "SEMICOLON", "DIFFERENTIAL_ORDER", + "BOOLEAN_LITERAL", "STRING_LITERAL", "NAME", "UNSIGNED_INTEGER", + "FLOAT" ] ruleNames = [ "DOCSTRING_TRIPLEQUOTE", "NEWLINE_FRAG", "KERNEL_JOINING", "WS", "LINE_ESCAPE", "DOCSTRING", "SL_COMMENT", "NEWLINE", @@ -416,18 +421,18 @@ class PyNestMLLexer(PyNestMLLexerBase): "RETURN_KEYWORD", "IF_KEYWORD", "ELIF_KEYWORD", "ELSE_KEYWORD", "FOR_KEYWORD", "WHILE_KEYWORD", "IN_KEYWORD", "STEP_KEYWORD", "INF_KEYWORD", "AND_KEYWORD", "OR_KEYWORD", "NOT_KEYWORD", - "RECORDABLE_KEYWORD", "KERNEL_KEYWORD", "MODEL_KEYWORD", - "STATE_KEYWORD", "PARAMETERS_KEYWORD", "INTERNALS_KEYWORD", - "UPDATE_KEYWORD", "EQUATIONS_KEYWORD", "INPUT_KEYWORD", - "OUTPUT_KEYWORD", "CONTINUOUS_KEYWORD", "ON_RECEIVE_KEYWORD", - "ON_CONDITION_KEYWORD", "SPIKE_KEYWORD", "INHIBITORY_KEYWORD", - "EXCITATORY_KEYWORD", "DECORATOR_HOMOGENEOUS", "DECORATOR_HETEROGENEOUS", - "AT", "ELLIPSIS", "LEFT_PAREN", "RIGHT_PAREN", "PLUS", - "TILDE", "PIPE", "CARET", "AMPERSAND", "LEFT_SQUARE_BRACKET", - "LEFT_ANGLE_MINUS", "RIGHT_SQUARE_BRACKET", "LEFT_LEFT_SQUARE", - "RIGHT_RIGHT_SQUARE", "LEFT_LEFT_ANGLE", "RIGHT_RIGHT_ANGLE", - "LEFT_ANGLE", "RIGHT_ANGLE", "LEFT_ANGLE_EQUALS", "PLUS_EQUALS", - "MINUS_EQUALS", "STAR_EQUALS", "FORWARD_SLASH_EQUALS", + "INCLUDE_KEYWORD", "RECORDABLE_KEYWORD", "KERNEL_KEYWORD", + "MODEL_KEYWORD", "STATE_KEYWORD", "PARAMETERS_KEYWORD", + "INTERNALS_KEYWORD", "UPDATE_KEYWORD", "EQUATIONS_KEYWORD", + "INPUT_KEYWORD", "OUTPUT_KEYWORD", "CONTINUOUS_KEYWORD", + "ON_RECEIVE_KEYWORD", "ON_CONDITION_KEYWORD", "SPIKE_KEYWORD", + "INHIBITORY_KEYWORD", "EXCITATORY_KEYWORD", "DECORATOR_HOMOGENEOUS", + "DECORATOR_HETEROGENEOUS", "AT", "ELLIPSIS", "LEFT_PAREN", + "RIGHT_PAREN", "PLUS", "TILDE", "PIPE", "CARET", "AMPERSAND", + "LEFT_SQUARE_BRACKET", "LEFT_ANGLE_MINUS", "RIGHT_SQUARE_BRACKET", + "LEFT_LEFT_SQUARE", "RIGHT_RIGHT_SQUARE", "LEFT_LEFT_ANGLE", + "RIGHT_RIGHT_ANGLE", "LEFT_ANGLE", "RIGHT_ANGLE", "LEFT_ANGLE_EQUALS", + "PLUS_EQUALS", "MINUS_EQUALS", "STAR_EQUALS", "FORWARD_SLASH_EQUALS", "EQUALS_EQUALS", "EXCLAMATION_EQUALS", "LEFT_ANGLE_RIGHT_ANGLE", "RIGHT_ANGLE_EQUALS", "COMMA", "MINUS", "EQUALS", "STAR", "STAR_STAR", "FORWARD_SLASH", "PERCENT", "QUESTION", "COLON", @@ -439,7 +444,7 @@ class PyNestMLLexer(PyNestMLLexerBase): def __init__(self, input=None, output:TextIO = sys.stdout): super().__init__(input, output) - self.checkVersion("4.13.1") + self.checkVersion("4.13.0") self._interp = LexerATNSimulator(self, self.atn, self.decisionsToDFA, PredictionContextCache()) self._actions = None self._predicates = None diff --git a/pynestml/generated/PyNestMLParser.py b/pynestml/generated/PyNestMLParser.py index ecb08158a..622399583 100644 --- a/pynestml/generated/PyNestMLParser.py +++ b/pynestml/generated/PyNestMLParser.py @@ -1,4 +1,4 @@ -# Generated from PyNestMLParser.g4 by ANTLR 4.13.1 +# Generated from PyNestMLParser.g4 by ANTLR 4.13.0 # encoding: utf-8 from antlr4 import * from io import StringIO @@ -10,226 +10,231 @@ def serializedATN(): return [ - 4,1,90,598,2,0,7,0,2,1,7,1,2,2,7,2,2,3,7,3,2,4,7,4,2,5,7,5,2,6,7, + 4,1,91,611,2,0,7,0,2,1,7,1,2,2,7,2,2,3,7,3,2,4,7,4,2,5,7,5,2,6,7, 6,2,7,7,7,2,8,7,8,2,9,7,9,2,10,7,10,2,11,7,11,2,12,7,12,2,13,7,13, 2,14,7,14,2,15,7,15,2,16,7,16,2,17,7,17,2,18,7,18,2,19,7,19,2,20, 7,20,2,21,7,21,2,22,7,22,2,23,7,23,2,24,7,24,2,25,7,25,2,26,7,26, 2,27,7,27,2,28,7,28,2,29,7,29,2,30,7,30,2,31,7,31,2,32,7,32,2,33, 7,33,2,34,7,34,2,35,7,35,2,36,7,36,2,37,7,37,2,38,7,38,2,39,7,39, 2,40,7,40,2,41,7,41,2,42,7,42,2,43,7,43,2,44,7,44,2,45,7,45,2,46, - 7,46,1,0,1,0,1,0,1,0,1,0,1,0,3,0,101,8,0,1,1,1,1,1,1,1,1,1,1,1,1, - 1,1,1,1,1,1,3,1,112,8,1,1,1,1,1,1,1,3,1,117,8,1,1,1,1,1,1,1,1,1, - 5,1,123,8,1,10,1,12,1,126,9,1,1,2,3,2,129,8,2,1,2,1,2,1,3,1,3,1, - 3,1,3,1,3,1,3,1,3,1,3,1,3,1,3,1,3,3,3,144,8,3,1,3,1,3,1,3,1,3,1, - 3,1,3,1,3,3,3,153,8,3,1,3,1,3,1,3,1,3,3,3,159,8,3,1,3,1,3,1,3,1, - 3,1,3,1,3,1,3,1,3,1,3,1,3,1,3,1,3,1,3,1,3,1,3,1,3,1,3,1,3,1,3,5, - 3,180,8,3,10,3,12,3,183,9,3,1,4,1,4,1,4,1,4,3,4,189,8,4,1,4,1,4, - 1,4,3,4,194,8,4,1,5,1,5,1,5,3,5,199,8,5,1,6,1,6,1,6,1,6,1,6,3,6, - 206,8,6,1,7,1,7,1,7,1,7,1,7,1,7,1,7,3,7,215,8,7,1,8,1,8,3,8,219, - 8,8,1,9,1,9,1,9,1,9,1,9,3,9,226,8,9,1,9,5,9,229,8,9,10,9,12,9,232, - 9,9,1,10,1,10,1,10,1,10,1,10,5,10,239,8,10,10,10,12,10,242,9,10, - 3,10,244,8,10,1,10,1,10,1,11,3,11,249,8,11,1,11,1,11,1,11,1,11,1, - 11,1,11,3,11,257,8,11,1,11,5,11,260,8,11,10,11,12,11,263,9,11,1, - 11,1,11,1,12,1,12,1,12,1,12,3,12,271,8,12,1,12,5,12,274,8,12,10, - 12,12,12,277,9,12,1,12,1,12,1,13,1,13,1,13,1,13,1,13,1,13,1,13,1, - 13,1,13,5,13,290,8,13,10,13,12,13,293,9,13,1,13,3,13,296,8,13,1, - 13,1,13,1,14,1,14,1,14,4,14,303,8,14,11,14,12,14,304,1,14,1,14,1, - 15,1,15,3,15,311,8,15,1,16,1,16,1,16,3,16,316,8,16,1,17,1,17,1,17, - 1,17,3,17,322,8,17,1,17,1,17,1,18,1,18,1,18,1,18,1,18,1,18,3,18, - 332,8,18,1,18,1,18,1,19,3,19,337,8,19,1,19,3,19,340,8,19,1,19,1, - 19,1,19,5,19,345,8,19,10,19,12,19,348,9,19,1,19,1,19,1,19,3,19,353, - 8,19,1,19,1,19,1,19,1,19,3,19,359,8,19,1,19,5,19,362,8,19,10,19, - 12,19,365,9,19,1,20,1,20,1,20,1,21,1,21,1,21,1,21,1,21,1,21,1,21, - 3,21,377,8,21,1,22,1,22,1,23,1,23,1,24,1,24,3,24,385,8,24,1,25,1, - 25,5,25,389,8,25,10,25,12,25,392,9,25,1,25,3,25,395,8,25,1,26,1, - 26,1,26,1,26,1,26,1,27,1,27,1,27,1,27,1,27,1,28,1,28,1,28,1,28,1, - 29,1,29,1,29,1,29,1,29,1,29,1,29,1,29,3,29,419,8,29,1,29,1,29,1, - 29,1,29,1,30,1,30,1,30,1,30,1,30,1,31,1,31,4,31,432,8,31,11,31,12, - 31,433,1,31,1,31,1,32,1,32,1,32,1,32,1,33,1,33,1,33,1,33,1,33,1, - 33,1,33,1,33,1,33,1,33,1,33,4,33,453,8,33,11,33,12,33,454,1,33,1, - 33,1,34,1,34,1,34,1,34,1,34,5,34,464,8,34,10,34,12,34,467,9,34,1, - 34,1,34,1,34,1,34,1,35,1,35,1,35,1,35,1,35,5,35,478,8,35,10,35,12, - 35,481,9,35,1,35,1,35,1,35,1,35,1,36,1,36,1,36,1,36,1,36,4,36,492, - 8,36,11,36,12,36,493,1,36,1,36,1,37,1,37,1,37,1,37,1,38,1,38,1,38, - 1,38,1,38,1,38,1,38,4,38,509,8,38,11,38,12,38,510,1,38,1,38,1,39, - 1,39,1,39,1,39,1,39,1,39,4,39,521,8,39,11,39,12,39,522,1,39,1,39, - 1,40,1,40,1,40,1,40,1,40,3,40,532,8,40,1,40,1,40,5,40,536,8,40,10, - 40,12,40,539,9,40,1,40,1,40,1,40,1,41,1,41,1,41,1,41,1,41,3,41,549, - 8,41,1,41,1,41,1,41,1,41,1,41,1,42,1,42,3,42,558,8,42,1,43,1,43, - 1,43,1,43,1,43,1,43,3,43,566,8,43,1,43,1,43,1,43,1,44,1,44,1,44, - 1,44,1,44,1,44,5,44,577,8,44,10,44,12,44,580,9,44,3,44,582,8,44, - 1,44,1,44,3,44,586,8,44,1,44,1,44,1,44,1,45,1,45,1,45,1,46,1,46, - 1,46,1,46,1,46,0,2,2,6,47,0,2,4,6,8,10,12,14,16,18,20,22,24,26,28, - 30,32,34,36,38,40,42,44,46,48,50,52,54,56,58,60,62,64,66,68,70,72, - 74,76,78,80,82,84,86,88,90,92,0,4,2,0,51,51,75,75,1,0,89,90,1,0, - 32,34,3,0,25,25,86,87,89,90,653,0,100,1,0,0,0,2,111,1,0,0,0,4,128, - 1,0,0,0,6,143,1,0,0,0,8,193,1,0,0,0,10,198,1,0,0,0,12,205,1,0,0, - 0,14,214,1,0,0,0,16,218,1,0,0,0,18,220,1,0,0,0,20,233,1,0,0,0,22, - 248,1,0,0,0,24,266,1,0,0,0,26,280,1,0,0,0,28,299,1,0,0,0,30,310, - 1,0,0,0,32,315,1,0,0,0,34,321,1,0,0,0,36,325,1,0,0,0,38,336,1,0, - 0,0,40,366,1,0,0,0,42,376,1,0,0,0,44,378,1,0,0,0,46,380,1,0,0,0, - 48,382,1,0,0,0,50,386,1,0,0,0,52,396,1,0,0,0,54,401,1,0,0,0,56,406, - 1,0,0,0,58,410,1,0,0,0,60,424,1,0,0,0,62,431,1,0,0,0,64,437,1,0, - 0,0,66,441,1,0,0,0,68,458,1,0,0,0,70,472,1,0,0,0,72,486,1,0,0,0, - 74,497,1,0,0,0,76,501,1,0,0,0,78,514,1,0,0,0,80,526,1,0,0,0,82,543, - 1,0,0,0,84,557,1,0,0,0,86,559,1,0,0,0,88,570,1,0,0,0,90,590,1,0, - 0,0,92,593,1,0,0,0,94,101,5,10,0,0,95,101,5,11,0,0,96,101,5,12,0, - 0,97,101,5,13,0,0,98,101,5,14,0,0,99,101,3,2,1,0,100,94,1,0,0,0, - 100,95,1,0,0,0,100,96,1,0,0,0,100,97,1,0,0,0,100,98,1,0,0,0,100, - 99,1,0,0,0,101,1,1,0,0,0,102,103,6,1,-1,0,103,104,5,49,0,0,104,105, - 3,2,1,0,105,106,5,50,0,0,106,112,1,0,0,0,107,108,5,89,0,0,108,109, - 5,79,0,0,109,112,3,2,1,2,110,112,5,88,0,0,111,102,1,0,0,0,111,107, - 1,0,0,0,111,110,1,0,0,0,112,124,1,0,0,0,113,116,10,3,0,0,114,117, - 5,77,0,0,115,117,5,79,0,0,116,114,1,0,0,0,116,115,1,0,0,0,117,118, - 1,0,0,0,118,123,3,2,1,4,119,120,10,4,0,0,120,121,5,78,0,0,121,123, - 3,4,2,0,122,113,1,0,0,0,122,119,1,0,0,0,123,126,1,0,0,0,124,122, - 1,0,0,0,124,125,1,0,0,0,125,3,1,0,0,0,126,124,1,0,0,0,127,129,7, - 0,0,0,128,127,1,0,0,0,128,129,1,0,0,0,129,130,1,0,0,0,130,131,5, - 89,0,0,131,5,1,0,0,0,132,133,6,3,-1,0,133,134,5,49,0,0,134,135,3, - 6,3,0,135,136,5,50,0,0,136,144,1,0,0,0,137,138,3,10,5,0,138,139, - 3,6,3,9,139,144,1,0,0,0,140,141,5,28,0,0,141,144,3,6,3,4,142,144, - 3,8,4,0,143,132,1,0,0,0,143,137,1,0,0,0,143,140,1,0,0,0,143,142, - 1,0,0,0,144,181,1,0,0,0,145,146,10,10,0,0,146,147,5,78,0,0,147,180, - 3,6,3,10,148,152,10,8,0,0,149,153,5,77,0,0,150,153,5,79,0,0,151, - 153,5,80,0,0,152,149,1,0,0,0,152,150,1,0,0,0,152,151,1,0,0,0,153, - 154,1,0,0,0,154,180,3,6,3,9,155,158,10,7,0,0,156,159,5,51,0,0,157, - 159,5,75,0,0,158,156,1,0,0,0,158,157,1,0,0,0,159,160,1,0,0,0,160, - 180,3,6,3,8,161,162,10,6,0,0,162,163,3,12,6,0,163,164,3,6,3,7,164, - 180,1,0,0,0,165,166,10,5,0,0,166,167,3,14,7,0,167,168,3,6,3,6,168, - 180,1,0,0,0,169,170,10,3,0,0,170,171,3,16,8,0,171,172,3,6,3,4,172, - 180,1,0,0,0,173,174,10,2,0,0,174,175,5,81,0,0,175,176,3,6,3,0,176, - 177,5,82,0,0,177,178,3,6,3,3,178,180,1,0,0,0,179,145,1,0,0,0,179, - 148,1,0,0,0,179,155,1,0,0,0,179,161,1,0,0,0,179,165,1,0,0,0,179, - 169,1,0,0,0,179,173,1,0,0,0,180,183,1,0,0,0,181,179,1,0,0,0,181, - 182,1,0,0,0,182,7,1,0,0,0,183,181,1,0,0,0,184,194,3,20,10,0,185, - 194,5,86,0,0,186,188,7,1,0,0,187,189,3,18,9,0,188,187,1,0,0,0,188, - 189,1,0,0,0,189,194,1,0,0,0,190,194,5,87,0,0,191,194,5,25,0,0,192, - 194,3,18,9,0,193,184,1,0,0,0,193,185,1,0,0,0,193,186,1,0,0,0,193, - 190,1,0,0,0,193,191,1,0,0,0,193,192,1,0,0,0,194,9,1,0,0,0,195,199, - 5,51,0,0,196,199,5,75,0,0,197,199,5,52,0,0,198,195,1,0,0,0,198,196, - 1,0,0,0,198,197,1,0,0,0,199,11,1,0,0,0,200,206,5,55,0,0,201,206, - 5,54,0,0,202,206,5,53,0,0,203,206,5,61,0,0,204,206,5,62,0,0,205, - 200,1,0,0,0,205,201,1,0,0,0,205,202,1,0,0,0,205,203,1,0,0,0,205, - 204,1,0,0,0,206,13,1,0,0,0,207,215,5,63,0,0,208,215,5,65,0,0,209, - 215,5,70,0,0,210,215,5,71,0,0,211,215,5,72,0,0,212,215,5,73,0,0, - 213,215,5,64,0,0,214,207,1,0,0,0,214,208,1,0,0,0,214,209,1,0,0,0, - 214,210,1,0,0,0,214,211,1,0,0,0,214,212,1,0,0,0,214,213,1,0,0,0, - 215,15,1,0,0,0,216,219,5,26,0,0,217,219,5,27,0,0,218,216,1,0,0,0, - 218,217,1,0,0,0,219,17,1,0,0,0,220,225,5,88,0,0,221,222,5,56,0,0, - 222,223,3,6,3,0,223,224,5,58,0,0,224,226,1,0,0,0,225,221,1,0,0,0, - 225,226,1,0,0,0,226,230,1,0,0,0,227,229,5,85,0,0,228,227,1,0,0,0, - 229,232,1,0,0,0,230,228,1,0,0,0,230,231,1,0,0,0,231,19,1,0,0,0,232, - 230,1,0,0,0,233,234,5,88,0,0,234,243,5,49,0,0,235,240,3,6,3,0,236, - 237,5,74,0,0,237,239,3,6,3,0,238,236,1,0,0,0,239,242,1,0,0,0,240, - 238,1,0,0,0,240,241,1,0,0,0,241,244,1,0,0,0,242,240,1,0,0,0,243, - 235,1,0,0,0,243,244,1,0,0,0,244,245,1,0,0,0,245,246,5,50,0,0,246, - 21,1,0,0,0,247,249,5,29,0,0,248,247,1,0,0,0,248,249,1,0,0,0,249, - 250,1,0,0,0,250,251,5,16,0,0,251,252,5,88,0,0,252,253,3,0,0,0,253, - 254,5,76,0,0,254,256,3,6,3,0,255,257,5,84,0,0,256,255,1,0,0,0,256, - 257,1,0,0,0,257,261,1,0,0,0,258,260,3,42,21,0,259,258,1,0,0,0,260, - 263,1,0,0,0,261,259,1,0,0,0,261,262,1,0,0,0,262,264,1,0,0,0,263, - 261,1,0,0,0,264,265,5,9,0,0,265,23,1,0,0,0,266,267,3,18,9,0,267, - 268,5,76,0,0,268,270,3,6,3,0,269,271,5,84,0,0,270,269,1,0,0,0,270, - 271,1,0,0,0,271,275,1,0,0,0,272,274,3,42,21,0,273,272,1,0,0,0,274, - 277,1,0,0,0,275,273,1,0,0,0,275,276,1,0,0,0,276,278,1,0,0,0,277, - 275,1,0,0,0,278,279,5,9,0,0,279,25,1,0,0,0,280,281,5,30,0,0,281, - 282,3,18,9,0,282,283,5,76,0,0,283,291,3,6,3,0,284,285,5,4,0,0,285, - 286,3,18,9,0,286,287,5,76,0,0,287,288,3,6,3,0,288,290,1,0,0,0,289, - 284,1,0,0,0,290,293,1,0,0,0,291,289,1,0,0,0,291,292,1,0,0,0,292, - 295,1,0,0,0,293,291,1,0,0,0,294,296,5,84,0,0,295,294,1,0,0,0,295, - 296,1,0,0,0,296,297,1,0,0,0,297,298,5,9,0,0,298,27,1,0,0,0,299,300, - 5,9,0,0,300,302,5,1,0,0,301,303,3,30,15,0,302,301,1,0,0,0,303,304, - 1,0,0,0,304,302,1,0,0,0,304,305,1,0,0,0,305,306,1,0,0,0,306,307, - 5,2,0,0,307,29,1,0,0,0,308,311,3,34,17,0,309,311,3,32,16,0,310,308, - 1,0,0,0,310,309,1,0,0,0,311,31,1,0,0,0,312,316,3,50,25,0,313,316, - 3,58,29,0,314,316,3,60,30,0,315,312,1,0,0,0,315,313,1,0,0,0,315, - 314,1,0,0,0,316,33,1,0,0,0,317,322,3,36,18,0,318,322,3,20,10,0,319, - 322,3,38,19,0,320,322,3,48,24,0,321,317,1,0,0,0,321,318,1,0,0,0, - 321,319,1,0,0,0,321,320,1,0,0,0,322,323,1,0,0,0,323,324,5,9,0,0, - 324,35,1,0,0,0,325,331,3,18,9,0,326,332,5,76,0,0,327,332,5,66,0, - 0,328,332,5,67,0,0,329,332,5,68,0,0,330,332,5,69,0,0,331,326,1,0, - 0,0,331,327,1,0,0,0,331,328,1,0,0,0,331,329,1,0,0,0,331,330,1,0, - 0,0,332,333,1,0,0,0,333,334,3,6,3,0,334,37,1,0,0,0,335,337,5,29, - 0,0,336,335,1,0,0,0,336,337,1,0,0,0,337,339,1,0,0,0,338,340,5,16, - 0,0,339,338,1,0,0,0,339,340,1,0,0,0,340,341,1,0,0,0,341,346,3,18, - 9,0,342,343,5,74,0,0,343,345,3,18,9,0,344,342,1,0,0,0,345,348,1, - 0,0,0,346,344,1,0,0,0,346,347,1,0,0,0,347,349,1,0,0,0,348,346,1, - 0,0,0,349,352,3,0,0,0,350,351,5,76,0,0,351,353,3,6,3,0,352,350,1, - 0,0,0,352,353,1,0,0,0,353,358,1,0,0,0,354,355,5,59,0,0,355,356,3, - 6,3,0,356,357,5,60,0,0,357,359,1,0,0,0,358,354,1,0,0,0,358,359,1, - 0,0,0,359,363,1,0,0,0,360,362,3,42,21,0,361,360,1,0,0,0,362,365, - 1,0,0,0,363,361,1,0,0,0,363,364,1,0,0,0,364,39,1,0,0,0,365,363,1, - 0,0,0,366,367,3,38,19,0,367,368,5,9,0,0,368,41,1,0,0,0,369,377,5, - 45,0,0,370,377,5,46,0,0,371,372,5,47,0,0,372,373,3,44,22,0,373,374, - 5,83,0,0,374,375,3,46,23,0,375,377,1,0,0,0,376,369,1,0,0,0,376,370, - 1,0,0,0,376,371,1,0,0,0,377,43,1,0,0,0,378,379,5,88,0,0,379,45,1, - 0,0,0,380,381,5,88,0,0,381,47,1,0,0,0,382,384,5,17,0,0,383,385,3, - 6,3,0,384,383,1,0,0,0,384,385,1,0,0,0,385,49,1,0,0,0,386,390,3,52, - 26,0,387,389,3,54,27,0,388,387,1,0,0,0,389,392,1,0,0,0,390,388,1, - 0,0,0,390,391,1,0,0,0,391,394,1,0,0,0,392,390,1,0,0,0,393,395,3, - 56,28,0,394,393,1,0,0,0,394,395,1,0,0,0,395,51,1,0,0,0,396,397,5, - 18,0,0,397,398,3,6,3,0,398,399,5,82,0,0,399,400,3,28,14,0,400,53, - 1,0,0,0,401,402,5,19,0,0,402,403,3,6,3,0,403,404,5,82,0,0,404,405, - 3,28,14,0,405,55,1,0,0,0,406,407,5,20,0,0,407,408,5,82,0,0,408,409, - 3,28,14,0,409,57,1,0,0,0,410,411,5,21,0,0,411,412,5,88,0,0,412,413, - 5,23,0,0,413,414,3,6,3,0,414,415,5,48,0,0,415,416,3,6,3,0,416,418, - 5,24,0,0,417,419,5,75,0,0,418,417,1,0,0,0,418,419,1,0,0,0,419,420, - 1,0,0,0,420,421,7,1,0,0,421,422,5,82,0,0,422,423,3,28,14,0,423,59, - 1,0,0,0,424,425,5,22,0,0,425,426,3,6,3,0,426,427,5,82,0,0,427,428, - 3,28,14,0,428,61,1,0,0,0,429,432,3,64,32,0,430,432,5,9,0,0,431,429, - 1,0,0,0,431,430,1,0,0,0,432,433,1,0,0,0,433,431,1,0,0,0,433,434, - 1,0,0,0,434,435,1,0,0,0,435,436,5,0,0,1,436,63,1,0,0,0,437,438,5, - 31,0,0,438,439,5,88,0,0,439,440,3,66,33,0,440,65,1,0,0,0,441,442, - 5,82,0,0,442,443,5,9,0,0,443,452,5,1,0,0,444,453,3,72,36,0,445,453, - 3,76,38,0,446,453,3,78,39,0,447,453,3,86,43,0,448,453,3,88,44,0, - 449,453,3,68,34,0,450,453,3,70,35,0,451,453,3,74,37,0,452,444,1, - 0,0,0,452,445,1,0,0,0,452,446,1,0,0,0,452,447,1,0,0,0,452,448,1, - 0,0,0,452,449,1,0,0,0,452,450,1,0,0,0,452,451,1,0,0,0,453,454,1, - 0,0,0,454,452,1,0,0,0,454,455,1,0,0,0,455,456,1,0,0,0,456,457,5, - 2,0,0,457,67,1,0,0,0,458,459,5,40,0,0,459,460,5,49,0,0,460,465,5, - 88,0,0,461,462,5,74,0,0,462,464,3,92,46,0,463,461,1,0,0,0,464,467, - 1,0,0,0,465,463,1,0,0,0,465,466,1,0,0,0,466,468,1,0,0,0,467,465, - 1,0,0,0,468,469,5,50,0,0,469,470,5,82,0,0,470,471,3,28,14,0,471, - 69,1,0,0,0,472,473,5,41,0,0,473,474,5,49,0,0,474,479,3,6,3,0,475, - 476,5,74,0,0,476,478,3,92,46,0,477,475,1,0,0,0,478,481,1,0,0,0,479, - 477,1,0,0,0,479,480,1,0,0,0,480,482,1,0,0,0,481,479,1,0,0,0,482, - 483,5,50,0,0,483,484,5,82,0,0,484,485,3,28,14,0,485,71,1,0,0,0,486, - 487,7,2,0,0,487,488,5,82,0,0,488,489,5,9,0,0,489,491,5,1,0,0,490, - 492,3,40,20,0,491,490,1,0,0,0,492,493,1,0,0,0,493,491,1,0,0,0,493, - 494,1,0,0,0,494,495,1,0,0,0,495,496,5,2,0,0,496,73,1,0,0,0,497,498, - 5,35,0,0,498,499,5,82,0,0,499,500,3,28,14,0,500,75,1,0,0,0,501,502, - 5,36,0,0,502,503,5,82,0,0,503,504,5,9,0,0,504,508,5,1,0,0,505,509, - 3,22,11,0,506,509,3,24,12,0,507,509,3,26,13,0,508,505,1,0,0,0,508, - 506,1,0,0,0,508,507,1,0,0,0,509,510,1,0,0,0,510,508,1,0,0,0,510, - 511,1,0,0,0,511,512,1,0,0,0,512,513,5,2,0,0,513,77,1,0,0,0,514,515, - 5,37,0,0,515,516,5,82,0,0,516,517,5,9,0,0,517,520,5,1,0,0,518,521, - 3,80,40,0,519,521,3,82,41,0,520,518,1,0,0,0,520,519,1,0,0,0,521, - 522,1,0,0,0,522,520,1,0,0,0,522,523,1,0,0,0,523,524,1,0,0,0,524, - 525,5,2,0,0,525,79,1,0,0,0,526,531,5,88,0,0,527,528,5,56,0,0,528, - 529,3,6,3,0,529,530,5,58,0,0,530,532,1,0,0,0,531,527,1,0,0,0,531, - 532,1,0,0,0,532,533,1,0,0,0,533,537,5,57,0,0,534,536,3,84,42,0,535, - 534,1,0,0,0,536,539,1,0,0,0,537,535,1,0,0,0,537,538,1,0,0,0,538, - 540,1,0,0,0,539,537,1,0,0,0,540,541,5,42,0,0,541,542,5,9,0,0,542, - 81,1,0,0,0,543,548,5,88,0,0,544,545,5,56,0,0,545,546,3,6,3,0,546, - 547,5,58,0,0,547,549,1,0,0,0,548,544,1,0,0,0,548,549,1,0,0,0,549, - 550,1,0,0,0,550,551,3,0,0,0,551,552,5,57,0,0,552,553,5,39,0,0,553, - 554,5,9,0,0,554,83,1,0,0,0,555,558,5,43,0,0,556,558,5,44,0,0,557, - 555,1,0,0,0,557,556,1,0,0,0,558,85,1,0,0,0,559,560,5,38,0,0,560, - 561,5,82,0,0,561,562,5,9,0,0,562,565,5,1,0,0,563,566,5,42,0,0,564, - 566,5,39,0,0,565,563,1,0,0,0,565,564,1,0,0,0,566,567,1,0,0,0,567, - 568,5,9,0,0,568,569,5,2,0,0,569,87,1,0,0,0,570,571,5,15,0,0,571, - 572,5,88,0,0,572,581,5,49,0,0,573,578,3,90,45,0,574,575,5,74,0,0, - 575,577,3,90,45,0,576,574,1,0,0,0,577,580,1,0,0,0,578,576,1,0,0, - 0,578,579,1,0,0,0,579,582,1,0,0,0,580,578,1,0,0,0,581,573,1,0,0, - 0,581,582,1,0,0,0,582,583,1,0,0,0,583,585,5,50,0,0,584,586,3,0,0, - 0,585,584,1,0,0,0,585,586,1,0,0,0,586,587,1,0,0,0,587,588,5,82,0, - 0,588,589,3,28,14,0,589,89,1,0,0,0,590,591,5,88,0,0,591,592,3,0, - 0,0,592,91,1,0,0,0,593,594,5,88,0,0,594,595,5,76,0,0,595,596,7,3, - 0,0,596,93,1,0,0,0,63,100,111,116,122,124,128,143,152,158,179,181, - 188,193,198,205,214,218,225,230,240,243,248,256,261,270,275,291, - 295,304,310,315,321,331,336,339,346,352,358,363,376,384,390,394, - 418,431,433,452,454,465,479,493,508,510,520,522,531,537,548,557, - 565,578,581,585 + 7,46,2,47,7,47,2,48,7,48,1,0,1,0,1,0,1,0,1,0,1,0,3,0,105,8,0,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,3,1,116,8,1,1,1,1,1,1,1,3,1,121, + 8,1,1,1,1,1,1,1,1,1,5,1,127,8,1,10,1,12,1,130,9,1,1,2,3,2,133,8, + 2,1,2,1,2,1,3,1,3,1,3,1,3,1,3,1,3,1,3,1,3,1,3,1,3,1,3,3,3,148,8, + 3,1,3,1,3,1,3,1,3,1,3,1,3,1,3,3,3,157,8,3,1,3,1,3,1,3,1,3,3,3,163, + 8,3,1,3,1,3,1,3,1,3,1,3,1,3,1,3,1,3,1,3,1,3,1,3,1,3,1,3,1,3,1,3, + 1,3,1,3,1,3,1,3,5,3,184,8,3,10,3,12,3,187,9,3,1,4,1,4,1,4,1,4,3, + 4,193,8,4,1,4,1,4,1,4,3,4,198,8,4,1,5,1,5,1,5,3,5,203,8,5,1,6,1, + 6,1,6,1,6,1,6,3,6,210,8,6,1,7,1,7,1,7,1,7,1,7,1,7,1,7,3,7,219,8, + 7,1,8,1,8,3,8,223,8,8,1,9,1,9,1,9,1,9,1,9,3,9,230,8,9,1,9,5,9,233, + 8,9,10,9,12,9,236,9,9,1,10,1,10,1,10,1,10,1,10,5,10,243,8,10,10, + 10,12,10,246,9,10,3,10,248,8,10,1,10,1,10,1,11,3,11,253,8,11,1,11, + 1,11,1,11,1,11,1,11,1,11,3,11,261,8,11,1,11,5,11,264,8,11,10,11, + 12,11,267,9,11,1,11,1,11,1,12,1,12,1,12,1,12,3,12,275,8,12,1,12, + 5,12,278,8,12,10,12,12,12,281,9,12,1,12,1,12,1,13,1,13,1,13,1,13, + 1,13,1,13,1,13,1,13,1,13,5,13,294,8,13,10,13,12,13,297,9,13,1,13, + 3,13,300,8,13,1,13,1,13,1,14,1,14,1,14,4,14,307,8,14,11,14,12,14, + 308,1,14,1,14,1,15,1,15,3,15,315,8,15,1,16,1,16,1,16,3,16,320,8, + 16,1,17,1,17,1,17,1,17,1,17,3,17,327,8,17,1,17,1,17,1,18,1,18,1, + 18,1,18,1,18,1,18,3,18,337,8,18,1,18,1,18,1,19,1,19,1,19,1,20,1, + 20,1,20,1,21,3,21,348,8,21,1,21,3,21,351,8,21,1,21,1,21,1,21,5,21, + 356,8,21,10,21,12,21,359,9,21,1,21,1,21,1,21,3,21,364,8,21,1,21, + 1,21,1,21,1,21,3,21,370,8,21,1,21,5,21,373,8,21,10,21,12,21,376, + 9,21,1,22,1,22,1,22,1,23,1,23,1,23,1,23,1,23,1,23,1,23,3,23,388, + 8,23,1,24,1,24,1,25,1,25,1,26,1,26,3,26,396,8,26,1,27,1,27,5,27, + 400,8,27,10,27,12,27,403,9,27,1,27,3,27,406,8,27,1,28,1,28,1,28, + 1,28,1,28,1,29,1,29,1,29,1,29,1,29,1,30,1,30,1,30,1,30,1,31,1,31, + 1,31,1,31,1,31,1,31,1,31,1,31,3,31,430,8,31,1,31,1,31,1,31,1,31, + 1,32,1,32,1,32,1,32,1,32,1,33,1,33,4,33,443,8,33,11,33,12,33,444, + 1,33,1,33,1,34,1,34,1,34,1,34,1,35,1,35,1,35,1,35,1,35,1,35,1,35, + 1,35,1,35,1,35,1,35,1,35,4,35,465,8,35,11,35,12,35,466,1,35,1,35, + 1,36,1,36,1,36,1,36,1,36,5,36,476,8,36,10,36,12,36,479,9,36,1,36, + 1,36,1,36,1,36,1,37,1,37,1,37,1,37,1,37,5,37,490,8,37,10,37,12,37, + 493,9,37,1,37,1,37,1,37,1,37,1,38,1,38,1,38,1,38,1,38,1,38,4,38, + 505,8,38,11,38,12,38,506,1,38,1,38,1,39,1,39,1,39,1,39,1,40,1,40, + 1,40,1,40,1,40,1,40,1,40,4,40,522,8,40,11,40,12,40,523,1,40,1,40, + 1,41,1,41,1,41,1,41,1,41,1,41,4,41,534,8,41,11,41,12,41,535,1,41, + 1,41,1,42,1,42,1,42,1,42,1,42,3,42,545,8,42,1,42,1,42,5,42,549,8, + 42,10,42,12,42,552,9,42,1,42,1,42,1,42,1,43,1,43,1,43,1,43,1,43, + 3,43,562,8,43,1,43,1,43,1,43,1,43,1,43,1,44,1,44,3,44,571,8,44,1, + 45,1,45,1,45,1,45,1,45,1,45,3,45,579,8,45,1,45,1,45,1,45,1,46,1, + 46,1,46,1,46,1,46,1,46,5,46,590,8,46,10,46,12,46,593,9,46,3,46,595, + 8,46,1,46,1,46,3,46,599,8,46,1,46,1,46,1,46,1,47,1,47,1,47,1,48, + 1,48,1,48,1,48,1,48,0,2,2,6,49,0,2,4,6,8,10,12,14,16,18,20,22,24, + 26,28,30,32,34,36,38,40,42,44,46,48,50,52,54,56,58,60,62,64,66,68, + 70,72,74,76,78,80,82,84,86,88,90,92,94,96,0,4,2,0,52,52,76,76,1, + 0,90,91,1,0,33,35,3,0,25,25,87,88,90,91,667,0,104,1,0,0,0,2,115, + 1,0,0,0,4,132,1,0,0,0,6,147,1,0,0,0,8,197,1,0,0,0,10,202,1,0,0,0, + 12,209,1,0,0,0,14,218,1,0,0,0,16,222,1,0,0,0,18,224,1,0,0,0,20,237, + 1,0,0,0,22,252,1,0,0,0,24,270,1,0,0,0,26,284,1,0,0,0,28,303,1,0, + 0,0,30,314,1,0,0,0,32,319,1,0,0,0,34,326,1,0,0,0,36,330,1,0,0,0, + 38,340,1,0,0,0,40,343,1,0,0,0,42,347,1,0,0,0,44,377,1,0,0,0,46,387, + 1,0,0,0,48,389,1,0,0,0,50,391,1,0,0,0,52,393,1,0,0,0,54,397,1,0, + 0,0,56,407,1,0,0,0,58,412,1,0,0,0,60,417,1,0,0,0,62,421,1,0,0,0, + 64,435,1,0,0,0,66,442,1,0,0,0,68,448,1,0,0,0,70,452,1,0,0,0,72,470, + 1,0,0,0,74,484,1,0,0,0,76,498,1,0,0,0,78,510,1,0,0,0,80,514,1,0, + 0,0,82,527,1,0,0,0,84,539,1,0,0,0,86,556,1,0,0,0,88,570,1,0,0,0, + 90,572,1,0,0,0,92,583,1,0,0,0,94,603,1,0,0,0,96,606,1,0,0,0,98,105, + 5,10,0,0,99,105,5,11,0,0,100,105,5,12,0,0,101,105,5,13,0,0,102,105, + 5,14,0,0,103,105,3,2,1,0,104,98,1,0,0,0,104,99,1,0,0,0,104,100,1, + 0,0,0,104,101,1,0,0,0,104,102,1,0,0,0,104,103,1,0,0,0,105,1,1,0, + 0,0,106,107,6,1,-1,0,107,108,5,50,0,0,108,109,3,2,1,0,109,110,5, + 51,0,0,110,116,1,0,0,0,111,112,5,90,0,0,112,113,5,80,0,0,113,116, + 3,2,1,2,114,116,5,89,0,0,115,106,1,0,0,0,115,111,1,0,0,0,115,114, + 1,0,0,0,116,128,1,0,0,0,117,120,10,3,0,0,118,121,5,78,0,0,119,121, + 5,80,0,0,120,118,1,0,0,0,120,119,1,0,0,0,121,122,1,0,0,0,122,127, + 3,2,1,4,123,124,10,4,0,0,124,125,5,79,0,0,125,127,3,4,2,0,126,117, + 1,0,0,0,126,123,1,0,0,0,127,130,1,0,0,0,128,126,1,0,0,0,128,129, + 1,0,0,0,129,3,1,0,0,0,130,128,1,0,0,0,131,133,7,0,0,0,132,131,1, + 0,0,0,132,133,1,0,0,0,133,134,1,0,0,0,134,135,5,90,0,0,135,5,1,0, + 0,0,136,137,6,3,-1,0,137,138,5,50,0,0,138,139,3,6,3,0,139,140,5, + 51,0,0,140,148,1,0,0,0,141,142,3,10,5,0,142,143,3,6,3,9,143,148, + 1,0,0,0,144,145,5,28,0,0,145,148,3,6,3,4,146,148,3,8,4,0,147,136, + 1,0,0,0,147,141,1,0,0,0,147,144,1,0,0,0,147,146,1,0,0,0,148,185, + 1,0,0,0,149,150,10,10,0,0,150,151,5,79,0,0,151,184,3,6,3,10,152, + 156,10,8,0,0,153,157,5,78,0,0,154,157,5,80,0,0,155,157,5,81,0,0, + 156,153,1,0,0,0,156,154,1,0,0,0,156,155,1,0,0,0,157,158,1,0,0,0, + 158,184,3,6,3,9,159,162,10,7,0,0,160,163,5,52,0,0,161,163,5,76,0, + 0,162,160,1,0,0,0,162,161,1,0,0,0,163,164,1,0,0,0,164,184,3,6,3, + 8,165,166,10,6,0,0,166,167,3,12,6,0,167,168,3,6,3,7,168,184,1,0, + 0,0,169,170,10,5,0,0,170,171,3,14,7,0,171,172,3,6,3,6,172,184,1, + 0,0,0,173,174,10,3,0,0,174,175,3,16,8,0,175,176,3,6,3,4,176,184, + 1,0,0,0,177,178,10,2,0,0,178,179,5,82,0,0,179,180,3,6,3,0,180,181, + 5,83,0,0,181,182,3,6,3,3,182,184,1,0,0,0,183,149,1,0,0,0,183,152, + 1,0,0,0,183,159,1,0,0,0,183,165,1,0,0,0,183,169,1,0,0,0,183,173, + 1,0,0,0,183,177,1,0,0,0,184,187,1,0,0,0,185,183,1,0,0,0,185,186, + 1,0,0,0,186,7,1,0,0,0,187,185,1,0,0,0,188,198,3,20,10,0,189,198, + 5,87,0,0,190,192,7,1,0,0,191,193,3,18,9,0,192,191,1,0,0,0,192,193, + 1,0,0,0,193,198,1,0,0,0,194,198,5,88,0,0,195,198,5,25,0,0,196,198, + 3,18,9,0,197,188,1,0,0,0,197,189,1,0,0,0,197,190,1,0,0,0,197,194, + 1,0,0,0,197,195,1,0,0,0,197,196,1,0,0,0,198,9,1,0,0,0,199,203,5, + 52,0,0,200,203,5,76,0,0,201,203,5,53,0,0,202,199,1,0,0,0,202,200, + 1,0,0,0,202,201,1,0,0,0,203,11,1,0,0,0,204,210,5,56,0,0,205,210, + 5,55,0,0,206,210,5,54,0,0,207,210,5,62,0,0,208,210,5,63,0,0,209, + 204,1,0,0,0,209,205,1,0,0,0,209,206,1,0,0,0,209,207,1,0,0,0,209, + 208,1,0,0,0,210,13,1,0,0,0,211,219,5,64,0,0,212,219,5,66,0,0,213, + 219,5,71,0,0,214,219,5,72,0,0,215,219,5,73,0,0,216,219,5,74,0,0, + 217,219,5,65,0,0,218,211,1,0,0,0,218,212,1,0,0,0,218,213,1,0,0,0, + 218,214,1,0,0,0,218,215,1,0,0,0,218,216,1,0,0,0,218,217,1,0,0,0, + 219,15,1,0,0,0,220,223,5,26,0,0,221,223,5,27,0,0,222,220,1,0,0,0, + 222,221,1,0,0,0,223,17,1,0,0,0,224,229,5,89,0,0,225,226,5,57,0,0, + 226,227,3,6,3,0,227,228,5,59,0,0,228,230,1,0,0,0,229,225,1,0,0,0, + 229,230,1,0,0,0,230,234,1,0,0,0,231,233,5,86,0,0,232,231,1,0,0,0, + 233,236,1,0,0,0,234,232,1,0,0,0,234,235,1,0,0,0,235,19,1,0,0,0,236, + 234,1,0,0,0,237,238,5,89,0,0,238,247,5,50,0,0,239,244,3,6,3,0,240, + 241,5,75,0,0,241,243,3,6,3,0,242,240,1,0,0,0,243,246,1,0,0,0,244, + 242,1,0,0,0,244,245,1,0,0,0,245,248,1,0,0,0,246,244,1,0,0,0,247, + 239,1,0,0,0,247,248,1,0,0,0,248,249,1,0,0,0,249,250,5,51,0,0,250, + 21,1,0,0,0,251,253,5,30,0,0,252,251,1,0,0,0,252,253,1,0,0,0,253, + 254,1,0,0,0,254,255,5,16,0,0,255,256,5,89,0,0,256,257,3,0,0,0,257, + 258,5,77,0,0,258,260,3,6,3,0,259,261,5,85,0,0,260,259,1,0,0,0,260, + 261,1,0,0,0,261,265,1,0,0,0,262,264,3,46,23,0,263,262,1,0,0,0,264, + 267,1,0,0,0,265,263,1,0,0,0,265,266,1,0,0,0,266,268,1,0,0,0,267, + 265,1,0,0,0,268,269,5,9,0,0,269,23,1,0,0,0,270,271,3,18,9,0,271, + 272,5,77,0,0,272,274,3,6,3,0,273,275,5,85,0,0,274,273,1,0,0,0,274, + 275,1,0,0,0,275,279,1,0,0,0,276,278,3,46,23,0,277,276,1,0,0,0,278, + 281,1,0,0,0,279,277,1,0,0,0,279,280,1,0,0,0,280,282,1,0,0,0,281, + 279,1,0,0,0,282,283,5,9,0,0,283,25,1,0,0,0,284,285,5,31,0,0,285, + 286,3,18,9,0,286,287,5,77,0,0,287,295,3,6,3,0,288,289,5,4,0,0,289, + 290,3,18,9,0,290,291,5,77,0,0,291,292,3,6,3,0,292,294,1,0,0,0,293, + 288,1,0,0,0,294,297,1,0,0,0,295,293,1,0,0,0,295,296,1,0,0,0,296, + 299,1,0,0,0,297,295,1,0,0,0,298,300,5,85,0,0,299,298,1,0,0,0,299, + 300,1,0,0,0,300,301,1,0,0,0,301,302,5,9,0,0,302,27,1,0,0,0,303,304, + 5,9,0,0,304,306,5,1,0,0,305,307,3,30,15,0,306,305,1,0,0,0,307,308, + 1,0,0,0,308,306,1,0,0,0,308,309,1,0,0,0,309,310,1,0,0,0,310,311, + 5,2,0,0,311,29,1,0,0,0,312,315,3,34,17,0,313,315,3,32,16,0,314,312, + 1,0,0,0,314,313,1,0,0,0,315,31,1,0,0,0,316,320,3,54,27,0,317,320, + 3,62,31,0,318,320,3,64,32,0,319,316,1,0,0,0,319,317,1,0,0,0,319, + 318,1,0,0,0,320,33,1,0,0,0,321,327,3,36,18,0,322,327,3,20,10,0,323, + 327,3,42,21,0,324,327,3,52,26,0,325,327,3,38,19,0,326,321,1,0,0, + 0,326,322,1,0,0,0,326,323,1,0,0,0,326,324,1,0,0,0,326,325,1,0,0, + 0,327,328,1,0,0,0,328,329,5,9,0,0,329,35,1,0,0,0,330,336,3,18,9, + 0,331,337,5,77,0,0,332,337,5,67,0,0,333,337,5,68,0,0,334,337,5,69, + 0,0,335,337,5,70,0,0,336,331,1,0,0,0,336,332,1,0,0,0,336,333,1,0, + 0,0,336,334,1,0,0,0,336,335,1,0,0,0,337,338,1,0,0,0,338,339,3,6, + 3,0,339,37,1,0,0,0,340,341,5,29,0,0,341,342,5,88,0,0,342,39,1,0, + 0,0,343,344,3,38,19,0,344,345,5,9,0,0,345,41,1,0,0,0,346,348,5,30, + 0,0,347,346,1,0,0,0,347,348,1,0,0,0,348,350,1,0,0,0,349,351,5,16, + 0,0,350,349,1,0,0,0,350,351,1,0,0,0,351,352,1,0,0,0,352,357,3,18, + 9,0,353,354,5,75,0,0,354,356,3,18,9,0,355,353,1,0,0,0,356,359,1, + 0,0,0,357,355,1,0,0,0,357,358,1,0,0,0,358,360,1,0,0,0,359,357,1, + 0,0,0,360,363,3,0,0,0,361,362,5,77,0,0,362,364,3,6,3,0,363,361,1, + 0,0,0,363,364,1,0,0,0,364,369,1,0,0,0,365,366,5,60,0,0,366,367,3, + 6,3,0,367,368,5,61,0,0,368,370,1,0,0,0,369,365,1,0,0,0,369,370,1, + 0,0,0,370,374,1,0,0,0,371,373,3,46,23,0,372,371,1,0,0,0,373,376, + 1,0,0,0,374,372,1,0,0,0,374,375,1,0,0,0,375,43,1,0,0,0,376,374,1, + 0,0,0,377,378,3,42,21,0,378,379,5,9,0,0,379,45,1,0,0,0,380,388,5, + 46,0,0,381,388,5,47,0,0,382,383,5,48,0,0,383,384,3,48,24,0,384,385, + 5,84,0,0,385,386,3,50,25,0,386,388,1,0,0,0,387,380,1,0,0,0,387,381, + 1,0,0,0,387,382,1,0,0,0,388,47,1,0,0,0,389,390,5,89,0,0,390,49,1, + 0,0,0,391,392,5,89,0,0,392,51,1,0,0,0,393,395,5,17,0,0,394,396,3, + 6,3,0,395,394,1,0,0,0,395,396,1,0,0,0,396,53,1,0,0,0,397,401,3,56, + 28,0,398,400,3,58,29,0,399,398,1,0,0,0,400,403,1,0,0,0,401,399,1, + 0,0,0,401,402,1,0,0,0,402,405,1,0,0,0,403,401,1,0,0,0,404,406,3, + 60,30,0,405,404,1,0,0,0,405,406,1,0,0,0,406,55,1,0,0,0,407,408,5, + 18,0,0,408,409,3,6,3,0,409,410,5,83,0,0,410,411,3,28,14,0,411,57, + 1,0,0,0,412,413,5,19,0,0,413,414,3,6,3,0,414,415,5,83,0,0,415,416, + 3,28,14,0,416,59,1,0,0,0,417,418,5,20,0,0,418,419,5,83,0,0,419,420, + 3,28,14,0,420,61,1,0,0,0,421,422,5,21,0,0,422,423,5,89,0,0,423,424, + 5,23,0,0,424,425,3,6,3,0,425,426,5,49,0,0,426,427,3,6,3,0,427,429, + 5,24,0,0,428,430,5,76,0,0,429,428,1,0,0,0,429,430,1,0,0,0,430,431, + 1,0,0,0,431,432,7,1,0,0,432,433,5,83,0,0,433,434,3,28,14,0,434,63, + 1,0,0,0,435,436,5,22,0,0,436,437,3,6,3,0,437,438,5,83,0,0,438,439, + 3,28,14,0,439,65,1,0,0,0,440,443,3,68,34,0,441,443,5,9,0,0,442,440, + 1,0,0,0,442,441,1,0,0,0,443,444,1,0,0,0,444,442,1,0,0,0,444,445, + 1,0,0,0,445,446,1,0,0,0,446,447,5,0,0,1,447,67,1,0,0,0,448,449,5, + 32,0,0,449,450,5,89,0,0,450,451,3,70,35,0,451,69,1,0,0,0,452,453, + 5,83,0,0,453,454,5,9,0,0,454,464,5,1,0,0,455,465,3,40,20,0,456,465, + 3,76,38,0,457,465,3,80,40,0,458,465,3,82,41,0,459,465,3,90,45,0, + 460,465,3,92,46,0,461,465,3,72,36,0,462,465,3,74,37,0,463,465,3, + 78,39,0,464,455,1,0,0,0,464,456,1,0,0,0,464,457,1,0,0,0,464,458, + 1,0,0,0,464,459,1,0,0,0,464,460,1,0,0,0,464,461,1,0,0,0,464,462, + 1,0,0,0,464,463,1,0,0,0,465,466,1,0,0,0,466,464,1,0,0,0,466,467, + 1,0,0,0,467,468,1,0,0,0,468,469,5,2,0,0,469,71,1,0,0,0,470,471,5, + 41,0,0,471,472,5,50,0,0,472,477,5,89,0,0,473,474,5,75,0,0,474,476, + 3,96,48,0,475,473,1,0,0,0,476,479,1,0,0,0,477,475,1,0,0,0,477,478, + 1,0,0,0,478,480,1,0,0,0,479,477,1,0,0,0,480,481,5,51,0,0,481,482, + 5,83,0,0,482,483,3,28,14,0,483,73,1,0,0,0,484,485,5,42,0,0,485,486, + 5,50,0,0,486,491,3,6,3,0,487,488,5,75,0,0,488,490,3,96,48,0,489, + 487,1,0,0,0,490,493,1,0,0,0,491,489,1,0,0,0,491,492,1,0,0,0,492, + 494,1,0,0,0,493,491,1,0,0,0,494,495,5,51,0,0,495,496,5,83,0,0,496, + 497,3,28,14,0,497,75,1,0,0,0,498,499,7,2,0,0,499,500,5,83,0,0,500, + 501,5,9,0,0,501,504,5,1,0,0,502,505,3,40,20,0,503,505,3,44,22,0, + 504,502,1,0,0,0,504,503,1,0,0,0,505,506,1,0,0,0,506,504,1,0,0,0, + 506,507,1,0,0,0,507,508,1,0,0,0,508,509,5,2,0,0,509,77,1,0,0,0,510, + 511,5,36,0,0,511,512,5,83,0,0,512,513,3,28,14,0,513,79,1,0,0,0,514, + 515,5,37,0,0,515,516,5,83,0,0,516,517,5,9,0,0,517,521,5,1,0,0,518, + 522,3,22,11,0,519,522,3,24,12,0,520,522,3,26,13,0,521,518,1,0,0, + 0,521,519,1,0,0,0,521,520,1,0,0,0,522,523,1,0,0,0,523,521,1,0,0, + 0,523,524,1,0,0,0,524,525,1,0,0,0,525,526,5,2,0,0,526,81,1,0,0,0, + 527,528,5,38,0,0,528,529,5,83,0,0,529,530,5,9,0,0,530,533,5,1,0, + 0,531,534,3,84,42,0,532,534,3,86,43,0,533,531,1,0,0,0,533,532,1, + 0,0,0,534,535,1,0,0,0,535,533,1,0,0,0,535,536,1,0,0,0,536,537,1, + 0,0,0,537,538,5,2,0,0,538,83,1,0,0,0,539,544,5,89,0,0,540,541,5, + 57,0,0,541,542,3,6,3,0,542,543,5,59,0,0,543,545,1,0,0,0,544,540, + 1,0,0,0,544,545,1,0,0,0,545,546,1,0,0,0,546,550,5,58,0,0,547,549, + 3,88,44,0,548,547,1,0,0,0,549,552,1,0,0,0,550,548,1,0,0,0,550,551, + 1,0,0,0,551,553,1,0,0,0,552,550,1,0,0,0,553,554,5,43,0,0,554,555, + 5,9,0,0,555,85,1,0,0,0,556,561,5,89,0,0,557,558,5,57,0,0,558,559, + 3,6,3,0,559,560,5,59,0,0,560,562,1,0,0,0,561,557,1,0,0,0,561,562, + 1,0,0,0,562,563,1,0,0,0,563,564,3,0,0,0,564,565,5,58,0,0,565,566, + 5,40,0,0,566,567,5,9,0,0,567,87,1,0,0,0,568,571,5,44,0,0,569,571, + 5,45,0,0,570,568,1,0,0,0,570,569,1,0,0,0,571,89,1,0,0,0,572,573, + 5,39,0,0,573,574,5,83,0,0,574,575,5,9,0,0,575,578,5,1,0,0,576,579, + 5,43,0,0,577,579,5,40,0,0,578,576,1,0,0,0,578,577,1,0,0,0,579,580, + 1,0,0,0,580,581,5,9,0,0,581,582,5,2,0,0,582,91,1,0,0,0,583,584,5, + 15,0,0,584,585,5,89,0,0,585,594,5,50,0,0,586,591,3,94,47,0,587,588, + 5,75,0,0,588,590,3,94,47,0,589,587,1,0,0,0,590,593,1,0,0,0,591,589, + 1,0,0,0,591,592,1,0,0,0,592,595,1,0,0,0,593,591,1,0,0,0,594,586, + 1,0,0,0,594,595,1,0,0,0,595,596,1,0,0,0,596,598,5,51,0,0,597,599, + 3,0,0,0,598,597,1,0,0,0,598,599,1,0,0,0,599,600,1,0,0,0,600,601, + 5,83,0,0,601,602,3,28,14,0,602,93,1,0,0,0,603,604,5,89,0,0,604,605, + 3,0,0,0,605,95,1,0,0,0,606,607,5,89,0,0,607,608,5,77,0,0,608,609, + 7,3,0,0,609,97,1,0,0,0,64,104,115,120,126,128,132,147,156,162,183, + 185,192,197,202,209,218,222,229,234,244,247,252,260,265,274,279, + 295,299,308,314,319,326,336,347,350,357,363,369,374,387,395,401, + 405,429,442,444,464,466,477,491,504,506,521,523,533,535,544,550, + 561,570,578,591,594,598 ] class PyNestMLParser ( Parser ): @@ -247,17 +252,17 @@ class PyNestMLParser ( Parser ): "", "", "'integer'", "'real'", "'string'", "'boolean'", "'void'", "'function'", "'inline'", "'return'", "'if'", "'elif'", "'else'", "'for'", "'while'", "'in'", - "'step'", "'inf'", "'and'", "'or'", "'not'", "'recordable'", - "'kernel'", "'model'", "'state'", "'parameters'", "'internals'", - "'update'", "'equations'", "'input'", "'output'", "'continuous'", - "'onReceive'", "'onCondition'", "'spike'", "'inhibitory'", - "'excitatory'", "'@homogeneous'", "'@heterogeneous'", - "'@'", "'...'", "'('", "')'", "'+'", "'~'", "'|'", - "'^'", "'&'", "'['", "'<-'", "']'", "'[['", "']]'", - "'<<'", "'>>'", "'<'", "'>'", "'<='", "'+='", "'-='", - "'*='", "'/='", "'=='", "'!='", "'<>'", "'>='", "','", - "'-'", "'='", "'*'", "'**'", "'/'", "'%'", "'?'", "':'", - "'::'", "';'", "'''" ] + "'step'", "'inf'", "'and'", "'or'", "'not'", "'include'", + "'recordable'", "'kernel'", "'model'", "'state'", "'parameters'", + "'internals'", "'update'", "'equations'", "'input'", + "'output'", "'continuous'", "'onReceive'", "'onCondition'", + "'spike'", "'inhibitory'", "'excitatory'", "'@homogeneous'", + "'@heterogeneous'", "'@'", "'...'", "'('", "')'", "'+'", + "'~'", "'|'", "'^'", "'&'", "'['", "'<-'", "']'", "'[['", + "']]'", "'<<'", "'>>'", "'<'", "'>'", "'<='", "'+='", + "'-='", "'*='", "'/='", "'=='", "'!='", "'<>'", "'>='", + "','", "'-'", "'='", "'*'", "'**'", "'/'", "'%'", "'?'", + "':'", "'::'", "';'", "'''" ] symbolicNames = [ "", "INDENT", "DEDENT", "DOCSTRING_TRIPLEQUOTE", "KERNEL_JOINING", "WS", "LINE_ESCAPE", "DOCSTRING", @@ -266,13 +271,13 @@ class PyNestMLParser ( Parser ): "FUNCTION_KEYWORD", "INLINE_KEYWORD", "RETURN_KEYWORD", "IF_KEYWORD", "ELIF_KEYWORD", "ELSE_KEYWORD", "FOR_KEYWORD", "WHILE_KEYWORD", "IN_KEYWORD", "STEP_KEYWORD", "INF_KEYWORD", - "AND_KEYWORD", "OR_KEYWORD", "NOT_KEYWORD", "RECORDABLE_KEYWORD", - "KERNEL_KEYWORD", "MODEL_KEYWORD", "STATE_KEYWORD", - "PARAMETERS_KEYWORD", "INTERNALS_KEYWORD", "UPDATE_KEYWORD", - "EQUATIONS_KEYWORD", "INPUT_KEYWORD", "OUTPUT_KEYWORD", - "CONTINUOUS_KEYWORD", "ON_RECEIVE_KEYWORD", "ON_CONDITION_KEYWORD", - "SPIKE_KEYWORD", "INHIBITORY_KEYWORD", "EXCITATORY_KEYWORD", - "DECORATOR_HOMOGENEOUS", "DECORATOR_HETEROGENEOUS", + "AND_KEYWORD", "OR_KEYWORD", "NOT_KEYWORD", "INCLUDE_KEYWORD", + "RECORDABLE_KEYWORD", "KERNEL_KEYWORD", "MODEL_KEYWORD", + "STATE_KEYWORD", "PARAMETERS_KEYWORD", "INTERNALS_KEYWORD", + "UPDATE_KEYWORD", "EQUATIONS_KEYWORD", "INPUT_KEYWORD", + "OUTPUT_KEYWORD", "CONTINUOUS_KEYWORD", "ON_RECEIVE_KEYWORD", + "ON_CONDITION_KEYWORD", "SPIKE_KEYWORD", "INHIBITORY_KEYWORD", + "EXCITATORY_KEYWORD", "DECORATOR_HOMOGENEOUS", "DECORATOR_HETEROGENEOUS", "AT", "ELLIPSIS", "LEFT_PAREN", "RIGHT_PAREN", "PLUS", "TILDE", "PIPE", "CARET", "AMPERSAND", "LEFT_SQUARE_BRACKET", "LEFT_ANGLE_MINUS", "RIGHT_SQUARE_BRACKET", "LEFT_LEFT_SQUARE", @@ -305,41 +310,44 @@ class PyNestMLParser ( Parser ): RULE_compoundStmt = 16 RULE_smallStmt = 17 RULE_assignment = 18 - RULE_declaration = 19 - RULE_declaration_newline = 20 - RULE_anyDecorator = 21 - RULE_namespaceDecoratorNamespace = 22 - RULE_namespaceDecoratorName = 23 - RULE_returnStmt = 24 - RULE_ifStmt = 25 - RULE_ifClause = 26 - RULE_elifClause = 27 - RULE_elseClause = 28 - RULE_forStmt = 29 - RULE_whileStmt = 30 - RULE_nestMLCompilationUnit = 31 - RULE_model = 32 - RULE_modelBody = 33 - RULE_onReceiveBlock = 34 - RULE_onConditionBlock = 35 - RULE_blockWithVariables = 36 - RULE_updateBlock = 37 - RULE_equationsBlock = 38 - RULE_inputBlock = 39 - RULE_spikeInputPort = 40 - RULE_continuousInputPort = 41 - RULE_inputQualifier = 42 - RULE_outputBlock = 43 - RULE_function = 44 - RULE_parameter = 45 - RULE_constParameter = 46 + RULE_includeStatement = 19 + RULE_includeStatement_newline = 20 + RULE_declaration = 21 + RULE_declaration_newline = 22 + RULE_anyDecorator = 23 + RULE_namespaceDecoratorNamespace = 24 + RULE_namespaceDecoratorName = 25 + RULE_returnStmt = 26 + RULE_ifStmt = 27 + RULE_ifClause = 28 + RULE_elifClause = 29 + RULE_elseClause = 30 + RULE_forStmt = 31 + RULE_whileStmt = 32 + RULE_nestMLCompilationUnit = 33 + RULE_model = 34 + RULE_modelBody = 35 + RULE_onReceiveBlock = 36 + RULE_onConditionBlock = 37 + RULE_blockWithVariables = 38 + RULE_updateBlock = 39 + RULE_equationsBlock = 40 + RULE_inputBlock = 41 + RULE_spikeInputPort = 42 + RULE_continuousInputPort = 43 + RULE_inputQualifier = 44 + RULE_outputBlock = 45 + RULE_function = 46 + RULE_parameter = 47 + RULE_constParameter = 48 ruleNames = [ "dataType", "unitType", "unitTypeExponent", "expression", "simpleExpression", "unaryOperator", "bitOperator", "comparisonOperator", "logicalOperator", "variable", "functionCall", "inlineExpression", "odeEquation", "kernel", "block", "stmt", "compoundStmt", - "smallStmt", "assignment", "declaration", "declaration_newline", - "anyDecorator", "namespaceDecoratorNamespace", "namespaceDecoratorName", + "smallStmt", "assignment", "includeStatement", "includeStatement_newline", + "declaration", "declaration_newline", "anyDecorator", + "namespaceDecoratorNamespace", "namespaceDecoratorName", "returnStmt", "ifStmt", "ifClause", "elifClause", "elseClause", "forStmt", "whileStmt", "nestMLCompilationUnit", "model", "modelBody", "onReceiveBlock", "onConditionBlock", "blockWithVariables", @@ -376,72 +384,73 @@ class PyNestMLParser ( Parser ): AND_KEYWORD=26 OR_KEYWORD=27 NOT_KEYWORD=28 - RECORDABLE_KEYWORD=29 - KERNEL_KEYWORD=30 - MODEL_KEYWORD=31 - STATE_KEYWORD=32 - PARAMETERS_KEYWORD=33 - INTERNALS_KEYWORD=34 - UPDATE_KEYWORD=35 - EQUATIONS_KEYWORD=36 - INPUT_KEYWORD=37 - OUTPUT_KEYWORD=38 - CONTINUOUS_KEYWORD=39 - ON_RECEIVE_KEYWORD=40 - ON_CONDITION_KEYWORD=41 - SPIKE_KEYWORD=42 - INHIBITORY_KEYWORD=43 - EXCITATORY_KEYWORD=44 - DECORATOR_HOMOGENEOUS=45 - DECORATOR_HETEROGENEOUS=46 - AT=47 - ELLIPSIS=48 - LEFT_PAREN=49 - RIGHT_PAREN=50 - PLUS=51 - TILDE=52 - PIPE=53 - CARET=54 - AMPERSAND=55 - LEFT_SQUARE_BRACKET=56 - LEFT_ANGLE_MINUS=57 - RIGHT_SQUARE_BRACKET=58 - LEFT_LEFT_SQUARE=59 - RIGHT_RIGHT_SQUARE=60 - LEFT_LEFT_ANGLE=61 - RIGHT_RIGHT_ANGLE=62 - LEFT_ANGLE=63 - RIGHT_ANGLE=64 - LEFT_ANGLE_EQUALS=65 - PLUS_EQUALS=66 - MINUS_EQUALS=67 - STAR_EQUALS=68 - FORWARD_SLASH_EQUALS=69 - EQUALS_EQUALS=70 - EXCLAMATION_EQUALS=71 - LEFT_ANGLE_RIGHT_ANGLE=72 - RIGHT_ANGLE_EQUALS=73 - COMMA=74 - MINUS=75 - EQUALS=76 - STAR=77 - STAR_STAR=78 - FORWARD_SLASH=79 - PERCENT=80 - QUESTION=81 - COLON=82 - DOUBLE_COLON=83 - SEMICOLON=84 - DIFFERENTIAL_ORDER=85 - BOOLEAN_LITERAL=86 - STRING_LITERAL=87 - NAME=88 - UNSIGNED_INTEGER=89 - FLOAT=90 + INCLUDE_KEYWORD=29 + RECORDABLE_KEYWORD=30 + KERNEL_KEYWORD=31 + MODEL_KEYWORD=32 + STATE_KEYWORD=33 + PARAMETERS_KEYWORD=34 + INTERNALS_KEYWORD=35 + UPDATE_KEYWORD=36 + EQUATIONS_KEYWORD=37 + INPUT_KEYWORD=38 + OUTPUT_KEYWORD=39 + CONTINUOUS_KEYWORD=40 + ON_RECEIVE_KEYWORD=41 + ON_CONDITION_KEYWORD=42 + SPIKE_KEYWORD=43 + INHIBITORY_KEYWORD=44 + EXCITATORY_KEYWORD=45 + DECORATOR_HOMOGENEOUS=46 + DECORATOR_HETEROGENEOUS=47 + AT=48 + ELLIPSIS=49 + LEFT_PAREN=50 + RIGHT_PAREN=51 + PLUS=52 + TILDE=53 + PIPE=54 + CARET=55 + AMPERSAND=56 + LEFT_SQUARE_BRACKET=57 + LEFT_ANGLE_MINUS=58 + RIGHT_SQUARE_BRACKET=59 + LEFT_LEFT_SQUARE=60 + RIGHT_RIGHT_SQUARE=61 + LEFT_LEFT_ANGLE=62 + RIGHT_RIGHT_ANGLE=63 + LEFT_ANGLE=64 + RIGHT_ANGLE=65 + LEFT_ANGLE_EQUALS=66 + PLUS_EQUALS=67 + MINUS_EQUALS=68 + STAR_EQUALS=69 + FORWARD_SLASH_EQUALS=70 + EQUALS_EQUALS=71 + EXCLAMATION_EQUALS=72 + LEFT_ANGLE_RIGHT_ANGLE=73 + RIGHT_ANGLE_EQUALS=74 + COMMA=75 + MINUS=76 + EQUALS=77 + STAR=78 + STAR_STAR=79 + FORWARD_SLASH=80 + PERCENT=81 + QUESTION=82 + COLON=83 + DOUBLE_COLON=84 + SEMICOLON=85 + DIFFERENTIAL_ORDER=86 + BOOLEAN_LITERAL=87 + STRING_LITERAL=88 + NAME=89 + UNSIGNED_INTEGER=90 + FLOAT=91 def __init__(self, input:TokenStream, output:TextIO = sys.stdout): super().__init__(input, output) - self.checkVersion("4.13.1") + self.checkVersion("4.13.0") self._interp = ParserATNSimulator(self, self.atn, self.decisionsToDFA, self.sharedContextCache) self._predicates = None @@ -497,37 +506,37 @@ def dataType(self): localctx = PyNestMLParser.DataTypeContext(self, self._ctx, self.state) self.enterRule(localctx, 0, self.RULE_dataType) try: - self.state = 100 + self.state = 104 self._errHandler.sync(self) token = self._input.LA(1) if token in [10]: self.enterOuterAlt(localctx, 1) - self.state = 94 + self.state = 98 localctx.isInt = self.match(PyNestMLParser.INTEGER_KEYWORD) pass elif token in [11]: self.enterOuterAlt(localctx, 2) - self.state = 95 + self.state = 99 localctx.isReal = self.match(PyNestMLParser.REAL_KEYWORD) pass elif token in [12]: self.enterOuterAlt(localctx, 3) - self.state = 96 + self.state = 100 localctx.isString = self.match(PyNestMLParser.STRING_KEYWORD) pass elif token in [13]: self.enterOuterAlt(localctx, 4) - self.state = 97 + self.state = 101 localctx.isBool = self.match(PyNestMLParser.BOOLEAN_KEYWORD) pass elif token in [14]: self.enterOuterAlt(localctx, 5) - self.state = 98 + self.state = 102 localctx.isVoid = self.match(PyNestMLParser.VOID_KEYWORD) pass - elif token in [49, 88, 89]: + elif token in [50, 89, 90]: self.enterOuterAlt(localctx, 6) - self.state = 99 + self.state = 103 localctx.unit = self.unitType(0) pass else: @@ -613,34 +622,34 @@ def unitType(self, _p:int=0): self.enterRecursionRule(localctx, 2, self.RULE_unitType, _p) try: self.enterOuterAlt(localctx, 1) - self.state = 111 + self.state = 115 self._errHandler.sync(self) token = self._input.LA(1) - if token in [49]: - self.state = 103 + if token in [50]: + self.state = 107 localctx.leftParentheses = self.match(PyNestMLParser.LEFT_PAREN) - self.state = 104 + self.state = 108 localctx.compoundUnit = self.unitType(0) - self.state = 105 + self.state = 109 localctx.rightParentheses = self.match(PyNestMLParser.RIGHT_PAREN) pass - elif token in [89]: - self.state = 107 + elif token in [90]: + self.state = 111 localctx.unitlessLiteral = self.match(PyNestMLParser.UNSIGNED_INTEGER) - self.state = 108 + self.state = 112 localctx.divOp = self.match(PyNestMLParser.FORWARD_SLASH) - self.state = 109 + self.state = 113 localctx.right = self.unitType(2) pass - elif token in [88]: - self.state = 110 + elif token in [89]: + self.state = 114 localctx.unit = self.match(PyNestMLParser.NAME) pass else: raise NoViableAltException(self) self._ctx.stop = self._input.LT(-1) - self.state = 124 + self.state = 128 self._errHandler.sync(self) _alt = self._interp.adaptivePredict(self._input,4,self._ctx) while _alt!=2 and _alt!=ATN.INVALID_ALT_NUMBER: @@ -648,32 +657,32 @@ def unitType(self, _p:int=0): if self._parseListeners is not None: self.triggerExitRuleEvent() _prevctx = localctx - self.state = 122 + self.state = 126 self._errHandler.sync(self) la_ = self._interp.adaptivePredict(self._input,3,self._ctx) if la_ == 1: localctx = PyNestMLParser.UnitTypeContext(self, _parentctx, _parentState) localctx.left = _prevctx self.pushNewRecursionContext(localctx, _startState, self.RULE_unitType) - self.state = 113 + self.state = 117 if not self.precpred(self._ctx, 3): from antlr4.error.Errors import FailedPredicateException raise FailedPredicateException(self, "self.precpred(self._ctx, 3)") - self.state = 116 + self.state = 120 self._errHandler.sync(self) token = self._input.LA(1) - if token in [77]: - self.state = 114 + if token in [78]: + self.state = 118 localctx.timesOp = self.match(PyNestMLParser.STAR) pass - elif token in [79]: - self.state = 115 + elif token in [80]: + self.state = 119 localctx.divOp = self.match(PyNestMLParser.FORWARD_SLASH) pass else: raise NoViableAltException(self) - self.state = 118 + self.state = 122 localctx.right = self.unitType(4) pass @@ -681,18 +690,18 @@ def unitType(self, _p:int=0): localctx = PyNestMLParser.UnitTypeContext(self, _parentctx, _parentState) localctx.base = _prevctx self.pushNewRecursionContext(localctx, _startState, self.RULE_unitType) - self.state = 119 + self.state = 123 if not self.precpred(self._ctx, 4): from antlr4.error.Errors import FailedPredicateException raise FailedPredicateException(self, "self.precpred(self._ctx, 4)") - self.state = 120 + self.state = 124 localctx.powOp = self.match(PyNestMLParser.STAR_STAR) - self.state = 121 + self.state = 125 localctx.exponent = self.unitTypeExponent() pass - self.state = 126 + self.state = 130 self._errHandler.sync(self) _alt = self._interp.adaptivePredict(self._input,4,self._ctx) @@ -740,20 +749,20 @@ def unitTypeExponent(self): self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 128 + self.state = 132 self._errHandler.sync(self) _la = self._input.LA(1) - if _la==51 or _la==75: - self.state = 127 + if _la==52 or _la==76: + self.state = 131 _la = self._input.LA(1) - if not(_la==51 or _la==75): + if not(_la==52 or _la==76): self._errHandler.recoverInline(self) else: self._errHandler.reportMatch(self) self.consume() - self.state = 130 + self.state = 134 self.match(PyNestMLParser.UNSIGNED_INTEGER) except RecognitionException as re: localctx.exception = re @@ -866,38 +875,38 @@ def expression(self, _p:int=0): self.enterRecursionRule(localctx, 6, self.RULE_expression, _p) try: self.enterOuterAlt(localctx, 1) - self.state = 143 + self.state = 147 self._errHandler.sync(self) token = self._input.LA(1) - if token in [49]: - self.state = 133 + if token in [50]: + self.state = 137 localctx.leftParentheses = self.match(PyNestMLParser.LEFT_PAREN) - self.state = 134 + self.state = 138 localctx.term = self.expression(0) - self.state = 135 + self.state = 139 localctx.rightParentheses = self.match(PyNestMLParser.RIGHT_PAREN) pass - elif token in [51, 52, 75]: - self.state = 137 + elif token in [52, 53, 76]: + self.state = 141 self.unaryOperator() - self.state = 138 + self.state = 142 localctx.term = self.expression(9) pass elif token in [28]: - self.state = 140 + self.state = 144 localctx.logicalNot = self.match(PyNestMLParser.NOT_KEYWORD) - self.state = 141 + self.state = 145 localctx.term = self.expression(4) pass - elif token in [25, 86, 87, 88, 89, 90]: - self.state = 142 + elif token in [25, 87, 88, 89, 90, 91]: + self.state = 146 self.simpleExpression() pass else: raise NoViableAltException(self) self._ctx.stop = self._input.LT(-1) - self.state = 181 + self.state = 185 self._errHandler.sync(self) _alt = self._interp.adaptivePredict(self._input,10,self._ctx) while _alt!=2 and _alt!=ATN.INVALID_ALT_NUMBER: @@ -905,20 +914,20 @@ def expression(self, _p:int=0): if self._parseListeners is not None: self.triggerExitRuleEvent() _prevctx = localctx - self.state = 179 + self.state = 183 self._errHandler.sync(self) la_ = self._interp.adaptivePredict(self._input,9,self._ctx) if la_ == 1: localctx = PyNestMLParser.ExpressionContext(self, _parentctx, _parentState) localctx.left = _prevctx self.pushNewRecursionContext(localctx, _startState, self.RULE_expression) - self.state = 145 + self.state = 149 if not self.precpred(self._ctx, 10): from antlr4.error.Errors import FailedPredicateException raise FailedPredicateException(self, "self.precpred(self._ctx, 10)") - self.state = 146 + self.state = 150 localctx.powOp = self.match(PyNestMLParser.STAR_STAR) - self.state = 147 + self.state = 151 localctx.right = self.expression(10) pass @@ -926,29 +935,29 @@ def expression(self, _p:int=0): localctx = PyNestMLParser.ExpressionContext(self, _parentctx, _parentState) localctx.left = _prevctx self.pushNewRecursionContext(localctx, _startState, self.RULE_expression) - self.state = 148 + self.state = 152 if not self.precpred(self._ctx, 8): from antlr4.error.Errors import FailedPredicateException raise FailedPredicateException(self, "self.precpred(self._ctx, 8)") - self.state = 152 + self.state = 156 self._errHandler.sync(self) token = self._input.LA(1) - if token in [77]: - self.state = 149 + if token in [78]: + self.state = 153 localctx.timesOp = self.match(PyNestMLParser.STAR) pass - elif token in [79]: - self.state = 150 + elif token in [80]: + self.state = 154 localctx.divOp = self.match(PyNestMLParser.FORWARD_SLASH) pass - elif token in [80]: - self.state = 151 + elif token in [81]: + self.state = 155 localctx.moduloOp = self.match(PyNestMLParser.PERCENT) pass else: raise NoViableAltException(self) - self.state = 154 + self.state = 158 localctx.right = self.expression(9) pass @@ -956,25 +965,25 @@ def expression(self, _p:int=0): localctx = PyNestMLParser.ExpressionContext(self, _parentctx, _parentState) localctx.left = _prevctx self.pushNewRecursionContext(localctx, _startState, self.RULE_expression) - self.state = 155 + self.state = 159 if not self.precpred(self._ctx, 7): from antlr4.error.Errors import FailedPredicateException raise FailedPredicateException(self, "self.precpred(self._ctx, 7)") - self.state = 158 + self.state = 162 self._errHandler.sync(self) token = self._input.LA(1) - if token in [51]: - self.state = 156 + if token in [52]: + self.state = 160 localctx.plusOp = self.match(PyNestMLParser.PLUS) pass - elif token in [75]: - self.state = 157 + elif token in [76]: + self.state = 161 localctx.minusOp = self.match(PyNestMLParser.MINUS) pass else: raise NoViableAltException(self) - self.state = 160 + self.state = 164 localctx.right = self.expression(8) pass @@ -982,13 +991,13 @@ def expression(self, _p:int=0): localctx = PyNestMLParser.ExpressionContext(self, _parentctx, _parentState) localctx.left = _prevctx self.pushNewRecursionContext(localctx, _startState, self.RULE_expression) - self.state = 161 + self.state = 165 if not self.precpred(self._ctx, 6): from antlr4.error.Errors import FailedPredicateException raise FailedPredicateException(self, "self.precpred(self._ctx, 6)") - self.state = 162 + self.state = 166 self.bitOperator() - self.state = 163 + self.state = 167 localctx.right = self.expression(7) pass @@ -996,13 +1005,13 @@ def expression(self, _p:int=0): localctx = PyNestMLParser.ExpressionContext(self, _parentctx, _parentState) localctx.left = _prevctx self.pushNewRecursionContext(localctx, _startState, self.RULE_expression) - self.state = 165 + self.state = 169 if not self.precpred(self._ctx, 5): from antlr4.error.Errors import FailedPredicateException raise FailedPredicateException(self, "self.precpred(self._ctx, 5)") - self.state = 166 + self.state = 170 self.comparisonOperator() - self.state = 167 + self.state = 171 localctx.right = self.expression(6) pass @@ -1010,13 +1019,13 @@ def expression(self, _p:int=0): localctx = PyNestMLParser.ExpressionContext(self, _parentctx, _parentState) localctx.left = _prevctx self.pushNewRecursionContext(localctx, _startState, self.RULE_expression) - self.state = 169 + self.state = 173 if not self.precpred(self._ctx, 3): from antlr4.error.Errors import FailedPredicateException raise FailedPredicateException(self, "self.precpred(self._ctx, 3)") - self.state = 170 + self.state = 174 self.logicalOperator() - self.state = 171 + self.state = 175 localctx.right = self.expression(4) pass @@ -1024,22 +1033,22 @@ def expression(self, _p:int=0): localctx = PyNestMLParser.ExpressionContext(self, _parentctx, _parentState) localctx.condition = _prevctx self.pushNewRecursionContext(localctx, _startState, self.RULE_expression) - self.state = 173 + self.state = 177 if not self.precpred(self._ctx, 2): from antlr4.error.Errors import FailedPredicateException raise FailedPredicateException(self, "self.precpred(self._ctx, 2)") - self.state = 174 + self.state = 178 self.match(PyNestMLParser.QUESTION) - self.state = 175 + self.state = 179 localctx.ifTrue = self.expression(0) - self.state = 176 + self.state = 180 self.match(PyNestMLParser.COLON) - self.state = 177 + self.state = 181 localctx.ifNot = self.expression(3) pass - self.state = 183 + self.state = 187 self._errHandler.sync(self) _alt = self._interp.adaptivePredict(self._input,10,self._ctx) @@ -1102,35 +1111,35 @@ def simpleExpression(self): self.enterRule(localctx, 8, self.RULE_simpleExpression) self._la = 0 # Token type try: - self.state = 193 + self.state = 197 self._errHandler.sync(self) la_ = self._interp.adaptivePredict(self._input,12,self._ctx) if la_ == 1: self.enterOuterAlt(localctx, 1) - self.state = 184 + self.state = 188 self.functionCall() pass elif la_ == 2: self.enterOuterAlt(localctx, 2) - self.state = 185 + self.state = 189 self.match(PyNestMLParser.BOOLEAN_LITERAL) pass elif la_ == 3: self.enterOuterAlt(localctx, 3) - self.state = 186 + self.state = 190 _la = self._input.LA(1) - if not(_la==89 or _la==90): + if not(_la==90 or _la==91): self._errHandler.recoverInline(self) else: self._errHandler.reportMatch(self) self.consume() - self.state = 188 + self.state = 192 self._errHandler.sync(self) la_ = self._interp.adaptivePredict(self._input,11,self._ctx) if la_ == 1: - self.state = 187 + self.state = 191 self.variable() @@ -1138,19 +1147,19 @@ def simpleExpression(self): elif la_ == 4: self.enterOuterAlt(localctx, 4) - self.state = 190 + self.state = 194 localctx.string = self.match(PyNestMLParser.STRING_LITERAL) pass elif la_ == 5: self.enterOuterAlt(localctx, 5) - self.state = 191 + self.state = 195 localctx.isInf = self.match(PyNestMLParser.INF_KEYWORD) pass elif la_ == 6: self.enterOuterAlt(localctx, 6) - self.state = 192 + self.state = 196 self.variable() pass @@ -1201,19 +1210,19 @@ def unaryOperator(self): self.enterRule(localctx, 10, self.RULE_unaryOperator) try: self.enterOuterAlt(localctx, 1) - self.state = 198 + self.state = 202 self._errHandler.sync(self) token = self._input.LA(1) - if token in [51]: - self.state = 195 + if token in [52]: + self.state = 199 localctx.unaryPlus = self.match(PyNestMLParser.PLUS) pass - elif token in [75]: - self.state = 196 + elif token in [76]: + self.state = 200 localctx.unaryMinus = self.match(PyNestMLParser.MINUS) pass - elif token in [52]: - self.state = 197 + elif token in [53]: + self.state = 201 localctx.unaryTilde = self.match(PyNestMLParser.TILDE) pass else: @@ -1273,27 +1282,27 @@ def bitOperator(self): self.enterRule(localctx, 12, self.RULE_bitOperator) try: self.enterOuterAlt(localctx, 1) - self.state = 205 + self.state = 209 self._errHandler.sync(self) token = self._input.LA(1) - if token in [55]: - self.state = 200 + if token in [56]: + self.state = 204 localctx.bitAnd = self.match(PyNestMLParser.AMPERSAND) pass - elif token in [54]: - self.state = 201 + elif token in [55]: + self.state = 205 localctx.bitXor = self.match(PyNestMLParser.CARET) pass - elif token in [53]: - self.state = 202 + elif token in [54]: + self.state = 206 localctx.bitOr = self.match(PyNestMLParser.PIPE) pass - elif token in [61]: - self.state = 203 + elif token in [62]: + self.state = 207 localctx.bitShiftLeft = self.match(PyNestMLParser.LEFT_LEFT_ANGLE) pass - elif token in [62]: - self.state = 204 + elif token in [63]: + self.state = 208 localctx.bitShiftRight = self.match(PyNestMLParser.RIGHT_RIGHT_ANGLE) pass else: @@ -1361,35 +1370,35 @@ def comparisonOperator(self): self.enterRule(localctx, 14, self.RULE_comparisonOperator) try: self.enterOuterAlt(localctx, 1) - self.state = 214 + self.state = 218 self._errHandler.sync(self) token = self._input.LA(1) - if token in [63]: - self.state = 207 + if token in [64]: + self.state = 211 localctx.lt = self.match(PyNestMLParser.LEFT_ANGLE) pass - elif token in [65]: - self.state = 208 + elif token in [66]: + self.state = 212 localctx.le = self.match(PyNestMLParser.LEFT_ANGLE_EQUALS) pass - elif token in [70]: - self.state = 209 + elif token in [71]: + self.state = 213 localctx.eq = self.match(PyNestMLParser.EQUALS_EQUALS) pass - elif token in [71]: - self.state = 210 + elif token in [72]: + self.state = 214 localctx.ne = self.match(PyNestMLParser.EXCLAMATION_EQUALS) pass - elif token in [72]: - self.state = 211 + elif token in [73]: + self.state = 215 localctx.ne2 = self.match(PyNestMLParser.LEFT_ANGLE_RIGHT_ANGLE) pass - elif token in [73]: - self.state = 212 + elif token in [74]: + self.state = 216 localctx.ge = self.match(PyNestMLParser.RIGHT_ANGLE_EQUALS) pass - elif token in [64]: - self.state = 213 + elif token in [65]: + self.state = 217 localctx.gt = self.match(PyNestMLParser.RIGHT_ANGLE) pass else: @@ -1437,15 +1446,15 @@ def logicalOperator(self): self.enterRule(localctx, 16, self.RULE_logicalOperator) try: self.enterOuterAlt(localctx, 1) - self.state = 218 + self.state = 222 self._errHandler.sync(self) token = self._input.LA(1) if token in [26]: - self.state = 216 + self.state = 220 localctx.logicalAnd = self.match(PyNestMLParser.AND_KEYWORD) pass elif token in [27]: - self.state = 217 + self.state = 221 localctx.logicalOr = self.match(PyNestMLParser.OR_KEYWORD) pass else: @@ -1506,28 +1515,28 @@ def variable(self): self.enterRule(localctx, 18, self.RULE_variable) try: self.enterOuterAlt(localctx, 1) - self.state = 220 + self.state = 224 localctx.name = self.match(PyNestMLParser.NAME) - self.state = 225 + self.state = 229 self._errHandler.sync(self) la_ = self._interp.adaptivePredict(self._input,17,self._ctx) if la_ == 1: - self.state = 221 + self.state = 225 self.match(PyNestMLParser.LEFT_SQUARE_BRACKET) - self.state = 222 + self.state = 226 localctx.vectorParameter = self.expression(0) - self.state = 223 + self.state = 227 self.match(PyNestMLParser.RIGHT_SQUARE_BRACKET) - self.state = 230 + self.state = 234 self._errHandler.sync(self) _alt = self._interp.adaptivePredict(self._input,18,self._ctx) while _alt!=2 and _alt!=ATN.INVALID_ALT_NUMBER: if _alt==1: - self.state = 227 + self.state = 231 self.match(PyNestMLParser.DIFFERENTIAL_ORDER) - self.state = 232 + self.state = 236 self._errHandler.sync(self) _alt = self._interp.adaptivePredict(self._input,18,self._ctx) @@ -1589,31 +1598,31 @@ def functionCall(self): self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 233 + self.state = 237 localctx.calleeName = self.match(PyNestMLParser.NAME) - self.state = 234 + self.state = 238 self.match(PyNestMLParser.LEFT_PAREN) - self.state = 243 + self.state = 247 self._errHandler.sync(self) _la = self._input.LA(1) - if (((_la) & ~0x3f) == 0 and ((1 << _la) & 7318349696466944) != 0) or ((((_la - 75)) & ~0x3f) == 0 and ((1 << (_la - 75)) & 63489) != 0): - self.state = 235 + if (((_la) & ~0x3f) == 0 and ((1 << _la) & 14636699090944000) != 0) or ((((_la - 76)) & ~0x3f) == 0 and ((1 << (_la - 76)) & 63489) != 0): + self.state = 239 self.expression(0) - self.state = 240 + self.state = 244 self._errHandler.sync(self) _la = self._input.LA(1) - while _la==74: - self.state = 236 + while _la==75: + self.state = 240 self.match(PyNestMLParser.COMMA) - self.state = 237 + self.state = 241 self.expression(0) - self.state = 242 + self.state = 246 self._errHandler.sync(self) _la = self._input.LA(1) - self.state = 245 + self.state = 249 self.match(PyNestMLParser.RIGHT_PAREN) except RecognitionException as re: localctx.exception = re @@ -1686,43 +1695,43 @@ def inlineExpression(self): self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 248 + self.state = 252 self._errHandler.sync(self) _la = self._input.LA(1) - if _la==29: - self.state = 247 + if _la==30: + self.state = 251 localctx.recordable = self.match(PyNestMLParser.RECORDABLE_KEYWORD) - self.state = 250 + self.state = 254 self.match(PyNestMLParser.INLINE_KEYWORD) - self.state = 251 + self.state = 255 localctx.variableName = self.match(PyNestMLParser.NAME) - self.state = 252 + self.state = 256 self.dataType() - self.state = 253 + self.state = 257 self.match(PyNestMLParser.EQUALS) - self.state = 254 + self.state = 258 self.expression(0) - self.state = 256 + self.state = 260 self._errHandler.sync(self) _la = self._input.LA(1) - if _la==84: - self.state = 255 + if _la==85: + self.state = 259 self.match(PyNestMLParser.SEMICOLON) - self.state = 261 + self.state = 265 self._errHandler.sync(self) _la = self._input.LA(1) - while (((_la) & ~0x3f) == 0 and ((1 << _la) & 246290604621824) != 0): - self.state = 258 + while (((_la) & ~0x3f) == 0 and ((1 << _la) & 492581209243648) != 0): + self.state = 262 localctx.decorator = self.anyDecorator() - self.state = 263 + self.state = 267 self._errHandler.sync(self) _la = self._input.LA(1) - self.state = 264 + self.state = 268 self.match(PyNestMLParser.NEWLINE) except RecognitionException as re: localctx.exception = re @@ -1786,31 +1795,31 @@ def odeEquation(self): self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 266 + self.state = 270 localctx.lhs = self.variable() - self.state = 267 + self.state = 271 self.match(PyNestMLParser.EQUALS) - self.state = 268 + self.state = 272 localctx.rhs = self.expression(0) - self.state = 270 + self.state = 274 self._errHandler.sync(self) _la = self._input.LA(1) - if _la==84: - self.state = 269 + if _la==85: + self.state = 273 self.match(PyNestMLParser.SEMICOLON) - self.state = 275 + self.state = 279 self._errHandler.sync(self) _la = self._input.LA(1) - while (((_la) & ~0x3f) == 0 and ((1 << _la) & 246290604621824) != 0): - self.state = 272 + while (((_la) & ~0x3f) == 0 and ((1 << _la) & 492581209243648) != 0): + self.state = 276 localctx.decorator = self.anyDecorator() - self.state = 277 + self.state = 281 self._errHandler.sync(self) _la = self._input.LA(1) - self.state = 278 + self.state = 282 self.match(PyNestMLParser.NEWLINE) except RecognitionException as re: localctx.exception = re @@ -1882,39 +1891,39 @@ def kernel(self): self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 280 + self.state = 284 self.match(PyNestMLParser.KERNEL_KEYWORD) - self.state = 281 + self.state = 285 self.variable() - self.state = 282 + self.state = 286 self.match(PyNestMLParser.EQUALS) - self.state = 283 + self.state = 287 self.expression(0) - self.state = 291 + self.state = 295 self._errHandler.sync(self) _la = self._input.LA(1) while _la==4: - self.state = 284 + self.state = 288 self.match(PyNestMLParser.KERNEL_JOINING) - self.state = 285 + self.state = 289 self.variable() - self.state = 286 + self.state = 290 self.match(PyNestMLParser.EQUALS) - self.state = 287 + self.state = 291 self.expression(0) - self.state = 293 + self.state = 297 self._errHandler.sync(self) _la = self._input.LA(1) - self.state = 295 + self.state = 299 self._errHandler.sync(self) _la = self._input.LA(1) - if _la==84: - self.state = 294 + if _la==85: + self.state = 298 self.match(PyNestMLParser.SEMICOLON) - self.state = 297 + self.state = 301 self.match(PyNestMLParser.NEWLINE) except RecognitionException as re: localctx.exception = re @@ -1967,23 +1976,23 @@ def block(self): self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 299 + self.state = 303 self.match(PyNestMLParser.NEWLINE) - self.state = 300 + self.state = 304 self.match(PyNestMLParser.INDENT) - self.state = 302 + self.state = 306 self._errHandler.sync(self) _la = self._input.LA(1) while True: - self.state = 301 + self.state = 305 self.stmt() - self.state = 304 + self.state = 308 self._errHandler.sync(self) _la = self._input.LA(1) - if not ((((_la) & ~0x3f) == 0 and ((1 << _la) & 543621120) != 0) or _la==88): + if not ((((_la) & ~0x3f) == 0 and ((1 << _la) & 1617362944) != 0) or _la==89): break - self.state = 306 + self.state = 310 self.match(PyNestMLParser.DEDENT) except RecognitionException as re: localctx.exception = re @@ -2026,17 +2035,17 @@ def stmt(self): localctx = PyNestMLParser.StmtContext(self, self._ctx, self.state) self.enterRule(localctx, 30, self.RULE_stmt) try: - self.state = 310 + self.state = 314 self._errHandler.sync(self) token = self._input.LA(1) - if token in [16, 17, 29, 88]: + if token in [16, 17, 29, 30, 89]: self.enterOuterAlt(localctx, 1) - self.state = 308 + self.state = 312 self.smallStmt() pass elif token in [18, 21, 22]: self.enterOuterAlt(localctx, 2) - self.state = 309 + self.state = 313 self.compoundStmt() pass else: @@ -2087,22 +2096,22 @@ def compoundStmt(self): localctx = PyNestMLParser.CompoundStmtContext(self, self._ctx, self.state) self.enterRule(localctx, 32, self.RULE_compoundStmt) try: - self.state = 315 + self.state = 319 self._errHandler.sync(self) token = self._input.LA(1) if token in [18]: self.enterOuterAlt(localctx, 1) - self.state = 312 + self.state = 316 self.ifStmt() pass elif token in [21]: self.enterOuterAlt(localctx, 2) - self.state = 313 + self.state = 317 self.forStmt() pass elif token in [22]: self.enterOuterAlt(localctx, 3) - self.state = 314 + self.state = 318 self.whileStmt() pass else: @@ -2143,6 +2152,10 @@ def returnStmt(self): return self.getTypedRuleContext(PyNestMLParser.ReturnStmtContext,0) + def includeStatement(self): + return self.getTypedRuleContext(PyNestMLParser.IncludeStatementContext,0) + + def getRuleIndex(self): return PyNestMLParser.RULE_smallStmt @@ -2161,31 +2174,36 @@ def smallStmt(self): self.enterRule(localctx, 34, self.RULE_smallStmt) try: self.enterOuterAlt(localctx, 1) - self.state = 321 + self.state = 326 self._errHandler.sync(self) la_ = self._interp.adaptivePredict(self._input,31,self._ctx) if la_ == 1: - self.state = 317 + self.state = 321 self.assignment() pass elif la_ == 2: - self.state = 318 + self.state = 322 self.functionCall() pass elif la_ == 3: - self.state = 319 + self.state = 323 self.declaration() pass elif la_ == 4: - self.state = 320 + self.state = 324 self.returnStmt() pass + elif la_ == 5: + self.state = 325 + self.includeStatement() + pass + - self.state = 323 + self.state = 328 self.match(PyNestMLParser.NEWLINE) except RecognitionException as re: localctx.exception = re @@ -2250,35 +2268,35 @@ def assignment(self): self.enterRule(localctx, 36, self.RULE_assignment) try: self.enterOuterAlt(localctx, 1) - self.state = 325 + self.state = 330 localctx.lhs_variable = self.variable() - self.state = 331 + self.state = 336 self._errHandler.sync(self) token = self._input.LA(1) - if token in [76]: - self.state = 326 + if token in [77]: + self.state = 331 localctx.directAssignment = self.match(PyNestMLParser.EQUALS) pass - elif token in [66]: - self.state = 327 + elif token in [67]: + self.state = 332 localctx.compoundSum = self.match(PyNestMLParser.PLUS_EQUALS) pass - elif token in [67]: - self.state = 328 + elif token in [68]: + self.state = 333 localctx.compoundMinus = self.match(PyNestMLParser.MINUS_EQUALS) pass - elif token in [68]: - self.state = 329 + elif token in [69]: + self.state = 334 localctx.compoundProduct = self.match(PyNestMLParser.STAR_EQUALS) pass - elif token in [69]: - self.state = 330 + elif token in [70]: + self.state = 335 localctx.compoundQuotient = self.match(PyNestMLParser.FORWARD_SLASH_EQUALS) pass else: raise NoViableAltException(self) - self.state = 333 + self.state = 338 self.expression(0) except RecognitionException as re: localctx.exception = re @@ -2289,6 +2307,95 @@ def assignment(self): return localctx + class IncludeStatementContext(ParserRuleContext): + __slots__ = 'parser' + + def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): + super().__init__(parent, invokingState) + self.parser = parser + + def INCLUDE_KEYWORD(self): + return self.getToken(PyNestMLParser.INCLUDE_KEYWORD, 0) + + def STRING_LITERAL(self): + return self.getToken(PyNestMLParser.STRING_LITERAL, 0) + + def getRuleIndex(self): + return PyNestMLParser.RULE_includeStatement + + def accept(self, visitor:ParseTreeVisitor): + if hasattr( visitor, "visitIncludeStatement" ): + return visitor.visitIncludeStatement(self) + else: + return visitor.visitChildren(self) + + + + + def includeStatement(self): + + localctx = PyNestMLParser.IncludeStatementContext(self, self._ctx, self.state) + self.enterRule(localctx, 38, self.RULE_includeStatement) + try: + self.enterOuterAlt(localctx, 1) + self.state = 340 + self.match(PyNestMLParser.INCLUDE_KEYWORD) + self.state = 341 + self.match(PyNestMLParser.STRING_LITERAL) + except RecognitionException as re: + localctx.exception = re + self._errHandler.reportError(self, re) + self._errHandler.recover(self, re) + finally: + self.exitRule() + return localctx + + + class IncludeStatement_newlineContext(ParserRuleContext): + __slots__ = 'parser' + + def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): + super().__init__(parent, invokingState) + self.parser = parser + + def includeStatement(self): + return self.getTypedRuleContext(PyNestMLParser.IncludeStatementContext,0) + + + def NEWLINE(self): + return self.getToken(PyNestMLParser.NEWLINE, 0) + + def getRuleIndex(self): + return PyNestMLParser.RULE_includeStatement_newline + + def accept(self, visitor:ParseTreeVisitor): + if hasattr( visitor, "visitIncludeStatement_newline" ): + return visitor.visitIncludeStatement_newline(self) + else: + return visitor.visitChildren(self) + + + + + def includeStatement_newline(self): + + localctx = PyNestMLParser.IncludeStatement_newlineContext(self, self._ctx, self.state) + self.enterRule(localctx, 40, self.RULE_includeStatement_newline) + try: + self.enterOuterAlt(localctx, 1) + self.state = 343 + self.includeStatement() + self.state = 344 + self.match(PyNestMLParser.NEWLINE) + except RecognitionException as re: + localctx.exception = re + self._errHandler.reportError(self, re) + self._errHandler.recover(self, re) + finally: + self.exitRule() + return localctx + + class DeclarationContext(ParserRuleContext): __slots__ = 'parser' @@ -2362,71 +2469,71 @@ def accept(self, visitor:ParseTreeVisitor): def declaration(self): localctx = PyNestMLParser.DeclarationContext(self, self._ctx, self.state) - self.enterRule(localctx, 38, self.RULE_declaration) + self.enterRule(localctx, 42, self.RULE_declaration) self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 336 + self.state = 347 self._errHandler.sync(self) _la = self._input.LA(1) - if _la==29: - self.state = 335 + if _la==30: + self.state = 346 localctx.isRecordable = self.match(PyNestMLParser.RECORDABLE_KEYWORD) - self.state = 339 + self.state = 350 self._errHandler.sync(self) _la = self._input.LA(1) if _la==16: - self.state = 338 + self.state = 349 localctx.isInlineExpression = self.match(PyNestMLParser.INLINE_KEYWORD) - self.state = 341 + self.state = 352 self.variable() - self.state = 346 + self.state = 357 self._errHandler.sync(self) _la = self._input.LA(1) - while _la==74: - self.state = 342 + while _la==75: + self.state = 353 self.match(PyNestMLParser.COMMA) - self.state = 343 + self.state = 354 self.variable() - self.state = 348 + self.state = 359 self._errHandler.sync(self) _la = self._input.LA(1) - self.state = 349 + self.state = 360 self.dataType() - self.state = 352 + self.state = 363 self._errHandler.sync(self) _la = self._input.LA(1) - if _la==76: - self.state = 350 + if _la==77: + self.state = 361 self.match(PyNestMLParser.EQUALS) - self.state = 351 + self.state = 362 localctx.rhs = self.expression(0) - self.state = 358 + self.state = 369 self._errHandler.sync(self) _la = self._input.LA(1) - if _la==59: - self.state = 354 + if _la==60: + self.state = 365 self.match(PyNestMLParser.LEFT_LEFT_SQUARE) - self.state = 355 + self.state = 366 localctx.invariant = self.expression(0) - self.state = 356 + self.state = 367 self.match(PyNestMLParser.RIGHT_RIGHT_SQUARE) - self.state = 363 + self.state = 374 self._errHandler.sync(self) _la = self._input.LA(1) - while (((_la) & ~0x3f) == 0 and ((1 << _la) & 246290604621824) != 0): - self.state = 360 + while (((_la) & ~0x3f) == 0 and ((1 << _la) & 492581209243648) != 0): + self.state = 371 localctx.decorator = self.anyDecorator() - self.state = 365 + self.state = 376 self._errHandler.sync(self) _la = self._input.LA(1) @@ -2468,12 +2575,12 @@ def accept(self, visitor:ParseTreeVisitor): def declaration_newline(self): localctx = PyNestMLParser.Declaration_newlineContext(self, self._ctx, self.state) - self.enterRule(localctx, 40, self.RULE_declaration_newline) + self.enterRule(localctx, 44, self.RULE_declaration_newline) try: self.enterOuterAlt(localctx, 1) - self.state = 366 + self.state = 377 self.declaration() - self.state = 367 + self.state = 378 self.match(PyNestMLParser.NEWLINE) except RecognitionException as re: localctx.exception = re @@ -2526,30 +2633,30 @@ def accept(self, visitor:ParseTreeVisitor): def anyDecorator(self): localctx = PyNestMLParser.AnyDecoratorContext(self, self._ctx, self.state) - self.enterRule(localctx, 42, self.RULE_anyDecorator) + self.enterRule(localctx, 46, self.RULE_anyDecorator) try: - self.state = 376 + self.state = 387 self._errHandler.sync(self) token = self._input.LA(1) - if token in [45]: + if token in [46]: self.enterOuterAlt(localctx, 1) - self.state = 369 + self.state = 380 self.match(PyNestMLParser.DECORATOR_HOMOGENEOUS) pass - elif token in [46]: + elif token in [47]: self.enterOuterAlt(localctx, 2) - self.state = 370 + self.state = 381 self.match(PyNestMLParser.DECORATOR_HETEROGENEOUS) pass - elif token in [47]: + elif token in [48]: self.enterOuterAlt(localctx, 3) - self.state = 371 + self.state = 382 self.match(PyNestMLParser.AT) - self.state = 372 + self.state = 383 self.namespaceDecoratorNamespace() - self.state = 373 + self.state = 384 self.match(PyNestMLParser.DOUBLE_COLON) - self.state = 374 + self.state = 385 self.namespaceDecoratorName() pass else: @@ -2590,10 +2697,10 @@ def accept(self, visitor:ParseTreeVisitor): def namespaceDecoratorNamespace(self): localctx = PyNestMLParser.NamespaceDecoratorNamespaceContext(self, self._ctx, self.state) - self.enterRule(localctx, 44, self.RULE_namespaceDecoratorNamespace) + self.enterRule(localctx, 48, self.RULE_namespaceDecoratorNamespace) try: self.enterOuterAlt(localctx, 1) - self.state = 378 + self.state = 389 localctx.name = self.match(PyNestMLParser.NAME) except RecognitionException as re: localctx.exception = re @@ -2630,10 +2737,10 @@ def accept(self, visitor:ParseTreeVisitor): def namespaceDecoratorName(self): localctx = PyNestMLParser.NamespaceDecoratorNameContext(self, self._ctx, self.state) - self.enterRule(localctx, 46, self.RULE_namespaceDecoratorName) + self.enterRule(localctx, 50, self.RULE_namespaceDecoratorName) try: self.enterOuterAlt(localctx, 1) - self.state = 380 + self.state = 391 localctx.name = self.match(PyNestMLParser.NAME) except RecognitionException as re: localctx.exception = re @@ -2673,17 +2780,17 @@ def accept(self, visitor:ParseTreeVisitor): def returnStmt(self): localctx = PyNestMLParser.ReturnStmtContext(self, self._ctx, self.state) - self.enterRule(localctx, 48, self.RULE_returnStmt) + self.enterRule(localctx, 52, self.RULE_returnStmt) self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 382 + self.state = 393 self.match(PyNestMLParser.RETURN_KEYWORD) - self.state = 384 + self.state = 395 self._errHandler.sync(self) _la = self._input.LA(1) - if (((_la) & ~0x3f) == 0 and ((1 << _la) & 7318349696466944) != 0) or ((((_la - 75)) & ~0x3f) == 0 and ((1 << (_la - 75)) & 63489) != 0): - self.state = 383 + if (((_la) & ~0x3f) == 0 and ((1 << _la) & 14636699090944000) != 0) or ((((_la - 76)) & ~0x3f) == 0 and ((1 << (_la - 76)) & 63489) != 0): + self.state = 394 self.expression(0) @@ -2733,27 +2840,27 @@ def accept(self, visitor:ParseTreeVisitor): def ifStmt(self): localctx = PyNestMLParser.IfStmtContext(self, self._ctx, self.state) - self.enterRule(localctx, 50, self.RULE_ifStmt) + self.enterRule(localctx, 54, self.RULE_ifStmt) self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 386 + self.state = 397 self.ifClause() - self.state = 390 + self.state = 401 self._errHandler.sync(self) _la = self._input.LA(1) while _la==19: - self.state = 387 + self.state = 398 self.elifClause() - self.state = 392 + self.state = 403 self._errHandler.sync(self) _la = self._input.LA(1) - self.state = 394 + self.state = 405 self._errHandler.sync(self) _la = self._input.LA(1) if _la==20: - self.state = 393 + self.state = 404 self.elseClause() @@ -2802,16 +2909,16 @@ def accept(self, visitor:ParseTreeVisitor): def ifClause(self): localctx = PyNestMLParser.IfClauseContext(self, self._ctx, self.state) - self.enterRule(localctx, 52, self.RULE_ifClause) + self.enterRule(localctx, 56, self.RULE_ifClause) try: self.enterOuterAlt(localctx, 1) - self.state = 396 + self.state = 407 self.match(PyNestMLParser.IF_KEYWORD) - self.state = 397 + self.state = 408 self.expression(0) - self.state = 398 + self.state = 409 self.match(PyNestMLParser.COLON) - self.state = 399 + self.state = 410 self.block() except RecognitionException as re: localctx.exception = re @@ -2858,16 +2965,16 @@ def accept(self, visitor:ParseTreeVisitor): def elifClause(self): localctx = PyNestMLParser.ElifClauseContext(self, self._ctx, self.state) - self.enterRule(localctx, 54, self.RULE_elifClause) + self.enterRule(localctx, 58, self.RULE_elifClause) try: self.enterOuterAlt(localctx, 1) - self.state = 401 + self.state = 412 self.match(PyNestMLParser.ELIF_KEYWORD) - self.state = 402 + self.state = 413 self.expression(0) - self.state = 403 + self.state = 414 self.match(PyNestMLParser.COLON) - self.state = 404 + self.state = 415 self.block() except RecognitionException as re: localctx.exception = re @@ -2910,14 +3017,14 @@ def accept(self, visitor:ParseTreeVisitor): def elseClause(self): localctx = PyNestMLParser.ElseClauseContext(self, self._ctx, self.state) - self.enterRule(localctx, 56, self.RULE_elseClause) + self.enterRule(localctx, 60, self.RULE_elseClause) try: self.enterOuterAlt(localctx, 1) - self.state = 406 + self.state = 417 self.match(PyNestMLParser.ELSE_KEYWORD) - self.state = 407 + self.state = 418 self.match(PyNestMLParser.COLON) - self.state = 408 + self.state = 419 self.block() except RecognitionException as re: localctx.exception = re @@ -2992,43 +3099,43 @@ def accept(self, visitor:ParseTreeVisitor): def forStmt(self): localctx = PyNestMLParser.ForStmtContext(self, self._ctx, self.state) - self.enterRule(localctx, 58, self.RULE_forStmt) + self.enterRule(localctx, 62, self.RULE_forStmt) self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 410 + self.state = 421 self.match(PyNestMLParser.FOR_KEYWORD) - self.state = 411 + self.state = 422 localctx.var = self.match(PyNestMLParser.NAME) - self.state = 412 + self.state = 423 self.match(PyNestMLParser.IN_KEYWORD) - self.state = 413 + self.state = 424 localctx.start_from = self.expression(0) - self.state = 414 + self.state = 425 self.match(PyNestMLParser.ELLIPSIS) - self.state = 415 + self.state = 426 localctx.end_at = self.expression(0) - self.state = 416 + self.state = 427 self.match(PyNestMLParser.STEP_KEYWORD) - self.state = 418 + self.state = 429 self._errHandler.sync(self) _la = self._input.LA(1) - if _la==75: - self.state = 417 + if _la==76: + self.state = 428 localctx.negative = self.match(PyNestMLParser.MINUS) - self.state = 420 + self.state = 431 _la = self._input.LA(1) - if not(_la==89 or _la==90): + if not(_la==90 or _la==91): self._errHandler.recoverInline(self) else: self._errHandler.reportMatch(self) self.consume() - self.state = 421 + self.state = 432 self.match(PyNestMLParser.COLON) - self.state = 422 + self.state = 433 self.block() except RecognitionException as re: localctx.exception = re @@ -3075,16 +3182,16 @@ def accept(self, visitor:ParseTreeVisitor): def whileStmt(self): localctx = PyNestMLParser.WhileStmtContext(self, self._ctx, self.state) - self.enterRule(localctx, 60, self.RULE_whileStmt) + self.enterRule(localctx, 64, self.RULE_whileStmt) try: self.enterOuterAlt(localctx, 1) - self.state = 424 + self.state = 435 self.match(PyNestMLParser.WHILE_KEYWORD) - self.state = 425 + self.state = 436 self.expression(0) - self.state = 426 + self.state = 437 self.match(PyNestMLParser.COLON) - self.state = 427 + self.state = 438 self.block() except RecognitionException as re: localctx.exception = re @@ -3133,35 +3240,35 @@ def accept(self, visitor:ParseTreeVisitor): def nestMLCompilationUnit(self): localctx = PyNestMLParser.NestMLCompilationUnitContext(self, self._ctx, self.state) - self.enterRule(localctx, 62, self.RULE_nestMLCompilationUnit) + self.enterRule(localctx, 66, self.RULE_nestMLCompilationUnit) self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 431 + self.state = 442 self._errHandler.sync(self) _la = self._input.LA(1) while True: - self.state = 431 + self.state = 442 self._errHandler.sync(self) token = self._input.LA(1) - if token in [31]: - self.state = 429 + if token in [32]: + self.state = 440 self.model() pass elif token in [9]: - self.state = 430 + self.state = 441 self.match(PyNestMLParser.NEWLINE) pass else: raise NoViableAltException(self) - self.state = 433 + self.state = 444 self._errHandler.sync(self) _la = self._input.LA(1) - if not (_la==9 or _la==31): + if not (_la==9 or _la==32): break - self.state = 435 + self.state = 446 self.match(PyNestMLParser.EOF) except RecognitionException as re: localctx.exception = re @@ -3204,14 +3311,14 @@ def accept(self, visitor:ParseTreeVisitor): def model(self): localctx = PyNestMLParser.ModelContext(self, self._ctx, self.state) - self.enterRule(localctx, 64, self.RULE_model) + self.enterRule(localctx, 68, self.RULE_model) try: self.enterOuterAlt(localctx, 1) - self.state = 437 + self.state = 448 self.match(PyNestMLParser.MODEL_KEYWORD) - self.state = 438 + self.state = 449 self.match(PyNestMLParser.NAME) - self.state = 439 + self.state = 450 self.modelBody() except RecognitionException as re: localctx.exception = re @@ -3241,6 +3348,13 @@ def INDENT(self): def DEDENT(self): return self.getToken(PyNestMLParser.DEDENT, 0) + def includeStatement_newline(self, i:int=None): + if i is None: + return self.getTypedRuleContexts(PyNestMLParser.IncludeStatement_newlineContext) + else: + return self.getTypedRuleContext(PyNestMLParser.IncludeStatement_newlineContext,i) + + def blockWithVariables(self, i:int=None): if i is None: return self.getTypedRuleContexts(PyNestMLParser.BlockWithVariablesContext) @@ -3312,65 +3426,69 @@ def accept(self, visitor:ParseTreeVisitor): def modelBody(self): localctx = PyNestMLParser.ModelBodyContext(self, self._ctx, self.state) - self.enterRule(localctx, 66, self.RULE_modelBody) + self.enterRule(localctx, 70, self.RULE_modelBody) self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 441 + self.state = 452 self.match(PyNestMLParser.COLON) - self.state = 442 + self.state = 453 self.match(PyNestMLParser.NEWLINE) - self.state = 443 + self.state = 454 self.match(PyNestMLParser.INDENT) - self.state = 452 + self.state = 464 self._errHandler.sync(self) _la = self._input.LA(1) while True: - self.state = 452 + self.state = 464 self._errHandler.sync(self) token = self._input.LA(1) - if token in [32, 33, 34]: - self.state = 444 + if token in [29]: + self.state = 455 + self.includeStatement_newline() + pass + elif token in [33, 34, 35]: + self.state = 456 self.blockWithVariables() pass - elif token in [36]: - self.state = 445 + elif token in [37]: + self.state = 457 self.equationsBlock() pass - elif token in [37]: - self.state = 446 + elif token in [38]: + self.state = 458 self.inputBlock() pass - elif token in [38]: - self.state = 447 + elif token in [39]: + self.state = 459 self.outputBlock() pass elif token in [15]: - self.state = 448 + self.state = 460 self.function() pass - elif token in [40]: - self.state = 449 + elif token in [41]: + self.state = 461 self.onReceiveBlock() pass - elif token in [41]: - self.state = 450 + elif token in [42]: + self.state = 462 self.onConditionBlock() pass - elif token in [35]: - self.state = 451 + elif token in [36]: + self.state = 463 self.updateBlock() pass else: raise NoViableAltException(self) - self.state = 454 + self.state = 466 self._errHandler.sync(self) _la = self._input.LA(1) - if not ((((_la) & ~0x3f) == 0 and ((1 << _la) & 3843995762688) != 0)): + if not ((((_la) & ~0x3f) == 0 and ((1 << _la) & 7688528363520) != 0)): break - self.state = 456 + self.state = 468 self.match(PyNestMLParser.DEDENT) except RecognitionException as re: localctx.exception = re @@ -3436,33 +3554,33 @@ def accept(self, visitor:ParseTreeVisitor): def onReceiveBlock(self): localctx = PyNestMLParser.OnReceiveBlockContext(self, self._ctx, self.state) - self.enterRule(localctx, 68, self.RULE_onReceiveBlock) + self.enterRule(localctx, 72, self.RULE_onReceiveBlock) self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 458 + self.state = 470 self.match(PyNestMLParser.ON_RECEIVE_KEYWORD) - self.state = 459 + self.state = 471 self.match(PyNestMLParser.LEFT_PAREN) - self.state = 460 + self.state = 472 localctx.inputPortName = self.match(PyNestMLParser.NAME) - self.state = 465 + self.state = 477 self._errHandler.sync(self) _la = self._input.LA(1) - while _la==74: - self.state = 461 + while _la==75: + self.state = 473 self.match(PyNestMLParser.COMMA) - self.state = 462 + self.state = 474 self.constParameter() - self.state = 467 + self.state = 479 self._errHandler.sync(self) _la = self._input.LA(1) - self.state = 468 + self.state = 480 self.match(PyNestMLParser.RIGHT_PAREN) - self.state = 469 + self.state = 481 self.match(PyNestMLParser.COLON) - self.state = 470 + self.state = 482 self.block() except RecognitionException as re: localctx.exception = re @@ -3529,33 +3647,33 @@ def accept(self, visitor:ParseTreeVisitor): def onConditionBlock(self): localctx = PyNestMLParser.OnConditionBlockContext(self, self._ctx, self.state) - self.enterRule(localctx, 70, self.RULE_onConditionBlock) + self.enterRule(localctx, 74, self.RULE_onConditionBlock) self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 472 + self.state = 484 self.match(PyNestMLParser.ON_CONDITION_KEYWORD) - self.state = 473 + self.state = 485 self.match(PyNestMLParser.LEFT_PAREN) - self.state = 474 + self.state = 486 localctx.condition = self.expression(0) - self.state = 479 + self.state = 491 self._errHandler.sync(self) _la = self._input.LA(1) - while _la==74: - self.state = 475 + while _la==75: + self.state = 487 self.match(PyNestMLParser.COMMA) - self.state = 476 + self.state = 488 self.constParameter() - self.state = 481 + self.state = 493 self._errHandler.sync(self) _la = self._input.LA(1) - self.state = 482 + self.state = 494 self.match(PyNestMLParser.RIGHT_PAREN) - self.state = 483 + self.state = 495 self.match(PyNestMLParser.COLON) - self.state = 484 + self.state = 496 self.block() except RecognitionException as re: localctx.exception = re @@ -3595,6 +3713,13 @@ def PARAMETERS_KEYWORD(self): def INTERNALS_KEYWORD(self): return self.getToken(PyNestMLParser.INTERNALS_KEYWORD, 0) + def includeStatement_newline(self, i:int=None): + if i is None: + return self.getTypedRuleContexts(PyNestMLParser.IncludeStatement_newlineContext) + else: + return self.getTypedRuleContext(PyNestMLParser.IncludeStatement_newlineContext,i) + + def declaration_newline(self, i:int=None): if i is None: return self.getTypedRuleContexts(PyNestMLParser.Declaration_newlineContext) @@ -3617,37 +3742,49 @@ def accept(self, visitor:ParseTreeVisitor): def blockWithVariables(self): localctx = PyNestMLParser.BlockWithVariablesContext(self, self._ctx, self.state) - self.enterRule(localctx, 72, self.RULE_blockWithVariables) + self.enterRule(localctx, 76, self.RULE_blockWithVariables) self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 486 + self.state = 498 localctx.blockType = self._input.LT(1) _la = self._input.LA(1) - if not((((_la) & ~0x3f) == 0 and ((1 << _la) & 30064771072) != 0)): + if not((((_la) & ~0x3f) == 0 and ((1 << _la) & 60129542144) != 0)): localctx.blockType = self._errHandler.recoverInline(self) else: self._errHandler.reportMatch(self) self.consume() - self.state = 487 + self.state = 499 self.match(PyNestMLParser.COLON) - self.state = 488 + self.state = 500 self.match(PyNestMLParser.NEWLINE) - self.state = 489 + self.state = 501 self.match(PyNestMLParser.INDENT) - self.state = 491 + self.state = 504 self._errHandler.sync(self) _la = self._input.LA(1) while True: - self.state = 490 - self.declaration_newline() - self.state = 493 + self.state = 504 + self._errHandler.sync(self) + token = self._input.LA(1) + if token in [29]: + self.state = 502 + self.includeStatement_newline() + pass + elif token in [16, 30, 89]: + self.state = 503 + self.declaration_newline() + pass + else: + raise NoViableAltException(self) + + self.state = 506 self._errHandler.sync(self) _la = self._input.LA(1) - if not (_la==16 or _la==29 or _la==88): + if not ((((_la) & ~0x3f) == 0 and ((1 << _la) & 1610678272) != 0) or _la==89): break - self.state = 495 + self.state = 508 self.match(PyNestMLParser.DEDENT) except RecognitionException as re: localctx.exception = re @@ -3690,14 +3827,14 @@ def accept(self, visitor:ParseTreeVisitor): def updateBlock(self): localctx = PyNestMLParser.UpdateBlockContext(self, self._ctx, self.state) - self.enterRule(localctx, 74, self.RULE_updateBlock) + self.enterRule(localctx, 78, self.RULE_updateBlock) try: self.enterOuterAlt(localctx, 1) - self.state = 497 + self.state = 510 self.match(PyNestMLParser.UPDATE_KEYWORD) - self.state = 498 + self.state = 511 self.match(PyNestMLParser.COLON) - self.state = 499 + self.state = 512 self.block() except RecognitionException as re: localctx.exception = re @@ -3766,47 +3903,47 @@ def accept(self, visitor:ParseTreeVisitor): def equationsBlock(self): localctx = PyNestMLParser.EquationsBlockContext(self, self._ctx, self.state) - self.enterRule(localctx, 76, self.RULE_equationsBlock) + self.enterRule(localctx, 80, self.RULE_equationsBlock) self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 501 + self.state = 514 self.match(PyNestMLParser.EQUATIONS_KEYWORD) - self.state = 502 + self.state = 515 self.match(PyNestMLParser.COLON) - self.state = 503 + self.state = 516 self.match(PyNestMLParser.NEWLINE) - self.state = 504 + self.state = 517 self.match(PyNestMLParser.INDENT) - self.state = 508 + self.state = 521 self._errHandler.sync(self) _la = self._input.LA(1) while True: - self.state = 508 + self.state = 521 self._errHandler.sync(self) token = self._input.LA(1) - if token in [16, 29]: - self.state = 505 + if token in [16, 30]: + self.state = 518 self.inlineExpression() pass - elif token in [88]: - self.state = 506 + elif token in [89]: + self.state = 519 self.odeEquation() pass - elif token in [30]: - self.state = 507 + elif token in [31]: + self.state = 520 self.kernel() pass else: raise NoViableAltException(self) - self.state = 510 + self.state = 523 self._errHandler.sync(self) _la = self._input.LA(1) - if not ((((_la) & ~0x3f) == 0 and ((1 << _la) & 1610678272) != 0) or _la==88): + if not ((((_la) & ~0x3f) == 0 and ((1 << _la) & 3221291008) != 0) or _la==89): break - self.state = 512 + self.state = 525 self.match(PyNestMLParser.DEDENT) except RecognitionException as re: localctx.exception = re @@ -3868,43 +4005,43 @@ def accept(self, visitor:ParseTreeVisitor): def inputBlock(self): localctx = PyNestMLParser.InputBlockContext(self, self._ctx, self.state) - self.enterRule(localctx, 78, self.RULE_inputBlock) + self.enterRule(localctx, 82, self.RULE_inputBlock) self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 514 + self.state = 527 self.match(PyNestMLParser.INPUT_KEYWORD) - self.state = 515 + self.state = 528 self.match(PyNestMLParser.COLON) - self.state = 516 + self.state = 529 self.match(PyNestMLParser.NEWLINE) - self.state = 517 + self.state = 530 self.match(PyNestMLParser.INDENT) - self.state = 520 + self.state = 533 self._errHandler.sync(self) _la = self._input.LA(1) while True: - self.state = 520 + self.state = 533 self._errHandler.sync(self) - la_ = self._interp.adaptivePredict(self._input,53,self._ctx) + la_ = self._interp.adaptivePredict(self._input,54,self._ctx) if la_ == 1: - self.state = 518 + self.state = 531 self.spikeInputPort() pass elif la_ == 2: - self.state = 519 + self.state = 532 self.continuousInputPort() pass - self.state = 522 + self.state = 535 self._errHandler.sync(self) _la = self._input.LA(1) - if not (_la==88): + if not (_la==89): break - self.state = 524 + self.state = 537 self.match(PyNestMLParser.DEDENT) except RecognitionException as re: localctx.exception = re @@ -3968,39 +4105,39 @@ def accept(self, visitor:ParseTreeVisitor): def spikeInputPort(self): localctx = PyNestMLParser.SpikeInputPortContext(self, self._ctx, self.state) - self.enterRule(localctx, 80, self.RULE_spikeInputPort) + self.enterRule(localctx, 84, self.RULE_spikeInputPort) self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 526 + self.state = 539 localctx.name = self.match(PyNestMLParser.NAME) - self.state = 531 + self.state = 544 self._errHandler.sync(self) _la = self._input.LA(1) - if _la==56: - self.state = 527 + if _la==57: + self.state = 540 self.match(PyNestMLParser.LEFT_SQUARE_BRACKET) - self.state = 528 + self.state = 541 localctx.sizeParameter = self.expression(0) - self.state = 529 + self.state = 542 self.match(PyNestMLParser.RIGHT_SQUARE_BRACKET) - self.state = 533 + self.state = 546 self.match(PyNestMLParser.LEFT_ANGLE_MINUS) - self.state = 537 + self.state = 550 self._errHandler.sync(self) _la = self._input.LA(1) - while _la==43 or _la==44: - self.state = 534 + while _la==44 or _la==45: + self.state = 547 self.inputQualifier() - self.state = 539 + self.state = 552 self._errHandler.sync(self) _la = self._input.LA(1) - self.state = 540 + self.state = 553 self.match(PyNestMLParser.SPIKE_KEYWORD) - self.state = 541 + self.state = 554 self.match(PyNestMLParser.NEWLINE) except RecognitionException as re: localctx.exception = re @@ -4061,31 +4198,31 @@ def accept(self, visitor:ParseTreeVisitor): def continuousInputPort(self): localctx = PyNestMLParser.ContinuousInputPortContext(self, self._ctx, self.state) - self.enterRule(localctx, 82, self.RULE_continuousInputPort) + self.enterRule(localctx, 86, self.RULE_continuousInputPort) self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 543 + self.state = 556 localctx.name = self.match(PyNestMLParser.NAME) - self.state = 548 + self.state = 561 self._errHandler.sync(self) _la = self._input.LA(1) - if _la==56: - self.state = 544 + if _la==57: + self.state = 557 self.match(PyNestMLParser.LEFT_SQUARE_BRACKET) - self.state = 545 + self.state = 558 localctx.sizeParameter = self.expression(0) - self.state = 546 + self.state = 559 self.match(PyNestMLParser.RIGHT_SQUARE_BRACKET) - self.state = 550 + self.state = 563 self.dataType() - self.state = 551 + self.state = 564 self.match(PyNestMLParser.LEFT_ANGLE_MINUS) - self.state = 552 + self.state = 565 self.match(PyNestMLParser.CONTINUOUS_KEYWORD) - self.state = 553 + self.state = 566 self.match(PyNestMLParser.NEWLINE) except RecognitionException as re: localctx.exception = re @@ -4126,18 +4263,18 @@ def accept(self, visitor:ParseTreeVisitor): def inputQualifier(self): localctx = PyNestMLParser.InputQualifierContext(self, self._ctx, self.state) - self.enterRule(localctx, 84, self.RULE_inputQualifier) + self.enterRule(localctx, 88, self.RULE_inputQualifier) try: self.enterOuterAlt(localctx, 1) - self.state = 557 + self.state = 570 self._errHandler.sync(self) token = self._input.LA(1) - if token in [43]: - self.state = 555 + if token in [44]: + self.state = 568 localctx.isInhibitory = self.match(PyNestMLParser.INHIBITORY_KEYWORD) pass - elif token in [44]: - self.state = 556 + elif token in [45]: + self.state = 569 localctx.isExcitatory = self.match(PyNestMLParser.EXCITATORY_KEYWORD) pass else: @@ -4200,34 +4337,34 @@ def accept(self, visitor:ParseTreeVisitor): def outputBlock(self): localctx = PyNestMLParser.OutputBlockContext(self, self._ctx, self.state) - self.enterRule(localctx, 86, self.RULE_outputBlock) + self.enterRule(localctx, 90, self.RULE_outputBlock) try: self.enterOuterAlt(localctx, 1) - self.state = 559 + self.state = 572 self.match(PyNestMLParser.OUTPUT_KEYWORD) - self.state = 560 + self.state = 573 self.match(PyNestMLParser.COLON) - self.state = 561 + self.state = 574 self.match(PyNestMLParser.NEWLINE) - self.state = 562 + self.state = 575 self.match(PyNestMLParser.INDENT) - self.state = 565 + self.state = 578 self._errHandler.sync(self) token = self._input.LA(1) - if token in [42]: - self.state = 563 + if token in [43]: + self.state = 576 localctx.isSpike = self.match(PyNestMLParser.SPIKE_KEYWORD) pass - elif token in [39]: - self.state = 564 + elif token in [40]: + self.state = 577 localctx.isContinuous = self.match(PyNestMLParser.CONTINUOUS_KEYWORD) pass else: raise NoViableAltException(self) - self.state = 567 + self.state = 580 self.match(PyNestMLParser.NEWLINE) - self.state = 568 + self.state = 581 self.match(PyNestMLParser.DEDENT) except RecognitionException as re: localctx.exception = re @@ -4297,49 +4434,49 @@ def accept(self, visitor:ParseTreeVisitor): def function(self): localctx = PyNestMLParser.FunctionContext(self, self._ctx, self.state) - self.enterRule(localctx, 88, self.RULE_function) + self.enterRule(localctx, 92, self.RULE_function) self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 570 + self.state = 583 self.match(PyNestMLParser.FUNCTION_KEYWORD) - self.state = 571 + self.state = 584 self.match(PyNestMLParser.NAME) - self.state = 572 + self.state = 585 self.match(PyNestMLParser.LEFT_PAREN) - self.state = 581 + self.state = 594 self._errHandler.sync(self) _la = self._input.LA(1) - if _la==88: - self.state = 573 + if _la==89: + self.state = 586 self.parameter() - self.state = 578 + self.state = 591 self._errHandler.sync(self) _la = self._input.LA(1) - while _la==74: - self.state = 574 + while _la==75: + self.state = 587 self.match(PyNestMLParser.COMMA) - self.state = 575 + self.state = 588 self.parameter() - self.state = 580 + self.state = 593 self._errHandler.sync(self) _la = self._input.LA(1) - self.state = 583 + self.state = 596 self.match(PyNestMLParser.RIGHT_PAREN) - self.state = 585 + self.state = 598 self._errHandler.sync(self) _la = self._input.LA(1) - if (((_la) & ~0x3f) == 0 and ((1 << _la) & 562949953453056) != 0) or _la==88 or _la==89: - self.state = 584 + if (((_la) & ~0x3f) == 0 and ((1 << _la) & 1125899906874368) != 0) or _la==89 or _la==90: + self.state = 597 localctx.returnType = self.dataType() - self.state = 587 + self.state = 600 self.match(PyNestMLParser.COLON) - self.state = 588 + self.state = 601 self.block() except RecognitionException as re: localctx.exception = re @@ -4379,12 +4516,12 @@ def accept(self, visitor:ParseTreeVisitor): def parameter(self): localctx = PyNestMLParser.ParameterContext(self, self._ctx, self.state) - self.enterRule(localctx, 90, self.RULE_parameter) + self.enterRule(localctx, 94, self.RULE_parameter) try: self.enterOuterAlt(localctx, 1) - self.state = 590 + self.state = 603 self.match(PyNestMLParser.NAME) - self.state = 591 + self.state = 604 self.dataType() except RecognitionException as re: localctx.exception = re @@ -4440,18 +4577,18 @@ def accept(self, visitor:ParseTreeVisitor): def constParameter(self): localctx = PyNestMLParser.ConstParameterContext(self, self._ctx, self.state) - self.enterRule(localctx, 92, self.RULE_constParameter) + self.enterRule(localctx, 96, self.RULE_constParameter) self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 593 + self.state = 606 localctx.name = self.match(PyNestMLParser.NAME) - self.state = 594 + self.state = 607 self.match(PyNestMLParser.EQUALS) - self.state = 595 + self.state = 608 localctx.value = self._input.LT(1) _la = self._input.LA(1) - if not(_la==25 or ((((_la - 86)) & ~0x3f) == 0 and ((1 << (_la - 86)) & 27) != 0)): + if not(_la==25 or ((((_la - 87)) & ~0x3f) == 0 and ((1 << (_la - 87)) & 27) != 0)): localctx.value = self._errHandler.recoverInline(self) else: self._errHandler.reportMatch(self) diff --git a/pynestml/generated/PyNestMLParserVisitor.py b/pynestml/generated/PyNestMLParserVisitor.py index 4f9cbf508..76b555f17 100644 --- a/pynestml/generated/PyNestMLParserVisitor.py +++ b/pynestml/generated/PyNestMLParserVisitor.py @@ -1,4 +1,4 @@ -# Generated from PyNestMLParser.g4 by ANTLR 4.13.1 +# Generated from PyNestMLParser.g4 by ANTLR 4.13.0 from antlr4 import * if "." in __name__: from .PyNestMLParser import PyNestMLParser @@ -104,6 +104,16 @@ def visitAssignment(self, ctx:PyNestMLParser.AssignmentContext): return self.visitChildren(ctx) + # Visit a parse tree produced by PyNestMLParser#includeStatement. + def visitIncludeStatement(self, ctx:PyNestMLParser.IncludeStatementContext): + return self.visitChildren(ctx) + + + # Visit a parse tree produced by PyNestMLParser#includeStatement_newline. + def visitIncludeStatement_newline(self, ctx:PyNestMLParser.IncludeStatement_newlineContext): + return self.visitChildren(ctx) + + # Visit a parse tree produced by PyNestMLParser#declaration. def visitDeclaration(self, ctx:PyNestMLParser.DeclarationContext): return self.visitChildren(ctx) diff --git a/pynestml/grammars/PyNestMLLexer.g4 b/pynestml/grammars/PyNestMLLexer.g4 index c7255e807..eaac04fc6 100644 --- a/pynestml/grammars/PyNestMLLexer.g4 +++ b/pynestml/grammars/PyNestMLLexer.g4 @@ -78,6 +78,7 @@ lexer grammar PyNestMLLexer; AND_KEYWORD : 'and'; OR_KEYWORD : 'or'; NOT_KEYWORD : 'not'; + INCLUDE_KEYWORD : 'include'; RECORDABLE_KEYWORD : 'recordable'; KERNEL_KEYWORD : 'kernel'; diff --git a/pynestml/grammars/PyNestMLParser.g4 b/pynestml/grammars/PyNestMLParser.g4 index 5d2af2d50..5ffd6e0b7 100644 --- a/pynestml/grammars/PyNestMLParser.g4 +++ b/pynestml/grammars/PyNestMLParser.g4 @@ -142,7 +142,8 @@ parser grammar PyNestMLParser; smallStmt : (assignment | functionCall | declaration - | returnStmt) NEWLINE; + | returnStmt + | includeStatement) NEWLINE; assignment : lhs_variable=variable (directAssignment=EQUALS | @@ -152,6 +153,9 @@ parser grammar PyNestMLParser; compoundQuotient=FORWARD_SLASH_EQUALS) expression; + includeStatement : INCLUDE_KEYWORD STRING_LITERAL; + includeStatement_newline : includeStatement NEWLINE; + /** ASTDeclaration A variable declaration. It can be a simple declaration defining one or multiple variables: 'a,b,c real = 0'. Or an function declaration 'function a = b + c'. @attribute isRecordable: Is true iff. declaration is recordable. @@ -233,7 +237,7 @@ parser grammar PyNestMLParser; @attribute function: A block declaring a user-defined function. */ modelBody: COLON - NEWLINE INDENT ( blockWithVariables | equationsBlock | inputBlock | outputBlock | function | onReceiveBlock | onConditionBlock | updateBlock )+ DEDENT; + NEWLINE INDENT ( includeStatement_newline | blockWithVariables | equationsBlock | inputBlock | outputBlock | function | onReceiveBlock | onConditionBlock | updateBlock )+ DEDENT; /** ASTOnReceiveBlock @attribute block implementation of the dynamics @@ -259,7 +263,7 @@ parser grammar PyNestMLParser; blockWithVariables: blockType=(STATE_KEYWORD | PARAMETERS_KEYWORD | INTERNALS_KEYWORD) COLON - NEWLINE INDENT declaration_newline+ DEDENT; + NEWLINE INDENT (includeStatement_newline | declaration_newline)+ DEDENT; /** ASTUpdateBlock The definition of a block where the dynamical behavior of the neuron is stated: update: diff --git a/tests/include_statement_test.py b/tests/include_statement_test.py new file mode 100644 index 000000000..235063492 --- /dev/null +++ b/tests/include_statement_test.py @@ -0,0 +1,47 @@ +# -*- coding: utf-8 -*- +# +# include_statement_test.py +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . +import os + +from antlr4.CommonTokenStream import CommonTokenStream +from antlr4.FileStream import FileStream +from antlr4.error.ErrorStrategy import BailErrorStrategy + +from pynestml.generated.PyNestMLLexer import PyNestMLLexer +from pynestml.generated.PyNestMLParser import PyNestMLParser + + +class TestIncludeStatement: + def test_include_statement(self): + input = os.path.realpath(os.path.join(os.path.dirname("__file__"), "resources", "IncludeStatementTest.nestml")) + + input_file = FileStream(input) + lexer = PyNestMLLexer(input_file) + lexer._errHandler = BailErrorStrategy() + lexer._errHandler.reset(lexer) + # create a token stream + stream = CommonTokenStream(lexer) + stream.fill() + # parse the file + parser = PyNestMLParser(stream) + parser._errHandler = BailErrorStrategy() + parser._errHandler.reset(parser) + compilation_unit = parser.nestMLCompilationUnit() + assert compilation_unit is not None diff --git a/tests/resources/IncludeStatementTest.nestml b/tests/resources/IncludeStatementTest.nestml new file mode 100644 index 000000000..193b5e000 --- /dev/null +++ b/tests/resources/IncludeStatementTest.nestml @@ -0,0 +1,47 @@ +""" +IncludeStatementTest.nestml +########################### + + +Description ++++++++++++ + +Test whether the include statement works as intended. + +Copyright statement ++++++++++++++++++++ + +This file is part of NEST. + +Copyright (C) 2004 The NEST Initiative + +NEST is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +NEST is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with NEST. If not, see . +""" + +model include_statement: + + include "model_a.nestml" + + state: + v mV = 42 mV + include "model_a.nestml" + + parameters: + include "model_a.nestml" + + internals: + include "model_a.nestml" + + update: + include "model_a.nestml" diff --git a/tests/resources/ModelA.nestml b/tests/resources/ModelA.nestml new file mode 100644 index 000000000..f9879d86f --- /dev/null +++ b/tests/resources/ModelA.nestml @@ -0,0 +1,35 @@ +""" +ModelA.nestml +############# + + +Description ++++++++++++ + +A simple model that can be included in other models + +Copyright statement ++++++++++++++++++++ + +This file is part of NEST. + +Copyright (C) 2004 The NEST Initiative + +NEST is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +NEST is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with NEST. If not, see . +""" + +model model_a: + parameters: + foo real = 1.5 + bar ms = 5 ms From 2563e634b759b7779752aa44f35db0ef62e330ad Mon Sep 17 00:00:00 2001 From: "C.A.P. Linssen" Date: Sun, 29 Sep 2024 09:40:45 +0200 Subject: [PATCH 02/25] run context condition checks only once, after model parsing --- .../stdp_third_factor_active_dendrite.ipynb | 2 +- pynestml/cocos/co_co_all_variables_defined.py | 38 +- pynestml/cocos/co_co_function_unique.py | 1 + pynestml/cocos/co_co_illegal_expression.py | 6 +- .../co_co_no_kernels_except_in_convolve.py | 49 +- pynestml/cocos/co_co_v_comp_exists.py | 3 - pynestml/cocos/co_cos_manager.py | 13 +- pynestml/codegeneration/builder.py | 4 +- .../codegeneration/nest_code_generator.py | 7 +- .../nest_compartmental_code_generator.py | 11 +- .../python_standalone_code_generator.py | 1 - .../spinnaker_code_generator.py | 3 +- pynestml/frontend/frontend_configuration.py | 4 +- pynestml/frontend/pynestml_frontend.py | 108 +-- pynestml/meta_model/ast_model.py | 37 +- pynestml/symbols/symbol.py | 2 +- pynestml/symbols/type_symbol.py | 5 +- pynestml/symbols/unit_type_symbol.py | 25 +- ...implicit_conversion_factors_transformer.py | 335 +++++++++ .../synapse_post_neuron_transformer.py | 7 +- pynestml/utils/ast_utils.py | 17 +- pynestml/utils/logger.py | 75 +- pynestml/utils/mechs_info_enricher.py | 64 +- pynestml/utils/messages.py | 28 +- pynestml/utils/model_parser.py | 6 + pynestml/utils/type_caster.py | 31 +- pynestml/visitors/ast_builder_visitor.py | 14 +- .../visitors/ast_function_call_visitor.py | 1 - pynestml/visitors/ast_symbol_table_visitor.py | 13 +- tests/cocos_test.py | 698 ------------------ tests/function_parameter_templating_test.py | 57 -- tests/nest_compartmental_tests/test__cocos.py | 92 ++- .../nest_delay_based_variables_test.py | 28 +- .../integrate_odes_test_params.nestml | 1 - .../integrate_odes_test_params2.nestml | 10 + tests/nest_tests/test_integrate_odes.py | 30 +- tests/test_cocos.py | 403 ++++++++++ tests/test_function_parameter_templating.py | 36 + tests/test_unit_system.py | 164 ++++ tests/unit_system_test.py | 177 ----- 40 files changed, 1338 insertions(+), 1268 deletions(-) create mode 100644 pynestml/transformers/assign_implicit_conversion_factors_transformer.py delete mode 100644 tests/cocos_test.py delete mode 100644 tests/function_parameter_templating_test.py create mode 100644 tests/nest_tests/resources/integrate_odes_test_params2.nestml create mode 100644 tests/test_cocos.py create mode 100644 tests/test_function_parameter_templating.py create mode 100644 tests/test_unit_system.py delete mode 100644 tests/unit_system_test.py diff --git a/doc/tutorials/stdp_third_factor_active_dendrite/stdp_third_factor_active_dendrite.ipynb b/doc/tutorials/stdp_third_factor_active_dendrite/stdp_third_factor_active_dendrite.ipynb index 147f5b4a1..3922d0ac8 100644 --- a/doc/tutorials/stdp_third_factor_active_dendrite/stdp_third_factor_active_dendrite.ipynb +++ b/doc/tutorials/stdp_third_factor_active_dendrite/stdp_third_factor_active_dendrite.ipynb @@ -1347,7 +1347,7 @@ " NESTCodeGeneratorUtils.generate_code_for(nestml_neuron_model,\n", " nestml_synapse_model,\n", " codegen_opts=codegen_opts,\n", - " logging_level=\"INFO\") # try \"INFO\" or \"DEBUG\" for more debug information" + " logging_level=\"WARNING\") # try \"INFO\" or \"DEBUG\" for more debug information" ] }, { diff --git a/pynestml/cocos/co_co_all_variables_defined.py b/pynestml/cocos/co_co_all_variables_defined.py index e41b0727e..38cfa89ab 100644 --- a/pynestml/cocos/co_co_all_variables_defined.py +++ b/pynestml/cocos/co_co_all_variables_defined.py @@ -41,11 +41,10 @@ class CoCoAllVariablesDefined(CoCo): """ @classmethod - def check_co_co(cls, node: ASTModel, after_ast_rewrite: bool = False): + def check_co_co(cls, node: ASTModel): """ Checks if this coco applies for the handed over neuron. Models which contain undefined variables are not correct. :param node: a single neuron instance. - :param after_ast_rewrite: indicates whether this coco is checked after the code generator has done rewriting of the abstract syntax tree. If True, checks are not as rigorous. Use False where possible. """ # for each variable in all expressions, check if the variable has been defined previously expression_collector_visitor = ASTExpressionCollectorVisitor() @@ -62,32 +61,6 @@ def check_co_co(cls, node: ASTModel, after_ast_rewrite: bool = False): # test if the symbol has been defined at least if symbol is None: - if after_ast_rewrite: # after ODE-toolbox transformations, convolutions are replaced by state variables, so cannot perform this check properly - symbol2 = node.get_scope().resolve_to_symbol(var.get_name(), SymbolKind.VARIABLE) - if symbol2 is not None: - # an inline expression defining this variable name (ignoring differential order) exists - if "__X__" in str(symbol2): # if this variable was the result of a convolution... - continue - else: - # for kernels, also allow derivatives of that kernel to appear - - inline_expr_names = [] - inline_exprs = [] - for equations_block in node.get_equations_blocks(): - inline_expr_names.extend([inline_expr.variable_name for inline_expr in equations_block.get_inline_expressions()]) - inline_exprs.extend(equations_block.get_inline_expressions()) - - if var.get_name() in inline_expr_names: - inline_expr_idx = inline_expr_names.index(var.get_name()) - inline_expr = inline_exprs[inline_expr_idx] - from pynestml.utils.ast_utils import ASTUtils - if ASTUtils.inline_aliases_convolution(inline_expr): - symbol2 = node.get_scope().resolve_to_symbol(var.get_name(), SymbolKind.VARIABLE) - if symbol2 is not None: - # actually, no problem detected, skip error - # XXX: TODO: check that differential order is less than or equal to that of the kernel - continue - # check if this symbol is actually a type, e.g. "mV" in the expression "(1 + 2) * mV" symbol2 = var.get_scope().resolve_to_symbol(var.get_complete_name(), SymbolKind.TYPE) if symbol2 is not None: @@ -106,9 +79,14 @@ def check_co_co(cls, node: ASTModel, after_ast_rewrite: bool = False): # in this case its ok if it is recursive or defined later on continue + if symbol.is_predefined: + continue + + if symbol.block_type == BlockType.LOCAL and symbol.get_referenced_object().get_source_position().before(var.get_source_position()): + continue + # check if it has been defined before usage, except for predefined symbols, input ports and variables added by the AST transformation functions - if (not symbol.is_predefined) \ - and symbol.block_type != BlockType.INPUT \ + if symbol.block_type != BlockType.INPUT \ and not symbol.get_referenced_object().get_source_position().is_added_source_position(): # except for parameters, those can be defined after if ((not symbol.get_referenced_object().get_source_position().before(var.get_source_position())) diff --git a/pynestml/cocos/co_co_function_unique.py b/pynestml/cocos/co_co_function_unique.py index 15643c0ad..bf0f2be60 100644 --- a/pynestml/cocos/co_co_function_unique.py +++ b/pynestml/cocos/co_co_function_unique.py @@ -65,4 +65,5 @@ def check_co_co(cls, model: ASTModel): log_level=LoggingLevel.ERROR, message=message, code=code) checked.append(funcA) + checked_funcs_names.append(func.get_name()) diff --git a/pynestml/cocos/co_co_illegal_expression.py b/pynestml/cocos/co_co_illegal_expression.py index b78396e3b..c362d0dc5 100644 --- a/pynestml/cocos/co_co_illegal_expression.py +++ b/pynestml/cocos/co_co_illegal_expression.py @@ -18,13 +18,13 @@ # # You should have received a copy of the GNU General Public License # along with NEST. If not, see . -from pynestml.meta_model.ast_inline_expression import ASTInlineExpression -from pynestml.utils.ast_source_location import ASTSourceLocation -from pynestml.meta_model.ast_declaration import ASTDeclaration from pynestml.cocos.co_co import CoCo +from pynestml.meta_model.ast_declaration import ASTDeclaration +from pynestml.meta_model.ast_inline_expression import ASTInlineExpression from pynestml.symbols.error_type_symbol import ErrorTypeSymbol from pynestml.symbols.predefined_types import PredefinedTypes +from pynestml.utils.ast_source_location import ASTSourceLocation from pynestml.utils.logger import LoggingLevel, Logger from pynestml.utils.logging_helper import LoggingHelper from pynestml.utils.messages import Messages diff --git a/pynestml/cocos/co_co_no_kernels_except_in_convolve.py b/pynestml/cocos/co_co_no_kernels_except_in_convolve.py index 18b862292..e318ae566 100644 --- a/pynestml/cocos/co_co_no_kernels_except_in_convolve.py +++ b/pynestml/cocos/co_co_no_kernels_except_in_convolve.py @@ -22,11 +22,14 @@ from typing import List from pynestml.cocos.co_co import CoCo +from pynestml.meta_model.ast_declaration import ASTDeclaration +from pynestml.meta_model.ast_external_variable import ASTExternalVariable from pynestml.meta_model.ast_function_call import ASTFunctionCall from pynestml.meta_model.ast_kernel import ASTKernel from pynestml.meta_model.ast_model import ASTModel from pynestml.meta_model.ast_node import ASTNode from pynestml.meta_model.ast_variable import ASTVariable +from pynestml.symbols.predefined_functions import PredefinedFunctions from pynestml.symbols.symbol import SymbolKind from pynestml.utils.logger import Logger, LoggingLevel from pynestml.utils.messages import Messages @@ -89,24 +92,44 @@ def visit_variable(self, node: ASTNode): if not (isinstance(node, ASTExternalVariable) and node.get_alternate_name()): code, message = Messages.get_no_variable_found(kernelName) Logger.log_message(node=self.__neuron_node, code=code, message=message, log_level=LoggingLevel.ERROR) + continue + if not symbol.is_kernel(): continue + if node.get_complete_name() == kernelName: - parent = node.get_parent() - if parent is not None: + parent = node + correct = False + while parent is not None and not isinstance(parent, ASTModel): + parent = parent.get_parent() + assert parent is not None + + if isinstance(parent, ASTDeclaration): + for lhs_var in parent.get_variables(): + if kernelName == lhs_var.get_complete_name(): + # kernel name appears on lhs of declaration, assume it is initial state + correct = True + parent = None # break out of outer loop + break + if isinstance(parent, ASTKernel): - continue - grandparent = parent.get_parent() - if grandparent is not None and isinstance(grandparent, ASTFunctionCall): - grandparent_func_name = grandparent.get_name() - if grandparent_func_name == 'convolve': - continue - code, message = Messages.get_kernel_outside_convolve(kernelName) - Logger.log_message(code=code, - message=message, - log_level=LoggingLevel.ERROR, - error_position=node.get_source_position()) + # kernel name is used inside kernel definition, e.g. for a node ``g``, it appears in ``kernel g'' = -1/tau**2 * g - 2/tau * g'`` + correct = True + break + + if isinstance(parent, ASTFunctionCall): + func_name = parent.get_name() + if func_name == PredefinedFunctions.CONVOLVE: + # kernel name is used inside convolve call + correct = True + + if not correct: + code, message = Messages.get_kernel_outside_convolve(kernelName) + Logger.log_message(code=code, + message=message, + log_level=LoggingLevel.ERROR, + error_position=node.get_source_position()) class KernelCollectingVisitor(ASTVisitor): diff --git a/pynestml/cocos/co_co_v_comp_exists.py b/pynestml/cocos/co_co_v_comp_exists.py index 4ef08c0ec..51308f2cc 100644 --- a/pynestml/cocos/co_co_v_comp_exists.py +++ b/pynestml/cocos/co_co_v_comp_exists.py @@ -43,9 +43,6 @@ def check_co_co(cls, neuron: ASTModel): Models which are supposed to be compartmental but do not contain state variable called v_comp are not correct. :param neuron: a single neuron instance. - :param after_ast_rewrite: indicates whether this coco is checked - after the code generator has done rewriting of the abstract syntax tree. - If True, checks are not as rigorous. Use False where possible. """ from pynestml.codegeneration.nest_compartmental_code_generator import NESTCompartmentalCodeGenerator diff --git a/pynestml/cocos/co_cos_manager.py b/pynestml/cocos/co_cos_manager.py index 01d008890..9ad3b37bf 100644 --- a/pynestml/cocos/co_cos_manager.py +++ b/pynestml/cocos/co_cos_manager.py @@ -69,6 +69,7 @@ from pynestml.cocos.co_co_priorities_correctly_specified import CoCoPrioritiesCorrectlySpecified from pynestml.meta_model.ast_model import ASTModel from pynestml.frontend.frontend_configuration import FrontendConfiguration +from pynestml.utils.logger import Logger class CoCosManager: @@ -123,12 +124,12 @@ def check_state_variables_initialized(cls, model: ASTModel): CoCoStateVariablesInitialized.check_co_co(model) @classmethod - def check_variables_defined_before_usage(cls, model: ASTModel, after_ast_rewrite: bool) -> None: + def check_variables_defined_before_usage(cls, model: ASTModel) -> None: """ Checks that all variables are defined before being used. :param model: a single model. """ - CoCoAllVariablesDefined.check_co_co(model, after_ast_rewrite) + CoCoAllVariablesDefined.check_co_co(model) @classmethod def check_v_comp_requirement(cls, neuron: ASTModel): @@ -402,17 +403,19 @@ def check_input_port_size_type(cls, model: ASTModel): CoCoVectorInputPortsCorrectSizeType.check_co_co(model) @classmethod - def post_symbol_table_builder_checks(cls, model: ASTModel, after_ast_rewrite: bool = False): + def check_cocos(cls, model: ASTModel, after_ast_rewrite: bool = False): """ Checks all context conditions. :param model: a single model object. """ + Logger.set_current_node(model) + cls.check_each_block_defined_at_most_once(model) cls.check_function_defined(model) cls.check_variables_unique_in_scope(model) cls.check_inline_expression_not_assigned_to(model) cls.check_state_variables_initialized(model) - cls.check_variables_defined_before_usage(model, after_ast_rewrite) + cls.check_variables_defined_before_usage(model) if FrontendConfiguration.get_target_platform().upper() == 'NEST_COMPARTMENTAL': # XXX: TODO: refactor this out; define a ``cocos_from_target_name()`` in the frontend instead. cls.check_v_comp_requirement(model) @@ -452,3 +455,5 @@ def post_symbol_table_builder_checks(cls, model: ASTModel, after_ast_rewrite: bo cls.check_co_co_priorities_correctly_specified(model) cls.check_resolution_func_legally_used(model) cls.check_input_port_size_type(model) + + Logger.set_current_node(None) diff --git a/pynestml/codegeneration/builder.py b/pynestml/codegeneration/builder.py index 2e6757c1a..a9f98bf58 100644 --- a/pynestml/codegeneration/builder.py +++ b/pynestml/codegeneration/builder.py @@ -20,12 +20,12 @@ # along with NEST. If not, see . from __future__ import annotations -import subprocess -import os from typing import Any, Mapping, Optional from abc import ABCMeta, abstractmethod +import os +import subprocess from pynestml.exceptions.invalid_target_exception import InvalidTargetException from pynestml.frontend.frontend_configuration import FrontendConfiguration diff --git a/pynestml/codegeneration/nest_code_generator.py b/pynestml/codegeneration/nest_code_generator.py index 0551e9a6e..155bea95c 100644 --- a/pynestml/codegeneration/nest_code_generator.py +++ b/pynestml/codegeneration/nest_code_generator.py @@ -28,6 +28,7 @@ import pynestml from pynestml.cocos.co_co_nest_synapse_delay_not_assigned_to import CoCoNESTSynapseDelayNotAssignedTo +from pynestml.cocos.co_cos_manager import CoCosManager from pynestml.codegeneration.code_generator import CodeGenerator from pynestml.codegeneration.code_generator_utils import CodeGeneratorUtils from pynestml.codegeneration.nest_assignments_helper import NestAssignmentsHelper @@ -374,6 +375,9 @@ def analyse_neuron(self, neuron: ASTModel) -> Tuple[Dict[str, ASTAssignment], Di if not used_in_eq: self.non_equations_state_variables[neuron.get_name()].append(var) + # cache state variables before symbol table update for the sake of delay variables + state_vars_before_update = neuron.get_state_symbols() + ASTUtils.remove_initial_values_for_kernels(neuron) kernels = ASTUtils.remove_kernel_definitions_from_equations_block(neuron) ASTUtils.update_initial_values_for_odes(neuron, [analytic_solver, numeric_solver]) @@ -388,7 +392,6 @@ def analyse_neuron(self, neuron: ASTModel) -> Tuple[Dict[str, ASTAssignment], Di neuron = ASTUtils.add_declarations_to_internals( neuron, self.analytic_solver[neuron.get_name()]["propagators"]) - state_vars_before_update = neuron.get_state_symbols() self.update_symbol_table(neuron) # Update the delay parameter parameters after symbol table update @@ -898,8 +901,8 @@ def update_symbol_table(self, neuron) -> None: """ SymbolTable.delete_model_scope(neuron.get_name()) symbol_table_visitor = ASTSymbolTableVisitor() - symbol_table_visitor.after_ast_rewrite_ = True neuron.accept(symbol_table_visitor) + CoCosManager.check_cocos(neuron, after_ast_rewrite=True) SymbolTable.add_model_scope(neuron.get_name(), neuron.get_scope()) def get_spike_update_expressions(self, neuron: ASTModel, kernel_buffers, solver_dicts, delta_factors) -> Tuple[Dict[str, ASTAssignment], Dict[str, ASTAssignment]]: diff --git a/pynestml/codegeneration/nest_compartmental_code_generator.py b/pynestml/codegeneration/nest_compartmental_code_generator.py index 4711bc497..00f061775 100644 --- a/pynestml/codegeneration/nest_compartmental_code_generator.py +++ b/pynestml/codegeneration/nest_compartmental_code_generator.py @@ -18,14 +18,18 @@ # # You should have received a copy of the GNU General Public License # along with NEST. If not, see . -import shutil + from typing import Any, Dict, List, Mapping, Optional import datetime import os from jinja2 import TemplateRuntimeError + +from odetoolbox import analysis + import pynestml +from pynestml.cocos.co_cos_manager import CoCosManager from pynestml.codegeneration.code_generator import CodeGenerator from pynestml.codegeneration.nest_assignments_helper import NestAssignmentsHelper from pynestml.codegeneration.nest_declarations_helper import NestDeclarationsHelper @@ -53,9 +57,9 @@ from pynestml.meta_model.ast_variable import ASTVariable from pynestml.symbol_table.symbol_table import SymbolTable from pynestml.symbols.symbol import SymbolKind +from pynestml.transformers.inline_expression_expansion_transformer import InlineExpressionExpansionTransformer from pynestml.utils.ast_vector_parameter_setter_and_printer import ASTVectorParameterSetterAndPrinter from pynestml.utils.ast_vector_parameter_setter_and_printer_factory import ASTVectorParameterSetterAndPrinterFactory -from pynestml.transformers.inline_expression_expansion_transformer import InlineExpressionExpansionTransformer from pynestml.utils.mechanism_processing import MechanismProcessing from pynestml.utils.channel_processing import ChannelProcessing from pynestml.utils.concentration_processing import ConcentrationProcessing @@ -72,7 +76,6 @@ from pynestml.utils.synapse_processing import SynapseProcessing from pynestml.visitors.ast_random_number_generator_visitor import ASTRandomNumberGeneratorVisitor from pynestml.visitors.ast_symbol_table_visitor import ASTSymbolTableVisitor -from odetoolbox import analysis class NESTCompartmentalCodeGenerator(CodeGenerator): @@ -740,8 +743,8 @@ def update_symbol_table(self, neuron, kernel_buffers): """ SymbolTable.delete_model_scope(neuron.get_name()) symbol_table_visitor = ASTSymbolTableVisitor() - symbol_table_visitor.after_ast_rewrite_ = True neuron.accept(symbol_table_visitor) + CoCosManager.check_cocos(neuron, after_ast_rewrite=True) SymbolTable.add_model_scope(neuron.get_name(), neuron.get_scope()) def _get_ast_variable(self, neuron, var_name) -> Optional[ASTVariable]: diff --git a/pynestml/codegeneration/python_standalone_code_generator.py b/pynestml/codegeneration/python_standalone_code_generator.py index f44123743..d6afaa095 100644 --- a/pynestml/codegeneration/python_standalone_code_generator.py +++ b/pynestml/codegeneration/python_standalone_code_generator.py @@ -111,7 +111,6 @@ def setup_printers(self): # GSL printers self._gsl_variable_printer = PythonSteppingFunctionVariablePrinter(None) - print("In Python code generator: created self._gsl_variable_printer = " + str(self._gsl_variable_printer)) self._gsl_function_call_printer = PythonSteppingFunctionFunctionCallPrinter(None) self._gsl_printer = PythonExpressionPrinter(simple_expression_printer=PythonSimpleExpressionPrinter(variable_printer=self._gsl_variable_printer, constant_printer=self._constant_printer, diff --git a/pynestml/codegeneration/spinnaker_code_generator.py b/pynestml/codegeneration/spinnaker_code_generator.py index 2a8fed7de..dce247e9c 100644 --- a/pynestml/codegeneration/spinnaker_code_generator.py +++ b/pynestml/codegeneration/spinnaker_code_generator.py @@ -137,7 +137,6 @@ def setup_printers(self): # GSL printers self._gsl_variable_printer = PythonSteppingFunctionVariablePrinter(None) - print("In Python code generator: created self._gsl_variable_printer = " + str(self._gsl_variable_printer)) self._gsl_function_call_printer = PythonSteppingFunctionFunctionCallPrinter(None) self._gsl_printer = PythonExpressionPrinter(simple_expression_printer=SpinnakerPythonSimpleExpressionPrinter( variable_printer=self._gsl_variable_printer, @@ -216,6 +215,7 @@ def generate_code(self, models: Sequence[ASTModel]) -> None: for model in models: cloned_model = model.clone() cloned_model.accept(ASTSymbolTableVisitor()) + CoCosManager.check_cocos(cloned_model) cloned_models.append(cloned_model) self.codegen_cpp.generate_code(cloned_models) @@ -224,6 +224,7 @@ def generate_code(self, models: Sequence[ASTModel]) -> None: for model in models: cloned_model = model.clone() cloned_model.accept(ASTSymbolTableVisitor()) + CoCosManager.check_cocos(cloned_model) cloned_models.append(cloned_model) self.codegen_py.generate_code(cloned_models) diff --git a/pynestml/frontend/frontend_configuration.py b/pynestml/frontend/frontend_configuration.py index 173534c95..aae1fc29a 100644 --- a/pynestml/frontend/frontend_configuration.py +++ b/pynestml/frontend/frontend_configuration.py @@ -244,8 +244,8 @@ def handle_module_name(cls, module_name): @classmethod def handle_target_platform(cls, target_platform: Optional[str]): - if target_platform is None or target_platform.upper() == 'NONE': - target_platform = '' # make sure `target_platform` is always a string + if target_platform is None: + target_platform = "NONE" # make sure `target_platform` is always a string from pynestml.frontend.pynestml_frontend import get_known_targets diff --git a/pynestml/frontend/pynestml_frontend.py b/pynestml/frontend/pynestml_frontend.py index c257822de..c3dc2d2ae 100644 --- a/pynestml/frontend/pynestml_frontend.py +++ b/pynestml/frontend/pynestml_frontend.py @@ -41,6 +41,8 @@ from pynestml.utils.logger import Logger, LoggingLevel from pynestml.utils.messages import Messages from pynestml.utils.model_parser import ModelParser +from pynestml.visitors.ast_parent_visitor import ASTParentVisitor +from pynestml.visitors.ast_symbol_table_visitor import ASTSymbolTableVisitor def get_known_targets(): @@ -131,10 +133,10 @@ def code_generator_from_target_name(target_name: str, options: Optional[Mapping[ return SpiNNakerCodeGenerator(options) if target_name.upper() == "NONE": - # dummy/null target: user requested to not generate any code + # dummy/null target: user requested to not generate any code (for instance, when just doing validation of a model) code, message = Messages.get_no_code_generated() Logger.log_message(None, code, message, None, LoggingLevel.INFO) - return CodeGenerator("", options) + return CodeGenerator(options) # cannot reach here due to earlier assert -- silence static checker warnings assert "Unknown code generator requested: " + target_name @@ -193,12 +195,17 @@ def generate_target(input_path: Union[str, Sequence[str]], target_platform: str, Enable development mode: code generation is attempted even for models that contain errors, and extra information is rendered in the generated code. codegen_opts : Optional[Mapping[str, Any]] A dictionary containing additional options for the target code generator. + + Return + ------ + errors_occurred + Flag indicating whether errors occurred during processing. False if processing was successful; True if errors occurred in any of the models. """ configure_front_end(input_path, target_platform, target_path, install_path, logging_level, module_name, store_log, suffix, dev, codegen_opts) - if not process() == 0: - raise Exception("Error(s) occurred while processing the model") + + return process() def configure_front_end(input_path: Union[str, Sequence[str]], target_platform: str, target_path=None, @@ -373,34 +380,36 @@ def generate_nest_compartmental_target(input_path: Union[str, Sequence[str]], ta def main() -> int: - """ + r""" Entry point for the command-line application. Returns ------- - The process exit code: 0 for success, > 0 for failure + exit_code + The process exit code: 0 for success, > 0 for failure """ try: FrontendConfiguration.parse_config(sys.argv[1:]) except InvalidPathException as e: print(e) + return 1 + # the default Python recursion limit is 1000, which might not be enough in practice when running an AST visitor on a deep tree, e.g. containing an automatically generated expression sys.setrecursionlimit(10000) + # after all argument have been collected, start the actual processing return int(process()) -def get_parsed_models(): +def get_parsed_models() -> List[ASTModel]: r""" Handle the parsing and validation of the NESTML files Returns ------- - models: Sequence[ASTModel] + models List of correctly parsed models - errors_occurred : bool - Flag indicating whether errors occurred during processing """ # init log dir create_report_dir() @@ -417,36 +426,29 @@ def get_parsed_models(): for nestml_file in nestml_files: parsed_unit = ModelParser.parse_file(nestml_file) - if parsed_unit is None: - # Parsing error in the NESTML model, return True - return [], True - - compilation_units.append(parsed_unit) + if parsed_unit: + compilation_units.append(parsed_unit) - if len(compilation_units) > 0: - # generate a list of all models - models: Sequence[ASTModel] = [] - for compilationUnit in compilation_units: - models.extend(compilationUnit.get_model_list()) + # generate a list of all models + models: Sequence[ASTModel] = [] + for compilation_unit in compilation_units: + CoCosManager.check_model_names_unique(compilation_unit) + models.extend(compilation_unit.get_model_list()) - # check that no models with duplicate names have been defined - CoCosManager.check_no_duplicate_compilation_unit_names(models) + # check that no models with duplicate names have been defined + CoCosManager.check_no_duplicate_compilation_unit_names(models) - # now exclude those which are broken, i.e. have errors. - for model in models: - if Logger.has_errors(model): - code, message = Messages.get_model_contains_errors(model.get_name()) - Logger.log_message(node=model, code=code, message=message, - error_position=model.get_source_position(), - log_level=LoggingLevel.WARNING) - return [model], True + for model in models: + model.accept(ASTParentVisitor()) + model.accept(ASTSymbolTableVisitor()) - return models, False + return models def transform_models(transformers, models): for transformer in transformers: models = transformer.transform(models) + return models @@ -454,14 +456,14 @@ def generate_code(code_generators, models): code_generators.generate_code(models) -def process(): +def process() -> bool: r""" The main toolchain workflow entry point. For all models: parse, validate, transform, generate code and build. - Returns - ------- - errors_occurred : bool - Flag indicating whether errors occurred during processing + Return + ------ + errors_occurred + Flag indicating whether errors occurred during processing. False if processing was successful; True if errors occurred in any of the models. """ # initialize and set options for transformers, code generator and builder @@ -478,20 +480,38 @@ def process(): if len(codegen_and_builder_opts) > 0: raise CodeGeneratorOptionsException("The code generator option(s) \"" + ", ".join(codegen_and_builder_opts.keys()) + "\" do not exist.") - models, errors_occurred = get_parsed_models() + models = get_parsed_models() + + # validation -- check cocos for models that do not have errors already + excluded_models = [] + for model in models: + if Logger.has_errors(model.name): + code, message = Messages.get_model_contains_errors(model.get_name()) + Logger.log_message(node=model, code=code, message=message, + error_position=model.get_source_position(), + log_level=LoggingLevel.WARNING) + excluded_models.append(model) + else: + CoCosManager.check_cocos(model) + + # exclude models that have errors + models = list(set(models) - set(excluded_models)) + + # transformation(s) + models = transform_models(transformers, models) - if not errors_occurred: - models = transform_models(transformers, models) - generate_code(code_generator, models) + # generate code + generate_code(code_generator, models) - # perform build - if _builder is not None: - _builder.build() + # perform build + if _builder is not None: + _builder.build() if FrontendConfiguration.store_log: store_log_to_file() - return errors_occurred + # return a boolean indicating whether errors occurred + return len(Logger.get_all_messages_of_level(LoggingLevel.ERROR)) > 0 def init_predefined(): diff --git a/pynestml/meta_model/ast_model.py b/pynestml/meta_model/ast_model.py index 834e56897..c4b7374bf 100644 --- a/pynestml/meta_model/ast_model.py +++ b/pynestml/meta_model/ast_model.py @@ -459,23 +459,27 @@ def add_to_internals_block(self, declaration: ASTDeclaration, index: int = -1) - Adds the handed over declaration the internals block :param declaration: a single declaration """ - assert len(self.get_internals_blocks()) <= 1, "Only one internals block supported for now" from pynestml.utils.ast_utils import ASTUtils + from pynestml.visitors.ast_symbol_table_visitor import ASTSymbolTableVisitor + from pynestml.visitors.ast_parent_visitor import ASTParentVisitor + + assert len(self.get_internals_blocks()) <= 1, "Only one internals block supported for now" + if not self.get_internals_blocks(): ASTUtils.create_internal_block(self) + n_declarations = len(self.get_internals_blocks()[0].get_declarations()) if n_declarations == 0: index = 0 else: index = 1 + (index % len(self.get_internals_blocks()[0].get_declarations())) + self.get_internals_blocks()[0].get_declarations().insert(index, declaration) declaration.update_scope(self.get_internals_blocks()[0].get_scope()) - from pynestml.visitors.ast_symbol_table_visitor import ASTSymbolTableVisitor - from pynestml.visitors.ast_parent_visitor import ASTParentVisitor symtable_vistor = ASTSymbolTableVisitor() symtable_vistor.block_type_stack.push(BlockType.INTERNALS) - declaration.accept(symtable_vistor) - self.get_internals_blocks()[0].accept(ASTParentVisitor()) + self.accept(ASTParentVisitor()) + self.accept(symtable_vistor) symtable_vistor.block_type_stack.pop() def add_to_state_block(self, declaration: ASTDeclaration) -> None: @@ -483,24 +487,26 @@ def add_to_state_block(self, declaration: ASTDeclaration) -> None: Adds the handed over declaration to an arbitrary state block. A state block will be created if none exists. :param declaration: a single declaration. """ - assert len(self.get_state_blocks()) <= 1, "Only one internals block supported for now" + from pynestml.symbols.symbol import SymbolKind from pynestml.utils.ast_utils import ASTUtils + from pynestml.visitors.ast_symbol_table_visitor import ASTSymbolTableVisitor + from pynestml.visitors.ast_parent_visitor import ASTParentVisitor + + assert len(self.get_state_blocks()) <= 1, "Only one internals block supported for now" + if not self.get_state_blocks(): ASTUtils.create_state_block(self) + self.get_state_blocks()[0].get_declarations().append(declaration) declaration.update_scope(self.get_state_blocks()[0].get_scope()) - from pynestml.visitors.ast_symbol_table_visitor import ASTSymbolTableVisitor - from pynestml.visitors.ast_parent_visitor import ASTParentVisitor symtable_vistor = ASTSymbolTableVisitor() symtable_vistor.block_type_stack.push(BlockType.STATE) - declaration.accept(symtable_vistor) - self.get_state_blocks()[0].accept(ASTParentVisitor()) + self.accept(ASTParentVisitor()) + self.accept(symtable_vistor) symtable_vistor.block_type_stack.pop() - from pynestml.symbols.symbol import SymbolKind - assert declaration.get_variables()[0].get_scope().resolve_to_symbol( - declaration.get_variables()[0].get_name(), SymbolKind.VARIABLE) is not None - assert declaration.get_scope().resolve_to_symbol(declaration.get_variables()[0].get_name(), - SymbolKind.VARIABLE) is not None + + assert declaration.get_variables()[0].get_scope().resolve_to_symbol(declaration.get_variables()[0].get_name(), SymbolKind.VARIABLE) is not None + assert declaration.get_scope().resolve_to_symbol(declaration.get_variables()[0].get_name(), SymbolKind.VARIABLE) is not None def print_comment(self, prefix: str = "") -> str: """ @@ -566,7 +572,6 @@ def get_spike_input_port_names(self) -> List[str]: """ Returns a list of all spike input ports defined in the model. """ - print("get_spike_input_port_names = " + str([port.get_symbol_name() for port in self.get_spike_input_ports()])) return [port.get_symbol_name() for port in self.get_spike_input_ports()] def get_continuous_input_ports(self) -> List[VariableSymbol]: diff --git a/pynestml/symbols/symbol.py b/pynestml/symbols/symbol.py index 1e294566b..c73435c6d 100644 --- a/pynestml/symbols/symbol.py +++ b/pynestml/symbols/symbol.py @@ -18,8 +18,8 @@ # # You should have received a copy of the GNU General Public License # along with NEST. If not, see . -from abc import ABCMeta, abstractmethod +from abc import ABCMeta, abstractmethod from enum import Enum diff --git a/pynestml/symbols/type_symbol.py b/pynestml/symbols/type_symbol.py index 7047cdbca..a3eb28a12 100644 --- a/pynestml/symbols/type_symbol.py +++ b/pynestml/symbols/type_symbol.py @@ -18,11 +18,11 @@ # # You should have received a copy of the GNU General Public License # along with NEST. If not, see . + from abc import ABCMeta, abstractmethod from pynestml.symbols.symbol import Symbol from pynestml.utils.logger import Logger, LoggingLevel -from pynestml.utils.messages import Messages class TypeSymbol(Symbol): @@ -198,6 +198,7 @@ def is_castable_to(self, _other_type): def binary_operation_not_defined_error(self, _operator, _other): from pynestml.symbols.error_type_symbol import ErrorTypeSymbol + from pynestml.utils.messages import Messages result = ErrorTypeSymbol() code, message = Messages.get_binary_operation_not_defined( lhs=self.print_nestml_type(), operator=_operator, rhs=_other.print_nestml_type()) @@ -208,6 +209,7 @@ def binary_operation_not_defined_error(self, _operator, _other): def unary_operation_not_defined_error(self, _operator): from pynestml.symbols.error_type_symbol import ErrorTypeSymbol result = ErrorTypeSymbol() + from pynestml.utils.messages import Messages code, message = Messages.get_unary_operation_not_defined(_operator, self.print_symbol()) Logger.log_message(code=code, message=message, error_position=self.referenced_object.get_source_position(), @@ -226,6 +228,7 @@ def inverse_of_unit(cls, other): return result def warn_implicit_cast_from_to(self, _from, _to): + from pynestml.utils.messages import Messages code, message = Messages.get_implicit_cast_rhs_to_lhs(_to.print_symbol(), _from.print_symbol()) Logger.log_message(code=code, message=message, error_position=self.get_referenced_object().get_source_position(), diff --git a/pynestml/symbols/unit_type_symbol.py b/pynestml/symbols/unit_type_symbol.py index 37c43b035..1f9977de0 100644 --- a/pynestml/symbols/unit_type_symbol.py +++ b/pynestml/symbols/unit_type_symbol.py @@ -19,6 +19,7 @@ # You should have received a copy of the GNU General Public License # along with NEST. If not, see . +from typing import Optional from pynestml.symbols.type_symbol import TypeSymbol from pynestml.utils.logger import Logger, LoggingLevel from pynestml.utils.messages import Messages @@ -131,12 +132,12 @@ def __sub__(self, other): def add_or_sub_another_unit(self, other): if self.equals(other): return other - else: - return self.attempt_magnitude_cast(other) + + return self.attempt_magnitude_cast(other) def attempt_magnitude_cast(self, other): if self.differs_only_in_magnitude(other): - factor = UnitTypeSymbol.get_conversion_factor(self.astropy_unit, other.astropy_unit) + factor = UnitTypeSymbol.get_conversion_factor(other.astropy_unit, self.astropy_unit) other.referenced_object.set_implicit_conversion_factor(factor) code, message = Messages.get_implicit_magnitude_conversion(self, other, factor) Logger.log_message(code=code, message=message, @@ -144,18 +145,20 @@ def attempt_magnitude_cast(self, other): log_level=LoggingLevel.INFO) return self - else: - return self.binary_operation_not_defined_error('+/-', other) - # TODO: change order of parameters to conform with the from_to scheme. - # TODO: Also rename to reflect that, i.e. get_conversion_factor_from_to + return self.binary_operation_not_defined_error('+/-', other) + @classmethod - def get_conversion_factor(cls, to, _from): + def get_conversion_factor(cls, _from, to) -> Optional[float]: """ - Calculates the conversion factor from _convertee_unit to target_unit. - Behaviour is only well-defined if both units have the same physical base type + Calculates the conversion factor from _convertee_unit to target_unit. Behaviour is only well-defined if both units have the same physical base type. """ - factor = (_from / to).si.scale + try: + factor = (_from / to).si.scale + except BaseException: + # this can fail in case of e.g. trying to convert from "1/s" to "2/s" + return None + return factor def is_castable_to(self, _other_type): diff --git a/pynestml/transformers/assign_implicit_conversion_factors_transformer.py b/pynestml/transformers/assign_implicit_conversion_factors_transformer.py new file mode 100644 index 000000000..f44ee12d5 --- /dev/null +++ b/pynestml/transformers/assign_implicit_conversion_factors_transformer.py @@ -0,0 +1,335 @@ +# -*- coding: utf-8 -*- +# +# assign_implicit_conversion_factors_transformer.py +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . + +from typing import Sequence, Union + +from pynestml.meta_model.ast_compound_stmt import ASTCompoundStmt +from pynestml.meta_model.ast_declaration import ASTDeclaration +from pynestml.meta_model.ast_inline_expression import ASTInlineExpression +from pynestml.meta_model.ast_node import ASTNode +from pynestml.meta_model.ast_small_stmt import ASTSmallStmt +from pynestml.meta_model.ast_stmt import ASTStmt +from pynestml.symbols.error_type_symbol import ErrorTypeSymbol +from pynestml.symbols.predefined_types import PredefinedTypes +from pynestml.symbols.symbol import SymbolKind +from pynestml.symbols.template_type_symbol import TemplateTypeSymbol +from pynestml.symbols.variadic_type_symbol import VariadicTypeSymbol +from pynestml.transformers.transformer import Transformer +from pynestml.utils.ast_source_location import ASTSourceLocation +from pynestml.utils.ast_utils import ASTUtils +from pynestml.utils.logger import LoggingLevel, Logger +from pynestml.utils.logging_helper import LoggingHelper +from pynestml.utils.messages import Messages +from pynestml.utils.type_caster import TypeCaster +from pynestml.visitors.ast_visitor import ASTVisitor + + +class AssignImplicitConversionFactorsTransformer(Transformer): + r""" + Assign implicit conversion factors in expressions. + """ + + def transform(self, models: Union[ASTNode, Sequence[ASTNode]]) -> Union[ASTNode, Sequence[ASTNode]]: + single = False + if isinstance(models, ASTNode): + single = True + models = [models] + + for model in models: + model.accept(AssignImplicitConversionFactorVisitor()) + self.__assign_return_types(model) + + if single: + return models[0] + return models + + def __assign_return_types(self, _node): + for userDefinedFunction in _node.get_functions(): + symbol = userDefinedFunction.get_scope().resolve_to_symbol(userDefinedFunction.get_name(), + SymbolKind.FUNCTION) + # first ensure that the block contains at least one statement + if symbol is not None and len(userDefinedFunction.get_block().get_stmts()) > 0: + # now check that the last statement is a return + self.__check_return_recursively(userDefinedFunction, + symbol.get_return_type(), + userDefinedFunction.get_block().get_stmts(), + False) + # now if it does not have a statement, but uses a return type, it is an error + elif symbol is not None and userDefinedFunction.has_return_type() and \ + not symbol.get_return_type().equals(PredefinedTypes.get_void_type()): + code, message = Messages.get_no_return() + Logger.log_message(node=_node, code=code, message=message, + error_position=userDefinedFunction.get_source_position(), + log_level=LoggingLevel.ERROR) + + def __check_return_recursively(self, processed_function, type_symbol=None, stmts=None, ret_defined: bool = False) -> None: + """ + For a handed over statement, it checks if the statement is a return statement and if it is typed according to the handed over type symbol. + :param type_symbol: a single type symbol + :type type_symbol: type_symbol + :param stmts: a list of statements, either simple or compound + :type stmts: list(ASTSmallStmt,ASTCompoundStmt) + :param ret_defined: indicates whether a ret has already been defined after this block of stmt, thus is not + necessary. Implies that the return has been defined in the higher level block + """ + # in order to ensure that in the sub-blocks, a return is not necessary, we check if the last one in this + # block is a return statement, thus it is not required to have a return in the sub-blocks, but optional + last_statement = stmts[len(stmts) - 1] + ret_defined = False or ret_defined + if (len(stmts) > 0 and isinstance(last_statement, ASTStmt) + and last_statement.is_small_stmt() + and last_statement.small_stmt.is_return_stmt()): + ret_defined = True + + # now check that returns are there if necessary and correctly typed + for c_stmt in stmts: + if c_stmt.is_small_stmt(): + stmt = c_stmt.small_stmt + else: + stmt = c_stmt.compound_stmt + + # if it is a small statement, check if it is a return statement + if isinstance(stmt, ASTSmallStmt) and stmt.is_return_stmt(): + # first check if the return is the last one in this block of statements + if stmts.index(c_stmt) != (len(stmts) - 1): + code, message = Messages.get_not_last_statement('Return') + Logger.log_message(error_position=stmt.get_source_position(), + code=code, message=message, + log_level=LoggingLevel.WARNING) + + # now check that it corresponds to the declared type + if stmt.get_return_stmt().has_expression() and type_symbol is PredefinedTypes.get_void_type(): + code, message = Messages.get_type_different_from_expected(PredefinedTypes.get_void_type(), + stmt.get_return_stmt().get_expression().type) + Logger.log_message(error_position=stmt.get_source_position(), + message=message, code=code, log_level=LoggingLevel.ERROR) + + # if it is not void check if the type corresponds to the one stated + if not stmt.get_return_stmt().has_expression() and \ + not type_symbol.equals(PredefinedTypes.get_void_type()): + code, message = Messages.get_type_different_from_expected(PredefinedTypes.get_void_type(), + type_symbol) + Logger.log_message(error_position=stmt.get_source_position(), + message=message, code=code, log_level=LoggingLevel.ERROR) + + if stmt.get_return_stmt().has_expression(): + type_of_return = stmt.get_return_stmt().get_expression().type + if isinstance(type_of_return, ErrorTypeSymbol): + code, message = Messages.get_type_could_not_be_derived(processed_function.get_name()) + Logger.log_message(error_position=stmt.get_source_position(), + code=code, message=message, log_level=LoggingLevel.ERROR) + elif not type_of_return.equals(type_symbol): + TypeCaster.try_to_recover_or_error(type_symbol, type_of_return, + stmt.get_return_stmt().get_expression()) + elif isinstance(stmt, ASTCompoundStmt): + # otherwise it is a compound stmt, thus check recursively + if stmt.is_if_stmt(): + self.__check_return_recursively(processed_function, + type_symbol, + stmt.get_if_stmt().get_if_clause().get_block().get_stmts(), + ret_defined) + for else_ifs in stmt.get_if_stmt().get_elif_clauses(): + self.__check_return_recursively(processed_function, + type_symbol, else_ifs.get_block().get_stmts(), ret_defined) + if stmt.get_if_stmt().has_else_clause(): + self.__check_return_recursively(processed_function, + type_symbol, + stmt.get_if_stmt().get_else_clause().get_block().get_stmts(), + ret_defined) + elif stmt.is_while_stmt(): + self.__check_return_recursively(processed_function, + type_symbol, stmt.get_while_stmt().get_block().get_stmts(), + ret_defined) + elif stmt.is_for_stmt(): + self.__check_return_recursively(processed_function, + type_symbol, stmt.get_for_stmt().get_block().get_stmts(), + ret_defined) + # now, if a return statement has not been defined in the corresponding higher level block, we have to ensure that it is defined here + elif not ret_defined and stmts.index(c_stmt) == (len(stmts) - 1): + if not (isinstance(stmt, ASTSmallStmt) and stmt.is_return_stmt()): + code, message = Messages.get_no_return() + Logger.log_message(error_position=stmt.get_source_position(), log_level=LoggingLevel.ERROR, + code=code, message=message) + + +class AssignImplicitConversionFactorVisitor(ASTVisitor): + """ + This visitor checks that all expression correspond to the expected type. + """ + + def visit_declaration(self, node): + """ + Visits a single declaration and asserts that type of lhs is equal to type of rhs. + :param node: a single declaration. + :type node: ASTDeclaration + """ + assert isinstance(node, ASTDeclaration) + if node.has_expression(): + if node.get_expression().get_source_position().equals(ASTSourceLocation.get_added_source_position()): + # no type checks are executed for added nodes, since we assume correctness + return + lhs_type = node.get_data_type().get_type_symbol() + rhs_type = node.get_expression().type + if isinstance(rhs_type, ErrorTypeSymbol): + LoggingHelper.drop_missing_type_error(node) + return + if self.__types_do_not_match(lhs_type, rhs_type): + TypeCaster.try_to_recover_or_error(lhs_type, rhs_type, node.get_expression()) + + def visit_inline_expression(self, node): + """ + Visits a single inline expression and asserts that type of lhs is equal to type of rhs. + """ + assert isinstance(node, ASTInlineExpression) + lhs_type = node.get_data_type().get_type_symbol() + rhs_type = node.get_expression().type + if isinstance(rhs_type, ErrorTypeSymbol): + LoggingHelper.drop_missing_type_error(node) + return + + if self.__types_do_not_match(lhs_type, rhs_type): + TypeCaster.try_to_recover_or_error(lhs_type, rhs_type, node.get_expression()) + + def visit_assignment(self, node): + """ + Visits a single expression and assures that type(lhs) == type(rhs). + :param node: a single assignment. + :type node: ASTAssignment + """ + from pynestml.meta_model.ast_assignment import ASTAssignment + assert isinstance(node, ASTAssignment) + + if node.get_source_position().equals(ASTSourceLocation.get_added_source_position()): + # no type checks are executed for added nodes, since we assume correctness + return + if node.is_direct_assignment: # case a = b is simple + self.handle_simple_assignment(node) + else: + self.handle_compound_assignment(node) # e.g. a *= b + + def handle_compound_assignment(self, node): + rhs_expr = node.get_expression() + lhs_variable_symbol = node.get_variable().resolve_in_own_scope() + rhs_type_symbol = rhs_expr.type + + if lhs_variable_symbol is None: + code, message = Messages.get_equation_var_not_in_state_block(node.get_variable().get_complete_name()) + Logger.log_message(code=code, message=message, error_position=node.get_source_position(), + log_level=LoggingLevel.ERROR) + return + + if isinstance(rhs_type_symbol, ErrorTypeSymbol): + LoggingHelper.drop_missing_type_error(node) + return + + lhs_type_symbol = lhs_variable_symbol.get_type_symbol() + + if node.is_compound_product: + if self.__types_do_not_match(lhs_type_symbol, lhs_type_symbol * rhs_type_symbol): + TypeCaster.try_to_recover_or_error(lhs_type_symbol, lhs_type_symbol * rhs_type_symbol, + node.get_expression()) + return + return + + if node.is_compound_quotient: + if self.__types_do_not_match(lhs_type_symbol, lhs_type_symbol / rhs_type_symbol): + TypeCaster.try_to_recover_or_error(lhs_type_symbol, lhs_type_symbol / rhs_type_symbol, + node.get_expression()) + return + return + + assert node.is_compound_sum or node.is_compound_minus + if self.__types_do_not_match(lhs_type_symbol, rhs_type_symbol): + TypeCaster.try_to_recover_or_error(lhs_type_symbol, rhs_type_symbol, + node.get_expression()) + + @staticmethod + def __types_do_not_match(lhs_type_symbol, rhs_type_symbol): + if lhs_type_symbol is None: + return True + + return not lhs_type_symbol.equals(rhs_type_symbol) + + def handle_simple_assignment(self, node): + from pynestml.symbols.symbol import SymbolKind + lhs_variable_symbol = node.get_scope().resolve_to_symbol(node.get_variable().get_complete_name(), + SymbolKind.VARIABLE) + + rhs_type_symbol = node.get_expression().type + if isinstance(rhs_type_symbol, ErrorTypeSymbol): + LoggingHelper.drop_missing_type_error(node) + return + + if lhs_variable_symbol is not None and self.__types_do_not_match(lhs_variable_symbol.get_type_symbol(), + rhs_type_symbol): + TypeCaster.try_to_recover_or_error(lhs_variable_symbol.get_type_symbol(), rhs_type_symbol, + node.get_expression()) + + def visit_function_call(self, node): + """ + Check consistency for a single function call: check if the called function has been declared, whether the number and types of arguments correspond to the declaration, etc. + + :param node: a single function call. + :type node: ASTFunctionCall + """ + func_name = node.get_name() + + if func_name == 'convolve': + return + + symbol = node.get_scope().resolve_to_symbol(node.get_name(), SymbolKind.FUNCTION) + + if symbol is None and ASTUtils.is_function_delay_variable(node): + return + + # first check if the function has been declared + if symbol is None: + code, message = Messages.get_function_not_declared(node.get_name()) + Logger.log_message(error_position=node.get_source_position(), log_level=LoggingLevel.ERROR, + code=code, message=message) + return + + # check if the number of arguments is the same as in the symbol; accept anything for variadic types + is_variadic: bool = len(symbol.get_parameter_types()) == 1 and isinstance(symbol.get_parameter_types()[0], VariadicTypeSymbol) + if (not is_variadic) and len(node.get_args()) != len(symbol.get_parameter_types()): + code, message = Messages.get_wrong_number_of_args(str(node), len(symbol.get_parameter_types()), + len(node.get_args())) + Logger.log_message(code=code, message=message, log_level=LoggingLevel.ERROR, + error_position=node.get_source_position()) + return + + # finally check if the call is correctly typed + expected_types = symbol.get_parameter_types() + actual_args = node.get_args() + actual_types = [arg.type for arg in actual_args] + for actual_arg, actual_type, expected_type in zip(actual_args, actual_types, expected_types): + if isinstance(actual_type, ErrorTypeSymbol): + code, message = Messages.get_type_could_not_be_derived(actual_arg) + Logger.log_message(code=code, message=message, log_level=LoggingLevel.ERROR, + error_position=actual_arg.get_source_position()) + return + + if isinstance(expected_type, VariadicTypeSymbol): + # variadic type symbol accepts anything + return + + if not actual_type.equals(expected_type) and not isinstance(expected_type, TemplateTypeSymbol): + TypeCaster.try_to_recover_or_error(expected_type, actual_type, actual_arg) diff --git a/pynestml/transformers/synapse_post_neuron_transformer.py b/pynestml/transformers/synapse_post_neuron_transformer.py index 68cc70a62..a06260824 100644 --- a/pynestml/transformers/synapse_post_neuron_transformer.py +++ b/pynestml/transformers/synapse_post_neuron_transformer.py @@ -23,6 +23,7 @@ from typing import Any, Sequence, Mapping, Optional, Union +from pynestml.cocos.co_cos_manager import CoCosManager from pynestml.frontend.frontend_configuration import FrontendConfiguration from pynestml.meta_model.ast_assignment import ASTAssignment from pynestml.meta_model.ast_equations_block import ASTEquationsBlock @@ -563,11 +564,6 @@ def mark_post_port(_expr=None): # replace occurrences of the variables in expressions in the original synapse with calls to the corresponding neuron getters # - # make sure the moved symbols can be resolved in the scope of the neuron (that's where ``ASTExternalVariable._altscope`` will be pointing to) - ast_symbol_table_visitor = ASTSymbolTableVisitor() - ast_symbol_table_visitor.after_ast_rewrite_ = True - new_neuron.accept(ast_symbol_table_visitor) - Logger.log_message( None, -1, "In synapse: replacing variables with suffixed external variable references", None, LoggingLevel.INFO) for state_var in syn_to_neuron_state_vars: @@ -609,7 +605,6 @@ def mark_post_port(_expr=None): new_neuron.accept(ASTParentVisitor()) new_synapse.accept(ASTParentVisitor()) ast_symbol_table_visitor = ASTSymbolTableVisitor() - ast_symbol_table_visitor.after_ast_rewrite_ = True new_neuron.accept(ast_symbol_table_visitor) new_synapse.accept(ast_symbol_table_visitor) diff --git a/pynestml/utils/ast_utils.py b/pynestml/utils/ast_utils.py index d3d6f6ef5..a3983694d 100644 --- a/pynestml/utils/ast_utils.py +++ b/pynestml/utils/ast_utils.py @@ -28,7 +28,6 @@ from pynestml.codegeneration.printers.ast_printer import ASTPrinter from pynestml.codegeneration.printers.cpp_variable_printer import CppVariablePrinter -from pynestml.codegeneration.printers.nestml_printer import NESTMLPrinter from pynestml.frontend.frontend_configuration import FrontendConfiguration from pynestml.generated.PyNestMLLexer import PyNestMLLexer from pynestml.meta_model.ast_assignment import ASTAssignment @@ -66,7 +65,6 @@ from pynestml.utils.messages import Messages from pynestml.utils.string_utils import removesuffix from pynestml.visitors.ast_higher_order_visitor import ASTHigherOrderVisitor -from pynestml.visitors.ast_parent_visitor import ASTParentVisitor from pynestml.visitors.ast_visitor import ASTVisitor @@ -1766,10 +1764,12 @@ def remove_initial_values_for_kernels(cls, model: ASTModel) -> None: @classmethod def update_initial_values_for_odes(cls, model: ASTModel, solver_dicts: List[dict]) -> None: """ - Update initial values for original ODE declarations (e.g. V_m', g_ahp'') that are present in the model - before ODE-toolbox processing, with the formatted variable names and initial values returned by ODE-toolbox. + Update initial values for original ODE declarations (e.g. V_m', g_ahp'') that are present in the model before ODE-toolbox processing, with the formatted variable names and initial values returned by ODE-toolbox. """ from pynestml.utils.model_parser import ModelParser + from pynestml.visitors.ast_parent_visitor import ASTParentVisitor + from pynestml.visitors.ast_symbol_table_visitor import ASTSymbolTableVisitor + assert len(model.get_equations_blocks()) == 1, "Only one equation block should be present" if not model.get_state_blocks(): @@ -1782,10 +1782,6 @@ def update_initial_values_for_odes(cls, model: ASTModel, solver_dicts: List[dict if cls.is_ode_variable(var.get_name(), model): assert cls.variable_in_solver(cls.to_ode_toolbox_processed_name(var_name), solver_dicts) - # replace the left-hand side variable name by the ode-toolbox format - var.set_name(cls.to_ode_toolbox_processed_name(var.get_complete_name())) - var.set_differential_order(0) - # replace the defining expression by the ode-toolbox result iv_expr = cls.get_initial_value_from_ode_toolbox_result( cls.to_ode_toolbox_processed_name(var_name), solver_dicts) @@ -1794,6 +1790,9 @@ def update_initial_values_for_odes(cls, model: ASTModel, solver_dicts: List[dict iv_expr.update_scope(state_block.get_scope()) iv_decl.set_expression(iv_expr) + model.accept(ASTParentVisitor()) + model.accept(ASTSymbolTableVisitor()) + @classmethod def integrate_odes_args_strs_from_function_call(cls, function_call: ASTFunctionCall): arg_names = [] @@ -2296,6 +2295,7 @@ def replace_convolve_calls_with_buffers_(cls, model: ASTModel, equations_block: r""" Replace all occurrences of `convolve(kernel[']^n, spike_input_port)` with the corresponding buffer variable, e.g. `g_E__X__spikes_exc[__d]^n` for a kernel named `g_E` and a spike input port named `spikes_exc`. """ + from pynestml.visitors.ast_symbol_table_visitor import ASTSymbolTableVisitor def replace_function_call_through_var(_expr=None): if _expr.is_function_call() and _expr.get_function_call().get_name() == "convolve": @@ -2326,6 +2326,7 @@ def func(x): return replace_function_call_through_var(x) if isinstance(x, ASTSimpleExpression) else True equations_block.accept(ASTHigherOrderVisitor(func)) + equations_block.accept(ASTSymbolTableVisitor()) @classmethod def update_blocktype_for_common_parameters(cls, node): diff --git a/pynestml/utils/logger.py b/pynestml/utils/logger.py index 06e95b804..8404f1245 100644 --- a/pynestml/utils/logger.py +++ b/pynestml/utils/logger.py @@ -19,7 +19,7 @@ # You should have received a copy of the GNU General Public License # along with NEST. If not, see . -from typing import List, Mapping, Optional, Tuple +from typing import List, Mapping, Optional, Tuple, Union from collections import OrderedDict from enum import Enum @@ -75,6 +75,7 @@ class Logger: def init_logger(cls, logging_level: LoggingLevel): """ Initializes the logger. + :param logging_level: the logging level as required :type logging_level: LoggingLevel """ @@ -82,7 +83,6 @@ def init_logger(cls, logging_level: LoggingLevel): cls.curr_message = 0 cls.log = {} cls.log_frozen = False - return @classmethod def freeze_log(cls, do_freeze: bool = True): @@ -95,6 +95,7 @@ def freeze_log(cls, do_freeze: bool = True): def get_log(cls) -> Mapping[int, Tuple[ASTNode, LoggingLevel, str]]: """ Returns the overall log of messages. The structure of the log is: (NODE, LEVEL, MESSAGE) + :return: mapping from id to ASTNode, log level and message. """ return cls.log @@ -103,6 +104,7 @@ def get_log(cls) -> Mapping[int, Tuple[ASTNode, LoggingLevel, str]]: def set_log(cls, log, counter): """ Restores log from the 'log' variable + :param log: the log :param counter: the counter """ @@ -113,20 +115,19 @@ def set_log(cls, log, counter): def log_message(cls, node: ASTNode = None, code: MessageCode = None, message: str = None, error_position: ASTSourceLocation = None, log_level: LoggingLevel = None): """ Logs the handed over message on the handed over node. If the current logging is appropriate, the message is also printed. + :param node: the node in which the error occurred :param code: a single error code - :type code: ErrorCode :param error_position: the position on which the error occurred. - :type error_position: SourcePosition :param message: a message. - :type message: str :param log_level: the corresponding log level. - :type log_level: LoggingLevel """ if cls.log_frozen: return + if cls.curr_message is None: cls.init_logger(LoggingLevel.INFO) + from pynestml.meta_model.ast_node import ASTNode from pynestml.utils.ast_source_location import ASTSourceLocation assert (node is None or isinstance(node, ASTNode)), \ @@ -134,15 +135,23 @@ def log_message(cls, node: ASTNode = None, code: MessageCode = None, message: st assert (error_position is None or isinstance(error_position, ASTSourceLocation)), \ '(PyNestML.Logger) Wrong type of error position provided (%s)!' % type(error_position) from pynestml.meta_model.ast_model import ASTModel + if isinstance(node, ASTModel): cls.log[cls.curr_message] = ( node.get_artifact_name(), node, log_level, code, error_position, message) - elif cls.current_node is not None: - cls.log[cls.curr_message] = (cls.current_node.get_artifact_name(), cls.current_node, + else: + if cls.current_node is not None: + artifact_name = cls.current_node.get_artifact_name() + else: + artifact_name = "" + + cls.log[cls.curr_message] = (artifact_name, cls.current_node, log_level, code, error_position, message) + cls.curr_message += 1 if cls.no_print: return + if cls.logging_level.value <= log_level.value: if isinstance(node, ASTInlineExpression): node_name = node.variable_name @@ -163,10 +172,9 @@ def log_message(cls, node: ASTNode = None, code: MessageCode = None, message: st def string_to_level(cls, string: str) -> LoggingLevel: """ Returns the logging level corresponding to the handed over string. If no such exits, returns None. + :param string: a single string representing the level. - :type string: str :return: a single logging level. - :rtype: LoggingLevel """ if string == 'DEBUG': return LoggingLevel.DEBUG @@ -183,7 +191,7 @@ def string_to_level(cls, string: str) -> LoggingLevel: if string == 'NO' or string == 'NONE': return LoggingLevel.NO - raise Exception('Tried to convert unknown string \"' + string + '\" to logging level') + raise Exception("Tried to convert unknown string '" + string + "' to logging level") @classmethod def level_to_string(cls, level: LoggingLevel) -> str: @@ -207,7 +215,7 @@ def level_to_string(cls, level: LoggingLevel) -> str: if level == LoggingLevel.NO: return 'NO' - raise Exception('Tried to convert unknown logging level \"' + str(level) + '\" to string') + raise Exception("Tried to convert unknown logging level '" + str(level) + "' to string") @classmethod def set_logging_level(cls, level: LoggingLevel) -> None: @@ -218,79 +226,89 @@ def set_logging_level(cls, level: LoggingLevel) -> None: """ if cls.log_frozen: return + cls.logging_level = level @classmethod def set_current_node(cls, node: Optional[ASTNode]) -> None: """ - Sets the handed over node as the currently processed one. This enables a retrieval of messages for a - specific node. - :param node: a single node instance + Sets the handed over node as the currently processed one. This enables a retrieval of messages for a specific node. + + :param node: a single node instance """ cls.current_node = node @classmethod - def get_all_messages_of_level_and_or_node(cls, node: ASTNode, level: LoggingLevel) -> List[Tuple[ASTNode, LoggingLevel, str]]: + def get_all_messages_of_level_and_or_node(cls, node: Union[ASTNode, str], level: LoggingLevel) -> List[Tuple[ASTNode, LoggingLevel, str]]: """ - Returns all messages which have a certain logging level, or have been reported for a certain node, or - both. + Returns all messages which have a certain logging level, or have been reported for a certain node, or both. + :param node: a single node instance :param level: a logging level - :type level: LoggingLevel :return: a list of messages with their levels. - :rtype: list((str,Logging_Level) """ if level is None and node is None: return cls.get_log() + + if isinstance(node, str): + # search by artifact name + node_artifact_name = node + node = None + else: + # search by artifact class object + node_artifact_name = None + ret = list() for (artifactName, node_i, logLevel, code, errorPosition, message) in cls.log.values(): - if (level == logLevel if level is not None else True) and ( - node if node is not None else True) and ( - node.get_artifact_name() == artifactName if node is not None else True): + if (level == logLevel if level is not None else True) and (node if node is not None else True) and (node_artifact_name == artifactName if node is not None else True): ret.append((node, logLevel, message)) + return ret @classmethod def get_all_messages_of_level(cls, level: LoggingLevel) -> List[Tuple[ASTNode, LoggingLevel, str]]: """ Returns all messages which have a certain logging level. + :param level: a logging level - :type level: LoggingLevel :return: a list of messages with their levels. - :rtype: list((str,Logging_Level) """ if level is None: return cls.get_log() + ret = list() for (artifactName, node, logLevel, code, errorPosition, message) in cls.log.values(): if level == logLevel: ret.append((node, logLevel, message)) + return ret @classmethod def get_all_messages_of_node(cls, node: ASTNode) -> List[Tuple[ASTNode, LoggingLevel, str]]: """ Returns all messages which have been reported for a certain node. + :param node: a single node instance :return: a list of messages with their levels. - :rtype: list((str,Logging_Level) """ if node is None: return cls.get_log() + ret = list() for (artifactName, node_i, logLevel, code, errorPosition, message) in cls.log.values(): if (node_i == node if node is not None else True) and \ (node.get_artifact_name() == artifactName if node is not None else True): ret.append((node, logLevel, message)) + return ret @classmethod def has_errors(cls, node: ASTNode) -> bool: """ Indicates whether the handed over node, thus the corresponding model, has errors. + :param node: a single node instance. :return: True if errors detected, otherwise False - :rtype: bool """ return len(cls.get_all_messages_of_level_and_or_node(node, LoggingLevel.ERROR)) > 0 @@ -311,6 +329,7 @@ def get_json_format(cls) -> str: (node.get_name() if node is not None else 'GLOBAL') + '", ' + \ '"severity":"' \ + str(logLevel.name) + '", ' + if code is not None: ret += '"code":"' + \ code.name + \ @@ -323,10 +342,12 @@ def get_json_format(cls) -> str: '", ' + \ '"message":"' + str(message).replace('"', "'") + '"}' ret += ',' + if len(cls.log.keys()) == 0: parsed = json.loads('[]', object_pairs_hook=OrderedDict) else: ret = ret[:-1] # delete the last "," ret += ']' parsed = json.loads(ret, object_pairs_hook=OrderedDict) + return json.dumps(parsed, indent=2, sort_keys=False) diff --git a/pynestml/utils/mechs_info_enricher.py b/pynestml/utils/mechs_info_enricher.py index 456ece178..ea645a02c 100644 --- a/pynestml/utils/mechs_info_enricher.py +++ b/pynestml/utils/mechs_info_enricher.py @@ -22,13 +22,14 @@ from collections import defaultdict from pynestml.meta_model.ast_model import ASTModel +from pynestml.symbols.predefined_functions import PredefinedFunctions +from pynestml.symbols.symbol import SymbolKind +from pynestml.utils.ast_vector_parameter_setter_and_printer_factory import ASTVectorParameterSetterAndPrinterFactory from pynestml.visitors.ast_parent_visitor import ASTParentVisitor from pynestml.visitors.ast_symbol_table_visitor import ASTSymbolTableVisitor from pynestml.utils.ast_utils import ASTUtils -from pynestml.visitors.ast_visitor import ASTVisitor from pynestml.utils.model_parser import ModelParser -from pynestml.symbols.predefined_functions import PredefinedFunctions -from pynestml.symbols.symbol import SymbolKind +from pynestml.visitors.ast_visitor import ASTVisitor class MechsInfoEnricher: @@ -57,33 +58,6 @@ def transform_ode_solutions(cls, neuron, mechs_info): solution_transformed["states"] = defaultdict() solution_transformed["propagators"] = defaultdict() - for variable_name, rhs_str in ode_info["ode_toolbox_output"][ode_solution_index]["initial_values"].items(): - variable = neuron.get_equations_blocks()[0].get_scope().resolve_to_symbol(variable_name, - SymbolKind.VARIABLE) - - expression = ModelParser.parse_expression(rhs_str) - # pretend that update expressions are in "equations" block, - # which should always be present, as synapses have been - # defined to get here - expression.update_scope(neuron.get_equations_blocks()[0].get_scope()) - expression.accept(ASTSymbolTableVisitor()) - - update_expr_str = ode_info["ode_toolbox_output"][ode_solution_index]["update_expressions"][ - variable_name] - update_expr_ast = ModelParser.parse_expression( - update_expr_str) - # pretend that update expressions are in "equations" block, - # which should always be present, as differential equations - # must have been defined to get here - update_expr_ast.update_scope( - neuron.get_equations_blocks()[0].get_scope()) - update_expr_ast.accept(ASTSymbolTableVisitor()) - - solution_transformed["states"][variable_name] = { - "ASTVariable": variable, - "init_expression": expression, - "update_expression": update_expr_ast, - } for variable_name, rhs_str in ode_info["ode_toolbox_output"][ode_solution_index]["propagators"].items(): prop_variable = neuron.get_equations_blocks()[0].get_scope().resolve_to_symbol(variable_name, SymbolKind.VARIABLE) @@ -118,6 +92,36 @@ def transform_ode_solutions(cls, neuron, mechs_info): PredefinedFunctions.TIME_RESOLUTION: mechanism_info["time_resolution_var"] = variable + for variable_name, rhs_str in ode_info["ode_toolbox_output"][ode_solution_index]["initial_values"].items(): + variable = neuron.get_equations_blocks()[0].get_scope().resolve_to_symbol(variable_name, + SymbolKind.VARIABLE) + + expression = ModelParser.parse_expression(rhs_str) + # pretend that update expressions are in "equations" block, + # which should always be present, as synapses have been + # defined to get here + expression.update_scope(neuron.get_equations_blocks()[0].get_scope()) + expression.accept(ASTSymbolTableVisitor()) + + update_expr_str = ode_info["ode_toolbox_output"][ode_solution_index]["update_expressions"][ + variable_name] + update_expr_ast = ModelParser.parse_expression( + update_expr_str) + # pretend that update expressions are in "equations" block, + # which should always be present, as differential equations + # must have been defined to get here + update_expr_ast.update_scope( + neuron.get_scope()) + update_expr_ast.accept(ASTParentVisitor()) + update_expr_ast.accept(ASTSymbolTableVisitor()) + neuron.accept(ASTSymbolTableVisitor()) + + solution_transformed["states"][variable_name] = { + "ASTVariable": variable, + "init_expression": expression, + "update_expression": update_expr_ast, + } + mechanism_info["ODEs"][ode_var_name]["transformed_solutions"].append(solution_transformed) neuron.accept(ASTParentVisitor()) diff --git a/pynestml/utils/messages.py b/pynestml/utils/messages.py index 69b32a8f4..27cd5cfcd 100644 --- a/pynestml/utils/messages.py +++ b/pynestml/utils/messages.py @@ -18,11 +18,15 @@ # # You should have received a copy of the GNU General Public License # along with NEST. If not, see . -from enum import Enum + +from __future__ import annotations + from typing import Tuple -from pynestml.meta_model.ast_inline_expression import ASTInlineExpression from collections.abc import Iterable +from enum import Enum + +from pynestml.meta_model.ast_inline_expression import ASTInlineExpression from pynestml.meta_model.ast_function import ASTFunction @@ -158,8 +162,8 @@ def get_input_path_not_found(cls, path): return MessageCode.INPUT_PATH_NOT_FOUND, message @classmethod - def get_unknown_target(cls, target): - message = 'Unknown target ("%s")' % (target) + def get_unknown_target_platform(cls, target: str): + message = "Unknown target: '" + target + "'" return MessageCode.UNKNOWN_TARGET, message @classmethod @@ -313,22 +317,13 @@ def get_different_type_rhs_lhs( return MessageCode.CAST_NOT_POSSIBLE, message @classmethod - def get_type_different_from_expected(cls, expected_type, got_type): + def get_type_different_from_expected(cls, expected_type, got_type) -> Tuple[MessageCode, str]: """ Returns a message indicating that the received type is different from the expected one. :param expected_type: the expected type - :type expected_type: TypeSymbol :param got_type: the actual type - :type got_type: type_symbol :return: a message - :rtype: (MessageCode,str) """ - from pynestml.symbols.type_symbol import TypeSymbol - assert (expected_type is not None and isinstance(expected_type, TypeSymbol)), \ - '(PyNestML.Utils.Message) Not a type symbol provided (%s)!' % type( - expected_type) - assert (got_type is not None and isinstance(got_type, TypeSymbol)), \ - '(PyNestML.Utils.Message) Not a type symbol provided (%s)!' % type(got_type) message = 'Actual type different from expected. Expected: \'%s\', got: \'%s\'!' % ( expected_type.print_symbol(), got_type.print_symbol()) return MessageCode.TYPE_DIFFERENT_FROM_EXPECTED, message @@ -430,11 +425,10 @@ def get_module_generated(cls, path: str) -> Tuple[MessageCode, str]: return MessageCode.MODULE_SUCCESSFULLY_GENERATED, message @classmethod - def get_variable_used_before_declaration(cls, variable_name): + def get_variable_used_before_declaration(cls, variable_name: str): """ Returns a message indicating that a variable is used before declaration. :param variable_name: a variable name - :type variable_name: str :return: a message :rtype: (MessageCode,str) """ @@ -701,7 +695,7 @@ def get_model_redeclared(cls, name: str) -> Tuple[MessageCode, str]: '(PyNestML.Utils.Message) Not a string provided (%s)!' % type(name) assert (name is not None and isinstance(name, str)), \ '(PyNestML.Utils.Message) Not a string provided (%s)!' % type(name) - message = 'model \'%s\' redeclared!' % name + message = 'Model \'%s\' redeclared!' % name return MessageCode.MODEL_REDECLARED, message @classmethod diff --git a/pynestml/utils/model_parser.py b/pynestml/utils/model_parser.py index 7fabf361e..62a8669bb 100644 --- a/pynestml/utils/model_parser.py +++ b/pynestml/utils/model_parser.py @@ -24,6 +24,7 @@ from antlr4 import CommonTokenStream, FileStream, InputStream from antlr4.error.ErrorStrategy import BailErrorStrategy, DefaultErrorStrategy from antlr4.error.ErrorListener import ConsoleErrorListener +from pynestml.cocos.co_cos_manager import CoCosManager from pynestml.generated.PyNestMLLexer import PyNestMLLexer from pynestml.generated.PyNestMLParser import PyNestMLParser @@ -65,6 +66,7 @@ from pynestml.meta_model.ast_variable import ASTVariable from pynestml.meta_model.ast_while_stmt import ASTWhileStmt from pynestml.symbol_table.symbol_table import SymbolTable +from pynestml.transformers.assign_implicit_conversion_factors_transformer import AssignImplicitConversionFactorsTransformer from pynestml.utils.ast_source_location import ASTSourceLocation from pynestml.utils.error_listener import NestMLErrorListener from pynestml.utils.logger import Logger, LoggingLevel @@ -142,10 +144,14 @@ def parse_file(cls, file_path=None): for model in ast.get_model_list(): model.accept(ASTSymbolTableVisitor()) SymbolTable.add_model_scope(model.get_name(), model.get_scope()) + Logger.set_current_node(model) + AssignImplicitConversionFactorsTransformer().transform(model) + Logger.set_current_node(None) # store source paths for model in ast.get_model_list(): model.file_path = file_path + ast.file_path = file_path return ast diff --git a/pynestml/utils/type_caster.py b/pynestml/utils/type_caster.py index 34e4e6ccc..4ce2624dd 100644 --- a/pynestml/utils/type_caster.py +++ b/pynestml/utils/type_caster.py @@ -28,12 +28,11 @@ class TypeCaster: @staticmethod def do_magnitude_conversion_rhs_to_lhs(_rhs_type_symbol, _lhs_type_symbol, _containing_expression): """ - determine conversion factor from rhs to lhs, register it with the relevant expression + Determine conversion factor from rhs to lhs, register it with the relevant expression """ _containing_expression.set_implicit_conversion_factor( - UnitTypeSymbol.get_conversion_factor(_lhs_type_symbol.astropy_unit, - _rhs_type_symbol.astropy_unit)) - _containing_expression.type = _lhs_type_symbol + UnitTypeSymbol.get_conversion_factor(_rhs_type_symbol.astropy_unit, + _lhs_type_symbol.astropy_unit)) code, message = Messages.get_implicit_magnitude_conversion(_lhs_type_symbol, _rhs_type_symbol, _containing_expression.get_implicit_conversion_factor()) Logger.log_message(code=code, message=message, @@ -45,18 +44,26 @@ def try_to_recover_or_error(_lhs_type_symbol, _rhs_type_symbol, _containing_expr if _rhs_type_symbol.is_castable_to(_lhs_type_symbol): if isinstance(_lhs_type_symbol, UnitTypeSymbol) \ and isinstance(_rhs_type_symbol, UnitTypeSymbol): - conversion_factor = UnitTypeSymbol.get_conversion_factor( - _lhs_type_symbol.astropy_unit, _rhs_type_symbol.astropy_unit) + conversion_factor = UnitTypeSymbol.get_conversion_factor(_rhs_type_symbol.astropy_unit, _lhs_type_symbol.astropy_unit) + + if conversion_factor is None: + # error during conversion + code, message = Messages.get_type_different_from_expected(_lhs_type_symbol, _rhs_type_symbol) + Logger.log_message(error_position=_containing_expression.get_source_position(), + code=code, message=message, log_level=LoggingLevel.ERROR) + return + if not conversion_factor == 1.: # the units are mutually convertible, but require a factor unequal to 1 (e.g. mV and A*Ohm) - TypeCaster.do_magnitude_conversion_rhs_to_lhs( - _rhs_type_symbol, _lhs_type_symbol, _containing_expression) + TypeCaster.do_magnitude_conversion_rhs_to_lhs(_rhs_type_symbol, _lhs_type_symbol, _containing_expression) + # the units are mutually convertible (e.g. V and A*Ohm) code, message = Messages.get_implicit_cast_rhs_to_lhs(_rhs_type_symbol.print_symbol(), _lhs_type_symbol.print_symbol()) Logger.log_message(error_position=_containing_expression.get_source_position(), code=code, message=message, log_level=LoggingLevel.INFO) - else: - code, message = Messages.get_type_different_from_expected(_lhs_type_symbol, _rhs_type_symbol) - Logger.log_message(error_position=_containing_expression.get_source_position(), - code=code, message=message, log_level=LoggingLevel.ERROR) + return + + code, message = Messages.get_type_different_from_expected(_lhs_type_symbol, _rhs_type_symbol) + Logger.log_message(error_position=_containing_expression.get_source_position(), + code=code, message=message, log_level=LoggingLevel.ERROR) diff --git a/pynestml/visitors/ast_builder_visitor.py b/pynestml/visitors/ast_builder_visitor.py index 0e766d530..bfc4dd902 100644 --- a/pynestml/visitors/ast_builder_visitor.py +++ b/pynestml/visitors/ast_builder_visitor.py @@ -52,16 +52,17 @@ def visitNestMLCompilationUnit(self, ctx): models = list() for child in ctx.model(): models.append(self.visit(child)) + # extract the name of the artifact from the context if hasattr(ctx.start.source[1], 'fileName'): artifact_name = ntpath.basename(ctx.start.source[1].fileName) else: artifact_name = 'parsed_from_string' + compilation_unit = ASTNodeFactory.create_ast_nestml_compilation_unit(list_of_models=models, source_position=create_source_pos(ctx), artifact_name=artifact_name) - # first ensure certain properties of the model - CoCosManager.check_model_names_unique(compilation_unit) + return compilation_unit # Visit a parse tree produced by PyNESTMLParser#datatype. @@ -387,15 +388,6 @@ def visitDeclaration(self, ctx): expression = self.visit(ctx.rhs) if ctx.rhs is not None else None invariant = self.visit(ctx.invariant) if ctx.invariant is not None else None - # print("Visiting variable \"" + str(str(ctx.NAME())) + "\"...") - # # check if this variable was decorated as homogeneous - # import pynestml.generated.PyNestMLLexer - # is_homogeneous = any([isinstance(ch, pynestml.generated.PyNestMLParser.PyNestMLParser.AnyDecoratorContext) \ - # and len(ch.getTokens(pynestml.generated.PyNestMLLexer.PyNestMLLexer.DECORATOR_HOMOGENEOUS)) > 0 \ - # for ch in ctx.parentCtx.children]) - # if is_homogeneous: - # print("\t----> is homogeneous") - declaration = ASTNodeFactory.create_ast_declaration(is_recordable=is_recordable, variables=variables, data_type=data_type, diff --git a/pynestml/visitors/ast_function_call_visitor.py b/pynestml/visitors/ast_function_call_visitor.py index 7d7bf75c4..e4ec8650e 100644 --- a/pynestml/visitors/ast_function_call_visitor.py +++ b/pynestml/visitors/ast_function_call_visitor.py @@ -94,7 +94,6 @@ def visit_simple_expression(self, node: ASTSimpleExpression) -> None: # return type of the convolve function is the type of the second parameter multiplied by the unit of time (s) if function_name == PredefinedFunctions.CONVOLVE: - # Deviations from the assumptions made here are handled in the convolveCoco buffer_parameter = node.get_function_call().get_args()[1] if buffer_parameter.get_variable() is not None: diff --git a/pynestml/visitors/ast_symbol_table_visitor.py b/pynestml/visitors/ast_symbol_table_visitor.py index 011182543..bc85d4cdd 100644 --- a/pynestml/visitors/ast_symbol_table_visitor.py +++ b/pynestml/visitors/ast_symbol_table_visitor.py @@ -19,7 +19,6 @@ # You should have received a copy of the GNU General Public License # along with NEST. If not, see . -from pynestml.cocos.co_cos_manager import CoCosManager from pynestml.meta_model.ast_model import ASTModel from pynestml.meta_model.ast_model_body import ASTModelBody from pynestml.meta_model.ast_namespace_decorator import ASTNamespaceDecorator @@ -53,7 +52,6 @@ def __init__(self): self.symbol_stack = Stack() self.scope_stack = Stack() self.block_type_stack = Stack() - self.after_ast_rewrite_ = False def visit_model(self, node: ASTModel) -> None: """ @@ -79,10 +77,6 @@ def visit_model(self, node: ASTModel) -> None: node.get_scope().add_symbol(types[symbol]) def endvisit_model(self, node: ASTModel): - # before following checks occur, we need to ensure several simple properties - CoCosManager.post_symbol_table_builder_checks( - node, after_ast_rewrite=self.after_ast_rewrite_) - # update the equations for equation_block in node.get_equations_blocks(): ASTUtils.assign_ode_to_variables(equation_block) @@ -287,8 +281,7 @@ def visit_declaration(self, node: ASTDeclaration) -> None: namespace_decorators = {} for d in node.get_decorators(): if isinstance(d, ASTNamespaceDecorator): - namespace_decorators[str(d.get_namespace())] = str( - d.get_name()) + namespace_decorators[str(d.get_namespace())] = str(d.get_name()) else: decorators.append(d) @@ -296,6 +289,7 @@ def visit_declaration(self, node: ASTDeclaration) -> None: block_type = None if not self.block_type_stack.is_empty(): block_type = self.block_type_stack.top() + for var in node.get_variables(): # for all variables declared create a new symbol var.update_scope(node.get_scope()) @@ -324,11 +318,14 @@ def visit_declaration(self, node: ASTDeclaration) -> None: symbol.set_comment(node.get_comment()) node.get_scope().add_symbol(symbol) var.set_type_symbol(type_symbol) + # the data type node.get_data_type().update_scope(node.get_scope()) + # the rhs update if node.has_expression(): node.get_expression().update_scope(node.get_scope()) + # the invariant update if node.has_invariant(): node.get_invariant().update_scope(node.get_scope()) diff --git a/tests/cocos_test.py b/tests/cocos_test.py deleted file mode 100644 index f557faaf0..000000000 --- a/tests/cocos_test.py +++ /dev/null @@ -1,698 +0,0 @@ -# -*- coding: utf-8 -*- -# -# cocos_test.py -# -# This file is part of NEST. -# -# Copyright (C) 2004 The NEST Initiative -# -# NEST is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 2 of the License, or -# (at your option) any later version. -# -# NEST is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with NEST. If not, see . - -from __future__ import print_function - -import os -import unittest - -from pynestml.utils.ast_source_location import ASTSourceLocation -from pynestml.symbol_table.symbol_table import SymbolTable -from pynestml.symbols.predefined_functions import PredefinedFunctions -from pynestml.symbols.predefined_types import PredefinedTypes -from pynestml.symbols.predefined_units import PredefinedUnits -from pynestml.symbols.predefined_variables import PredefinedVariables -from pynestml.utils.logger import LoggingLevel, Logger -from pynestml.utils.model_parser import ModelParser - - -class CoCosTest(unittest.TestCase): - - def setUp(self): - Logger.init_logger(LoggingLevel.INFO) - SymbolTable.initialize_symbol_table( - ASTSourceLocation( - start_line=0, - start_column=0, - end_line=0, - end_column=0)) - PredefinedUnits.register_units() - PredefinedTypes.register_types() - PredefinedVariables.register_variables() - PredefinedFunctions.register_functions() - - def test_invalid_element_defined_after_usage(self): - Logger.set_logging_level(LoggingLevel.INFO) - model = ModelParser.parse_file( - os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'invalid')), - 'CoCoVariableDefinedAfterUsage.nestml')) - self.assertEqual(len( - Logger.get_all_messages_of_level_and_or_node(model.get_model_list()[0], LoggingLevel.ERROR)), 1) - - def test_valid_element_defined_after_usage(self): - Logger.set_logging_level(LoggingLevel.INFO) - model = ModelParser.parse_file( - os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'valid')), - 'CoCoVariableDefinedAfterUsage.nestml')) - self.assertEqual(len( - Logger.get_all_messages_of_level_and_or_node(model.get_model_list()[0], LoggingLevel.ERROR)), 0) - - def test_invalid_element_in_same_line(self): - Logger.set_logging_level(LoggingLevel.INFO) - model = ModelParser.parse_file( - os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'invalid')), - 'CoCoElementInSameLine.nestml')) - self.assertEqual(len( - Logger.get_all_messages_of_level_and_or_node(model.get_model_list()[0], LoggingLevel.ERROR)), 1) - - def test_valid_element_in_same_line(self): - Logger.set_logging_level(LoggingLevel.INFO) - model = ModelParser.parse_file( - os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'valid')), - 'CoCoElementInSameLine.nestml')) - self.assertEqual(len( - Logger.get_all_messages_of_level_and_or_node(model.get_model_list()[0], LoggingLevel.ERROR)), 0) - - def test_invalid_integrate_odes_called_if_equations_defined(self): - Logger.set_logging_level(LoggingLevel.INFO) - model = ModelParser.parse_file( - os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'invalid')), - 'CoCoIntegrateOdesCalledIfEquationsDefined.nestml')) - self.assertEqual(len( - Logger.get_all_messages_of_level_and_or_node(model.get_model_list()[0], LoggingLevel.ERROR)), 1) - - def test_valid_integrate_odes_called_if_equations_defined(self): - Logger.set_logging_level(LoggingLevel.INFO) - model = ModelParser.parse_file( - os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'valid')), - 'CoCoIntegrateOdesCalledIfEquationsDefined.nestml')) - self.assertEqual(len( - Logger.get_all_messages_of_level_and_or_node(model.get_model_list()[0], LoggingLevel.ERROR)), 0) - - def test_invalid_element_not_defined_in_scope(self): - Logger.set_logging_level(LoggingLevel.INFO) - model = ModelParser.parse_file( - os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'invalid')), - 'CoCoVariableNotDefined.nestml')) - self.assertEqual(len(Logger.get_all_messages_of_level_and_or_node(model.get_model_list()[0], - LoggingLevel.ERROR)), 5) - - def test_valid_element_not_defined_in_scope(self): - Logger.set_logging_level(LoggingLevel.INFO) - model = ModelParser.parse_file( - os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'valid')), - 'CoCoVariableNotDefined.nestml')) - self.assertEqual( - len(Logger.get_all_messages_of_level_and_or_node(model.get_model_list()[0], LoggingLevel.ERROR)), - 0) - - def test_variable_with_same_name_as_unit(self): - Logger.set_logging_level(LoggingLevel.NO) - model = ModelParser.parse_file( - os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'valid')), - 'CoCoVariableWithSameNameAsUnit.nestml')) - self.assertEqual( - len(Logger.get_all_messages_of_level_and_or_node(model.get_model_list()[0], LoggingLevel.WARNING)), - 3) - - def test_invalid_variable_redeclaration(self): - Logger.set_logging_level(LoggingLevel.INFO) - model = ModelParser.parse_file( - os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'invalid')), - 'CoCoVariableRedeclared.nestml')) - self.assertEqual(len( - Logger.get_all_messages_of_level_and_or_node(model.get_model_list()[0], LoggingLevel.ERROR)), 1) - - def test_valid_variable_redeclaration(self): - Logger.set_logging_level(LoggingLevel.INFO) - model = ModelParser.parse_file( - os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'valid')), - 'CoCoVariableRedeclared.nestml')) - self.assertEqual(len( - Logger.get_all_messages_of_level_and_or_node(model.get_model_list()[0], LoggingLevel.ERROR)), 0) - - def test_invalid_each_block_unique(self): - Logger.set_logging_level(LoggingLevel.INFO) - model = ModelParser.parse_file( - os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'invalid')), - 'CoCoEachBlockUnique.nestml')) - self.assertEqual(len( - Logger.get_all_messages_of_level_and_or_node(model.get_model_list()[0], LoggingLevel.ERROR)), 2) - - def test_valid_each_block_unique(self): - Logger.set_logging_level(LoggingLevel.INFO) - model = ModelParser.parse_file( - os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'valid')), - 'CoCoEachBlockUnique.nestml')) - self.assertEqual(len( - Logger.get_all_messages_of_level_and_or_node(model.get_model_list()[0], LoggingLevel.ERROR)), 0) - - def test_invalid_function_unique_and_defined(self): - Logger.set_logging_level(LoggingLevel.INFO) - model = ModelParser.parse_file( - os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'invalid')), - 'CoCoFunctionNotUnique.nestml')) - self.assertEqual( - len(Logger.get_all_messages_of_level_and_or_node(model.get_model_list()[0], LoggingLevel.ERROR)), 5) - - def test_valid_function_unique_and_defined(self): - Logger.set_logging_level(LoggingLevel.INFO) - model = ModelParser.parse_file( - os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'valid')), - 'CoCoFunctionNotUnique.nestml')) - self.assertEqual( - len(Logger.get_all_messages_of_level_and_or_node(model.get_model_list()[0], LoggingLevel.ERROR)), 0) - - def test_invalid_inline_expressions_have_rhs(self): - Logger.set_logging_level(LoggingLevel.INFO) - model = ModelParser.parse_file( - os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'invalid')), - 'CoCoInlineExpressionHasNoRhs.nestml')) - assert model is None - - def test_valid_inline_expressions_have_rhs(self): - Logger.set_logging_level(LoggingLevel.INFO) - model = ModelParser.parse_file( - os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'valid')), - 'CoCoInlineExpressionHasNoRhs.nestml')) - self.assertEqual(len( - Logger.get_all_messages_of_level_and_or_node(model.get_model_list()[0], LoggingLevel.ERROR)), 0) - - def test_invalid_inline_expression_has_several_lhs(self): - Logger.set_logging_level(LoggingLevel.INFO) - model = ModelParser.parse_file( - os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'invalid')), - 'CoCoInlineExpressionWithSeveralLhs.nestml')) - assert model is None - - def test_valid_inline_expression_has_several_lhs(self): - Logger.set_logging_level(LoggingLevel.INFO) - model = ModelParser.parse_file( - os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'valid')), - 'CoCoInlineExpressionWithSeveralLhs.nestml')) - self.assertEqual(len( - Logger.get_all_messages_of_level_and_or_node(model.get_model_list()[0], LoggingLevel.ERROR)), 0) - - def test_invalid_no_values_assigned_to_input_ports(self): - Logger.set_logging_level(LoggingLevel.INFO) - model = ModelParser.parse_file( - os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'invalid')), - 'CoCoValueAssignedToInputPort.nestml')) - self.assertEqual(len( - Logger.get_all_messages_of_level_and_or_node(model.get_model_list()[0], LoggingLevel.ERROR)), 1) - - def test_valid_no_values_assigned_to_input_ports(self): - Logger.set_logging_level(LoggingLevel.INFO) - model = ModelParser.parse_file( - os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'valid')), - 'CoCoValueAssignedToInputPort.nestml')) - self.assertEqual(len( - Logger.get_all_messages_of_level_and_or_node(model.get_model_list()[0], LoggingLevel.ERROR)), 0) - - def test_invalid_order_of_equations_correct(self): - Logger.set_logging_level(LoggingLevel.INFO) - model = ModelParser.parse_file( - os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'invalid')), - 'CoCoNoOrderOfEquations.nestml')) - self.assertEqual(len( - Logger.get_all_messages_of_level_and_or_node(model.get_model_list()[0], LoggingLevel.ERROR)), 2) - - def test_valid_order_of_equations_correct(self): - Logger.set_logging_level(LoggingLevel.INFO) - model = ModelParser.parse_file( - os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'valid')), - 'CoCoNoOrderOfEquations.nestml')) - self.assertEqual(len( - Logger.get_all_messages_of_level_and_or_node(model.get_model_list()[0], LoggingLevel.ERROR)), 0) - - def test_invalid_numerator_of_unit_one(self): - Logger.set_logging_level(LoggingLevel.INFO) - model = ModelParser.parse_file( - os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'invalid')), - 'CoCoUnitNumeratorNotOne.nestml')) - self.assertEqual(len(Logger.get_all_messages_of_level_and_or_node(model.get_model_list()[0], - LoggingLevel.ERROR)), 2) - - def test_valid_numerator_of_unit_one(self): - Logger.set_logging_level(LoggingLevel.INFO) - model = ModelParser.parse_file( - os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'valid')), - 'CoCoUnitNumeratorNotOne.nestml')) - self.assertEqual(len( - Logger.get_all_messages_of_level_and_or_node(model.get_model_list()[0], LoggingLevel.ERROR)), 0) - - def test_invalid_names_of_neurons_unique(self): - Logger.init_logger(LoggingLevel.INFO) - ModelParser.parse_file( - os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'invalid')), - 'CoCoMultipleNeuronsWithEqualName.nestml')) - self.assertEqual(len(Logger.get_all_messages_of_level_and_or_node(None, LoggingLevel.ERROR)), 1) - - def test_valid_names_of_neurons_unique(self): - Logger.init_logger(LoggingLevel.INFO) - ModelParser.parse_file( - os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'valid')), - 'CoCoMultipleNeuronsWithEqualName.nestml')) - self.assertEqual(len(Logger.get_all_messages_of_level_and_or_node(None, LoggingLevel.ERROR)), 0) - - def test_invalid_no_nest_collision(self): - Logger.set_logging_level(LoggingLevel.INFO) - model = ModelParser.parse_file( - os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'invalid')), - 'CoCoNestNamespaceCollision.nestml')) - self.assertEqual(len( - Logger.get_all_messages_of_level_and_or_node(model.get_model_list()[0], LoggingLevel.ERROR)), 1) - - def test_valid_no_nest_collision(self): - Logger.set_logging_level(LoggingLevel.INFO) - model = ModelParser.parse_file( - os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'valid')), - 'CoCoNestNamespaceCollision.nestml')) - self.assertEqual(len( - Logger.get_all_messages_of_level_and_or_node(model.get_model_list()[0], LoggingLevel.ERROR)), 0) - - def test_invalid_redundant_input_port_keywords_detected(self): - Logger.set_logging_level(LoggingLevel.INFO) - model = ModelParser.parse_file( - os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'invalid')), - 'CoCoInputPortWithRedundantTypes.nestml')) - self.assertEqual(len( - Logger.get_all_messages_of_level_and_or_node(model.get_model_list()[0], LoggingLevel.ERROR)), 1) - - def test_valid_redundant_input_port_keywords_detected(self): - Logger.set_logging_level(LoggingLevel.INFO) - model = ModelParser.parse_file( - os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'valid')), - 'CoCoInputPortWithRedundantTypes.nestml')) - self.assertEqual(len( - Logger.get_all_messages_of_level_and_or_node(model.get_model_list()[0], LoggingLevel.ERROR)), 0) - - def test_invalid_parameters_assigned_only_in_parameters_block(self): - Logger.set_logging_level(LoggingLevel.INFO) - model = ModelParser.parse_file( - os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'invalid')), - 'CoCoParameterAssignedOutsideBlock.nestml')) - self.assertEqual(len( - Logger.get_all_messages_of_level_and_or_node(model.get_model_list()[0], LoggingLevel.ERROR)), 1) - - def test_valid_parameters_assigned_only_in_parameters_block(self): - Logger.set_logging_level(LoggingLevel.INFO) - model = ModelParser.parse_file( - os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'valid')), - 'CoCoParameterAssignedOutsideBlock.nestml')) - self.assertEqual(len( - Logger.get_all_messages_of_level_and_or_node(model.get_model_list()[0], LoggingLevel.ERROR)), 0) - - def test_invalid_inline_expressions_assigned_only_in_declaration(self): - Logger.set_logging_level(LoggingLevel.INFO) - model = ModelParser.parse_file( - os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'invalid')), - 'CoCoAssignmentToInlineExpression.nestml')) - self.assertEqual(len( - Logger.get_all_messages_of_level_and_or_node(model.get_model_list()[0], LoggingLevel.ERROR)), 1) - - def test_invalid_internals_assigned_only_in_internals_block(self): - Logger.set_logging_level(LoggingLevel.INFO) - model = ModelParser.parse_file( - os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'invalid')), - 'CoCoInternalAssignedOutsideBlock.nestml')) - self.assertEqual(len( - Logger.get_all_messages_of_level_and_or_node(model.get_model_list()[0], LoggingLevel.ERROR)), 1) - - def test_valid_internals_assigned_only_in_internals_block(self): - Logger.set_logging_level(LoggingLevel.INFO) - model = ModelParser.parse_file( - os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'valid')), - 'CoCoInternalAssignedOutsideBlock.nestml')) - self.assertEqual(len( - Logger.get_all_messages_of_level_and_or_node(model.get_model_list()[0], LoggingLevel.ERROR)), 0) - - def test_invalid_function_with_wrong_arg_number_detected(self): - Logger.set_logging_level(LoggingLevel.INFO) - model = ModelParser.parse_file( - os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'invalid')), - 'CoCoFunctionCallNotConsistentWrongArgNumber.nestml')) - self.assertEqual(len( - Logger.get_all_messages_of_level_and_or_node(model.get_model_list()[0], LoggingLevel.ERROR)), 1) - - def test_valid_function_with_wrong_arg_number_detected(self): - Logger.set_logging_level(LoggingLevel.INFO) - model = ModelParser.parse_file( - os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'valid')), - 'CoCoFunctionCallNotConsistentWrongArgNumber.nestml')) - self.assertEqual(len( - Logger.get_all_messages_of_level_and_or_node(model.get_model_list()[0], LoggingLevel.ERROR)), 0) - - def test_invalid_init_values_have_rhs_and_ode(self): - Logger.set_logging_level(LoggingLevel.INFO) - model = ModelParser.parse_file( - os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'invalid')), - 'CoCoInitValuesWithoutOde.nestml')) - self.assertEqual(len( - Logger.get_all_messages_of_level_and_or_node(model.get_model_list()[0], LoggingLevel.WARNING)), 2) - - def test_valid_init_values_have_rhs_and_ode(self): - Logger.set_logging_level(LoggingLevel.INFO) - model = ModelParser.parse_file( - os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'valid')), - 'CoCoInitValuesWithoutOde.nestml')) - self.assertEqual(len( - Logger.get_all_messages_of_level_and_or_node(model.get_model_list()[0], LoggingLevel.WARNING)), 2) - - def test_invalid_incorrect_return_stmt_detected(self): - Logger.set_logging_level(LoggingLevel.INFO) - model = ModelParser.parse_file( - os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'invalid')), - 'CoCoIncorrectReturnStatement.nestml')) - self.assertEqual(len( - Logger.get_all_messages_of_level_and_or_node(model.get_model_list()[0], LoggingLevel.ERROR)), 4) - - def test_valid_incorrect_return_stmt_detected(self): - Logger.set_logging_level(LoggingLevel.INFO) - model = ModelParser.parse_file( - os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'valid')), - 'CoCoIncorrectReturnStatement.nestml')) - self.assertEqual(len( - Logger.get_all_messages_of_level_and_or_node(model.get_model_list()[0], LoggingLevel.ERROR)), 0) - - def test_invalid_ode_vars_outside_init_block_detected(self): - Logger.set_logging_level(LoggingLevel.INFO) - model = ModelParser.parse_file( - os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'invalid')), - 'CoCoOdeVarNotInInitialValues.nestml')) - self.assertEqual(len( - Logger.get_all_messages_of_level_and_or_node(model.get_model_list()[0], LoggingLevel.ERROR)), 1) - - def test_valid_ode_vars_outside_init_block_detected(self): - Logger.set_logging_level(LoggingLevel.INFO) - model = ModelParser.parse_file( - os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'valid')), - 'CoCoOdeVarNotInInitialValues.nestml')) - self.assertEqual(len( - Logger.get_all_messages_of_level_and_or_node(model.get_model_list()[0], LoggingLevel.ERROR)), 0) - - def test_invalid_convolve_correctly_defined(self): - Logger.set_logging_level(LoggingLevel.INFO) - model = ModelParser.parse_file( - os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'invalid')), - 'CoCoConvolveNotCorrectlyProvided.nestml')) - self.assertEqual(len(Logger.get_all_messages_of_level_and_or_node(model.get_model_list()[0], - LoggingLevel.ERROR)), 3) - - def test_valid_convolve_correctly_defined(self): - Logger.set_logging_level(LoggingLevel.INFO) - model = ModelParser.parse_file( - os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'valid')), - 'CoCoConvolveNotCorrectlyProvided.nestml')) - self.assertEqual(len( - Logger.get_all_messages_of_level_and_or_node(model.get_model_list()[0], LoggingLevel.ERROR)), 0) - - def test_invalid_vector_in_non_vector_declaration_detected(self): - Logger.set_logging_level(LoggingLevel.INFO) - model = ModelParser.parse_file( - os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'invalid')), - 'CoCoVectorInNonVectorDeclaration.nestml')) - self.assertEqual(len( - Logger.get_all_messages_of_level_and_or_node(model.get_model_list()[0], LoggingLevel.ERROR)), 1) - - def test_valid_vector_in_non_vector_declaration_detected(self): - Logger.set_logging_level(LoggingLevel.INFO) - model = ModelParser.parse_file( - os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'valid')), - 'CoCoVectorInNonVectorDeclaration.nestml')) - self.assertEqual(len( - Logger.get_all_messages_of_level_and_or_node(model.get_model_list()[0], LoggingLevel.ERROR)), 0) - - def test_invalid_vector_parameter_declaration(self): - Logger.set_logging_level(LoggingLevel.INFO) - model = ModelParser.parse_file( - os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'invalid')), - 'CoCoVectorParameterDeclaration.nestml')) - self.assertEqual(len( - Logger.get_all_messages_of_level_and_or_node(model.get_model_list()[0], LoggingLevel.ERROR)), 1) - - def test_valid_vector_parameter_declaration(self): - Logger.set_logging_level(LoggingLevel.INFO) - model = ModelParser.parse_file( - os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'valid')), - 'CoCoVectorParameterDeclaration.nestml')) - self.assertEqual(len( - Logger.get_all_messages_of_level_and_or_node(model.get_model_list()[0], LoggingLevel.ERROR)), 0) - - def test_invalid_vector_parameter_type(self): - Logger.set_logging_level(LoggingLevel.INFO) - model = ModelParser.parse_file( - os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'invalid')), - 'CoCoVectorParameterType.nestml')) - self.assertEqual(len( - Logger.get_all_messages_of_level_and_or_node(model.get_model_list()[0], LoggingLevel.ERROR)), 1) - - def test_valid_vector_parameter_type(self): - Logger.set_logging_level(LoggingLevel.INFO) - model = ModelParser.parse_file( - os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'valid')), - 'CoCoVectorParameterType.nestml')) - self.assertEqual(len( - Logger.get_all_messages_of_level_and_or_node(model.get_model_list()[0], LoggingLevel.ERROR)), 0) - - def test_invalid_vector_parameter_size(self): - Logger.set_logging_level(LoggingLevel.INFO) - model = ModelParser.parse_file( - os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'invalid')), - 'CoCoVectorDeclarationSize.nestml')) - self.assertEqual(len( - Logger.get_all_messages_of_level_and_or_node(model.get_model_list()[0], LoggingLevel.ERROR)), 2) - - def test_valid_vector_parameter_size(self): - Logger.set_logging_level(LoggingLevel.INFO) - model = ModelParser.parse_file( - os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'valid')), - 'CoCoVectorDeclarationSize.nestml')) - self.assertEqual(len( - Logger.get_all_messages_of_level_and_or_node(model.get_model_list()[0], LoggingLevel.ERROR)), 0) - - def test_invalid_convolve_correctly_parameterized(self): - Logger.set_logging_level(LoggingLevel.INFO) - model = ModelParser.parse_file( - os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'invalid')), - 'CoCoConvolveNotCorrectlyParametrized.nestml')) - self.assertEqual(len( - Logger.get_all_messages_of_level_and_or_node(model.get_model_list()[0], LoggingLevel.ERROR)), 2) - - def test_valid_convolve_correctly_parameterized(self): - Logger.set_logging_level(LoggingLevel.INFO) - model = ModelParser.parse_file( - os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'valid')), - 'CoCoConvolveNotCorrectlyParametrized.nestml')) - self.assertEqual(len(Logger.get_all_messages_of_level_and_or_node(model.get_model_list()[0], - LoggingLevel.ERROR)), 0) - - def test_invalid_invariant_correctly_typed(self): - Logger.set_logging_level(LoggingLevel.INFO) - model = ModelParser.parse_file( - os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'invalid')), - 'CoCoInvariantNotBool.nestml')) - self.assertEqual(len( - Logger.get_all_messages_of_level_and_or_node(model.get_model_list()[0], LoggingLevel.ERROR)), 1) - - def test_valid_invariant_correctly_typed(self): - Logger.set_logging_level(LoggingLevel.INFO) - model = ModelParser.parse_file( - os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'valid')), - 'CoCoInvariantNotBool.nestml')) - self.assertEqual(len( - Logger.get_all_messages_of_level_and_or_node(model.get_model_list()[0], LoggingLevel.ERROR)), 0) - - def test_invalid_expression_correctly_typed(self): - Logger.set_logging_level(LoggingLevel.INFO) - model = ModelParser.parse_file( - os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'invalid')), - 'CoCoIllegalExpression.nestml')) - self.assertEqual(len(Logger.get_all_messages_of_level_and_or_node(model.get_model_list()[0], - LoggingLevel.ERROR)), 6) - - def test_valid_expression_correctly_typed(self): - Logger.set_logging_level(LoggingLevel.INFO) - model = ModelParser.parse_file( - os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'valid')), - 'CoCoIllegalExpression.nestml')) - self.assertEqual(len( - Logger.get_all_messages_of_level_and_or_node(model.get_model_list()[0], LoggingLevel.ERROR)), 0) - - def test_invalid_compound_expression_correctly_typed(self): - Logger.set_logging_level(LoggingLevel.INFO) - model = ModelParser.parse_file( - os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'invalid')), - 'CompoundOperatorWithDifferentButCompatibleUnits.nestml')) - self.assertEqual(len( - Logger.get_all_messages_of_level_and_or_node(model.get_model_list()[0], LoggingLevel.ERROR)), 5) - - def test_valid_compound_expression_correctly_typed(self): - Logger.set_logging_level(LoggingLevel.INFO) - model = ModelParser.parse_file( - os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'valid')), - 'CompoundOperatorWithDifferentButCompatibleUnits.nestml')) - self.assertEqual(len( - Logger.get_all_messages_of_level_and_or_node(model.get_model_list()[0], LoggingLevel.ERROR)), 0) - - def test_invalid_ode_correctly_typed(self): - Logger.set_logging_level(LoggingLevel.INFO) - model = ModelParser.parse_file( - os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'invalid')), - 'CoCoOdeIncorrectlyTyped.nestml')) - self.assertTrue(len(Logger.get_all_messages_of_level_and_or_node(model.get_model_list()[0], - LoggingLevel.ERROR)) > 0) - - def test_valid_ode_correctly_typed(self): - Logger.set_logging_level(LoggingLevel.INFO) - model = ModelParser.parse_file( - os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'valid')), - 'CoCoOdeCorrectlyTyped.nestml')) - self.assertEqual(len( - Logger.get_all_messages_of_level_and_or_node(model.get_model_list()[0], LoggingLevel.ERROR)), 0) - - def test_invalid_output_block_defined_if_emit_call(self): - """test that an error is raised when the emit_spike() function is called by the neuron, but an output block is not defined""" - Logger.set_logging_level(LoggingLevel.INFO) - model = ModelParser.parse_file( - os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'invalid')), - 'CoCoOutputPortDefinedIfEmitCall.nestml')) - self.assertTrue(len(Logger.get_all_messages_of_level_and_or_node(model.get_model_list()[0], - LoggingLevel.ERROR)) > 0) - - def test_invalid_output_port_defined_if_emit_call(self): - """test that an error is raised when the emit_spike() function is called by the neuron, but a spiking output port is not defined""" - Logger.set_logging_level(LoggingLevel.INFO) - model = ModelParser.parse_file( - os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'invalid')), - 'CoCoOutputPortDefinedIfEmitCall-2.nestml')) - self.assertTrue(len(Logger.get_all_messages_of_level_and_or_node(model.get_model_list()[0], - LoggingLevel.ERROR)) > 0) - - def test_valid_output_port_defined_if_emit_call(self): - """test that no error is raised when the output block is missing, but not emit_spike() functions are called""" - Logger.set_logging_level(LoggingLevel.INFO) - model = ModelParser.parse_file( - os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'valid')), - 'CoCoOutputPortDefinedIfEmitCall.nestml')) - self.assertEqual(len( - Logger.get_all_messages_of_level_and_or_node(model.get_model_list()[0], LoggingLevel.ERROR)), 0) - - def test_valid_coco_kernel_type(self): - """ - Test the functionality of CoCoKernelType. - """ - Logger.set_logging_level(LoggingLevel.INFO) - model = ModelParser.parse_file( - os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'valid')), - 'CoCoKernelType.nestml')) - self.assertEqual(len( - Logger.get_all_messages_of_level_and_or_node(model.get_model_list()[0], LoggingLevel.ERROR)), 0) - - def test_invalid_coco_kernel_type(self): - """ - Test the functionality of CoCoKernelType. - """ - Logger.set_logging_level(LoggingLevel.INFO) - model = ModelParser.parse_file( - os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'invalid')), - 'CoCoKernelType.nestml')) - self.assertEqual(len( - Logger.get_all_messages_of_level_and_or_node(model.get_model_list()[0], LoggingLevel.ERROR)), 1) - - def test_invalid_coco_kernel_type_initial_values(self): - """ - Test the functionality of CoCoKernelType. - """ - Logger.set_logging_level(LoggingLevel.INFO) - model = ModelParser.parse_file( - os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'invalid')), - 'CoCoKernelTypeInitialValues.nestml')) - self.assertEqual(len( - Logger.get_all_messages_of_level_and_or_node(model.get_model_list()[0], LoggingLevel.ERROR)), 4) - - def test_valid_coco_state_variables_initialized(self): - """ - Test that the CoCo condition is applicable for all the variables in the state block initialized with a value - """ - Logger.set_logging_level(LoggingLevel.INFO) - model = ModelParser.parse_file( - os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'valid')), - 'CoCoStateVariablesInitialized.nestml')) - self.assertEqual(len( - Logger.get_all_messages_of_level_and_or_node(model.get_model_list()[0], LoggingLevel.ERROR)), 0) - - def test_invalid_coco_state_variables_initialized(self): - """ - Test that the CoCo condition is applicable for all the variables in the state block not initialized - """ - Logger.set_logging_level(LoggingLevel.INFO) - model = ModelParser.parse_file( - os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'invalid')), - 'CoCoStateVariablesInitialized.nestml')) - self.assertEqual(len( - Logger.get_all_messages_of_level_and_or_node(model.get_model_list()[0], LoggingLevel.ERROR)), 2) - - def test_invalid_co_co_priorities_correctly_specified(self): - """ - """ - Logger.set_logging_level(LoggingLevel.INFO) - model = ModelParser.parse_file( - os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'invalid')), - 'CoCoPrioritiesCorrectlySpecified.nestml')) - self.assertEqual(len( - Logger.get_all_messages_of_level_and_or_node(model.get_model_list()[0], LoggingLevel.ERROR)), 1) - - def test_valid_co_co_priorities_correctly_specified(self): - """ - """ - Logger.set_logging_level(LoggingLevel.INFO) - model = ModelParser.parse_file( - os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'valid')), - 'CoCoPrioritiesCorrectlySpecified.nestml')) - self.assertEqual(len( - Logger.get_all_messages_of_level_and_or_node(model.get_model_list()[0], LoggingLevel.ERROR)), 0) - - def test_invalid_co_co_resolution_legally_used(self): - """ - """ - Logger.set_logging_level(LoggingLevel.INFO) - model = ModelParser.parse_file( - os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'invalid')), - 'CoCoResolutionLegallyUsed.nestml')) - self.assertEqual(len( - Logger.get_all_messages_of_level_and_or_node(model.get_model_list()[0], LoggingLevel.ERROR)), 2) - - def test_valid_co_co_resolution_legally_used(self): - """ - """ - Logger.set_logging_level(LoggingLevel.INFO) - model = ModelParser.parse_file( - os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'valid')), - 'CoCoResolutionLegallyUsed.nestml')) - self.assertEqual(len( - Logger.get_all_messages_of_level_and_or_node(model.get_model_list()[0], LoggingLevel.ERROR)), 0) - - def test_valid_co_co_vector_input_port(self): - Logger.set_logging_level(LoggingLevel.INFO) - model = ModelParser.parse_file( - os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'valid')), - 'CoCoVectorInputPortSizeAndType.nestml')) - self.assertEqual(len( - Logger.get_all_messages_of_level_and_or_node(model.get_model_list()[0], LoggingLevel.ERROR)), 0) - - def test_invalid_co_co_vector_input_port(self): - Logger.set_logging_level(LoggingLevel.INFO) - model = ModelParser.parse_file( - os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'invalid')), - 'CoCoVectorInputPortSizeAndType.nestml')) - self.assertEqual(len( - Logger.get_all_messages_of_level_and_or_node(model.get_model_list()[0], LoggingLevel.ERROR)), 1) diff --git a/tests/function_parameter_templating_test.py b/tests/function_parameter_templating_test.py deleted file mode 100644 index e3cb89e41..000000000 --- a/tests/function_parameter_templating_test.py +++ /dev/null @@ -1,57 +0,0 @@ -# -*- coding: utf-8 -*- -# -# function_parameter_templating_test.py -# -# This file is part of NEST. -# -# Copyright (C) 2004 The NEST Initiative -# -# NEST is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 2 of the License, or -# (at your option) any later version. -# -# NEST is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with NEST. If not, see . - -import os -import unittest - -from pynestml.symbol_table.symbol_table import SymbolTable -from pynestml.symbols.predefined_functions import PredefinedFunctions -from pynestml.symbols.predefined_types import PredefinedTypes -from pynestml.symbols.predefined_units import PredefinedUnits -from pynestml.symbols.predefined_variables import PredefinedVariables -from pynestml.utils.ast_source_location import ASTSourceLocation -from pynestml.utils.logger import Logger, LoggingLevel -from pynestml.utils.model_parser import ModelParser - -# minor setup steps required -SymbolTable.initialize_symbol_table(ASTSourceLocation(start_line=0, start_column=0, end_line=0, end_column=0)) -PredefinedUnits.register_units() -PredefinedTypes.register_types() -PredefinedVariables.register_variables() -PredefinedFunctions.register_functions() - - -class FunctionParameterTemplatingTest(unittest.TestCase): - """ - This test is used to test the correct derivation of types when functions use templated type parameters. - """ - - def test(self): - Logger.init_logger(LoggingLevel.INFO) - model = ModelParser.parse_file( - os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), - "resources", "FunctionParameterTemplatingTest.nestml")))) - self.assertEqual(len(Logger.get_all_messages_of_level_and_or_node(model.get_model_list()[0], - LoggingLevel.ERROR)), 7) - - -if __name__ == '__main__': - unittest.main() diff --git a/tests/nest_compartmental_tests/test__cocos.py b/tests/nest_compartmental_tests/test__cocos.py index dc4daa28c..7ee55f8a1 100644 --- a/tests/nest_compartmental_tests/test__cocos.py +++ b/tests/nest_compartmental_tests/test__cocos.py @@ -21,41 +21,39 @@ from __future__ import print_function +from typing import Optional + import os import pytest -from pynestml.frontend.frontend_configuration import FrontendConfiguration - -from pynestml.utils.ast_source_location import ASTSourceLocation +from pynestml.meta_model.ast_model import ASTModel from pynestml.symbol_table.symbol_table import SymbolTable from pynestml.symbols.predefined_functions import PredefinedFunctions from pynestml.symbols.predefined_types import PredefinedTypes from pynestml.symbols.predefined_units import PredefinedUnits from pynestml.symbols.predefined_variables import PredefinedVariables +from pynestml.utils.ast_source_location import ASTSourceLocation from pynestml.utils.logger import LoggingLevel, Logger from pynestml.utils.model_parser import ModelParser -@pytest.fixture -def setUp(): - Logger.init_logger(LoggingLevel.INFO) - SymbolTable.initialize_symbol_table( - ASTSourceLocation( - start_line=0, - start_column=0, - end_line=0, - end_column=0)) - PredefinedUnits.register_units() - PredefinedTypes.register_types() - PredefinedVariables.register_variables() - PredefinedFunctions.register_functions() - FrontendConfiguration.target_platform = "NEST_COMPARTMENTAL" - - class TestCoCos: - def test_invalid_cm_variables_declared(self, setUp): - model = ModelParser.parse_file( + @pytest.fixture(scope="module", autouse=True) + def setUp(self): + SymbolTable.initialize_symbol_table( + ASTSourceLocation( + start_line=0, + start_column=0, + end_line=0, + end_column=0)) + PredefinedUnits.register_units() + PredefinedTypes.register_types() + PredefinedVariables.register_variables() + PredefinedFunctions.register_functions() + + def test_invalid_cm_variables_declared(self): + model = self._parse_and_validate_model( os.path.join( os.path.realpath( os.path.join( @@ -63,11 +61,10 @@ def test_invalid_cm_variables_declared(self, setUp): 'invalid')), 'CoCoCmVariablesDeclared.nestml')) assert len(Logger.get_all_messages_of_level_and_or_node( - model.get_model_list()[0], LoggingLevel.ERROR)) == 5 + model, LoggingLevel.ERROR)) == 6 - def test_valid_cm_variables_declared(self, setUp): - Logger.set_logging_level(LoggingLevel.INFO) - model = ModelParser.parse_file( + def test_valid_cm_variables_declared(self): + model = self._parse_and_validate_model( os.path.join( os.path.realpath( os.path.join( @@ -75,12 +72,12 @@ def test_valid_cm_variables_declared(self, setUp): 'valid')), 'CoCoCmVariablesDeclared.nestml')) assert len(Logger.get_all_messages_of_level_and_or_node( - model.get_model_list()[0], LoggingLevel.ERROR)) == 0 + model, LoggingLevel.ERROR)) == 0 # it is currently not enforced for the non-cm parameter block, but cm # needs that - def test_invalid_cm_variable_has_rhs(self, setUp): - model = ModelParser.parse_file( + def test_invalid_cm_variable_has_rhs(self): + model = self._parse_and_validate_model( os.path.join( os.path.realpath( os.path.join( @@ -88,11 +85,11 @@ def test_invalid_cm_variable_has_rhs(self, setUp): 'invalid')), 'CoCoCmVariableHasRhs.nestml')) assert len(Logger.get_all_messages_of_level_and_or_node( - model.get_model_list()[0], LoggingLevel.ERROR)) == 2 + model, LoggingLevel.ERROR)) == 2 - def test_valid_cm_variable_has_rhs(self, setUp): + def test_valid_cm_variable_has_rhs(self): Logger.set_logging_level(LoggingLevel.INFO) - model = ModelParser.parse_file( + model = self._parse_and_validate_model( os.path.join( os.path.realpath( os.path.join( @@ -100,12 +97,12 @@ def test_valid_cm_variable_has_rhs(self, setUp): 'valid')), 'CoCoCmVariableHasRhs.nestml')) assert len(Logger.get_all_messages_of_level_and_or_node( - model.get_model_list()[0], LoggingLevel.ERROR)) == 0 + model, LoggingLevel.ERROR)) == 0 # it is currently not enforced for the non-cm parameter block, but cm # needs that - def test_invalid_cm_v_comp_exists(self, setUp): - model = ModelParser.parse_file( + def test_invalid_cm_v_comp_exists(self): + model = self._parse_and_validate_model( os.path.join( os.path.realpath( os.path.join( @@ -113,11 +110,11 @@ def test_invalid_cm_v_comp_exists(self, setUp): 'invalid')), 'CoCoCmVcompExists.nestml')) assert len(Logger.get_all_messages_of_level_and_or_node( - model.get_model_list()[0], LoggingLevel.ERROR)) == 4 + model, LoggingLevel.ERROR)) == 4 - def test_valid_cm_v_comp_exists(self, setUp): + def test_valid_cm_v_comp_exists(self): Logger.set_logging_level(LoggingLevel.INFO) - model = ModelParser.parse_file( + model = self._parse_and_validate_model( os.path.join( os.path.realpath( os.path.join( @@ -125,4 +122,23 @@ def test_valid_cm_v_comp_exists(self, setUp): 'valid')), 'CoCoCmVcompExists.nestml')) assert len(Logger.get_all_messages_of_level_and_or_node( - model.get_model_list()[0], LoggingLevel.ERROR)) == 0 + model, LoggingLevel.ERROR)) == 0 + + def _parse_and_validate_model(self, fname: str) -> Optional[str]: + from pynestml.frontend.pynestml_frontend import generate_target + + Logger.init_logger(LoggingLevel.DEBUG) + + try: + generate_target(input_path=fname, target_platform="NONE", logging_level="DEBUG") + except BaseException: + return None + + ast_compilation_unit = ModelParser.parse_file(fname) + if ast_compilation_unit is None or len(ast_compilation_unit.get_model_list()) == 0: + return None + + model: ASTModel = ast_compilation_unit.get_model_list()[0] + model_name = model.get_name() + + return model_name diff --git a/tests/nest_tests/nest_delay_based_variables_test.py b/tests/nest_tests/nest_delay_based_variables_test.py index 51f863e19..a11c280f2 100644 --- a/tests/nest_tests/nest_delay_based_variables_test.py +++ b/tests/nest_tests/nest_delay_based_variables_test.py @@ -19,13 +19,12 @@ # You should have received a copy of the GNU General Public License # along with NEST. If not, see . +from typing import List + import numpy as np import os -from typing import List import pytest -import nest - try: import matplotlib import matplotlib.pyplot as plt @@ -34,15 +33,12 @@ except BaseException: TEST_PLOTS = False +import nest + from pynestml.codegeneration.nest_tools import NESTTools from pynestml.frontend.pynestml_frontend import generate_nest_target -target_path = "target_delay" -logging_level = "DEBUG" -suffix = "_nestml" - - def plot_fig(times, recordable_events_delay: dict, recordable_events: dict, filename: str): fig, axes = plt.subplots(len(recordable_events), 1, figsize=(7, 9), sharex=True) for i, recordable_name in enumerate(recordable_events_delay.keys()): @@ -86,6 +82,9 @@ def run_simulation(neuron_model_name: str, module_name: str, recordables: List[s ("DelayDifferentialEquationsWithNumericSolver.nestml", "dde_numeric_nestml", ["x", "z"]), ("DelayDifferentialEquationsWithMixedSolver.nestml", "dde_mixed_nestml", ["x", "z"])]) def test_dde_with_analytic_solver(file_name: str, neuron_model_name: str, recordables: List[str]): + target_path = "target_delay" + logging_level = "DEBUG" + suffix = "_nestml" input_path = os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), "resources", file_name))) module_name = neuron_model_name + "_module" print("Module name: ", module_name) @@ -112,16 +111,3 @@ def test_dde_with_analytic_solver(file_name: str, neuron_model_name: str, record if neuron_model_name == "dde_analytic_nestml": np.testing.assert_allclose(recordable_events_delay[recordables[1]][int(delay):], recordable_events[recordables[1]][:-int(delay)]) - - @pytest.fixture(scope="function", autouse=True) - def cleanup(self): - # Run the test - yield - - # clean up - import shutil - if self.target_path: - try: - shutil.rmtree(self.target_path) - except Exception: - pass diff --git a/tests/nest_tests/resources/integrate_odes_test_params.nestml b/tests/nest_tests/resources/integrate_odes_test_params.nestml index d07fe8fd4..d6430e537 100644 --- a/tests/nest_tests/resources/integrate_odes_test_params.nestml +++ b/tests/nest_tests/resources/integrate_odes_test_params.nestml @@ -8,7 +8,6 @@ model integrate_odes_test: update: integrate_odes(2 * test_1) - integrate_odes(test_3) integrate_odes(100 ms) integrate_odes(test_1) integrate_odes(test_2) diff --git a/tests/nest_tests/resources/integrate_odes_test_params2.nestml b/tests/nest_tests/resources/integrate_odes_test_params2.nestml new file mode 100644 index 000000000..616401e48 --- /dev/null +++ b/tests/nest_tests/resources/integrate_odes_test_params2.nestml @@ -0,0 +1,10 @@ +""" +Model for testing the integrate_odes() function. +""" +model integrate_odes_test: + state: + test_1 real = 0. + test_2 real = 0. + + update: + integrate_odes(test_3) diff --git a/tests/nest_tests/test_integrate_odes.py b/tests/nest_tests/test_integrate_odes.py index 99b94c6ca..6ddb699b4 100644 --- a/tests/nest_tests/test_integrate_odes.py +++ b/tests/nest_tests/test_integrate_odes.py @@ -27,16 +27,9 @@ import nest -from pynestml.utils.ast_source_location import ASTSourceLocation -from pynestml.symbol_table.symbol_table import SymbolTable -from pynestml.symbols.predefined_functions import PredefinedFunctions -from pynestml.symbols.predefined_types import PredefinedTypes -from pynestml.symbols.predefined_units import PredefinedUnits -from pynestml.symbols.predefined_variables import PredefinedVariables from pynestml.codegeneration.nest_tools import NESTTools -from pynestml.frontend.pynestml_frontend import generate_nest_target +from pynestml.frontend.pynestml_frontend import generate_nest_target, generate_target from pynestml.utils.logger import LoggingLevel, Logger -from pynestml.utils.model_parser import ModelParser try: import matplotlib @@ -227,12 +220,15 @@ def test_integrate_odes_nonlinear(self): def test_integrate_odes_params(self): r"""Test the integrate_odes() function, in particular with respect to the parameter types.""" - Logger.init_logger(LoggingLevel.INFO) - SymbolTable.initialize_symbol_table(ASTSourceLocation(start_line=0, start_column=0, end_line=0, end_column=0)) - PredefinedUnits.register_units() - PredefinedTypes.register_types() - PredefinedVariables.register_variables() - PredefinedFunctions.register_functions() - Logger.set_logging_level(LoggingLevel.INFO) - model = ModelParser.parse_file(os.path.realpath(os.path.join(os.path.dirname(__file__), os.path.join("resources", "integrate_odes_test_params.nestml")))) - assert len(Logger.get_all_messages_of_level_and_or_node(model.get_model_list()[0], LoggingLevel.ERROR)) == 6 + fname = os.path.realpath(os.path.join(os.path.dirname(__file__), os.path.join("resources", "integrate_odes_test_params.nestml"))) + generate_target(input_path=fname, target_platform="NONE", logging_level="DEBUG") + + assert len(Logger.get_all_messages_of_level_and_or_node("integrate_odes_test", LoggingLevel.ERROR)) == 2 + + def test_integrate_odes_params2(self): + r"""Test the integrate_odes() function, in particular with respect to non-existent parameter variables.""" + + fname = os.path.realpath(os.path.join(os.path.dirname(__file__), os.path.join("resources", "integrate_odes_test_params2.nestml"))) + generate_target(input_path=fname, target_platform="NONE", logging_level="DEBUG") + + assert len(Logger.get_all_messages_of_level_and_or_node("integrate_odes_test", LoggingLevel.ERROR)) == 2 diff --git a/tests/test_cocos.py b/tests/test_cocos.py new file mode 100644 index 000000000..81f519eaf --- /dev/null +++ b/tests/test_cocos.py @@ -0,0 +1,403 @@ +# -*- coding: utf-8 -*- +# +# test_cocos.py +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . + +from __future__ import print_function + +from typing import Optional + +import os +import pytest + +from pynestml.meta_model.ast_model import ASTModel +from pynestml.symbol_table.symbol_table import SymbolTable +from pynestml.symbols.predefined_functions import PredefinedFunctions +from pynestml.symbols.predefined_types import PredefinedTypes +from pynestml.symbols.predefined_units import PredefinedUnits +from pynestml.symbols.predefined_variables import PredefinedVariables +from pynestml.utils.ast_source_location import ASTSourceLocation +from pynestml.utils.logger import LoggingLevel, Logger +from pynestml.utils.model_parser import ModelParser + + +class TestCoCos: + + @pytest.fixture(scope="module", autouse=True) + def setUp(self): + SymbolTable.initialize_symbol_table( + ASTSourceLocation( + start_line=0, + start_column=0, + end_line=0, + end_column=0)) + PredefinedUnits.register_units() + PredefinedTypes.register_types() + PredefinedVariables.register_variables() + PredefinedFunctions.register_functions() + + def test_invalid_element_defined_after_usage(self): + model = self._parse_and_validate_model(os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'invalid')), 'CoCoVariableDefinedAfterUsage.nestml')) + assert len(Logger.get_all_messages_of_level_and_or_node(model, LoggingLevel.ERROR)) == 1 + + def test_valid_element_defined_after_usage(self): + model = self._parse_and_validate_model(os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'valid')), 'CoCoVariableDefinedAfterUsage.nestml')) + assert len(Logger.get_all_messages_of_level_and_or_node(model, LoggingLevel.ERROR)) == 0 + + def test_invalid_element_in_same_line(self): + model = self._parse_and_validate_model(os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'invalid')), 'CoCoElementInSameLine.nestml')) + assert len(Logger.get_all_messages_of_level_and_or_node(model, LoggingLevel.ERROR)) == 1 + + def test_valid_element_in_same_line(self): + model = self._parse_and_validate_model(os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'valid')), 'CoCoElementInSameLine.nestml')) + assert len(Logger.get_all_messages_of_level_and_or_node(model, LoggingLevel.ERROR)) == 0 + + def test_invalid_integrate_odes_called_if_equations_defined(self): + model = self._parse_and_validate_model(os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'invalid')), 'CoCoIntegrateOdesCalledIfEquationsDefined.nestml')) + assert len(Logger.get_all_messages_of_level_and_or_node(model, LoggingLevel.ERROR)) == 1 + + def test_valid_integrate_odes_called_if_equations_defined(self): + model = self._parse_and_validate_model(os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'valid')), 'CoCoIntegrateOdesCalledIfEquationsDefined.nestml')) + assert len(Logger.get_all_messages_of_level_and_or_node(model, LoggingLevel.ERROR)) == 0 + + def test_invalid_element_not_defined_in_scope(self): + model = self._parse_and_validate_model(os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'invalid')), 'CoCoVariableNotDefined.nestml')) + assert len(Logger.get_all_messages_of_level_and_or_node(model, LoggingLevel.ERROR)) == 6 + + def test_valid_element_not_defined_in_scope(self): + model = self._parse_and_validate_model(os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'valid')), 'CoCoVariableNotDefined.nestml')) + assert len(Logger.get_all_messages_of_level_and_or_node(model, LoggingLevel.ERROR)) == 0 + + def test_variable_with_same_name_as_unit(self): + Logger.set_logging_level(LoggingLevel.NO) + model = self._parse_and_validate_model(os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'valid')), 'CoCoVariableWithSameNameAsUnit.nestml')) + assert len(Logger.get_all_messages_of_level_and_or_node(model, LoggingLevel.WARNING)) == 3 + + def test_invalid_variable_redeclaration(self): + model = self._parse_and_validate_model(os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'invalid')), 'CoCoVariableRedeclared.nestml')) + assert len(Logger.get_all_messages_of_level_and_or_node(model, LoggingLevel.ERROR)) == 1 + + def test_valid_variable_redeclaration(self): + model = self._parse_and_validate_model(os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'valid')), 'CoCoVariableRedeclared.nestml')) + assert len(Logger.get_all_messages_of_level_and_or_node(model, LoggingLevel.ERROR)) == 0 + + def test_invalid_each_block_unique(self): + model = self._parse_and_validate_model(os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'invalid')), 'CoCoEachBlockUnique.nestml')) + assert len(Logger.get_all_messages_of_level_and_or_node(model, LoggingLevel.ERROR)) == 2 + + def test_valid_each_block_unique(self): + model = self._parse_and_validate_model(os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'valid')), 'CoCoEachBlockUnique.nestml')) + assert len(Logger.get_all_messages_of_level_and_or_node(model, LoggingLevel.ERROR)) == 0 + + def test_invalid_function_unique_and_defined(self): + model = self._parse_and_validate_model(os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'invalid')), 'CoCoFunctionNotUnique.nestml')) + assert len(Logger.get_all_messages_of_level_and_or_node(model, LoggingLevel.ERROR)) == 8 + + def test_valid_function_unique_and_defined(self): + model = self._parse_and_validate_model(os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'valid')), 'CoCoFunctionNotUnique.nestml')) + assert len(Logger.get_all_messages_of_level_and_or_node(model, LoggingLevel.ERROR)) == 0 + + def test_invalid_inline_expressions_have_rhs(self): + model = self._parse_and_validate_model(os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'invalid')), 'CoCoInlineExpressionHasNoRhs.nestml')) + assert model is None + + def test_valid_inline_expressions_have_rhs(self): + model = self._parse_and_validate_model(os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'valid')), 'CoCoInlineExpressionHasNoRhs.nestml')) + assert len(Logger.get_all_messages_of_level_and_or_node(model, LoggingLevel.ERROR)) == 0 + + def test_invalid_inline_expression_has_several_lhs(self): + model = self._parse_and_validate_model(os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'invalid')), 'CoCoInlineExpressionWithSeveralLhs.nestml')) + assert model is None + + def test_valid_inline_expression_has_several_lhs(self): + model = self._parse_and_validate_model(os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'valid')), 'CoCoInlineExpressionWithSeveralLhs.nestml')) + assert len(Logger.get_all_messages_of_level_and_or_node(model, LoggingLevel.ERROR)) == 0 + + def test_invalid_no_values_assigned_to_input_ports(self): + model = self._parse_and_validate_model(os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'invalid')), 'CoCoValueAssignedToInputPort.nestml')) + assert len(Logger.get_all_messages_of_level_and_or_node(model, LoggingLevel.ERROR)) == 1 + + def test_valid_no_values_assigned_to_input_ports(self): + model = self._parse_and_validate_model(os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'valid')), 'CoCoValueAssignedToInputPort.nestml')) + assert len(Logger.get_all_messages_of_level_and_or_node(model, LoggingLevel.ERROR)) == 0 + + def test_invalid_order_of_equations_correct(self): + model = self._parse_and_validate_model(os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'invalid')), 'CoCoNoOrderOfEquations.nestml')) + assert len(Logger.get_all_messages_of_level_and_or_node(model, LoggingLevel.ERROR)) == 2 + + def test_valid_order_of_equations_correct(self): + model = self._parse_and_validate_model(os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'valid')), 'CoCoNoOrderOfEquations.nestml')) + assert len(Logger.get_all_messages_of_level_and_or_node(model, LoggingLevel.ERROR)) == 0 + + def test_invalid_numerator_of_unit_one(self): + model = self._parse_and_validate_model(os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'invalid')), 'CoCoUnitNumeratorNotOne.nestml')) + assert len(Logger.get_all_messages_of_level_and_or_node(model, LoggingLevel.ERROR)) == 2 + + def test_valid_numerator_of_unit_one(self): + model = self._parse_and_validate_model(os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'valid')), 'CoCoUnitNumeratorNotOne.nestml')) + assert len(Logger.get_all_messages_of_level_and_or_node(model, LoggingLevel.ERROR)) == 0 + + def test_invalid_names_of_neurons_unique(self): + model = self._parse_and_validate_model(os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'invalid')), 'CoCoMultipleNeuronsWithEqualName.nestml')) + assert len(Logger.get_all_messages_of_level_and_or_node(model, LoggingLevel.ERROR)) == 3 + + def test_valid_names_of_neurons_unique(self): + self._parse_and_validate_model(os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'valid')), 'CoCoMultipleNeuronsWithEqualName.nestml')) + assert len(Logger.get_all_messages_of_level_and_or_node(None, LoggingLevel.ERROR)) == 0 + + def test_invalid_no_nest_collision(self): + model = self._parse_and_validate_model(os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'invalid')), 'CoCoNestNamespaceCollision.nestml')) + assert len(Logger.get_all_messages_of_level_and_or_node(model, LoggingLevel.ERROR)) == 1 + + def test_valid_no_nest_collision(self): + model = self._parse_and_validate_model(os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'valid')), 'CoCoNestNamespaceCollision.nestml')) + assert len(Logger.get_all_messages_of_level_and_or_node(model, LoggingLevel.ERROR)) == 0 + + def test_invalid_redundant_input_port_keywords_detected(self): + model = self._parse_and_validate_model(os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'invalid')), 'CoCoInputPortWithRedundantTypes.nestml')) + assert len(Logger.get_all_messages_of_level_and_or_node(model, LoggingLevel.ERROR)) == 1 + + def test_valid_redundant_input_port_keywords_detected(self): + model = self._parse_and_validate_model(os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'valid')), 'CoCoInputPortWithRedundantTypes.nestml')) + assert len(Logger.get_all_messages_of_level_and_or_node(model, LoggingLevel.ERROR)) == 0 + + def test_invalid_parameters_assigned_only_in_parameters_block(self): + model = self._parse_and_validate_model(os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'invalid')), 'CoCoParameterAssignedOutsideBlock.nestml')) + assert len(Logger.get_all_messages_of_level_and_or_node(model, LoggingLevel.ERROR)) == 1 + + def test_valid_parameters_assigned_only_in_parameters_block(self): + model = self._parse_and_validate_model(os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'valid')), 'CoCoParameterAssignedOutsideBlock.nestml')) + assert len(Logger.get_all_messages_of_level_and_or_node(model, LoggingLevel.ERROR)) == 0 + + def test_invalid_inline_expressions_assigned_only_in_declaration(self): + model = self._parse_and_validate_model(os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'invalid')), 'CoCoAssignmentToInlineExpression.nestml')) + assert len(Logger.get_all_messages_of_level_and_or_node(model, LoggingLevel.ERROR)) == 1 + + def test_invalid_internals_assigned_only_in_internals_block(self): + model = self._parse_and_validate_model(os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'invalid')), 'CoCoInternalAssignedOutsideBlock.nestml')) + assert len(Logger.get_all_messages_of_level_and_or_node(model, LoggingLevel.ERROR)) == 1 + + def test_valid_internals_assigned_only_in_internals_block(self): + model = self._parse_and_validate_model(os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'valid')), 'CoCoInternalAssignedOutsideBlock.nestml')) + assert len(Logger.get_all_messages_of_level_and_or_node(model, LoggingLevel.ERROR)) == 0 + + def test_invalid_function_with_wrong_arg_number_detected(self): + model = self._parse_and_validate_model(os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'invalid')), 'CoCoFunctionCallNotConsistentWrongArgNumber.nestml')) + assert len(Logger.get_all_messages_of_level_and_or_node(model, LoggingLevel.ERROR)) == 2 + + def test_valid_function_with_wrong_arg_number_detected(self): + model = self._parse_and_validate_model(os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'valid')), 'CoCoFunctionCallNotConsistentWrongArgNumber.nestml')) + assert len(Logger.get_all_messages_of_level_and_or_node(model, LoggingLevel.ERROR)) == 0 + + def test_invalid_init_values_have_rhs_and_ode(self): + model = self._parse_and_validate_model(os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'invalid')), 'CoCoInitValuesWithoutOde.nestml')) + assert len(Logger.get_all_messages_of_level_and_or_node(model, LoggingLevel.WARNING)) == 2 + + def test_valid_init_values_have_rhs_and_ode(self): + model = self._parse_and_validate_model(os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'valid')), 'CoCoInitValuesWithoutOde.nestml')) + assert len(Logger.get_all_messages_of_level_and_or_node(model, LoggingLevel.WARNING)) == 2 + + def test_invalid_incorrect_return_stmt_detected(self): + model = self._parse_and_validate_model(os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'invalid')), 'CoCoIncorrectReturnStatement.nestml')) + assert len(Logger.get_all_messages_of_level_and_or_node(model, LoggingLevel.ERROR)) == 8 + + def test_valid_incorrect_return_stmt_detected(self): + model = self._parse_and_validate_model(os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'valid')), 'CoCoIncorrectReturnStatement.nestml')) + assert len(Logger.get_all_messages_of_level_and_or_node(model, LoggingLevel.ERROR)) == 0 + + def test_invalid_ode_vars_outside_init_block_detected(self): + model = self._parse_and_validate_model(os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'invalid')), 'CoCoOdeVarNotInInitialValues.nestml')) + assert len(Logger.get_all_messages_of_level_and_or_node(model, LoggingLevel.ERROR)) == 1 + + def test_valid_ode_vars_outside_init_block_detected(self): + model = self._parse_and_validate_model(os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'valid')), 'CoCoOdeVarNotInInitialValues.nestml')) + assert len(Logger.get_all_messages_of_level_and_or_node(model, LoggingLevel.ERROR)) == 0 + + def test_invalid_convolve_correctly_defined(self): + model = self._parse_and_validate_model(os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'invalid')), 'CoCoConvolveNotCorrectlyProvided.nestml')) + assert len(Logger.get_all_messages_of_level_and_or_node(model, LoggingLevel.ERROR)) == 2 + + def test_valid_convolve_correctly_defined(self): + model = self._parse_and_validate_model(os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'valid')), 'CoCoConvolveNotCorrectlyProvided.nestml')) + assert len(Logger.get_all_messages_of_level_and_or_node(model, LoggingLevel.ERROR)) == 0 + + def test_invalid_vector_in_non_vector_declaration_detected(self): + model = self._parse_and_validate_model(os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'invalid')), 'CoCoVectorInNonVectorDeclaration.nestml')) + assert len(Logger.get_all_messages_of_level_and_or_node(model, LoggingLevel.ERROR)) == 1 + + def test_valid_vector_in_non_vector_declaration_detected(self): + model = self._parse_and_validate_model(os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'valid')), 'CoCoVectorInNonVectorDeclaration.nestml')) + assert len(Logger.get_all_messages_of_level_and_or_node(model, LoggingLevel.ERROR)) == 0 + + def test_invalid_vector_parameter_declaration(self): + model = self._parse_and_validate_model(os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'invalid')), 'CoCoVectorParameterDeclaration.nestml')) + assert len(Logger.get_all_messages_of_level_and_or_node(model, LoggingLevel.ERROR)) == 1 + + def test_valid_vector_parameter_declaration(self): + model = self._parse_and_validate_model(os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'valid')), 'CoCoVectorParameterDeclaration.nestml')) + assert len(Logger.get_all_messages_of_level_and_or_node(model, LoggingLevel.ERROR)) == 0 + + def test_invalid_vector_parameter_type(self): + model = self._parse_and_validate_model(os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'invalid')), 'CoCoVectorParameterType.nestml')) + assert len(Logger.get_all_messages_of_level_and_or_node(model, LoggingLevel.ERROR)) == 1 + + def test_valid_vector_parameter_type(self): + model = self._parse_and_validate_model(os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'valid')), 'CoCoVectorParameterType.nestml')) + assert len(Logger.get_all_messages_of_level_and_or_node(model, LoggingLevel.ERROR)) == 0 + + def test_invalid_vector_parameter_size(self): + model = self._parse_and_validate_model(os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'invalid')), 'CoCoVectorDeclarationSize.nestml')) + assert len(Logger.get_all_messages_of_level_and_or_node(model, LoggingLevel.ERROR)) == 2 + + def test_valid_vector_parameter_size(self): + model = self._parse_and_validate_model(os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'valid')), 'CoCoVectorDeclarationSize.nestml')) + assert len(Logger.get_all_messages_of_level_and_or_node(model, LoggingLevel.ERROR)) == 0 + + def test_invalid_convolve_correctly_parameterized(self): + model = self._parse_and_validate_model(os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'invalid')), 'CoCoConvolveNotCorrectlyParametrized.nestml')) + assert len(Logger.get_all_messages_of_level_and_or_node(model, LoggingLevel.ERROR)) == 2 + + def test_valid_convolve_correctly_parameterized(self): + model = self._parse_and_validate_model(os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'valid')), 'CoCoConvolveNotCorrectlyParametrized.nestml')) + assert len(Logger.get_all_messages_of_level_and_or_node(model, LoggingLevel.ERROR)) == 0 + + def test_invalid_invariant_correctly_typed(self): + model = self._parse_and_validate_model(os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'invalid')), 'CoCoInvariantNotBool.nestml')) + assert len(Logger.get_all_messages_of_level_and_or_node(model, LoggingLevel.ERROR)) == 1 + + def test_valid_invariant_correctly_typed(self): + model = self._parse_and_validate_model(os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'valid')), 'CoCoInvariantNotBool.nestml')) + assert len(Logger.get_all_messages_of_level_and_or_node(model, LoggingLevel.ERROR)) == 0 + + def test_invalid_expression_correctly_typed(self): + model = self._parse_and_validate_model(os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'invalid')), 'CoCoIllegalExpression.nestml')) + assert len(Logger.get_all_messages_of_level_and_or_node(model, LoggingLevel.ERROR)) == 2 + + def test_valid_expression_correctly_typed(self): + model = self._parse_and_validate_model(os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'valid')), 'CoCoIllegalExpression.nestml')) + assert len(Logger.get_all_messages_of_level_and_or_node(model, LoggingLevel.ERROR)) == 0 + + def test_invalid_compound_expression_correctly_typed(self): + model = self._parse_and_validate_model(os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'invalid')), 'CompoundOperatorWithDifferentButCompatibleUnits.nestml')) + assert len(Logger.get_all_messages_of_level_and_or_node(model, LoggingLevel.ERROR)) == 10 + + def test_valid_compound_expression_correctly_typed(self): + model = self._parse_and_validate_model(os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'valid')), 'CompoundOperatorWithDifferentButCompatibleUnits.nestml')) + assert len(Logger.get_all_messages_of_level_and_or_node(model, LoggingLevel.ERROR)) == 0 + + def test_invalid_ode_correctly_typed(self): + model = self._parse_and_validate_model(os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'invalid')), 'CoCoOdeIncorrectlyTyped.nestml')) + assert len(Logger.get_all_messages_of_level_and_or_node(model, LoggingLevel.ERROR)) > 0 + + def test_valid_ode_correctly_typed(self): + model = self._parse_and_validate_model(os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'valid')), 'CoCoOdeCorrectlyTyped.nestml')) + assert len(Logger.get_all_messages_of_level_and_or_node(model, LoggingLevel.ERROR)) == 0 + + def test_invalid_output_block_defined_if_emit_call(self): + """test that an error is raised when the emit_spike() function is called by the neuron, but an output block is not defined""" + model = self._parse_and_validate_model(os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'invalid')), 'CoCoOutputPortDefinedIfEmitCall.nestml')) + assert len(Logger.get_all_messages_of_level_and_or_node(model, LoggingLevel.ERROR)) > 0 + + def test_invalid_output_port_defined_if_emit_call(self): + """test that an error is raised when the emit_spike() function is called by the neuron, but a spiking output port is not defined""" + model = self._parse_and_validate_model(os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'invalid')), 'CoCoOutputPortDefinedIfEmitCall-2.nestml')) + assert len(Logger.get_all_messages_of_level_and_or_node(model, LoggingLevel.ERROR)) > 0 + + def test_valid_output_port_defined_if_emit_call(self): + """test that no error is raised when the output block is missing, but not emit_spike() functions are called""" + model = self._parse_and_validate_model(os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'valid')), 'CoCoOutputPortDefinedIfEmitCall.nestml')) + assert len(Logger.get_all_messages_of_level_and_or_node(model, LoggingLevel.ERROR)) == 0 + + def test_valid_coco_kernel_type(self): + """ + Test the functionality of CoCoKernelType. + """ + model = self._parse_and_validate_model(os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'valid')), 'CoCoKernelType.nestml')) + assert len(Logger.get_all_messages_of_level_and_or_node(model, LoggingLevel.ERROR)) == 0 + + def test_invalid_coco_kernel_type(self): + """ + Test the functionality of CoCoKernelType. + """ + model = self._parse_and_validate_model(os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'invalid')), 'CoCoKernelType.nestml')) + assert len(Logger.get_all_messages_of_level_and_or_node(model, LoggingLevel.ERROR)) == 1 + + def test_invalid_coco_kernel_type_initial_values(self): + """ + Test the functionality of CoCoKernelType. + """ + model = self._parse_and_validate_model(os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'invalid')), 'CoCoKernelTypeInitialValues.nestml')) + assert len(Logger.get_all_messages_of_level_and_or_node(model, LoggingLevel.ERROR)) == 4 + + def test_valid_coco_state_variables_initialized(self): + """ + Test that the CoCo condition is applicable for all the variables in the state block initialized with a value + """ + model = self._parse_and_validate_model(os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'valid')), 'CoCoStateVariablesInitialized.nestml')) + assert len(Logger.get_all_messages_of_level_and_or_node(model, LoggingLevel.ERROR)) == 0 + + def test_invalid_coco_state_variables_initialized(self): + """ + Test that the CoCo condition is applicable for all the variables in the state block not initialized + """ + model = self._parse_and_validate_model(os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'invalid')), 'CoCoStateVariablesInitialized.nestml')) + assert len(Logger.get_all_messages_of_level_and_or_node(model, LoggingLevel.ERROR)) == 2 + + def test_invalid_co_co_priorities_correctly_specified(self): + model = self._parse_and_validate_model(os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'invalid')), 'CoCoPrioritiesCorrectlySpecified.nestml')) + assert len(Logger.get_all_messages_of_level_and_or_node(model, LoggingLevel.ERROR)) == 1 + + def test_valid_co_co_priorities_correctly_specified(self): + model = self._parse_and_validate_model(os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'valid')), 'CoCoPrioritiesCorrectlySpecified.nestml')) + assert len(Logger.get_all_messages_of_level_and_or_node(model, LoggingLevel.ERROR)) == 0 + + def test_invalid_co_co_resolution_legally_used(self): + model = self._parse_and_validate_model(os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'invalid')), 'CoCoResolutionLegallyUsed.nestml')) + assert len(Logger.get_all_messages_of_level_and_or_node(model, LoggingLevel.ERROR)) == 2 + + def test_valid_co_co_resolution_legally_used(self): + model = self._parse_and_validate_model(os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'valid')), 'CoCoResolutionLegallyUsed.nestml')) + assert len(Logger.get_all_messages_of_level_and_or_node(model, LoggingLevel.ERROR)) == 0 + + def test_valid_co_co_vector_input_port(self): + model = self._parse_and_validate_model(os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'valid')), 'CoCoVectorInputPortSizeAndType.nestml')) + assert len(Logger.get_all_messages_of_level_and_or_node(model, LoggingLevel.ERROR)) == 0 + + def test_invalid_co_co_vector_input_port(self): + model = self._parse_and_validate_model(os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'invalid')), 'CoCoVectorInputPortSizeAndType.nestml')) + assert len(Logger.get_all_messages_of_level_and_or_node(model, LoggingLevel.ERROR)) == 1 + + def _parse_and_validate_model(self, fname: str) -> Optional[str]: + from pynestml.frontend.pynestml_frontend import generate_target + + Logger.init_logger(LoggingLevel.DEBUG) + + try: + generate_target(input_path=fname, target_platform="NONE", logging_level="DEBUG") + except BaseException: + return None + + ast_compilation_unit = ModelParser.parse_file(fname) + if ast_compilation_unit is None or len(ast_compilation_unit.get_model_list()) == 0: + return None + + model: ASTModel = ast_compilation_unit.get_model_list()[0] + model_name = model.get_name() + + return model_name diff --git a/tests/test_function_parameter_templating.py b/tests/test_function_parameter_templating.py new file mode 100644 index 000000000..b93e06780 --- /dev/null +++ b/tests/test_function_parameter_templating.py @@ -0,0 +1,36 @@ +# -*- coding: utf-8 -*- +# +# test_function_parameter_templating.py +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . + +import os + +from pynestml.utils.logger import Logger, LoggingLevel +from pynestml.frontend.pynestml_frontend import generate_target + + +class TestFunctionParameterTemplating: + """ + This test is used to test the correct derivation of types when functions use templated type parameters. + """ + + def test(self): + fname = os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), "resources", "FunctionParameterTemplatingTest.nestml"))) + generate_target(input_path=fname, target_platform="NONE", logging_level="DEBUG") + assert len(Logger.get_all_messages_of_level_and_or_node("templated_function_parameters_type_test", LoggingLevel.ERROR)) == 5 diff --git a/tests/test_unit_system.py b/tests/test_unit_system.py new file mode 100644 index 000000000..2cad0b98d --- /dev/null +++ b/tests/test_unit_system.py @@ -0,0 +1,164 @@ +# -*- coding: utf-8 -*- +# +# test_unit_system.py +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . + +import os +import pytest + +from pynestml.codegeneration.printers.constant_printer import ConstantPrinter +from pynestml.codegeneration.printers.cpp_expression_printer import CppExpressionPrinter +from pynestml.codegeneration.printers.cpp_simple_expression_printer import CppSimpleExpressionPrinter +from pynestml.codegeneration.printers.cpp_type_symbol_printer import CppTypeSymbolPrinter +from pynestml.codegeneration.printers.cpp_variable_printer import CppVariablePrinter +from pynestml.codegeneration.printers.nest_cpp_function_call_printer import NESTCppFunctionCallPrinter +from pynestml.codegeneration.printers.nestml_variable_printer import NestMLVariablePrinter +from pynestml.frontend.pynestml_frontend import generate_target +from pynestml.symbol_table.symbol_table import SymbolTable +from pynestml.symbols.predefined_functions import PredefinedFunctions +from pynestml.symbols.predefined_types import PredefinedTypes +from pynestml.symbols.predefined_units import PredefinedUnits +from pynestml.symbols.predefined_variables import PredefinedVariables +from pynestml.utils.ast_source_location import ASTSourceLocation +from pynestml.utils.logger import Logger, LoggingLevel +from pynestml.utils.model_parser import ModelParser + + +class TestUnitSystem: + r""" + Test class for units system. + """ + + @pytest.fixture(scope="class", autouse=True) + def setUp(self, request): + Logger.set_logging_level(LoggingLevel.INFO) + + SymbolTable.initialize_symbol_table(ASTSourceLocation(start_line=0, start_column=0, end_line=0, end_column=0)) + + PredefinedUnits.register_units() + PredefinedTypes.register_types() + PredefinedVariables.register_variables() + PredefinedFunctions.register_functions() + + Logger.init_logger(LoggingLevel.INFO) + + variable_printer = NestMLVariablePrinter(None) + function_call_printer = NESTCppFunctionCallPrinter(None) + cpp_variable_printer = CppVariablePrinter(None) + self.printer = CppExpressionPrinter(CppSimpleExpressionPrinter(cpp_variable_printer, + ConstantPrinter(), + function_call_printer)) + cpp_variable_printer._expression_printer = self.printer + variable_printer._expression_printer = self.printer + function_call_printer._expression_printer = self.printer + + request.cls.printer = self.printer + + def get_first_statement_in_update_block(self, model): + if model.get_model_list()[0].get_update_blocks()[0]: + return model.get_model_list()[0].get_update_blocks()[0].get_block().get_stmts()[0] + + return None + + def get_first_declaration_in_state_block(self, model): + assert len(model.get_model_list()[0].get_state_blocks()) == 1 + + return model.get_model_list()[0].get_state_blocks()[0].get_declarations()[0] + + def get_first_declared_function(self, model): + return model.get_model_list()[0].get_functions()[0] + + def print_rhs_of_first_assignment_in_update_block(self, model): + assignment = self.get_first_statement_in_update_block(model).small_stmt.get_assignment() + expression = assignment.get_expression() + + return self.printer.print(expression) + + def print_first_function_call_in_update_block(self, model): + function_call = self.get_first_statement_in_update_block(model).small_stmt.get_function_call() + + return self.printer.print(function_call) + + def print_rhs_of_first_declaration_in_state_block(self, model): + declaration = self.get_first_declaration_in_state_block(model) + expression = declaration.get_expression() + + return self.printer.print(expression) + + def print_first_return_statement_in_first_declared_function(self, model): + func = self.get_first_declared_function(model) + return_expression = func.get_block().get_stmts()[0].small_stmt.get_return_stmt().get_expression() + return self.printer.print(return_expression) + + def test_expression_after_magnitude_conversion_in_direct_assignment(self): + model = ModelParser.parse_file(os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'resources')), 'DirectAssignmentWithDifferentButCompatibleUnits.nestml')) + printed_rhs_expression = self.print_rhs_of_first_assignment_in_update_block(model) + + assert printed_rhs_expression == '(1000.0 * (10 * V))' + + def test_expression_after_nested_magnitude_conversion_in_direct_assignment(self): + model = ModelParser.parse_file(os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'resources')), 'DirectAssignmentWithDifferentButCompatibleNestedUnits.nestml')) + printed_rhs_expression = self.print_rhs_of_first_assignment_in_update_block(model) + + assert printed_rhs_expression == '(1000.0 * (10 * V + (0.001 * (5 * mV)) + 20 * V + (1000.0 * (1 * kV))))' + + def test_expression_after_magnitude_conversion_in_compound_assignment(self): + model = ModelParser.parse_file(os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'resources')), 'CompoundAssignmentWithDifferentButCompatibleUnits.nestml')) + printed_rhs_expression = self.print_rhs_of_first_assignment_in_update_block(model) + + assert printed_rhs_expression == '(0.001 * (1200 * mV))' + + def test_expression_after_magnitude_conversion_in_declaration(self): + model = ModelParser.parse_file(os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'resources')), 'DeclarationWithDifferentButCompatibleUnitMagnitude.nestml')) + printed_rhs_expression = self.print_rhs_of_first_declaration_in_state_block(model) + + assert printed_rhs_expression == '(1000.0 * (10 * V))' + + def test_expression_after_type_conversion_in_declaration(self): + model = ModelParser.parse_file(os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'resources')), 'DeclarationWithDifferentButCompatibleUnits.nestml')) + declaration = self.get_first_declaration_in_state_block(model) + from astropy import units as u + + assert declaration.get_expression().type.unit.unit == u.mV + + def test_declaration_with_same_variable_name_as_unit(self): + Logger.init_logger(LoggingLevel.DEBUG) + + generate_target(input_path=os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'resources')), 'DeclarationWithSameVariableNameAsUnit.nestml'), target_platform="NONE", logging_level="DEBUG") + + assert len(Logger.get_all_messages_of_level_and_or_node("BlockTest", LoggingLevel.ERROR)) == 0 + assert len(Logger.get_all_messages_of_level_and_or_node("BlockTest", LoggingLevel.WARNING)) == 3 + + def test_expression_after_magnitude_conversion_in_standalone_function_call(self): + model = ModelParser.parse_file(os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'resources')), 'FunctionCallWithDifferentButCompatibleUnits.nestml')) + printed_function_call = self.print_first_function_call_in_update_block(model) + + assert printed_function_call == 'foo((1000.0 * (10 * V)))' + + def test_expression_after_magnitude_conversion_in_rhs_function_call(self): + model = ModelParser.parse_file(os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'resources')), 'RhsFunctionCallWithDifferentButCompatibleUnits.nestml')) + printed_function_call = self.print_rhs_of_first_assignment_in_update_block(model) + + assert printed_function_call == 'foo((1000.0 * (10 * V)))' + + def test_return_stmt_after_magnitude_conversion_in_function_body(self): + model = ModelParser.parse_file(os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'resources')), 'FunctionBodyReturnStatementWithDifferentButCompatibleUnits.nestml')) + printed_return_stmt = self.print_first_return_statement_in_first_declared_function(model) + + assert printed_return_stmt == '(0.001 * (bar))' diff --git a/tests/unit_system_test.py b/tests/unit_system_test.py deleted file mode 100644 index 1f7817b91..000000000 --- a/tests/unit_system_test.py +++ /dev/null @@ -1,177 +0,0 @@ -# -*- coding: utf-8 -*- -# -# unit_system_test.py -# -# This file is part of NEST. -# -# Copyright (C) 2004 The NEST Initiative -# -# NEST is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 2 of the License, or -# (at your option) any later version. -# -# NEST is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with NEST. If not, see . - -import os -import unittest -from pynestml.codegeneration.printers.constant_printer import ConstantPrinter - -from pynestml.codegeneration.printers.cpp_expression_printer import CppExpressionPrinter -from pynestml.codegeneration.printers.cpp_simple_expression_printer import CppSimpleExpressionPrinter -from pynestml.codegeneration.printers.cpp_type_symbol_printer import CppTypeSymbolPrinter -from pynestml.codegeneration.printers.nestml_variable_printer import NestMLVariablePrinter -from pynestml.symbol_table.symbol_table import SymbolTable -from pynestml.symbols.predefined_functions import PredefinedFunctions -from pynestml.symbols.predefined_types import PredefinedTypes -from pynestml.symbols.predefined_units import PredefinedUnits -from pynestml.symbols.predefined_variables import PredefinedVariables -from pynestml.utils.ast_source_location import ASTSourceLocation -from pynestml.codegeneration.printers.cpp_variable_printer import CppVariablePrinter -from pynestml.codegeneration.printers.nest_cpp_function_call_printer import NESTCppFunctionCallPrinter -from pynestml.codegeneration.printers.cpp_function_call_printer import CppFunctionCallPrinter -from pynestml.utils.logger import Logger, LoggingLevel -from pynestml.utils.model_parser import ModelParser - - -SymbolTable.initialize_symbol_table(ASTSourceLocation(start_line=0, start_column=0, end_line=0, end_column=0)) - -PredefinedUnits.register_units() -PredefinedTypes.register_types() -PredefinedVariables.register_variables() -PredefinedFunctions.register_functions() - -Logger.init_logger(LoggingLevel.INFO) - -type_symbol_printer = CppTypeSymbolPrinter() -variable_printer = NestMLVariablePrinter(None) -function_call_printer = NESTCppFunctionCallPrinter(None) -cpp_variable_printer = CppVariablePrinter(None) -printer = CppExpressionPrinter(CppSimpleExpressionPrinter(cpp_variable_printer, - ConstantPrinter(), - function_call_printer)) -cpp_variable_printer._expression_printer = printer -variable_printer._expression_printer = printer -function_call_printer._expression_printer = printer - - -def get_first_statement_in_update_block(model): - if model.get_model_list()[0].get_update_blocks()[0]: - return model.get_model_list()[0].get_update_blocks()[0].get_block().get_stmts()[0] - return None - - -def get_first_declaration_in_state_block(model): - assert len(model.get_model_list()[0].get_state_blocks()) == 1 - return model.get_model_list()[0].get_state_blocks()[0].get_declarations()[0] - - -def get_first_declared_function(model): - return model.get_model_list()[0].get_functions()[0] - - -def print_rhs_of_first_assignment_in_update_block(model): - assignment = get_first_statement_in_update_block(model).small_stmt.get_assignment() - expression = assignment.get_expression() - return printer.print(expression) - - -def print_first_function_call_in_update_block(model): - function_call = get_first_statement_in_update_block(model).small_stmt.get_function_call() - return printer.print(function_call) - - -def print_rhs_of_first_declaration_in_state_block(model): - declaration = get_first_declaration_in_state_block(model) - expression = declaration.get_expression() - return printer.print(expression) - - -def print_first_return_statement_in_first_declared_function(model): - func = get_first_declared_function(model) - return_expression = func.get_block().get_stmts()[0].small_stmt.get_return_stmt().get_expression() - return printer.print(return_expression) - - -class UnitSystemTest(unittest.TestCase): - """ - Test class for everything Unit related. - """ - - def setUp(self): - Logger.set_logging_level(LoggingLevel.INFO) - - def test_expression_after_magnitude_conversion_in_direct_assignment(self): - Logger.set_logging_level(LoggingLevel.INFO) - model = ModelParser.parse_file( - os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'resources')), - 'DirectAssignmentWithDifferentButCompatibleUnits.nestml')) - printed_rhs_expression = print_rhs_of_first_assignment_in_update_block(model) - - self.assertEqual(printed_rhs_expression, '(1000.0 * (10 * V))') - - def test_expression_after_nested_magnitude_conversion_in_direct_assignment(self): - model = ModelParser.parse_file( - os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'resources')), - 'DirectAssignmentWithDifferentButCompatibleNestedUnits.nestml')) - printed_rhs_expression = print_rhs_of_first_assignment_in_update_block(model) - - self.assertEqual(printed_rhs_expression, '(1000.0 * (10 * V + (0.001 * (5 * mV)) + 20 * V + (1000.0 * (1 * kV))))') - - def test_expression_after_magnitude_conversion_in_compound_assignment(self): - model = ModelParser.parse_file( - os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'resources')), - 'CompoundAssignmentWithDifferentButCompatibleUnits.nestml')) - printed_rhs_expression = print_rhs_of_first_assignment_in_update_block(model) - self.assertEqual(printed_rhs_expression, '(0.001 * (1200 * mV))') - - def test_expression_after_magnitude_conversion_in_declaration(self): - model = ModelParser.parse_file( - os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'resources')), - 'DeclarationWithDifferentButCompatibleUnitMagnitude.nestml')) - printed_rhs_expression = print_rhs_of_first_declaration_in_state_block(model) - self.assertEqual(printed_rhs_expression, '(1000.0 * (10 * V))') - - def test_expression_after_type_conversion_in_declaration(self): - model = ModelParser.parse_file( - os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'resources')), - 'DeclarationWithDifferentButCompatibleUnits.nestml')) - declaration = get_first_declaration_in_state_block(model) - from astropy import units as u - self.assertTrue(declaration.get_expression().type.unit.unit == u.mV) - - def test_declaration_with_same_variable_name_as_unit(self): - model = ModelParser.parse_file( - os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'resources')), - 'DeclarationWithSameVariableNameAsUnit.nestml')) - self.assertEqual(len( - Logger.get_all_messages_of_level_and_or_node(model.get_model_list()[0], LoggingLevel.ERROR)), 0) - self.assertEqual(len( - Logger.get_all_messages_of_level_and_or_node(model.get_model_list()[0], LoggingLevel.WARNING)), 3) - - def test_expression_after_magnitude_conversion_in_standalone_function_call(self): - model = ModelParser.parse_file( - os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'resources')), - 'FunctionCallWithDifferentButCompatibleUnits.nestml')) - printed_function_call = print_first_function_call_in_update_block(model) - self.assertEqual(printed_function_call, 'foo((1000.0 * (10 * V)))') - - def test_expression_after_magnitude_conversion_in_rhs_function_call(self): - model = ModelParser.parse_file( - os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'resources')), - 'RhsFunctionCallWithDifferentButCompatibleUnits.nestml')) - printed_function_call = print_rhs_of_first_assignment_in_update_block(model) - self.assertEqual(printed_function_call, 'foo((1000.0 * (10 * V)))') - - def test_return_stmt_after_magnitude_conversion_in_function_body(self): - model = ModelParser.parse_file( - os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'resources')), - 'FunctionBodyReturnStatementWithDifferentButCompatibleUnits.nestml')) - printed_return_stmt = print_first_return_statement_in_first_declared_function(model) - self.assertEqual(printed_return_stmt, '(0.001 * (bar))') From 3bae1907d469dfccfdd076f62d006a2655f284f2 Mon Sep 17 00:00:00 2001 From: "C.A.P. Linssen" Date: Mon, 7 Oct 2024 06:03:31 -0700 Subject: [PATCH 03/25] run context condition checks only once, after model parsing --- pynestml/frontend/pynestml_frontend.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/pynestml/frontend/pynestml_frontend.py b/pynestml/frontend/pynestml_frontend.py index ca3866619..b161dad17 100644 --- a/pynestml/frontend/pynestml_frontend.py +++ b/pynestml/frontend/pynestml_frontend.py @@ -488,14 +488,15 @@ def process() -> bool: # validation -- check cocos for models that do not have errors already excluded_models = [] for model in models: + if not Logger.has_errors(model.name): + CoCosManager.check_cocos(model) + if Logger.has_errors(model.name): code, message = Messages.get_model_contains_errors(model.get_name()) Logger.log_message(node=model, code=code, message=message, error_position=model.get_source_position(), log_level=LoggingLevel.WARNING) excluded_models.append(model) - else: - CoCosManager.check_cocos(model) # exclude models that have errors models = list(set(models) - set(excluded_models)) From eecc955a4ea5ea5fa13dff0828af619d7e4ecede Mon Sep 17 00:00:00 2001 From: "C.A.P. Linssen" Date: Mon, 7 Oct 2024 06:43:40 -0700 Subject: [PATCH 04/25] add include statement --- .../codegeneration/printers/nestml_printer.py | 9 ++ pynestml/frontend/pynestml_frontend.py | 5 + pynestml/grammars/PyNestMLParser.g4 | 10 +- pynestml/meta_model/ast_include_stmt.py | 75 ++++++++++++ pynestml/meta_model/ast_small_stmt.py | 46 +++++-- pynestml/utils/model_parser.py | 112 +++++++++++++++++- pynestml/visitors/ast_builder_visitor.py | 2 + .../visitors/ast_include_statement_visitor.py | 62 ++++++++++ tests/resources/IncludeStatementTest.nestml | 11 +- tests/resources/ModelA.nestml | 36 +----- ...ment_test.py => test_include_statement.py} | 20 +--- 11 files changed, 310 insertions(+), 78 deletions(-) create mode 100644 pynestml/meta_model/ast_include_stmt.py create mode 100644 pynestml/visitors/ast_include_statement_visitor.py rename tests/{include_statement_test.py => test_include_statement.py} (61%) diff --git a/pynestml/codegeneration/printers/nestml_printer.py b/pynestml/codegeneration/printers/nestml_printer.py index f03d9931d..9e8547c9d 100644 --- a/pynestml/codegeneration/printers/nestml_printer.py +++ b/pynestml/codegeneration/printers/nestml_printer.py @@ -38,6 +38,7 @@ from pynestml.meta_model.ast_function_call import ASTFunctionCall from pynestml.meta_model.ast_if_clause import ASTIfClause from pynestml.meta_model.ast_if_stmt import ASTIfStmt +from pynestml.meta_model.ast_include_stmt import ASTIncludeStmt from pynestml.meta_model.ast_input_block import ASTInputBlock from pynestml.meta_model.ast_input_port import ASTInputPort from pynestml.meta_model.ast_input_qualifier import ASTInputQualifier @@ -443,6 +444,11 @@ def print_return_stmt(self, node: ASTReturnStmt): ret += "return " + (self.print(node.get_expression()) if node.has_expression() else "") return ret + def print_include_stmt(self, node: ASTIncludeStmt): + ret = print_n_spaces(self.indent) + ret += "include \"" + node.get_filename() + "\"" + return ret + def print_simple_expression(self, node: ASTSimpleExpression) -> str: if node.is_function_call(): return self.print(node.function_call) @@ -481,7 +487,10 @@ def print_small_stmt(self, node: ASTSmallStmt) -> str: ret += print_sl_comment(node.in_comment) + "\n" elif node.is_declaration(): ret = self.print(node.get_declaration()) + elif node.is_include_stmt(): + ret = self.print(node.get_include_stmt()) else: + assert node.is_return_stmt() ret = self.print(node.get_return_stmt()) return ret diff --git a/pynestml/frontend/pynestml_frontend.py b/pynestml/frontend/pynestml_frontend.py index b161dad17..2cb9b8ce4 100644 --- a/pynestml/frontend/pynestml_frontend.py +++ b/pynestml/frontend/pynestml_frontend.py @@ -41,6 +41,7 @@ from pynestml.utils.logger import Logger, LoggingLevel from pynestml.utils.messages import Messages from pynestml.utils.model_parser import ModelParser +from pynestml.visitors.ast_include_statement_visitor import ASTIncludeStatementVisitor from pynestml.visitors.ast_parent_visitor import ASTParentVisitor from pynestml.visitors.ast_symbol_table_visitor import ASTSymbolTableVisitor @@ -435,6 +436,10 @@ def get_parsed_models() -> List[ASTModel]: CoCosManager.check_model_names_unique(compilation_unit) models.extend(compilation_unit.get_model_list()) + # swap include statements for included file + for model in models: + model.accept(ASTIncludeStatementVisitor(os.path.dirname(model.file_path))) + # check that no models with duplicate names have been defined CoCosManager.check_no_duplicate_compilation_unit_names(models) diff --git a/pynestml/grammars/PyNestMLParser.g4 b/pynestml/grammars/PyNestMLParser.g4 index 5ffd6e0b7..c3cb98045 100644 --- a/pynestml/grammars/PyNestMLParser.g4 +++ b/pynestml/grammars/PyNestMLParser.g4 @@ -143,7 +143,7 @@ parser grammar PyNestMLParser; | functionCall | declaration | returnStmt - | includeStatement) NEWLINE; + | includeStmt) NEWLINE; assignment : lhs_variable=variable (directAssignment=EQUALS | @@ -153,8 +153,8 @@ parser grammar PyNestMLParser; compoundQuotient=FORWARD_SLASH_EQUALS) expression; - includeStatement : INCLUDE_KEYWORD STRING_LITERAL; - includeStatement_newline : includeStatement NEWLINE; + include : INCLUDE_KEYWORD STRING_LITERAL; + includeStmt_newline : includeStmt NEWLINE; /** ASTDeclaration A variable declaration. It can be a simple declaration defining one or multiple variables: 'a,b,c real = 0'. Or an function declaration 'function a = b + c'. @@ -237,7 +237,7 @@ parser grammar PyNestMLParser; @attribute function: A block declaring a user-defined function. */ modelBody: COLON - NEWLINE INDENT ( includeStatement_newline | blockWithVariables | equationsBlock | inputBlock | outputBlock | function | onReceiveBlock | onConditionBlock | updateBlock )+ DEDENT; + NEWLINE INDENT ( includeStmt_newline | blockWithVariables | equationsBlock | inputBlock | outputBlock | function | onReceiveBlock | onConditionBlock | updateBlock )+ DEDENT; /** ASTOnReceiveBlock @attribute block implementation of the dynamics @@ -263,7 +263,7 @@ parser grammar PyNestMLParser; blockWithVariables: blockType=(STATE_KEYWORD | PARAMETERS_KEYWORD | INTERNALS_KEYWORD) COLON - NEWLINE INDENT (includeStatement_newline | declaration_newline)+ DEDENT; + NEWLINE INDENT (includeStmt_newline | declaration_newline)+ DEDENT; /** ASTUpdateBlock The definition of a block where the dynamical behavior of the neuron is stated: update: diff --git a/pynestml/meta_model/ast_include_stmt.py b/pynestml/meta_model/ast_include_stmt.py new file mode 100644 index 000000000..9657f4054 --- /dev/null +++ b/pynestml/meta_model/ast_include_stmt.py @@ -0,0 +1,75 @@ +# -*- coding: utf-8 -*- +# +# ast_include_stmt.py +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . + +from typing import List + +from pynestml.meta_model.ast_node import ASTNode + + +class ASTIncludeStmt(ASTNode): + """ + This class is used to store an include statement. + """ + + def __init__(self, filename: str, *args, **kwargs): + """ + Standard constructor. + + Parameters for superclass (ASTNode) can be passed through :python:`*args` and :python:`**kwargs`. + + :param filename: the filename of the included file (can be a single file name, or file path) + """ + super(ASTIncludeStmt, self).__init__(*args, **kwargs) + self.filename = filename + + def clone(self): + """ + Return a clone ("deep copy") of this node. + + :return: new AST node instance + :rtype: ASTIncludeStmt + """ + dup = ASTIncludeStmt(filename=self.filename, + # ASTNode common attributes: + source_position=self.source_position, + scope=self.scope, + comment=self.comment, + pre_comments=[s for s in self.pre_comments], + in_comment=self.in_comment, + implicit_conversion_factor=self.implicit_conversion_factor) + + return dup + + def get_filename(self) -> str: + """ + Returns the filename of the included file (can be a single file name, or file path). + :return: filename + """ + return self.filename + + def equals(self, other: ASTNode) -> bool: + r""" + The equality method. + """ + if not isinstance(other, ASTIncludeStmt): + return False + + return self.get_filename().equals(other.get_filename()) diff --git a/pynestml/meta_model/ast_small_stmt.py b/pynestml/meta_model/ast_small_stmt.py index e570084f2..84e5e08d5 100644 --- a/pynestml/meta_model/ast_small_stmt.py +++ b/pynestml/meta_model/ast_small_stmt.py @@ -19,19 +19,20 @@ # You should have received a copy of the GNU General Public License # along with NEST. If not, see . -from typing import List +from typing import List, Optional +from pynestml.meta_model.ast_assignment import ASTAssignment +from pynestml.meta_model.ast_declaration import ASTDeclaration +from pynestml.meta_model.ast_function_call import ASTFunctionCall +from pynestml.meta_model.ast_include_stmt import ASTIncludeStmt from pynestml.meta_model.ast_node import ASTNode +from pynestml.meta_model.ast_return_stmt import ASTReturnStmt class ASTSmallStmt(ASTNode): """ This class is used to store small statements, e.g., a declaration. - Grammar: - smallStmt : assignment - | functionCall - | declaration - | returnStmt; + Attributes: assignment (ast_assignment): A assignment reference. function_call (ast_function_call): A function call reference. @@ -39,26 +40,23 @@ class ASTSmallStmt(ASTNode): return_stmt (ast_return_stmt): A reference to the returns statement. """ - def __init__(self, assignment=None, function_call=None, declaration=None, return_stmt=None, *args, **kwargs): + def __init__(self, assignment: Optional[ASTAssignment] = None, function_call: Optional[ASTFunctionCall] = None, declaration: Optional[ASTDeclaration] = None, return_stmt: Optional[ASTReturnStmt] = None, include_stmt: Optional[ASTIncludeStmt] = None, *args, **kwargs): """ Standard constructor. Parameters for superclass (ASTNode) can be passed through :python:`*args` and :python:`**kwargs`. :param assignment: an meta_model-assignment object. - :type assignment: ASTAssignment :param function_call: an meta_model-function call object. - :type function_call: ASTFunctionCall :param declaration: an meta_model-declaration object. - :type declaration: ASTDeclaration :param return_stmt: an meta_model-return statement object. - :type return_stmt: ASTReturnStmt """ super(ASTSmallStmt, self).__init__(*args, **kwargs) self.assignment = assignment self.function_call = function_call self.declaration = declaration self.return_stmt = return_stmt + self.include_stmt = include_stmt def clone(self): """ @@ -79,10 +77,14 @@ def clone(self): return_stmt_dup = None if self.return_stmt: return_stmt_dup = self.return_stmt.clone() + include_stmt_dup = None + if self.include_stmt: + include_stmt_dup = self.include_stmt.clone() dup = ASTSmallStmt(assignment=assignment_dup, function_call=function_call_dup, declaration=declaration_dup, return_stmt=return_stmt_dup, + include_stmt=include_stmt_dup, # ASTNode common attributes: source_position=self.source_position, scope=self.scope, @@ -157,6 +159,20 @@ def get_return_stmt(self): """ return self.return_stmt + def is_include_stmt(self) -> bool: + """ + Returns whether it is a include statement or not. + :return: True if include stmt, False else. + """ + return self.include_stmt is not None + + def get_include_stmt(self) -> Optional[ASTIncludeStmt]: + """ + Returns the include statement. + :return: the include statement. + """ + return self.include_stmt + def get_children(self) -> List[ASTNode]: r""" Returns the children of this node, if any. @@ -174,6 +190,9 @@ def get_children(self) -> List[ASTNode]: if self.is_return_stmt(): return [self.get_return_stmt()] + if self.is_include_stmt(): + return [self.get_include_stmt()] + return [] def equals(self, other: ASTNode) -> bool: @@ -201,4 +220,9 @@ def equals(self, other: ASTNode) -> bool: if self.is_return_stmt() and other.is_return_stmt() and not self.get_return_stmt().equals( other.get_return_stmt()): return False + if self.is_include_stmt() + other.is_include_stmt() == 1: + return False + if self.is_include_stmt() and other.is_include_stmt() and not self.get_include_stmt().equals( + other.get_include_stmt()): + return False return True diff --git a/pynestml/utils/model_parser.py b/pynestml/utils/model_parser.py index 62a8669bb..c66259c4f 100644 --- a/pynestml/utils/model_parser.py +++ b/pynestml/utils/model_parser.py @@ -54,6 +54,8 @@ from pynestml.meta_model.ast_model import ASTModel from pynestml.meta_model.ast_model_body import ASTModelBody from pynestml.meta_model.ast_ode_equation import ASTOdeEquation +from pynestml.meta_model.ast_on_condition_block import ASTOnConditionBlock +from pynestml.meta_model.ast_on_receive_block import ASTOnReceiveBlock from pynestml.meta_model.ast_output_block import ASTOutputBlock from pynestml.meta_model.ast_parameter import ASTParameter from pynestml.meta_model.ast_return_stmt import ASTReturnStmt @@ -387,6 +389,20 @@ def parse_output_block(cls, string): ret.accept(ASTHigherOrderVisitor(log_set_added_source_position)) return ret + @classmethod + def parse_on_receive_block(cls, string: str) -> ASTOnReceiveBlock: + (builder, parser) = tokenize(string) + ret = builder.visit(parser.onReceiveBlock()) + ret.accept(ASTHigherOrderVisitor(log_set_added_source_position)) + return ret + + @classmethod + def parse_on_condition_block(cls, string: str) -> ASTOnConditionBlock: + (builder, parser) = tokenize(string) + ret = builder.visit(parser.onConditionBlock()) + ret.accept(ASTHigherOrderVisitor(log_set_added_source_position)) + return ret + @classmethod def parse_parameter(cls, string): # type: (str) -> ASTParameter @@ -440,7 +456,7 @@ def parse_update_block(cls, string): # type: (str) -> ASTUpdateBlock (builder, parser) = tokenize(string) ret = builder.visit(parser.updateBlock()) - ret.accept(ASTHigherOrderVisitor(log_set_added_source_position)) + ret.accept(ASTHigherOrderVisitor(log_sparse_included_fileet_added_source_position)) return ret @classmethod @@ -459,6 +475,100 @@ def parse_while_stmt(cls, string): ret.accept(ASTHigherOrderVisitor(log_set_added_source_position)) return ret + @classmethod + def parse_included_file(cls, filename: str): + with open(filename, 'r') as file: + lines = file.readlines() + + ast = None + try: + ast = ModelParser.parse_model(lines) + except: + pass + + if not ast: + try: + ast = ModelParser.parse_model_body(lines) + except: + pass + + if not ast: + try: + ast = ModelParser.parse_block_with_variables(lines) + except: + pass + + if not ast: + try: + ast = ModelParser.parse_equations_block(lines) + except: + pass + + if not ast: + try: + ast = ModelParser.parse_input_block(lines) + except: + pass + + if not ast: + try: + ast = ModelParser.parse_output_block(lines) + except: + pass + + if not ast: + try: + ast = ModelParser.parse_on_receive_block(lines) + except: + pass + + if not ast: + try: + ast = ModelParser.parse_on_condition_block(lines) + except: + pass + + if not ast: + try: + ast = ModelParser.parse_update_block(lines) + except: + pass + + + + + + + + + + + + + + if not ast: + try: + ast = ModelParser.parse_block(lines) + except: + pass + + if not ast: + try: + ast = ModelParser.parse_stmt(lines) + except: + pass + + if not ast: + try: + ast = ModelParser.parse_small_stmt(lines) + except: + pass + + assert ast + + return ast + + def tokenize(string: str) -> Tuple[ASTBuilderVisitor, PyNestMLParser]: lexer = PyNestMLLexer(InputStream(string)) diff --git a/pynestml/visitors/ast_builder_visitor.py b/pynestml/visitors/ast_builder_visitor.py index bfc4dd902..72c815b26 100644 --- a/pynestml/visitors/ast_builder_visitor.py +++ b/pynestml/visitors/ast_builder_visitor.py @@ -347,8 +347,10 @@ def visitSmallStmt(self, ctx): function_call = self.visit(ctx.functionCall()) if ctx.functionCall() is not None else None declaration = self.visit(ctx.declaration()) if ctx.declaration() is not None else None return_stmt = self.visit(ctx.returnStmt()) if ctx.returnStmt() is not None else None + include_stmt = self.visit(ctx.includeStmt()) if ctx.includeStmt() is not None else None node = ASTNodeFactory.create_ast_small_stmt(assignment=assignment, function_call=function_call, declaration=declaration, return_stmt=return_stmt, + include_stmt=include_stmt, source_position=create_source_pos(ctx)) # update_node_comments(node, self.__comments.visit(ctx)) update_node_comments(node, self.__comments.visit(ctx)) diff --git a/pynestml/visitors/ast_include_statement_visitor.py b/pynestml/visitors/ast_include_statement_visitor.py new file mode 100644 index 000000000..5ac982ae0 --- /dev/null +++ b/pynestml/visitors/ast_include_statement_visitor.py @@ -0,0 +1,62 @@ +# -*- coding: utf-8 -*- +# +# ast_include_statement_visitor.py +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . + +from typing import Optional +from pynestml.meta_model.ast_expression import ASTExpression +from pynestml.meta_model.ast_small_stmt import ASTSmallStmt +from pynestml.meta_model.ast_update_block import ASTUpdateBlock +from pynestml.symbols.boolean_type_symbol import BooleanTypeSymbol +from pynestml.symbols.error_type_symbol import ErrorTypeSymbol +from pynestml.symbols.predefined_types import PredefinedTypes +from pynestml.symbols.string_type_symbol import StringTypeSymbol +from pynestml.symbols.unit_type_symbol import UnitTypeSymbol +from pynestml.utils.logger import Logger, LoggingLevel +from pynestml.utils.messages import MessageCode, Messages +from pynestml.utils.model_parser import ModelParser +from pynestml.visitors.ast_visitor import ASTVisitor + + +class ASTIncludeStatementVisitor(ASTVisitor): + """ + """ + + def __init__(self, model_path: Optional[str]): + super().__init__() + self.model_path = model_path + + def visit_update_block(self, node: ASTUpdateBlock): + """ + + :param expr: an expression + """ + print(node) + import pdb;pdb.set_trace() + + def visit_small_stmt(self, node: ASTSmallStmt): + """ + + :param expr: an expression + """ + if node.is_include_stmt(): + filename = node.get_filename() + parsed_included_file = ModelParser.parse_included_file(filename) + print(parsed_included_file) + import pdb;pdb.set_trace() diff --git a/tests/resources/IncludeStatementTest.nestml b/tests/resources/IncludeStatementTest.nestml index 193b5e000..301184ec1 100644 --- a/tests/resources/IncludeStatementTest.nestml +++ b/tests/resources/IncludeStatementTest.nestml @@ -31,17 +31,8 @@ along with NEST. If not, see . model include_statement: - include "model_a.nestml" - state: v mV = 42 mV - include "model_a.nestml" - - parameters: - include "model_a.nestml" - - internals: - include "model_a.nestml" update: - include "model_a.nestml" + include "ModelA.nestml" diff --git a/tests/resources/ModelA.nestml b/tests/resources/ModelA.nestml index f9879d86f..b1b1f08e0 100644 --- a/tests/resources/ModelA.nestml +++ b/tests/resources/ModelA.nestml @@ -1,35 +1 @@ -""" -ModelA.nestml -############# - - -Description -+++++++++++ - -A simple model that can be included in other models - -Copyright statement -+++++++++++++++++++ - -This file is part of NEST. - -Copyright (C) 2004 The NEST Initiative - -NEST is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -NEST is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with NEST. If not, see . -""" - -model model_a: - parameters: - foo real = 1.5 - bar ms = 5 ms +println("Hello, world! {v}") diff --git a/tests/include_statement_test.py b/tests/test_include_statement.py similarity index 61% rename from tests/include_statement_test.py rename to tests/test_include_statement.py index 235063492..e7cc71387 100644 --- a/tests/include_statement_test.py +++ b/tests/test_include_statement.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- # -# include_statement_test.py +# test_include_statement.py # # This file is part of NEST. # @@ -23,6 +23,7 @@ from antlr4.CommonTokenStream import CommonTokenStream from antlr4.FileStream import FileStream from antlr4.error.ErrorStrategy import BailErrorStrategy +from pynestml.frontend.pynestml_frontend import generate_target from pynestml.generated.PyNestMLLexer import PyNestMLLexer from pynestml.generated.PyNestMLParser import PyNestMLParser @@ -30,18 +31,5 @@ class TestIncludeStatement: def test_include_statement(self): - input = os.path.realpath(os.path.join(os.path.dirname("__file__"), "resources", "IncludeStatementTest.nestml")) - - input_file = FileStream(input) - lexer = PyNestMLLexer(input_file) - lexer._errHandler = BailErrorStrategy() - lexer._errHandler.reset(lexer) - # create a token stream - stream = CommonTokenStream(lexer) - stream.fill() - # parse the file - parser = PyNestMLParser(stream) - parser._errHandler = BailErrorStrategy() - parser._errHandler.reset(parser) - compilation_unit = parser.nestMLCompilationUnit() - assert compilation_unit is not None + fname = os.path.realpath(os.path.join(os.path.dirname("__file__"), "tests", "resources", "IncludeStatementTest.nestml")) + generate_target(input_path=fname, target_platform="NONE", logging_level="DEBUG") From a377d193288a6a3f4671b2e19c81bd0271ad797d Mon Sep 17 00:00:00 2001 From: Pooja Babu Date: Mon, 7 Oct 2024 15:45:57 +0200 Subject: [PATCH 05/25] Generate parser files --- pynestml/generated/PyNestMLParser.py | 62 ++++++++++----------- pynestml/generated/PyNestMLParserVisitor.py | 8 +-- pynestml/grammars/PyNestMLParser.g4 | 2 +- 3 files changed, 36 insertions(+), 36 deletions(-) diff --git a/pynestml/generated/PyNestMLParser.py b/pynestml/generated/PyNestMLParser.py index 622399583..5ce763d6c 100644 --- a/pynestml/generated/PyNestMLParser.py +++ b/pynestml/generated/PyNestMLParser.py @@ -310,8 +310,8 @@ class PyNestMLParser ( Parser ): RULE_compoundStmt = 16 RULE_smallStmt = 17 RULE_assignment = 18 - RULE_includeStatement = 19 - RULE_includeStatement_newline = 20 + RULE_includeStmt = 19 + RULE_includeStmt_newline = 20 RULE_declaration = 21 RULE_declaration_newline = 22 RULE_anyDecorator = 23 @@ -345,7 +345,7 @@ class PyNestMLParser ( Parser ): "simpleExpression", "unaryOperator", "bitOperator", "comparisonOperator", "logicalOperator", "variable", "functionCall", "inlineExpression", "odeEquation", "kernel", "block", "stmt", "compoundStmt", - "smallStmt", "assignment", "includeStatement", "includeStatement_newline", + "smallStmt", "assignment", "includeStmt", "includeStmt_newline", "declaration", "declaration_newline", "anyDecorator", "namespaceDecoratorNamespace", "namespaceDecoratorName", "returnStmt", "ifStmt", "ifClause", "elifClause", "elseClause", @@ -2152,8 +2152,8 @@ def returnStmt(self): return self.getTypedRuleContext(PyNestMLParser.ReturnStmtContext,0) - def includeStatement(self): - return self.getTypedRuleContext(PyNestMLParser.IncludeStatementContext,0) + def includeStmt(self): + return self.getTypedRuleContext(PyNestMLParser.IncludeStmtContext,0) def getRuleIndex(self): @@ -2199,7 +2199,7 @@ def smallStmt(self): elif la_ == 5: self.state = 325 - self.includeStatement() + self.includeStmt() pass @@ -2307,7 +2307,7 @@ def assignment(self): return localctx - class IncludeStatementContext(ParserRuleContext): + class IncludeStmtContext(ParserRuleContext): __slots__ = 'parser' def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): @@ -2321,21 +2321,21 @@ def STRING_LITERAL(self): return self.getToken(PyNestMLParser.STRING_LITERAL, 0) def getRuleIndex(self): - return PyNestMLParser.RULE_includeStatement + return PyNestMLParser.RULE_includeStmt def accept(self, visitor:ParseTreeVisitor): - if hasattr( visitor, "visitIncludeStatement" ): - return visitor.visitIncludeStatement(self) + if hasattr( visitor, "visitIncludeStmt" ): + return visitor.visitIncludeStmt(self) else: return visitor.visitChildren(self) - def includeStatement(self): + def includeStmt(self): - localctx = PyNestMLParser.IncludeStatementContext(self, self._ctx, self.state) - self.enterRule(localctx, 38, self.RULE_includeStatement) + localctx = PyNestMLParser.IncludeStmtContext(self, self._ctx, self.state) + self.enterRule(localctx, 38, self.RULE_includeStmt) try: self.enterOuterAlt(localctx, 1) self.state = 340 @@ -2351,40 +2351,40 @@ def includeStatement(self): return localctx - class IncludeStatement_newlineContext(ParserRuleContext): + class IncludeStmt_newlineContext(ParserRuleContext): __slots__ = 'parser' def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): super().__init__(parent, invokingState) self.parser = parser - def includeStatement(self): - return self.getTypedRuleContext(PyNestMLParser.IncludeStatementContext,0) + def includeStmt(self): + return self.getTypedRuleContext(PyNestMLParser.IncludeStmtContext,0) def NEWLINE(self): return self.getToken(PyNestMLParser.NEWLINE, 0) def getRuleIndex(self): - return PyNestMLParser.RULE_includeStatement_newline + return PyNestMLParser.RULE_includeStmt_newline def accept(self, visitor:ParseTreeVisitor): - if hasattr( visitor, "visitIncludeStatement_newline" ): - return visitor.visitIncludeStatement_newline(self) + if hasattr( visitor, "visitIncludeStmt_newline" ): + return visitor.visitIncludeStmt_newline(self) else: return visitor.visitChildren(self) - def includeStatement_newline(self): + def includeStmt_newline(self): - localctx = PyNestMLParser.IncludeStatement_newlineContext(self, self._ctx, self.state) - self.enterRule(localctx, 40, self.RULE_includeStatement_newline) + localctx = PyNestMLParser.IncludeStmt_newlineContext(self, self._ctx, self.state) + self.enterRule(localctx, 40, self.RULE_includeStmt_newline) try: self.enterOuterAlt(localctx, 1) self.state = 343 - self.includeStatement() + self.includeStmt() self.state = 344 self.match(PyNestMLParser.NEWLINE) except RecognitionException as re: @@ -3348,11 +3348,11 @@ def INDENT(self): def DEDENT(self): return self.getToken(PyNestMLParser.DEDENT, 0) - def includeStatement_newline(self, i:int=None): + def includeStmt_newline(self, i:int=None): if i is None: - return self.getTypedRuleContexts(PyNestMLParser.IncludeStatement_newlineContext) + return self.getTypedRuleContexts(PyNestMLParser.IncludeStmt_newlineContext) else: - return self.getTypedRuleContext(PyNestMLParser.IncludeStatement_newlineContext,i) + return self.getTypedRuleContext(PyNestMLParser.IncludeStmt_newlineContext,i) def blockWithVariables(self, i:int=None): @@ -3445,7 +3445,7 @@ def modelBody(self): token = self._input.LA(1) if token in [29]: self.state = 455 - self.includeStatement_newline() + self.includeStmt_newline() pass elif token in [33, 34, 35]: self.state = 456 @@ -3713,11 +3713,11 @@ def PARAMETERS_KEYWORD(self): def INTERNALS_KEYWORD(self): return self.getToken(PyNestMLParser.INTERNALS_KEYWORD, 0) - def includeStatement_newline(self, i:int=None): + def includeStmt_newline(self, i:int=None): if i is None: - return self.getTypedRuleContexts(PyNestMLParser.IncludeStatement_newlineContext) + return self.getTypedRuleContexts(PyNestMLParser.IncludeStmt_newlineContext) else: - return self.getTypedRuleContext(PyNestMLParser.IncludeStatement_newlineContext,i) + return self.getTypedRuleContext(PyNestMLParser.IncludeStmt_newlineContext,i) def declaration_newline(self, i:int=None): @@ -3769,7 +3769,7 @@ def blockWithVariables(self): token = self._input.LA(1) if token in [29]: self.state = 502 - self.includeStatement_newline() + self.includeStmt_newline() pass elif token in [16, 30, 89]: self.state = 503 diff --git a/pynestml/generated/PyNestMLParserVisitor.py b/pynestml/generated/PyNestMLParserVisitor.py index 76b555f17..a204344f1 100644 --- a/pynestml/generated/PyNestMLParserVisitor.py +++ b/pynestml/generated/PyNestMLParserVisitor.py @@ -104,13 +104,13 @@ def visitAssignment(self, ctx:PyNestMLParser.AssignmentContext): return self.visitChildren(ctx) - # Visit a parse tree produced by PyNestMLParser#includeStatement. - def visitIncludeStatement(self, ctx:PyNestMLParser.IncludeStatementContext): + # Visit a parse tree produced by PyNestMLParser#includeStmt. + def visitIncludeStmt(self, ctx:PyNestMLParser.IncludeStmtContext): return self.visitChildren(ctx) - # Visit a parse tree produced by PyNestMLParser#includeStatement_newline. - def visitIncludeStatement_newline(self, ctx:PyNestMLParser.IncludeStatement_newlineContext): + # Visit a parse tree produced by PyNestMLParser#includeStmt_newline. + def visitIncludeStmt_newline(self, ctx:PyNestMLParser.IncludeStmt_newlineContext): return self.visitChildren(ctx) diff --git a/pynestml/grammars/PyNestMLParser.g4 b/pynestml/grammars/PyNestMLParser.g4 index c3cb98045..30dd86cb0 100644 --- a/pynestml/grammars/PyNestMLParser.g4 +++ b/pynestml/grammars/PyNestMLParser.g4 @@ -153,7 +153,7 @@ parser grammar PyNestMLParser; compoundQuotient=FORWARD_SLASH_EQUALS) expression; - include : INCLUDE_KEYWORD STRING_LITERAL; + includeStmt : INCLUDE_KEYWORD STRING_LITERAL; includeStmt_newline : includeStmt NEWLINE; /** ASTDeclaration A variable declaration. It can be a simple declaration defining one or multiple variables: From ff6d3d4f458d9fbcfa0a105b0b7704a57f0fa53e Mon Sep 17 00:00:00 2001 From: "C.A.P. Linssen" Date: Mon, 7 Oct 2024 07:46:47 -0700 Subject: [PATCH 06/25] add include statement --- .../codegeneration/printers/model_printer.py | 7 +++ .../codegeneration/printers/nestml_printer.py | 2 +- pynestml/frontend/pynestml_frontend.py | 4 ++ pynestml/generated/PyNestMLLexer.py | 4 +- pynestml/generated/PyNestMLParser.py | 7 +-- pynestml/generated/PyNestMLParserVisitor.py | 2 +- pynestml/grammars/PyNestMLParser.g4 | 2 +- pynestml/meta_model/ast_include_stmt.py | 6 +++ pynestml/meta_model/ast_node_factory.py | 8 ++- pynestml/utils/model_parser.py | 52 +++++++++++++++++-- pynestml/visitors/ast_builder_visitor.py | 6 ++- .../visitors/ast_include_statement_visitor.py | 15 ++++-- 12 files changed, 98 insertions(+), 17 deletions(-) diff --git a/pynestml/codegeneration/printers/model_printer.py b/pynestml/codegeneration/printers/model_printer.py index ab52c5569..e8be387f1 100644 --- a/pynestml/codegeneration/printers/model_printer.py +++ b/pynestml/codegeneration/printers/model_printer.py @@ -35,6 +35,7 @@ from pynestml.meta_model.ast_function import ASTFunction from pynestml.meta_model.ast_if_clause import ASTIfClause from pynestml.meta_model.ast_if_stmt import ASTIfStmt +from pynestml.meta_model.ast_include_stmt import ASTIncludeStmt from pynestml.meta_model.ast_input_block import ASTInputBlock from pynestml.meta_model.ast_input_qualifier import ASTInputQualifier from pynestml.meta_model.ast_kernel import ASTKernel @@ -159,6 +160,9 @@ def print_parameter(self, node: ASTParameter) -> str: def print_return_stmt(self, node: ASTReturnStmt) -> str: raise Exception("Printer does not support printing this node type") + def print_include_stmt(self, node: ASTIncludeStmt) -> str: + raise Exception("Printer does not support printing this node type") + def print_small_stmt(self, node: ASTSmallStmt) -> str: raise Exception("Printer does not support printing this node type") @@ -286,6 +290,9 @@ def print(self, node: ASTNode) -> str: if isinstance(node, ASTReturnStmt): return self.print_return_stmt(node) + if isinstance(node, ASTIncludeStmt): + return self.print_include_stmt(node) + if isinstance(node, ASTSimpleExpression): return self.print_simple_expression(node) diff --git a/pynestml/codegeneration/printers/nestml_printer.py b/pynestml/codegeneration/printers/nestml_printer.py index 9e8547c9d..c3510547f 100644 --- a/pynestml/codegeneration/printers/nestml_printer.py +++ b/pynestml/codegeneration/printers/nestml_printer.py @@ -446,7 +446,7 @@ def print_return_stmt(self, node: ASTReturnStmt): def print_include_stmt(self, node: ASTIncludeStmt): ret = print_n_spaces(self.indent) - ret += "include \"" + node.get_filename() + "\"" + ret += "include " + node.get_filename() return ret def print_simple_expression(self, node: ASTSimpleExpression) -> str: diff --git a/pynestml/frontend/pynestml_frontend.py b/pynestml/frontend/pynestml_frontend.py index 2cb9b8ce4..5c0586cde 100644 --- a/pynestml/frontend/pynestml_frontend.py +++ b/pynestml/frontend/pynestml_frontend.py @@ -440,6 +440,10 @@ def get_parsed_models() -> List[ASTModel]: for model in models: model.accept(ASTIncludeStatementVisitor(os.path.dirname(model.file_path))) + print("After swapping include statements, model: ") + print(model) + import pdb;pdb.set_trace() + # check that no models with duplicate names have been defined CoCosManager.check_no_duplicate_compilation_unit_names(models) diff --git a/pynestml/generated/PyNestMLLexer.py b/pynestml/generated/PyNestMLLexer.py index 3594f35cb..58c5fa7b6 100644 --- a/pynestml/generated/PyNestMLLexer.py +++ b/pynestml/generated/PyNestMLLexer.py @@ -1,4 +1,4 @@ -# Generated from PyNestMLLexer.g4 by ANTLR 4.13.0 +# Generated from PyNestMLLexer.g4 by ANTLR 4.13.2 from antlr4 import * from io import StringIO import sys @@ -444,7 +444,7 @@ class PyNestMLLexer(PyNestMLLexerBase): def __init__(self, input=None, output:TextIO = sys.stdout): super().__init__(input, output) - self.checkVersion("4.13.0") + self.checkVersion("4.13.2") self._interp = LexerATNSimulator(self, self.atn, self.decisionsToDFA, PredictionContextCache()) self._actions = None self._predicates = None diff --git a/pynestml/generated/PyNestMLParser.py b/pynestml/generated/PyNestMLParser.py index 5ce763d6c..407b1e18f 100644 --- a/pynestml/generated/PyNestMLParser.py +++ b/pynestml/generated/PyNestMLParser.py @@ -1,4 +1,4 @@ -# Generated from PyNestMLParser.g4 by ANTLR 4.13.0 +# Generated from PyNestMLParser.g4 by ANTLR 4.13.2 # encoding: utf-8 from antlr4 import * from io import StringIO @@ -450,7 +450,7 @@ class PyNestMLParser ( Parser ): def __init__(self, input:TokenStream, output:TextIO = sys.stdout): super().__init__(input, output) - self.checkVersion("4.13.0") + self.checkVersion("4.13.2") self._interp = ParserATNSimulator(self, self.atn, self.decisionsToDFA, self.sharedContextCache) self._predicates = None @@ -2313,6 +2313,7 @@ class IncludeStmtContext(ParserRuleContext): def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): super().__init__(parent, invokingState) self.parser = parser + self.filename = None # Token def INCLUDE_KEYWORD(self): return self.getToken(PyNestMLParser.INCLUDE_KEYWORD, 0) @@ -2341,7 +2342,7 @@ def includeStmt(self): self.state = 340 self.match(PyNestMLParser.INCLUDE_KEYWORD) self.state = 341 - self.match(PyNestMLParser.STRING_LITERAL) + localctx.filename = self.match(PyNestMLParser.STRING_LITERAL) except RecognitionException as re: localctx.exception = re self._errHandler.reportError(self, re) diff --git a/pynestml/generated/PyNestMLParserVisitor.py b/pynestml/generated/PyNestMLParserVisitor.py index a204344f1..75b0c10de 100644 --- a/pynestml/generated/PyNestMLParserVisitor.py +++ b/pynestml/generated/PyNestMLParserVisitor.py @@ -1,4 +1,4 @@ -# Generated from PyNestMLParser.g4 by ANTLR 4.13.0 +# Generated from PyNestMLParser.g4 by ANTLR 4.13.2 from antlr4 import * if "." in __name__: from .PyNestMLParser import PyNestMLParser diff --git a/pynestml/grammars/PyNestMLParser.g4 b/pynestml/grammars/PyNestMLParser.g4 index 30dd86cb0..47f4e621a 100644 --- a/pynestml/grammars/PyNestMLParser.g4 +++ b/pynestml/grammars/PyNestMLParser.g4 @@ -153,7 +153,7 @@ parser grammar PyNestMLParser; compoundQuotient=FORWARD_SLASH_EQUALS) expression; - includeStmt : INCLUDE_KEYWORD STRING_LITERAL; + includeStmt : INCLUDE_KEYWORD filename=STRING_LITERAL; includeStmt_newline : includeStmt NEWLINE; /** ASTDeclaration A variable declaration. It can be a simple declaration defining one or multiple variables: diff --git a/pynestml/meta_model/ast_include_stmt.py b/pynestml/meta_model/ast_include_stmt.py index 9657f4054..c6e98cdbd 100644 --- a/pynestml/meta_model/ast_include_stmt.py +++ b/pynestml/meta_model/ast_include_stmt.py @@ -73,3 +73,9 @@ def equals(self, other: ASTNode) -> bool: return False return self.get_filename().equals(other.get_filename()) + + def get_children(self) -> List[ASTNode]: + r""" + Returns the children of this node, if any. + """ + return [] diff --git a/pynestml/meta_model/ast_node_factory.py b/pynestml/meta_model/ast_node_factory.py index da3986be9..37de524a9 100644 --- a/pynestml/meta_model/ast_node_factory.py +++ b/pynestml/meta_model/ast_node_factory.py @@ -37,6 +37,7 @@ from pynestml.meta_model.ast_for_stmt import ASTForStmt from pynestml.meta_model.ast_function import ASTFunction from pynestml.meta_model.ast_function_call import ASTFunctionCall +from pynestml.meta_model.ast_include_stmt import ASTIncludeStmt from pynestml.meta_model.ast_inline_expression import ASTInlineExpression from pynestml.meta_model.ast_input_block import ASTInputBlock from pynestml.meta_model.ast_input_port import ASTInputPort @@ -309,6 +310,10 @@ def create_ast_return_stmt(cls, expression=None, source_position=None): # type: (ASTSimpleExpression|ASTExpression,ASTSourceLocation) -> ASTReturnStmt return ASTReturnStmt(expression, source_position=source_position) + @classmethod + def create_ast_include_stmt(cls, filename="", source_position=None): + return ASTIncludeStmt(filename, source_position=source_position) + @classmethod def create_ast_simple_expression(cls, function_call=None, # type: Union(ASTFunctionCall,None) boolean_literal=None, # type: Union(bool,None) @@ -327,9 +332,10 @@ def create_ast_small_stmt(cls, function_call=None, # type: ASTFunctionCall declaration=None, # type: ASTDeclaration return_stmt=None, # type: ASTReturnStmt + include_stmt=None, # type: ASTIncludeStmt source_position=None # type: ASTSourceLocation ): # type: (...) -> ASTSmallStmt - return ASTSmallStmt(assignment, function_call, declaration, return_stmt, source_position=source_position) + return ASTSmallStmt(assignment, function_call, declaration, return_stmt, include_stmt, source_position=source_position) @classmethod def create_ast_unary_operator(cls, is_unary_plus=False, is_unary_minus=False, is_unary_tilde=False, diff --git a/pynestml/utils/model_parser.py b/pynestml/utils/model_parser.py index c66259c4f..72194762b 100644 --- a/pynestml/utils/model_parser.py +++ b/pynestml/utils/model_parser.py @@ -478,8 +478,7 @@ def parse_while_stmt(cls, string): @classmethod def parse_included_file(cls, filename: str): with open(filename, 'r') as file: - lines = file.readlines() - + lines = file.read() ast = None try: ast = ModelParser.parse_model(lines) @@ -570,15 +569,60 @@ def parse_included_file(cls, filename: str): +# def tokenize(string: str) -> Tuple[ASTBuilderVisitor, PyNestMLParser]: +# lexer = PyNestMLLexer(InputStream(string)) +# # create a token stream +# stream = CommonTokenStream(lexer) +# stream.fill() +# parser = PyNestMLParser(stream) +# builder = ASTBuilderVisitor(stream.tokens) +# return builder, parser + + + def tokenize(string: str) -> Tuple[ASTBuilderVisitor, PyNestMLParser]: - lexer = PyNestMLLexer(InputStream(string)) + + lexer = PyNestMLLexer() + lexer.removeErrorListeners() + lexer._errHandler = BailErrorStrategy() # halt immediately on lexer errors + lexer._errHandler.reset(lexer) + lexer.inputStream = InputStream(string) # create a token stream stream = CommonTokenStream(lexer) stream.fill() - parser = PyNestMLParser(stream) + lexerErrorListener = NestMLErrorListener() + if lexerErrorListener._error_occurred: + raise Exception("Lexer error") + + # parse the file + parser = PyNestMLParser(None) + parser.removeErrorListeners() + parser._errHandler = BailErrorStrategy() + parser._errHandler.reset(parser) + parser.setTokenStream(stream) + builder = ASTBuilderVisitor(stream.tokens) return builder, parser + + + + + + + + + + + + + + + + + + + def log_set_added_source_position(node): node.set_source_position(ASTSourceLocation.get_added_source_position()) diff --git a/pynestml/visitors/ast_builder_visitor.py b/pynestml/visitors/ast_builder_visitor.py index 72c815b26..09395e22a 100644 --- a/pynestml/visitors/ast_builder_visitor.py +++ b/pynestml/visitors/ast_builder_visitor.py @@ -352,7 +352,6 @@ def visitSmallStmt(self, ctx): declaration=declaration, return_stmt=return_stmt, include_stmt=include_stmt, source_position=create_source_pos(ctx)) - # update_node_comments(node, self.__comments.visit(ctx)) update_node_comments(node, self.__comments.visit(ctx)) return node @@ -406,6 +405,11 @@ def visitReturnStmt(self, ctx): ret_expression = self.visit(ctx.expression()) if ctx.expression() is not None else None return ASTNodeFactory.create_ast_return_stmt(expression=ret_expression, source_position=create_source_pos(ctx)) + # Visit a parse tree produced by PyNESTMLParser#returnStmt. + def visitIncludeStmt(self, ctx): + filename = ctx.filename.text[1:-1] # strip quotation marks + return ASTNodeFactory.create_ast_include_stmt(filename=filename, source_position=create_source_pos(ctx)) + # Visit a parse tree produced by PyNESTMLParser#ifStmt. def visitIfStmt(self, ctx): if_clause = self.visit(ctx.ifClause()) if ctx.ifClause() is not None else None diff --git a/pynestml/visitors/ast_include_statement_visitor.py b/pynestml/visitors/ast_include_statement_visitor.py index 5ac982ae0..2b838af6e 100644 --- a/pynestml/visitors/ast_include_statement_visitor.py +++ b/pynestml/visitors/ast_include_statement_visitor.py @@ -19,7 +19,9 @@ # You should have received a copy of the GNU General Public License # along with NEST. If not, see . +import os from typing import Optional +from pynestml.meta_model.ast_block import ASTBlock from pynestml.meta_model.ast_expression import ASTExpression from pynestml.meta_model.ast_small_stmt import ASTSmallStmt from pynestml.meta_model.ast_update_block import ASTUpdateBlock @@ -31,6 +33,7 @@ from pynestml.utils.logger import Logger, LoggingLevel from pynestml.utils.messages import MessageCode, Messages from pynestml.utils.model_parser import ModelParser +from pynestml.visitors.ast_parent_visitor import ASTParentVisitor from pynestml.visitors.ast_visitor import ASTVisitor @@ -48,7 +51,6 @@ def visit_update_block(self, node: ASTUpdateBlock): :param expr: an expression """ print(node) - import pdb;pdb.set_trace() def visit_small_stmt(self, node: ASTSmallStmt): """ @@ -56,7 +58,14 @@ def visit_small_stmt(self, node: ASTSmallStmt): :param expr: an expression """ if node.is_include_stmt(): - filename = node.get_filename() + filename = node.get_include_stmt().get_filename() + if not os.path.isabs(filename): + filename = os.path.join(self.model_path, filename) parsed_included_file = ModelParser.parse_included_file(filename) print(parsed_included_file) - import pdb;pdb.set_trace() + + if isinstance(node.get_parent().get_parent(), ASTBlock): + idx = node.get_parent().get_parent().get_stmts().index(node.get_parent()) + blk = node.get_parent().get_parent() + blk.get_stmts()[idx] = parsed_included_file + blk.accept(ASTParentVisitor()) From 5b2865fd69c79bff270cee64269efe1f8188b4c2 Mon Sep 17 00:00:00 2001 From: "C.A.P. Linssen" Date: Fri, 11 Oct 2024 11:01:30 +0200 Subject: [PATCH 07/25] add include statement --- pynestml/frontend/pynestml_frontend.py | 4 ---- pynestml/visitors/ast_include_statement_visitor.py | 4 +--- 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/pynestml/frontend/pynestml_frontend.py b/pynestml/frontend/pynestml_frontend.py index 59c325643..d56c62439 100644 --- a/pynestml/frontend/pynestml_frontend.py +++ b/pynestml/frontend/pynestml_frontend.py @@ -439,10 +439,6 @@ def get_parsed_models() -> List[ASTModel]: for model in models: model.accept(ASTIncludeStatementVisitor(os.path.dirname(model.file_path))) - print("After swapping include statements, model: ") - print(model) - import pdb;pdb.set_trace() - # check that no models with duplicate names have been defined CoCosManager.check_no_duplicate_compilation_unit_names(models) diff --git a/pynestml/visitors/ast_include_statement_visitor.py b/pynestml/visitors/ast_include_statement_visitor.py index 2b838af6e..3b8543714 100644 --- a/pynestml/visitors/ast_include_statement_visitor.py +++ b/pynestml/visitors/ast_include_statement_visitor.py @@ -47,14 +47,12 @@ def __init__(self, model_path: Optional[str]): def visit_update_block(self, node: ASTUpdateBlock): """ - :param expr: an expression """ print(node) def visit_small_stmt(self, node: ASTSmallStmt): """ - :param expr: an expression """ if node.is_include_stmt(): @@ -63,7 +61,7 @@ def visit_small_stmt(self, node: ASTSmallStmt): filename = os.path.join(self.model_path, filename) parsed_included_file = ModelParser.parse_included_file(filename) print(parsed_included_file) - + if isinstance(node.get_parent().get_parent(), ASTBlock): idx = node.get_parent().get_parent().get_stmts().index(node.get_parent()) blk = node.get_parent().get_parent() From 20255b31762706c600081eb6626111c2c70521e8 Mon Sep 17 00:00:00 2001 From: "C.A.P. Linssen" Date: Fri, 22 Nov 2024 15:40:18 +0100 Subject: [PATCH 08/25] add include statement --- ...implicit_conversion_factors_transformer.py | 335 ------------------ pynestml/utils/model_parser.py | 3 +- 2 files changed, 1 insertion(+), 337 deletions(-) delete mode 100644 pynestml/transformers/assign_implicit_conversion_factors_transformer.py diff --git a/pynestml/transformers/assign_implicit_conversion_factors_transformer.py b/pynestml/transformers/assign_implicit_conversion_factors_transformer.py deleted file mode 100644 index f44ee12d5..000000000 --- a/pynestml/transformers/assign_implicit_conversion_factors_transformer.py +++ /dev/null @@ -1,335 +0,0 @@ -# -*- coding: utf-8 -*- -# -# assign_implicit_conversion_factors_transformer.py -# -# This file is part of NEST. -# -# Copyright (C) 2004 The NEST Initiative -# -# NEST is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 2 of the License, or -# (at your option) any later version. -# -# NEST is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with NEST. If not, see . - -from typing import Sequence, Union - -from pynestml.meta_model.ast_compound_stmt import ASTCompoundStmt -from pynestml.meta_model.ast_declaration import ASTDeclaration -from pynestml.meta_model.ast_inline_expression import ASTInlineExpression -from pynestml.meta_model.ast_node import ASTNode -from pynestml.meta_model.ast_small_stmt import ASTSmallStmt -from pynestml.meta_model.ast_stmt import ASTStmt -from pynestml.symbols.error_type_symbol import ErrorTypeSymbol -from pynestml.symbols.predefined_types import PredefinedTypes -from pynestml.symbols.symbol import SymbolKind -from pynestml.symbols.template_type_symbol import TemplateTypeSymbol -from pynestml.symbols.variadic_type_symbol import VariadicTypeSymbol -from pynestml.transformers.transformer import Transformer -from pynestml.utils.ast_source_location import ASTSourceLocation -from pynestml.utils.ast_utils import ASTUtils -from pynestml.utils.logger import LoggingLevel, Logger -from pynestml.utils.logging_helper import LoggingHelper -from pynestml.utils.messages import Messages -from pynestml.utils.type_caster import TypeCaster -from pynestml.visitors.ast_visitor import ASTVisitor - - -class AssignImplicitConversionFactorsTransformer(Transformer): - r""" - Assign implicit conversion factors in expressions. - """ - - def transform(self, models: Union[ASTNode, Sequence[ASTNode]]) -> Union[ASTNode, Sequence[ASTNode]]: - single = False - if isinstance(models, ASTNode): - single = True - models = [models] - - for model in models: - model.accept(AssignImplicitConversionFactorVisitor()) - self.__assign_return_types(model) - - if single: - return models[0] - return models - - def __assign_return_types(self, _node): - for userDefinedFunction in _node.get_functions(): - symbol = userDefinedFunction.get_scope().resolve_to_symbol(userDefinedFunction.get_name(), - SymbolKind.FUNCTION) - # first ensure that the block contains at least one statement - if symbol is not None and len(userDefinedFunction.get_block().get_stmts()) > 0: - # now check that the last statement is a return - self.__check_return_recursively(userDefinedFunction, - symbol.get_return_type(), - userDefinedFunction.get_block().get_stmts(), - False) - # now if it does not have a statement, but uses a return type, it is an error - elif symbol is not None and userDefinedFunction.has_return_type() and \ - not symbol.get_return_type().equals(PredefinedTypes.get_void_type()): - code, message = Messages.get_no_return() - Logger.log_message(node=_node, code=code, message=message, - error_position=userDefinedFunction.get_source_position(), - log_level=LoggingLevel.ERROR) - - def __check_return_recursively(self, processed_function, type_symbol=None, stmts=None, ret_defined: bool = False) -> None: - """ - For a handed over statement, it checks if the statement is a return statement and if it is typed according to the handed over type symbol. - :param type_symbol: a single type symbol - :type type_symbol: type_symbol - :param stmts: a list of statements, either simple or compound - :type stmts: list(ASTSmallStmt,ASTCompoundStmt) - :param ret_defined: indicates whether a ret has already been defined after this block of stmt, thus is not - necessary. Implies that the return has been defined in the higher level block - """ - # in order to ensure that in the sub-blocks, a return is not necessary, we check if the last one in this - # block is a return statement, thus it is not required to have a return in the sub-blocks, but optional - last_statement = stmts[len(stmts) - 1] - ret_defined = False or ret_defined - if (len(stmts) > 0 and isinstance(last_statement, ASTStmt) - and last_statement.is_small_stmt() - and last_statement.small_stmt.is_return_stmt()): - ret_defined = True - - # now check that returns are there if necessary and correctly typed - for c_stmt in stmts: - if c_stmt.is_small_stmt(): - stmt = c_stmt.small_stmt - else: - stmt = c_stmt.compound_stmt - - # if it is a small statement, check if it is a return statement - if isinstance(stmt, ASTSmallStmt) and stmt.is_return_stmt(): - # first check if the return is the last one in this block of statements - if stmts.index(c_stmt) != (len(stmts) - 1): - code, message = Messages.get_not_last_statement('Return') - Logger.log_message(error_position=stmt.get_source_position(), - code=code, message=message, - log_level=LoggingLevel.WARNING) - - # now check that it corresponds to the declared type - if stmt.get_return_stmt().has_expression() and type_symbol is PredefinedTypes.get_void_type(): - code, message = Messages.get_type_different_from_expected(PredefinedTypes.get_void_type(), - stmt.get_return_stmt().get_expression().type) - Logger.log_message(error_position=stmt.get_source_position(), - message=message, code=code, log_level=LoggingLevel.ERROR) - - # if it is not void check if the type corresponds to the one stated - if not stmt.get_return_stmt().has_expression() and \ - not type_symbol.equals(PredefinedTypes.get_void_type()): - code, message = Messages.get_type_different_from_expected(PredefinedTypes.get_void_type(), - type_symbol) - Logger.log_message(error_position=stmt.get_source_position(), - message=message, code=code, log_level=LoggingLevel.ERROR) - - if stmt.get_return_stmt().has_expression(): - type_of_return = stmt.get_return_stmt().get_expression().type - if isinstance(type_of_return, ErrorTypeSymbol): - code, message = Messages.get_type_could_not_be_derived(processed_function.get_name()) - Logger.log_message(error_position=stmt.get_source_position(), - code=code, message=message, log_level=LoggingLevel.ERROR) - elif not type_of_return.equals(type_symbol): - TypeCaster.try_to_recover_or_error(type_symbol, type_of_return, - stmt.get_return_stmt().get_expression()) - elif isinstance(stmt, ASTCompoundStmt): - # otherwise it is a compound stmt, thus check recursively - if stmt.is_if_stmt(): - self.__check_return_recursively(processed_function, - type_symbol, - stmt.get_if_stmt().get_if_clause().get_block().get_stmts(), - ret_defined) - for else_ifs in stmt.get_if_stmt().get_elif_clauses(): - self.__check_return_recursively(processed_function, - type_symbol, else_ifs.get_block().get_stmts(), ret_defined) - if stmt.get_if_stmt().has_else_clause(): - self.__check_return_recursively(processed_function, - type_symbol, - stmt.get_if_stmt().get_else_clause().get_block().get_stmts(), - ret_defined) - elif stmt.is_while_stmt(): - self.__check_return_recursively(processed_function, - type_symbol, stmt.get_while_stmt().get_block().get_stmts(), - ret_defined) - elif stmt.is_for_stmt(): - self.__check_return_recursively(processed_function, - type_symbol, stmt.get_for_stmt().get_block().get_stmts(), - ret_defined) - # now, if a return statement has not been defined in the corresponding higher level block, we have to ensure that it is defined here - elif not ret_defined and stmts.index(c_stmt) == (len(stmts) - 1): - if not (isinstance(stmt, ASTSmallStmt) and stmt.is_return_stmt()): - code, message = Messages.get_no_return() - Logger.log_message(error_position=stmt.get_source_position(), log_level=LoggingLevel.ERROR, - code=code, message=message) - - -class AssignImplicitConversionFactorVisitor(ASTVisitor): - """ - This visitor checks that all expression correspond to the expected type. - """ - - def visit_declaration(self, node): - """ - Visits a single declaration and asserts that type of lhs is equal to type of rhs. - :param node: a single declaration. - :type node: ASTDeclaration - """ - assert isinstance(node, ASTDeclaration) - if node.has_expression(): - if node.get_expression().get_source_position().equals(ASTSourceLocation.get_added_source_position()): - # no type checks are executed for added nodes, since we assume correctness - return - lhs_type = node.get_data_type().get_type_symbol() - rhs_type = node.get_expression().type - if isinstance(rhs_type, ErrorTypeSymbol): - LoggingHelper.drop_missing_type_error(node) - return - if self.__types_do_not_match(lhs_type, rhs_type): - TypeCaster.try_to_recover_or_error(lhs_type, rhs_type, node.get_expression()) - - def visit_inline_expression(self, node): - """ - Visits a single inline expression and asserts that type of lhs is equal to type of rhs. - """ - assert isinstance(node, ASTInlineExpression) - lhs_type = node.get_data_type().get_type_symbol() - rhs_type = node.get_expression().type - if isinstance(rhs_type, ErrorTypeSymbol): - LoggingHelper.drop_missing_type_error(node) - return - - if self.__types_do_not_match(lhs_type, rhs_type): - TypeCaster.try_to_recover_or_error(lhs_type, rhs_type, node.get_expression()) - - def visit_assignment(self, node): - """ - Visits a single expression and assures that type(lhs) == type(rhs). - :param node: a single assignment. - :type node: ASTAssignment - """ - from pynestml.meta_model.ast_assignment import ASTAssignment - assert isinstance(node, ASTAssignment) - - if node.get_source_position().equals(ASTSourceLocation.get_added_source_position()): - # no type checks are executed for added nodes, since we assume correctness - return - if node.is_direct_assignment: # case a = b is simple - self.handle_simple_assignment(node) - else: - self.handle_compound_assignment(node) # e.g. a *= b - - def handle_compound_assignment(self, node): - rhs_expr = node.get_expression() - lhs_variable_symbol = node.get_variable().resolve_in_own_scope() - rhs_type_symbol = rhs_expr.type - - if lhs_variable_symbol is None: - code, message = Messages.get_equation_var_not_in_state_block(node.get_variable().get_complete_name()) - Logger.log_message(code=code, message=message, error_position=node.get_source_position(), - log_level=LoggingLevel.ERROR) - return - - if isinstance(rhs_type_symbol, ErrorTypeSymbol): - LoggingHelper.drop_missing_type_error(node) - return - - lhs_type_symbol = lhs_variable_symbol.get_type_symbol() - - if node.is_compound_product: - if self.__types_do_not_match(lhs_type_symbol, lhs_type_symbol * rhs_type_symbol): - TypeCaster.try_to_recover_or_error(lhs_type_symbol, lhs_type_symbol * rhs_type_symbol, - node.get_expression()) - return - return - - if node.is_compound_quotient: - if self.__types_do_not_match(lhs_type_symbol, lhs_type_symbol / rhs_type_symbol): - TypeCaster.try_to_recover_or_error(lhs_type_symbol, lhs_type_symbol / rhs_type_symbol, - node.get_expression()) - return - return - - assert node.is_compound_sum or node.is_compound_minus - if self.__types_do_not_match(lhs_type_symbol, rhs_type_symbol): - TypeCaster.try_to_recover_or_error(lhs_type_symbol, rhs_type_symbol, - node.get_expression()) - - @staticmethod - def __types_do_not_match(lhs_type_symbol, rhs_type_symbol): - if lhs_type_symbol is None: - return True - - return not lhs_type_symbol.equals(rhs_type_symbol) - - def handle_simple_assignment(self, node): - from pynestml.symbols.symbol import SymbolKind - lhs_variable_symbol = node.get_scope().resolve_to_symbol(node.get_variable().get_complete_name(), - SymbolKind.VARIABLE) - - rhs_type_symbol = node.get_expression().type - if isinstance(rhs_type_symbol, ErrorTypeSymbol): - LoggingHelper.drop_missing_type_error(node) - return - - if lhs_variable_symbol is not None and self.__types_do_not_match(lhs_variable_symbol.get_type_symbol(), - rhs_type_symbol): - TypeCaster.try_to_recover_or_error(lhs_variable_symbol.get_type_symbol(), rhs_type_symbol, - node.get_expression()) - - def visit_function_call(self, node): - """ - Check consistency for a single function call: check if the called function has been declared, whether the number and types of arguments correspond to the declaration, etc. - - :param node: a single function call. - :type node: ASTFunctionCall - """ - func_name = node.get_name() - - if func_name == 'convolve': - return - - symbol = node.get_scope().resolve_to_symbol(node.get_name(), SymbolKind.FUNCTION) - - if symbol is None and ASTUtils.is_function_delay_variable(node): - return - - # first check if the function has been declared - if symbol is None: - code, message = Messages.get_function_not_declared(node.get_name()) - Logger.log_message(error_position=node.get_source_position(), log_level=LoggingLevel.ERROR, - code=code, message=message) - return - - # check if the number of arguments is the same as in the symbol; accept anything for variadic types - is_variadic: bool = len(symbol.get_parameter_types()) == 1 and isinstance(symbol.get_parameter_types()[0], VariadicTypeSymbol) - if (not is_variadic) and len(node.get_args()) != len(symbol.get_parameter_types()): - code, message = Messages.get_wrong_number_of_args(str(node), len(symbol.get_parameter_types()), - len(node.get_args())) - Logger.log_message(code=code, message=message, log_level=LoggingLevel.ERROR, - error_position=node.get_source_position()) - return - - # finally check if the call is correctly typed - expected_types = symbol.get_parameter_types() - actual_args = node.get_args() - actual_types = [arg.type for arg in actual_args] - for actual_arg, actual_type, expected_type in zip(actual_args, actual_types, expected_types): - if isinstance(actual_type, ErrorTypeSymbol): - code, message = Messages.get_type_could_not_be_derived(actual_arg) - Logger.log_message(code=code, message=message, log_level=LoggingLevel.ERROR, - error_position=actual_arg.get_source_position()) - return - - if isinstance(expected_type, VariadicTypeSymbol): - # variadic type symbol accepts anything - return - - if not actual_type.equals(expected_type) and not isinstance(expected_type, TemplateTypeSymbol): - TypeCaster.try_to_recover_or_error(expected_type, actual_type, actual_arg) diff --git a/pynestml/utils/model_parser.py b/pynestml/utils/model_parser.py index 2faa9dad3..0f2034e17 100644 --- a/pynestml/utils/model_parser.py +++ b/pynestml/utils/model_parser.py @@ -68,7 +68,6 @@ from pynestml.meta_model.ast_variable import ASTVariable from pynestml.meta_model.ast_while_stmt import ASTWhileStmt from pynestml.symbol_table.symbol_table import SymbolTable -from pynestml.transformers.assign_implicit_conversion_factors_transformer import AssignImplicitConversionFactorsTransformer from pynestml.utils.ast_source_location import ASTSourceLocation from pynestml.utils.error_listener import NestMLErrorListener from pynestml.utils.logger import Logger, LoggingLevel @@ -457,7 +456,7 @@ def parse_update_block(cls, string): # type: (str) -> ASTUpdateBlock (builder, parser) = tokenize(string) ret = builder.visit(parser.updateBlock()) - ret.accept(ASTHigherOrderVisitor(log_sparse_included_fileet_added_source_position)) + ret.accept(ASTHigherOrderVisitor(log_set_added_source_position)) return ret @classmethod From e3abec801cc0ca0c6073b782fa1778fdebddf9a0 Mon Sep 17 00:00:00 2001 From: "C.A.P. Linssen" Date: Fri, 22 Nov 2024 22:12:35 +0100 Subject: [PATCH 09/25] add include statement --- pynestml/frontend/pynestml_frontend.py | 9 +- pynestml/utils/model_parser.py | 51 ++++--- .../visitors/ast_include_statement_visitor.py | 44 +++++- .../resources/IncludeStatementTest.nestml | 0 .../resources/IncludeStatementTest2.nestml | 38 +++++ .../resources/IncludeStatementTest3.nestml | 38 +++++ .../resources/IncludeStatementTest4.nestml | 38 +++++ tests/nest_tests/resources/ModelA.nestml | 1 + tests/nest_tests/resources/ModelB.nestml | 1 + tests/nest_tests/resources/ModelC.nestml | 1 + tests/nest_tests/resources/ModelD.nestml | 4 + tests/nest_tests/test_include_statement.py | 135 ++++++++++++++++++ tests/resources/ModelA.nestml | 1 - tests/test_include_statement.py | 35 ----- 14 files changed, 325 insertions(+), 71 deletions(-) rename tests/{ => nest_tests}/resources/IncludeStatementTest.nestml (100%) create mode 100644 tests/nest_tests/resources/IncludeStatementTest2.nestml create mode 100644 tests/nest_tests/resources/IncludeStatementTest3.nestml create mode 100644 tests/nest_tests/resources/IncludeStatementTest4.nestml create mode 100644 tests/nest_tests/resources/ModelA.nestml create mode 100644 tests/nest_tests/resources/ModelB.nestml create mode 100644 tests/nest_tests/resources/ModelC.nestml create mode 100644 tests/nest_tests/resources/ModelD.nestml create mode 100644 tests/nest_tests/test_include_statement.py delete mode 100644 tests/resources/ModelA.nestml delete mode 100644 tests/test_include_statement.py diff --git a/pynestml/frontend/pynestml_frontend.py b/pynestml/frontend/pynestml_frontend.py index d56c62439..40983a800 100644 --- a/pynestml/frontend/pynestml_frontend.py +++ b/pynestml/frontend/pynestml_frontend.py @@ -41,6 +41,8 @@ from pynestml.utils.logger import Logger, LoggingLevel from pynestml.utils.messages import Messages from pynestml.utils.model_parser import ModelParser +from pynestml.visitors.assign_implicit_conversion_factors_visitor import AssignImplicitConversionFactorsVisitor +from pynestml.visitors.ast_include_statement_visitor import ASTIncludeStatementVisitor from pynestml.visitors.ast_parent_visitor import ASTParentVisitor from pynestml.visitors.ast_symbol_table_visitor import ASTSymbolTableVisitor @@ -404,7 +406,7 @@ def main() -> int: def get_parsed_models() -> List[ASTModel]: r""" - Handle the parsing and validation of the NESTML files + Handle the parsing and validation of the NESTML files Returns ------- @@ -438,6 +440,11 @@ def get_parsed_models() -> List[ASTModel]: # swap include statements for included file for model in models: model.accept(ASTIncludeStatementVisitor(os.path.dirname(model.file_path))) + model.accept(ASTSymbolTableVisitor()) + + # ....... + for model in models: + model.accept(AssignImplicitConversionFactorsVisitor()) # check that no models with duplicate names have been defined CoCosManager.check_no_duplicate_compilation_unit_names(models) diff --git a/pynestml/utils/model_parser.py b/pynestml/utils/model_parser.py index 0f2034e17..6d4c6793e 100644 --- a/pynestml/utils/model_parser.py +++ b/pynestml/utils/model_parser.py @@ -19,11 +19,12 @@ # You should have received a copy of the GNU General Public License # along with NEST. If not, see . -from typing import Tuple +from typing import List, Tuple, Union from antlr4 import CommonTokenStream, FileStream, InputStream from antlr4.error.ErrorStrategy import BailErrorStrategy, DefaultErrorStrategy from antlr4.error.ErrorListener import ConsoleErrorListener +from antlr4.error.Errors import ParseCancellationException from pynestml.cocos.co_cos_manager import CoCosManager from pynestml.generated.PyNestMLLexer import PyNestMLLexer @@ -53,6 +54,7 @@ from pynestml.meta_model.ast_nestml_compilation_unit import ASTNestMLCompilationUnit from pynestml.meta_model.ast_model import ASTModel from pynestml.meta_model.ast_model_body import ASTModelBody +from pynestml.meta_model.ast_node import ASTNode from pynestml.meta_model.ast_ode_equation import ASTOdeEquation from pynestml.meta_model.ast_on_condition_block import ASTOnConditionBlock from pynestml.meta_model.ast_on_receive_block import ASTOnReceiveBlock @@ -146,9 +148,6 @@ def parse_file(cls, file_path=None): for model in ast.get_model_list(): model.accept(ASTSymbolTableVisitor()) SymbolTable.add_model_scope(model.get_name(), model.get_scope()) - Logger.set_current_node(model) - model.accept(AssignImplicitConversionFactorsVisitor()) - Logger.set_current_node(None) # store source paths for model in ast.get_model_list(): @@ -175,12 +174,22 @@ def parse_declaration(cls, string): return ret @classmethod - def parse_stmt(cls, string): + def parse_stmt(cls, string: str) -> Union[ASTStmt, List[ASTStmt]]: # type: (str) -> ASTStmt + stmts = [] (builder, parser) = tokenize(string) - ret = builder.visit(parser.stmt()) - ret.accept(ASTHigherOrderVisitor(log_set_added_source_position)) - return ret + while True: + try: + stmt = builder.visit(parser.stmt()) + stmts.append(stmt) + except ParseCancellationException: + # no more statements left to parse + break + + if len(stmts) == 1: + return stmts[0] + + return stmts @classmethod def parse_assignment(cls, string): @@ -476,7 +485,7 @@ def parse_while_stmt(cls, string): return ret @classmethod - def parse_included_file(cls, filename: str): + def parse_included_file(cls, filename: str) -> Union[ASTNode, List[ASTNode]]: with open(filename, 'r') as file: lines = file.read() ast = None @@ -496,13 +505,13 @@ def parse_included_file(cls, filename: str): ast = ModelParser.parse_block_with_variables(lines) except: pass - + if not ast: try: ast = ModelParser.parse_equations_block(lines) except: pass - + if not ast: try: ast = ModelParser.parse_input_block(lines) @@ -514,7 +523,7 @@ def parse_included_file(cls, filename: str): ast = ModelParser.parse_output_block(lines) except: pass - + if not ast: try: ast = ModelParser.parse_on_receive_block(lines) @@ -526,37 +535,25 @@ def parse_included_file(cls, filename: str): ast = ModelParser.parse_on_condition_block(lines) except: pass - + if not ast: try: ast = ModelParser.parse_update_block(lines) except: pass - - - - - - - - - - - - if not ast: try: ast = ModelParser.parse_block(lines) except: pass - + if not ast: try: ast = ModelParser.parse_stmt(lines) except: pass - + if not ast: try: ast = ModelParser.parse_small_stmt(lines) diff --git a/pynestml/visitors/ast_include_statement_visitor.py b/pynestml/visitors/ast_include_statement_visitor.py index 3b8543714..76b373bd5 100644 --- a/pynestml/visitors/ast_include_statement_visitor.py +++ b/pynestml/visitors/ast_include_statement_visitor.py @@ -19,11 +19,15 @@ # You should have received a copy of the GNU General Public License # along with NEST. If not, see . -import os from typing import Optional + +import os + from pynestml.meta_model.ast_block import ASTBlock +from pynestml.meta_model.ast_equations_block import ASTEquationsBlock from pynestml.meta_model.ast_expression import ASTExpression from pynestml.meta_model.ast_small_stmt import ASTSmallStmt +from pynestml.meta_model.ast_stmt import ASTStmt from pynestml.meta_model.ast_update_block import ASTUpdateBlock from pynestml.symbols.boolean_type_symbol import BooleanTypeSymbol from pynestml.symbols.error_type_symbol import ErrorTypeSymbol @@ -59,11 +63,37 @@ def visit_small_stmt(self, node: ASTSmallStmt): filename = node.get_include_stmt().get_filename() if not os.path.isabs(filename): filename = os.path.join(self.model_path, filename) + parsed_included_file = ModelParser.parse_included_file(filename) - print(parsed_included_file) - if isinstance(node.get_parent().get_parent(), ASTBlock): - idx = node.get_parent().get_parent().get_stmts().index(node.get_parent()) - blk = node.get_parent().get_parent() - blk.get_stmts()[idx] = parsed_included_file - blk.accept(ASTParentVisitor()) + if isinstance(parsed_included_file, list): + new_stmts = parsed_included_file + + if isinstance(node.get_parent().get_parent(), ASTBlock): + blk = node.get_parent().get_parent() + idx = blk.get_stmts().index(node.get_parent()) + blk.get_stmts().pop(idx) + blk.stmts = blk.stmts[:idx] + new_stmts + blk.stmts[idx:] + for new_stmt in new_stmts: + new_stmt.parent_ = blk + blk.accept(ASTParentVisitor()) + + elif isinstance(node.get_parent().get_parent(), ASTEquationsBlock): + print("not handled yet") + + + elif isinstance(parsed_included_file, ASTStmt): + new_stmt = parsed_included_file + + if isinstance(node.get_parent().get_parent(), ASTBlock): + blk = node.get_parent().get_parent() + idx = blk.get_stmts().index(node.get_parent()) + blk.get_stmts()[idx] = new_stmt + new_stmt.parent_ = blk + blk.accept(ASTParentVisitor()) + + elif isinstance(node.get_parent().get_parent(), ASTEquationsBlock): + print("not handled yet") + + else: + print("not handled yet!") diff --git a/tests/resources/IncludeStatementTest.nestml b/tests/nest_tests/resources/IncludeStatementTest.nestml similarity index 100% rename from tests/resources/IncludeStatementTest.nestml rename to tests/nest_tests/resources/IncludeStatementTest.nestml diff --git a/tests/nest_tests/resources/IncludeStatementTest2.nestml b/tests/nest_tests/resources/IncludeStatementTest2.nestml new file mode 100644 index 000000000..9d5409242 --- /dev/null +++ b/tests/nest_tests/resources/IncludeStatementTest2.nestml @@ -0,0 +1,38 @@ +""" +IncludeStatementTest.nestml +########################### + + +Description ++++++++++++ + +Test whether the include statement works as intended. + +Copyright statement ++++++++++++++++++++ + +This file is part of NEST. + +Copyright (C) 2004 The NEST Initiative + +NEST is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +NEST is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with NEST. If not, see . +""" + +model include_statement2: + + state: + v mV = 42 mV + + update: + include "ModelB.nestml" diff --git a/tests/nest_tests/resources/IncludeStatementTest3.nestml b/tests/nest_tests/resources/IncludeStatementTest3.nestml new file mode 100644 index 000000000..70999709a --- /dev/null +++ b/tests/nest_tests/resources/IncludeStatementTest3.nestml @@ -0,0 +1,38 @@ +""" +IncludeStatementTest.nestml +########################### + + +Description ++++++++++++ + +Test whether the include statement works as intended. + +Copyright statement ++++++++++++++++++++ + +This file is part of NEST. + +Copyright (C) 2004 The NEST Initiative + +NEST is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +NEST is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with NEST. If not, see . +""" + +model include_statement3: + + state: + v mV = 42 mV + + update: + include "ModelC.nestml" diff --git a/tests/nest_tests/resources/IncludeStatementTest4.nestml b/tests/nest_tests/resources/IncludeStatementTest4.nestml new file mode 100644 index 000000000..7f8d9598e --- /dev/null +++ b/tests/nest_tests/resources/IncludeStatementTest4.nestml @@ -0,0 +1,38 @@ +""" +IncludeStatementTest4.nestml +########################### + + +Description ++++++++++++ + +Test whether the include statement works as intended. + +Copyright statement ++++++++++++++++++++ + +This file is part of NEST. + +Copyright (C) 2004 The NEST Initiative + +NEST is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +NEST is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with NEST. If not, see . +""" + +model include_statement4: + + state: + v mV = 42 mV + + update: + include "ModelD.nestml" diff --git a/tests/nest_tests/resources/ModelA.nestml b/tests/nest_tests/resources/ModelA.nestml new file mode 100644 index 000000000..fb533873a --- /dev/null +++ b/tests/nest_tests/resources/ModelA.nestml @@ -0,0 +1 @@ +v = 2.71 diff --git a/tests/nest_tests/resources/ModelB.nestml b/tests/nest_tests/resources/ModelB.nestml new file mode 100644 index 000000000..f04922e8a --- /dev/null +++ b/tests/nest_tests/resources/ModelB.nestml @@ -0,0 +1 @@ +v += 1 mV diff --git a/tests/nest_tests/resources/ModelC.nestml b/tests/nest_tests/resources/ModelC.nestml new file mode 100644 index 000000000..888d4ae3b --- /dev/null +++ b/tests/nest_tests/resources/ModelC.nestml @@ -0,0 +1 @@ +v += 1 pA diff --git a/tests/nest_tests/resources/ModelD.nestml b/tests/nest_tests/resources/ModelD.nestml new file mode 100644 index 000000000..31e433a1b --- /dev/null +++ b/tests/nest_tests/resources/ModelD.nestml @@ -0,0 +1,4 @@ +v += 1 mV +if v > 100 mV: + v = 0 mV + println("test") diff --git a/tests/nest_tests/test_include_statement.py b/tests/nest_tests/test_include_statement.py new file mode 100644 index 000000000..02dba44a3 --- /dev/null +++ b/tests/nest_tests/test_include_statement.py @@ -0,0 +1,135 @@ +# -*- coding: utf-8 -*- +# +# test_include_statement.py +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . + +import nest +import numpy as np +import scipy as sp +import os + +from pynestml.frontend.pynestml_frontend import generate_nest_target +from pynestml.codegeneration.nest_tools import NESTTools + + +class TestIncludeStatement: + def test_include_statement(self): + input_path = os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), "resources", "IncludeStatementTest.nestml"))) + target_path = "target" + logging_level = "DEBUG" + module_name = "nestmlmodule" + suffix = "_nestml" + + nest.set_verbosity("M_ALL") + generate_nest_target(input_path, + target_path=target_path, + logging_level=logging_level, + module_name=module_name, + suffix=suffix) + nest.ResetKernel() + nest.Install("nestmlmodule") + + nrn = nest.Create("include_statement_nestml") + mm = nest.Create("multimeter") + + nest.SetStatus(mm, {"record_from": ["v"]}) + + nest.Connect(mm, nrn) + + nest.Simulate(100.) + + v = mm.get("events")["v"] + np.testing.assert_allclose(v[-1], 2.71) + + def test_include_statement2(self): + input_path = os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), "resources", "IncludeStatementTest2.nestml"))) + target_path = "target" + logging_level = "DEBUG" + module_name = "nestmlmodule" + suffix = "_nestml" + + nest.set_verbosity("M_ALL") + generate_nest_target(input_path, + target_path=target_path, + logging_level=logging_level, + module_name=module_name, + suffix=suffix) + nest.ResetKernel() + nest.resolution = 0.1 # [ms] + nest.Install("nestmlmodule") + + nrn = nest.Create("include_statement2_nestml") + mm = nest.Create("multimeter") + + nest.SetStatus(mm, {"record_from": ["v"], + "interval": nest.resolution}) + + nest.Connect(mm, nrn) + + nest.Simulate(101.) + + v = mm.get("events")["v"] + np.testing.assert_allclose(v[-1], 1042.) + + def test_include_statement3(self): + r"""check for failure if the included file has wrong unit types""" + input_path = os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), "resources", "IncludeStatementTest3.nestml"))) + target_path = "target" + logging_level = "DEBUG" + module_name = "nestmlmodule" + suffix = "_nestml" + + nest.set_verbosity("M_ALL") + generate_nest_target(input_path, + target_path=target_path, + logging_level=logging_level, + module_name=module_name, + suffix=suffix) + from pynestml.utils.logger import Logger, LoggingLevel + assert len(Logger.get_all_messages_of_level_and_or_node("include_statement3_nestml", LoggingLevel.ERROR)) > 0 + + def test_include_statement4(self): + input_path = os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), "resources", "IncludeStatementTest4.nestml"))) + target_path = "target" + logging_level = "DEBUG" + module_name = "nestmlmodule" + suffix = "_nestml" + + nest.set_verbosity("M_ALL") + generate_nest_target(input_path, + target_path=target_path, + logging_level=logging_level, + module_name=module_name, + suffix=suffix) + nest.ResetKernel() + nest.resolution = 0.1 # [ms] + nest.Install("nestmlmodule") + + nrn = nest.Create("include_statement4_nestml") + mm = nest.Create("multimeter") + + nest.SetStatus(mm, {"record_from": ["v"], + "interval": nest.resolution}) + + nest.Connect(mm, nrn) + + nest.Simulate(151.) + + v = mm.get("events")["v"] + np.testing.assert_allclose(v[-1], 27.) diff --git a/tests/resources/ModelA.nestml b/tests/resources/ModelA.nestml deleted file mode 100644 index b1b1f08e0..000000000 --- a/tests/resources/ModelA.nestml +++ /dev/null @@ -1 +0,0 @@ -println("Hello, world! {v}") diff --git a/tests/test_include_statement.py b/tests/test_include_statement.py deleted file mode 100644 index e7cc71387..000000000 --- a/tests/test_include_statement.py +++ /dev/null @@ -1,35 +0,0 @@ -# -*- coding: utf-8 -*- -# -# test_include_statement.py -# -# This file is part of NEST. -# -# Copyright (C) 2004 The NEST Initiative -# -# NEST is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 2 of the License, or -# (at your option) any later version. -# -# NEST is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with NEST. If not, see . -import os - -from antlr4.CommonTokenStream import CommonTokenStream -from antlr4.FileStream import FileStream -from antlr4.error.ErrorStrategy import BailErrorStrategy -from pynestml.frontend.pynestml_frontend import generate_target - -from pynestml.generated.PyNestMLLexer import PyNestMLLexer -from pynestml.generated.PyNestMLParser import PyNestMLParser - - -class TestIncludeStatement: - def test_include_statement(self): - fname = os.path.realpath(os.path.join(os.path.dirname("__file__"), "tests", "resources", "IncludeStatementTest.nestml")) - generate_target(input_path=fname, target_platform="NONE", logging_level="DEBUG") From 0726cd639958e8f74925bfa09109248501f1bf71 Mon Sep 17 00:00:00 2001 From: "C.A.P. Linssen" Date: Mon, 25 Nov 2024 17:06:52 +0100 Subject: [PATCH 10/25] add include statement --- pynestml/generated/PyNestMLParser.py | 384 +++++++++--------- pynestml/grammars/PyNestMLParser.g4 | 2 +- pynestml/visitors/ast_builder_visitor.py | 7 + .../visitors/ast_include_statement_visitor.py | 85 ++-- pynestml/visitors/ast_visitor.py | 29 ++ .../resources/IncludeStatementTest5.nestml | 36 ++ tests/nest_tests/resources/ModelA.nestml | 2 +- ...tatement_model_test_equations_block.nestml | 2 + ...atement_model_test_parameters_block.nestml | 2 + ...de_statement_model_test_state_block.nestml | 3 + ...e_statement_model_test_update_block.nestml | 4 + tests/nest_tests/test_include_statement.py | 194 +++++---- 12 files changed, 448 insertions(+), 302 deletions(-) create mode 100644 tests/nest_tests/resources/IncludeStatementTest5.nestml create mode 100644 tests/nest_tests/resources/include_statement_model_test_equations_block.nestml create mode 100644 tests/nest_tests/resources/include_statement_model_test_parameters_block.nestml create mode 100644 tests/nest_tests/resources/include_statement_model_test_state_block.nestml create mode 100644 tests/nest_tests/resources/include_statement_model_test_update_block.nestml diff --git a/pynestml/generated/PyNestMLParser.py b/pynestml/generated/PyNestMLParser.py index ef6aa7bda..e4f90d6e4 100644 --- a/pynestml/generated/PyNestMLParser.py +++ b/pynestml/generated/PyNestMLParser.py @@ -10,7 +10,7 @@ def serializedATN(): return [ - 4,1,92,641,2,0,7,0,2,1,7,1,2,2,7,2,2,3,7,3,2,4,7,4,2,5,7,5,2,6,7, + 4,1,92,642,2,0,7,0,2,1,7,1,2,2,7,2,2,3,7,3,2,4,7,4,2,5,7,5,2,6,7, 6,2,7,7,7,2,8,7,8,2,9,7,9,2,10,7,10,2,11,7,11,2,12,7,12,2,13,7,13, 2,14,7,14,2,15,7,15,2,16,7,16,2,17,7,17,2,18,7,18,2,19,7,19,2,20, 7,20,2,21,7,21,2,22,7,22,2,23,7,23,2,24,7,24,2,25,7,25,2,26,7,26, @@ -52,66 +52,66 @@ def serializedATN(): 1,36,1,36,1,36,1,37,1,37,1,37,1,37,1,37,5,37,490,8,37,10,37,12,37, 493,9,37,1,37,1,37,1,37,1,37,1,38,1,38,1,38,1,38,1,38,1,38,4,38, 505,8,38,11,38,12,38,506,1,38,1,38,1,39,1,39,1,39,1,39,1,40,1,40, - 1,40,1,40,1,40,1,40,1,40,4,40,522,8,40,11,40,12,40,523,1,40,1,40, - 1,41,1,41,1,41,1,41,1,41,1,41,3,41,534,8,41,1,41,1,41,1,41,1,41, - 5,41,540,8,41,10,41,12,41,543,9,41,3,41,545,8,41,1,41,3,41,548,8, - 41,4,41,550,8,41,11,41,12,41,551,1,41,1,41,1,42,1,42,1,42,1,42,1, - 42,3,42,561,8,42,1,42,1,42,5,42,565,8,42,10,42,12,42,568,9,42,1, - 42,1,42,1,42,1,43,1,43,1,43,1,43,1,43,3,43,578,8,43,1,43,1,43,1, - 43,1,43,1,43,1,44,1,44,3,44,587,8,44,1,45,1,45,1,45,1,45,1,45,1, - 45,1,45,1,45,1,45,5,45,598,8,45,10,45,12,45,601,9,45,3,45,603,8, - 45,1,45,3,45,606,8,45,1,45,3,45,609,8,45,1,45,1,45,1,45,1,46,1,46, - 1,46,1,46,1,46,1,46,5,46,620,8,46,10,46,12,46,623,9,46,3,46,625, - 8,46,1,46,1,46,3,46,629,8,46,1,46,1,46,1,46,1,47,1,47,1,47,1,48, - 1,48,1,48,1,48,1,48,0,2,2,6,49,0,2,4,6,8,10,12,14,16,18,20,22,24, - 26,28,30,32,34,36,38,40,42,44,46,48,50,52,54,56,58,60,62,64,66,68, - 70,72,74,76,78,80,82,84,86,88,90,92,94,96,0,4,2,0,52,52,76,76,1, - 0,91,92,1,0,33,35,3,0,25,25,88,89,91,92,703,0,104,1,0,0,0,2,115, - 1,0,0,0,4,132,1,0,0,0,6,147,1,0,0,0,8,197,1,0,0,0,10,202,1,0,0,0, - 12,209,1,0,0,0,14,218,1,0,0,0,16,222,1,0,0,0,18,224,1,0,0,0,20,237, - 1,0,0,0,22,252,1,0,0,0,24,270,1,0,0,0,26,284,1,0,0,0,28,303,1,0, - 0,0,30,314,1,0,0,0,32,319,1,0,0,0,34,326,1,0,0,0,36,330,1,0,0,0, - 38,340,1,0,0,0,40,343,1,0,0,0,42,347,1,0,0,0,44,377,1,0,0,0,46,387, - 1,0,0,0,48,389,1,0,0,0,50,391,1,0,0,0,52,393,1,0,0,0,54,397,1,0, - 0,0,56,407,1,0,0,0,58,412,1,0,0,0,60,417,1,0,0,0,62,421,1,0,0,0, - 64,435,1,0,0,0,66,442,1,0,0,0,68,448,1,0,0,0,70,452,1,0,0,0,72,470, - 1,0,0,0,74,484,1,0,0,0,76,498,1,0,0,0,78,510,1,0,0,0,80,514,1,0, - 0,0,82,527,1,0,0,0,84,555,1,0,0,0,86,572,1,0,0,0,88,586,1,0,0,0, - 90,588,1,0,0,0,92,613,1,0,0,0,94,633,1,0,0,0,96,636,1,0,0,0,98,105, - 5,10,0,0,99,105,5,11,0,0,100,105,5,12,0,0,101,105,5,13,0,0,102,105, - 5,14,0,0,103,105,3,2,1,0,104,98,1,0,0,0,104,99,1,0,0,0,104,100,1, - 0,0,0,104,101,1,0,0,0,104,102,1,0,0,0,104,103,1,0,0,0,105,1,1,0, - 0,0,106,107,6,1,-1,0,107,108,5,50,0,0,108,109,3,2,1,0,109,110,5, - 51,0,0,110,116,1,0,0,0,111,112,5,91,0,0,112,113,5,80,0,0,113,116, - 3,2,1,2,114,116,5,90,0,0,115,106,1,0,0,0,115,111,1,0,0,0,115,114, - 1,0,0,0,116,128,1,0,0,0,117,120,10,3,0,0,118,121,5,78,0,0,119,121, - 5,80,0,0,120,118,1,0,0,0,120,119,1,0,0,0,121,122,1,0,0,0,122,127, - 3,2,1,4,123,124,10,4,0,0,124,125,5,79,0,0,125,127,3,4,2,0,126,117, - 1,0,0,0,126,123,1,0,0,0,127,130,1,0,0,0,128,126,1,0,0,0,128,129, - 1,0,0,0,129,3,1,0,0,0,130,128,1,0,0,0,131,133,7,0,0,0,132,131,1, - 0,0,0,132,133,1,0,0,0,133,134,1,0,0,0,134,135,5,91,0,0,135,5,1,0, - 0,0,136,137,6,3,-1,0,137,138,5,50,0,0,138,139,3,6,3,0,139,140,5, - 51,0,0,140,148,1,0,0,0,141,142,3,10,5,0,142,143,3,6,3,9,143,148, - 1,0,0,0,144,145,5,28,0,0,145,148,3,6,3,4,146,148,3,8,4,0,147,136, - 1,0,0,0,147,141,1,0,0,0,147,144,1,0,0,0,147,146,1,0,0,0,148,185, - 1,0,0,0,149,150,10,10,0,0,150,151,5,79,0,0,151,184,3,6,3,10,152, - 156,10,8,0,0,153,157,5,78,0,0,154,157,5,80,0,0,155,157,5,81,0,0, - 156,153,1,0,0,0,156,154,1,0,0,0,156,155,1,0,0,0,157,158,1,0,0,0, - 158,184,3,6,3,9,159,162,10,7,0,0,160,163,5,52,0,0,161,163,5,76,0, - 0,162,160,1,0,0,0,162,161,1,0,0,0,163,164,1,0,0,0,164,184,3,6,3, - 8,165,166,10,6,0,0,166,167,3,12,6,0,167,168,3,6,3,7,168,184,1,0, - 0,0,169,170,10,5,0,0,170,171,3,14,7,0,171,172,3,6,3,6,172,184,1, - 0,0,0,173,174,10,3,0,0,174,175,3,16,8,0,175,176,3,6,3,4,176,184, - 1,0,0,0,177,178,10,2,0,0,178,179,5,82,0,0,179,180,3,6,3,0,180,181, - 5,83,0,0,181,182,3,6,3,3,182,184,1,0,0,0,183,149,1,0,0,0,183,152, - 1,0,0,0,183,159,1,0,0,0,183,165,1,0,0,0,183,169,1,0,0,0,183,173, - 1,0,0,0,183,177,1,0,0,0,184,187,1,0,0,0,185,183,1,0,0,0,185,186, - 1,0,0,0,186,7,1,0,0,0,187,185,1,0,0,0,188,198,3,20,10,0,189,198, - 5,88,0,0,190,192,7,1,0,0,191,193,3,18,9,0,192,191,1,0,0,0,192,193, - 1,0,0,0,193,198,1,0,0,0,194,198,5,89,0,0,195,198,5,25,0,0,196,198, - 3,18,9,0,197,188,1,0,0,0,197,189,1,0,0,0,197,190,1,0,0,0,197,194, - 1,0,0,0,197,195,1,0,0,0,197,196,1,0,0,0,198,9,1,0,0,0,199,203,5, - 52,0,0,200,203,5,76,0,0,201,203,5,53,0,0,202,199,1,0,0,0,202,200, + 1,40,1,40,1,40,1,40,1,40,1,40,4,40,523,8,40,11,40,12,40,524,1,40, + 1,40,1,41,1,41,1,41,1,41,1,41,1,41,3,41,535,8,41,1,41,1,41,1,41, + 1,41,5,41,541,8,41,10,41,12,41,544,9,41,3,41,546,8,41,1,41,3,41, + 549,8,41,4,41,551,8,41,11,41,12,41,552,1,41,1,41,1,42,1,42,1,42, + 1,42,1,42,3,42,562,8,42,1,42,1,42,5,42,566,8,42,10,42,12,42,569, + 9,42,1,42,1,42,1,42,1,43,1,43,1,43,1,43,1,43,3,43,579,8,43,1,43, + 1,43,1,43,1,43,1,43,1,44,1,44,3,44,588,8,44,1,45,1,45,1,45,1,45, + 1,45,1,45,1,45,1,45,1,45,5,45,599,8,45,10,45,12,45,602,9,45,3,45, + 604,8,45,1,45,3,45,607,8,45,1,45,3,45,610,8,45,1,45,1,45,1,45,1, + 46,1,46,1,46,1,46,1,46,1,46,5,46,621,8,46,10,46,12,46,624,9,46,3, + 46,626,8,46,1,46,1,46,3,46,630,8,46,1,46,1,46,1,46,1,47,1,47,1,47, + 1,48,1,48,1,48,1,48,1,48,0,2,2,6,49,0,2,4,6,8,10,12,14,16,18,20, + 22,24,26,28,30,32,34,36,38,40,42,44,46,48,50,52,54,56,58,60,62,64, + 66,68,70,72,74,76,78,80,82,84,86,88,90,92,94,96,0,4,2,0,52,52,76, + 76,1,0,91,92,1,0,33,35,3,0,25,25,88,89,91,92,705,0,104,1,0,0,0,2, + 115,1,0,0,0,4,132,1,0,0,0,6,147,1,0,0,0,8,197,1,0,0,0,10,202,1,0, + 0,0,12,209,1,0,0,0,14,218,1,0,0,0,16,222,1,0,0,0,18,224,1,0,0,0, + 20,237,1,0,0,0,22,252,1,0,0,0,24,270,1,0,0,0,26,284,1,0,0,0,28,303, + 1,0,0,0,30,314,1,0,0,0,32,319,1,0,0,0,34,326,1,0,0,0,36,330,1,0, + 0,0,38,340,1,0,0,0,40,343,1,0,0,0,42,347,1,0,0,0,44,377,1,0,0,0, + 46,387,1,0,0,0,48,389,1,0,0,0,50,391,1,0,0,0,52,393,1,0,0,0,54,397, + 1,0,0,0,56,407,1,0,0,0,58,412,1,0,0,0,60,417,1,0,0,0,62,421,1,0, + 0,0,64,435,1,0,0,0,66,442,1,0,0,0,68,448,1,0,0,0,70,452,1,0,0,0, + 72,470,1,0,0,0,74,484,1,0,0,0,76,498,1,0,0,0,78,510,1,0,0,0,80,514, + 1,0,0,0,82,528,1,0,0,0,84,556,1,0,0,0,86,573,1,0,0,0,88,587,1,0, + 0,0,90,589,1,0,0,0,92,614,1,0,0,0,94,634,1,0,0,0,96,637,1,0,0,0, + 98,105,5,10,0,0,99,105,5,11,0,0,100,105,5,12,0,0,101,105,5,13,0, + 0,102,105,5,14,0,0,103,105,3,2,1,0,104,98,1,0,0,0,104,99,1,0,0,0, + 104,100,1,0,0,0,104,101,1,0,0,0,104,102,1,0,0,0,104,103,1,0,0,0, + 105,1,1,0,0,0,106,107,6,1,-1,0,107,108,5,50,0,0,108,109,3,2,1,0, + 109,110,5,51,0,0,110,116,1,0,0,0,111,112,5,91,0,0,112,113,5,80,0, + 0,113,116,3,2,1,2,114,116,5,90,0,0,115,106,1,0,0,0,115,111,1,0,0, + 0,115,114,1,0,0,0,116,128,1,0,0,0,117,120,10,3,0,0,118,121,5,78, + 0,0,119,121,5,80,0,0,120,118,1,0,0,0,120,119,1,0,0,0,121,122,1,0, + 0,0,122,127,3,2,1,4,123,124,10,4,0,0,124,125,5,79,0,0,125,127,3, + 4,2,0,126,117,1,0,0,0,126,123,1,0,0,0,127,130,1,0,0,0,128,126,1, + 0,0,0,128,129,1,0,0,0,129,3,1,0,0,0,130,128,1,0,0,0,131,133,7,0, + 0,0,132,131,1,0,0,0,132,133,1,0,0,0,133,134,1,0,0,0,134,135,5,91, + 0,0,135,5,1,0,0,0,136,137,6,3,-1,0,137,138,5,50,0,0,138,139,3,6, + 3,0,139,140,5,51,0,0,140,148,1,0,0,0,141,142,3,10,5,0,142,143,3, + 6,3,9,143,148,1,0,0,0,144,145,5,28,0,0,145,148,3,6,3,4,146,148,3, + 8,4,0,147,136,1,0,0,0,147,141,1,0,0,0,147,144,1,0,0,0,147,146,1, + 0,0,0,148,185,1,0,0,0,149,150,10,10,0,0,150,151,5,79,0,0,151,184, + 3,6,3,10,152,156,10,8,0,0,153,157,5,78,0,0,154,157,5,80,0,0,155, + 157,5,81,0,0,156,153,1,0,0,0,156,154,1,0,0,0,156,155,1,0,0,0,157, + 158,1,0,0,0,158,184,3,6,3,9,159,162,10,7,0,0,160,163,5,52,0,0,161, + 163,5,76,0,0,162,160,1,0,0,0,162,161,1,0,0,0,163,164,1,0,0,0,164, + 184,3,6,3,8,165,166,10,6,0,0,166,167,3,12,6,0,167,168,3,6,3,7,168, + 184,1,0,0,0,169,170,10,5,0,0,170,171,3,14,7,0,171,172,3,6,3,6,172, + 184,1,0,0,0,173,174,10,3,0,0,174,175,3,16,8,0,175,176,3,6,3,4,176, + 184,1,0,0,0,177,178,10,2,0,0,178,179,5,82,0,0,179,180,3,6,3,0,180, + 181,5,83,0,0,181,182,3,6,3,3,182,184,1,0,0,0,183,149,1,0,0,0,183, + 152,1,0,0,0,183,159,1,0,0,0,183,165,1,0,0,0,183,169,1,0,0,0,183, + 173,1,0,0,0,183,177,1,0,0,0,184,187,1,0,0,0,185,183,1,0,0,0,185, + 186,1,0,0,0,186,7,1,0,0,0,187,185,1,0,0,0,188,198,3,20,10,0,189, + 198,5,88,0,0,190,192,7,1,0,0,191,193,3,18,9,0,192,191,1,0,0,0,192, + 193,1,0,0,0,193,198,1,0,0,0,194,198,5,89,0,0,195,198,5,25,0,0,196, + 198,3,18,9,0,197,188,1,0,0,0,197,189,1,0,0,0,197,190,1,0,0,0,197, + 194,1,0,0,0,197,195,1,0,0,0,197,196,1,0,0,0,198,9,1,0,0,0,199,203, + 5,52,0,0,200,203,5,76,0,0,201,203,5,53,0,0,202,199,1,0,0,0,202,200, 1,0,0,0,202,201,1,0,0,0,203,11,1,0,0,0,204,210,5,56,0,0,205,210, 5,55,0,0,206,210,5,54,0,0,207,210,5,62,0,0,208,210,5,63,0,0,209, 204,1,0,0,0,209,205,1,0,0,0,209,206,1,0,0,0,209,207,1,0,0,0,209, @@ -206,47 +206,48 @@ def serializedATN(): 504,502,1,0,0,0,504,503,1,0,0,0,505,506,1,0,0,0,506,504,1,0,0,0, 506,507,1,0,0,0,507,508,1,0,0,0,508,509,5,2,0,0,509,77,1,0,0,0,510, 511,5,36,0,0,511,512,5,83,0,0,512,513,3,28,14,0,513,79,1,0,0,0,514, - 515,5,37,0,0,515,516,5,83,0,0,516,517,5,9,0,0,517,521,5,1,0,0,518, - 522,3,22,11,0,519,522,3,24,12,0,520,522,3,26,13,0,521,518,1,0,0, - 0,521,519,1,0,0,0,521,520,1,0,0,0,522,523,1,0,0,0,523,521,1,0,0, - 0,523,524,1,0,0,0,524,525,1,0,0,0,525,526,5,2,0,0,526,81,1,0,0,0, - 527,528,5,38,0,0,528,529,5,83,0,0,529,530,5,9,0,0,530,549,5,1,0, - 0,531,534,3,84,42,0,532,534,3,86,43,0,533,531,1,0,0,0,533,532,1, - 0,0,0,534,547,1,0,0,0,535,544,5,50,0,0,536,541,3,94,47,0,537,538, - 5,75,0,0,538,540,3,94,47,0,539,537,1,0,0,0,540,543,1,0,0,0,541,539, - 1,0,0,0,541,542,1,0,0,0,542,545,1,0,0,0,543,541,1,0,0,0,544,536, - 1,0,0,0,544,545,1,0,0,0,545,546,1,0,0,0,546,548,5,51,0,0,547,535, - 1,0,0,0,547,548,1,0,0,0,548,550,1,0,0,0,549,533,1,0,0,0,550,551, - 1,0,0,0,551,549,1,0,0,0,551,552,1,0,0,0,552,553,1,0,0,0,553,554, - 5,2,0,0,554,83,1,0,0,0,555,560,5,90,0,0,556,557,5,57,0,0,557,558, - 3,6,3,0,558,559,5,59,0,0,559,561,1,0,0,0,560,556,1,0,0,0,560,561, - 1,0,0,0,561,562,1,0,0,0,562,566,5,58,0,0,563,565,3,88,44,0,564,563, - 1,0,0,0,565,568,1,0,0,0,566,564,1,0,0,0,566,567,1,0,0,0,567,569, - 1,0,0,0,568,566,1,0,0,0,569,570,5,43,0,0,570,571,5,9,0,0,571,85, - 1,0,0,0,572,577,5,90,0,0,573,574,5,57,0,0,574,575,3,6,3,0,575,576, - 5,59,0,0,576,578,1,0,0,0,577,573,1,0,0,0,577,578,1,0,0,0,578,579, - 1,0,0,0,579,580,3,0,0,0,580,581,5,58,0,0,581,582,5,40,0,0,582,583, - 5,9,0,0,583,87,1,0,0,0,584,587,5,44,0,0,585,587,5,45,0,0,586,584, - 1,0,0,0,586,585,1,0,0,0,587,89,1,0,0,0,588,589,5,39,0,0,589,590, - 5,83,0,0,590,591,5,9,0,0,591,608,5,1,0,0,592,605,5,43,0,0,593,602, - 5,50,0,0,594,599,3,94,47,0,595,596,5,75,0,0,596,598,3,94,47,0,597, - 595,1,0,0,0,598,601,1,0,0,0,599,597,1,0,0,0,599,600,1,0,0,0,600, - 603,1,0,0,0,601,599,1,0,0,0,602,594,1,0,0,0,602,603,1,0,0,0,603, - 604,1,0,0,0,604,606,5,51,0,0,605,593,1,0,0,0,605,606,1,0,0,0,606, - 609,1,0,0,0,607,609,5,40,0,0,608,592,1,0,0,0,608,607,1,0,0,0,609, - 610,1,0,0,0,610,611,5,9,0,0,611,612,5,2,0,0,612,91,1,0,0,0,613,614, - 5,15,0,0,614,615,5,90,0,0,615,624,5,50,0,0,616,621,3,94,47,0,617, - 618,5,75,0,0,618,620,3,94,47,0,619,617,1,0,0,0,620,623,1,0,0,0,621, - 619,1,0,0,0,621,622,1,0,0,0,622,625,1,0,0,0,623,621,1,0,0,0,624, - 616,1,0,0,0,624,625,1,0,0,0,625,626,1,0,0,0,626,628,5,51,0,0,627, - 629,3,0,0,0,628,627,1,0,0,0,628,629,1,0,0,0,629,630,1,0,0,0,630, - 631,5,83,0,0,631,632,3,28,14,0,632,93,1,0,0,0,633,634,5,90,0,0,634, - 635,3,0,0,0,635,95,1,0,0,0,636,637,5,90,0,0,637,638,5,77,0,0,638, - 639,7,3,0,0,639,97,1,0,0,0,70,104,115,120,126,128,132,147,156,162, - 183,185,192,197,202,209,218,222,229,234,244,247,252,260,265,274, - 279,295,299,308,314,319,326,336,347,350,357,363,369,374,387,395, - 401,405,429,442,444,464,466,477,491,504,506,521,523,533,541,544, - 547,551,560,566,577,586,599,602,605,608,621,624,628 + 515,5,37,0,0,515,516,5,83,0,0,516,517,5,9,0,0,517,522,5,1,0,0,518, + 523,3,22,11,0,519,523,3,24,12,0,520,523,3,26,13,0,521,523,3,40,20, + 0,522,518,1,0,0,0,522,519,1,0,0,0,522,520,1,0,0,0,522,521,1,0,0, + 0,523,524,1,0,0,0,524,522,1,0,0,0,524,525,1,0,0,0,525,526,1,0,0, + 0,526,527,5,2,0,0,527,81,1,0,0,0,528,529,5,38,0,0,529,530,5,83,0, + 0,530,531,5,9,0,0,531,550,5,1,0,0,532,535,3,84,42,0,533,535,3,86, + 43,0,534,532,1,0,0,0,534,533,1,0,0,0,535,548,1,0,0,0,536,545,5,50, + 0,0,537,542,3,94,47,0,538,539,5,75,0,0,539,541,3,94,47,0,540,538, + 1,0,0,0,541,544,1,0,0,0,542,540,1,0,0,0,542,543,1,0,0,0,543,546, + 1,0,0,0,544,542,1,0,0,0,545,537,1,0,0,0,545,546,1,0,0,0,546,547, + 1,0,0,0,547,549,5,51,0,0,548,536,1,0,0,0,548,549,1,0,0,0,549,551, + 1,0,0,0,550,534,1,0,0,0,551,552,1,0,0,0,552,550,1,0,0,0,552,553, + 1,0,0,0,553,554,1,0,0,0,554,555,5,2,0,0,555,83,1,0,0,0,556,561,5, + 90,0,0,557,558,5,57,0,0,558,559,3,6,3,0,559,560,5,59,0,0,560,562, + 1,0,0,0,561,557,1,0,0,0,561,562,1,0,0,0,562,563,1,0,0,0,563,567, + 5,58,0,0,564,566,3,88,44,0,565,564,1,0,0,0,566,569,1,0,0,0,567,565, + 1,0,0,0,567,568,1,0,0,0,568,570,1,0,0,0,569,567,1,0,0,0,570,571, + 5,43,0,0,571,572,5,9,0,0,572,85,1,0,0,0,573,578,5,90,0,0,574,575, + 5,57,0,0,575,576,3,6,3,0,576,577,5,59,0,0,577,579,1,0,0,0,578,574, + 1,0,0,0,578,579,1,0,0,0,579,580,1,0,0,0,580,581,3,0,0,0,581,582, + 5,58,0,0,582,583,5,40,0,0,583,584,5,9,0,0,584,87,1,0,0,0,585,588, + 5,44,0,0,586,588,5,45,0,0,587,585,1,0,0,0,587,586,1,0,0,0,588,89, + 1,0,0,0,589,590,5,39,0,0,590,591,5,83,0,0,591,592,5,9,0,0,592,609, + 5,1,0,0,593,606,5,43,0,0,594,603,5,50,0,0,595,600,3,94,47,0,596, + 597,5,75,0,0,597,599,3,94,47,0,598,596,1,0,0,0,599,602,1,0,0,0,600, + 598,1,0,0,0,600,601,1,0,0,0,601,604,1,0,0,0,602,600,1,0,0,0,603, + 595,1,0,0,0,603,604,1,0,0,0,604,605,1,0,0,0,605,607,5,51,0,0,606, + 594,1,0,0,0,606,607,1,0,0,0,607,610,1,0,0,0,608,610,5,40,0,0,609, + 593,1,0,0,0,609,608,1,0,0,0,610,611,1,0,0,0,611,612,5,9,0,0,612, + 613,5,2,0,0,613,91,1,0,0,0,614,615,5,15,0,0,615,616,5,90,0,0,616, + 625,5,50,0,0,617,622,3,94,47,0,618,619,5,75,0,0,619,621,3,94,47, + 0,620,618,1,0,0,0,621,624,1,0,0,0,622,620,1,0,0,0,622,623,1,0,0, + 0,623,626,1,0,0,0,624,622,1,0,0,0,625,617,1,0,0,0,625,626,1,0,0, + 0,626,627,1,0,0,0,627,629,5,51,0,0,628,630,3,0,0,0,629,628,1,0,0, + 0,629,630,1,0,0,0,630,631,1,0,0,0,631,632,5,83,0,0,632,633,3,28, + 14,0,633,93,1,0,0,0,634,635,5,90,0,0,635,636,3,0,0,0,636,95,1,0, + 0,0,637,638,5,90,0,0,638,639,5,77,0,0,639,640,7,3,0,0,640,97,1,0, + 0,0,70,104,115,120,126,128,132,147,156,162,183,185,192,197,202,209, + 218,222,229,234,244,247,252,260,265,274,279,295,299,308,314,319, + 326,336,347,350,357,363,369,374,387,395,401,405,429,442,444,464, + 466,477,491,504,506,522,524,534,542,545,548,552,561,567,578,587, + 600,603,606,609,622,625,629 ] class PyNestMLParser ( Parser ): @@ -3902,6 +3903,13 @@ def kernel(self, i:int=None): return self.getTypedRuleContext(PyNestMLParser.KernelContext,i) + def includeStmt_newline(self, i:int=None): + if i is None: + return self.getTypedRuleContexts(PyNestMLParser.IncludeStmt_newlineContext) + else: + return self.getTypedRuleContext(PyNestMLParser.IncludeStmt_newlineContext,i) + + def getRuleIndex(self): return PyNestMLParser.RULE_equationsBlock @@ -3929,11 +3937,11 @@ def equationsBlock(self): self.match(PyNestMLParser.NEWLINE) self.state = 517 self.match(PyNestMLParser.INDENT) - self.state = 521 + self.state = 522 self._errHandler.sync(self) _la = self._input.LA(1) while True: - self.state = 521 + self.state = 522 self._errHandler.sync(self) token = self._input.LA(1) if token in [16, 30]: @@ -3948,16 +3956,20 @@ def equationsBlock(self): self.state = 520 self.kernel() pass + elif token in [29]: + self.state = 521 + self.includeStmt_newline() + pass else: raise NoViableAltException(self) - self.state = 523 + self.state = 524 self._errHandler.sync(self) _la = self._input.LA(1) - if not ((((_la) & ~0x3f) == 0 and ((1 << _la) & 3221291008) != 0) or _la==90): + if not ((((_la) & ~0x3f) == 0 and ((1 << _la) & 3758161920) != 0) or _la==90): break - self.state = 525 + self.state = 526 self.match(PyNestMLParser.DEDENT) except RecognitionException as re: localctx.exception = re @@ -4048,69 +4060,69 @@ def inputBlock(self): self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 527 - self.match(PyNestMLParser.INPUT_KEYWORD) self.state = 528 - self.match(PyNestMLParser.COLON) + self.match(PyNestMLParser.INPUT_KEYWORD) self.state = 529 - self.match(PyNestMLParser.NEWLINE) + self.match(PyNestMLParser.COLON) self.state = 530 + self.match(PyNestMLParser.NEWLINE) + self.state = 531 self.match(PyNestMLParser.INDENT) - self.state = 549 + self.state = 550 self._errHandler.sync(self) _la = self._input.LA(1) while True: - self.state = 533 + self.state = 534 self._errHandler.sync(self) la_ = self._interp.adaptivePredict(self._input,54,self._ctx) if la_ == 1: - self.state = 531 + self.state = 532 self.spikeInputPort() pass elif la_ == 2: - self.state = 532 + self.state = 533 self.continuousInputPort() pass - self.state = 547 + self.state = 548 self._errHandler.sync(self) _la = self._input.LA(1) if _la==50: - self.state = 535 + self.state = 536 self.match(PyNestMLParser.LEFT_PAREN) - self.state = 544 + self.state = 545 self._errHandler.sync(self) _la = self._input.LA(1) if _la==90: - self.state = 536 + self.state = 537 self.parameter() - self.state = 541 + self.state = 542 self._errHandler.sync(self) _la = self._input.LA(1) while _la==75: - self.state = 537 - self.match(PyNestMLParser.COMMA) self.state = 538 + self.match(PyNestMLParser.COMMA) + self.state = 539 self.parameter() - self.state = 543 + self.state = 544 self._errHandler.sync(self) _la = self._input.LA(1) - self.state = 546 + self.state = 547 self.match(PyNestMLParser.RIGHT_PAREN) - self.state = 551 + self.state = 552 self._errHandler.sync(self) _la = self._input.LA(1) if not (_la==90): break - self.state = 553 + self.state = 554 self.match(PyNestMLParser.DEDENT) except RecognitionException as re: localctx.exception = re @@ -4178,35 +4190,35 @@ def spikeInputPort(self): self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 555 + self.state = 556 localctx.name = self.match(PyNestMLParser.NAME) - self.state = 560 + self.state = 561 self._errHandler.sync(self) _la = self._input.LA(1) if _la==57: - self.state = 556 - self.match(PyNestMLParser.LEFT_SQUARE_BRACKET) self.state = 557 - localctx.sizeParameter = self.expression(0) + self.match(PyNestMLParser.LEFT_SQUARE_BRACKET) self.state = 558 + localctx.sizeParameter = self.expression(0) + self.state = 559 self.match(PyNestMLParser.RIGHT_SQUARE_BRACKET) - self.state = 562 + self.state = 563 self.match(PyNestMLParser.LEFT_ANGLE_MINUS) - self.state = 566 + self.state = 567 self._errHandler.sync(self) _la = self._input.LA(1) while _la==44 or _la==45: - self.state = 563 + self.state = 564 self.inputQualifier() - self.state = 568 + self.state = 569 self._errHandler.sync(self) _la = self._input.LA(1) - self.state = 569 - self.match(PyNestMLParser.SPIKE_KEYWORD) self.state = 570 + self.match(PyNestMLParser.SPIKE_KEYWORD) + self.state = 571 self.match(PyNestMLParser.NEWLINE) except RecognitionException as re: localctx.exception = re @@ -4271,27 +4283,27 @@ def continuousInputPort(self): self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 572 + self.state = 573 localctx.name = self.match(PyNestMLParser.NAME) - self.state = 577 + self.state = 578 self._errHandler.sync(self) _la = self._input.LA(1) if _la==57: - self.state = 573 - self.match(PyNestMLParser.LEFT_SQUARE_BRACKET) self.state = 574 - localctx.sizeParameter = self.expression(0) + self.match(PyNestMLParser.LEFT_SQUARE_BRACKET) self.state = 575 + localctx.sizeParameter = self.expression(0) + self.state = 576 self.match(PyNestMLParser.RIGHT_SQUARE_BRACKET) - self.state = 579 - self.dataType() self.state = 580 - self.match(PyNestMLParser.LEFT_ANGLE_MINUS) + self.dataType() self.state = 581 - self.match(PyNestMLParser.CONTINUOUS_KEYWORD) + self.match(PyNestMLParser.LEFT_ANGLE_MINUS) self.state = 582 + self.match(PyNestMLParser.CONTINUOUS_KEYWORD) + self.state = 583 self.match(PyNestMLParser.NEWLINE) except RecognitionException as re: localctx.exception = re @@ -4335,15 +4347,15 @@ def inputQualifier(self): self.enterRule(localctx, 88, self.RULE_inputQualifier) try: self.enterOuterAlt(localctx, 1) - self.state = 586 + self.state = 587 self._errHandler.sync(self) token = self._input.LA(1) if token in [44]: - self.state = 584 + self.state = 585 localctx.isInhibitory = self.match(PyNestMLParser.INHIBITORY_KEYWORD) pass elif token in [45]: - self.state = 585 + self.state = 586 localctx.isExcitatory = self.match(PyNestMLParser.EXCITATORY_KEYWORD) pass else: @@ -4430,61 +4442,61 @@ def outputBlock(self): self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 588 - self.match(PyNestMLParser.OUTPUT_KEYWORD) self.state = 589 - self.match(PyNestMLParser.COLON) + self.match(PyNestMLParser.OUTPUT_KEYWORD) self.state = 590 - self.match(PyNestMLParser.NEWLINE) + self.match(PyNestMLParser.COLON) self.state = 591 + self.match(PyNestMLParser.NEWLINE) + self.state = 592 self.match(PyNestMLParser.INDENT) - self.state = 608 + self.state = 609 self._errHandler.sync(self) token = self._input.LA(1) if token in [43]: - self.state = 592 + self.state = 593 localctx.isSpike = self.match(PyNestMLParser.SPIKE_KEYWORD) - self.state = 605 + self.state = 606 self._errHandler.sync(self) _la = self._input.LA(1) if _la==50: - self.state = 593 + self.state = 594 self.match(PyNestMLParser.LEFT_PAREN) - self.state = 602 + self.state = 603 self._errHandler.sync(self) _la = self._input.LA(1) if _la==90: - self.state = 594 + self.state = 595 localctx.attribute = self.parameter() - self.state = 599 + self.state = 600 self._errHandler.sync(self) _la = self._input.LA(1) while _la==75: - self.state = 595 - self.match(PyNestMLParser.COMMA) self.state = 596 + self.match(PyNestMLParser.COMMA) + self.state = 597 localctx.attribute = self.parameter() - self.state = 601 + self.state = 602 self._errHandler.sync(self) _la = self._input.LA(1) - self.state = 604 + self.state = 605 self.match(PyNestMLParser.RIGHT_PAREN) pass elif token in [40]: - self.state = 607 + self.state = 608 localctx.isContinuous = self.match(PyNestMLParser.CONTINUOUS_KEYWORD) pass else: raise NoViableAltException(self) - self.state = 610 - self.match(PyNestMLParser.NEWLINE) self.state = 611 + self.match(PyNestMLParser.NEWLINE) + self.state = 612 self.match(PyNestMLParser.DEDENT) except RecognitionException as re: localctx.exception = re @@ -4558,45 +4570,45 @@ def function(self): self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 613 - self.match(PyNestMLParser.FUNCTION_KEYWORD) self.state = 614 - self.match(PyNestMLParser.NAME) + self.match(PyNestMLParser.FUNCTION_KEYWORD) self.state = 615 + self.match(PyNestMLParser.NAME) + self.state = 616 self.match(PyNestMLParser.LEFT_PAREN) - self.state = 624 + self.state = 625 self._errHandler.sync(self) _la = self._input.LA(1) if _la==90: - self.state = 616 + self.state = 617 self.parameter() - self.state = 621 + self.state = 622 self._errHandler.sync(self) _la = self._input.LA(1) while _la==75: - self.state = 617 - self.match(PyNestMLParser.COMMA) self.state = 618 + self.match(PyNestMLParser.COMMA) + self.state = 619 self.parameter() - self.state = 623 + self.state = 624 self._errHandler.sync(self) _la = self._input.LA(1) - self.state = 626 + self.state = 627 self.match(PyNestMLParser.RIGHT_PAREN) - self.state = 628 + self.state = 629 self._errHandler.sync(self) _la = self._input.LA(1) if (((_la) & ~0x3f) == 0 and ((1 << _la) & 1125899906874368) != 0) or _la==90 or _la==91: - self.state = 627 + self.state = 628 localctx.returnType = self.dataType() - self.state = 630 - self.match(PyNestMLParser.COLON) self.state = 631 + self.match(PyNestMLParser.COLON) + self.state = 632 self.block() except RecognitionException as re: localctx.exception = re @@ -4639,9 +4651,9 @@ def parameter(self): self.enterRule(localctx, 94, self.RULE_parameter) try: self.enterOuterAlt(localctx, 1) - self.state = 633 - self.match(PyNestMLParser.NAME) self.state = 634 + self.match(PyNestMLParser.NAME) + self.state = 635 self.dataType() except RecognitionException as re: localctx.exception = re @@ -4701,11 +4713,11 @@ def constParameter(self): self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 636 - localctx.name = self.match(PyNestMLParser.NAME) self.state = 637 - self.match(PyNestMLParser.EQUALS) + localctx.name = self.match(PyNestMLParser.NAME) self.state = 638 + self.match(PyNestMLParser.EQUALS) + self.state = 639 localctx.value = self._input.LT(1) _la = self._input.LA(1) if not(_la==25 or ((((_la - 88)) & ~0x3f) == 0 and ((1 << (_la - 88)) & 27) != 0)): diff --git a/pynestml/grammars/PyNestMLParser.g4 b/pynestml/grammars/PyNestMLParser.g4 index 2f052b795..4f122c731 100644 --- a/pynestml/grammars/PyNestMLParser.g4 +++ b/pynestml/grammars/PyNestMLParser.g4 @@ -279,7 +279,7 @@ parser grammar PyNestMLParser; @attribute odeEquation: A single ode equation statement, e.g., V_m' = ... */ equationsBlock: EQUATIONS_KEYWORD COLON - NEWLINE INDENT ( inlineExpression | odeEquation | kernel )+ DEDENT; + NEWLINE INDENT ( inlineExpression | odeEquation | kernel | includeStmt_newline )+ DEDENT; /** ASTInputBlock represents a single input block, e.g.: input: diff --git a/pynestml/visitors/ast_builder_visitor.py b/pynestml/visitors/ast_builder_visitor.py index a8d040d41..a2d5319c7 100644 --- a/pynestml/visitors/ast_builder_visitor.py +++ b/pynestml/visitors/ast_builder_visitor.py @@ -405,6 +405,10 @@ def visitReturnStmt(self, ctx): ret_expression = self.visit(ctx.expression()) if ctx.expression() is not None else None return ASTNodeFactory.create_ast_return_stmt(expression=ret_expression, source_position=create_source_pos(ctx)) + # Visit a parse tree produced by PyNESTMLParser#returnStmt. + def visitIncludeStmt_newline(self, ctx): + return self.visitIncludeStmt(ctx.includeStmt()) + # Visit a parse tree produced by PyNESTMLParser#returnStmt. def visitIncludeStmt(self, ctx): filename = ctx.filename.text[1:-1] # strip quotation marks @@ -517,6 +521,9 @@ def visitModelBody(self, ctx): """ body_elements = list() # visit all var_block children + if ctx.includeStmt_newline() is not None: + for child in ctx.includeStmt_newline(): + body_elements.append(child) if ctx.onReceiveBlock() is not None: for child in ctx.onReceiveBlock(): body_elements.append(child) diff --git a/pynestml/visitors/ast_include_statement_visitor.py b/pynestml/visitors/ast_include_statement_visitor.py index 76b373bd5..efde46ace 100644 --- a/pynestml/visitors/ast_include_statement_visitor.py +++ b/pynestml/visitors/ast_include_statement_visitor.py @@ -24,8 +24,11 @@ import os from pynestml.meta_model.ast_block import ASTBlock +from pynestml.meta_model.ast_block_with_variables import ASTBlockWithVariables from pynestml.meta_model.ast_equations_block import ASTEquationsBlock from pynestml.meta_model.ast_expression import ASTExpression +from pynestml.meta_model.ast_include_stmt import ASTIncludeStmt +from pynestml.meta_model.ast_model_body import ASTModelBody from pynestml.meta_model.ast_small_stmt import ASTSmallStmt from pynestml.meta_model.ast_stmt import ASTStmt from pynestml.meta_model.ast_update_block import ASTUpdateBlock @@ -49,51 +52,67 @@ def __init__(self, model_path: Optional[str]): super().__init__() self.model_path = model_path - def visit_update_block(self, node: ASTUpdateBlock): - """ - :param expr: an expression - """ - print(node) + def visit_include_stmt(self, node: ASTIncludeStmt): + self._handle_include_stmt(node) def visit_small_stmt(self, node: ASTSmallStmt): """ :param expr: an expression """ if node.is_include_stmt(): - filename = node.get_include_stmt().get_filename() - if not os.path.isabs(filename): - filename = os.path.join(self.model_path, filename) - - parsed_included_file = ModelParser.parse_included_file(filename) - - if isinstance(parsed_included_file, list): - new_stmts = parsed_included_file - - if isinstance(node.get_parent().get_parent(), ASTBlock): - blk = node.get_parent().get_parent() - idx = blk.get_stmts().index(node.get_parent()) - blk.get_stmts().pop(idx) - blk.stmts = blk.stmts[:idx] + new_stmts + blk.stmts[idx:] - for new_stmt in new_stmts: - new_stmt.parent_ = blk - blk.accept(ASTParentVisitor()) + self._handle_include_stmt(node.get_include_stmt()) - elif isinstance(node.get_parent().get_parent(), ASTEquationsBlock): - print("not handled yet") + def _handle_include_stmt(self, node: ASTIncludeStmt): + filename = node.get_filename() + if not os.path.isabs(filename): + filename = os.path.join(self.model_path, filename) + parsed_included_file = ModelParser.parse_included_file(filename) - elif isinstance(parsed_included_file, ASTStmt): - new_stmt = parsed_included_file + if isinstance(parsed_included_file, list): + new_stmts = parsed_included_file - if isinstance(node.get_parent().get_parent(), ASTBlock): - blk = node.get_parent().get_parent() - idx = blk.get_stmts().index(node.get_parent()) - blk.get_stmts()[idx] = new_stmt + if isinstance(node.get_parent().get_parent(), ASTBlock): + blk = node.get_parent().get_parent() + idx = blk.get_stmts().index(node.get_parent()) + blk.get_stmts().pop(idx) + blk.stmts = blk.stmts[:idx] + new_stmts + blk.stmts[idx:] + for new_stmt in new_stmts: new_stmt.parent_ = blk blk.accept(ASTParentVisitor()) - elif isinstance(node.get_parent().get_parent(), ASTEquationsBlock): - print("not handled yet") + elif isinstance(node.get_parent().get_parent(), ASTEquationsBlock): + print("not handled yet") + import pdb;pdb.set_trace() + elif isinstance(parsed_included_file, ASTStmt): + new_stmt = parsed_included_file + + if isinstance(node.get_parent().get_parent(), ASTBlock): + blk = node.get_parent().get_parent() + idx = blk.get_stmts().index(node.get_parent()) + blk.get_stmts()[idx] = new_stmt + new_stmt.parent_ = blk + blk.accept(ASTParentVisitor()) + + # elif isinstance(node.get_parent().get_parent(), ASTEquationsBlock): + else: + print("not handled yet") + import pdb;pdb.set_trace() + + elif isinstance(parsed_included_file, ASTBlockWithVariables): + new_blk = parsed_included_file + if isinstance(node.get_parent(), ASTModelBody): + idx = node.get_parent().get_body_elements().index(node) + node.get_parent().body_elements[idx] = new_blk + new_blk.parent_ = node + node.accept(ASTParentVisitor()) else: - print("not handled yet!") + print("not handled yet") + import pdb;pdb.set_trace() + + else: + print("not handled yet!") + import pdb;pdb.set_trace() + + import pdb;pdb.set_trace() diff --git a/pynestml/visitors/ast_visitor.py b/pynestml/visitors/ast_visitor.py index c2b4dab01..80f870620 100644 --- a/pynestml/visitors/ast_visitor.py +++ b/pynestml/visitors/ast_visitor.py @@ -37,6 +37,7 @@ from pynestml.meta_model.ast_function_call import ASTFunctionCall from pynestml.meta_model.ast_if_clause import ASTIfClause from pynestml.meta_model.ast_if_stmt import ASTIfStmt +from pynestml.meta_model.ast_include_stmt import ASTIncludeStmt from pynestml.meta_model.ast_input_block import ASTInputBlock from pynestml.meta_model.ast_input_port import ASTInputPort from pynestml.meta_model.ast_input_qualifier import ASTInputQualifier @@ -315,6 +316,22 @@ def visit_inline_expression(self, node): """ return + def visit_include_stmt(self, node): + """ + Used to visit a single inline expression. + :param node: a single inline expression. + :type node: ..... + """ + return + + def endvisit_include_stmt(self, node): + """ + Used to visit a single inline expression. + :param node: a single inline expression. + :type node: ..... + """ + return + def visit_kernel(self, node): """ Used to visit a single kernel. @@ -832,6 +849,9 @@ def visit(self, node: ASTNode): if isinstance(node, ASTSimpleExpression): self.visit_simple_expression(node) return + if isinstance(node, ASTIncludeStmt): + self.visit_include_stmt(node) + return if isinstance(node, ASTSmallStmt): self.visit_small_stmt(node) return @@ -963,6 +983,9 @@ def traverse(self, node): if isinstance(node, ASTSimpleExpression): self.traverse_simple_expression(node) return + if isinstance(node, ASTIncludeStmt): + self.traverse_include_stmt(node) + return if isinstance(node, ASTSmallStmt): self.traverse_small_stmt(node) return @@ -1094,6 +1117,9 @@ def endvisit(self, node): if isinstance(node, ASTSimpleExpression): self.endvisit_simple_expression(node) return + if isinstance(node, ASTIncludeStmt): + self.endvisit_include_stmt(node) + return if isinstance(node, ASTSmallStmt): self.endvisit_small_stmt(node) return @@ -1296,6 +1322,9 @@ def traverse_return_stmt(self, node): if node.get_expression() is not None: node.get_expression().accept(self.get_real_self()) + def traverse_include_stmt(self, node): + pass + def traverse_simple_expression(self, node): if node.get_function_call() is not None: node.get_function_call().accept(self.get_real_self()) diff --git a/tests/nest_tests/resources/IncludeStatementTest5.nestml b/tests/nest_tests/resources/IncludeStatementTest5.nestml new file mode 100644 index 000000000..627362958 --- /dev/null +++ b/tests/nest_tests/resources/IncludeStatementTest5.nestml @@ -0,0 +1,36 @@ +""" +IncludeStatementTest5.nestml +########################### + + +Description ++++++++++++ + +Test whether the include statement works as intended. + +Copyright statement ++++++++++++++++++++ + +This file is part of NEST. + +Copyright (C) 2004 The NEST Initiative + +NEST is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +NEST is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with NEST. If not, see . +""" + +model include_statement5: + include "include_statement_model_test_state_block.nestml" + include "include_statement_model_test_parameters_block.nestml" + include "include_statement_model_test_update_block.nestml" + include "include_statement_model_test_equations_block.nestml" diff --git a/tests/nest_tests/resources/ModelA.nestml b/tests/nest_tests/resources/ModelA.nestml index fb533873a..c0dabc770 100644 --- a/tests/nest_tests/resources/ModelA.nestml +++ b/tests/nest_tests/resources/ModelA.nestml @@ -1 +1 @@ -v = 2.71 +v = 2.71 mV diff --git a/tests/nest_tests/resources/include_statement_model_test_equations_block.nestml b/tests/nest_tests/resources/include_statement_model_test_equations_block.nestml new file mode 100644 index 000000000..a8aedc7ce --- /dev/null +++ b/tests/nest_tests/resources/include_statement_model_test_equations_block.nestml @@ -0,0 +1,2 @@ +equations: + x' = A diff --git a/tests/nest_tests/resources/include_statement_model_test_parameters_block.nestml b/tests/nest_tests/resources/include_statement_model_test_parameters_block.nestml new file mode 100644 index 000000000..28c84efbf --- /dev/null +++ b/tests/nest_tests/resources/include_statement_model_test_parameters_block.nestml @@ -0,0 +1,2 @@ +parameters: + A real = 42 / ms diff --git a/tests/nest_tests/resources/include_statement_model_test_state_block.nestml b/tests/nest_tests/resources/include_statement_model_test_state_block.nestml new file mode 100644 index 000000000..c139af335 --- /dev/null +++ b/tests/nest_tests/resources/include_statement_model_test_state_block.nestml @@ -0,0 +1,3 @@ +state: + x real = 0. + y real = 0 \ No newline at end of file diff --git a/tests/nest_tests/resources/include_statement_model_test_update_block.nestml b/tests/nest_tests/resources/include_statement_model_test_update_block.nestml new file mode 100644 index 000000000..3dee362d2 --- /dev/null +++ b/tests/nest_tests/resources/include_statement_model_test_update_block.nestml @@ -0,0 +1,4 @@ +update: + if x > 100.: + x = 0. + y += 1 diff --git a/tests/nest_tests/test_include_statement.py b/tests/nest_tests/test_include_statement.py index 02dba44a3..6a91b8846 100644 --- a/tests/nest_tests/test_include_statement.py +++ b/tests/nest_tests/test_include_statement.py @@ -29,83 +29,113 @@ class TestIncludeStatement: - def test_include_statement(self): - input_path = os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), "resources", "IncludeStatementTest.nestml"))) - target_path = "target" - logging_level = "DEBUG" - module_name = "nestmlmodule" - suffix = "_nestml" - - nest.set_verbosity("M_ALL") - generate_nest_target(input_path, - target_path=target_path, - logging_level=logging_level, - module_name=module_name, - suffix=suffix) - nest.ResetKernel() - nest.Install("nestmlmodule") - - nrn = nest.Create("include_statement_nestml") - mm = nest.Create("multimeter") - - nest.SetStatus(mm, {"record_from": ["v"]}) - - nest.Connect(mm, nrn) - - nest.Simulate(100.) - - v = mm.get("events")["v"] - np.testing.assert_allclose(v[-1], 2.71) - - def test_include_statement2(self): - input_path = os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), "resources", "IncludeStatementTest2.nestml"))) - target_path = "target" - logging_level = "DEBUG" - module_name = "nestmlmodule" - suffix = "_nestml" - - nest.set_verbosity("M_ALL") - generate_nest_target(input_path, - target_path=target_path, - logging_level=logging_level, - module_name=module_name, - suffix=suffix) - nest.ResetKernel() - nest.resolution = 0.1 # [ms] - nest.Install("nestmlmodule") - - nrn = nest.Create("include_statement2_nestml") - mm = nest.Create("multimeter") - - nest.SetStatus(mm, {"record_from": ["v"], - "interval": nest.resolution}) - - nest.Connect(mm, nrn) - - nest.Simulate(101.) - - v = mm.get("events")["v"] - np.testing.assert_allclose(v[-1], 1042.) - - def test_include_statement3(self): - r"""check for failure if the included file has wrong unit types""" - input_path = os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), "resources", "IncludeStatementTest3.nestml"))) - target_path = "target" - logging_level = "DEBUG" - module_name = "nestmlmodule" - suffix = "_nestml" - - nest.set_verbosity("M_ALL") - generate_nest_target(input_path, - target_path=target_path, - logging_level=logging_level, - module_name=module_name, - suffix=suffix) - from pynestml.utils.logger import Logger, LoggingLevel - assert len(Logger.get_all_messages_of_level_and_or_node("include_statement3_nestml", LoggingLevel.ERROR)) > 0 - - def test_include_statement4(self): - input_path = os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), "resources", "IncludeStatementTest4.nestml"))) + # def test_include_statement(self): + # input_path = os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), "resources", "IncludeStatementTest.nestml"))) + # target_path = "target" + # logging_level = "DEBUG" + # module_name = "nestmlmodule" + # suffix = "_nestml" + + # nest.set_verbosity("M_ALL") + # generate_nest_target(input_path, + # target_path=target_path, + # logging_level=logging_level, + # module_name=module_name, + # suffix=suffix) + # nest.ResetKernel() + # nest.Install("nestmlmodule") + + # nrn = nest.Create("include_statement_nestml") + # mm = nest.Create("multimeter") + + # nest.SetStatus(mm, {"record_from": ["v"]}) + + # nest.Connect(mm, nrn) + + # nest.Simulate(100.) + + # v = mm.get("events")["v"] + # np.testing.assert_allclose(v[-1], 2.71) + + # def test_include_statement2(self): + # input_path = os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), "resources", "IncludeStatementTest2.nestml"))) + # target_path = "target" + # logging_level = "DEBUG" + # module_name = "nestmlmodule" + # suffix = "_nestml" + + # nest.set_verbosity("M_ALL") + # generate_nest_target(input_path, + # target_path=target_path, + # logging_level=logging_level, + # module_name=module_name, + # suffix=suffix) + # nest.ResetKernel() + # nest.resolution = 0.1 # [ms] + # nest.Install("nestmlmodule") + + # nrn = nest.Create("include_statement2_nestml") + # mm = nest.Create("multimeter") + + # nest.SetStatus(mm, {"record_from": ["v"], + # "interval": nest.resolution}) + + # nest.Connect(mm, nrn) + + # nest.Simulate(101.) + + # v = mm.get("events")["v"] + # np.testing.assert_allclose(v[-1], 1042.) + + # def test_include_statement3(self): + # r"""check for failure if the included file has wrong unit types""" + # input_path = os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), "resources", "IncludeStatementTest3.nestml"))) + # target_path = "target" + # logging_level = "DEBUG" + # module_name = "nestmlmodule" + # suffix = "_nestml" + + # nest.set_verbosity("M_ALL") + # generate_nest_target(input_path, + # target_path=target_path, + # logging_level=logging_level, + # module_name=module_name, + # suffix=suffix) + # from pynestml.utils.logger import Logger, LoggingLevel + # assert len(Logger.get_all_messages_of_level_and_or_node("include_statement3_nestml", LoggingLevel.ERROR)) > 0 + + # def test_include_statement4(self): + # input_path = os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), "resources", "IncludeStatementTest4.nestml"))) + # target_path = "target" + # logging_level = "DEBUG" + # module_name = "nestmlmodule" + # suffix = "_nestml" + + # nest.set_verbosity("M_ALL") + # generate_nest_target(input_path, + # target_path=target_path, + # logging_level=logging_level, + # module_name=module_name, + # suffix=suffix) + # nest.ResetKernel() + # nest.resolution = 0.1 # [ms] + # nest.Install("nestmlmodule") + + # nrn = nest.Create("include_statement4_nestml") + # mm = nest.Create("multimeter") + + # nest.SetStatus(mm, {"record_from": ["v"], + # "interval": nest.resolution}) + + # nest.Connect(mm, nrn) + + # nest.Simulate(151.) + + # v = mm.get("events")["v"] + # np.testing.assert_allclose(v[-1], 27.) + + def test_include_statement5(self): + input_path = os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), "resources", "IncludeStatementTest5.nestml"))) target_path = "target" logging_level = "DEBUG" module_name = "nestmlmodule" @@ -121,15 +151,17 @@ def test_include_statement4(self): nest.resolution = 0.1 # [ms] nest.Install("nestmlmodule") - nrn = nest.Create("include_statement4_nestml") + nrn = nest.Create("include_statement5_nestml") mm = nest.Create("multimeter") - nest.SetStatus(mm, {"record_from": ["v"], + nest.SetStatus(mm, {"record_from": ["x", "y"], "interval": nest.resolution}) nest.Connect(mm, nrn) nest.Simulate(151.) - v = mm.get("events")["v"] - np.testing.assert_allclose(v[-1], 27.) + x = mm.get("events")["x"] + y = mm.get("events")["y"] + np.testing.assert_allclose(x[-1], 27.) + np.testing.assert_allclose(y[-1], 23) From 229a3a6972851dcc4452670098abf286fa295c42 Mon Sep 17 00:00:00 2001 From: "C.A.P. Linssen" Date: Tue, 26 Nov 2024 01:16:39 +0100 Subject: [PATCH 11/25] add include statement --- .../spinnaker_code_generator.py | 2 +- pynestml/frontend/pynestml_frontend.py | 2 + pynestml/utils/model_parser.py | 60 ++--- .../visitors/ast_include_statement_visitor.py | 49 ++-- ...atement_model_test_parameters_block.nestml | 2 +- ...e_statement_model_test_update_block.nestml | 1 + tests/nest_tests/test_include_statement.py | 213 +++++++++--------- 7 files changed, 152 insertions(+), 177 deletions(-) diff --git a/pynestml/codegeneration/spinnaker_code_generator.py b/pynestml/codegeneration/spinnaker_code_generator.py index f9d55b583..f7ff7752f 100644 --- a/pynestml/codegeneration/spinnaker_code_generator.py +++ b/pynestml/codegeneration/spinnaker_code_generator.py @@ -219,5 +219,5 @@ def generate_code(self, models: Sequence[ASTModel]) -> None: cloned_models.append(cloned_model) self.codegen_cpp.generate_code(cloned_models) - CoCosManager.check_cocos(cloned_model) + CoCosManager.check_cocos(cloned_model) self.codegen_py.generate_code(cloned_models) diff --git a/pynestml/frontend/pynestml_frontend.py b/pynestml/frontend/pynestml_frontend.py index 40983a800..60441e054 100644 --- a/pynestml/frontend/pynestml_frontend.py +++ b/pynestml/frontend/pynestml_frontend.py @@ -441,6 +441,8 @@ def get_parsed_models() -> List[ASTModel]: for model in models: model.accept(ASTIncludeStatementVisitor(os.path.dirname(model.file_path))) model.accept(ASTSymbolTableVisitor()) + print("MODEL AFTER INCLUDES REPLACED:") + print(model) # ....... for model in models: diff --git a/pynestml/utils/model_parser.py b/pynestml/utils/model_parser.py index 6d4c6793e..7b2b26fe2 100644 --- a/pynestml/utils/model_parser.py +++ b/pynestml/utils/model_parser.py @@ -183,6 +183,10 @@ def parse_stmt(cls, string: str) -> Union[ASTStmt, List[ASTStmt]]: stmt = builder.visit(parser.stmt()) stmts.append(stmt) except ParseCancellationException: + if not stmts: + # this is the only the first statement to be visited, and it failed, so there is nothing here that can be parsed as a statement + raise ParseCancellationException() + # no more statements left to parse break @@ -491,73 +495,73 @@ def parse_included_file(cls, filename: str) -> Union[ASTNode, List[ASTNode]]: ast = None try: ast = ModelParser.parse_model(lines) - except: + except (ParseCancellationException, AttributeError): pass if not ast: try: ast = ModelParser.parse_model_body(lines) - except: + except (ParseCancellationException, AttributeError): pass if not ast: try: ast = ModelParser.parse_block_with_variables(lines) - except: + except (ParseCancellationException, AttributeError): pass if not ast: try: ast = ModelParser.parse_equations_block(lines) - except: + except (ParseCancellationException, AttributeError): pass if not ast: try: ast = ModelParser.parse_input_block(lines) - except: + except (ParseCancellationException, AttributeError): pass if not ast: try: ast = ModelParser.parse_output_block(lines) - except: + except (ParseCancellationException, AttributeError): pass if not ast: try: ast = ModelParser.parse_on_receive_block(lines) - except: + except (ParseCancellationException, AttributeError): pass if not ast: try: ast = ModelParser.parse_on_condition_block(lines) - except: + except (ParseCancellationException, AttributeError): pass if not ast: try: ast = ModelParser.parse_update_block(lines) - except: + except (ParseCancellationException, AttributeError): pass if not ast: try: ast = ModelParser.parse_block(lines) - except: + except (ParseCancellationException, AttributeError): pass if not ast: try: ast = ModelParser.parse_stmt(lines) - except: + except (ParseCancellationException, AttributeError): pass if not ast: try: ast = ModelParser.parse_small_stmt(lines) - except: + except (ParseCancellationException, AttributeError): pass assert ast @@ -565,20 +569,7 @@ def parse_included_file(cls, filename: str) -> Union[ASTNode, List[ASTNode]]: return ast - -# def tokenize(string: str) -> Tuple[ASTBuilderVisitor, PyNestMLParser]: -# lexer = PyNestMLLexer(InputStream(string)) -# # create a token stream -# stream = CommonTokenStream(lexer) -# stream.fill() -# parser = PyNestMLParser(stream) -# builder = ASTBuilderVisitor(stream.tokens) -# return builder, parser - - - def tokenize(string: str) -> Tuple[ASTBuilderVisitor, PyNestMLParser]: - lexer = PyNestMLLexer() lexer.removeErrorListeners() lexer._errHandler = BailErrorStrategy() # halt immediately on lexer errors @@ -601,25 +592,6 @@ def tokenize(string: str) -> Tuple[ASTBuilderVisitor, PyNestMLParser]: builder = ASTBuilderVisitor(stream.tokens) return builder, parser - - - - - - - - - - - - - - - - - - - def log_set_added_source_position(node): node.set_source_position(ASTSourceLocation.get_added_source_position()) diff --git a/pynestml/visitors/ast_include_statement_visitor.py b/pynestml/visitors/ast_include_statement_visitor.py index efde46ace..b1b7a5e12 100644 --- a/pynestml/visitors/ast_include_statement_visitor.py +++ b/pynestml/visitors/ast_include_statement_visitor.py @@ -62,6 +62,15 @@ def visit_small_stmt(self, node: ASTSmallStmt): if node.is_include_stmt(): self._handle_include_stmt(node.get_include_stmt()) + def _replace_statements(self, include_stmt, new_stmts): + blk = include_stmt.get_parent() + idx = blk.get_stmts().index(include_stmt) + blk.get_stmts().pop(idx) + blk.stmts = blk.stmts[:idx] + new_stmts + blk.stmts[idx:] + for new_stmt in new_stmts: + new_stmt.parent_ = blk + blk.accept(ASTParentVisitor()) + def _handle_include_stmt(self, node: ASTIncludeStmt): filename = node.get_filename() if not os.path.isabs(filename): @@ -71,48 +80,38 @@ def _handle_include_stmt(self, node: ASTIncludeStmt): if isinstance(parsed_included_file, list): new_stmts = parsed_included_file + include_stmt = node.get_parent().get_parent() - if isinstance(node.get_parent().get_parent(), ASTBlock): - blk = node.get_parent().get_parent() - idx = blk.get_stmts().index(node.get_parent()) - blk.get_stmts().pop(idx) - blk.stmts = blk.stmts[:idx] + new_stmts + blk.stmts[idx:] - for new_stmt in new_stmts: - new_stmt.parent_ = blk - blk.accept(ASTParentVisitor()) + if isinstance(include_stmt.get_parent(), ASTBlock): + self._replace_statements(include_stmt, new_stmts) elif isinstance(node.get_parent().get_parent(), ASTEquationsBlock): - print("not handled yet") - import pdb;pdb.set_trace() + print("not handled yet 4") + assert False elif isinstance(parsed_included_file, ASTStmt): new_stmt = parsed_included_file + include_stmt = node.get_parent().get_parent() - if isinstance(node.get_parent().get_parent(), ASTBlock): - blk = node.get_parent().get_parent() - idx = blk.get_stmts().index(node.get_parent()) - blk.get_stmts()[idx] = new_stmt - new_stmt.parent_ = blk - blk.accept(ASTParentVisitor()) + if isinstance(include_stmt.get_parent(), ASTBlock): + self._replace_statements(include_stmt, [new_stmt]) # elif isinstance(node.get_parent().get_parent(), ASTEquationsBlock): else: - print("not handled yet") - import pdb;pdb.set_trace() + print("not handled yet 1") + assert False - elif isinstance(parsed_included_file, ASTBlockWithVariables): + elif isinstance(parsed_included_file, ASTBlockWithVariables) or isinstance(parsed_included_file, ASTUpdateBlock) or isinstance(parsed_included_file, ASTEquationsBlock): new_blk = parsed_included_file if isinstance(node.get_parent(), ASTModelBody): idx = node.get_parent().get_body_elements().index(node) node.get_parent().body_elements[idx] = new_blk new_blk.parent_ = node node.accept(ASTParentVisitor()) + new_blk.accept(ASTParentVisitor()) else: - print("not handled yet") - import pdb;pdb.set_trace() + print("not handled yet 2") + assert False else: - print("not handled yet!") - import pdb;pdb.set_trace() - - import pdb;pdb.set_trace() + assert False diff --git a/tests/nest_tests/resources/include_statement_model_test_parameters_block.nestml b/tests/nest_tests/resources/include_statement_model_test_parameters_block.nestml index 28c84efbf..2f60c4cd2 100644 --- a/tests/nest_tests/resources/include_statement_model_test_parameters_block.nestml +++ b/tests/nest_tests/resources/include_statement_model_test_parameters_block.nestml @@ -1,2 +1,2 @@ parameters: - A real = 42 / ms + A ms**-1 = 42 / ms diff --git a/tests/nest_tests/resources/include_statement_model_test_update_block.nestml b/tests/nest_tests/resources/include_statement_model_test_update_block.nestml index 3dee362d2..4b7906599 100644 --- a/tests/nest_tests/resources/include_statement_model_test_update_block.nestml +++ b/tests/nest_tests/resources/include_statement_model_test_update_block.nestml @@ -1,4 +1,5 @@ update: + integrate_odes() if x > 100.: x = 0. y += 1 diff --git a/tests/nest_tests/test_include_statement.py b/tests/nest_tests/test_include_statement.py index 6a91b8846..7e8d6019e 100644 --- a/tests/nest_tests/test_include_statement.py +++ b/tests/nest_tests/test_include_statement.py @@ -29,110 +29,110 @@ class TestIncludeStatement: - # def test_include_statement(self): - # input_path = os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), "resources", "IncludeStatementTest.nestml"))) - # target_path = "target" - # logging_level = "DEBUG" - # module_name = "nestmlmodule" - # suffix = "_nestml" - - # nest.set_verbosity("M_ALL") - # generate_nest_target(input_path, - # target_path=target_path, - # logging_level=logging_level, - # module_name=module_name, - # suffix=suffix) - # nest.ResetKernel() - # nest.Install("nestmlmodule") - - # nrn = nest.Create("include_statement_nestml") - # mm = nest.Create("multimeter") - - # nest.SetStatus(mm, {"record_from": ["v"]}) - - # nest.Connect(mm, nrn) - - # nest.Simulate(100.) - - # v = mm.get("events")["v"] - # np.testing.assert_allclose(v[-1], 2.71) - - # def test_include_statement2(self): - # input_path = os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), "resources", "IncludeStatementTest2.nestml"))) - # target_path = "target" - # logging_level = "DEBUG" - # module_name = "nestmlmodule" - # suffix = "_nestml" - - # nest.set_verbosity("M_ALL") - # generate_nest_target(input_path, - # target_path=target_path, - # logging_level=logging_level, - # module_name=module_name, - # suffix=suffix) - # nest.ResetKernel() - # nest.resolution = 0.1 # [ms] - # nest.Install("nestmlmodule") - - # nrn = nest.Create("include_statement2_nestml") - # mm = nest.Create("multimeter") - - # nest.SetStatus(mm, {"record_from": ["v"], - # "interval": nest.resolution}) - - # nest.Connect(mm, nrn) - - # nest.Simulate(101.) - - # v = mm.get("events")["v"] - # np.testing.assert_allclose(v[-1], 1042.) - - # def test_include_statement3(self): - # r"""check for failure if the included file has wrong unit types""" - # input_path = os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), "resources", "IncludeStatementTest3.nestml"))) - # target_path = "target" - # logging_level = "DEBUG" - # module_name = "nestmlmodule" - # suffix = "_nestml" - - # nest.set_verbosity("M_ALL") - # generate_nest_target(input_path, - # target_path=target_path, - # logging_level=logging_level, - # module_name=module_name, - # suffix=suffix) - # from pynestml.utils.logger import Logger, LoggingLevel - # assert len(Logger.get_all_messages_of_level_and_or_node("include_statement3_nestml", LoggingLevel.ERROR)) > 0 - - # def test_include_statement4(self): - # input_path = os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), "resources", "IncludeStatementTest4.nestml"))) - # target_path = "target" - # logging_level = "DEBUG" - # module_name = "nestmlmodule" - # suffix = "_nestml" - - # nest.set_verbosity("M_ALL") - # generate_nest_target(input_path, - # target_path=target_path, - # logging_level=logging_level, - # module_name=module_name, - # suffix=suffix) - # nest.ResetKernel() - # nest.resolution = 0.1 # [ms] - # nest.Install("nestmlmodule") - - # nrn = nest.Create("include_statement4_nestml") - # mm = nest.Create("multimeter") - - # nest.SetStatus(mm, {"record_from": ["v"], - # "interval": nest.resolution}) - - # nest.Connect(mm, nrn) - - # nest.Simulate(151.) - - # v = mm.get("events")["v"] - # np.testing.assert_allclose(v[-1], 27.) + def test_include_statement(self): + input_path = os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), "resources", "IncludeStatementTest.nestml"))) + target_path = "target" + logging_level = "DEBUG" + module_name = "nestmlmodule" + suffix = "_nestml" + + nest.set_verbosity("M_ALL") + generate_nest_target(input_path, + target_path=target_path, + logging_level=logging_level, + module_name=module_name, + suffix=suffix) + nest.ResetKernel() + nest.Install("nestmlmodule") + + nrn = nest.Create("include_statement_nestml") + mm = nest.Create("multimeter") + + nest.SetStatus(mm, {"record_from": ["v"]}) + + nest.Connect(mm, nrn) + + nest.Simulate(100.) + + v = mm.get("events")["v"] + np.testing.assert_allclose(v[-1], 2.71) + + def test_include_statement2(self): + input_path = os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), "resources", "IncludeStatementTest2.nestml"))) + target_path = "target" + logging_level = "DEBUG" + module_name = "nestmlmodule" + suffix = "_nestml" + + nest.set_verbosity("M_ALL") + generate_nest_target(input_path, + target_path=target_path, + logging_level=logging_level, + module_name=module_name, + suffix=suffix) + nest.ResetKernel() + nest.resolution = 0.1 # [ms] + nest.Install("nestmlmodule") + + nrn = nest.Create("include_statement2_nestml") + mm = nest.Create("multimeter") + + nest.SetStatus(mm, {"record_from": ["v"], + "interval": nest.resolution}) + + nest.Connect(mm, nrn) + + nest.Simulate(101.) + + v = mm.get("events")["v"] + np.testing.assert_allclose(v[-1], 1042.) + + def test_include_statement3(self): + r"""check for failure if the included file has wrong unit types""" + input_path = os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), "resources", "IncludeStatementTest3.nestml"))) + target_path = "target" + logging_level = "DEBUG" + module_name = "nestmlmodule" + suffix = "_nestml" + + nest.set_verbosity("M_ALL") + generate_nest_target(input_path, + target_path=target_path, + logging_level=logging_level, + module_name=module_name, + suffix=suffix) + from pynestml.utils.logger import Logger, LoggingLevel + assert len(Logger.get_all_messages_of_level_and_or_node("include_statement3_nestml", LoggingLevel.ERROR)) > 0 + + def test_include_statement4(self): + input_path = os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), "resources", "IncludeStatementTest4.nestml"))) + target_path = "target" + logging_level = "DEBUG" + module_name = "nestmlmodule" + suffix = "_nestml" + + nest.set_verbosity("M_ALL") + generate_nest_target(input_path, + target_path=target_path, + logging_level=logging_level, + module_name=module_name, + suffix=suffix) + nest.ResetKernel() + nest.resolution = 0.1 # [ms] + nest.Install("nestmlmodule") + + nrn = nest.Create("include_statement4_nestml") + mm = nest.Create("multimeter") + + nest.SetStatus(mm, {"record_from": ["v"], + "interval": nest.resolution}) + + nest.Connect(mm, nrn) + + nest.Simulate(151.) + + v = mm.get("events")["v"] + np.testing.assert_allclose(v[-1], 27.) def test_include_statement5(self): input_path = os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), "resources", "IncludeStatementTest5.nestml"))) @@ -163,5 +163,6 @@ def test_include_statement5(self): x = mm.get("events")["x"] y = mm.get("events")["y"] - np.testing.assert_allclose(x[-1], 27.) - np.testing.assert_allclose(y[-1], 23) + + np.testing.assert_allclose(x[-1], 50.4) + np.testing.assert_allclose(y[-1], 62.) From 7b3f12791b2db31da28efa51f48b5d71b5903189 Mon Sep 17 00:00:00 2001 From: "C.A.P. Linssen" Date: Thu, 28 Nov 2024 02:24:10 +0100 Subject: [PATCH 12/25] clean up NESTML grammar definition --- ...user_defined_function_correctly_defined.py | 14 +- .../codegeneration/printers/model_printer.py | 8 +- .../codegeneration/printers/nestml_printer.py | 89 +- .../point_neuron/common/NeuronClass.jinja2 | 16 +- .../common/SynapseHeader.h.jinja2 | 28 +- .../directives_cpp/ForStatement.jinja2 | 8 +- .../directives_cpp/IfStatement.jinja2 | 12 +- .../{Block.jinja2 => StmtsBody.jinja2} | 4 +- .../directives_cpp/WhileStatement.jinja2 | 8 +- ...cm_neuroncurrents_@NEURON_NAME@.cpp.jinja2 | 16 +- .../point_neuron/@NEURON_NAME@.py.jinja2 | 16 +- .../point_neuron/directives_py/Block.jinja2 | 11 - .../directives_py/ForStatement.jinja2 | 4 +- .../directives_py/IfStatement.jinja2 | 12 +- .../directives_py/StmtsBody.jinja2 | 11 + .../directives_py/WhileStatement.jinja2 | 4 +- .../@NEURON_NAME@_impl.h.jinja2 | 4 +- .../@SYNAPSE_NAME@_impl.c.jinja2 | 8 +- pynestml/generated/PyNestMLLexer.py | 4 +- pynestml/generated/PyNestMLLexerBase.py | 9 +- pynestml/generated/PyNestMLParser.py | 1890 +++++++++-------- pynestml/generated/PyNestMLParserVisitor.py | 34 +- pynestml/grammars/PyNestMLLexer.g4 | 42 +- pynestml/grammars/PyNestMLParser.g4 | 549 ++--- pynestml/meta_model/ast_elif_clause.py | 44 +- pynestml/meta_model/ast_else_clause.py | 37 +- pynestml/meta_model/ast_for_stmt.py | 50 +- pynestml/meta_model/ast_function.py | 35 +- pynestml/meta_model/ast_if_clause.py | 40 +- pynestml/meta_model/ast_node_factory.py | 20 +- pynestml/meta_model/ast_on_condition_block.py | 24 +- pynestml/meta_model/ast_on_receive_block.py | 22 +- .../{ast_block.py => ast_stmts_body.py} | 24 +- pynestml/meta_model/ast_update_block.py | 43 +- pynestml/meta_model/ast_while_stmt.py | 34 +- .../synapse_post_neuron_transformer.py | 2 +- pynestml/utils/ast_utils.py | 26 +- pynestml/utils/model_parser.py | 37 +- ...ign_implicit_conversion_factors_visitor.py | 14 +- pynestml/visitors/ast_builder_visitor.py | 35 +- pynestml/visitors/ast_symbol_table_visitor.py | 20 +- pynestml/visitors/ast_visitor.py | 44 +- ...printer_test.py => test_nestml_printer.py} | 151 +- tests/test_unit_system.py | 4 +- 44 files changed, 1838 insertions(+), 1669 deletions(-) rename pynestml/codegeneration/resources_nest/point_neuron/directives_cpp/{Block.jinja2 => StmtsBody.jinja2} (72%) delete mode 100644 pynestml/codegeneration/resources_python_standalone/point_neuron/directives_py/Block.jinja2 create mode 100644 pynestml/codegeneration/resources_python_standalone/point_neuron/directives_py/StmtsBody.jinja2 rename pynestml/meta_model/{ast_block.py => ast_stmts_body.py} (84%) rename tests/{nestml_printer_test.py => test_nestml_printer.py} (60%) diff --git a/pynestml/cocos/co_co_user_defined_function_correctly_defined.py b/pynestml/cocos/co_co_user_defined_function_correctly_defined.py index 50fb915bc..ec62a9ac4 100644 --- a/pynestml/cocos/co_co_user_defined_function_correctly_defined.py +++ b/pynestml/cocos/co_co_user_defined_function_correctly_defined.py @@ -61,10 +61,10 @@ def check_co_co(cls, _node=None): symbol = userDefinedFunction.get_scope().resolve_to_symbol(userDefinedFunction.get_name(), SymbolKind.FUNCTION) # first ensure that the block contains at least one statement - if symbol is not None and len(userDefinedFunction.get_block().get_stmts()) > 0: + if symbol is not None and len(userDefinedFunction.get_stmts_body().get_stmts()) > 0: # now check that the last statement is a return cls.__check_return_recursively(symbol.get_return_type(), - userDefinedFunction.get_block().get_stmts(), False) + userDefinedFunction.get_stmts_body().get_stmts(), False) # now if it does not have a statement, but uses a return type, it is an error elif symbol is not None and userDefinedFunction.has_return_type() and \ not symbol.get_return_type().equals(PredefinedTypes.get_void_type()): @@ -135,19 +135,19 @@ def __check_return_recursively(cls, type_symbol=None, stmts=None, ret_defined=Fa # otherwise it is a compound stmt, thus check recursively if stmt.is_if_stmt(): cls.__check_return_recursively(type_symbol, - stmt.get_if_stmt().get_if_clause().get_block().get_stmts(), + stmt.get_if_stmt().get_if_clause().get_stmts_body().get_stmts(), ret_defined) for else_ifs in stmt.get_if_stmt().get_elif_clauses(): - cls.__check_return_recursively(type_symbol, else_ifs.get_block().get_stmts(), ret_defined) + cls.__check_return_recursively(type_symbol, else_ifs.get_stmts_body().get_stmts(), ret_defined) if stmt.get_if_stmt().has_else_clause(): cls.__check_return_recursively(type_symbol, - stmt.get_if_stmt().get_else_clause().get_block().get_stmts(), + stmt.get_if_stmt().get_else_clause().get_stmts_body().get_stmts(), ret_defined) elif stmt.is_while_stmt(): - cls.__check_return_recursively(type_symbol, stmt.get_while_stmt().get_block().get_stmts(), + cls.__check_return_recursively(type_symbol, stmt.get_while_stmt().get_stmts_body().get_stmts(), ret_defined) elif stmt.is_for_stmt(): - cls.__check_return_recursively(type_symbol, stmt.get_for_stmt().get_block().get_stmts(), + cls.__check_return_recursively(type_symbol, stmt.get_for_stmt().get_stmts_body().get_stmts(), ret_defined) # now, if a return statement has not been defined in the corresponding higher level block, we have # to ensure that it is defined here diff --git a/pynestml/codegeneration/printers/model_printer.py b/pynestml/codegeneration/printers/model_printer.py index ab52c5569..b8b257dff 100644 --- a/pynestml/codegeneration/printers/model_printer.py +++ b/pynestml/codegeneration/printers/model_printer.py @@ -23,7 +23,7 @@ from pynestml.meta_model.ast_arithmetic_operator import ASTArithmeticOperator from pynestml.meta_model.ast_assignment import ASTAssignment from pynestml.meta_model.ast_bit_operator import ASTBitOperator -from pynestml.meta_model.ast_block import ASTBlock +from pynestml.meta_model.ast_stmts_body import ASTStmtsBody from pynestml.meta_model.ast_block_with_variables import ASTBlockWithVariables from pynestml.meta_model.ast_compound_stmt import ASTCompoundStmt from pynestml.meta_model.ast_data_type import ASTDataType @@ -78,7 +78,7 @@ def print_assignment(self, node: ASTAssignment) -> str: def print_bit_operator(self, node: ASTBitOperator) -> str: raise Exception("Printer does not support printing this node type") - def print_block(self, node: ASTBlock) -> str: + def print_stmts_body(self, node: ASTStmtsBody) -> str: raise Exception("Printer does not support printing this node type") def print_block_with_variables(self, node: ASTBlockWithVariables) -> str: @@ -196,8 +196,8 @@ def print(self, node: ASTNode) -> str: if isinstance(node, ASTBitOperator): return self.print_bit_operator(node) - if isinstance(node, ASTBlock): - return self.print_block(node) + if isinstance(node, ASTStmtsBody): + return self.print_stmts_body(node) if isinstance(node, ASTBlockWithVariables): return self.print_block_with_variables(node) diff --git a/pynestml/codegeneration/printers/nestml_printer.py b/pynestml/codegeneration/printers/nestml_printer.py index 481fc9a6a..3703ed6c5 100644 --- a/pynestml/codegeneration/printers/nestml_printer.py +++ b/pynestml/codegeneration/printers/nestml_printer.py @@ -23,7 +23,7 @@ from pynestml.meta_model.ast_arithmetic_operator import ASTArithmeticOperator from pynestml.meta_model.ast_assignment import ASTAssignment from pynestml.meta_model.ast_bit_operator import ASTBitOperator -from pynestml.meta_model.ast_block import ASTBlock +from pynestml.meta_model.ast_stmts_body import ASTStmtsBody from pynestml.meta_model.ast_block_with_variables import ASTBlockWithVariables from pynestml.meta_model.ast_comparison_operator import ASTComparisonOperator from pynestml.meta_model.ast_compound_stmt import ASTCompoundStmt @@ -76,10 +76,9 @@ def __init__(self): def print_model(self, node: ASTModel) -> str: ret = print_ml_comments(node.pre_comments, self.indent, False) - self.inc_indent() ret += "model " + node.get_name() + ":" + print_sl_comment(node.in_comment) ret += "\n" + self.print(node.get_body()) - self.dec_indent() + return ret def print_arithmetic_operator(celf, node: ASTArithmeticOperator) -> str: @@ -138,21 +137,17 @@ def print_bit_operator(self, node: ASTBitOperator) -> str: raise RuntimeError("Unknown bit operator") - def print_block(self, node: ASTBlock) -> str: + def print_stmts_body(self, node: ASTStmtsBody) -> str: ret = "" - self.inc_indent() for stmt in node.stmts: ret += self.print(stmt) - self.dec_indent() - return ret def print_block_with_variables(self, node: ASTBlockWithVariables) -> str: - temp_indent = self.indent - self.inc_indent() - ret = print_ml_comments(node.pre_comments, temp_indent, False) - ret += print_n_spaces(temp_indent) + ret = print_ml_comments(node.pre_comments, self.indent, False) + ret += print_n_spaces(self.indent) + if node.is_state: ret += "state" elif node.is_parameters: @@ -160,17 +155,26 @@ def print_block_with_variables(self, node: ASTBlockWithVariables) -> str: else: assert node.is_internals ret += "internals" + ret += ":" + print_sl_comment(node.in_comment) + "\n" + if node.get_declarations() is not None: + self.inc_indent() for decl in node.get_declarations(): ret += self.print(decl) - self.dec_indent() + + self.dec_indent() + return ret def print_model_body(self, node: ASTModelBody) -> str: + self.inc_indent() ret = "" for elem in node.body_elements: ret += self.print(elem) + + self.dec_indent() + return ret def print_comparison_operator(self, node: ASTComparisonOperator) -> str: @@ -257,11 +261,20 @@ def print_declaration(self, node: ASTDeclaration) -> str: return ret def print_elif_clause(self, node: ASTElifClause) -> str: - return (print_n_spaces(self.indent) + "elif " + self.print(node.get_condition()) - + ":\n" + self.print(node.get_block())) + ret = print_n_spaces(self.indent) + "elif " + self.print(node.get_condition()) + ":\n" + self.inc_indent() + ret += self.print(node.get_stmts_body()) + self.dec_indent() + + return ret def print_else_clause(self, node: ASTElseClause) -> str: - return print_n_spaces(self.indent) + "else:\n" + self.print(node.get_block()) + ret = print_n_spaces(self.indent) + "else:\n" + self.inc_indent() + ret += self.print(node.get_stmts_body()) + self.dec_indent() + + return ret def print_equations_block(self, node: ASTEquationsBlock) -> str: temp_indent = self.indent @@ -301,12 +314,14 @@ def print_for_stmt(self, node: ASTForStmt) -> str: ret += ("for " + node.get_variable() + " in " + self.print(node.get_start_from()) + "..." + self.print(node.get_end_at()) + " step " + str(node.get_step()) + ":" + print_sl_comment(node.in_comment) + "\n") - ret += self.print(node.get_block()) + self.inc_indent() + ret += self.print(node.get_stmts_body()) + self.dec_indent() return ret def print_function(self, node: ASTFunction) -> str: ret = print_ml_comments(node.pre_comments, self.indent) - ret += "function " + node.get_name() + "(" + ret += print_n_spaces(self.indent) + "function " + node.get_name() + "(" if node.has_parameters(): for par in node.get_parameters(): ret += self.print(par) @@ -314,7 +329,10 @@ def print_function(self, node: ASTFunction) -> str: if node.has_return_type(): ret += " " + self.print(node.get_return_type()) ret += ":" + print_sl_comment(node.in_comment) + "\n" - ret += self.print(node.get_block()) + "\n" + self.inc_indent() + ret += self.print(node.get_stmts_body()) + "\n" + self.dec_indent() + return ret def print_function_call(self, node: ASTFunctionCall) -> str: @@ -323,14 +341,19 @@ def print_function_call(self, node: ASTFunctionCall) -> str: ret += self.print(node.get_args()[i]) if i < len(node.get_args()) - 1: # in the case that it is not the last arg, print also a comma ret += "," + ret += ")" + return ret def print_if_clause(self, node: ASTIfClause) -> str: ret = print_ml_comments(node.pre_comments, self.indent) ret += print_n_spaces(self.indent) + "if " + self.print(node.get_condition()) + ":" ret += print_sl_comment(node.in_comment) + "\n" - ret += self.print(node.get_block()) + self.inc_indent() + ret += self.print(node.get_stmts_body()) + self.dec_indent() + return ret def print_if_stmt(self, node: ASTIfStmt) -> str: @@ -341,6 +364,7 @@ def print_if_stmt(self, node: ASTIfStmt) -> str: if node.get_else_clause() is not None: ret += self.print(node.get_else_clause()) ret += print_n_spaces(self.indent) + "\n" + return ret def print_input_block(self, node: ASTInputBlock) -> str: @@ -519,31 +543,39 @@ def print_unit_type(self, node: ASTUnitType) -> str: return self.print(node.base) + "**" + str(node.exponent) if node.is_arithmetic_expression(): - t_lhs = ( - self.print(node.get_lhs()) if isinstance(node.get_lhs(), ASTUnitType) else str(node.get_lhs())) + t_lhs = self.print(node.get_lhs()) if isinstance(node.get_lhs(), ASTUnitType) else str(node.get_lhs()) if node.is_times: return t_lhs + "*" + self.print(node.get_rhs()) - else: - return t_lhs + "/" + self.print(node.get_rhs()) + + return t_lhs + "/" + self.print(node.get_rhs()) return node.unit def print_on_receive_block(self, node: ASTOnReceiveBlock) -> str: ret = print_ml_comments(node.pre_comments, self.indent, False) ret += print_n_spaces(self.indent) + "onReceive(" + node.port_name + "):" + print_sl_comment(node.in_comment) + "\n" - ret += self.print(node.get_block()) + self.inc_indent() + ret += self.print(node.get_stmts_body()) + self.dec_indent() + return ret def print_on_condition_block(self, node: ASTOnConditionBlock) -> str: ret = print_ml_comments(node.pre_comments, self.indent, False) ret += print_n_spaces(self.indent) + "onCondition(" + self.print(node.get_cond_expr()) + "):" + print_sl_comment(node.in_comment) + "\n" - ret += self.print(node.get_block()) + self.inc_indent() + ret += self.print(node.get_stmts_body()) + self.dec_indent() + return ret def print_update_block(self, node: ASTUpdateBlock): ret = print_ml_comments(node.pre_comments, self.indent, False) ret += print_n_spaces(self.indent) + "update:" + print_sl_comment(node.in_comment) + "\n" - ret += self.print(node.get_block()) + self.inc_indent() + ret += self.print(node.get_stmts_body()) + self.dec_indent() + return ret def print_variable(self, node: ASTVariable): @@ -561,7 +593,10 @@ def print_while_stmt(self, node: ASTWhileStmt) -> str: ret = print_ml_comments(node.pre_comments, self.indent, False) ret += (print_n_spaces(self.indent) + "while " + self.print(node.get_condition()) + ":" + print_sl_comment(node.in_comment) + "\n") - ret += self.print(node.get_block()) + self.inc_indent() + ret += self.print(node.get_stmts_body()) + self.dec_indent() + return ret def inc_indent(self): diff --git a/pynestml/codegeneration/resources_nest/point_neuron/common/NeuronClass.jinja2 b/pynestml/codegeneration/resources_nest/point_neuron/common/NeuronClass.jinja2 index a4253ce90..8cc3dd0dc 100644 --- a/pynestml/codegeneration/resources_nest/point_neuron/common/NeuronClass.jinja2 +++ b/pynestml/codegeneration/resources_nest/point_neuron/common/NeuronClass.jinja2 @@ -588,8 +588,8 @@ void {{ neuronName }}::pre_run_hook() {{ function_declaration.FunctionDeclaration(function, neuronName + "::") }} { {%- filter indent(2,True) %} -{%- with ast = function.get_block() %} -{%- include "directives_cpp/Block.jinja2" %} +{%- with ast = function.get_stmts_body() %} +{%- include "directives_cpp/StmtsBody.jinja2" %} {%- endwith %} {%- endfilter %} } @@ -782,13 +782,13 @@ void {{ neuronName }}::update(nest::Time const & origin, const long from, const {% if neuron.get_update_blocks() %} {%- filter indent(2) %} {%- for block in neuron.get_update_blocks() %} -{%- set ast = block.get_block() %} +{%- set ast = block.get_stmts_body() %} {%- if ast.print_comment('*')|length > 1 %} /* {{ast.print_comment('*')}} */ {%- endif %} -{%- include "directives_cpp/Block.jinja2" %} +{%- include "directives_cpp/StmtsBody.jinja2" %} {%- endfor %} {%- endfilter %} {%- endif %} @@ -853,14 +853,14 @@ void {{ neuronName }}::update(nest::Time const & origin, const long from, const {%- for block in neuron.get_on_condition_blocks() %} if ({{ printer.print(block.get_cond_expr()) }}) { -{%- set ast = block.get_block() %} +{%- set ast = block.get_stmts_body() %} {%- if ast.print_comment('*') | length > 1 %} /* {{ast.print_comment('*')}} */ {%- endif %} {%- filter indent(6) %} -{%- include "directives_cpp/Block.jinja2" %} +{%- include "directives_cpp/StmtsBody.jinja2" %} {%- endfilter %} } {%- endfor %} @@ -1141,14 +1141,14 @@ void {{ neuronName }}::handle(nest::CurrentEvent& e) // ------------------------------------------------------------------------- {%- for blk in neuron.get_on_receive_blocks() %} -{%- set ast = blk.get_block() %} +{%- set ast = blk.get_stmts_body() %} void {{ neuronName }}::on_receive_block_{{ blk.get_port_name() }}() { const double __timestep = nest::Time::get_resolution().get_ms(); // do not remove, this is necessary for the timestep() function {%- filter indent(2, True) -%} -{%- include "directives_cpp/Block.jinja2" %} +{%- include "directives_cpp/StmtsBody.jinja2" %} {%- endfilter %} } diff --git a/pynestml/codegeneration/resources_nest/point_neuron/common/SynapseHeader.h.jinja2 b/pynestml/codegeneration/resources_nest/point_neuron/common/SynapseHeader.h.jinja2 index 86cd059a0..de4e2f85b 100644 --- a/pynestml/codegeneration/resources_nest/point_neuron/common/SynapseHeader.h.jinja2 +++ b/pynestml/codegeneration/resources_nest/point_neuron/common/SynapseHeader.h.jinja2 @@ -851,8 +851,8 @@ void get_entry_from_continuous_variable_history(double t, **/ {% if synapse.get_on_receive_block(post_port) %} {%- set dynamics = synapse.get_on_receive_block(post_port) %} -{%- with ast = dynamics.get_block() %} -{%- include "directives_cpp/Block.jinja2" %} +{%- with ast = dynamics.get_stmts_body() %} +{%- include "directives_cpp/StmtsBody.jinja2" %} {%- endwith %} {%- endif %} {%- endfor %} @@ -903,9 +903,9 @@ void get_entry_from_continuous_variable_history(double t, **/ {% if synapse.get_on_receive_block(pre_port) %} {%- set dynamics = synapse.get_on_receive_block(pre_port) %} -{%- with ast = dynamics.get_block() %} +{%- with ast = dynamics.get_stmts_body() %} {%- filter indent(6, True) %} -{%- include "directives_cpp/Block.jinja2" %} +{%- include "directives_cpp/StmtsBody.jinja2" %} {%- endfilter %} {%- endwith %} {%- endif %} @@ -951,8 +951,8 @@ void get_entry_from_continuous_variable_history(double t, **/ {%- if synapse.get_on_receive_block(post_port) %} {%- set dynamics = synapse.get_on_receive_block(post_port) %} -{%- with ast = dynamics.get_block() %} -{%- include "directives_cpp/Block.jinja2" %} +{%- with ast = dynamics.get_stmts_body() %} +{%- include "directives_cpp/StmtsBody.jinja2" %} {%- endwith %} {%- endif %} {%- endfor %} @@ -1027,8 +1027,8 @@ void {%- filter indent(4, True) %} {%- set dynamics = synapse.get_on_receive_block(vt_port) %} -{%- with ast = dynamics.get_block() %} -{%- include "directives_cpp/Block.jinja2" %} +{%- with ast = dynamics.get_stmts_body() %} +{%- include "directives_cpp/StmtsBody.jinja2" %} {%- endwith %} {%- endfilter %} // process remaining dopa spikes in (t0, t1] @@ -1047,8 +1047,8 @@ void **/ {%- filter indent(6, True) %} {%- set dynamics = synapse.get_on_receive_block(vt_port) %} -{%- with ast = dynamics.get_block() %} -{%- include "directives_cpp/Block.jinja2" %} +{%- with ast = dynamics.get_stmts_body() %} +{%- include "directives_cpp/StmtsBody.jinja2" %} {%- endwith %} {%- endfilter %} @@ -1325,13 +1325,13 @@ inline void {%- if synapse.get_update_blocks() %} {%- filter indent(2) %} {%- for block in synapse.get_update_blocks() %} -{%- set ast = block.get_block() %} +{%- set ast = block.get_stmts_body() %} {%- if ast.print_comment('*')|length > 1 %} /* {{ast.print_comment('*')}} */ {%- endif %} -{%- include "directives_cpp/Block.jinja2" %} +{%- include "directives_cpp/StmtsBody.jinja2" %} {%- endfor %} {%- endfilter %} {%- endif %} @@ -1410,8 +1410,8 @@ inline void **/ {%- set dynamics = synapse.get_on_receive_block(post_port) %} -{%- with ast = dynamics.get_block() %} -{%- include "directives_cpp/Block.jinja2" %} +{%- with ast = dynamics.get_stmts_body() %} +{%- include "directives_cpp/StmtsBody.jinja2" %} {%- endwith %} {%- endfor %} {%- endif %} diff --git a/pynestml/codegeneration/resources_nest/point_neuron/directives_cpp/ForStatement.jinja2 b/pynestml/codegeneration/resources_nest/point_neuron/directives_cpp/ForStatement.jinja2 index f5c32841b..53fd412a5 100644 --- a/pynestml/codegeneration/resources_nest/point_neuron/directives_cpp/ForStatement.jinja2 +++ b/pynestml/codegeneration/resources_nest/point_neuron/directives_cpp/ForStatement.jinja2 @@ -14,7 +14,9 @@ for ( {{ ast.get_variable() }} = {{ printer.print(ast.get_start_from()) }}; {%- endif -%} {{ printer.print(ast.get_end_at()) }}; {{ ast.get_variable() }} += {{ ast.get_step() }} ) { -{%- with ast = ast.get_block() %} -{%- include "directives_cpp/Block.jinja2" %} -{%- endwith %} +{%- filter indent(2) %} +{%- with ast = ast.get_stmts_body() %} +{%- include "directives_cpp/StmtsBody.jinja2" %} +{%- endwith %} +{%- endfilter %} } diff --git a/pynestml/codegeneration/resources_nest/point_neuron/directives_cpp/IfStatement.jinja2 b/pynestml/codegeneration/resources_nest/point_neuron/directives_cpp/IfStatement.jinja2 index 137f10cf0..cf4a45608 100644 --- a/pynestml/codegeneration/resources_nest/point_neuron/directives_cpp/IfStatement.jinja2 +++ b/pynestml/codegeneration/resources_nest/point_neuron/directives_cpp/IfStatement.jinja2 @@ -6,8 +6,8 @@ if ({{ printer.print(ast.get_if_clause().get_condition()) }}) { {%- filter indent(2, True) %} -{%- with ast = ast.get_if_clause().get_block() %} -{%- include "directives_cpp/Block.jinja2" %} +{%- with ast = ast.get_if_clause().get_stmts_body() %} +{%- include "directives_cpp/StmtsBody.jinja2" %} {%- endwith %} {%- endfilter %} {%- for elif in ast.get_elif_clauses() %} @@ -15,8 +15,8 @@ if ({{ printer.print(ast.get_if_clause().get_condition()) }}) else if ({{ printer.print(elif.get_condition()) }}) { {%- filter indent(2, True) %} -{%- with ast = elif.get_block() %} -{%- include "directives_cpp/Block.jinja2" %} +{%- with ast = elif.get_stmts_body() %} +{%- include "directives_cpp/StmtsBody.jinja2" %} {%- endwith %} {%- endfilter %} {%- endfor %} @@ -25,8 +25,8 @@ else if ({{ printer.print(elif.get_condition()) }}) else { {%- filter indent(2, True) %} -{%- with ast = ast.get_else_clause().get_block() %} -{%- include "directives_cpp/Block.jinja2" %} +{%- with ast = ast.get_else_clause().get_stmts_body() %} +{%- include "directives_cpp/StmtsBody.jinja2" %} {%- endwith %} {%- endfilter %} {%- endif %} diff --git a/pynestml/codegeneration/resources_nest/point_neuron/directives_cpp/Block.jinja2 b/pynestml/codegeneration/resources_nest/point_neuron/directives_cpp/StmtsBody.jinja2 similarity index 72% rename from pynestml/codegeneration/resources_nest/point_neuron/directives_cpp/Block.jinja2 rename to pynestml/codegeneration/resources_nest/point_neuron/directives_cpp/StmtsBody.jinja2 index 61ea653c0..dc1419aaf 100644 --- a/pynestml/codegeneration/resources_nest/point_neuron/directives_cpp/Block.jinja2 +++ b/pynestml/codegeneration/resources_nest/point_neuron/directives_cpp/StmtsBody.jinja2 @@ -1,7 +1,5 @@ {# - Handles a complex block statement - @grammar: Block = ( Stmt | NEWLINE )*; - @param ast ASTBlock + Handles an ASTStmtsBody #} {%- if tracing %}/* generated by {{self._TemplateReference__context.name}} */ {% endif %} {%- for statement in ast.get_stmts() %} diff --git a/pynestml/codegeneration/resources_nest/point_neuron/directives_cpp/WhileStatement.jinja2 b/pynestml/codegeneration/resources_nest/point_neuron/directives_cpp/WhileStatement.jinja2 index 0606b5f87..ef171ac81 100644 --- a/pynestml/codegeneration/resources_nest/point_neuron/directives_cpp/WhileStatement.jinja2 +++ b/pynestml/codegeneration/resources_nest/point_neuron/directives_cpp/WhileStatement.jinja2 @@ -5,7 +5,9 @@ {%- if tracing %}/* generated by {{self._TemplateReference__context.name}} */ {% endif %} while ( {{ printer.print(ast.get_condition()) }}) { -{%- with ast = ast.get_block() %} -{%- include "directives_cpp/Block.jinja2" %} -{%- endwith %} +{%- filter indent(2) %} +{%- with ast = ast.get_stmts_body() %} +{%- include "directives_cpp/StmtsBody.jinja2" %} +{%- endwith %} +{%- endfilter %} } diff --git a/pynestml/codegeneration/resources_nest_compartmental/cm_neuron/cm_neuroncurrents_@NEURON_NAME@.cpp.jinja2 b/pynestml/codegeneration/resources_nest_compartmental/cm_neuron/cm_neuroncurrents_@NEURON_NAME@.cpp.jinja2 index fdf83b974..3cc3e4730 100644 --- a/pynestml/codegeneration/resources_nest_compartmental/cm_neuron/cm_neuroncurrents_@NEURON_NAME@.cpp.jinja2 +++ b/pynestml/codegeneration/resources_nest_compartmental/cm_neuron/cm_neuroncurrents_@NEURON_NAME@.cpp.jinja2 @@ -85,8 +85,8 @@ along with NEST. If not, see . inline {{ function_declaration.FunctionDeclaration(function, "nest::"~ion_channel_name~cm_unique_suffix~"::") }} { {%- filter indent(2,True) %} -{%- with ast = function.get_block() %} -{%- include "directives_cpp/Block.jinja2" %} +{%- with ast = function.get_stmts_body() %} +{%- include "directives_cpp/StmtsBody.jinja2" %} {%- endwith %} {%- endfilter %} } @@ -98,8 +98,8 @@ inline {{ function_declaration.FunctionDeclaration(function, "nest::"~ion_channe {{ vectorized_function_declaration.FunctionDeclaration(function, "nest::"~ion_channel_name~cm_unique_suffix~"::") }} { {%- filter indent(2,True) %} -{%- with ast = function.get_block() %} -{%- include "directives_cpp/VectorizedBlock.jinja2" %} +{%- with ast = function.get_stmts_body() %} +{%- include "directives_cpp/VectorizedStmtsBody.jinja2" %} {%- endwith %} {%- endfilter %} } @@ -799,8 +799,8 @@ std::pair< std::vector< double >, std::vector< double > > nest::{{synapse_name}} inline {{ function_declaration.FunctionDeclaration(function, "nest::"~synapse_name~cm_unique_suffix~"::") }} { {%- filter indent(2,True) %} -{%- with ast = function.get_block() %} -{%- include "directives/Block.jinja2" %} +{%- with ast = function.get_stmts_body() %} +{%- include "directives/StmtsBody.jinja2" %} {%- endwith %} {%- endfilter %} } @@ -1002,8 +1002,8 @@ std::pair< std::vector< double >, std::vector< double > > nest::{{continuous_nam inline {{ function_declaration.FunctionDeclaration(function, "nest::"~continuous_name~cm_unique_suffix~"::") }} { {%- filter indent(2,True) %} -{%- with ast = function.get_block() %} -{%- include "directives/Block.jinja2" %} +{%- with ast = function.get_stmts_body() %} +{%- include "directives/StmtsBody.jinja2" %} {%- endwith %} {%- endfilter %} } diff --git a/pynestml/codegeneration/resources_python_standalone/point_neuron/@NEURON_NAME@.py.jinja2 b/pynestml/codegeneration/resources_python_standalone/point_neuron/@NEURON_NAME@.py.jinja2 index 9e3d1e404..a54f210ba 100644 --- a/pynestml/codegeneration/resources_python_standalone/point_neuron/@NEURON_NAME@.py.jinja2 +++ b/pynestml/codegeneration/resources_python_standalone/point_neuron/@NEURON_NAME@.py.jinja2 @@ -208,8 +208,8 @@ class Neuron_{{neuronName}}(Neuron): {% for function in neuron.get_functions() -%} {{ function_declaration.FunctionDeclaration(function, neuronName) }}: {%- filter indent(4,True) %} -{%- with ast = function.get_block() %} -{%- include "directives_py/Block.jinja2" %} +{%- with ast = function.get_stmts_body() %} +{%- include "directives_py/StmtsBody.jinja2" %} {%- endwith %} {%- endfilter %} {%- endfor %} @@ -300,8 +300,8 @@ class Neuron_{{neuronName}}(Neuron): {% if neuron.get_update_blocks()|length > 0 %} {%- filter indent(4) %} {%- for dynamics in neuron.get_update_blocks() %} -{%- set ast = dynamics.get_block() %} -{%- include "directives_py/Block.jinja2" %} +{%- set ast = dynamics.get_stmts_body() %} +{%- include "directives_py/StmtsBody.jinja2" %} {%- endfor %} {%- endfilter %} {%- endif %} @@ -346,12 +346,12 @@ class Neuron_{{neuronName}}(Neuron): # ------------------------------------------------------------------------- {%- for block in neuron.get_on_condition_blocks() %} if {{ printer.print(block.get_cond_expr()) }}: -{%- set ast = block.get_block() %} +{%- set ast = block.get_stmts_body() %} {%- if ast.print_comment('#') | length > 1 %} # {{ast.print_comment('#')}} {%- endif %} {%- filter indent(6) %} -{%- include "directives_py/Block.jinja2" %} +{%- include "directives_py/StmtsBody.jinja2" %} {%- endfilter %} {%- endfor %} @@ -383,9 +383,9 @@ class Neuron_{{neuronName}}(Neuron): # ------------------------------------------------------------------------- {%- for blk in neuron.get_on_receive_blocks() %} -{%- set ast = blk.get_block() %} +{%- set ast = blk.get_stmts_body() %} def on_receive_block_{{ blk.get_port_name() }}(self): {%- filter indent(4, True) -%} -{%- include "directives_py/Block.jinja2" %} +{%- include "directives_py/StmtsBody.jinja2" %} {%- endfilter %} {% endfor %} diff --git a/pynestml/codegeneration/resources_python_standalone/point_neuron/directives_py/Block.jinja2 b/pynestml/codegeneration/resources_python_standalone/point_neuron/directives_py/Block.jinja2 deleted file mode 100644 index 985179281..000000000 --- a/pynestml/codegeneration/resources_python_standalone/point_neuron/directives_py/Block.jinja2 +++ /dev/null @@ -1,11 +0,0 @@ -{# - Handles a complex block statement - @grammar: Block = ( Stmt | NEWLINE )*; - @param ast ASTBlock -#} -{%- if tracing %}# generated by {{self._TemplateReference__context.name}}{% endif %} -{%- for statement in ast.get_stmts() %} -{%- with stmt = statement %} -{%- include "directives_py/Statement.jinja2" %} -{%- endwith %} -{%- endfor %} diff --git a/pynestml/codegeneration/resources_python_standalone/point_neuron/directives_py/ForStatement.jinja2 b/pynestml/codegeneration/resources_python_standalone/point_neuron/directives_py/ForStatement.jinja2 index d3509ade5..262038f16 100644 --- a/pynestml/codegeneration/resources_python_standalone/point_neuron/directives_py/ForStatement.jinja2 +++ b/pynestml/codegeneration/resources_python_standalone/point_neuron/directives_py/ForStatement.jinja2 @@ -6,8 +6,8 @@ for {{ ast.get_variable() }} in range({{ printer.print(ast.get_start_from()) }}, {{ printer.print(ast.get_end_at()) }}): {%- filter indent(2) %} -{%- with ast = ast.get_block() %} -{%- include "directives_py/Block.jinja2" %} +{%- with ast = ast.get_stmts_body() %} +{%- include "directives_py/StmtsBody.jinja2" %} {%- endwith %} {%- endfilter %} {{ ast.get_variable() }} += {{ ast.get_step() }} diff --git a/pynestml/codegeneration/resources_python_standalone/point_neuron/directives_py/IfStatement.jinja2 b/pynestml/codegeneration/resources_python_standalone/point_neuron/directives_py/IfStatement.jinja2 index 89634dd9d..baf9ee70e 100644 --- a/pynestml/codegeneration/resources_python_standalone/point_neuron/directives_py/IfStatement.jinja2 +++ b/pynestml/codegeneration/resources_python_standalone/point_neuron/directives_py/IfStatement.jinja2 @@ -5,20 +5,20 @@ {%- if tracing %}# generated by {{self._TemplateReference__context.name}} {% endif %} if {{ printer.print(ast.get_if_clause().get_condition()) }}: {%- filter indent(2) %} -{%- set ast = ast.get_if_clause().get_block() %} -{%- include "directives_py/Block.jinja2" %} +{%- set ast = ast.get_if_clause().get_stmts_body() %} +{%- include "directives_py/StmtsBody.jinja2" %} {%- endfilter %} {%- for elif in ast.get_elif_clauses() %} elif {{ printer.print(elif.get_condition()) }}: {%- filter indent(2) %} -{%- set ast = elif.get_block() %} -{%- include "directives_py/Block.jinja2" %} +{%- set ast = elif.get_stmts_body() %} +{%- include "directives_py/StmtsBody.jinja2" %} {%- endfilter %} {%- endfor %} {%- if ast.has_else_clause() %} else: {%- filter indent(2) %} -{%- set ast = ast.get_else_clause().get_block() %} -{%- include "directives_py/Block.jinja2" %} +{%- set ast = ast.get_else_clause().get_stmts_body() %} +{%- include "directives_py/StmtsBody.jinja2" %} {%- endfilter %} {%- endif %} diff --git a/pynestml/codegeneration/resources_python_standalone/point_neuron/directives_py/StmtsBody.jinja2 b/pynestml/codegeneration/resources_python_standalone/point_neuron/directives_py/StmtsBody.jinja2 new file mode 100644 index 000000000..a6e4627b0 --- /dev/null +++ b/pynestml/codegeneration/resources_python_standalone/point_neuron/directives_py/StmtsBody.jinja2 @@ -0,0 +1,11 @@ +{# + Handles a sequence of statements + @param ast ASTStmtsBody +#} +{%- if tracing %}# generated by {{ self._TemplateReference__context.name }}{% endif %} + +{%- for statement in ast.get_stmts() %} +{%- with stmt = statement %} +{%- include "directives_py/Statement.jinja2" %} +{%- endwith %} +{%- endfor %} diff --git a/pynestml/codegeneration/resources_python_standalone/point_neuron/directives_py/WhileStatement.jinja2 b/pynestml/codegeneration/resources_python_standalone/point_neuron/directives_py/WhileStatement.jinja2 index 50970cc29..324769f8b 100644 --- a/pynestml/codegeneration/resources_python_standalone/point_neuron/directives_py/WhileStatement.jinja2 +++ b/pynestml/codegeneration/resources_python_standalone/point_neuron/directives_py/WhileStatement.jinja2 @@ -5,6 +5,6 @@ {%- if tracing %}# generated by {{self._TemplateReference__context.name}}{% endif %} while {{ printer.print(ast.get_condition()) }}: {%- filter indent(2) %} -{%- set ast = ast.get_block() %} -{%- include "directives_py/Block.jinja2" %} +{%- set ast = ast.get_stmts_body() %} +{%- include "directives_py/StmtsBody.jinja2" %} {%- endfilter %} diff --git a/pynestml/codegeneration/resources_spinnaker/@NEURON_NAME@_impl.h.jinja2 b/pynestml/codegeneration/resources_spinnaker/@NEURON_NAME@_impl.h.jinja2 index 891c888dd..c1bacaa7c 100644 --- a/pynestml/codegeneration/resources_spinnaker/@NEURON_NAME@_impl.h.jinja2 +++ b/pynestml/codegeneration/resources_spinnaker/@NEURON_NAME@_impl.h.jinja2 @@ -230,13 +230,13 @@ static void neuron_impl_do_timestep_update( {%- if neuron.get_update_blocks() %} {%- filter indent(8) %} {%- for block in neuron.get_update_blocks() %} -{%- set ast = block.get_block() %} +{%- set ast = block.get_stmts_body() %} {%- if ast.print_comment('*')|length > 1 %} /* {{ast.print_comment('*')}} */ {%- endif %} -{%- include "directives_cpp/Block.jinja2" %} +{%- include "directives_cpp/StmtsBody.jinja2" %} {%- endfor %} {%- endfilter %} {%- endif %} diff --git a/pynestml/codegeneration/resources_spinnaker/@SYNAPSE_NAME@_impl.c.jinja2 b/pynestml/codegeneration/resources_spinnaker/@SYNAPSE_NAME@_impl.c.jinja2 index e7fe320a3..a36f0d12c 100644 --- a/pynestml/codegeneration/resources_spinnaker/@SYNAPSE_NAME@_impl.c.jinja2 +++ b/pynestml/codegeneration/resources_spinnaker/@SYNAPSE_NAME@_impl.c.jinja2 @@ -189,8 +189,8 @@ static inline update_state_t timing_apply_post_spike( // {%- set dynamics = synapse.get_on_receive_block(post_port) %} -{%- with ast = dynamics.get_block() %} -{%- include "directives_cpp/Block.jinja2" %} +{%- with ast = dynamics.get_stmts_body() %} +{%- include "directives_cpp/StmtsBody.jinja2" %} {%- endwith %} {%- endfor %} {%- endif %} @@ -224,8 +224,8 @@ static inline update_state_t timing_apply_pre_spike( // {%- set dynamics = synapse.get_on_receive_block(pre_port) %} -{%- with ast = dynamics.get_block() %} -{%- include "directives_cpp/Block.jinja2" %} +{%- with ast = dynamics.get_stmts_body() %} +{%- include "directives_cpp/StmtsBody.jinja2" %} {%- endwith %} {%- endfor %} {%- endfilter %} diff --git a/pynestml/generated/PyNestMLLexer.py b/pynestml/generated/PyNestMLLexer.py index fe99b1dd7..426cb4ae6 100644 --- a/pynestml/generated/PyNestMLLexer.py +++ b/pynestml/generated/PyNestMLLexer.py @@ -461,7 +461,7 @@ def action(self, localctx:RuleContext, ruleIndex:int, actionIndex:int): def NEWLINE_action(self, localctx:RuleContext , actionIndex:int): if actionIndex == 0: - self.onNewLine() + self.onNewLine() def sempred(self, localctx:RuleContext, ruleIndex:int, predIndex:int): @@ -477,7 +477,7 @@ def sempred(self, localctx:RuleContext, ruleIndex:int, predIndex:int): def NEWLINE_sempred(self, localctx:RuleContext, predIndex:int): if predIndex == 0: - return self.atStartOfInput() + return self.atStartOfInput() diff --git a/pynestml/generated/PyNestMLLexerBase.py b/pynestml/generated/PyNestMLLexerBase.py index 8480f5354..f8509be4d 100644 --- a/pynestml/generated/PyNestMLLexerBase.py +++ b/pynestml/generated/PyNestMLLexerBase.py @@ -18,13 +18,14 @@ # # You should have received a copy of the GNU General Public License # along with NEST. If not, see . -from typing import TextIO -from antlr4 import * -from antlr4.Token import CommonToken -import sys from typing import TextIO + import re +import sys + +from antlr4 import * +from antlr4.Token import CommonToken from pynestml.generated.PyNestMLParser import PyNestMLParser diff --git a/pynestml/generated/PyNestMLParser.py b/pynestml/generated/PyNestMLParser.py index 2c51de196..1ff97f5ed 100644 --- a/pynestml/generated/PyNestMLParser.py +++ b/pynestml/generated/PyNestMLParser.py @@ -10,7 +10,7 @@ def serializedATN(): return [ - 4,1,91,628,2,0,7,0,2,1,7,1,2,2,7,2,2,3,7,3,2,4,7,4,2,5,7,5,2,6,7, + 4,1,91,654,2,0,7,0,2,1,7,1,2,2,7,2,2,3,7,3,2,4,7,4,2,5,7,5,2,6,7, 6,2,7,7,7,2,8,7,8,2,9,7,9,2,10,7,10,2,11,7,11,2,12,7,12,2,13,7,13, 2,14,7,14,2,15,7,15,2,16,7,16,2,17,7,17,2,18,7,18,2,19,7,19,2,20, 7,20,2,21,7,21,2,22,7,22,2,23,7,23,2,24,7,24,2,25,7,25,2,26,7,26, @@ -20,228 +20,238 @@ def serializedATN(): 7,46,1,0,1,0,1,0,1,0,1,0,1,0,3,0,101,8,0,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,3,1,112,8,1,1,1,1,1,1,1,3,1,117,8,1,1,1,1,1,1,1,1,1, 5,1,123,8,1,10,1,12,1,126,9,1,1,2,3,2,129,8,2,1,2,1,2,1,3,1,3,1, - 3,1,3,1,3,1,3,1,3,1,3,1,3,1,3,1,3,3,3,144,8,3,1,3,1,3,1,3,1,3,1, - 3,1,3,1,3,3,3,153,8,3,1,3,1,3,1,3,1,3,3,3,159,8,3,1,3,1,3,1,3,1, - 3,1,3,1,3,1,3,1,3,1,3,1,3,1,3,1,3,1,3,1,3,1,3,1,3,1,3,1,3,1,3,5, - 3,180,8,3,10,3,12,3,183,9,3,1,4,1,4,1,4,1,4,3,4,189,8,4,1,4,1,4, - 1,4,3,4,194,8,4,1,5,1,5,1,5,3,5,199,8,5,1,6,1,6,1,6,1,6,1,6,3,6, - 206,8,6,1,7,1,7,1,7,1,7,1,7,1,7,1,7,3,7,215,8,7,1,8,1,8,3,8,219, - 8,8,1,9,1,9,1,9,1,9,1,9,3,9,226,8,9,1,9,5,9,229,8,9,10,9,12,9,232, - 9,9,1,10,1,10,1,10,1,10,1,10,5,10,239,8,10,10,10,12,10,242,9,10, - 3,10,244,8,10,1,10,1,10,1,11,3,11,249,8,11,1,11,1,11,1,11,1,11,1, - 11,1,11,3,11,257,8,11,1,11,5,11,260,8,11,10,11,12,11,263,9,11,1, - 11,1,11,1,12,1,12,1,12,1,12,3,12,271,8,12,1,12,5,12,274,8,12,10, - 12,12,12,277,9,12,1,12,1,12,1,13,1,13,1,13,1,13,1,13,1,13,1,13,1, - 13,1,13,5,13,290,8,13,10,13,12,13,293,9,13,1,13,3,13,296,8,13,1, - 13,1,13,1,14,1,14,1,14,4,14,303,8,14,11,14,12,14,304,1,14,1,14,1, - 15,1,15,3,15,311,8,15,1,16,1,16,1,16,3,16,316,8,16,1,17,1,17,1,17, - 1,17,3,17,322,8,17,1,17,1,17,1,18,1,18,1,18,1,18,1,18,1,18,3,18, - 332,8,18,1,18,1,18,1,19,3,19,337,8,19,1,19,3,19,340,8,19,1,19,1, - 19,1,19,5,19,345,8,19,10,19,12,19,348,9,19,1,19,1,19,1,19,3,19,353, - 8,19,1,19,1,19,1,19,1,19,3,19,359,8,19,1,19,5,19,362,8,19,10,19, - 12,19,365,9,19,1,20,1,20,1,20,1,21,1,21,1,21,1,21,1,21,1,21,1,21, - 3,21,377,8,21,1,22,1,22,1,23,1,23,1,24,1,24,3,24,385,8,24,1,25,1, - 25,5,25,389,8,25,10,25,12,25,392,9,25,1,25,3,25,395,8,25,1,26,1, - 26,1,26,1,26,1,26,1,27,1,27,1,27,1,27,1,27,1,28,1,28,1,28,1,28,1, - 29,1,29,1,29,1,29,1,29,1,29,1,29,1,29,3,29,419,8,29,1,29,1,29,1, - 29,1,29,1,30,1,30,1,30,1,30,1,30,1,31,1,31,4,31,432,8,31,11,31,12, - 31,433,1,31,1,31,1,32,1,32,1,32,1,32,1,33,1,33,1,33,1,33,1,33,1, - 33,1,33,1,33,1,33,1,33,1,33,4,33,453,8,33,11,33,12,33,454,1,33,1, - 33,1,34,1,34,1,34,1,34,1,34,5,34,464,8,34,10,34,12,34,467,9,34,1, - 34,1,34,1,34,1,34,1,35,1,35,1,35,1,35,1,35,5,35,478,8,35,10,35,12, - 35,481,9,35,1,35,1,35,1,35,1,35,1,36,1,36,1,36,1,36,1,36,4,36,492, - 8,36,11,36,12,36,493,1,36,1,36,1,37,1,37,1,37,1,37,1,38,1,38,1,38, - 1,38,1,38,1,38,1,38,4,38,509,8,38,11,38,12,38,510,1,38,1,38,1,39, - 1,39,1,39,1,39,1,39,1,39,3,39,521,8,39,1,39,1,39,1,39,1,39,5,39, - 527,8,39,10,39,12,39,530,9,39,3,39,532,8,39,1,39,3,39,535,8,39,4, - 39,537,8,39,11,39,12,39,538,1,39,1,39,1,40,1,40,1,40,1,40,1,40,3, - 40,548,8,40,1,40,1,40,5,40,552,8,40,10,40,12,40,555,9,40,1,40,1, - 40,1,40,1,41,1,41,1,41,1,41,1,41,3,41,565,8,41,1,41,1,41,1,41,1, - 41,1,41,1,42,1,42,3,42,574,8,42,1,43,1,43,1,43,1,43,1,43,1,43,1, - 43,1,43,1,43,5,43,585,8,43,10,43,12,43,588,9,43,3,43,590,8,43,1, - 43,3,43,593,8,43,1,43,3,43,596,8,43,1,43,1,43,1,43,1,44,1,44,1,44, - 1,44,1,44,1,44,5,44,607,8,44,10,44,12,44,610,9,44,3,44,612,8,44, - 1,44,1,44,3,44,616,8,44,1,44,1,44,1,44,1,45,1,45,1,45,1,46,1,46, - 1,46,1,46,1,46,0,2,2,6,47,0,2,4,6,8,10,12,14,16,18,20,22,24,26,28, - 30,32,34,36,38,40,42,44,46,48,50,52,54,56,58,60,62,64,66,68,70,72, - 74,76,78,80,82,84,86,88,90,92,0,4,2,0,51,51,75,75,1,0,90,91,1,0, - 32,34,3,0,25,25,87,88,90,91,689,0,100,1,0,0,0,2,111,1,0,0,0,4,128, - 1,0,0,0,6,143,1,0,0,0,8,193,1,0,0,0,10,198,1,0,0,0,12,205,1,0,0, - 0,14,214,1,0,0,0,16,218,1,0,0,0,18,220,1,0,0,0,20,233,1,0,0,0,22, - 248,1,0,0,0,24,266,1,0,0,0,26,280,1,0,0,0,28,299,1,0,0,0,30,310, - 1,0,0,0,32,315,1,0,0,0,34,321,1,0,0,0,36,325,1,0,0,0,38,336,1,0, - 0,0,40,366,1,0,0,0,42,376,1,0,0,0,44,378,1,0,0,0,46,380,1,0,0,0, - 48,382,1,0,0,0,50,386,1,0,0,0,52,396,1,0,0,0,54,401,1,0,0,0,56,406, - 1,0,0,0,58,410,1,0,0,0,60,424,1,0,0,0,62,431,1,0,0,0,64,437,1,0, - 0,0,66,441,1,0,0,0,68,458,1,0,0,0,70,472,1,0,0,0,72,486,1,0,0,0, - 74,497,1,0,0,0,76,501,1,0,0,0,78,514,1,0,0,0,80,542,1,0,0,0,82,559, - 1,0,0,0,84,573,1,0,0,0,86,575,1,0,0,0,88,600,1,0,0,0,90,620,1,0, - 0,0,92,623,1,0,0,0,94,101,5,10,0,0,95,101,5,11,0,0,96,101,5,12,0, - 0,97,101,5,13,0,0,98,101,5,14,0,0,99,101,3,2,1,0,100,94,1,0,0,0, - 100,95,1,0,0,0,100,96,1,0,0,0,100,97,1,0,0,0,100,98,1,0,0,0,100, - 99,1,0,0,0,101,1,1,0,0,0,102,103,6,1,-1,0,103,104,5,49,0,0,104,105, - 3,2,1,0,105,106,5,50,0,0,106,112,1,0,0,0,107,108,5,90,0,0,108,109, - 5,79,0,0,109,112,3,2,1,2,110,112,5,89,0,0,111,102,1,0,0,0,111,107, - 1,0,0,0,111,110,1,0,0,0,112,124,1,0,0,0,113,116,10,3,0,0,114,117, - 5,77,0,0,115,117,5,79,0,0,116,114,1,0,0,0,116,115,1,0,0,0,117,118, - 1,0,0,0,118,123,3,2,1,4,119,120,10,4,0,0,120,121,5,78,0,0,121,123, - 3,4,2,0,122,113,1,0,0,0,122,119,1,0,0,0,123,126,1,0,0,0,124,122, - 1,0,0,0,124,125,1,0,0,0,125,3,1,0,0,0,126,124,1,0,0,0,127,129,7, - 0,0,0,128,127,1,0,0,0,128,129,1,0,0,0,129,130,1,0,0,0,130,131,5, - 90,0,0,131,5,1,0,0,0,132,133,6,3,-1,0,133,134,5,49,0,0,134,135,3, - 6,3,0,135,136,5,50,0,0,136,144,1,0,0,0,137,138,3,10,5,0,138,139, - 3,6,3,9,139,144,1,0,0,0,140,141,5,28,0,0,141,144,3,6,3,4,142,144, - 3,8,4,0,143,132,1,0,0,0,143,137,1,0,0,0,143,140,1,0,0,0,143,142, - 1,0,0,0,144,181,1,0,0,0,145,146,10,10,0,0,146,147,5,78,0,0,147,180, - 3,6,3,10,148,152,10,8,0,0,149,153,5,77,0,0,150,153,5,79,0,0,151, - 153,5,80,0,0,152,149,1,0,0,0,152,150,1,0,0,0,152,151,1,0,0,0,153, - 154,1,0,0,0,154,180,3,6,3,9,155,158,10,7,0,0,156,159,5,51,0,0,157, - 159,5,75,0,0,158,156,1,0,0,0,158,157,1,0,0,0,159,160,1,0,0,0,160, - 180,3,6,3,8,161,162,10,6,0,0,162,163,3,12,6,0,163,164,3,6,3,7,164, - 180,1,0,0,0,165,166,10,5,0,0,166,167,3,14,7,0,167,168,3,6,3,6,168, - 180,1,0,0,0,169,170,10,3,0,0,170,171,3,16,8,0,171,172,3,6,3,4,172, - 180,1,0,0,0,173,174,10,2,0,0,174,175,5,81,0,0,175,176,3,6,3,0,176, - 177,5,82,0,0,177,178,3,6,3,3,178,180,1,0,0,0,179,145,1,0,0,0,179, - 148,1,0,0,0,179,155,1,0,0,0,179,161,1,0,0,0,179,165,1,0,0,0,179, - 169,1,0,0,0,179,173,1,0,0,0,180,183,1,0,0,0,181,179,1,0,0,0,181, - 182,1,0,0,0,182,7,1,0,0,0,183,181,1,0,0,0,184,194,3,20,10,0,185, - 194,5,87,0,0,186,188,7,1,0,0,187,189,3,18,9,0,188,187,1,0,0,0,188, - 189,1,0,0,0,189,194,1,0,0,0,190,194,5,88,0,0,191,194,5,25,0,0,192, - 194,3,18,9,0,193,184,1,0,0,0,193,185,1,0,0,0,193,186,1,0,0,0,193, - 190,1,0,0,0,193,191,1,0,0,0,193,192,1,0,0,0,194,9,1,0,0,0,195,199, - 5,51,0,0,196,199,5,75,0,0,197,199,5,52,0,0,198,195,1,0,0,0,198,196, - 1,0,0,0,198,197,1,0,0,0,199,11,1,0,0,0,200,206,5,55,0,0,201,206, - 5,54,0,0,202,206,5,53,0,0,203,206,5,61,0,0,204,206,5,62,0,0,205, - 200,1,0,0,0,205,201,1,0,0,0,205,202,1,0,0,0,205,203,1,0,0,0,205, - 204,1,0,0,0,206,13,1,0,0,0,207,215,5,63,0,0,208,215,5,65,0,0,209, - 215,5,70,0,0,210,215,5,71,0,0,211,215,5,72,0,0,212,215,5,73,0,0, - 213,215,5,64,0,0,214,207,1,0,0,0,214,208,1,0,0,0,214,209,1,0,0,0, - 214,210,1,0,0,0,214,211,1,0,0,0,214,212,1,0,0,0,214,213,1,0,0,0, - 215,15,1,0,0,0,216,219,5,26,0,0,217,219,5,27,0,0,218,216,1,0,0,0, - 218,217,1,0,0,0,219,17,1,0,0,0,220,225,5,89,0,0,221,222,5,56,0,0, - 222,223,3,6,3,0,223,224,5,58,0,0,224,226,1,0,0,0,225,221,1,0,0,0, - 225,226,1,0,0,0,226,230,1,0,0,0,227,229,5,85,0,0,228,227,1,0,0,0, - 229,232,1,0,0,0,230,228,1,0,0,0,230,231,1,0,0,0,231,19,1,0,0,0,232, - 230,1,0,0,0,233,234,5,89,0,0,234,243,5,49,0,0,235,240,3,6,3,0,236, - 237,5,74,0,0,237,239,3,6,3,0,238,236,1,0,0,0,239,242,1,0,0,0,240, - 238,1,0,0,0,240,241,1,0,0,0,241,244,1,0,0,0,242,240,1,0,0,0,243, - 235,1,0,0,0,243,244,1,0,0,0,244,245,1,0,0,0,245,246,5,50,0,0,246, - 21,1,0,0,0,247,249,5,29,0,0,248,247,1,0,0,0,248,249,1,0,0,0,249, - 250,1,0,0,0,250,251,5,16,0,0,251,252,5,89,0,0,252,253,3,0,0,0,253, - 254,5,76,0,0,254,256,3,6,3,0,255,257,5,84,0,0,256,255,1,0,0,0,256, - 257,1,0,0,0,257,261,1,0,0,0,258,260,3,42,21,0,259,258,1,0,0,0,260, - 263,1,0,0,0,261,259,1,0,0,0,261,262,1,0,0,0,262,264,1,0,0,0,263, - 261,1,0,0,0,264,265,5,9,0,0,265,23,1,0,0,0,266,267,3,18,9,0,267, - 268,5,76,0,0,268,270,3,6,3,0,269,271,5,84,0,0,270,269,1,0,0,0,270, - 271,1,0,0,0,271,275,1,0,0,0,272,274,3,42,21,0,273,272,1,0,0,0,274, - 277,1,0,0,0,275,273,1,0,0,0,275,276,1,0,0,0,276,278,1,0,0,0,277, - 275,1,0,0,0,278,279,5,9,0,0,279,25,1,0,0,0,280,281,5,30,0,0,281, - 282,3,18,9,0,282,283,5,76,0,0,283,291,3,6,3,0,284,285,5,4,0,0,285, - 286,3,18,9,0,286,287,5,76,0,0,287,288,3,6,3,0,288,290,1,0,0,0,289, - 284,1,0,0,0,290,293,1,0,0,0,291,289,1,0,0,0,291,292,1,0,0,0,292, - 295,1,0,0,0,293,291,1,0,0,0,294,296,5,84,0,0,295,294,1,0,0,0,295, - 296,1,0,0,0,296,297,1,0,0,0,297,298,5,9,0,0,298,27,1,0,0,0,299,300, - 5,9,0,0,300,302,5,1,0,0,301,303,3,30,15,0,302,301,1,0,0,0,303,304, - 1,0,0,0,304,302,1,0,0,0,304,305,1,0,0,0,305,306,1,0,0,0,306,307, - 5,2,0,0,307,29,1,0,0,0,308,311,3,34,17,0,309,311,3,32,16,0,310,308, - 1,0,0,0,310,309,1,0,0,0,311,31,1,0,0,0,312,316,3,50,25,0,313,316, - 3,58,29,0,314,316,3,60,30,0,315,312,1,0,0,0,315,313,1,0,0,0,315, - 314,1,0,0,0,316,33,1,0,0,0,317,322,3,36,18,0,318,322,3,20,10,0,319, - 322,3,38,19,0,320,322,3,48,24,0,321,317,1,0,0,0,321,318,1,0,0,0, - 321,319,1,0,0,0,321,320,1,0,0,0,322,323,1,0,0,0,323,324,5,9,0,0, - 324,35,1,0,0,0,325,331,3,18,9,0,326,332,5,76,0,0,327,332,5,66,0, - 0,328,332,5,67,0,0,329,332,5,68,0,0,330,332,5,69,0,0,331,326,1,0, - 0,0,331,327,1,0,0,0,331,328,1,0,0,0,331,329,1,0,0,0,331,330,1,0, - 0,0,332,333,1,0,0,0,333,334,3,6,3,0,334,37,1,0,0,0,335,337,5,29, - 0,0,336,335,1,0,0,0,336,337,1,0,0,0,337,339,1,0,0,0,338,340,5,16, - 0,0,339,338,1,0,0,0,339,340,1,0,0,0,340,341,1,0,0,0,341,346,3,18, - 9,0,342,343,5,74,0,0,343,345,3,18,9,0,344,342,1,0,0,0,345,348,1, - 0,0,0,346,344,1,0,0,0,346,347,1,0,0,0,347,349,1,0,0,0,348,346,1, - 0,0,0,349,352,3,0,0,0,350,351,5,76,0,0,351,353,3,6,3,0,352,350,1, - 0,0,0,352,353,1,0,0,0,353,358,1,0,0,0,354,355,5,59,0,0,355,356,3, - 6,3,0,356,357,5,60,0,0,357,359,1,0,0,0,358,354,1,0,0,0,358,359,1, - 0,0,0,359,363,1,0,0,0,360,362,3,42,21,0,361,360,1,0,0,0,362,365, - 1,0,0,0,363,361,1,0,0,0,363,364,1,0,0,0,364,39,1,0,0,0,365,363,1, - 0,0,0,366,367,3,38,19,0,367,368,5,9,0,0,368,41,1,0,0,0,369,377,5, - 45,0,0,370,377,5,46,0,0,371,372,5,47,0,0,372,373,3,44,22,0,373,374, - 5,83,0,0,374,375,3,46,23,0,375,377,1,0,0,0,376,369,1,0,0,0,376,370, - 1,0,0,0,376,371,1,0,0,0,377,43,1,0,0,0,378,379,5,89,0,0,379,45,1, - 0,0,0,380,381,5,89,0,0,381,47,1,0,0,0,382,384,5,17,0,0,383,385,3, - 6,3,0,384,383,1,0,0,0,384,385,1,0,0,0,385,49,1,0,0,0,386,390,3,52, - 26,0,387,389,3,54,27,0,388,387,1,0,0,0,389,392,1,0,0,0,390,388,1, - 0,0,0,390,391,1,0,0,0,391,394,1,0,0,0,392,390,1,0,0,0,393,395,3, - 56,28,0,394,393,1,0,0,0,394,395,1,0,0,0,395,51,1,0,0,0,396,397,5, - 18,0,0,397,398,3,6,3,0,398,399,5,82,0,0,399,400,3,28,14,0,400,53, - 1,0,0,0,401,402,5,19,0,0,402,403,3,6,3,0,403,404,5,82,0,0,404,405, - 3,28,14,0,405,55,1,0,0,0,406,407,5,20,0,0,407,408,5,82,0,0,408,409, - 3,28,14,0,409,57,1,0,0,0,410,411,5,21,0,0,411,412,5,89,0,0,412,413, - 5,23,0,0,413,414,3,6,3,0,414,415,5,48,0,0,415,416,3,6,3,0,416,418, - 5,24,0,0,417,419,5,75,0,0,418,417,1,0,0,0,418,419,1,0,0,0,419,420, - 1,0,0,0,420,421,7,1,0,0,421,422,5,82,0,0,422,423,3,28,14,0,423,59, - 1,0,0,0,424,425,5,22,0,0,425,426,3,6,3,0,426,427,5,82,0,0,427,428, - 3,28,14,0,428,61,1,0,0,0,429,432,3,64,32,0,430,432,5,9,0,0,431,429, - 1,0,0,0,431,430,1,0,0,0,432,433,1,0,0,0,433,431,1,0,0,0,433,434, - 1,0,0,0,434,435,1,0,0,0,435,436,5,0,0,1,436,63,1,0,0,0,437,438,5, - 31,0,0,438,439,5,89,0,0,439,440,3,66,33,0,440,65,1,0,0,0,441,442, - 5,82,0,0,442,443,5,9,0,0,443,452,5,1,0,0,444,453,3,72,36,0,445,453, - 3,76,38,0,446,453,3,78,39,0,447,453,3,86,43,0,448,453,3,88,44,0, - 449,453,3,68,34,0,450,453,3,70,35,0,451,453,3,74,37,0,452,444,1, - 0,0,0,452,445,1,0,0,0,452,446,1,0,0,0,452,447,1,0,0,0,452,448,1, - 0,0,0,452,449,1,0,0,0,452,450,1,0,0,0,452,451,1,0,0,0,453,454,1, - 0,0,0,454,452,1,0,0,0,454,455,1,0,0,0,455,456,1,0,0,0,456,457,5, - 2,0,0,457,67,1,0,0,0,458,459,5,40,0,0,459,460,5,49,0,0,460,465,5, - 89,0,0,461,462,5,74,0,0,462,464,3,92,46,0,463,461,1,0,0,0,464,467, - 1,0,0,0,465,463,1,0,0,0,465,466,1,0,0,0,466,468,1,0,0,0,467,465, - 1,0,0,0,468,469,5,50,0,0,469,470,5,82,0,0,470,471,3,28,14,0,471, - 69,1,0,0,0,472,473,5,41,0,0,473,474,5,49,0,0,474,479,3,6,3,0,475, - 476,5,74,0,0,476,478,3,92,46,0,477,475,1,0,0,0,478,481,1,0,0,0,479, - 477,1,0,0,0,479,480,1,0,0,0,480,482,1,0,0,0,481,479,1,0,0,0,482, - 483,5,50,0,0,483,484,5,82,0,0,484,485,3,28,14,0,485,71,1,0,0,0,486, - 487,7,2,0,0,487,488,5,82,0,0,488,489,5,9,0,0,489,491,5,1,0,0,490, - 492,3,40,20,0,491,490,1,0,0,0,492,493,1,0,0,0,493,491,1,0,0,0,493, - 494,1,0,0,0,494,495,1,0,0,0,495,496,5,2,0,0,496,73,1,0,0,0,497,498, - 5,35,0,0,498,499,5,82,0,0,499,500,3,28,14,0,500,75,1,0,0,0,501,502, - 5,36,0,0,502,503,5,82,0,0,503,504,5,9,0,0,504,508,5,1,0,0,505,509, - 3,22,11,0,506,509,3,24,12,0,507,509,3,26,13,0,508,505,1,0,0,0,508, - 506,1,0,0,0,508,507,1,0,0,0,509,510,1,0,0,0,510,508,1,0,0,0,510, - 511,1,0,0,0,511,512,1,0,0,0,512,513,5,2,0,0,513,77,1,0,0,0,514,515, - 5,37,0,0,515,516,5,82,0,0,516,517,5,9,0,0,517,536,5,1,0,0,518,521, - 3,80,40,0,519,521,3,82,41,0,520,518,1,0,0,0,520,519,1,0,0,0,521, - 534,1,0,0,0,522,531,5,49,0,0,523,528,3,90,45,0,524,525,5,74,0,0, - 525,527,3,90,45,0,526,524,1,0,0,0,527,530,1,0,0,0,528,526,1,0,0, - 0,528,529,1,0,0,0,529,532,1,0,0,0,530,528,1,0,0,0,531,523,1,0,0, - 0,531,532,1,0,0,0,532,533,1,0,0,0,533,535,5,50,0,0,534,522,1,0,0, - 0,534,535,1,0,0,0,535,537,1,0,0,0,536,520,1,0,0,0,537,538,1,0,0, - 0,538,536,1,0,0,0,538,539,1,0,0,0,539,540,1,0,0,0,540,541,5,2,0, - 0,541,79,1,0,0,0,542,547,5,89,0,0,543,544,5,56,0,0,544,545,3,6,3, - 0,545,546,5,58,0,0,546,548,1,0,0,0,547,543,1,0,0,0,547,548,1,0,0, - 0,548,549,1,0,0,0,549,553,5,57,0,0,550,552,3,84,42,0,551,550,1,0, - 0,0,552,555,1,0,0,0,553,551,1,0,0,0,553,554,1,0,0,0,554,556,1,0, - 0,0,555,553,1,0,0,0,556,557,5,42,0,0,557,558,5,9,0,0,558,81,1,0, - 0,0,559,564,5,89,0,0,560,561,5,56,0,0,561,562,3,6,3,0,562,563,5, - 58,0,0,563,565,1,0,0,0,564,560,1,0,0,0,564,565,1,0,0,0,565,566,1, - 0,0,0,566,567,3,0,0,0,567,568,5,57,0,0,568,569,5,39,0,0,569,570, - 5,9,0,0,570,83,1,0,0,0,571,574,5,43,0,0,572,574,5,44,0,0,573,571, - 1,0,0,0,573,572,1,0,0,0,574,85,1,0,0,0,575,576,5,38,0,0,576,577, - 5,82,0,0,577,578,5,9,0,0,578,595,5,1,0,0,579,592,5,42,0,0,580,589, - 5,49,0,0,581,586,3,90,45,0,582,583,5,74,0,0,583,585,3,90,45,0,584, - 582,1,0,0,0,585,588,1,0,0,0,586,584,1,0,0,0,586,587,1,0,0,0,587, - 590,1,0,0,0,588,586,1,0,0,0,589,581,1,0,0,0,589,590,1,0,0,0,590, - 591,1,0,0,0,591,593,5,50,0,0,592,580,1,0,0,0,592,593,1,0,0,0,593, - 596,1,0,0,0,594,596,5,39,0,0,595,579,1,0,0,0,595,594,1,0,0,0,596, - 597,1,0,0,0,597,598,5,9,0,0,598,599,5,2,0,0,599,87,1,0,0,0,600,601, - 5,15,0,0,601,602,5,89,0,0,602,611,5,49,0,0,603,608,3,90,45,0,604, - 605,5,74,0,0,605,607,3,90,45,0,606,604,1,0,0,0,607,610,1,0,0,0,608, - 606,1,0,0,0,608,609,1,0,0,0,609,612,1,0,0,0,610,608,1,0,0,0,611, - 603,1,0,0,0,611,612,1,0,0,0,612,613,1,0,0,0,613,615,5,50,0,0,614, - 616,3,0,0,0,615,614,1,0,0,0,615,616,1,0,0,0,616,617,1,0,0,0,617, - 618,5,82,0,0,618,619,3,28,14,0,619,89,1,0,0,0,620,621,5,89,0,0,621, - 622,3,0,0,0,622,91,1,0,0,0,623,624,5,89,0,0,624,625,5,76,0,0,625, - 626,7,3,0,0,626,93,1,0,0,0,69,100,111,116,122,124,128,143,152,158, - 179,181,188,193,198,205,214,218,225,230,240,243,248,256,261,270, - 275,291,295,304,310,315,321,331,336,339,346,352,358,363,376,384, - 390,394,418,431,433,452,454,465,479,493,508,510,520,528,531,534, - 538,547,553,564,573,586,589,592,595,608,611,615 + 3,1,3,1,3,1,3,1,3,3,3,140,8,3,1,4,1,4,1,5,1,5,1,6,1,6,1,6,1,6,1, + 6,1,6,1,6,1,6,1,6,1,6,1,6,3,6,157,8,6,1,6,1,6,1,6,1,6,1,6,1,6,1, + 6,3,6,166,8,6,1,6,1,6,1,6,1,6,3,6,172,8,6,1,6,1,6,1,6,1,6,1,6,1, + 6,1,6,1,6,1,6,1,6,1,6,1,6,1,6,1,6,1,6,1,6,1,6,1,6,1,6,5,6,193,8, + 6,10,6,12,6,196,9,6,1,7,1,7,1,7,1,7,3,7,202,8,7,1,7,1,7,1,7,3,7, + 207,8,7,1,8,1,8,1,8,3,8,212,8,8,1,9,1,9,1,9,1,9,1,9,3,9,219,8,9, + 1,10,1,10,1,10,1,10,1,10,1,10,1,10,3,10,228,8,10,1,11,1,11,3,11, + 232,8,11,1,12,1,12,1,12,1,12,1,12,3,12,239,8,12,1,12,5,12,242,8, + 12,10,12,12,12,245,9,12,1,13,1,13,1,13,1,13,1,13,5,13,252,8,13,10, + 13,12,13,255,9,13,3,13,257,8,13,1,13,1,13,1,14,3,14,262,8,14,1,14, + 1,14,1,14,1,14,1,14,1,14,3,14,270,8,14,1,14,5,14,273,8,14,10,14, + 12,14,276,9,14,1,14,1,14,1,15,1,15,1,15,1,15,3,15,284,8,15,1,15, + 5,15,287,8,15,10,15,12,15,290,9,15,1,15,1,15,1,16,1,16,1,16,1,16, + 1,16,1,16,1,16,1,16,1,16,5,16,303,8,16,10,16,12,16,306,9,16,1,16, + 3,16,309,8,16,1,16,1,16,1,17,3,17,314,8,17,1,17,1,17,3,17,318,8, + 17,1,18,1,18,1,18,3,18,323,8,18,1,19,1,19,1,19,1,19,3,19,329,8,19, + 1,19,1,19,1,20,1,20,1,20,1,20,1,20,1,20,3,20,339,8,20,1,20,1,20, + 1,21,3,21,344,8,21,1,21,3,21,347,8,21,1,21,1,21,1,21,5,21,352,8, + 21,10,21,12,21,355,9,21,1,21,1,21,1,21,3,21,360,8,21,1,21,1,21,1, + 21,1,21,3,21,366,8,21,1,21,5,21,369,8,21,10,21,12,21,372,9,21,1, + 22,1,22,1,22,1,23,4,23,378,8,23,11,23,12,23,379,1,24,1,24,3,24,384, + 8,24,1,25,1,25,5,25,388,8,25,10,25,12,25,391,9,25,1,25,3,25,394, + 8,25,1,26,1,26,1,26,1,26,1,26,1,26,1,26,1,26,1,27,1,27,1,27,1,27, + 1,27,1,27,1,27,1,27,1,28,1,28,1,28,1,28,1,28,1,28,1,28,1,29,1,29, + 1,29,1,29,1,29,1,29,1,29,1,29,3,29,427,8,29,1,29,1,29,1,29,1,29, + 1,29,1,29,1,29,1,30,1,30,1,30,1,30,1,30,1,30,1,30,1,30,1,31,1,31, + 4,31,446,8,31,11,31,12,31,447,1,31,1,31,1,32,1,32,1,32,1,32,1,32, + 1,33,1,33,1,33,1,33,1,33,1,33,1,33,1,33,1,33,1,33,4,33,467,8,33, + 11,33,12,33,468,1,33,1,33,1,34,1,34,1,34,1,34,1,34,5,34,478,8,34, + 10,34,12,34,481,9,34,1,34,1,34,1,34,1,34,1,34,1,34,1,34,1,35,1,35, + 1,35,1,35,1,35,5,35,495,8,35,10,35,12,35,498,9,35,1,35,1,35,1,35, + 1,35,1,35,1,35,1,35,1,36,1,36,1,36,1,36,1,36,4,36,512,8,36,11,36, + 12,36,513,1,36,1,36,1,37,1,37,1,37,1,37,1,37,1,37,1,37,1,38,1,38, + 1,38,1,38,1,38,1,38,1,38,4,38,532,8,38,11,38,12,38,533,1,38,1,38, + 1,39,1,39,1,39,1,39,1,39,1,39,3,39,544,8,39,1,39,1,39,1,39,1,39, + 5,39,550,8,39,10,39,12,39,553,9,39,3,39,555,8,39,1,39,3,39,558,8, + 39,4,39,560,8,39,11,39,12,39,561,1,39,1,39,1,40,1,40,1,40,1,40,1, + 40,3,40,571,8,40,1,40,1,40,5,40,575,8,40,10,40,12,40,578,9,40,1, + 40,1,40,1,40,1,41,1,41,1,41,1,41,1,41,3,41,588,8,41,1,41,1,41,1, + 41,1,41,1,41,1,42,1,42,3,42,597,8,42,1,43,1,43,1,43,1,43,1,43,1, + 43,1,43,1,43,1,43,5,43,608,8,43,10,43,12,43,611,9,43,3,43,613,8, + 43,1,43,3,43,616,8,43,1,43,3,43,619,8,43,1,43,1,43,1,43,1,44,1,44, + 1,44,1,44,1,44,1,44,5,44,630,8,44,10,44,12,44,633,9,44,3,44,635, + 8,44,1,44,1,44,3,44,639,8,44,1,44,1,44,1,44,1,44,1,44,1,44,1,45, + 1,45,1,45,1,46,1,46,1,46,1,46,1,46,0,2,2,12,47,0,2,4,6,8,10,12,14, + 16,18,20,22,24,26,28,30,32,34,36,38,40,42,44,46,48,50,52,54,56,58, + 60,62,64,66,68,70,72,74,76,78,80,82,84,86,88,90,92,0,4,2,0,51,51, + 75,75,1,0,90,91,1,0,32,34,3,0,25,25,87,88,90,91,716,0,100,1,0,0, + 0,2,111,1,0,0,0,4,128,1,0,0,0,6,139,1,0,0,0,8,141,1,0,0,0,10,143, + 1,0,0,0,12,156,1,0,0,0,14,206,1,0,0,0,16,211,1,0,0,0,18,218,1,0, + 0,0,20,227,1,0,0,0,22,231,1,0,0,0,24,233,1,0,0,0,26,246,1,0,0,0, + 28,261,1,0,0,0,30,279,1,0,0,0,32,293,1,0,0,0,34,313,1,0,0,0,36,322, + 1,0,0,0,38,328,1,0,0,0,40,332,1,0,0,0,42,343,1,0,0,0,44,373,1,0, + 0,0,46,377,1,0,0,0,48,381,1,0,0,0,50,385,1,0,0,0,52,395,1,0,0,0, + 54,403,1,0,0,0,56,411,1,0,0,0,58,418,1,0,0,0,60,435,1,0,0,0,62,445, + 1,0,0,0,64,451,1,0,0,0,66,456,1,0,0,0,68,472,1,0,0,0,70,489,1,0, + 0,0,72,506,1,0,0,0,74,517,1,0,0,0,76,524,1,0,0,0,78,537,1,0,0,0, + 80,565,1,0,0,0,82,582,1,0,0,0,84,596,1,0,0,0,86,598,1,0,0,0,88,623, + 1,0,0,0,90,646,1,0,0,0,92,649,1,0,0,0,94,101,5,10,0,0,95,101,5,11, + 0,0,96,101,5,12,0,0,97,101,5,13,0,0,98,101,5,14,0,0,99,101,3,2,1, + 0,100,94,1,0,0,0,100,95,1,0,0,0,100,96,1,0,0,0,100,97,1,0,0,0,100, + 98,1,0,0,0,100,99,1,0,0,0,101,1,1,0,0,0,102,103,6,1,-1,0,103,104, + 5,49,0,0,104,105,3,2,1,0,105,106,5,50,0,0,106,112,1,0,0,0,107,108, + 5,90,0,0,108,109,5,79,0,0,109,112,3,2,1,2,110,112,5,89,0,0,111,102, + 1,0,0,0,111,107,1,0,0,0,111,110,1,0,0,0,112,124,1,0,0,0,113,116, + 10,3,0,0,114,117,5,77,0,0,115,117,5,79,0,0,116,114,1,0,0,0,116,115, + 1,0,0,0,117,118,1,0,0,0,118,123,3,2,1,4,119,120,10,4,0,0,120,121, + 5,78,0,0,121,123,3,4,2,0,122,113,1,0,0,0,122,119,1,0,0,0,123,126, + 1,0,0,0,124,122,1,0,0,0,124,125,1,0,0,0,125,3,1,0,0,0,126,124,1, + 0,0,0,127,129,7,0,0,0,128,127,1,0,0,0,128,129,1,0,0,0,129,130,1, + 0,0,0,130,131,5,90,0,0,131,5,1,0,0,0,132,140,5,45,0,0,133,140,5, + 46,0,0,134,135,5,47,0,0,135,136,3,8,4,0,136,137,5,83,0,0,137,138, + 3,10,5,0,138,140,1,0,0,0,139,132,1,0,0,0,139,133,1,0,0,0,139,134, + 1,0,0,0,140,7,1,0,0,0,141,142,5,89,0,0,142,9,1,0,0,0,143,144,5,89, + 0,0,144,11,1,0,0,0,145,146,6,6,-1,0,146,147,5,49,0,0,147,148,3,12, + 6,0,148,149,5,50,0,0,149,157,1,0,0,0,150,151,3,16,8,0,151,152,3, + 12,6,9,152,157,1,0,0,0,153,154,5,28,0,0,154,157,3,12,6,4,155,157, + 3,14,7,0,156,145,1,0,0,0,156,150,1,0,0,0,156,153,1,0,0,0,156,155, + 1,0,0,0,157,194,1,0,0,0,158,159,10,10,0,0,159,160,5,78,0,0,160,193, + 3,12,6,10,161,165,10,8,0,0,162,166,5,77,0,0,163,166,5,79,0,0,164, + 166,5,80,0,0,165,162,1,0,0,0,165,163,1,0,0,0,165,164,1,0,0,0,166, + 167,1,0,0,0,167,193,3,12,6,9,168,171,10,7,0,0,169,172,5,51,0,0,170, + 172,5,75,0,0,171,169,1,0,0,0,171,170,1,0,0,0,172,173,1,0,0,0,173, + 193,3,12,6,8,174,175,10,6,0,0,175,176,3,18,9,0,176,177,3,12,6,7, + 177,193,1,0,0,0,178,179,10,5,0,0,179,180,3,20,10,0,180,181,3,12, + 6,6,181,193,1,0,0,0,182,183,10,3,0,0,183,184,3,22,11,0,184,185,3, + 12,6,4,185,193,1,0,0,0,186,187,10,2,0,0,187,188,5,81,0,0,188,189, + 3,12,6,0,189,190,5,82,0,0,190,191,3,12,6,3,191,193,1,0,0,0,192,158, + 1,0,0,0,192,161,1,0,0,0,192,168,1,0,0,0,192,174,1,0,0,0,192,178, + 1,0,0,0,192,182,1,0,0,0,192,186,1,0,0,0,193,196,1,0,0,0,194,192, + 1,0,0,0,194,195,1,0,0,0,195,13,1,0,0,0,196,194,1,0,0,0,197,207,3, + 26,13,0,198,207,5,87,0,0,199,201,7,1,0,0,200,202,3,24,12,0,201,200, + 1,0,0,0,201,202,1,0,0,0,202,207,1,0,0,0,203,207,5,88,0,0,204,207, + 5,25,0,0,205,207,3,24,12,0,206,197,1,0,0,0,206,198,1,0,0,0,206,199, + 1,0,0,0,206,203,1,0,0,0,206,204,1,0,0,0,206,205,1,0,0,0,207,15,1, + 0,0,0,208,212,5,51,0,0,209,212,5,75,0,0,210,212,5,52,0,0,211,208, + 1,0,0,0,211,209,1,0,0,0,211,210,1,0,0,0,212,17,1,0,0,0,213,219,5, + 55,0,0,214,219,5,54,0,0,215,219,5,53,0,0,216,219,5,61,0,0,217,219, + 5,62,0,0,218,213,1,0,0,0,218,214,1,0,0,0,218,215,1,0,0,0,218,216, + 1,0,0,0,218,217,1,0,0,0,219,19,1,0,0,0,220,228,5,63,0,0,221,228, + 5,65,0,0,222,228,5,70,0,0,223,228,5,71,0,0,224,228,5,72,0,0,225, + 228,5,73,0,0,226,228,5,64,0,0,227,220,1,0,0,0,227,221,1,0,0,0,227, + 222,1,0,0,0,227,223,1,0,0,0,227,224,1,0,0,0,227,225,1,0,0,0,227, + 226,1,0,0,0,228,21,1,0,0,0,229,232,5,26,0,0,230,232,5,27,0,0,231, + 229,1,0,0,0,231,230,1,0,0,0,232,23,1,0,0,0,233,238,5,89,0,0,234, + 235,5,56,0,0,235,236,3,12,6,0,236,237,5,58,0,0,237,239,1,0,0,0,238, + 234,1,0,0,0,238,239,1,0,0,0,239,243,1,0,0,0,240,242,5,85,0,0,241, + 240,1,0,0,0,242,245,1,0,0,0,243,241,1,0,0,0,243,244,1,0,0,0,244, + 25,1,0,0,0,245,243,1,0,0,0,246,247,5,89,0,0,247,256,5,49,0,0,248, + 253,3,12,6,0,249,250,5,74,0,0,250,252,3,12,6,0,251,249,1,0,0,0,252, + 255,1,0,0,0,253,251,1,0,0,0,253,254,1,0,0,0,254,257,1,0,0,0,255, + 253,1,0,0,0,256,248,1,0,0,0,256,257,1,0,0,0,257,258,1,0,0,0,258, + 259,5,50,0,0,259,27,1,0,0,0,260,262,5,29,0,0,261,260,1,0,0,0,261, + 262,1,0,0,0,262,263,1,0,0,0,263,264,5,16,0,0,264,265,5,89,0,0,265, + 266,3,0,0,0,266,267,5,76,0,0,267,269,3,12,6,0,268,270,5,84,0,0,269, + 268,1,0,0,0,269,270,1,0,0,0,270,274,1,0,0,0,271,273,3,6,3,0,272, + 271,1,0,0,0,273,276,1,0,0,0,274,272,1,0,0,0,274,275,1,0,0,0,275, + 277,1,0,0,0,276,274,1,0,0,0,277,278,5,9,0,0,278,29,1,0,0,0,279,280, + 3,24,12,0,280,281,5,76,0,0,281,283,3,12,6,0,282,284,5,84,0,0,283, + 282,1,0,0,0,283,284,1,0,0,0,284,288,1,0,0,0,285,287,3,6,3,0,286, + 285,1,0,0,0,287,290,1,0,0,0,288,286,1,0,0,0,288,289,1,0,0,0,289, + 291,1,0,0,0,290,288,1,0,0,0,291,292,5,9,0,0,292,31,1,0,0,0,293,294, + 5,30,0,0,294,295,3,24,12,0,295,296,5,76,0,0,296,304,3,12,6,0,297, + 298,5,4,0,0,298,299,3,24,12,0,299,300,5,76,0,0,300,301,3,12,6,0, + 301,303,1,0,0,0,302,297,1,0,0,0,303,306,1,0,0,0,304,302,1,0,0,0, + 304,305,1,0,0,0,305,308,1,0,0,0,306,304,1,0,0,0,307,309,5,84,0,0, + 308,307,1,0,0,0,308,309,1,0,0,0,309,310,1,0,0,0,310,311,5,9,0,0, + 311,33,1,0,0,0,312,314,5,9,0,0,313,312,1,0,0,0,313,314,1,0,0,0,314, + 317,1,0,0,0,315,318,3,38,19,0,316,318,3,36,18,0,317,315,1,0,0,0, + 317,316,1,0,0,0,318,35,1,0,0,0,319,323,3,50,25,0,320,323,3,58,29, + 0,321,323,3,60,30,0,322,319,1,0,0,0,322,320,1,0,0,0,322,321,1,0, + 0,0,323,37,1,0,0,0,324,329,3,40,20,0,325,329,3,26,13,0,326,329,3, + 42,21,0,327,329,3,48,24,0,328,324,1,0,0,0,328,325,1,0,0,0,328,326, + 1,0,0,0,328,327,1,0,0,0,329,330,1,0,0,0,330,331,5,9,0,0,331,39,1, + 0,0,0,332,338,3,24,12,0,333,339,5,76,0,0,334,339,5,66,0,0,335,339, + 5,67,0,0,336,339,5,68,0,0,337,339,5,69,0,0,338,333,1,0,0,0,338,334, + 1,0,0,0,338,335,1,0,0,0,338,336,1,0,0,0,338,337,1,0,0,0,339,340, + 1,0,0,0,340,341,3,12,6,0,341,41,1,0,0,0,342,344,5,29,0,0,343,342, + 1,0,0,0,343,344,1,0,0,0,344,346,1,0,0,0,345,347,5,16,0,0,346,345, + 1,0,0,0,346,347,1,0,0,0,347,348,1,0,0,0,348,353,3,24,12,0,349,350, + 5,74,0,0,350,352,3,24,12,0,351,349,1,0,0,0,352,355,1,0,0,0,353,351, + 1,0,0,0,353,354,1,0,0,0,354,356,1,0,0,0,355,353,1,0,0,0,356,359, + 3,0,0,0,357,358,5,76,0,0,358,360,3,12,6,0,359,357,1,0,0,0,359,360, + 1,0,0,0,360,365,1,0,0,0,361,362,5,59,0,0,362,363,3,12,6,0,363,364, + 5,60,0,0,364,366,1,0,0,0,365,361,1,0,0,0,365,366,1,0,0,0,366,370, + 1,0,0,0,367,369,3,6,3,0,368,367,1,0,0,0,369,372,1,0,0,0,370,368, + 1,0,0,0,370,371,1,0,0,0,371,43,1,0,0,0,372,370,1,0,0,0,373,374,3, + 42,21,0,374,375,5,9,0,0,375,45,1,0,0,0,376,378,3,34,17,0,377,376, + 1,0,0,0,378,379,1,0,0,0,379,377,1,0,0,0,379,380,1,0,0,0,380,47,1, + 0,0,0,381,383,5,17,0,0,382,384,3,12,6,0,383,382,1,0,0,0,383,384, + 1,0,0,0,384,49,1,0,0,0,385,389,3,52,26,0,386,388,3,54,27,0,387,386, + 1,0,0,0,388,391,1,0,0,0,389,387,1,0,0,0,389,390,1,0,0,0,390,393, + 1,0,0,0,391,389,1,0,0,0,392,394,3,56,28,0,393,392,1,0,0,0,393,394, + 1,0,0,0,394,51,1,0,0,0,395,396,5,18,0,0,396,397,3,12,6,0,397,398, + 5,82,0,0,398,399,5,9,0,0,399,400,5,1,0,0,400,401,3,46,23,0,401,402, + 5,2,0,0,402,53,1,0,0,0,403,404,5,19,0,0,404,405,3,12,6,0,405,406, + 5,82,0,0,406,407,5,9,0,0,407,408,5,1,0,0,408,409,3,46,23,0,409,410, + 5,2,0,0,410,55,1,0,0,0,411,412,5,20,0,0,412,413,5,82,0,0,413,414, + 5,9,0,0,414,415,5,1,0,0,415,416,3,46,23,0,416,417,5,2,0,0,417,57, + 1,0,0,0,418,419,5,21,0,0,419,420,5,89,0,0,420,421,5,23,0,0,421,422, + 3,12,6,0,422,423,5,48,0,0,423,424,3,12,6,0,424,426,5,24,0,0,425, + 427,5,75,0,0,426,425,1,0,0,0,426,427,1,0,0,0,427,428,1,0,0,0,428, + 429,7,1,0,0,429,430,5,82,0,0,430,431,5,9,0,0,431,432,5,1,0,0,432, + 433,3,46,23,0,433,434,5,2,0,0,434,59,1,0,0,0,435,436,5,22,0,0,436, + 437,3,12,6,0,437,438,5,82,0,0,438,439,5,9,0,0,439,440,5,1,0,0,440, + 441,3,46,23,0,441,442,5,2,0,0,442,61,1,0,0,0,443,446,3,64,32,0,444, + 446,5,9,0,0,445,443,1,0,0,0,445,444,1,0,0,0,446,447,1,0,0,0,447, + 445,1,0,0,0,447,448,1,0,0,0,448,449,1,0,0,0,449,450,5,0,0,1,450, + 63,1,0,0,0,451,452,5,31,0,0,452,453,5,89,0,0,453,454,5,82,0,0,454, + 455,3,66,33,0,455,65,1,0,0,0,456,457,5,9,0,0,457,466,5,1,0,0,458, + 467,3,72,36,0,459,467,3,76,38,0,460,467,3,78,39,0,461,467,3,86,43, + 0,462,467,3,88,44,0,463,467,3,68,34,0,464,467,3,70,35,0,465,467, + 3,74,37,0,466,458,1,0,0,0,466,459,1,0,0,0,466,460,1,0,0,0,466,461, + 1,0,0,0,466,462,1,0,0,0,466,463,1,0,0,0,466,464,1,0,0,0,466,465, + 1,0,0,0,467,468,1,0,0,0,468,466,1,0,0,0,468,469,1,0,0,0,469,470, + 1,0,0,0,470,471,5,2,0,0,471,67,1,0,0,0,472,473,5,40,0,0,473,474, + 5,49,0,0,474,479,5,89,0,0,475,476,5,74,0,0,476,478,3,92,46,0,477, + 475,1,0,0,0,478,481,1,0,0,0,479,477,1,0,0,0,479,480,1,0,0,0,480, + 482,1,0,0,0,481,479,1,0,0,0,482,483,5,50,0,0,483,484,5,82,0,0,484, + 485,5,9,0,0,485,486,5,1,0,0,486,487,3,46,23,0,487,488,5,2,0,0,488, + 69,1,0,0,0,489,490,5,41,0,0,490,491,5,49,0,0,491,496,3,12,6,0,492, + 493,5,74,0,0,493,495,3,92,46,0,494,492,1,0,0,0,495,498,1,0,0,0,496, + 494,1,0,0,0,496,497,1,0,0,0,497,499,1,0,0,0,498,496,1,0,0,0,499, + 500,5,50,0,0,500,501,5,82,0,0,501,502,5,9,0,0,502,503,5,1,0,0,503, + 504,3,46,23,0,504,505,5,2,0,0,505,71,1,0,0,0,506,507,7,2,0,0,507, + 508,5,82,0,0,508,509,5,9,0,0,509,511,5,1,0,0,510,512,3,44,22,0,511, + 510,1,0,0,0,512,513,1,0,0,0,513,511,1,0,0,0,513,514,1,0,0,0,514, + 515,1,0,0,0,515,516,5,2,0,0,516,73,1,0,0,0,517,518,5,35,0,0,518, + 519,5,82,0,0,519,520,5,9,0,0,520,521,5,1,0,0,521,522,3,46,23,0,522, + 523,5,2,0,0,523,75,1,0,0,0,524,525,5,36,0,0,525,526,5,82,0,0,526, + 527,5,9,0,0,527,531,5,1,0,0,528,532,3,28,14,0,529,532,3,30,15,0, + 530,532,3,32,16,0,531,528,1,0,0,0,531,529,1,0,0,0,531,530,1,0,0, + 0,532,533,1,0,0,0,533,531,1,0,0,0,533,534,1,0,0,0,534,535,1,0,0, + 0,535,536,5,2,0,0,536,77,1,0,0,0,537,538,5,37,0,0,538,539,5,82,0, + 0,539,540,5,9,0,0,540,559,5,1,0,0,541,544,3,80,40,0,542,544,3,82, + 41,0,543,541,1,0,0,0,543,542,1,0,0,0,544,557,1,0,0,0,545,554,5,49, + 0,0,546,551,3,90,45,0,547,548,5,74,0,0,548,550,3,90,45,0,549,547, + 1,0,0,0,550,553,1,0,0,0,551,549,1,0,0,0,551,552,1,0,0,0,552,555, + 1,0,0,0,553,551,1,0,0,0,554,546,1,0,0,0,554,555,1,0,0,0,555,556, + 1,0,0,0,556,558,5,50,0,0,557,545,1,0,0,0,557,558,1,0,0,0,558,560, + 1,0,0,0,559,543,1,0,0,0,560,561,1,0,0,0,561,559,1,0,0,0,561,562, + 1,0,0,0,562,563,1,0,0,0,563,564,5,2,0,0,564,79,1,0,0,0,565,570,5, + 89,0,0,566,567,5,56,0,0,567,568,3,12,6,0,568,569,5,58,0,0,569,571, + 1,0,0,0,570,566,1,0,0,0,570,571,1,0,0,0,571,572,1,0,0,0,572,576, + 5,57,0,0,573,575,3,84,42,0,574,573,1,0,0,0,575,578,1,0,0,0,576,574, + 1,0,0,0,576,577,1,0,0,0,577,579,1,0,0,0,578,576,1,0,0,0,579,580, + 5,42,0,0,580,581,5,9,0,0,581,81,1,0,0,0,582,587,5,89,0,0,583,584, + 5,56,0,0,584,585,3,12,6,0,585,586,5,58,0,0,586,588,1,0,0,0,587,583, + 1,0,0,0,587,588,1,0,0,0,588,589,1,0,0,0,589,590,3,0,0,0,590,591, + 5,57,0,0,591,592,5,39,0,0,592,593,5,9,0,0,593,83,1,0,0,0,594,597, + 5,43,0,0,595,597,5,44,0,0,596,594,1,0,0,0,596,595,1,0,0,0,597,85, + 1,0,0,0,598,599,5,38,0,0,599,600,5,82,0,0,600,601,5,9,0,0,601,618, + 5,1,0,0,602,615,5,42,0,0,603,612,5,49,0,0,604,609,3,90,45,0,605, + 606,5,74,0,0,606,608,3,90,45,0,607,605,1,0,0,0,608,611,1,0,0,0,609, + 607,1,0,0,0,609,610,1,0,0,0,610,613,1,0,0,0,611,609,1,0,0,0,612, + 604,1,0,0,0,612,613,1,0,0,0,613,614,1,0,0,0,614,616,5,50,0,0,615, + 603,1,0,0,0,615,616,1,0,0,0,616,619,1,0,0,0,617,619,5,39,0,0,618, + 602,1,0,0,0,618,617,1,0,0,0,619,620,1,0,0,0,620,621,5,9,0,0,621, + 622,5,2,0,0,622,87,1,0,0,0,623,624,5,15,0,0,624,625,5,89,0,0,625, + 634,5,49,0,0,626,631,3,90,45,0,627,628,5,74,0,0,628,630,3,90,45, + 0,629,627,1,0,0,0,630,633,1,0,0,0,631,629,1,0,0,0,631,632,1,0,0, + 0,632,635,1,0,0,0,633,631,1,0,0,0,634,626,1,0,0,0,634,635,1,0,0, + 0,635,636,1,0,0,0,636,638,5,50,0,0,637,639,3,0,0,0,638,637,1,0,0, + 0,638,639,1,0,0,0,639,640,1,0,0,0,640,641,5,82,0,0,641,642,5,9,0, + 0,642,643,5,1,0,0,643,644,3,46,23,0,644,645,5,2,0,0,645,89,1,0,0, + 0,646,647,5,89,0,0,647,648,3,0,0,0,648,91,1,0,0,0,649,650,5,89,0, + 0,650,651,5,76,0,0,651,652,7,3,0,0,652,93,1,0,0,0,70,100,111,116, + 122,124,128,139,156,165,171,192,194,201,206,211,218,227,231,238, + 243,253,256,261,269,274,283,288,304,308,313,317,322,328,338,343, + 346,353,359,365,370,379,383,389,393,426,445,447,466,468,479,496, + 513,531,533,543,551,554,557,561,570,576,587,596,609,612,615,618, + 631,634,638 ] class PyNestMLParser ( Parser ): @@ -301,27 +311,27 @@ class PyNestMLParser ( Parser ): RULE_dataType = 0 RULE_unitType = 1 RULE_unitTypeExponent = 2 - RULE_expression = 3 - RULE_simpleExpression = 4 - RULE_unaryOperator = 5 - RULE_bitOperator = 6 - RULE_comparisonOperator = 7 - RULE_logicalOperator = 8 - RULE_variable = 9 - RULE_functionCall = 10 - RULE_inlineExpression = 11 - RULE_odeEquation = 12 - RULE_kernel = 13 - RULE_block = 14 - RULE_stmt = 15 - RULE_compoundStmt = 16 - RULE_smallStmt = 17 - RULE_assignment = 18 - RULE_declaration = 19 - RULE_declaration_newline = 20 - RULE_anyDecorator = 21 - RULE_namespaceDecoratorNamespace = 22 - RULE_namespaceDecoratorName = 23 + RULE_anyDecorator = 3 + RULE_namespaceDecoratorNamespace = 4 + RULE_namespaceDecoratorName = 5 + RULE_expression = 6 + RULE_simpleExpression = 7 + RULE_unaryOperator = 8 + RULE_bitOperator = 9 + RULE_comparisonOperator = 10 + RULE_logicalOperator = 11 + RULE_variable = 12 + RULE_functionCall = 13 + RULE_inlineExpression = 14 + RULE_odeEquation = 15 + RULE_kernel = 16 + RULE_stmt = 17 + RULE_compoundStmt = 18 + RULE_smallStmt = 19 + RULE_assignment = 20 + RULE_declaration = 21 + RULE_declaration_newline = 22 + RULE_stmtsBody = 23 RULE_returnStmt = 24 RULE_ifStmt = 25 RULE_ifClause = 26 @@ -346,18 +356,19 @@ class PyNestMLParser ( Parser ): RULE_parameter = 45 RULE_constParameter = 46 - ruleNames = [ "dataType", "unitType", "unitTypeExponent", "expression", - "simpleExpression", "unaryOperator", "bitOperator", "comparisonOperator", - "logicalOperator", "variable", "functionCall", "inlineExpression", - "odeEquation", "kernel", "block", "stmt", "compoundStmt", - "smallStmt", "assignment", "declaration", "declaration_newline", - "anyDecorator", "namespaceDecoratorNamespace", "namespaceDecoratorName", - "returnStmt", "ifStmt", "ifClause", "elifClause", "elseClause", - "forStmt", "whileStmt", "nestMLCompilationUnit", "model", - "modelBody", "onReceiveBlock", "onConditionBlock", "blockWithVariables", - "updateBlock", "equationsBlock", "inputBlock", "spikeInputPort", - "continuousInputPort", "inputQualifier", "outputBlock", - "function", "parameter", "constParameter" ] + ruleNames = [ "dataType", "unitType", "unitTypeExponent", "anyDecorator", + "namespaceDecoratorNamespace", "namespaceDecoratorName", + "expression", "simpleExpression", "unaryOperator", "bitOperator", + "comparisonOperator", "logicalOperator", "variable", + "functionCall", "inlineExpression", "odeEquation", "kernel", + "stmt", "compoundStmt", "smallStmt", "assignment", "declaration", + "declaration_newline", "stmtsBody", "returnStmt", "ifStmt", + "ifClause", "elifClause", "elseClause", "forStmt", "whileStmt", + "nestMLCompilationUnit", "model", "modelBody", "onReceiveBlock", + "onConditionBlock", "blockWithVariables", "updateBlock", + "equationsBlock", "inputBlock", "spikeInputPort", "continuousInputPort", + "inputQualifier", "outputBlock", "function", "parameter", + "constParameter" ] EOF = Token.EOF INDENT=1 @@ -777,6 +788,166 @@ def unitTypeExponent(self): return localctx + class AnyDecoratorContext(ParserRuleContext): + __slots__ = 'parser' + + def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): + super().__init__(parent, invokingState) + self.parser = parser + + def DECORATOR_HOMOGENEOUS(self): + return self.getToken(PyNestMLParser.DECORATOR_HOMOGENEOUS, 0) + + def DECORATOR_HETEROGENEOUS(self): + return self.getToken(PyNestMLParser.DECORATOR_HETEROGENEOUS, 0) + + def AT(self): + return self.getToken(PyNestMLParser.AT, 0) + + def namespaceDecoratorNamespace(self): + return self.getTypedRuleContext(PyNestMLParser.NamespaceDecoratorNamespaceContext,0) + + + def DOUBLE_COLON(self): + return self.getToken(PyNestMLParser.DOUBLE_COLON, 0) + + def namespaceDecoratorName(self): + return self.getTypedRuleContext(PyNestMLParser.NamespaceDecoratorNameContext,0) + + + def getRuleIndex(self): + return PyNestMLParser.RULE_anyDecorator + + def accept(self, visitor:ParseTreeVisitor): + if hasattr( visitor, "visitAnyDecorator" ): + return visitor.visitAnyDecorator(self) + else: + return visitor.visitChildren(self) + + + + + def anyDecorator(self): + + localctx = PyNestMLParser.AnyDecoratorContext(self, self._ctx, self.state) + self.enterRule(localctx, 6, self.RULE_anyDecorator) + try: + self.state = 139 + self._errHandler.sync(self) + token = self._input.LA(1) + if token in [45]: + self.enterOuterAlt(localctx, 1) + self.state = 132 + self.match(PyNestMLParser.DECORATOR_HOMOGENEOUS) + pass + elif token in [46]: + self.enterOuterAlt(localctx, 2) + self.state = 133 + self.match(PyNestMLParser.DECORATOR_HETEROGENEOUS) + pass + elif token in [47]: + self.enterOuterAlt(localctx, 3) + self.state = 134 + self.match(PyNestMLParser.AT) + self.state = 135 + self.namespaceDecoratorNamespace() + self.state = 136 + self.match(PyNestMLParser.DOUBLE_COLON) + self.state = 137 + self.namespaceDecoratorName() + pass + else: + raise NoViableAltException(self) + + except RecognitionException as re: + localctx.exception = re + self._errHandler.reportError(self, re) + self._errHandler.recover(self, re) + finally: + self.exitRule() + return localctx + + + class NamespaceDecoratorNamespaceContext(ParserRuleContext): + __slots__ = 'parser' + + def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): + super().__init__(parent, invokingState) + self.parser = parser + self.name = None # Token + + def NAME(self): + return self.getToken(PyNestMLParser.NAME, 0) + + def getRuleIndex(self): + return PyNestMLParser.RULE_namespaceDecoratorNamespace + + def accept(self, visitor:ParseTreeVisitor): + if hasattr( visitor, "visitNamespaceDecoratorNamespace" ): + return visitor.visitNamespaceDecoratorNamespace(self) + else: + return visitor.visitChildren(self) + + + + + def namespaceDecoratorNamespace(self): + + localctx = PyNestMLParser.NamespaceDecoratorNamespaceContext(self, self._ctx, self.state) + self.enterRule(localctx, 8, self.RULE_namespaceDecoratorNamespace) + try: + self.enterOuterAlt(localctx, 1) + self.state = 141 + localctx.name = self.match(PyNestMLParser.NAME) + except RecognitionException as re: + localctx.exception = re + self._errHandler.reportError(self, re) + self._errHandler.recover(self, re) + finally: + self.exitRule() + return localctx + + + class NamespaceDecoratorNameContext(ParserRuleContext): + __slots__ = 'parser' + + def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): + super().__init__(parent, invokingState) + self.parser = parser + self.name = None # Token + + def NAME(self): + return self.getToken(PyNestMLParser.NAME, 0) + + def getRuleIndex(self): + return PyNestMLParser.RULE_namespaceDecoratorName + + def accept(self, visitor:ParseTreeVisitor): + if hasattr( visitor, "visitNamespaceDecoratorName" ): + return visitor.visitNamespaceDecoratorName(self) + else: + return visitor.visitChildren(self) + + + + + def namespaceDecoratorName(self): + + localctx = PyNestMLParser.NamespaceDecoratorNameContext(self, self._ctx, self.state) + self.enterRule(localctx, 10, self.RULE_namespaceDecoratorName) + try: + self.enterOuterAlt(localctx, 1) + self.state = 143 + localctx.name = self.match(PyNestMLParser.NAME) + except RecognitionException as re: + localctx.exception = re + self._errHandler.reportError(self, re) + self._errHandler.recover(self, re) + finally: + self.exitRule() + return localctx + + class ExpressionContext(ParserRuleContext): __slots__ = 'parser' @@ -875,63 +1046,63 @@ def expression(self, _p:int=0): _parentState = self.state localctx = PyNestMLParser.ExpressionContext(self, self._ctx, _parentState) _prevctx = localctx - _startState = 6 - self.enterRecursionRule(localctx, 6, self.RULE_expression, _p) + _startState = 12 + self.enterRecursionRule(localctx, 12, self.RULE_expression, _p) try: self.enterOuterAlt(localctx, 1) - self.state = 143 + self.state = 156 self._errHandler.sync(self) token = self._input.LA(1) if token in [49]: - self.state = 133 + self.state = 146 localctx.leftParentheses = self.match(PyNestMLParser.LEFT_PAREN) - self.state = 134 + self.state = 147 localctx.term = self.expression(0) - self.state = 135 + self.state = 148 localctx.rightParentheses = self.match(PyNestMLParser.RIGHT_PAREN) pass elif token in [51, 52, 75]: - self.state = 137 + self.state = 150 self.unaryOperator() - self.state = 138 + self.state = 151 localctx.term = self.expression(9) pass elif token in [28]: - self.state = 140 + self.state = 153 localctx.logicalNot = self.match(PyNestMLParser.NOT_KEYWORD) - self.state = 141 + self.state = 154 localctx.term = self.expression(4) pass elif token in [25, 87, 88, 89, 90, 91]: - self.state = 142 + self.state = 155 self.simpleExpression() pass else: raise NoViableAltException(self) self._ctx.stop = self._input.LT(-1) - self.state = 181 + self.state = 194 self._errHandler.sync(self) - _alt = self._interp.adaptivePredict(self._input,10,self._ctx) + _alt = self._interp.adaptivePredict(self._input,11,self._ctx) while _alt!=2 and _alt!=ATN.INVALID_ALT_NUMBER: if _alt==1: if self._parseListeners is not None: self.triggerExitRuleEvent() _prevctx = localctx - self.state = 179 + self.state = 192 self._errHandler.sync(self) - la_ = self._interp.adaptivePredict(self._input,9,self._ctx) + la_ = self._interp.adaptivePredict(self._input,10,self._ctx) if la_ == 1: localctx = PyNestMLParser.ExpressionContext(self, _parentctx, _parentState) localctx.left = _prevctx self.pushNewRecursionContext(localctx, _startState, self.RULE_expression) - self.state = 145 + self.state = 158 if not self.precpred(self._ctx, 10): from antlr4.error.Errors import FailedPredicateException raise FailedPredicateException(self, "self.precpred(self._ctx, 10)") - self.state = 146 + self.state = 159 localctx.powOp = self.match(PyNestMLParser.STAR_STAR) - self.state = 147 + self.state = 160 localctx.right = self.expression(10) pass @@ -939,29 +1110,29 @@ def expression(self, _p:int=0): localctx = PyNestMLParser.ExpressionContext(self, _parentctx, _parentState) localctx.left = _prevctx self.pushNewRecursionContext(localctx, _startState, self.RULE_expression) - self.state = 148 + self.state = 161 if not self.precpred(self._ctx, 8): from antlr4.error.Errors import FailedPredicateException raise FailedPredicateException(self, "self.precpred(self._ctx, 8)") - self.state = 152 + self.state = 165 self._errHandler.sync(self) token = self._input.LA(1) if token in [77]: - self.state = 149 + self.state = 162 localctx.timesOp = self.match(PyNestMLParser.STAR) pass elif token in [79]: - self.state = 150 + self.state = 163 localctx.divOp = self.match(PyNestMLParser.FORWARD_SLASH) pass elif token in [80]: - self.state = 151 + self.state = 164 localctx.moduloOp = self.match(PyNestMLParser.PERCENT) pass else: raise NoViableAltException(self) - self.state = 154 + self.state = 167 localctx.right = self.expression(9) pass @@ -969,25 +1140,25 @@ def expression(self, _p:int=0): localctx = PyNestMLParser.ExpressionContext(self, _parentctx, _parentState) localctx.left = _prevctx self.pushNewRecursionContext(localctx, _startState, self.RULE_expression) - self.state = 155 + self.state = 168 if not self.precpred(self._ctx, 7): from antlr4.error.Errors import FailedPredicateException raise FailedPredicateException(self, "self.precpred(self._ctx, 7)") - self.state = 158 + self.state = 171 self._errHandler.sync(self) token = self._input.LA(1) if token in [51]: - self.state = 156 + self.state = 169 localctx.plusOp = self.match(PyNestMLParser.PLUS) pass elif token in [75]: - self.state = 157 + self.state = 170 localctx.minusOp = self.match(PyNestMLParser.MINUS) pass else: raise NoViableAltException(self) - self.state = 160 + self.state = 173 localctx.right = self.expression(8) pass @@ -995,13 +1166,13 @@ def expression(self, _p:int=0): localctx = PyNestMLParser.ExpressionContext(self, _parentctx, _parentState) localctx.left = _prevctx self.pushNewRecursionContext(localctx, _startState, self.RULE_expression) - self.state = 161 + self.state = 174 if not self.precpred(self._ctx, 6): from antlr4.error.Errors import FailedPredicateException raise FailedPredicateException(self, "self.precpred(self._ctx, 6)") - self.state = 162 + self.state = 175 self.bitOperator() - self.state = 163 + self.state = 176 localctx.right = self.expression(7) pass @@ -1009,13 +1180,13 @@ def expression(self, _p:int=0): localctx = PyNestMLParser.ExpressionContext(self, _parentctx, _parentState) localctx.left = _prevctx self.pushNewRecursionContext(localctx, _startState, self.RULE_expression) - self.state = 165 + self.state = 178 if not self.precpred(self._ctx, 5): from antlr4.error.Errors import FailedPredicateException raise FailedPredicateException(self, "self.precpred(self._ctx, 5)") - self.state = 166 + self.state = 179 self.comparisonOperator() - self.state = 167 + self.state = 180 localctx.right = self.expression(6) pass @@ -1023,13 +1194,13 @@ def expression(self, _p:int=0): localctx = PyNestMLParser.ExpressionContext(self, _parentctx, _parentState) localctx.left = _prevctx self.pushNewRecursionContext(localctx, _startState, self.RULE_expression) - self.state = 169 + self.state = 182 if not self.precpred(self._ctx, 3): from antlr4.error.Errors import FailedPredicateException raise FailedPredicateException(self, "self.precpred(self._ctx, 3)") - self.state = 170 + self.state = 183 self.logicalOperator() - self.state = 171 + self.state = 184 localctx.right = self.expression(4) pass @@ -1037,24 +1208,24 @@ def expression(self, _p:int=0): localctx = PyNestMLParser.ExpressionContext(self, _parentctx, _parentState) localctx.condition = _prevctx self.pushNewRecursionContext(localctx, _startState, self.RULE_expression) - self.state = 173 + self.state = 186 if not self.precpred(self._ctx, 2): from antlr4.error.Errors import FailedPredicateException raise FailedPredicateException(self, "self.precpred(self._ctx, 2)") - self.state = 174 + self.state = 187 self.match(PyNestMLParser.QUESTION) - self.state = 175 + self.state = 188 localctx.ifTrue = self.expression(0) - self.state = 176 + self.state = 189 self.match(PyNestMLParser.COLON) - self.state = 177 + self.state = 190 localctx.ifNot = self.expression(3) pass - self.state = 183 + self.state = 196 self._errHandler.sync(self) - _alt = self._interp.adaptivePredict(self._input,10,self._ctx) + _alt = self._interp.adaptivePredict(self._input,11,self._ctx) except RecognitionException as re: localctx.exception = re @@ -1112,38 +1283,38 @@ def accept(self, visitor:ParseTreeVisitor): def simpleExpression(self): localctx = PyNestMLParser.SimpleExpressionContext(self, self._ctx, self.state) - self.enterRule(localctx, 8, self.RULE_simpleExpression) + self.enterRule(localctx, 14, self.RULE_simpleExpression) self._la = 0 # Token type try: - self.state = 193 + self.state = 206 self._errHandler.sync(self) - la_ = self._interp.adaptivePredict(self._input,12,self._ctx) + la_ = self._interp.adaptivePredict(self._input,13,self._ctx) if la_ == 1: self.enterOuterAlt(localctx, 1) - self.state = 184 + self.state = 197 self.functionCall() pass elif la_ == 2: self.enterOuterAlt(localctx, 2) - self.state = 185 + self.state = 198 self.match(PyNestMLParser.BOOLEAN_LITERAL) pass elif la_ == 3: self.enterOuterAlt(localctx, 3) - self.state = 186 + self.state = 199 _la = self._input.LA(1) if not(_la==90 or _la==91): self._errHandler.recoverInline(self) else: self._errHandler.reportMatch(self) self.consume() - self.state = 188 + self.state = 201 self._errHandler.sync(self) - la_ = self._interp.adaptivePredict(self._input,11,self._ctx) + la_ = self._interp.adaptivePredict(self._input,12,self._ctx) if la_ == 1: - self.state = 187 + self.state = 200 self.variable() @@ -1151,19 +1322,19 @@ def simpleExpression(self): elif la_ == 4: self.enterOuterAlt(localctx, 4) - self.state = 190 + self.state = 203 localctx.string = self.match(PyNestMLParser.STRING_LITERAL) pass elif la_ == 5: self.enterOuterAlt(localctx, 5) - self.state = 191 + self.state = 204 localctx.isInf = self.match(PyNestMLParser.INF_KEYWORD) pass elif la_ == 6: self.enterOuterAlt(localctx, 6) - self.state = 192 + self.state = 205 self.variable() pass @@ -1211,22 +1382,24 @@ def accept(self, visitor:ParseTreeVisitor): def unaryOperator(self): localctx = PyNestMLParser.UnaryOperatorContext(self, self._ctx, self.state) - self.enterRule(localctx, 10, self.RULE_unaryOperator) + self.enterRule(localctx, 16, self.RULE_unaryOperator) try: - self.enterOuterAlt(localctx, 1) - self.state = 198 + self.state = 211 self._errHandler.sync(self) token = self._input.LA(1) if token in [51]: - self.state = 195 + self.enterOuterAlt(localctx, 1) + self.state = 208 localctx.unaryPlus = self.match(PyNestMLParser.PLUS) pass elif token in [75]: - self.state = 196 + self.enterOuterAlt(localctx, 2) + self.state = 209 localctx.unaryMinus = self.match(PyNestMLParser.MINUS) pass elif token in [52]: - self.state = 197 + self.enterOuterAlt(localctx, 3) + self.state = 210 localctx.unaryTilde = self.match(PyNestMLParser.TILDE) pass else: @@ -1283,30 +1456,34 @@ def accept(self, visitor:ParseTreeVisitor): def bitOperator(self): localctx = PyNestMLParser.BitOperatorContext(self, self._ctx, self.state) - self.enterRule(localctx, 12, self.RULE_bitOperator) + self.enterRule(localctx, 18, self.RULE_bitOperator) try: - self.enterOuterAlt(localctx, 1) - self.state = 205 + self.state = 218 self._errHandler.sync(self) token = self._input.LA(1) if token in [55]: - self.state = 200 + self.enterOuterAlt(localctx, 1) + self.state = 213 localctx.bitAnd = self.match(PyNestMLParser.AMPERSAND) pass elif token in [54]: - self.state = 201 + self.enterOuterAlt(localctx, 2) + self.state = 214 localctx.bitXor = self.match(PyNestMLParser.CARET) pass elif token in [53]: - self.state = 202 + self.enterOuterAlt(localctx, 3) + self.state = 215 localctx.bitOr = self.match(PyNestMLParser.PIPE) pass elif token in [61]: - self.state = 203 + self.enterOuterAlt(localctx, 4) + self.state = 216 localctx.bitShiftLeft = self.match(PyNestMLParser.LEFT_LEFT_ANGLE) pass elif token in [62]: - self.state = 204 + self.enterOuterAlt(localctx, 5) + self.state = 217 localctx.bitShiftRight = self.match(PyNestMLParser.RIGHT_RIGHT_ANGLE) pass else: @@ -1371,38 +1548,44 @@ def accept(self, visitor:ParseTreeVisitor): def comparisonOperator(self): localctx = PyNestMLParser.ComparisonOperatorContext(self, self._ctx, self.state) - self.enterRule(localctx, 14, self.RULE_comparisonOperator) + self.enterRule(localctx, 20, self.RULE_comparisonOperator) try: - self.enterOuterAlt(localctx, 1) - self.state = 214 + self.state = 227 self._errHandler.sync(self) token = self._input.LA(1) if token in [63]: - self.state = 207 + self.enterOuterAlt(localctx, 1) + self.state = 220 localctx.lt = self.match(PyNestMLParser.LEFT_ANGLE) pass elif token in [65]: - self.state = 208 + self.enterOuterAlt(localctx, 2) + self.state = 221 localctx.le = self.match(PyNestMLParser.LEFT_ANGLE_EQUALS) pass elif token in [70]: - self.state = 209 + self.enterOuterAlt(localctx, 3) + self.state = 222 localctx.eq = self.match(PyNestMLParser.EQUALS_EQUALS) pass elif token in [71]: - self.state = 210 + self.enterOuterAlt(localctx, 4) + self.state = 223 localctx.ne = self.match(PyNestMLParser.EXCLAMATION_EQUALS) pass elif token in [72]: - self.state = 211 + self.enterOuterAlt(localctx, 5) + self.state = 224 localctx.ne2 = self.match(PyNestMLParser.LEFT_ANGLE_RIGHT_ANGLE) pass elif token in [73]: - self.state = 212 + self.enterOuterAlt(localctx, 6) + self.state = 225 localctx.ge = self.match(PyNestMLParser.RIGHT_ANGLE_EQUALS) pass elif token in [64]: - self.state = 213 + self.enterOuterAlt(localctx, 7) + self.state = 226 localctx.gt = self.match(PyNestMLParser.RIGHT_ANGLE) pass else: @@ -1447,18 +1630,19 @@ def accept(self, visitor:ParseTreeVisitor): def logicalOperator(self): localctx = PyNestMLParser.LogicalOperatorContext(self, self._ctx, self.state) - self.enterRule(localctx, 16, self.RULE_logicalOperator) + self.enterRule(localctx, 22, self.RULE_logicalOperator) try: - self.enterOuterAlt(localctx, 1) - self.state = 218 + self.state = 231 self._errHandler.sync(self) token = self._input.LA(1) if token in [26]: - self.state = 216 + self.enterOuterAlt(localctx, 1) + self.state = 229 localctx.logicalAnd = self.match(PyNestMLParser.AND_KEYWORD) pass elif token in [27]: - self.state = 217 + self.enterOuterAlt(localctx, 2) + self.state = 230 localctx.logicalOr = self.match(PyNestMLParser.OR_KEYWORD) pass else: @@ -1516,33 +1700,33 @@ def accept(self, visitor:ParseTreeVisitor): def variable(self): localctx = PyNestMLParser.VariableContext(self, self._ctx, self.state) - self.enterRule(localctx, 18, self.RULE_variable) + self.enterRule(localctx, 24, self.RULE_variable) try: self.enterOuterAlt(localctx, 1) - self.state = 220 + self.state = 233 localctx.name = self.match(PyNestMLParser.NAME) - self.state = 225 + self.state = 238 self._errHandler.sync(self) - la_ = self._interp.adaptivePredict(self._input,17,self._ctx) + la_ = self._interp.adaptivePredict(self._input,18,self._ctx) if la_ == 1: - self.state = 221 + self.state = 234 self.match(PyNestMLParser.LEFT_SQUARE_BRACKET) - self.state = 222 + self.state = 235 localctx.vectorParameter = self.expression(0) - self.state = 223 + self.state = 236 self.match(PyNestMLParser.RIGHT_SQUARE_BRACKET) - self.state = 230 + self.state = 243 self._errHandler.sync(self) - _alt = self._interp.adaptivePredict(self._input,18,self._ctx) + _alt = self._interp.adaptivePredict(self._input,19,self._ctx) while _alt!=2 and _alt!=ATN.INVALID_ALT_NUMBER: if _alt==1: - self.state = 227 + self.state = 240 self.match(PyNestMLParser.DIFFERENTIAL_ORDER) - self.state = 232 + self.state = 245 self._errHandler.sync(self) - _alt = self._interp.adaptivePredict(self._input,18,self._ctx) + _alt = self._interp.adaptivePredict(self._input,19,self._ctx) except RecognitionException as re: localctx.exception = re @@ -1598,35 +1782,35 @@ def accept(self, visitor:ParseTreeVisitor): def functionCall(self): localctx = PyNestMLParser.FunctionCallContext(self, self._ctx, self.state) - self.enterRule(localctx, 20, self.RULE_functionCall) + self.enterRule(localctx, 26, self.RULE_functionCall) self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 233 + self.state = 246 localctx.calleeName = self.match(PyNestMLParser.NAME) - self.state = 234 + self.state = 247 self.match(PyNestMLParser.LEFT_PAREN) - self.state = 243 + self.state = 256 self._errHandler.sync(self) _la = self._input.LA(1) if (((_la) & ~0x3f) == 0 and ((1 << _la) & 7318349696466944) != 0) or ((((_la - 75)) & ~0x3f) == 0 and ((1 << (_la - 75)) & 126977) != 0): - self.state = 235 + self.state = 248 self.expression(0) - self.state = 240 + self.state = 253 self._errHandler.sync(self) _la = self._input.LA(1) while _la==74: - self.state = 236 + self.state = 249 self.match(PyNestMLParser.COMMA) - self.state = 237 + self.state = 250 self.expression(0) - self.state = 242 + self.state = 255 self._errHandler.sync(self) _la = self._input.LA(1) - self.state = 245 + self.state = 258 self.match(PyNestMLParser.RIGHT_PAREN) except RecognitionException as re: localctx.exception = re @@ -1695,47 +1879,47 @@ def accept(self, visitor:ParseTreeVisitor): def inlineExpression(self): localctx = PyNestMLParser.InlineExpressionContext(self, self._ctx, self.state) - self.enterRule(localctx, 22, self.RULE_inlineExpression) + self.enterRule(localctx, 28, self.RULE_inlineExpression) self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 248 + self.state = 261 self._errHandler.sync(self) _la = self._input.LA(1) if _la==29: - self.state = 247 + self.state = 260 localctx.recordable = self.match(PyNestMLParser.RECORDABLE_KEYWORD) - self.state = 250 + self.state = 263 self.match(PyNestMLParser.INLINE_KEYWORD) - self.state = 251 + self.state = 264 localctx.variableName = self.match(PyNestMLParser.NAME) - self.state = 252 + self.state = 265 self.dataType() - self.state = 253 + self.state = 266 self.match(PyNestMLParser.EQUALS) - self.state = 254 + self.state = 267 self.expression(0) - self.state = 256 + self.state = 269 self._errHandler.sync(self) _la = self._input.LA(1) if _la==84: - self.state = 255 + self.state = 268 self.match(PyNestMLParser.SEMICOLON) - self.state = 261 + self.state = 274 self._errHandler.sync(self) _la = self._input.LA(1) while (((_la) & ~0x3f) == 0 and ((1 << _la) & 246290604621824) != 0): - self.state = 258 + self.state = 271 localctx.decorator = self.anyDecorator() - self.state = 263 + self.state = 276 self._errHandler.sync(self) _la = self._input.LA(1) - self.state = 264 + self.state = 277 self.match(PyNestMLParser.NEWLINE) except RecognitionException as re: localctx.exception = re @@ -1795,35 +1979,35 @@ def accept(self, visitor:ParseTreeVisitor): def odeEquation(self): localctx = PyNestMLParser.OdeEquationContext(self, self._ctx, self.state) - self.enterRule(localctx, 24, self.RULE_odeEquation) + self.enterRule(localctx, 30, self.RULE_odeEquation) self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 266 + self.state = 279 localctx.lhs = self.variable() - self.state = 267 + self.state = 280 self.match(PyNestMLParser.EQUALS) - self.state = 268 + self.state = 281 localctx.rhs = self.expression(0) - self.state = 270 + self.state = 283 self._errHandler.sync(self) _la = self._input.LA(1) if _la==84: - self.state = 269 + self.state = 282 self.match(PyNestMLParser.SEMICOLON) - self.state = 275 + self.state = 288 self._errHandler.sync(self) _la = self._input.LA(1) while (((_la) & ~0x3f) == 0 and ((1 << _la) & 246290604621824) != 0): - self.state = 272 + self.state = 285 localctx.decorator = self.anyDecorator() - self.state = 277 + self.state = 290 self._errHandler.sync(self) _la = self._input.LA(1) - self.state = 278 + self.state = 291 self.match(PyNestMLParser.NEWLINE) except RecognitionException as re: localctx.exception = re @@ -1891,113 +2075,44 @@ def accept(self, visitor:ParseTreeVisitor): def kernel(self): localctx = PyNestMLParser.KernelContext(self, self._ctx, self.state) - self.enterRule(localctx, 26, self.RULE_kernel) + self.enterRule(localctx, 32, self.RULE_kernel) self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 280 + self.state = 293 self.match(PyNestMLParser.KERNEL_KEYWORD) - self.state = 281 + self.state = 294 self.variable() - self.state = 282 + self.state = 295 self.match(PyNestMLParser.EQUALS) - self.state = 283 + self.state = 296 self.expression(0) - self.state = 291 + self.state = 304 self._errHandler.sync(self) _la = self._input.LA(1) while _la==4: - self.state = 284 + self.state = 297 self.match(PyNestMLParser.KERNEL_JOINING) - self.state = 285 + self.state = 298 self.variable() - self.state = 286 + self.state = 299 self.match(PyNestMLParser.EQUALS) - self.state = 287 + self.state = 300 self.expression(0) - self.state = 293 + self.state = 306 self._errHandler.sync(self) _la = self._input.LA(1) - self.state = 295 + self.state = 308 self._errHandler.sync(self) _la = self._input.LA(1) if _la==84: - self.state = 294 + self.state = 307 self.match(PyNestMLParser.SEMICOLON) - self.state = 297 - self.match(PyNestMLParser.NEWLINE) - except RecognitionException as re: - localctx.exception = re - self._errHandler.reportError(self, re) - self._errHandler.recover(self, re) - finally: - self.exitRule() - return localctx - - - class BlockContext(ParserRuleContext): - __slots__ = 'parser' - - def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): - super().__init__(parent, invokingState) - self.parser = parser - - def NEWLINE(self): - return self.getToken(PyNestMLParser.NEWLINE, 0) - - def INDENT(self): - return self.getToken(PyNestMLParser.INDENT, 0) - - def DEDENT(self): - return self.getToken(PyNestMLParser.DEDENT, 0) - - def stmt(self, i:int=None): - if i is None: - return self.getTypedRuleContexts(PyNestMLParser.StmtContext) - else: - return self.getTypedRuleContext(PyNestMLParser.StmtContext,i) - - - def getRuleIndex(self): - return PyNestMLParser.RULE_block - - def accept(self, visitor:ParseTreeVisitor): - if hasattr( visitor, "visitBlock" ): - return visitor.visitBlock(self) - else: - return visitor.visitChildren(self) - - - - - def block(self): - - localctx = PyNestMLParser.BlockContext(self, self._ctx, self.state) - self.enterRule(localctx, 28, self.RULE_block) - self._la = 0 # Token type - try: - self.enterOuterAlt(localctx, 1) - self.state = 299 + self.state = 310 self.match(PyNestMLParser.NEWLINE) - self.state = 300 - self.match(PyNestMLParser.INDENT) - self.state = 302 - self._errHandler.sync(self) - _la = self._input.LA(1) - while True: - self.state = 301 - self.stmt() - self.state = 304 - self._errHandler.sync(self) - _la = self._input.LA(1) - if not ((((_la) & ~0x3f) == 0 and ((1 << _la) & 543621120) != 0) or _la==89): - break - - self.state = 306 - self.match(PyNestMLParser.DEDENT) except RecognitionException as re: localctx.exception = re self._errHandler.reportError(self, re) @@ -2022,6 +2137,9 @@ def compoundStmt(self): return self.getTypedRuleContext(PyNestMLParser.CompoundStmtContext,0) + def NEWLINE(self): + return self.getToken(PyNestMLParser.NEWLINE, 0) + def getRuleIndex(self): return PyNestMLParser.RULE_stmt @@ -2037,19 +2155,27 @@ def accept(self, visitor:ParseTreeVisitor): def stmt(self): localctx = PyNestMLParser.StmtContext(self, self._ctx, self.state) - self.enterRule(localctx, 30, self.RULE_stmt) + self.enterRule(localctx, 34, self.RULE_stmt) + self._la = 0 # Token type try: - self.state = 310 + self.enterOuterAlt(localctx, 1) + self.state = 313 + self._errHandler.sync(self) + _la = self._input.LA(1) + if _la==9: + self.state = 312 + self.match(PyNestMLParser.NEWLINE) + + + self.state = 317 self._errHandler.sync(self) token = self._input.LA(1) if token in [16, 17, 29, 89]: - self.enterOuterAlt(localctx, 1) - self.state = 308 + self.state = 315 self.smallStmt() pass elif token in [18, 21, 22]: - self.enterOuterAlt(localctx, 2) - self.state = 309 + self.state = 316 self.compoundStmt() pass else: @@ -2098,24 +2224,24 @@ def accept(self, visitor:ParseTreeVisitor): def compoundStmt(self): localctx = PyNestMLParser.CompoundStmtContext(self, self._ctx, self.state) - self.enterRule(localctx, 32, self.RULE_compoundStmt) + self.enterRule(localctx, 36, self.RULE_compoundStmt) try: - self.state = 315 + self.state = 322 self._errHandler.sync(self) token = self._input.LA(1) if token in [18]: self.enterOuterAlt(localctx, 1) - self.state = 312 + self.state = 319 self.ifStmt() pass elif token in [21]: self.enterOuterAlt(localctx, 2) - self.state = 313 + self.state = 320 self.forStmt() pass elif token in [22]: self.enterOuterAlt(localctx, 3) - self.state = 314 + self.state = 321 self.whileStmt() pass else: @@ -2171,34 +2297,34 @@ def accept(self, visitor:ParseTreeVisitor): def smallStmt(self): localctx = PyNestMLParser.SmallStmtContext(self, self._ctx, self.state) - self.enterRule(localctx, 34, self.RULE_smallStmt) + self.enterRule(localctx, 38, self.RULE_smallStmt) try: self.enterOuterAlt(localctx, 1) - self.state = 321 + self.state = 328 self._errHandler.sync(self) - la_ = self._interp.adaptivePredict(self._input,31,self._ctx) + la_ = self._interp.adaptivePredict(self._input,32,self._ctx) if la_ == 1: - self.state = 317 + self.state = 324 self.assignment() pass elif la_ == 2: - self.state = 318 + self.state = 325 self.functionCall() pass elif la_ == 3: - self.state = 319 + self.state = 326 self.declaration() pass elif la_ == 4: - self.state = 320 + self.state = 327 self.returnStmt() pass - self.state = 323 + self.state = 330 self.match(PyNestMLParser.NEWLINE) except RecognitionException as re: localctx.exception = re @@ -2260,38 +2386,38 @@ def accept(self, visitor:ParseTreeVisitor): def assignment(self): localctx = PyNestMLParser.AssignmentContext(self, self._ctx, self.state) - self.enterRule(localctx, 36, self.RULE_assignment) + self.enterRule(localctx, 40, self.RULE_assignment) try: self.enterOuterAlt(localctx, 1) - self.state = 325 + self.state = 332 localctx.lhs_variable = self.variable() - self.state = 331 + self.state = 338 self._errHandler.sync(self) token = self._input.LA(1) if token in [76]: - self.state = 326 + self.state = 333 localctx.directAssignment = self.match(PyNestMLParser.EQUALS) pass elif token in [66]: - self.state = 327 + self.state = 334 localctx.compoundSum = self.match(PyNestMLParser.PLUS_EQUALS) pass elif token in [67]: - self.state = 328 + self.state = 335 localctx.compoundMinus = self.match(PyNestMLParser.MINUS_EQUALS) pass elif token in [68]: - self.state = 329 + self.state = 336 localctx.compoundProduct = self.match(PyNestMLParser.STAR_EQUALS) pass elif token in [69]: - self.state = 330 + self.state = 337 localctx.compoundQuotient = self.match(PyNestMLParser.FORWARD_SLASH_EQUALS) pass else: raise NoViableAltException(self) - self.state = 333 + self.state = 340 self.expression(0) except RecognitionException as re: localctx.exception = re @@ -2375,71 +2501,71 @@ def accept(self, visitor:ParseTreeVisitor): def declaration(self): localctx = PyNestMLParser.DeclarationContext(self, self._ctx, self.state) - self.enterRule(localctx, 38, self.RULE_declaration) + self.enterRule(localctx, 42, self.RULE_declaration) self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 336 + self.state = 343 self._errHandler.sync(self) _la = self._input.LA(1) if _la==29: - self.state = 335 + self.state = 342 localctx.isRecordable = self.match(PyNestMLParser.RECORDABLE_KEYWORD) - self.state = 339 + self.state = 346 self._errHandler.sync(self) _la = self._input.LA(1) if _la==16: - self.state = 338 + self.state = 345 localctx.isInlineExpression = self.match(PyNestMLParser.INLINE_KEYWORD) - self.state = 341 + self.state = 348 self.variable() - self.state = 346 + self.state = 353 self._errHandler.sync(self) _la = self._input.LA(1) while _la==74: - self.state = 342 + self.state = 349 self.match(PyNestMLParser.COMMA) - self.state = 343 + self.state = 350 self.variable() - self.state = 348 + self.state = 355 self._errHandler.sync(self) _la = self._input.LA(1) - self.state = 349 + self.state = 356 self.dataType() - self.state = 352 + self.state = 359 self._errHandler.sync(self) _la = self._input.LA(1) if _la==76: - self.state = 350 + self.state = 357 self.match(PyNestMLParser.EQUALS) - self.state = 351 + self.state = 358 localctx.rhs = self.expression(0) - self.state = 358 + self.state = 365 self._errHandler.sync(self) _la = self._input.LA(1) if _la==59: - self.state = 354 + self.state = 361 self.match(PyNestMLParser.LEFT_LEFT_SQUARE) - self.state = 355 + self.state = 362 localctx.invariant = self.expression(0) - self.state = 356 + self.state = 363 self.match(PyNestMLParser.RIGHT_RIGHT_SQUARE) - self.state = 363 + self.state = 370 self._errHandler.sync(self) _la = self._input.LA(1) while (((_la) & ~0x3f) == 0 and ((1 << _la) & 246290604621824) != 0): - self.state = 360 + self.state = 367 localctx.decorator = self.anyDecorator() - self.state = 365 + self.state = 372 self._errHandler.sync(self) _la = self._input.LA(1) @@ -2481,12 +2607,12 @@ def accept(self, visitor:ParseTreeVisitor): def declaration_newline(self): localctx = PyNestMLParser.Declaration_newlineContext(self, self._ctx, self.state) - self.enterRule(localctx, 40, self.RULE_declaration_newline) + self.enterRule(localctx, 44, self.RULE_declaration_newline) try: self.enterOuterAlt(localctx, 1) - self.state = 366 + self.state = 373 self.declaration() - self.state = 367 + self.state = 374 self.match(PyNestMLParser.NEWLINE) except RecognitionException as re: localctx.exception = re @@ -2497,157 +2623,51 @@ def declaration_newline(self): return localctx - class AnyDecoratorContext(ParserRuleContext): + class StmtsBodyContext(ParserRuleContext): __slots__ = 'parser' def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): super().__init__(parent, invokingState) self.parser = parser - def DECORATOR_HOMOGENEOUS(self): - return self.getToken(PyNestMLParser.DECORATOR_HOMOGENEOUS, 0) - - def DECORATOR_HETEROGENEOUS(self): - return self.getToken(PyNestMLParser.DECORATOR_HETEROGENEOUS, 0) - - def AT(self): - return self.getToken(PyNestMLParser.AT, 0) - - def namespaceDecoratorNamespace(self): - return self.getTypedRuleContext(PyNestMLParser.NamespaceDecoratorNamespaceContext,0) - - - def DOUBLE_COLON(self): - return self.getToken(PyNestMLParser.DOUBLE_COLON, 0) - - def namespaceDecoratorName(self): - return self.getTypedRuleContext(PyNestMLParser.NamespaceDecoratorNameContext,0) - - - def getRuleIndex(self): - return PyNestMLParser.RULE_anyDecorator - - def accept(self, visitor:ParseTreeVisitor): - if hasattr( visitor, "visitAnyDecorator" ): - return visitor.visitAnyDecorator(self) - else: - return visitor.visitChildren(self) - - - - - def anyDecorator(self): - - localctx = PyNestMLParser.AnyDecoratorContext(self, self._ctx, self.state) - self.enterRule(localctx, 42, self.RULE_anyDecorator) - try: - self.state = 376 - self._errHandler.sync(self) - token = self._input.LA(1) - if token in [45]: - self.enterOuterAlt(localctx, 1) - self.state = 369 - self.match(PyNestMLParser.DECORATOR_HOMOGENEOUS) - pass - elif token in [46]: - self.enterOuterAlt(localctx, 2) - self.state = 370 - self.match(PyNestMLParser.DECORATOR_HETEROGENEOUS) - pass - elif token in [47]: - self.enterOuterAlt(localctx, 3) - self.state = 371 - self.match(PyNestMLParser.AT) - self.state = 372 - self.namespaceDecoratorNamespace() - self.state = 373 - self.match(PyNestMLParser.DOUBLE_COLON) - self.state = 374 - self.namespaceDecoratorName() - pass - else: - raise NoViableAltException(self) - - except RecognitionException as re: - localctx.exception = re - self._errHandler.reportError(self, re) - self._errHandler.recover(self, re) - finally: - self.exitRule() - return localctx - - - class NamespaceDecoratorNamespaceContext(ParserRuleContext): - __slots__ = 'parser' - - def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): - super().__init__(parent, invokingState) - self.parser = parser - self.name = None # Token - - def NAME(self): - return self.getToken(PyNestMLParser.NAME, 0) - - def getRuleIndex(self): - return PyNestMLParser.RULE_namespaceDecoratorNamespace - - def accept(self, visitor:ParseTreeVisitor): - if hasattr( visitor, "visitNamespaceDecoratorNamespace" ): - return visitor.visitNamespaceDecoratorNamespace(self) + def stmt(self, i:int=None): + if i is None: + return self.getTypedRuleContexts(PyNestMLParser.StmtContext) else: - return visitor.visitChildren(self) - - - - - def namespaceDecoratorNamespace(self): - - localctx = PyNestMLParser.NamespaceDecoratorNamespaceContext(self, self._ctx, self.state) - self.enterRule(localctx, 44, self.RULE_namespaceDecoratorNamespace) - try: - self.enterOuterAlt(localctx, 1) - self.state = 378 - localctx.name = self.match(PyNestMLParser.NAME) - except RecognitionException as re: - localctx.exception = re - self._errHandler.reportError(self, re) - self._errHandler.recover(self, re) - finally: - self.exitRule() - return localctx - - - class NamespaceDecoratorNameContext(ParserRuleContext): - __slots__ = 'parser' - - def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): - super().__init__(parent, invokingState) - self.parser = parser - self.name = None # Token + return self.getTypedRuleContext(PyNestMLParser.StmtContext,i) - def NAME(self): - return self.getToken(PyNestMLParser.NAME, 0) def getRuleIndex(self): - return PyNestMLParser.RULE_namespaceDecoratorName + return PyNestMLParser.RULE_stmtsBody def accept(self, visitor:ParseTreeVisitor): - if hasattr( visitor, "visitNamespaceDecoratorName" ): - return visitor.visitNamespaceDecoratorName(self) + if hasattr( visitor, "visitStmtsBody" ): + return visitor.visitStmtsBody(self) else: return visitor.visitChildren(self) - def namespaceDecoratorName(self): + def stmtsBody(self): - localctx = PyNestMLParser.NamespaceDecoratorNameContext(self, self._ctx, self.state) - self.enterRule(localctx, 46, self.RULE_namespaceDecoratorName) + localctx = PyNestMLParser.StmtsBodyContext(self, self._ctx, self.state) + self.enterRule(localctx, 46, self.RULE_stmtsBody) + self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 380 - localctx.name = self.match(PyNestMLParser.NAME) + self.state = 377 + self._errHandler.sync(self) + _la = self._input.LA(1) + while True: + self.state = 376 + self.stmt() + self.state = 379 + self._errHandler.sync(self) + _la = self._input.LA(1) + if not ((((_la) & ~0x3f) == 0 and ((1 << _la) & 543621632) != 0) or _la==89): + break + except RecognitionException as re: localctx.exception = re self._errHandler.reportError(self, re) @@ -2690,13 +2710,13 @@ def returnStmt(self): self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 382 + self.state = 381 self.match(PyNestMLParser.RETURN_KEYWORD) - self.state = 384 + self.state = 383 self._errHandler.sync(self) _la = self._input.LA(1) if (((_la) & ~0x3f) == 0 and ((1 << _la) & 7318349696466944) != 0) or ((((_la - 75)) & ~0x3f) == 0 and ((1 << (_la - 75)) & 126977) != 0): - self.state = 383 + self.state = 382 self.expression(0) @@ -2750,23 +2770,23 @@ def ifStmt(self): self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 386 + self.state = 385 self.ifClause() - self.state = 390 + self.state = 389 self._errHandler.sync(self) _la = self._input.LA(1) while _la==19: - self.state = 387 + self.state = 386 self.elifClause() - self.state = 392 + self.state = 391 self._errHandler.sync(self) _la = self._input.LA(1) - self.state = 394 + self.state = 393 self._errHandler.sync(self) _la = self._input.LA(1) if _la==20: - self.state = 393 + self.state = 392 self.elseClause() @@ -2796,9 +2816,18 @@ def expression(self): def COLON(self): return self.getToken(PyNestMLParser.COLON, 0) - def block(self): - return self.getTypedRuleContext(PyNestMLParser.BlockContext,0) + def NEWLINE(self): + return self.getToken(PyNestMLParser.NEWLINE, 0) + + def INDENT(self): + return self.getToken(PyNestMLParser.INDENT, 0) + + def stmtsBody(self): + return self.getTypedRuleContext(PyNestMLParser.StmtsBodyContext,0) + + def DEDENT(self): + return self.getToken(PyNestMLParser.DEDENT, 0) def getRuleIndex(self): return PyNestMLParser.RULE_ifClause @@ -2818,14 +2847,20 @@ def ifClause(self): self.enterRule(localctx, 52, self.RULE_ifClause) try: self.enterOuterAlt(localctx, 1) - self.state = 396 + self.state = 395 self.match(PyNestMLParser.IF_KEYWORD) - self.state = 397 + self.state = 396 self.expression(0) - self.state = 398 + self.state = 397 self.match(PyNestMLParser.COLON) + self.state = 398 + self.match(PyNestMLParser.NEWLINE) self.state = 399 - self.block() + self.match(PyNestMLParser.INDENT) + self.state = 400 + self.stmtsBody() + self.state = 401 + self.match(PyNestMLParser.DEDENT) except RecognitionException as re: localctx.exception = re self._errHandler.reportError(self, re) @@ -2852,10 +2887,19 @@ def expression(self): def COLON(self): return self.getToken(PyNestMLParser.COLON, 0) - def block(self): - return self.getTypedRuleContext(PyNestMLParser.BlockContext,0) + def NEWLINE(self): + return self.getToken(PyNestMLParser.NEWLINE, 0) + + def INDENT(self): + return self.getToken(PyNestMLParser.INDENT, 0) + + def stmtsBody(self): + return self.getTypedRuleContext(PyNestMLParser.StmtsBodyContext,0) + def DEDENT(self): + return self.getToken(PyNestMLParser.DEDENT, 0) + def getRuleIndex(self): return PyNestMLParser.RULE_elifClause @@ -2874,14 +2918,20 @@ def elifClause(self): self.enterRule(localctx, 54, self.RULE_elifClause) try: self.enterOuterAlt(localctx, 1) - self.state = 401 + self.state = 403 self.match(PyNestMLParser.ELIF_KEYWORD) - self.state = 402 + self.state = 404 self.expression(0) - self.state = 403 + self.state = 405 self.match(PyNestMLParser.COLON) - self.state = 404 - self.block() + self.state = 406 + self.match(PyNestMLParser.NEWLINE) + self.state = 407 + self.match(PyNestMLParser.INDENT) + self.state = 408 + self.stmtsBody() + self.state = 409 + self.match(PyNestMLParser.DEDENT) except RecognitionException as re: localctx.exception = re self._errHandler.reportError(self, re) @@ -2904,10 +2954,19 @@ def ELSE_KEYWORD(self): def COLON(self): return self.getToken(PyNestMLParser.COLON, 0) - def block(self): - return self.getTypedRuleContext(PyNestMLParser.BlockContext,0) + def NEWLINE(self): + return self.getToken(PyNestMLParser.NEWLINE, 0) + + def INDENT(self): + return self.getToken(PyNestMLParser.INDENT, 0) + + def stmtsBody(self): + return self.getTypedRuleContext(PyNestMLParser.StmtsBodyContext,0) + def DEDENT(self): + return self.getToken(PyNestMLParser.DEDENT, 0) + def getRuleIndex(self): return PyNestMLParser.RULE_elseClause @@ -2926,12 +2985,18 @@ def elseClause(self): self.enterRule(localctx, 56, self.RULE_elseClause) try: self.enterOuterAlt(localctx, 1) - self.state = 406 + self.state = 411 self.match(PyNestMLParser.ELSE_KEYWORD) - self.state = 407 + self.state = 412 self.match(PyNestMLParser.COLON) - self.state = 408 - self.block() + self.state = 413 + self.match(PyNestMLParser.NEWLINE) + self.state = 414 + self.match(PyNestMLParser.INDENT) + self.state = 415 + self.stmtsBody() + self.state = 416 + self.match(PyNestMLParser.DEDENT) except RecognitionException as re: localctx.exception = re self._errHandler.reportError(self, re) @@ -2967,9 +3032,18 @@ def STEP_KEYWORD(self): def COLON(self): return self.getToken(PyNestMLParser.COLON, 0) - def block(self): - return self.getTypedRuleContext(PyNestMLParser.BlockContext,0) + def NEWLINE(self): + return self.getToken(PyNestMLParser.NEWLINE, 0) + + def INDENT(self): + return self.getToken(PyNestMLParser.INDENT, 0) + + def stmtsBody(self): + return self.getTypedRuleContext(PyNestMLParser.StmtsBodyContext,0) + + def DEDENT(self): + return self.getToken(PyNestMLParser.DEDENT, 0) def NAME(self): return self.getToken(PyNestMLParser.NAME, 0) @@ -3009,40 +3083,46 @@ def forStmt(self): self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 410 + self.state = 418 self.match(PyNestMLParser.FOR_KEYWORD) - self.state = 411 + self.state = 419 localctx.var = self.match(PyNestMLParser.NAME) - self.state = 412 + self.state = 420 self.match(PyNestMLParser.IN_KEYWORD) - self.state = 413 + self.state = 421 localctx.start_from = self.expression(0) - self.state = 414 + self.state = 422 self.match(PyNestMLParser.ELLIPSIS) - self.state = 415 + self.state = 423 localctx.end_at = self.expression(0) - self.state = 416 + self.state = 424 self.match(PyNestMLParser.STEP_KEYWORD) - self.state = 418 + self.state = 426 self._errHandler.sync(self) _la = self._input.LA(1) if _la==75: - self.state = 417 + self.state = 425 localctx.negative = self.match(PyNestMLParser.MINUS) - self.state = 420 + self.state = 428 _la = self._input.LA(1) if not(_la==90 or _la==91): self._errHandler.recoverInline(self) else: self._errHandler.reportMatch(self) self.consume() - self.state = 421 + self.state = 429 self.match(PyNestMLParser.COLON) - self.state = 422 - self.block() + self.state = 430 + self.match(PyNestMLParser.NEWLINE) + self.state = 431 + self.match(PyNestMLParser.INDENT) + self.state = 432 + self.stmtsBody() + self.state = 433 + self.match(PyNestMLParser.DEDENT) except RecognitionException as re: localctx.exception = re self._errHandler.reportError(self, re) @@ -3069,9 +3149,18 @@ def expression(self): def COLON(self): return self.getToken(PyNestMLParser.COLON, 0) - def block(self): - return self.getTypedRuleContext(PyNestMLParser.BlockContext,0) + def NEWLINE(self): + return self.getToken(PyNestMLParser.NEWLINE, 0) + + def INDENT(self): + return self.getToken(PyNestMLParser.INDENT, 0) + + def stmtsBody(self): + return self.getTypedRuleContext(PyNestMLParser.StmtsBodyContext,0) + + def DEDENT(self): + return self.getToken(PyNestMLParser.DEDENT, 0) def getRuleIndex(self): return PyNestMLParser.RULE_whileStmt @@ -3091,14 +3180,20 @@ def whileStmt(self): self.enterRule(localctx, 60, self.RULE_whileStmt) try: self.enterOuterAlt(localctx, 1) - self.state = 424 + self.state = 435 self.match(PyNestMLParser.WHILE_KEYWORD) - self.state = 425 + self.state = 436 self.expression(0) - self.state = 426 + self.state = 437 self.match(PyNestMLParser.COLON) - self.state = 427 - self.block() + self.state = 438 + self.match(PyNestMLParser.NEWLINE) + self.state = 439 + self.match(PyNestMLParser.INDENT) + self.state = 440 + self.stmtsBody() + self.state = 441 + self.match(PyNestMLParser.DEDENT) except RecognitionException as re: localctx.exception = re self._errHandler.reportError(self, re) @@ -3150,31 +3245,31 @@ def nestMLCompilationUnit(self): self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 431 + self.state = 445 self._errHandler.sync(self) _la = self._input.LA(1) while True: - self.state = 431 + self.state = 445 self._errHandler.sync(self) token = self._input.LA(1) if token in [31]: - self.state = 429 + self.state = 443 self.model() pass elif token in [9]: - self.state = 430 + self.state = 444 self.match(PyNestMLParser.NEWLINE) pass else: raise NoViableAltException(self) - self.state = 433 + self.state = 447 self._errHandler.sync(self) _la = self._input.LA(1) if not (_la==9 or _la==31): break - self.state = 435 + self.state = 449 self.match(PyNestMLParser.EOF) except RecognitionException as re: localctx.exception = re @@ -3198,6 +3293,9 @@ def MODEL_KEYWORD(self): def NAME(self): return self.getToken(PyNestMLParser.NAME, 0) + def COLON(self): + return self.getToken(PyNestMLParser.COLON, 0) + def modelBody(self): return self.getTypedRuleContext(PyNestMLParser.ModelBodyContext,0) @@ -3220,11 +3318,13 @@ def model(self): self.enterRule(localctx, 64, self.RULE_model) try: self.enterOuterAlt(localctx, 1) - self.state = 437 + self.state = 451 self.match(PyNestMLParser.MODEL_KEYWORD) - self.state = 438 + self.state = 452 self.match(PyNestMLParser.NAME) - self.state = 439 + self.state = 453 + self.match(PyNestMLParser.COLON) + self.state = 454 self.modelBody() except RecognitionException as re: localctx.exception = re @@ -3242,9 +3342,6 @@ def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): super().__init__(parent, invokingState) self.parser = parser - def COLON(self): - return self.getToken(PyNestMLParser.COLON, 0) - def NEWLINE(self): return self.getToken(PyNestMLParser.NEWLINE, 0) @@ -3329,61 +3426,59 @@ def modelBody(self): self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 441 - self.match(PyNestMLParser.COLON) - self.state = 442 + self.state = 456 self.match(PyNestMLParser.NEWLINE) - self.state = 443 + self.state = 457 self.match(PyNestMLParser.INDENT) - self.state = 452 + self.state = 466 self._errHandler.sync(self) _la = self._input.LA(1) while True: - self.state = 452 + self.state = 466 self._errHandler.sync(self) token = self._input.LA(1) if token in [32, 33, 34]: - self.state = 444 + self.state = 458 self.blockWithVariables() pass elif token in [36]: - self.state = 445 + self.state = 459 self.equationsBlock() pass elif token in [37]: - self.state = 446 + self.state = 460 self.inputBlock() pass elif token in [38]: - self.state = 447 + self.state = 461 self.outputBlock() pass elif token in [15]: - self.state = 448 + self.state = 462 self.function() pass elif token in [40]: - self.state = 449 + self.state = 463 self.onReceiveBlock() pass elif token in [41]: - self.state = 450 + self.state = 464 self.onConditionBlock() pass elif token in [35]: - self.state = 451 + self.state = 465 self.updateBlock() pass else: raise NoViableAltException(self) - self.state = 454 + self.state = 468 self._errHandler.sync(self) _la = self._input.LA(1) if not ((((_la) & ~0x3f) == 0 and ((1 << _la) & 3843995762688) != 0)): break - self.state = 456 + self.state = 470 self.match(PyNestMLParser.DEDENT) except RecognitionException as re: localctx.exception = re @@ -3414,10 +3509,19 @@ def RIGHT_PAREN(self): def COLON(self): return self.getToken(PyNestMLParser.COLON, 0) - def block(self): - return self.getTypedRuleContext(PyNestMLParser.BlockContext,0) + def NEWLINE(self): + return self.getToken(PyNestMLParser.NEWLINE, 0) + + def INDENT(self): + return self.getToken(PyNestMLParser.INDENT, 0) + + def stmtsBody(self): + return self.getTypedRuleContext(PyNestMLParser.StmtsBodyContext,0) + def DEDENT(self): + return self.getToken(PyNestMLParser.DEDENT, 0) + def NAME(self): return self.getToken(PyNestMLParser.NAME, 0) @@ -3453,30 +3557,36 @@ def onReceiveBlock(self): self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 458 + self.state = 472 self.match(PyNestMLParser.ON_RECEIVE_KEYWORD) - self.state = 459 + self.state = 473 self.match(PyNestMLParser.LEFT_PAREN) - self.state = 460 + self.state = 474 localctx.inputPortName = self.match(PyNestMLParser.NAME) - self.state = 465 + self.state = 479 self._errHandler.sync(self) _la = self._input.LA(1) while _la==74: - self.state = 461 + self.state = 475 self.match(PyNestMLParser.COMMA) - self.state = 462 + self.state = 476 self.constParameter() - self.state = 467 + self.state = 481 self._errHandler.sync(self) _la = self._input.LA(1) - self.state = 468 + self.state = 482 self.match(PyNestMLParser.RIGHT_PAREN) - self.state = 469 + self.state = 483 self.match(PyNestMLParser.COLON) - self.state = 470 - self.block() + self.state = 484 + self.match(PyNestMLParser.NEWLINE) + self.state = 485 + self.match(PyNestMLParser.INDENT) + self.state = 486 + self.stmtsBody() + self.state = 487 + self.match(PyNestMLParser.DEDENT) except RecognitionException as re: localctx.exception = re self._errHandler.reportError(self, re) @@ -3506,9 +3616,18 @@ def RIGHT_PAREN(self): def COLON(self): return self.getToken(PyNestMLParser.COLON, 0) - def block(self): - return self.getTypedRuleContext(PyNestMLParser.BlockContext,0) + def NEWLINE(self): + return self.getToken(PyNestMLParser.NEWLINE, 0) + + def INDENT(self): + return self.getToken(PyNestMLParser.INDENT, 0) + + def stmtsBody(self): + return self.getTypedRuleContext(PyNestMLParser.StmtsBodyContext,0) + + def DEDENT(self): + return self.getToken(PyNestMLParser.DEDENT, 0) def expression(self): return self.getTypedRuleContext(PyNestMLParser.ExpressionContext,0) @@ -3546,30 +3665,36 @@ def onConditionBlock(self): self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 472 + self.state = 489 self.match(PyNestMLParser.ON_CONDITION_KEYWORD) - self.state = 473 + self.state = 490 self.match(PyNestMLParser.LEFT_PAREN) - self.state = 474 + self.state = 491 localctx.condition = self.expression(0) - self.state = 479 + self.state = 496 self._errHandler.sync(self) _la = self._input.LA(1) while _la==74: - self.state = 475 + self.state = 492 self.match(PyNestMLParser.COMMA) - self.state = 476 + self.state = 493 self.constParameter() - self.state = 481 + self.state = 498 self._errHandler.sync(self) _la = self._input.LA(1) - self.state = 482 + self.state = 499 self.match(PyNestMLParser.RIGHT_PAREN) - self.state = 483 + self.state = 500 self.match(PyNestMLParser.COLON) - self.state = 484 - self.block() + self.state = 501 + self.match(PyNestMLParser.NEWLINE) + self.state = 502 + self.match(PyNestMLParser.INDENT) + self.state = 503 + self.stmtsBody() + self.state = 504 + self.match(PyNestMLParser.DEDENT) except RecognitionException as re: localctx.exception = re self._errHandler.reportError(self, re) @@ -3634,7 +3759,7 @@ def blockWithVariables(self): self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 486 + self.state = 506 localctx.blockType = self._input.LT(1) _la = self._input.LA(1) if not((((_la) & ~0x3f) == 0 and ((1 << _la) & 30064771072) != 0)): @@ -3642,25 +3767,25 @@ def blockWithVariables(self): else: self._errHandler.reportMatch(self) self.consume() - self.state = 487 + self.state = 507 self.match(PyNestMLParser.COLON) - self.state = 488 + self.state = 508 self.match(PyNestMLParser.NEWLINE) - self.state = 489 + self.state = 509 self.match(PyNestMLParser.INDENT) - self.state = 491 + self.state = 511 self._errHandler.sync(self) _la = self._input.LA(1) while True: - self.state = 490 + self.state = 510 self.declaration_newline() - self.state = 493 + self.state = 513 self._errHandler.sync(self) _la = self._input.LA(1) if not (_la==16 or _la==29 or _la==89): break - self.state = 495 + self.state = 515 self.match(PyNestMLParser.DEDENT) except RecognitionException as re: localctx.exception = re @@ -3684,9 +3809,18 @@ def UPDATE_KEYWORD(self): def COLON(self): return self.getToken(PyNestMLParser.COLON, 0) - def block(self): - return self.getTypedRuleContext(PyNestMLParser.BlockContext,0) + def NEWLINE(self): + return self.getToken(PyNestMLParser.NEWLINE, 0) + + def INDENT(self): + return self.getToken(PyNestMLParser.INDENT, 0) + + def stmtsBody(self): + return self.getTypedRuleContext(PyNestMLParser.StmtsBodyContext,0) + + def DEDENT(self): + return self.getToken(PyNestMLParser.DEDENT, 0) def getRuleIndex(self): return PyNestMLParser.RULE_updateBlock @@ -3706,12 +3840,18 @@ def updateBlock(self): self.enterRule(localctx, 74, self.RULE_updateBlock) try: self.enterOuterAlt(localctx, 1) - self.state = 497 + self.state = 517 self.match(PyNestMLParser.UPDATE_KEYWORD) - self.state = 498 + self.state = 518 self.match(PyNestMLParser.COLON) - self.state = 499 - self.block() + self.state = 519 + self.match(PyNestMLParser.NEWLINE) + self.state = 520 + self.match(PyNestMLParser.INDENT) + self.state = 521 + self.stmtsBody() + self.state = 522 + self.match(PyNestMLParser.DEDENT) except RecognitionException as re: localctx.exception = re self._errHandler.reportError(self, re) @@ -3783,43 +3923,43 @@ def equationsBlock(self): self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 501 + self.state = 524 self.match(PyNestMLParser.EQUATIONS_KEYWORD) - self.state = 502 + self.state = 525 self.match(PyNestMLParser.COLON) - self.state = 503 + self.state = 526 self.match(PyNestMLParser.NEWLINE) - self.state = 504 + self.state = 527 self.match(PyNestMLParser.INDENT) - self.state = 508 + self.state = 531 self._errHandler.sync(self) _la = self._input.LA(1) while True: - self.state = 508 + self.state = 531 self._errHandler.sync(self) token = self._input.LA(1) if token in [16, 29]: - self.state = 505 + self.state = 528 self.inlineExpression() pass elif token in [89]: - self.state = 506 + self.state = 529 self.odeEquation() pass elif token in [30]: - self.state = 507 + self.state = 530 self.kernel() pass else: raise NoViableAltException(self) - self.state = 510 + self.state = 533 self._errHandler.sync(self) _la = self._input.LA(1) if not ((((_la) & ~0x3f) == 0 and ((1 << _la) & 1610678272) != 0) or _la==89): break - self.state = 512 + self.state = 535 self.match(PyNestMLParser.DEDENT) except RecognitionException as re: localctx.exception = re @@ -3910,69 +4050,69 @@ def inputBlock(self): self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 514 + self.state = 537 self.match(PyNestMLParser.INPUT_KEYWORD) - self.state = 515 + self.state = 538 self.match(PyNestMLParser.COLON) - self.state = 516 + self.state = 539 self.match(PyNestMLParser.NEWLINE) - self.state = 517 + self.state = 540 self.match(PyNestMLParser.INDENT) - self.state = 536 + self.state = 559 self._errHandler.sync(self) _la = self._input.LA(1) while True: - self.state = 520 + self.state = 543 self._errHandler.sync(self) - la_ = self._interp.adaptivePredict(self._input,53,self._ctx) + la_ = self._interp.adaptivePredict(self._input,54,self._ctx) if la_ == 1: - self.state = 518 + self.state = 541 self.spikeInputPort() pass elif la_ == 2: - self.state = 519 + self.state = 542 self.continuousInputPort() pass - self.state = 534 + self.state = 557 self._errHandler.sync(self) _la = self._input.LA(1) if _la==49: - self.state = 522 + self.state = 545 self.match(PyNestMLParser.LEFT_PAREN) - self.state = 531 + self.state = 554 self._errHandler.sync(self) _la = self._input.LA(1) if _la==89: - self.state = 523 + self.state = 546 self.parameter() - self.state = 528 + self.state = 551 self._errHandler.sync(self) _la = self._input.LA(1) while _la==74: - self.state = 524 + self.state = 547 self.match(PyNestMLParser.COMMA) - self.state = 525 + self.state = 548 self.parameter() - self.state = 530 + self.state = 553 self._errHandler.sync(self) _la = self._input.LA(1) - self.state = 533 + self.state = 556 self.match(PyNestMLParser.RIGHT_PAREN) - self.state = 538 + self.state = 561 self._errHandler.sync(self) _la = self._input.LA(1) if not (_la==89): break - self.state = 540 + self.state = 563 self.match(PyNestMLParser.DEDENT) except RecognitionException as re: localctx.exception = re @@ -4040,35 +4180,35 @@ def spikeInputPort(self): self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 542 + self.state = 565 localctx.name = self.match(PyNestMLParser.NAME) - self.state = 547 + self.state = 570 self._errHandler.sync(self) _la = self._input.LA(1) if _la==56: - self.state = 543 + self.state = 566 self.match(PyNestMLParser.LEFT_SQUARE_BRACKET) - self.state = 544 + self.state = 567 localctx.sizeParameter = self.expression(0) - self.state = 545 + self.state = 568 self.match(PyNestMLParser.RIGHT_SQUARE_BRACKET) - self.state = 549 + self.state = 572 self.match(PyNestMLParser.LEFT_ANGLE_MINUS) - self.state = 553 + self.state = 576 self._errHandler.sync(self) _la = self._input.LA(1) while _la==43 or _la==44: - self.state = 550 + self.state = 573 self.inputQualifier() - self.state = 555 + self.state = 578 self._errHandler.sync(self) _la = self._input.LA(1) - self.state = 556 + self.state = 579 self.match(PyNestMLParser.SPIKE_KEYWORD) - self.state = 557 + self.state = 580 self.match(PyNestMLParser.NEWLINE) except RecognitionException as re: localctx.exception = re @@ -4133,27 +4273,27 @@ def continuousInputPort(self): self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 559 + self.state = 582 localctx.name = self.match(PyNestMLParser.NAME) - self.state = 564 + self.state = 587 self._errHandler.sync(self) _la = self._input.LA(1) if _la==56: - self.state = 560 + self.state = 583 self.match(PyNestMLParser.LEFT_SQUARE_BRACKET) - self.state = 561 + self.state = 584 localctx.sizeParameter = self.expression(0) - self.state = 562 + self.state = 585 self.match(PyNestMLParser.RIGHT_SQUARE_BRACKET) - self.state = 566 + self.state = 589 self.dataType() - self.state = 567 + self.state = 590 self.match(PyNestMLParser.LEFT_ANGLE_MINUS) - self.state = 568 + self.state = 591 self.match(PyNestMLParser.CONTINUOUS_KEYWORD) - self.state = 569 + self.state = 592 self.match(PyNestMLParser.NEWLINE) except RecognitionException as re: localctx.exception = re @@ -4196,16 +4336,17 @@ def inputQualifier(self): localctx = PyNestMLParser.InputQualifierContext(self, self._ctx, self.state) self.enterRule(localctx, 84, self.RULE_inputQualifier) try: - self.enterOuterAlt(localctx, 1) - self.state = 573 + self.state = 596 self._errHandler.sync(self) token = self._input.LA(1) if token in [43]: - self.state = 571 + self.enterOuterAlt(localctx, 1) + self.state = 594 localctx.isInhibitory = self.match(PyNestMLParser.INHIBITORY_KEYWORD) pass elif token in [44]: - self.state = 572 + self.enterOuterAlt(localctx, 2) + self.state = 595 localctx.isExcitatory = self.match(PyNestMLParser.EXCITATORY_KEYWORD) pass else: @@ -4292,61 +4433,61 @@ def outputBlock(self): self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 575 + self.state = 598 self.match(PyNestMLParser.OUTPUT_KEYWORD) - self.state = 576 + self.state = 599 self.match(PyNestMLParser.COLON) - self.state = 577 + self.state = 600 self.match(PyNestMLParser.NEWLINE) - self.state = 578 + self.state = 601 self.match(PyNestMLParser.INDENT) - self.state = 595 + self.state = 618 self._errHandler.sync(self) token = self._input.LA(1) if token in [42]: - self.state = 579 + self.state = 602 localctx.isSpike = self.match(PyNestMLParser.SPIKE_KEYWORD) - self.state = 592 + self.state = 615 self._errHandler.sync(self) _la = self._input.LA(1) if _la==49: - self.state = 580 + self.state = 603 self.match(PyNestMLParser.LEFT_PAREN) - self.state = 589 + self.state = 612 self._errHandler.sync(self) _la = self._input.LA(1) if _la==89: - self.state = 581 + self.state = 604 localctx.attribute = self.parameter() - self.state = 586 + self.state = 609 self._errHandler.sync(self) _la = self._input.LA(1) while _la==74: - self.state = 582 + self.state = 605 self.match(PyNestMLParser.COMMA) - self.state = 583 + self.state = 606 localctx.attribute = self.parameter() - self.state = 588 + self.state = 611 self._errHandler.sync(self) _la = self._input.LA(1) - self.state = 591 + self.state = 614 self.match(PyNestMLParser.RIGHT_PAREN) pass elif token in [39]: - self.state = 594 + self.state = 617 localctx.isContinuous = self.match(PyNestMLParser.CONTINUOUS_KEYWORD) pass else: raise NoViableAltException(self) - self.state = 597 + self.state = 620 self.match(PyNestMLParser.NEWLINE) - self.state = 598 + self.state = 621 self.match(PyNestMLParser.DEDENT) except RecognitionException as re: localctx.exception = re @@ -4380,9 +4521,18 @@ def RIGHT_PAREN(self): def COLON(self): return self.getToken(PyNestMLParser.COLON, 0) - def block(self): - return self.getTypedRuleContext(PyNestMLParser.BlockContext,0) + def NEWLINE(self): + return self.getToken(PyNestMLParser.NEWLINE, 0) + + def INDENT(self): + return self.getToken(PyNestMLParser.INDENT, 0) + + def stmtsBody(self): + return self.getTypedRuleContext(PyNestMLParser.StmtsBodyContext,0) + + def DEDENT(self): + return self.getToken(PyNestMLParser.DEDENT, 0) def parameter(self, i:int=None): if i is None: @@ -4420,46 +4570,52 @@ def function(self): self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 600 + self.state = 623 self.match(PyNestMLParser.FUNCTION_KEYWORD) - self.state = 601 + self.state = 624 self.match(PyNestMLParser.NAME) - self.state = 602 + self.state = 625 self.match(PyNestMLParser.LEFT_PAREN) - self.state = 611 + self.state = 634 self._errHandler.sync(self) _la = self._input.LA(1) if _la==89: - self.state = 603 + self.state = 626 self.parameter() - self.state = 608 + self.state = 631 self._errHandler.sync(self) _la = self._input.LA(1) while _la==74: - self.state = 604 + self.state = 627 self.match(PyNestMLParser.COMMA) - self.state = 605 + self.state = 628 self.parameter() - self.state = 610 + self.state = 633 self._errHandler.sync(self) _la = self._input.LA(1) - self.state = 613 + self.state = 636 self.match(PyNestMLParser.RIGHT_PAREN) - self.state = 615 + self.state = 638 self._errHandler.sync(self) _la = self._input.LA(1) if (((_la) & ~0x3f) == 0 and ((1 << _la) & 562949953453056) != 0) or _la==89 or _la==90: - self.state = 614 + self.state = 637 localctx.returnType = self.dataType() - self.state = 617 + self.state = 640 self.match(PyNestMLParser.COLON) - self.state = 618 - self.block() + self.state = 641 + self.match(PyNestMLParser.NEWLINE) + self.state = 642 + self.match(PyNestMLParser.INDENT) + self.state = 643 + self.stmtsBody() + self.state = 644 + self.match(PyNestMLParser.DEDENT) except RecognitionException as re: localctx.exception = re self._errHandler.reportError(self, re) @@ -4501,9 +4657,9 @@ def parameter(self): self.enterRule(localctx, 90, self.RULE_parameter) try: self.enterOuterAlt(localctx, 1) - self.state = 620 + self.state = 646 self.match(PyNestMLParser.NAME) - self.state = 621 + self.state = 647 self.dataType() except RecognitionException as re: localctx.exception = re @@ -4563,11 +4719,11 @@ def constParameter(self): self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 623 + self.state = 649 localctx.name = self.match(PyNestMLParser.NAME) - self.state = 624 + self.state = 650 self.match(PyNestMLParser.EQUALS) - self.state = 625 + self.state = 651 localctx.value = self._input.LT(1) _la = self._input.LA(1) if not(_la==25 or ((((_la - 87)) & ~0x3f) == 0 and ((1 << (_la - 87)) & 27) != 0)): @@ -4589,7 +4745,7 @@ def sempred(self, localctx:RuleContext, ruleIndex:int, predIndex:int): if self._predicates == None: self._predicates = dict() self._predicates[1] = self.unitType_sempred - self._predicates[3] = self.expression_sempred + self._predicates[6] = self.expression_sempred pred = self._predicates.get(ruleIndex, None) if pred is None: raise Exception("No predicate with index:" + str(ruleIndex)) diff --git a/pynestml/generated/PyNestMLParserVisitor.py b/pynestml/generated/PyNestMLParserVisitor.py index dc4499256..77aedc6b3 100644 --- a/pynestml/generated/PyNestMLParserVisitor.py +++ b/pynestml/generated/PyNestMLParserVisitor.py @@ -24,6 +24,21 @@ def visitUnitTypeExponent(self, ctx:PyNestMLParser.UnitTypeExponentContext): return self.visitChildren(ctx) + # Visit a parse tree produced by PyNestMLParser#anyDecorator. + def visitAnyDecorator(self, ctx:PyNestMLParser.AnyDecoratorContext): + return self.visitChildren(ctx) + + + # Visit a parse tree produced by PyNestMLParser#namespaceDecoratorNamespace. + def visitNamespaceDecoratorNamespace(self, ctx:PyNestMLParser.NamespaceDecoratorNamespaceContext): + return self.visitChildren(ctx) + + + # Visit a parse tree produced by PyNestMLParser#namespaceDecoratorName. + def visitNamespaceDecoratorName(self, ctx:PyNestMLParser.NamespaceDecoratorNameContext): + return self.visitChildren(ctx) + + # Visit a parse tree produced by PyNestMLParser#expression. def visitExpression(self, ctx:PyNestMLParser.ExpressionContext): return self.visitChildren(ctx) @@ -79,11 +94,6 @@ def visitKernel(self, ctx:PyNestMLParser.KernelContext): return self.visitChildren(ctx) - # Visit a parse tree produced by PyNestMLParser#block. - def visitBlock(self, ctx:PyNestMLParser.BlockContext): - return self.visitChildren(ctx) - - # Visit a parse tree produced by PyNestMLParser#stmt. def visitStmt(self, ctx:PyNestMLParser.StmtContext): return self.visitChildren(ctx) @@ -114,18 +124,8 @@ def visitDeclaration_newline(self, ctx:PyNestMLParser.Declaration_newlineContext return self.visitChildren(ctx) - # Visit a parse tree produced by PyNestMLParser#anyDecorator. - def visitAnyDecorator(self, ctx:PyNestMLParser.AnyDecoratorContext): - return self.visitChildren(ctx) - - - # Visit a parse tree produced by PyNestMLParser#namespaceDecoratorNamespace. - def visitNamespaceDecoratorNamespace(self, ctx:PyNestMLParser.NamespaceDecoratorNamespaceContext): - return self.visitChildren(ctx) - - - # Visit a parse tree produced by PyNestMLParser#namespaceDecoratorName. - def visitNamespaceDecoratorName(self, ctx:PyNestMLParser.NamespaceDecoratorNameContext): + # Visit a parse tree produced by PyNestMLParser#stmtsBody. + def visitStmtsBody(self, ctx:PyNestMLParser.StmtsBodyContext): return self.visitChildren(ctx) diff --git a/pynestml/grammars/PyNestMLLexer.g4 b/pynestml/grammars/PyNestMLLexer.g4 index b5e36be4f..9b562117d 100644 --- a/pynestml/grammars/PyNestMLLexer.g4 +++ b/pynestml/grammars/PyNestMLLexer.g4 @@ -29,7 +29,7 @@ lexer grammar PyNestMLLexer; } // N.B. the zeroth channel is the normal channel, the first is HIDDEN, so COMMENT=2 - channels {COMMENT} + channels { COMMENT } DOCSTRING_TRIPLEQUOTE : '"""'; fragment NEWLINE_FRAG : '\r'? '\n'; // non-capturing newline, as a helper to define the channel rules @@ -43,21 +43,17 @@ lexer grammar PyNestMLLexer; DOCSTRING : DOCSTRING_TRIPLEQUOTE .*? DOCSTRING_TRIPLEQUOTE NEWLINE_FRAG+? -> channel(2); - SL_COMMENT: ('#' (~('\n' |'\r' ))*) -> channel(2); + SL_COMMENT : ('#' (~('\n' | '\r'))* ) -> channel(2); // we cannot capture the final \n here, because the comment might appear to the right of an expression - // newline is defined as a token - NEWLINE - : ( {self.atStartOfInput()}? WS - | ( '\r'? '\n' ) WS? - ) - {self.onNewLine()} - ; + // newline is handled inside the ``onNewLine()`` method of the PyNestMLLexerBase class + NEWLINE : ( { self.atStartOfInput() }? WS | ('\r'? '\n') WS? ) + { self.onNewLine() }; /** - * Symbols and literals are parsed first - * - * Decorator (@) keywords are defined with their @-symbol in front, because otherwise they would preclude the user from defining variables with the same name as a decorator keyword. (Rules are matched in the order in which they appear.) - */ + * Symbols and literals are parsed first + * + * Decorator (@) keywords are defined with their @-symbol in front, because otherwise they would preclude the user from defining variables with the same name as a decorator keyword. (Rules are matched in the order in which they appear.) + */ INTEGER_KEYWORD : 'integer'; REAL_KEYWORD : 'real'; @@ -142,16 +138,15 @@ lexer grammar PyNestMLLexer; /** - * Boolean values, i.e., true and false, should be handled as tokens in order to enable handling of lower - * and upper case definitions. Here, we allow both concepts, the python like syntax starting with upper case and - * the concept as currently used in NESTML with the lower case. - */ + * Boolean values, i.e., true and false, should be handled as tokens in order to enable handling of lower + * and upper case definitions. Here, we allow both concepts, the python like syntax starting with upper case and + * the concept as currently used in NESTML with the lower case. + */ BOOLEAN_LITERAL : 'true' | 'True' | 'false' | 'False' ; /** - * String literals are always enclosed in "...". - */ - + * String literals are always enclosed in double quotation marks. + */ STRING_LITERAL : '"' ('\\' (([ \t]+ ('\r'? '\n')?)|.) | ~[\\\r\n"])* '"'; NAME : ( [a-zA-Z] | '_' | '$' )( [a-zA-Z] | '_' | [0-9] | '$' )*; @@ -176,9 +171,8 @@ lexer grammar PyNestMLLexer; FLOAT : POINT_FLOAT | EXPONENT_FLOAT; fragment POINT_FLOAT : UNSIGNED_INTEGER? FULLSTOP UNSIGNED_INTEGER - | UNSIGNED_INTEGER FULLSTOP - ; + | UNSIGNED_INTEGER FULLSTOP; - fragment EXPONENT_FLOAT: ( UNSIGNED_INTEGER | POINT_FLOAT ) [eE] EXPONENT ; + fragment EXPONENT_FLOAT : ( UNSIGNED_INTEGER | POINT_FLOAT ) [eE] EXPONENT; - fragment EXPONENT: ( PLUS | MINUS )? UNSIGNED_INTEGER; + fragment EXPONENT : ( PLUS | MINUS )? UNSIGNED_INTEGER; diff --git a/pynestml/grammars/PyNestMLParser.g4 b/pynestml/grammars/PyNestMLParser.g4 index 5c5b4c270..26492e74c 100644 --- a/pynestml/grammars/PyNestMLParser.g4 +++ b/pynestml/grammars/PyNestMLParser.g4 @@ -25,16 +25,15 @@ parser grammar PyNestMLParser; options { tokenVocab = PyNestMLLexer; } - /********************************************************************************************************************* - * Units-Language - *********************************************************************************************************************/ + // ------------------------------------------------------------------------- + // Physical units and types + // ------------------------------------------------------------------------- /** - ASTDatatype. Represents predefined data types and gives a possibility to use an unit - data type. - @attribute boolean getters for integer, real, ... - @attribute unitType a SI data type - */ + * ASTDatatype. Represents predefined data types and gives a possibility to use an unit data type. + * @attribute boolean getters for integer, real, ... + * @attribute unitType a SI data type + **/ dataType : isInt=INTEGER_KEYWORD | isReal=REAL_KEYWORD | isString=STRING_KEYWORD @@ -42,9 +41,8 @@ parser grammar PyNestMLParser; | isVoid=VOID_KEYWORD | unit=unitType; /** - ASTUnitType. Represents an unit data type. It can be a plain data type as 'mV' or a - complex data type as 'mV/s' - */ + * ASTUnitType. Represents an unit data type. It can be a plain data type as 'mV' or a complex data type as 'mV/s' + **/ unitType : leftParentheses=LEFT_PAREN compoundUnit=unitType rightParentheses=RIGHT_PAREN | base=unitType powOp=STAR_STAR exponent=unitTypeExponent | left=unitType (timesOp=STAR | divOp=FORWARD_SLASH) right=unitType @@ -54,72 +52,94 @@ parser grammar PyNestMLParser; unitTypeExponent : ( PLUS | MINUS )? UNSIGNED_INTEGER; - /********************************************************************************************************************* - * Expressions-Language - *********************************************************************************************************************/ + // ------------------------------------------------------------------------- + // Decorators on equations, expressions, declarations, etc. + // ------------------------------------------------------------------------- - /** - ASTExpression, i.e., several subexpressions combined by one or more operators, - e.g., 10mV + V_m - (V_reset * 2)/ms, or a simple expression, e.g. 10mV. - */ - expression : leftParentheses=LEFT_PAREN term=expression rightParentheses=RIGHT_PAREN - | left=expression powOp=STAR_STAR right=expression - | unaryOperator term=expression - | left=expression (timesOp=STAR | divOp=FORWARD_SLASH | moduloOp=PERCENT) right=expression - | left=expression (plusOp=PLUS | minusOp=MINUS) right=expression - | left=expression bitOperator right=expression - | left=expression comparisonOperator right=expression - | logicalNot=NOT_KEYWORD term=expression - | left=expression logicalOperator right=expression - | condition=expression QUESTION ifTrue=expression COLON ifNot=expression - | simpleExpression - ; + anyDecorator : DECORATOR_HOMOGENEOUS + | DECORATOR_HETEROGENEOUS + | AT namespaceDecoratorNamespace DOUBLE_COLON namespaceDecoratorName; - /** - ASTSimpleExpression, consisting of a single element without combining operator, e.g., - 10mV, inf, V_m. - @attribute functionCall: A simple function call, e.g., myFunc(a,b) - @attribute BOOLEAN_LITERAL: A single boolean literal, e.g., True. - @attribute INTEGER: A integer number, e.g., 10. - @attribute FLOAT: A float number, e.g., 10.01. - @attribute variable: A optional variable representing the unit, e.g., ms, OR a single variable representing a reference, e.g. V_m. - @attribute isInf: True iff, this expression shall represent the value infinity. - */ - simpleExpression : functionCall - | BOOLEAN_LITERAL // true & false; - | (UNSIGNED_INTEGER | FLOAT) (variable)? - | string=STRING_LITERAL - | isInf=INF_KEYWORD - | variable; + namespaceDecoratorNamespace : name=NAME; + namespaceDecoratorName : name=NAME; - unaryOperator : (unaryPlus=PLUS | unaryMinus=MINUS | unaryTilde=TILDE); - bitOperator : (bitAnd=AMPERSAND | bitXor=CARET | bitOr=PIPE | bitShiftLeft=LEFT_LEFT_ANGLE | bitShiftRight=RIGHT_RIGHT_ANGLE); + // ------------------------------------------------------------------------- + // Expressions + // ------------------------------------------------------------------------- - comparisonOperator : (lt=LEFT_ANGLE | le=LEFT_ANGLE_EQUALS | eq=EQUALS_EQUALS | ne=EXCLAMATION_EQUALS | ne2=LEFT_ANGLE_RIGHT_ANGLE | ge=RIGHT_ANGLE_EQUALS | gt=RIGHT_ANGLE); + /** + * ASTExpression, i.e., several subexpressions combined by one or more operators, e.g. ``10mV + V_m - (V_reset * 2)/ms``, or a simple expression, e.g. ``10 mV``. + **/ + expression : leftParentheses=LEFT_PAREN term=expression rightParentheses=RIGHT_PAREN + | left=expression powOp=STAR_STAR right=expression + | unaryOperator term=expression + | left=expression (timesOp=STAR | divOp=FORWARD_SLASH | moduloOp=PERCENT) right=expression + | left=expression (plusOp=PLUS | minusOp=MINUS) right=expression + | left=expression bitOperator right=expression + | left=expression comparisonOperator right=expression + | logicalNot=NOT_KEYWORD term=expression + | left=expression logicalOperator right=expression + | condition=expression QUESTION ifTrue=expression COLON ifNot=expression + | simpleExpression; - logicalOperator : (logicalAnd=AND_KEYWORD | logicalOr=OR_KEYWORD ); + /** + * ASTSimpleExpression, consisting of a single element without combining operator, e.g. ``10 mV``, ``inf``, ``V_m``. + * @attribute functionCall: A simple function call, e.g., myFunc(a,b) + * @attribute BOOLEAN_LITERAL: A single boolean literal, e.g., True. + * @attribute INTEGER: A integer number, e.g., 10. + * @attribute FLOAT: A float number, e.g., 10.01. + * @attribute variable: A optional variable representing the unit, e.g., ms, OR a single variable representing a reference, e.g. V_m. + * @attribute isInf: True iff, this expression shall represent the value infinity. + **/ + simpleExpression : functionCall + | BOOLEAN_LITERAL // true & false; + | (UNSIGNED_INTEGER | FLOAT) (variable)? + | string=STRING_LITERAL + | isInf=INF_KEYWORD + | variable; + + unaryOperator : unaryPlus=PLUS + | unaryMinus=MINUS + | unaryTilde=TILDE; + + bitOperator : bitAnd=AMPERSAND + | bitXor=CARET + | bitOr=PIPE + | bitShiftLeft=LEFT_LEFT_ANGLE + | bitShiftRight=RIGHT_RIGHT_ANGLE; + + comparisonOperator : lt=LEFT_ANGLE + | le=LEFT_ANGLE_EQUALS + | eq=EQUALS_EQUALS + | ne=EXCLAMATION_EQUALS + | ne2=LEFT_ANGLE_RIGHT_ANGLE + | ge=RIGHT_ANGLE_EQUALS + | gt=RIGHT_ANGLE; + + logicalOperator : logicalAnd=AND_KEYWORD + | logicalOr=OR_KEYWORD; /** - ASTVariable Provides a 'marker' AST node to identify variables used in expressions. - @attribute name: The name of the variable without the differential order, e.g. V_m - @attribute vectorParameter: An optional array parameter, e.g., 'tau_syn ms[n_receptors]'. - @attribute differentialOrder: The corresponding differential order, e.g. 2 - */ + * ASTVariable Provides a 'marker' AST node to identify variables used in expressions. + * @attribute name: The name of the variable without the differential order, e.g. V_m + * @attribute vectorParameter: An optional array parameter, e.g., 'tau_syn ms[n_receptors]'. + * @attribute differentialOrder: The corresponding differential order, e.g. 2 + **/ variable : name=NAME - (LEFT_SQUARE_BRACKET vectorParameter=expression RIGHT_SQUARE_BRACKET)? - (DIFFERENTIAL_ORDER)*; + (LEFT_SQUARE_BRACKET vectorParameter=expression RIGHT_SQUARE_BRACKET)? + (DIFFERENTIAL_ORDER)*; /** - ASTFunctionCall Represents a function call, e.g. myFun("a", "b"). - @attribute calleeName: The (qualified) name of the functions - @attribute args: Comma separated list of expressions representing parameters. - */ + * ASTFunctionCall Represents a function call, e.g. myFun("a", "b"). + * @attribute calleeName: The (qualified) name of the functions + * @attribute args: Comma separated list of expressions representing parameters. + **/ functionCall : calleeName=NAME LEFT_PAREN (expression (COMMA expression)*)? RIGHT_PAREN; - /********************************************************************************************************************* - * Equations-Language - *********************************************************************************************************************/ + // ------------------------------------------------------------------------- + // Equations + // ------------------------------------------------------------------------- inlineExpression : (recordable=RECORDABLE_KEYWORD)? INLINE_KEYWORD variableName=NAME dataType EQUALS expression (SEMICOLON)? decorator=anyDecorator* NEWLINE; @@ -127,230 +147,215 @@ parser grammar PyNestMLParser; kernel : KERNEL_KEYWORD variable EQUALS expression (KERNEL_JOINING variable EQUALS expression)* SEMICOLON? NEWLINE; - /********************************************************************************************************************* - * Procedural-Language - *********************************************************************************************************************/ + // ------------------------------------------------------------------------- + // Procedural + // ------------------------------------------------------------------------- - block : NEWLINE INDENT stmt+ DEDENT; - - stmt : smallStmt | compoundStmt; + stmt : NEWLINE? (smallStmt | compoundStmt); compoundStmt : ifStmt - | forStmt - | whileStmt; + | forStmt + | whileStmt; smallStmt : (assignment - | functionCall - | declaration - | returnStmt) NEWLINE; + | functionCall + | declaration + | returnStmt) NEWLINE; assignment : lhs_variable=variable - (directAssignment=EQUALS | - compoundSum=PLUS_EQUALS | - compoundMinus=MINUS_EQUALS | - compoundProduct=STAR_EQUALS | - compoundQuotient=FORWARD_SLASH_EQUALS) + (directAssignment=EQUALS + | compoundSum=PLUS_EQUALS + | compoundMinus=MINUS_EQUALS + | compoundProduct=STAR_EQUALS + | compoundQuotient=FORWARD_SLASH_EQUALS) expression; - /** ASTDeclaration A variable declaration. It can be a simple declaration defining one or multiple variables: - 'a,b,c real = 0'. Or an function declaration 'function a = b + c'. - @attribute isRecordable: Is true iff. declaration is recordable. - @attribute isInlineExpression: Is true iff. declaration is an inline expression. - @attribute variable: List with variables. - @attribute datatype: Obligatory data type, e.g., 'real' or 'mV/s'. - @attribute rhs: An optional initial expression, e.g., 'a real = 10+10' - @attribute invariant: A single, optional invariant expression, e.g., '[a < 21]' - */ - declaration : - (isRecordable=RECORDABLE_KEYWORD)? (isInlineExpression=INLINE_KEYWORD)? - variable (COMMA variable)* - dataType - ( EQUALS rhs = expression)? - (LEFT_LEFT_SQUARE invariant=expression RIGHT_RIGHT_SQUARE)? - decorator=anyDecorator*; - - declaration_newline: declaration NEWLINE; - - /** ... - */ - anyDecorator : DECORATOR_HOMOGENEOUS | DECORATOR_HETEROGENEOUS | AT namespaceDecoratorNamespace DOUBLE_COLON namespaceDecoratorName; + /** + * ASTDeclaration A variable declaration. It can be a simple declaration defining one or multiple variables (``a,b,c real = 0``), or an function declaration ``function a = b + c``. + * @attribute isRecordable: Is true iff. declaration is recordable. + * @attribute isInlineExpression: Is true iff. declaration is an inline expression. + * @attribute variable: List with variables. + * @attribute datatype: Obligatory data type, e.g., 'real' or 'mV/s'. + * @attribute rhs: An optional initial expression, e.g., 'a real = 10+10' + * @attribute invariant: A single, optional invariant expression, e.g., '[a < 21]' + **/ + declaration : (isRecordable=RECORDABLE_KEYWORD)? (isInlineExpression=INLINE_KEYWORD)? + variable (COMMA variable)* + dataType + (EQUALS rhs = expression)? + (LEFT_LEFT_SQUARE invariant=expression RIGHT_RIGHT_SQUARE)? + decorator=anyDecorator*; + + declaration_newline : declaration NEWLINE; /** - ASTVariable Provides a 'marker' AST node to identify variables used in expressions. - @attribute name: The name of the variable without the differential order, e.g. V_m - @attribute differentialOrder: The corresponding differential order, e.g. 2 - */ - namespaceDecoratorNamespace : name=NAME; - namespaceDecoratorName : name=NAME; + * ASTStmtsBody A sequence of statements. + **/ + stmtsBody : stmt+; - /** ASTReturnStmt Models the return statement in a function. - @expression An optional return expression, e.g., return tempVar - */ + /** + * ASTReturnStmt Models the return statement in a function. + * @expression An optional return expression + **/ returnStmt : RETURN_KEYWORD expression?; - ifStmt : ifClause - elifClause* - (elseClause)?; - - ifClause : IF_KEYWORD expression COLON block; - - elifClause : ELIF_KEYWORD expression COLON block; - - elseClause : ELSE_KEYWORD COLON block; - - forStmt : FOR_KEYWORD var=NAME IN_KEYWORD start_from=expression ELLIPSIS end_at=expression STEP_KEYWORD - (negative=MINUS?) (UNSIGNED_INTEGER | FLOAT) - COLON - block; - - whileStmt : WHILE_KEYWORD expression COLON block; - - /********************************************************************************************************************* - * NestML: language root element - *********************************************************************************************************************/ - - /** ASTNestMLCompilationUnit represents a collection of models. - @attribute model: A list of processed models. - */ - nestMLCompilationUnit: ( model | NEWLINE )+ EOF; - -/********************************************************************************************************************* - * NestML model and model blocks - *********************************************************************************************************************/ - - /** ASTModel Represents a single dynamical system model, such as a neuron or a synapse. - @attribute Name: The name of the model, e.g., ht_neuron. - @attribute body: The body of the model consisting of several sub-blocks. - */ - model : MODEL_KEYWORD NAME modelBody; - - /** ASTBody The body of the model, e.g. internal, state, parameter... - @attribute blockWithVariables: A single block of variables, e.g. the state block. - @attribute equationsBlock: A block of ode declarations. - @attribute inputBlock: A block of input port declarations. - @attribute outputBlock: A block of output declarations. - @attribute updateBlock: A single update block containing the dynamic behavior. - @attribute function: A block declaring a user-defined function. - */ - modelBody: COLON - NEWLINE INDENT ( blockWithVariables | equationsBlock | inputBlock | outputBlock | function | onReceiveBlock | onConditionBlock | updateBlock )+ DEDENT; - - /** ASTOnReceiveBlock - @attribute block implementation of the dynamics - */ - onReceiveBlock: ON_RECEIVE_KEYWORD LEFT_PAREN inputPortName=NAME (COMMA constParameter)* RIGHT_PAREN COLON - block; - - /** ASTOnConditionBlock - @attribute block implementation of the dynamics - */ - onConditionBlock: ON_CONDITION_KEYWORD LEFT_PAREN condition=expression (COMMA constParameter)* RIGHT_PAREN COLON - block; - - /** ASTBlockWithVariables Represent a block with variables and constants, e.g.: - state: - y0, y1, y2, y3 mV [y1 > 0; y2 > 0] - - @attribute state: True iff the varblock is a state. - @attribute parameters: True iff the varblock is a parameters block. - @attribute internals: True iff the varblock is a state internals block. - @attribute declaration: A list of corresponding declarations. - */ - blockWithVariables: - blockType=(STATE_KEYWORD | PARAMETERS_KEYWORD | INTERNALS_KEYWORD) - COLON - NEWLINE INDENT declaration_newline+ DEDENT; - - /** ASTUpdateBlock The definition of a block where the dynamical behavior of the neuron is stated: - update: - if r == 0: # not refractory - integrate(V) - @attribute block Implementation of the dynamics. - */ - updateBlock: UPDATE_KEYWORD COLON - block; - - /** ASTEquationsBlock A block declaring equations and inline expressions. - @attribute inlineExpression: A single inline expression, e.g., inline V_m mV = ... - @attribute odeEquation: A single ode equation statement, e.g., V_m' = ... - */ - equationsBlock: EQUATIONS_KEYWORD COLON + ifStmt : ifClause elifClause* (elseClause)?; + + ifClause : IF_KEYWORD expression COLON + NEWLINE INDENT stmtsBody DEDENT; + + elifClause : ELIF_KEYWORD expression COLON + NEWLINE INDENT stmtsBody DEDENT; + + elseClause : ELSE_KEYWORD COLON + NEWLINE INDENT stmtsBody DEDENT; + + forStmt : FOR_KEYWORD var=NAME IN_KEYWORD start_from=expression ELLIPSIS end_at=expression STEP_KEYWORD (negative=MINUS?) (UNSIGNED_INTEGER | FLOAT) COLON + NEWLINE INDENT stmtsBody DEDENT; + + whileStmt : WHILE_KEYWORD expression COLON + NEWLINE INDENT stmtsBody DEDENT; + + // ------------------------------------------------------------------------- + // NESTML language root element + // ------------------------------------------------------------------------- + + /** + * ASTNestMLCompilationUnit represents a collection of models. + * @attribute model: A list of processed models. + **/ + nestMLCompilationUnit : ( model | NEWLINE )+ EOF; + + // ------------------------------------------------------------------------- + // NESTML model and model blocks + // ------------------------------------------------------------------------- + + /** + * ASTModel Represents a single dynamical system model, such as a neuron or a synapse. + * @attribute NAME: The name of the model, e.g., ht_neuron. + * @attribute modelBody: The body of the model consisting of several sub-blocks. + **/ + model : MODEL_KEYWORD NAME COLON + modelBody; + + /** + * ASTBody The body of the model, e.g. internal, state, parameter... + * @attribute blockWithVariables: A single block of variables, e.g. the state block. + * @attribute equationsBlock: A block of ode declarations. + * @attribute inputBlock: A block of input port declarations. + * @attribute outputBlock: A block of output declarations. + * @attribute function: A block declaring a user-defined function. + * @attribute onReceiveBlock: A block declaring event handler statements. + * @attribute onConditionBlock: A block declaring condition statements. + * @attribute updateBlock: A single update block containing the dynamic behavior. + **/ + modelBody : NEWLINE INDENT ( blockWithVariables | equationsBlock | inputBlock | outputBlock | function | onReceiveBlock | onConditionBlock | updateBlock )+ DEDENT; + + /** + * ASTOnReceiveBlock + * @attribute stmtsBody implementation of the dynamics + **/ + onReceiveBlock : ON_RECEIVE_KEYWORD LEFT_PAREN inputPortName=NAME (COMMA constParameter)* RIGHT_PAREN COLON + NEWLINE INDENT stmtsBody DEDENT; + + /** + * ASTOnConditionBlock + * @attribute stmtsBody implementation of the dynamics + **/ + onConditionBlock : ON_CONDITION_KEYWORD LEFT_PAREN condition=expression (COMMA constParameter)* RIGHT_PAREN COLON + NEWLINE INDENT stmtsBody DEDENT; + + /** + * ASTBlockWithVariables Represent a block with variables and constants + * @attribute state: True iff the varblock is a state block. + * @attribute parameters: True iff the varblock is a parameters block. + * @attribute internals: True iff the varblock is a state internals block. + * @attribute declaration: A list of corresponding declarations. + **/ + blockWithVariables : blockType=(STATE_KEYWORD | PARAMETERS_KEYWORD | INTERNALS_KEYWORD) COLON + NEWLINE INDENT declaration_newline+ DEDENT; + + /** + * ASTUpdateBlock The definition of a block where the dynamical behavior of the neuron is stated. + * @attribute stmtsBody Implementation of the dynamics. + **/ + updateBlock : UPDATE_KEYWORD COLON + NEWLINE INDENT stmtsBody DEDENT; + + /** + * ASTEquationsBlock A block declaring equations, kernels and inline expressions. + * @attribute inlineExpression: A single inline expression definition. + * @attribute odeEquation: A single ODE definition. + * @attribute kernel: A single kernel definition. + **/ + equationsBlock : EQUATIONS_KEYWORD COLON NEWLINE INDENT ( inlineExpression | odeEquation | kernel )+ DEDENT; - /** ASTInputBlock represents a single input block, e.g.: - input: - spike_in <- excitatory spike - current_in pA <- continuous - @attribute inputPort: A list of input ports. - */ - inputBlock: INPUT_KEYWORD COLON - NEWLINE INDENT ((spikeInputPort | continuousInputPort) (LEFT_PAREN (parameter (COMMA parameter)*)? RIGHT_PAREN)?)+ DEDENT; - - /** ASTInputPort represents a single input port, e.g.: - spike_in[3] <- excitatory spike - I_stim[3] pA <- continuous - @attribute name: The name of the input port. - @attribute sizeParameter: Optional size parameter for model with multiple input ports. - @attribute datatype: Optional data type of the port. - @attribute inputQualifier: The qualifier keyword of the input port, to indicate e.g. inhibitory-only or excitatory-only spiking inputs on this port. - @attribute isSpike: Indicates that this input port accepts spikes. - @attribute isContinuous: Indicates that this input port accepts continuous-time input. - */ - spikeInputPort: - name=NAME - (LEFT_SQUARE_BRACKET sizeParameter=expression RIGHT_SQUARE_BRACKET)? - LEFT_ANGLE_MINUS inputQualifier* - SPIKE_KEYWORD NEWLINE; - - continuousInputPort: - name = NAME - (LEFT_SQUARE_BRACKET sizeParameter=expression RIGHT_SQUARE_BRACKET)? - dataType - LEFT_ANGLE_MINUS CONTINUOUS_KEYWORD NEWLINE; - - - /** ASTInputQualifier represents the qualifier of an inputPort. Only valid for spiking inputs. - @attribute isInhibitory: Indicates that this spiking input port is inhibitory. - @attribute isExcitatory: Indicates that this spiking input port is excitatory. - */ - inputQualifier : (isInhibitory=INHIBITORY_KEYWORD | isExcitatory=EXCITATORY_KEYWORD); - - /** ASTOutputBlock Represents the output block of the neuron, i.e., declarations of output ports: - output: - spike - @attribute isSpike: true if and only if the neuron has a spike output. - @attribute isContinuous: true if and only if the neuron has a continuous-time output. - */ - outputBlock: OUTPUT_KEYWORD COLON - NEWLINE INDENT ((isSpike=SPIKE_KEYWORD (LEFT_PAREN (attribute=parameter (COMMA attribute=parameter)*)? RIGHT_PAREN)?) | isContinuous=CONTINUOUS_KEYWORD) - NEWLINE DEDENT; - - /** ASTFunction A single declaration of a user-defined function definition: - function set_V_m(v mV): - y3 = v - E_L - @attribute name: The name of the function. - @attribute parameters: List with function parameters. - @attribute returnType: An arbitrary return type, e.g. string or mV. - @attribute block: Implementation of the function. - */ - function: FUNCTION_KEYWORD NAME LEFT_PAREN (parameter (COMMA parameter)*)? RIGHT_PAREN (returnType=dataType)? - COLON - block - ; - - /** ASTParameter represents a single parameter consisting of a name and the corresponding - data type, e.g. T_in ms - @attribute name: The name of the parameter. - @attribute dataType: The corresponding data type. - */ + /** + * ASTInputBlock represents a single input block. + * @attribute spikeInputPort: A list of spiking input ports. + * @attribute continuousInputPort: A list of continous-time input ports. + **/ + inputBlock : INPUT_KEYWORD COLON + NEWLINE INDENT ((spikeInputPort | continuousInputPort) (LEFT_PAREN (parameter (COMMA parameter)*)? RIGHT_PAREN)?)+ DEDENT; + + /** + * ASTInputPort represents a single input port. + * @attribute name: The name of the input port. + * @attribute sizeParameter: Optional size parameter for model with multiple input ports. + * @attribute datatype: Optional data type of the port. + * @attribute inputQualifier: The qualifier keyword of the input port, to indicate e.g. inhibitory-only or excitatory-only spiking inputs on this port. + **/ + spikeInputPort : name=NAME + (LEFT_SQUARE_BRACKET sizeParameter=expression RIGHT_SQUARE_BRACKET)? + LEFT_ANGLE_MINUS inputQualifier* + SPIKE_KEYWORD NEWLINE; + + continuousInputPort : name = NAME + (LEFT_SQUARE_BRACKET sizeParameter=expression RIGHT_SQUARE_BRACKET)? + dataType + LEFT_ANGLE_MINUS CONTINUOUS_KEYWORD NEWLINE; + + /** + * ASTInputQualifier represents the qualifier of an inputPort. Only valid for spiking inputs. + * @attribute isInhibitory: Indicates that this spiking input port is inhibitory. + * @attribute isExcitatory: Indicates that this spiking input port is excitatory. + **/ + inputQualifier : isInhibitory=INHIBITORY_KEYWORD | isExcitatory=EXCITATORY_KEYWORD; + + /** + * ASTOutputBlock Represents the output block of the model, i.e., declarations of output ports. + * @attribute isSpike: true if and only if the model has a spike output. + * @attribute isContinuous: true if and only if the model has a continuous-time output. + **/ + outputBlock : OUTPUT_KEYWORD COLON + NEWLINE INDENT ((isSpike=SPIKE_KEYWORD (LEFT_PAREN (attribute=parameter (COMMA attribute=parameter)*)? RIGHT_PAREN)?) | isContinuous=CONTINUOUS_KEYWORD) + NEWLINE DEDENT; + + /** + * ASTFunction A single declaration of a user-defined function definition. + * @attribute name: The name of the function. + * @attribute parameters: List with function parameters. + * @attribute returnType: An arbitrary return type, e.g. string or mV. + * @attribute stmtsBody: Implementation of the function. + **/ + function: FUNCTION_KEYWORD NAME LEFT_PAREN (parameter (COMMA parameter)*)? RIGHT_PAREN (returnType=dataType)? COLON + NEWLINE INDENT stmtsBody DEDENT; + + /** + * ASTParameter represents a single parameter consisting of a name and the corresponding data type, e.g. ``T_in ms``. + * @attribute NAME: The name of the parameter. + * @attribute dataType: The corresponding data type. + **/ parameter : NAME dataType; - /** ASTConstParameter represents a single parameter consisting of a name and a literal default value, e.g. "foo=42". - @attribute name: The name of the parameter. - @attribute value: The corresponding default value. - */ + /** + * ASTConstParameter represents a single parameter consisting of a name and a literal default value, e.g. ``foo=42``. + * @attribute name: The name of the parameter. + * @attribute value: The corresponding default value. + **/ constParameter : name=NAME EQUALS value=(BOOLEAN_LITERAL - | UNSIGNED_INTEGER - | FLOAT - | STRING_LITERAL - | INF_KEYWORD); + | UNSIGNED_INTEGER + | FLOAT + | STRING_LITERAL + | INF_KEYWORD); diff --git a/pynestml/meta_model/ast_elif_clause.py b/pynestml/meta_model/ast_elif_clause.py index 1165cd3b7..8332409ca 100644 --- a/pynestml/meta_model/ast_elif_clause.py +++ b/pynestml/meta_model/ast_elif_clause.py @@ -20,21 +20,18 @@ # along with NEST. If not, see . from typing import List +from pynestml.meta_model.ast_expression import ASTExpression from pynestml.meta_model.ast_node import ASTNode +from pynestml.meta_model.ast_stmts_body import ASTStmtsBody class ASTElifClause(ASTNode): - """ + r""" This class is used to store elif-clauses. - Grammar: - elifClause : 'elif' rhs BLOCK_OPEN block; - Attribute: - condition = None - block = None """ - def __init__(self, condition, block, *args, **kwargs): + def __init__(self, condition, stmts_body: ASTStmtsBody, *args, **kwargs): """ Standard constructor. @@ -42,11 +39,10 @@ def __init__(self, condition, block, *args, **kwargs): :param condition: the condition of the block. :type condition: ast_expression - :param block: a block of statements. - :type block: ast_block + :param stmts_body: a body of statements. """ super(ASTElifClause, self).__init__(*args, **kwargs) - self.block = block + self.stmts_body = stmts_body self.condition = condition def clone(self): @@ -56,13 +52,13 @@ def clone(self): :return: new AST node instance :rtype: ASTElifClause """ - block_dup = None - if self.block: - block_dup = self.block.clone() + stmts_body_dup = None + if self.stmts_body: + stmts_body_dup = self.stmts_body.clone() condition_dup = None if self.condition: condition_dup = self.condition.clone() - dup = ASTElifClause(block=block_dup, + dup = ASTElifClause(stmts_body=stmts_body_dup, condition=condition_dup, # ASTNode common attributes: source_position=self.source_position, @@ -74,21 +70,19 @@ def clone(self): return dup - def get_condition(self): + def get_condition(self) -> ASTExpression: """ - Returns the condition of the block. + Returns the condition of the elif. :return: the condition. - :rtype: ast_expression """ return self.condition - def get_block(self): + def get_stmts_body(self) -> ASTStmtsBody: """ - Returns the block of statements. - :return: the block of statements. - :rtype: ast_block + Returns the body of statements. + :return: the body of statements. """ - return self.block + return self.stmts_body def get_children(self) -> List[ASTNode]: r""" @@ -99,8 +93,8 @@ def get_children(self) -> List[ASTNode]: if self.get_condition(): children.append(self.get_condition()) - if self.get_block(): - children.append(self.get_block()) + if self.get_stmts_body(): + children.append(self.get_stmts_body()) return children @@ -111,4 +105,4 @@ def equals(self, other: ASTNode) -> bool: if not isinstance(other, ASTElifClause): return False - return self.get_condition().equals(other.get_condition()) and self.get_block().equals(other.get_block()) + return self.get_condition().equals(other.get_condition()) and self.get_stmts_body().equals(other.get_stmts_body()) diff --git a/pynestml/meta_model/ast_else_clause.py b/pynestml/meta_model/ast_else_clause.py index 55bd8fdea..a6c604107 100644 --- a/pynestml/meta_model/ast_else_clause.py +++ b/pynestml/meta_model/ast_else_clause.py @@ -22,28 +22,24 @@ from typing import List from pynestml.meta_model.ast_node import ASTNode +from pynestml.meta_model.ast_stmts_body import ASTStmtsBody class ASTElseClause(ASTNode): - """ + r""" This class is used to store a single else-clause. - Grammar: - elseClause : 'else' BLOCK_OPEN block; - Attributes: - block = None """ - def __init__(self, block, *args, **kwargs): + def __init__(self, stmts_body: ASTStmtsBody, *args, **kwargs): """ Standard constructor. Parameters for superclass (ASTNode) can be passed through :python:`*args` and :python:`**kwargs`. - :param block: a block of statements. - :type block: ast_block + :param stmts_body: a body of statements. """ super(ASTElseClause, self).__init__(*args, **kwargs) - self.block = block + self.stmts_body = stmts_body def clone(self): """ @@ -52,10 +48,10 @@ def clone(self): :return: new AST node instance :rtype: ASTElseClause """ - block_dup = None - if self.block: - block_dup = self.block.clone() - dup = ASTElseClause(block=block_dup, + stmts_body_dup = None + if self.stmts_body: + stmts_body_dup = self.stmts_body.clone() + dup = ASTElseClause(stmts_body=stmts_body_dup, # ASTNode common attributes: source_position=self.source_position, scope=self.scope, @@ -66,21 +62,20 @@ def clone(self): return dup - def get_block(self): + def get_stmts_body(self) -> ASTStmtsBody: """ - Returns the block of statements. - :return: the block of statements. - :rtype: ast_block + Returns the body of statements. + :return: the body of statements. """ - return self.block + return self.stmts_body def get_children(self) -> List[ASTNode]: r""" Returns the children of this node, if any. :return: List of children of this node. """ - if self.get_block(): - return [self.get_block()] + if self.get_stmts_body(): + return [self.get_stmts_body()] return [] @@ -91,4 +86,4 @@ def equals(self, other: ASTNode) -> bool: if not isinstance(other, ASTElseClause): return False - return self.get_block().equals(other.get_block()) + return self.get_stmts_body().equals(other.get_stmts_body()) diff --git a/pynestml/meta_model/ast_for_stmt.py b/pynestml/meta_model/ast_for_stmt.py index 399071d01..191bf6cd9 100644 --- a/pynestml/meta_model/ast_for_stmt.py +++ b/pynestml/meta_model/ast_for_stmt.py @@ -22,23 +22,15 @@ from typing import List from pynestml.meta_model.ast_node import ASTNode +from pynestml.meta_model.ast_stmts_body import ASTStmtsBody class ASTForStmt(ASTNode): - """ - This class is used to store a for-block. - Grammar: - forStmt : 'for' var=NAME 'in' vrom=rhs - '...' to=rhs 'step' step=signedNumericLiteral BLOCK_OPEN block BLOCK_CLOSE; - Attributes: - variable = None - start_from = None - end_at = None - step = None - block = None + r""" + This class is used to store a "for" statement. """ - def __init__(self, variable, start_from, end_at, step, block, *args, **kwargs): + def __init__(self, variable, start_from, end_at, step, stmts_body: ASTStmtsBody, *args, **kwargs): """ Standard constructor. @@ -52,15 +44,14 @@ def __init__(self, variable, start_from, end_at, step, block, *args, **kwargs): :type end_at: ast_expression :param step: the length of a single step. :type step: float/int - :param block: a block of statements. - :type block: ast_block + :param stmts_body: a body of statements. """ super(ASTForStmt, self).__init__(*args, **kwargs) - self.block = block - self.step = step - self.end_at = end_at - self.start_from = start_from self.variable = variable + self.start_from = start_from + self.end_at = end_at + self.step = step + self.stmts_body = stmts_body def clone(self): """ @@ -81,14 +72,14 @@ def clone(self): step_dup = None if self.step: step_dup = self.step - block_dup = None - if self.block: - block_dup = self.block.clone() + stmts_body_dup = None + if self.stmts_body: + stmts_body_dup = self.stmts_body.clone() dup = ASTForStmt(variable=variable_dup, start_from=start_from_dup, end_at=end_at_dup, step=step_dup, - block=block_dup, + stmts_body=stmts_body_dup, # ASTNode common attributes: source_position=self.source_position, scope=self.scope, @@ -131,13 +122,12 @@ def get_step(self): """ return self.step - def get_block(self): + def get_stmts_body(self) -> ASTStmtsBody: """ - Returns the block of statements. - :return: the block of statements. - :rtype: ast_block + Returns the body of statements. + :return: the body of statements. """ - return self.block + return self.stmts_body def get_children(self) -> List[ASTNode]: r""" @@ -151,8 +141,8 @@ def get_children(self) -> List[ASTNode]: if self.get_end_at(): children.append(self.get_end_at()) - if self.get_block(): - children.append(self.get_block()) + if self.get_stmts_body(): + children.append(self.get_stmts_body()) return children @@ -170,4 +160,4 @@ def equals(self, other: ASTNode) -> bool: return False if self.get_step() != other.get_step(): return False - return self.get_block().equals(other.get_block()) + return self.get_stmts_body().equals(other.get_stmts_body()) diff --git a/pynestml/meta_model/ast_function.py b/pynestml/meta_model/ast_function.py index 842c086ad..989a7dfae 100644 --- a/pynestml/meta_model/ast_function.py +++ b/pynestml/meta_model/ast_function.py @@ -23,7 +23,7 @@ from copy import copy -from pynestml.meta_model.ast_block import ASTBlock +from pynestml.meta_model.ast_stmts_body import ASTStmtsBody from pynestml.meta_model.ast_data_type import ASTDataType from pynestml.meta_model.ast_node import ASTNode from pynestml.meta_model.ast_parameter import ASTParameter @@ -54,7 +54,7 @@ class ASTFunction(ASTNode): type_symbol = None """ - def __init__(self, name: str, parameters: List[ASTParameter], return_type: Optional[ASTDataType], block: ASTBlock, type_symbol=None, *args, **kwargs): + def __init__(self, name: str, parameters: List[ASTParameter], return_type: Optional[ASTDataType], stmts_body: ASTStmtsBody, type_symbol=None, *args, **kwargs): """ Standard constructor. @@ -63,13 +63,13 @@ def __init__(self, name: str, parameters: List[ASTParameter], return_type: Optio :param name: the name of the defined function. :param parameters: (Optional) Set of parameters. :param return_type: (Optional) Return type. - :param block: a block of declarations. + :param stmts_body: a body of declarations. """ super(ASTFunction, self).__init__(*args, **kwargs) - self.block = block - self.return_type = return_type - self.parameters = parameters self.name = name + self.parameters = parameters + self.return_type = return_type + self.stmts_body = stmts_body self.type_symbol = type_symbol def clone(self): @@ -79,9 +79,9 @@ def clone(self): :return: new AST node instance :rtype: ASTFunction """ - block_dup = None - if self.block: - block_dup = self.block.clone() + stmts_body_dup = None + if self.stmts_body: + stmts_body_dup = self.stmts_body.clone() return_type_dup = None if self.return_type: return_type_dup = self.return_type.clone() @@ -90,7 +90,7 @@ def clone(self): dup = ASTFunction(name=self.name, parameters=parameters_dup, return_type=return_type_dup, - block=block_dup, + stmts_body=stmts_body_dup, type_symbol=self.type_symbol, # ASTNode common attributes: source_position=self.source_position, @@ -140,13 +140,12 @@ def get_return_type(self): """ return self.return_type - def get_block(self): + def get_stmts_body(self) -> ASTStmtsBody: """ - Returns the block containing the definitions. - :return: the block of the definitions. - :rtype: ast_block + Returns the body containing the statements. + :return: the body """ - return self.block + return self.stmts_body def get_type_symbol(self): """ @@ -175,8 +174,8 @@ def get_children(self) -> List[ASTNode]: if self.has_return_type(): children.append(self.get_return_type()) - if self.get_block(): - children.append(self.get_block()) + if self.get_stmts_body(): + children.append(self.get_stmts_body()) return children @@ -206,4 +205,4 @@ def equals(self, other: ASTNode) -> bool: and not self.get_return_type().equals(other.get_return_type())): return False - return self.get_block().equals(other.get_block()) + return self.get_stmts_body().equals(other.get_stmts_body()) diff --git a/pynestml/meta_model/ast_if_clause.py b/pynestml/meta_model/ast_if_clause.py index 36b8cdc9b..999485f9b 100644 --- a/pynestml/meta_model/ast_if_clause.py +++ b/pynestml/meta_model/ast_if_clause.py @@ -22,19 +22,15 @@ from typing import List from pynestml.meta_model.ast_node import ASTNode +from pynestml.meta_model.ast_stmts_body import ASTStmtsBody class ASTIfClause(ASTNode): - """ - This class is used to store a single if-clause. - Grammar: - ifClause : 'if' expr BLOCK_OPEN block; - Attributes: - condition = None - block = None + r""" + This class is used to store a single ``if``-clause. """ - def __init__(self, condition, block, *args, **kwargs): + def __init__(self, condition, stmts_body: ASTStmtsBody, *args, **kwargs): """ Standard constructor. @@ -43,11 +39,10 @@ def __init__(self, condition, block, *args, **kwargs): :param condition: the condition of the block. :type condition: ASTExpression :param block: a block of statements. - :type block: ASTBlock """ super(ASTIfClause, self).__init__(*args, **kwargs) - self.block = block self.condition = condition + self.stmts_body = stmts_body def clone(self): """ @@ -56,14 +51,14 @@ def clone(self): :return: new AST node instance :rtype: ASTIfClause """ - block_dup = None - if self.block: - block_dup = self.block.clone() + stmts_body_dup = None + if self.stmts_body: + stmts_body_dup = self.stmts_body.clone() condition_dup = None if self.condition: condition_dup = self.condition.clone() dup = ASTIfClause(condition=condition_dup, - block=block_dup, + stmts_body=stmts_body_dup, # ASTNode common attributes: source_position=self.source_position, scope=self.scope, @@ -76,19 +71,18 @@ def clone(self): def get_condition(self): """ - Returns the condition of the block. + Returns the condition of the if statement. :return: the condition. :rtype: ASTExpression """ return self.condition - def get_block(self): + def get_stmts_body(self) -> ASTStmtsBody: """ - Returns the block of statements. - :return: the block of statements. - :rtype: ASTBlock + Returns the body of statements. + :return: the body of statements. """ - return self.block + return self.stmts_body def get_children(self) -> List[ASTNode]: r""" @@ -100,8 +94,8 @@ def get_children(self) -> List[ASTNode]: if self.get_condition(): children.append(self.get_condition()) - if self.get_block(): - children.append(self.get_block()) + if self.get_stmts_body(): + children.append(self.get_stmts_body()) return children @@ -111,4 +105,4 @@ def equals(self, other: ASTNode) -> bool: """ if not isinstance(other, ASTIfClause): return False - return self.get_condition().equals(other.get_condition()) and self.get_block().equals(other.get_block()) + return self.get_condition().equals(other.get_condition()) and self.get_stmts_body().equals(other.get_stmts_body()) diff --git a/pynestml/meta_model/ast_node_factory.py b/pynestml/meta_model/ast_node_factory.py index 781d75f9e..63775f023 100644 --- a/pynestml/meta_model/ast_node_factory.py +++ b/pynestml/meta_model/ast_node_factory.py @@ -24,7 +24,7 @@ from pynestml.meta_model.ast_arithmetic_operator import ASTArithmeticOperator from pynestml.meta_model.ast_assignment import ASTAssignment from pynestml.meta_model.ast_bit_operator import ASTBitOperator -from pynestml.meta_model.ast_block import ASTBlock +from pynestml.meta_model.ast_stmts_body import ASTStmtsBody from pynestml.meta_model.ast_block_with_variables import ASTBlockWithVariables from pynestml.meta_model.ast_comparison_operator import ASTComparisonOperator from pynestml.meta_model.ast_compound_stmt import ASTCompoundStmt @@ -101,8 +101,8 @@ def create_ast_bit_operator(cls, is_bit_and=False, is_bit_xor=False, is_bit_or=F @classmethod def create_ast_block(cls, stmts, source_position): - # type: (list(ASTSmallStmt|ASTCompoundStmt),ASTSourceLocation) -> ASTBlock - return ASTBlock(stmts, source_position=source_position) + # type: (list(ASTSmallStmt|ASTCompoundStmt),ASTSourceLocation) -> ASTStmtsBody + return ASTStmtsBody(stmts, source_position=source_position) @classmethod def create_ast_block_with_variables(cls, is_state=False, is_parameters=False, is_internals=False, @@ -162,12 +162,12 @@ def create_ast_declaration(cls, @classmethod def create_ast_elif_clause(cls, condition, block, source_position=None): - # type: (ASTExpression|ASTSimpleExpression,ASTBlock,ASTSourceLocation) -> ASTElifClause + # type: (ASTExpression|ASTSimpleExpression,ASTStmtsBody,ASTSourceLocation) -> ASTElifClause return ASTElifClause(condition, block, source_position=source_position) @classmethod def create_ast_else_clause(cls, block, source_position): - # type: (ASTBlock,ASTSourceLocation) -> ASTElseClause + # type: (ASTStmtsBody,ASTSourceLocation) -> ASTElseClause return ASTElseClause(block, source_position=source_position) @classmethod @@ -222,14 +222,14 @@ def create_ast_for_stmt(cls, start_from, # type: Union(ASTSimpleExpression,ASTExpression) end_at, # type: Union(ASTSimpleExpression,ASTExpression) step=0, # type: float - block=None, # type: ASTBlock + block=None, # type: ASTStmtsBody source_position=None # type: ASTSourceLocation ): # type: (...) -> ASTForStmt return ASTForStmt(variable, start_from, end_at, step, block, source_position=source_position) @classmethod def create_ast_function(cls, name, parameters, return_type, block, source_position): - # type: (str,(None|list(ASTParameter)),(ASTDataType|None),ASTBlock,ASTSourceLocation) -> ASTFunction + # type: (str,(None|list(ASTParameter)),(ASTDataType|None),ASTStmtsBody,ASTSourceLocation) -> ASTFunction return ASTFunction(name, parameters, return_type, block, source_position=source_position) @classmethod @@ -239,7 +239,7 @@ def create_ast_function_call(cls, callee_name, args, source_position=None): @classmethod def create_ast_if_clause(cls, condition, block, source_position): - # type: (ASTSimpleExpression|ASTExpression,ASTBlock,ASTSourceLocation) -> ASTIfClause + # type: (ASTSimpleExpression|ASTExpression,ASTStmtsBody,ASTSourceLocation) -> ASTIfClause return ASTIfClause(condition, block, source_position=source_position) @classmethod @@ -355,7 +355,7 @@ def create_ast_unit_type(cls, @classmethod def create_ast_update_block(cls, block, source_position): - # type: (ASTBlock,ASTSourceLocation) -> ASTUpdateBlock + # type: (ASTStmtsBody,ASTSourceLocation) -> ASTUpdateBlock return ASTUpdateBlock(block, source_position=source_position) @classmethod @@ -369,7 +369,7 @@ def create_ast_variable(cls, name: str, differential_order: int = 0, vector_para @classmethod def create_ast_while_stmt(cls, condition, # type: Union(ASTSimpleExpression,ASTExpression) - block, # type: ASTBlock + block, # type: ASTStmtsBody source_position # type: ASTSourceLocation ): # type: (...) -> ASTWhileStmt return ASTWhileStmt(condition, block, source_position=source_position) diff --git a/pynestml/meta_model/ast_on_condition_block.py b/pynestml/meta_model/ast_on_condition_block.py index d8e1ac4cd..6f38044d8 100644 --- a/pynestml/meta_model/ast_on_condition_block.py +++ b/pynestml/meta_model/ast_on_condition_block.py @@ -23,7 +23,7 @@ from typing import Any, List, Optional, Mapping -from pynestml.meta_model.ast_block import ASTBlock +from pynestml.meta_model.ast_stmts_body import ASTStmtsBody from pynestml.meta_model.ast_expression import ASTExpression from pynestml.meta_model.ast_node import ASTNode @@ -33,14 +33,14 @@ class ASTOnConditionBlock(ASTNode): This class is used to store a declaration of an onCondition block """ - def __init__(self, block: ASTBlock, cond_expr: ASTExpression, const_parameters: Optional[Mapping] = None, *args, **kwargs): + def __init__(self, stmts_body: ASTStmtsBody, cond_expr: ASTExpression, const_parameters: Optional[Mapping] = None, *args, **kwargs): r""" Standard constructor. - :param block: a block of definitions. + :param stmts_body: a body of statements. :param source_position: the position of this element in the source file. """ super(ASTOnConditionBlock, self).__init__(*args, **kwargs) - self.block = block + self.stmts_body = stmts_body self.cond_expr = cond_expr self.const_parameters = const_parameters if self.const_parameters is None: @@ -52,7 +52,7 @@ def clone(self) -> ASTOnConditionBlock: :return: new AST node instance """ - dup = ASTOnConditionBlock(block=self.block.clone(), + dup = ASTOnConditionBlock(stmts_body=self.stmts_body.clone(), cond_expr=self.cond_expr, const_parameters=self.const_parameters, # ASTNode common attributes: @@ -68,12 +68,12 @@ def clone(self) -> ASTOnConditionBlock: def get_const_parameters(self): return self.const_parameters - def get_block(self) -> ASTBlock: + def get_stmts_body(self) -> ASTStmtsBody: r""" - Returns the block of definitions. - :return: the block + Returns the body of statements. + :return: the body of statements """ - return self.block + return self.stmts_body def get_cond_expr(self) -> str: r""" @@ -91,8 +91,8 @@ def get_children(self) -> List[ASTNode]: if self.cond_expr: children.append(self.cond_expr) - if self.get_block(): - children.append(self.get_block()) + if self.get_stmts_body(): + children.append(self.get_stmts_body()) return children @@ -103,4 +103,4 @@ def equals(self, other: ASTNode) -> bool: if not isinstance(other, ASTOnConditionBlock): return False - return self.get_block().equals(other.get_block()) and self.cond_expr == other.cond_expr + return self.get_stmts_body().equals(other.get_stmts_body()) and self.cond_expr == other.cond_expr diff --git a/pynestml/meta_model/ast_on_receive_block.py b/pynestml/meta_model/ast_on_receive_block.py index d7ca37812..9118eea4c 100644 --- a/pynestml/meta_model/ast_on_receive_block.py +++ b/pynestml/meta_model/ast_on_receive_block.py @@ -23,7 +23,7 @@ from typing import Any, List, Optional, Mapping -from pynestml.meta_model.ast_block import ASTBlock +from pynestml.meta_model.ast_stmts_body import ASTStmtsBody from pynestml.meta_model.ast_node import ASTNode @@ -38,14 +38,14 @@ class ASTOnReceiveBlock(ASTNode): """ - def __init__(self, block: ASTBlock, port_name: str, const_parameters: Optional[Mapping] = None, *args, **kwargs): + def __init__(self, stmts_body: ASTStmtsBody, port_name: str, const_parameters: Optional[Mapping] = None, *args, **kwargs): r""" Standard constructor. - :param block: a block of definitions. + :param stmts_body: a body of statements. :param source_position: the position of this element in the source file. """ super(ASTOnReceiveBlock, self).__init__(*args, **kwargs) - self.block = block + self.stmts_body = stmts_body self.port_name = port_name self.const_parameters = const_parameters if self.const_parameters is None: @@ -57,7 +57,7 @@ def clone(self) -> ASTOnReceiveBlock: :return: new AST node instance """ - dup = ASTOnReceiveBlock(block=self.block.clone(), + dup = ASTOnReceiveBlock(stmts_body=self.stmts_body.clone(), port_name=self.port_name, const_parameters=self.const_parameters, # ASTNode common attributes: @@ -73,12 +73,12 @@ def clone(self) -> ASTOnReceiveBlock: def get_const_parameters(self): return self.const_parameters - def get_block(self) -> ASTBlock: + def get_stmts_body(self) -> ASTStmtsBody: r""" - Returns the block of definitions. - :return: the block + Returns the body of statements. + :return: the body of statements """ - return self.block + return self.stmts_body def get_port_name(self) -> str: r""" @@ -92,7 +92,7 @@ def get_children(self) -> List[ASTNode]: Returns the children of this node, if any. :return: List of children of this node. """ - return [self.get_block()] + return [self.get_stmts_body()] def equals(self, other: ASTNode) -> bool: r""" @@ -101,4 +101,4 @@ def equals(self, other: ASTNode) -> bool: if not isinstance(other, ASTOnReceiveBlock): return False - return self.get_block().equals(other.get_block()) and self.port_name == other.port_name + return self.get_stmts_body().equals(other.get_stmts_body()) and self.port_name == other.port_name diff --git a/pynestml/meta_model/ast_block.py b/pynestml/meta_model/ast_stmts_body.py similarity index 84% rename from pynestml/meta_model/ast_block.py rename to pynestml/meta_model/ast_stmts_body.py index 436378e43..52e7159d9 100644 --- a/pynestml/meta_model/ast_block.py +++ b/pynestml/meta_model/ast_stmts_body.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- # -# ast_block.py +# ast_stmts_body.py # # This file is part of NEST. # @@ -24,7 +24,7 @@ from pynestml.meta_model.ast_node import ASTNode -class ASTBlock(ASTNode): +class ASTStmtsBody(ASTNode): """ This class is used to store a single block of declarations, i.e., statements. Grammar: @@ -49,7 +49,7 @@ def __init__(self, stmts, *args, **kwargs): assert (stmt is not None and isinstance(stmt, ASTStmt)), \ '(PyNestML.ASTBlock) No or wrong type of statement provided (%s)!' % type(stmt) - super(ASTBlock, self).__init__(*args, **kwargs) + super(ASTStmtsBody, self).__init__(*args, **kwargs) self.stmts = stmts def clone(self): @@ -60,14 +60,14 @@ def clone(self): :rtype: ASTBlock """ stmts_dup = [stmt.clone() for stmt in self.stmts] - dup = ASTBlock(stmts_dup, - # ASTNode common attriutes: - source_position=self.source_position, - scope=self.scope, - comment=self.comment, - pre_comments=[s for s in self.pre_comments], - in_comment=self.in_comment, - implicit_conversion_factor=self.implicit_conversion_factor) + dup = ASTStmtsBody(stmts_dup, + # ASTNode common attriutes: + source_position=self.source_position, + scope=self.scope, + comment=self.comment, + pre_comments=[s for s in self.pre_comments], + in_comment=self.in_comment, + implicit_conversion_factor=self.implicit_conversion_factor) return dup @@ -108,7 +108,7 @@ def equals(self, other: ASTNode) -> bool: r""" The equality method. """ - if not isinstance(other, ASTBlock): + if not isinstance(other, ASTStmtsBody): return False if len(self.get_stmts()) != len(other.get_stmts()): return False diff --git a/pynestml/meta_model/ast_update_block.py b/pynestml/meta_model/ast_update_block.py index 27c84fa1a..6a7f05dc3 100644 --- a/pynestml/meta_model/ast_update_block.py +++ b/pynestml/meta_model/ast_update_block.py @@ -21,41 +21,26 @@ from typing import List -from pynestml.meta_model.ast_block import ASTBlock +from pynestml.meta_model.ast_stmts_body import ASTStmtsBody from pynestml.meta_model.ast_node import ASTNode class ASTUpdateBlock(ASTNode): + r""" + The ``update`` block in the model. """ - This class is used to store dynamic blocks. - ASTUpdateBlock is a special function definition: - update: - if r == 0: # not refractory - integrate(V) - @attribute block Implementation of the dynamics. - Grammar: - updateBlock: - 'update' - BLOCK_OPEN - block - BLOCK_CLOSE; - Attributes: - block = None - """ - - def __init__(self, block, *args, **kwargs): + def __init__(self, stmts_body: ASTStmtsBody, *args, **kwargs): """ Standard constructor. Parameters for superclass (ASTNode) can be passed through :python:`*args` and :python:`**kwargs`. :param block: a block of definitions. - :type block: ASTBlock """ super(ASTUpdateBlock, self).__init__(*args, **kwargs) - assert isinstance(block, ASTBlock) - self.block = block + assert isinstance(stmts_body, ASTStmtsBody) + self.stmts_body = stmts_body def clone(self): """ @@ -64,7 +49,7 @@ def clone(self): :return: new AST node instance :rtype: ASTUpdateBlock """ - dup = ASTUpdateBlock(block=self.block.clone(), + dup = ASTUpdateBlock(stmts_body=self.stmts_body.clone(), # ASTNode common attributes: source_position=self.source_position, scope=self.scope, @@ -75,20 +60,19 @@ def clone(self): return dup - def get_block(self): + def get_stmts_body(self) -> ASTStmtsBody: """ - Returns the block of definitions. - :return: the block - :rtype: ASTBlock + Returns the body of statements. + :return: the statements body """ - return self.block + return self.stmts_body def get_children(self) -> List[ASTNode]: r""" Returns the children of this node, if any. :return: List of children of this node. """ - return [self.get_block()] + return [self.get_stmts_body()] def equals(self, other: ASTNode) -> bool: r""" @@ -96,4 +80,5 @@ def equals(self, other: ASTNode) -> bool: """ if not isinstance(other, ASTUpdateBlock): return False - return self.get_block().equals(other.get_block()) + + return self.get_stmts_body().equals(other.get_stmts_body()) diff --git a/pynestml/meta_model/ast_while_stmt.py b/pynestml/meta_model/ast_while_stmt.py index 88d87eb22..1a1c51138 100644 --- a/pynestml/meta_model/ast_while_stmt.py +++ b/pynestml/meta_model/ast_while_stmt.py @@ -21,7 +21,7 @@ from typing import List -from pynestml.meta_model.ast_block import ASTBlock +from pynestml.meta_model.ast_stmts_body import ASTStmtsBody from pynestml.meta_model.ast_expression import ASTExpression from pynestml.meta_model.ast_node import ASTNode @@ -36,19 +36,18 @@ class ASTWhileStmt(ASTNode): block = None """ - def __init__(self, condition: ASTExpression, block: ASTBlock, *args, **kwargs): + def __init__(self, condition: ASTExpression, stmts_body: ASTStmtsBody, *args, **kwargs): """ Standard constructor. Parameters for superclass (ASTNode) can be passed through :python:`*args` and :python:`**kwargs`. - :param condition: the condition of the block. + :param condition: the condition of the ``while`` loop. :type condition: ASTExpression - :param block: a block of statements. - :type block: ASTBlock + :param stmts_body: a body of statements. """ super(ASTWhileStmt, self).__init__(*args, **kwargs) - self.block = block + self.stmts_body = stmts_body self.condition = condition def clone(self): @@ -58,13 +57,13 @@ def clone(self): :return: new AST node instance :rtype: ASTWhileStmt """ - block_dup = None - if self.block: - block_dup = self.block.clone() + stmts_body_dup = None + if self.stmts_body: + stmts_body_dup = self.stmts_body.clone() condition_dup = None if self.condition: condition_dup = self.condition.clone() - dup = ASTWhileStmt(block=block_dup, + dup = ASTWhileStmt(stmts_body=stmts_body_dup, condition=condition_dup, # ASTNode common attributes: source_position=self.source_position, @@ -84,13 +83,12 @@ def get_condition(self): """ return self.condition - def get_block(self): + def get_stmts_body(self) -> ASTStmtsBody: """ - Returns the block of statements. - :return: the block of statements. - :rtype: ASTBlock + Returns the body of statements. + :return: the body of statements. """ - return self.block + return self.stmts_body def get_children(self) -> List[ASTNode]: r""" @@ -101,8 +99,8 @@ def get_children(self) -> List[ASTNode]: if self.get_condition(): children.append(self.get_condition()) - if self.get_block(): - children.append(self.get_block()) + if self.get_stmts_body(): + children.append(self.get_stmts_body()) return children @@ -112,4 +110,4 @@ def equals(self, other: ASTNode) -> bool: """ if not isinstance(other, ASTWhileStmt): return False - return self.get_condition().equals(other.get_condition()) and self.get_block().equals(other.get_block()) + return self.get_condition().equals(other.get_condition()) and self.get_stmts_body().equals(other.get_stmts_body()) diff --git a/pynestml/transformers/synapse_post_neuron_transformer.py b/pynestml/transformers/synapse_post_neuron_transformer.py index 5ba8aef26..81089ecb2 100644 --- a/pynestml/transformers/synapse_post_neuron_transformer.py +++ b/pynestml/transformers/synapse_post_neuron_transformer.py @@ -486,7 +486,7 @@ def mark_post_port(_expr=None): if self.is_post_port(port.name, new_neuron.name, new_synapse.name): post_receive_blocks = ASTUtils.get_on_receive_blocks_by_input_port_name(new_synapse, port.name) for post_receive_block in post_receive_blocks: - stmts = post_receive_block.get_block().get_stmts() + stmts = post_receive_block.get_stmts_body().get_stmts() for stmt in stmts: if stmt.is_small_stmt() \ and stmt.small_stmt.is_assignment() \ diff --git a/pynestml/utils/ast_utils.py b/pynestml/utils/ast_utils.py index d66318130..6c6f44f24 100644 --- a/pynestml/utils/ast_utils.py +++ b/pynestml/utils/ast_utils.py @@ -31,7 +31,7 @@ from pynestml.frontend.frontend_configuration import FrontendConfiguration from pynestml.generated.PyNestMLLexer import PyNestMLLexer from pynestml.meta_model.ast_assignment import ASTAssignment -from pynestml.meta_model.ast_block import ASTBlock +from pynestml.meta_model.ast_stmts_body import ASTStmtsBody from pynestml.meta_model.ast_block_with_variables import ASTBlockWithVariables from pynestml.meta_model.ast_declaration import ASTDeclaration from pynestml.meta_model.ast_elif_clause import ASTElifClause @@ -518,7 +518,7 @@ def contains_convolve_call(cls, variable: VariableSymbol) -> bool: return False @classmethod - def get_declaration_by_name(cls, blocks: Union[ASTBlock, List[ASTBlock]], var_name: str) -> Optional[ASTDeclaration]: + def get_declaration_by_name(cls, blocks: Union[ASTStmtsBody, List[ASTStmtsBody]], var_name: str) -> Optional[ASTDeclaration]: """ Get a declaration by variable name. :param blocks: the block or blocks to look for the variable in @@ -534,7 +534,7 @@ def get_declaration_by_name(cls, blocks: Union[ASTBlock, List[ASTBlock]], var_na return None @classmethod - def all_variables_defined_in_block(cls, blocks: Union[ASTBlock, List[ASTBlock]]) -> List[ASTVariable]: + def all_variables_defined_in_block(cls, blocks: Union[ASTStmtsBody, List[ASTStmtsBody]]) -> List[ASTVariable]: """return a list of all variable declarations in a block or blocks""" if isinstance(blocks, ASTNode): blocks = [blocks] @@ -998,7 +998,7 @@ def add_ode_to_variable(cls, ode_equation: ASTOdeEquation): @classmethod def get_statements_from_block(cls, var_name, block): """XXX: only simple statements such as assignments are supported for now. if..then..else compound statements and so are not yet supported.""" - block = block.get_block() + block = block.get_stmts_body() all_stmts = block.get_stmts() stmts = [] for node in all_stmts: @@ -1200,9 +1200,9 @@ def add_assignment_to_update_block(cls, assignment: ASTAssignment, neuron: ASTMo source_position=ASTSourceLocation.get_added_source_position()) if not neuron.get_update_blocks(): neuron.create_empty_update_block() - neuron.get_update_blocks()[0].get_block().get_stmts().append(stmt) - small_stmt.update_scope(neuron.get_update_blocks()[0].get_block().get_scope()) - stmt.update_scope(neuron.get_update_blocks()[0].get_block().get_scope()) + neuron.get_update_blocks()[0].get_stmts_body().get_stmts().append(stmt) + small_stmt.update_scope(neuron.get_update_blocks()[0].get_stmts_body().get_scope()) + stmt.update_scope(neuron.get_update_blocks()[0].get_stmts_body().get_scope()) return neuron @classmethod @@ -1220,9 +1220,9 @@ def add_declaration_to_update_block(cls, declaration: ASTDeclaration, neuron: AS source_position=ASTSourceLocation.get_added_source_position()) if not neuron.get_update_blocks(): neuron.create_empty_update_block() - neuron.get_update_blocks()[0].get_block().get_stmts().append(stmt) - small_stmt.update_scope(neuron.get_update_blocks()[0].get_block().get_scope()) - stmt.update_scope(neuron.get_update_blocks()[0].get_block().get_scope()) + neuron.get_update_blocks()[0].get_stmts_body().get_stmts().append(stmt) + small_stmt.update_scope(neuron.get_update_blocks()[0].get_stmts_body().get_scope()) + stmt.update_scope(neuron.get_update_blocks()[0].get_stmts_body().get_scope()) return neuron @classmethod @@ -1680,7 +1680,7 @@ def collect_vars(_expr=None): return vars_used_ @classmethod - def get_declarations_from_block(cls, var_name: str, block: ASTBlock) -> List[ASTDeclaration]: + def get_declarations_from_block(cls, var_name: str, block: ASTStmtsBody) -> List[ASTDeclaration]: """ Get declarations from the given block containing the given variable on the left-hand side. @@ -1928,7 +1928,7 @@ def _visit_if_clause(self, node: ASTIfClause) -> None: cond_vars = ASTUtils.get_all_variables_names_in_expression(node.condition) if var in cond_vars: # collect all variables assigned to in the if-block -- they all depend on ``var`` - self.vars |= ASTUtils.get_all_variables_assigned_to(node.block) + self.vars |= ASTUtils.get_all_variables_assigned_to(node.get_stmts_body()) def visit_if_clause(self, node: ASTIfClause) -> None: self._visit_if_clause(node) @@ -2441,7 +2441,7 @@ def get_function_calls(cls, ast_node: ASTNode, function_list: List[str]) -> List return res @classmethod - def resolve_to_variable_symbol_in_blocks(cls, variable_name: str, blocks: List[ASTBlock]): + def resolve_to_variable_symbol_in_blocks(cls, variable_name: str, blocks: List[ASTStmtsBody]): r""" Resolve a variable (by name) to its corresponding ``Symbol`` within the AST blocks in ``blocks``. """ diff --git a/pynestml/utils/model_parser.py b/pynestml/utils/model_parser.py index d11618119..295740809 100644 --- a/pynestml/utils/model_parser.py +++ b/pynestml/utils/model_parser.py @@ -23,14 +23,15 @@ from antlr4 import CommonTokenStream, FileStream, InputStream from antlr4.error.ErrorStrategy import BailErrorStrategy, DefaultErrorStrategy -from antlr4.error.ErrorListener import ConsoleErrorListener -from pynestml.cocos.co_cos_manager import CoCosManager +from antlr4.error.ErrorListener import ConsoleErrorListener, ErrorListener +from antlr4.error.Errors import ParseCancellationException +from pynestml.cocos.co_cos_manager import CoCosManager from pynestml.generated.PyNestMLLexer import PyNestMLLexer from pynestml.generated.PyNestMLParser import PyNestMLParser from pynestml.meta_model.ast_arithmetic_operator import ASTArithmeticOperator from pynestml.meta_model.ast_assignment import ASTAssignment -from pynestml.meta_model.ast_block import ASTBlock +from pynestml.meta_model.ast_stmts_body import ASTStmtsBody from pynestml.meta_model.ast_block_with_variables import ASTBlockWithVariables from pynestml.meta_model.ast_comparison_operator import ASTComparisonOperator from pynestml.meta_model.ast_compound_stmt import ASTCompoundStmt @@ -196,14 +197,6 @@ def parse_bit_operator(cls, string): ret.accept(ASTHigherOrderVisitor(log_set_added_source_position)) return ret - @classmethod - def parse_block(cls, string): - # type: (str) -> ASTBlock - (builder, parser) = tokenize(string) - ret = builder.visit(parser.block()) - ret.accept(ASTHigherOrderVisitor(log_set_added_source_position)) - return ret - @classmethod def parse_block_with_variables(cls, string): # type: (str) -> ASTBlockWithVariables @@ -215,7 +208,7 @@ def parse_block_with_variables(cls, string): @classmethod def parse_model_body(cls, string: str) -> ASTModelBody: (builder, parser) = tokenize(string) - ret = builder.visit(parser.body()) + ret = builder.visit(parser.modelBody()) ret.accept(ASTHigherOrderVisitor(log_set_added_source_position)) return ret @@ -459,6 +452,22 @@ def parse_while_stmt(cls, string): ret.accept(ASTHigherOrderVisitor(log_set_added_source_position)) return ret + @classmethod + def parse_stmts_body(cls, string): + # type: (str) -> ASTStmtsBody + (builder, parser) = tokenize(string) + ret = builder.visit(parser.stmtsBody()) + ret.accept(ASTHigherOrderVisitor(log_set_added_source_position)) + return ret + + +class BailConsoleErrorListener(ErrorListener): + """Print error message to the console as well as bail""" + def syntaxError(self, recognizer, offendingSymbol, line, column, msg, e): + s = "line " + str(line) + ":" + str(column) + " " + msg + print(s) + raise ParseCancellationException(s) + def tokenize(string: str) -> Tuple[ASTBuilderVisitor, PyNestMLParser]: lexer = PyNestMLLexer(InputStream(string)) @@ -466,7 +475,11 @@ def tokenize(string: str) -> Tuple[ASTBuilderVisitor, PyNestMLParser]: stream = CommonTokenStream(lexer) stream.fill() parser = PyNestMLParser(stream) + + parser.addErrorListener(BailConsoleErrorListener()) + builder = ASTBuilderVisitor(stream.tokens) + return builder, parser diff --git a/pynestml/visitors/assign_implicit_conversion_factors_visitor.py b/pynestml/visitors/assign_implicit_conversion_factors_visitor.py index 0fe4b93a7..bad89d52c 100644 --- a/pynestml/visitors/assign_implicit_conversion_factors_visitor.py +++ b/pynestml/visitors/assign_implicit_conversion_factors_visitor.py @@ -221,11 +221,11 @@ def __assign_return_types(self, _node): symbol = userDefinedFunction.get_scope().resolve_to_symbol(userDefinedFunction.get_name(), SymbolKind.FUNCTION) # first ensure that the block contains at least one statement - if symbol is not None and len(userDefinedFunction.get_block().get_stmts()) > 0: + if symbol is not None and len(userDefinedFunction.get_stmts_body().get_stmts()) > 0: # now check that the last statement is a return self.__check_return_recursively(userDefinedFunction, symbol.get_return_type(), - userDefinedFunction.get_block().get_stmts(), + userDefinedFunction.get_stmts_body().get_stmts(), False) # now if it does not have a statement, but uses a return type, it is an error elif symbol is not None and userDefinedFunction.has_return_type() and \ @@ -300,23 +300,23 @@ def __check_return_recursively(self, processed_function, type_symbol=None, stmts if stmt.is_if_stmt(): self.__check_return_recursively(processed_function, type_symbol, - stmt.get_if_stmt().get_if_clause().get_block().get_stmts(), + stmt.get_if_stmt().get_if_clause().get_stmts_body().get_stmts(), ret_defined) for else_ifs in stmt.get_if_stmt().get_elif_clauses(): self.__check_return_recursively(processed_function, - type_symbol, else_ifs.get_block().get_stmts(), ret_defined) + type_symbol, else_ifs.get_stmts_body().get_stmts(), ret_defined) if stmt.get_if_stmt().has_else_clause(): self.__check_return_recursively(processed_function, type_symbol, - stmt.get_if_stmt().get_else_clause().get_block().get_stmts(), + stmt.get_if_stmt().get_else_clause().get_stmts_body().get_stmts(), ret_defined) elif stmt.is_while_stmt(): self.__check_return_recursively(processed_function, - type_symbol, stmt.get_while_stmt().get_block().get_stmts(), + type_symbol, stmt.get_while_stmt().get_stmts_body().get_stmts(), ret_defined) elif stmt.is_for_stmt(): self.__check_return_recursively(processed_function, - type_symbol, stmt.get_for_stmt().get_block().get_stmts(), + type_symbol, stmt.get_for_stmt().get_stmts_body().get_stmts(), ret_defined) # now, if a return statement has not been defined in the corresponding higher level block, we have to ensure that it is defined here elif not ret_defined and stmts.index(c_stmt) == (len(stmts) - 1): diff --git a/pynestml/visitors/ast_builder_visitor.py b/pynestml/visitors/ast_builder_visitor.py index 02a9bd396..edcab7a22 100644 --- a/pynestml/visitors/ast_builder_visitor.py +++ b/pynestml/visitors/ast_builder_visitor.py @@ -184,8 +184,8 @@ def visitExpression(self, ctx): elif (condition is not None) and (if_true is not None) and (if_not is not None): return ASTNodeFactory.create_ast_ternary_expression(condition=condition, if_true=if_true, if_not=if_not, source_position=source_pos) - else: - raise RuntimeError('Type of rhs @%s,%s not recognized!' % (ctx.start.line, ctx.start.column)) + + raise RuntimeError('Type of rhs @%s,%s not recognized!' % (ctx.start.line, ctx.start.column)) # Visit a parse tree produced by PyNESTMLParser#simpleExpression. def visitSimpleExpression(self, ctx): @@ -201,12 +201,13 @@ def visitSimpleExpression(self, ctx): is_inf = (True if ctx.isInf is not None else False) variable = (self.visit(ctx.variable()) if ctx.variable() is not None else None) string = (str(ctx.string.text) if ctx.string is not None else None) - return ASTNodeFactory.create_ast_simple_expression(function_call=function_call, + node = ASTNodeFactory.create_ast_simple_expression(function_call=function_call, boolean_literal=boolean_literal, numeric_literal=numeric_literal, is_inf=is_inf, variable=variable, string=string, source_position=create_source_pos(ctx)) + return node # Visit a parse tree produced by PyNESTMLParser#unaryOperator. def visitUnaryOperator(self, ctx): @@ -323,8 +324,8 @@ def visitKernel(self, ctx): update_node_comments(kernel, self.__comments.visit(ctx)) return kernel - # Visit a parse tree produced by PyNESTMLParser#block. - def visitBlock(self, ctx): + # Visit a parse tree produced by PyNESTMLParser#stmtsBody + def visitStmtsBody(self, ctx): stmts = list() if ctx.stmt() is not None: for stmt in ctx.stmt(): @@ -402,7 +403,8 @@ def visitDeclaration(self, ctx): # Visit a parse tree produced by PyNESTMLParser#returnStmt. def visitReturnStmt(self, ctx): ret_expression = self.visit(ctx.expression()) if ctx.expression() is not None else None - return ASTNodeFactory.create_ast_return_stmt(expression=ret_expression, source_position=create_source_pos(ctx)) + node = ASTNodeFactory.create_ast_return_stmt(expression=ret_expression, source_position=create_source_pos(ctx)) + return node # Visit a parse tree produced by PyNESTMLParser#ifStmt. def visitIfStmt(self, ctx): @@ -419,7 +421,7 @@ def visitIfStmt(self, ctx): # Visit a parse tree produced by PyNESTMLParser#ifClause. def visitIfClause(self, ctx): condition = self.visit(ctx.expression()) if ctx.expression() is not None else None - block = self.visit(ctx.block()) if ctx.block() is not None else None + block = self.visit(ctx.stmtsBody()) if ctx.stmtsBody() is not None else None ret = ASTNodeFactory.create_ast_if_clause(condition=condition, block=block, source_position=create_source_pos(ctx)) update_node_comments(ret, self.__comments.visitStmt(ctx)) @@ -428,7 +430,7 @@ def visitIfClause(self, ctx): # Visit a parse tree produced by PyNESTMLParser#elifClause. def visitElifClause(self, ctx): condition = self.visit(ctx.expression()) if ctx.expression() is not None else None - block = self.visit(ctx.block()) if ctx.block() is not None else None + block = self.visit(ctx.stmtsBody()) if ctx.stmtsBody() is not None else None node = ASTNodeFactory.create_ast_elif_clause(condition=condition, block=block, source_position=create_source_pos(ctx)) update_node_comments(node, self.__comments.visit(ctx)) @@ -436,7 +438,7 @@ def visitElifClause(self, ctx): # Visit a parse tree produced by PyNESTMLParser#elseClause. def visitElseClause(self, ctx): - block = self.visit(ctx.block()) if ctx.block() is not None else None + block = self.visit(ctx.stmtsBody()) if ctx.stmtsBody() is not None else None node = ASTNodeFactory.create_ast_else_clause(block=block, source_position=create_source_pos(ctx)) update_node_comments(node, self.__comments.visit(ctx)) return node @@ -453,7 +455,7 @@ def visitForStmt(self, ctx): value = float(str(ctx.FLOAT())) step = step_scalar * value - block = self.visit(ctx.block()) if ctx.block() is not None else None + block = self.visit(ctx.stmtsBody()) if ctx.stmtsBody() is not None else None node = ASTNodeFactory.create_ast_for_stmt(variable=variable, start_from=start_from, end_at=end_at, step=step, block=block, source_position=create_source_pos(ctx)) update_node_comments(node, self.__comments.visit(ctx)) @@ -462,7 +464,7 @@ def visitForStmt(self, ctx): # Visit a parse tree produced by PyNESTMLParser#whileStmt. def visitWhileStmt(self, ctx): cond = self.visit(ctx.expression()) if ctx.expression() is not None else None - block = self.visit(ctx.block()) if ctx.block() is not None else None + block = self.visit(ctx.stmtsBody()) if ctx.stmtsBody() is not None else None node = ASTNodeFactory.create_ast_while_stmt(condition=cond, block=block, source_position=create_source_pos(ctx)) update_node_comments(node, self.__comments.visit(ctx)) return node @@ -563,7 +565,7 @@ def visitBlockWithVariables(self, ctx): return ret def visitUpdateBlock(self, ctx): - block = self.visit(ctx.block()) if ctx.block() is not None else None + block = self.visit(ctx.stmtsBody()) if ctx.stmtsBody() is not None else None ret = ASTNodeFactory.create_ast_update_block(block=block, source_position=create_source_pos(ctx)) update_node_comments(ret, self.__comments.visit(ctx)) return ret @@ -673,7 +675,7 @@ def visitFunction(self, ctx): parameters.append(self.visit(par)) elif ctx.parameters() is not None: parameters.append(ctx.parameter()) - block = self.visit(ctx.block()) if ctx.block() is not None else None + block = self.visit(ctx.stmtsBody()) if ctx.stmtsBody() is not None else None return_type = self.visit(ctx.returnType) if ctx.returnType is not None else None node = ASTNodeFactory.create_ast_function(name=name, parameters=parameters, block=block, return_type=return_type, source_position=create_source_pos(ctx)) @@ -694,7 +696,7 @@ def visitStmt(self, ctx): return ASTNodeFactory.create_ast_stmt(small, compound, create_source_pos(ctx)) def visitOnReceiveBlock(self, ctx): - block = self.visit(ctx.block()) if ctx.block() is not None else None + block = self.visit(ctx.stmtsBody()) if ctx.stmtsBody() is not None else None port_name = ctx.inputPortName.text const_parameters = {} for el in ctx.constParameter(): @@ -704,7 +706,7 @@ def visitOnReceiveBlock(self, ctx): return ret def visitOnConditionBlock(self, ctx): - block = self.visit(ctx.block()) if ctx.block() is not None else None + block = self.visit(ctx.stmtsBody()) if ctx.stmtsBody() is not None else None cond_expr: ASTExpression = self.visit(ctx.condition) const_parameters = {} for el in ctx.constParameter(): @@ -715,6 +717,9 @@ def visitOnConditionBlock(self, ctx): def update_node_comments(node, comments): + if not comments: + return + node.comment = comments[0] node.pre_comments = comments[1] node.in_comment = comments[2] diff --git a/pynestml/visitors/ast_symbol_table_visitor.py b/pynestml/visitors/ast_symbol_table_visitor.py index f9cde46e4..a0f01e9fa 100644 --- a/pynestml/visitors/ast_symbol_table_visitor.py +++ b/pynestml/visitors/ast_symbol_table_visitor.py @@ -113,8 +113,8 @@ def visit_function(self, node): if node.has_return_type(): node.get_return_type().update_scope(scope) - if node.get_block() is not None: - node.get_block().update_scope(scope) + if node.get_stmts_body() is not None: + node.get_stmts_body().update_scope(scope) def endvisit_function(self, node): symbol = self.symbol_stack.pop() @@ -158,7 +158,7 @@ def visit_update_block(self, node): scope = Scope(scope_type=ScopeType.UPDATE, enclosing_scope=node.get_scope(), source_position=node.get_source_position()) node.get_scope().add_scope(scope) - node.get_block().update_scope(scope) + node.get_stmts_body().update_scope(scope) return def endvisit_update_block(self, node=None): @@ -175,7 +175,7 @@ def visit_on_receive_block(self, node): scope = Scope(scope_type=ScopeType.ON_RECEIVE, enclosing_scope=node.get_scope(), source_position=node.get_source_position()) node.get_scope().add_scope(scope) - node.get_block().update_scope(scope) + node.get_stmts_body().update_scope(scope) def endvisit_on_receive_block(self, node=None): self.block_type_stack.pop() @@ -190,7 +190,7 @@ def visit_on_condition_block(self, node): scope = Scope(scope_type=ScopeType.ON_CONDITION, enclosing_scope=node.get_scope(), source_position=node.get_source_position()) node.get_scope().add_scope(scope) - node.get_block().update_scope(scope) + node.get_stmts_body().update_scope(scope) node.get_cond_expr().update_scope(node.get_scope()) def endvisit_on_condition_block(self, node=None): @@ -355,7 +355,7 @@ def visit_if_clause(self, node): :type node: ast_if_clause """ node.get_condition().update_scope(node.get_scope()) - node.get_block().update_scope(node.get_scope()) + node.get_stmts_body().update_scope(node.get_scope()) def visit_elif_clause(self, node): """ @@ -364,7 +364,7 @@ def visit_elif_clause(self, node): :type node: ast_elif_clause """ node.get_condition().update_scope(node.get_scope()) - node.get_block().update_scope(node.get_scope()) + node.get_stmts_body().update_scope(node.get_scope()) def visit_else_clause(self, node): """ @@ -372,7 +372,7 @@ def visit_else_clause(self, node): :param node: an else clause. :type node: ast_else_clause """ - node.get_block().update_scope(node.get_scope()) + node.get_stmts_body().update_scope(node.get_scope()) def visit_for_stmt(self, node): """ @@ -382,7 +382,7 @@ def visit_for_stmt(self, node): """ node.get_start_from().update_scope(node.get_scope()) node.get_end_at().update_scope(node.get_scope()) - node.get_block().update_scope(node.get_scope()) + node.get_stmts_body().update_scope(node.get_scope()) def visit_while_stmt(self, node): """ @@ -391,7 +391,7 @@ def visit_while_stmt(self, node): :type node: ast_while_stmt """ node.get_condition().update_scope(node.get_scope()) - node.get_block().update_scope(node.get_scope()) + node.get_stmts_body().update_scope(node.get_scope()) def visit_data_type(self, node): """ diff --git a/pynestml/visitors/ast_visitor.py b/pynestml/visitors/ast_visitor.py index c2b4dab01..630759f6d 100644 --- a/pynestml/visitors/ast_visitor.py +++ b/pynestml/visitors/ast_visitor.py @@ -22,7 +22,7 @@ from pynestml.meta_model.ast_arithmetic_operator import ASTArithmeticOperator from pynestml.meta_model.ast_assignment import ASTAssignment from pynestml.meta_model.ast_bit_operator import ASTBitOperator -from pynestml.meta_model.ast_block import ASTBlock +from pynestml.meta_model.ast_stmts_body import ASTStmtsBody from pynestml.meta_model.ast_block_with_variables import ASTBlockWithVariables from pynestml.meta_model.ast_comparison_operator import ASTComparisonOperator from pynestml.meta_model.ast_compound_stmt import ASTCompoundStmt @@ -745,7 +745,7 @@ def visit(self, node: ASTNode): if isinstance(node, ASTBitOperator): self.visit_bit_operator(node) return - if isinstance(node, ASTBlock): + if isinstance(node, ASTStmtsBody): self.visit_block(node) return if isinstance(node, ASTBlockWithVariables): @@ -876,7 +876,7 @@ def traverse(self, node): if isinstance(node, ASTBitOperator): self.traverse_bit_operator(node) return - if isinstance(node, ASTBlock): + if isinstance(node, ASTStmtsBody): self.traverse_block(node) return if isinstance(node, ASTBlockWithVariables): @@ -1007,7 +1007,7 @@ def endvisit(self, node): if isinstance(node, ASTBitOperator): self.endvisit_bit_operator(node) return - if isinstance(node, ASTBlock): + if isinstance(node, ASTStmtsBody): self.endvisit_block(node) return if isinstance(node, ASTBlockWithVariables): @@ -1178,12 +1178,12 @@ def traverse_declaration(self, node): def traverse_elif_clause(self, node): if node.get_condition() is not None: node.get_condition().accept(self.get_real_self()) - if node.get_block() is not None: - node.get_block().accept(self.get_real_self()) + if node.get_stmts_body() is not None: + node.get_stmts_body().accept(self.get_real_self()) def traverse_else_clause(self, node): - if node.get_block() is not None: - node.get_block().accept(self.get_real_self()) + if node.get_stmts_body() is not None: + node.get_stmts_body().accept(self.get_real_self()) def traverse_equations_block(self, node): if node.get_declarations() is not None: @@ -1213,16 +1213,16 @@ def traverse_for_stmt(self, node): node.get_start_from().accept(self.get_real_self()) if node.get_end_at() is not None: node.get_end_at().accept(self.get_real_self()) - if node.get_block() is not None: - node.get_block().accept(self.get_real_self()) + if node.get_stmts_body() is not None: + node.get_stmts_body().accept(self.get_real_self()) def traverse_function(self, node): for sub_node in node.get_parameters(): sub_node.accept(self.get_real_self()) if node.get_return_type() is not None: node.get_return_type().accept(self.get_real_self()) - if node.get_block() is not None: - node.get_block().accept(self.get_real_self()) + if node.get_stmts_body() is not None: + node.get_stmts_body().accept(self.get_real_self()) def traverse_function_call(self, node): if node.get_args() is not None: @@ -1232,8 +1232,8 @@ def traverse_function_call(self, node): def traverse_if_clause(self, node): if node.get_condition() is not None: node.get_condition().accept(self.get_real_self()) - if node.get_block() is not None: - node.get_block().accept(self.get_real_self()) + if node.get_stmts_body() is not None: + node.get_stmts_body().accept(self.get_real_self()) def traverse_if_stmt(self, node): if node.get_if_clause() is not None: @@ -1327,18 +1327,18 @@ def traverse_unit_type(self, node): node.compound_unit.accept(self.get_real_self()) def traverse_update_block(self, node): - if node.get_block() is not None: - node.get_block().accept(self.get_real_self()) + if node.get_stmts_body() is not None: + node.get_stmts_body().accept(self.get_real_self()) def traverse_on_receive_block(self, node): - if node.get_block() is not None: - node.get_block().accept(self.get_real_self()) + if node.get_stmts_body() is not None: + node.get_stmts_body().accept(self.get_real_self()) def traverse_on_condition_block(self, node): if node.get_cond_expr() is not None: node.get_cond_expr().accept(self.get_real_self()) - if node.get_block() is not None: - node.get_block().accept(self.get_real_self()) + if node.get_stmts_body() is not None: + node.get_stmts_body().accept(self.get_real_self()) def traverse_variable(self, node): if node.get_vector_parameter() is not None: @@ -1347,8 +1347,8 @@ def traverse_variable(self, node): def traverse_while_stmt(self, node): if node.get_condition() is not None: node.get_condition().accept(self.get_real_self()) - if node.get_block() is not None: - node.get_block().accept(self.get_real_self()) + if node.get_stmts_body() is not None: + node.get_stmts_body().accept(self.get_real_self()) def traverse_stmt(self, node): if node.is_small_stmt(): diff --git a/tests/nestml_printer_test.py b/tests/test_nestml_printer.py similarity index 60% rename from tests/nestml_printer_test.py rename to tests/test_nestml_printer.py index 2ac258a3e..9fb73c720 100644 --- a/tests/nestml_printer_test.py +++ b/tests/test_nestml_printer.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- # -# nestml_printer_test.py +# test_nestml_printer.py # # This file is part of NEST. # @@ -18,8 +18,9 @@ # # You should have received a copy of the GNU General Public License # along with NEST. If not, see . + import os -import unittest +import pytest from pynestml.codegeneration.printers.nestml_printer import NESTMLPrinter from pynestml.symbol_table.symbol_table import SymbolTable @@ -32,13 +33,13 @@ from pynestml.utils.model_parser import ModelParser -class NestMLPrinterTest(unittest.TestCase): +class TestNESTMLMLPrinter: """ Tests if NESTMLPrinter works as intended. """ + @pytest.fixture(scope="module", autouse=True) def setUp(self): - # setups the infrastructure PredefinedUnits.register_units() PredefinedTypes.register_types() PredefinedFunctions.register_functions() @@ -47,52 +48,52 @@ def setUp(self): Logger.init_logger(LoggingLevel.INFO) def test_block_with_variables_with_comments(self): - block = "# pre1\n" \ - "state: # in\n" \ - " # real pre\n" \ - " # real pre2\n" \ - " r real = 0\n" - model = ModelParser.parse_block_with_variables(block) + block = " # pre1\n" \ + " state: # in\n" \ + " # real pre\n" \ + " # real pre2\n" \ + " r real = 0\n" + model = ModelParser.parse_model_body(block) model_printer = NESTMLPrinter() - self.assertEqual(block, model_printer.print(model)) + assert block == model_printer.print(model) def test_block_with_variables_with_in_comments(self): - block = "# pre1\n" \ - "state:\n" \ - " r real = 0 # in comment\n" - model = ModelParser.parse_block_with_variables(block) + block = " # pre1\n" \ + " state:\n" \ + " r real = 0 # in comment\n" + model = ModelParser.parse_model_body(block) model_printer = NESTMLPrinter() - self.assertEqual(block, model_printer.print(model)) + assert block == model_printer.print(model) def test_block_with_variables_without_comments(self): block = "state:\n" \ " r real = 0\n" model = ModelParser.parse_block_with_variables(block) model_printer = NESTMLPrinter() - self.assertEqual(block, model_printer.print(model)) + assert block == model_printer.print(model) def test_assignment_with_comments(self): - assignment = " # pre\n" \ - " a = b # in\n" - model = ModelParser.parse_block(assignment) + assignment = "# pre\n" \ + "a = b # in\n" + model = ModelParser.parse_stmts_body(assignment) model_printer = NESTMLPrinter() - self.assertEqual(assignment, model_printer.print(model)) + assert assignment == model_printer.print(model) def test_assignment_without_comments(self): assignment = "a = b\n" model = ModelParser.parse_assignment(assignment) model_printer = NESTMLPrinter() - self.assertEqual(assignment, model_printer.print(model)) + assert assignment == model_printer.print(model) def test_function_with_comments(self): - t_function = "# pre func\n" \ - "function test(Tau_1 ms) real: # in func\n" \ - " # decl pre\n" \ - " exact_integration_adjustment real = ((1 / Tau_2) - (1 / Tau_1)) * ms # decl in\n" \ - " return normalisation_factor\n" - model = ModelParser.parse_function(t_function) + t_function = " # pre func\n" \ + " function test(Tau_1 ms) real: # in func\n" \ + " # decl pre\n" \ + " exact_integration_adjustment real = ((1 / Tau_2) - (1 / Tau_1)) * ms # decl in\n" \ + " return normalisation_factor\n" + model = ModelParser.parse_model_body(t_function) model_printer = NESTMLPrinter() - self.assertEqual(t_function, model_printer.print(model)) + assert t_function == model_printer.print(model) def test_function_without_comments(self): t_function = "function test(Tau_1 ms) real:\n" \ @@ -100,20 +101,20 @@ def test_function_without_comments(self): " return normalisation_factor\n" model = ModelParser.parse_function(t_function) model_printer = NESTMLPrinter() - self.assertEqual(t_function, model_printer.print(model)) + assert t_function == model_printer.print(model) def test_function_call_with_comments(self): - function_call = " # pre\n" \ - " min(1,2) # in\n" - model = ModelParser.parse_block(function_call) + function_call = "# pre\n" \ + "min(1,2) # in\n" + model = ModelParser.parse_stmts_body(function_call) model_printer = NESTMLPrinter() - self.assertEqual(function_call, model_printer.print(model)) + assert function_call == model_printer.print(model) def test_function_call_without_comments(self): function_call = "min(1,2)\n" model = ModelParser.parse_stmt(function_call) model_printer = NESTMLPrinter() - self.assertEqual(function_call, model_printer.print(model)) + assert function_call == model_printer.print(model) def test_neuron_with_comments(self): neuron = "# pre\n" \ @@ -122,107 +123,109 @@ def test_neuron_with_comments(self): " foo integer = 0\n" model = ModelParser.parse_nestml_compilation_unit(neuron) model_printer = NESTMLPrinter() - self.assertEqual(neuron, model_printer.print(model)) + assert neuron == model_printer.print(model) def test_neuron_with_docstring(self): neuron = '"""hello, world\n" \ "\n" \ - "3.141592653589793"""\n'\ - "model test:\n" + "3.141592653589793"""\n' \ + "model test:\n" \ + " parameters:\n" \ + " foo integer = 0\n" model = ModelParser.parse_model(neuron) model_printer = NESTMLPrinter() - self.assertEqual(neuron, model_printer.print(model)) + assert neuron == model_printer.print(model) def test_declaration_with_comments(self): - declaration = " # pre\n" \ - " test mV = 10mV # in\n" - model = ModelParser.parse_block(declaration) + declaration = "# pre\n" \ + "test mV = 10mV # in\n" + model = ModelParser.parse_stmts_body(declaration) model_printer = NESTMLPrinter() - self.assertEqual(declaration, model_printer.print(model)) + assert declaration == model_printer.print(model) def test_declaration_without_comments(self): declaration = "test mV = 10mV\n" model = ModelParser.parse_declaration(declaration) model_printer = NESTMLPrinter() - self.assertEqual(declaration, model_printer.print(model)) + assert declaration == model_printer.print(model) def test_equations_block_with_comments(self): - block = "# pre\n" \ - "equations: # in\n" \ - " # pre1 v\n" \ - " # pre2 v\n" \ - " v' = -v / t\n" - model = ModelParser.parse_equations_block(block) + block = " # pre\n" \ + " equations: # in\n" \ + " # pre1 v\n" \ + " # pre2 v\n" \ + " v' = -v / t\n" + model = ModelParser.parse_model_body(block) model_printer = NESTMLPrinter() - self.assertEqual(block, model_printer.print(model)) + assert block == model_printer.print(model) def test_equations_block_without_comments(self): block = "equations:\n" \ " v' = -v / t\n" model = ModelParser.parse_equations_block(block) model_printer = NESTMLPrinter() - self.assertEqual(block, model_printer.print(model)) + assert block == model_printer.print(model) def test_for_stmt_with_comments(self): - stmt = " # pre\n" \ - " for i in 10 - 3.14...10 + 3.14 step -1: # in\n" \ - " j = j + 1\n" - model = ModelParser.parse_block(stmt) + stmt = "# pre\n" \ + "for i in 10 - 3.14...10 + 3.14 step -1: # in\n" \ + " j = j + 1\n" + model = ModelParser.parse_stmts_body(stmt) model_printer = NESTMLPrinter() - self.assertEqual(stmt, model_printer.print(model)) + assert stmt == model_printer.print(model) def test_for_stmt_without_comments(self): stmt = "for i in 10 - 3.14...10 + 3.14 step -1: # in\n" \ " j += 1\n" model = ModelParser.parse_for_stmt(stmt) model_printer = NESTMLPrinter() - self.assertEqual(stmt, model_printer.print(model)) + assert stmt == model_printer.print(model) def test_while_stmt_with_comments(self): - stmt = " # pre\n" \ - " while true: # in\n" \ - " i += 1\n" - model = ModelParser.parse_block(stmt) + stmt = "# pre\n" \ + "while true: # in\n" \ + " i += 1\n" + model = ModelParser.parse_stmts_body(stmt) model_printer = NESTMLPrinter() - self.assertEqual(stmt, model_printer.print(model)) + assert stmt == model_printer.print(model) def test_while_stmt_without_comments(self): stmt = "while true:\n" \ " i -= 0.5\n" model = ModelParser.parse_while_stmt(stmt) model_printer = NESTMLPrinter() - self.assertEqual(stmt, model_printer.print(model)) + assert stmt == model_printer.print(model) def test_update_block_with_comments(self): - block = "# pre\n" \ - "update: # in\n" \ - " j = 0\n" - model = ModelParser.parse_update_block(block) + block = " # pre\n" \ + " update: # in\n" \ + " j = 0\n" + model = ModelParser.parse_model_body(block) model_printer = NESTMLPrinter() - self.assertEqual(block, model_printer.print(model)) + assert block == model_printer.print(model) def test_update_block_without_comments(self): block = "update:\n" \ " j = 3\n" model = ModelParser.parse_update_block(block) model_printer = NESTMLPrinter() - self.assertEqual(block, model_printer.print(model)) + assert block == model_printer.print(model) def test_variable(self): var = "V_m" model = ModelParser.parse_variable(var) model_printer = NESTMLPrinter() - self.assertEqual(var, model_printer.print(model)) + assert var == model_printer.print(model) def test_unit_type(self): unit = "1/(mV*kg**2)" model = ModelParser.parse_unit_type(unit) model_printer = NESTMLPrinter() - self.assertEqual(unit, model_printer.print(model)) + assert unit == model_printer.print(model) def test_unary_operator(self): - ops = {"-", "+", "~"} + ops = ["-", "+", "~"] for op in ops: model = ModelParser.parse_unary_operator(op) model_printer = NESTMLPrinter() - self.assertEqual(op, model_printer.print(model)) + assert op == model_printer.print(model) diff --git a/tests/test_unit_system.py b/tests/test_unit_system.py index 2cad0b98d..ab4b5a560 100644 --- a/tests/test_unit_system.py +++ b/tests/test_unit_system.py @@ -72,7 +72,7 @@ def setUp(self, request): def get_first_statement_in_update_block(self, model): if model.get_model_list()[0].get_update_blocks()[0]: - return model.get_model_list()[0].get_update_blocks()[0].get_block().get_stmts()[0] + return model.get_model_list()[0].get_update_blocks()[0].get_stmts_body().get_stmts()[0] return None @@ -103,7 +103,7 @@ def print_rhs_of_first_declaration_in_state_block(self, model): def print_first_return_statement_in_first_declared_function(self, model): func = self.get_first_declared_function(model) - return_expression = func.get_block().get_stmts()[0].small_stmt.get_return_stmt().get_expression() + return_expression = func.get_stmts_body().get_stmts()[0].small_stmt.get_return_stmt().get_expression() return self.printer.print(return_expression) def test_expression_after_magnitude_conversion_in_direct_assignment(self): From ac188a6a02c43b3743f10f82a25cadc698032623 Mon Sep 17 00:00:00 2001 From: "C.A.P. Linssen" Date: Thu, 28 Nov 2024 11:41:39 +0100 Subject: [PATCH 13/25] add include statement --- pynestml/grammars/PyNestMLLexer.g4 | 2 +- pynestml/grammars/PyNestMLParser.g4 | 5 ++--- pynestml/utils/model_parser.py | 2 +- tests/nest_tests/resources/IncludeStatementTest.nestml | 2 +- tests/nest_tests/resources/IncludeStatementTest2.nestml | 2 +- tests/nest_tests/resources/IncludeStatementTest3.nestml | 2 +- tests/nest_tests/resources/IncludeStatementTest4.nestml | 2 +- tests/nest_tests/resources/IncludeStatementTest5.nestml | 8 ++++---- tests/nest_tests/resources/{ => includes}/ModelA.nestml | 0 tests/nest_tests/resources/{ => includes}/ModelB.nestml | 0 tests/nest_tests/resources/{ => includes}/ModelC.nestml | 0 tests/nest_tests/resources/{ => includes}/ModelD.nestml | 0 .../include_statement_model_test_equations_block.nestml | 0 .../include_statement_model_test_parameters_block.nestml | 0 .../include_statement_model_test_state_block.nestml | 0 .../include_statement_model_test_update_block.nestml | 0 tests/nestml_printer_test.py | 2 +- 17 files changed, 13 insertions(+), 14 deletions(-) rename tests/nest_tests/resources/{ => includes}/ModelA.nestml (100%) rename tests/nest_tests/resources/{ => includes}/ModelB.nestml (100%) rename tests/nest_tests/resources/{ => includes}/ModelC.nestml (100%) rename tests/nest_tests/resources/{ => includes}/ModelD.nestml (100%) rename tests/nest_tests/resources/{ => includes}/include_statement_model_test_equations_block.nestml (100%) rename tests/nest_tests/resources/{ => includes}/include_statement_model_test_parameters_block.nestml (100%) rename tests/nest_tests/resources/{ => includes}/include_statement_model_test_state_block.nestml (100%) rename tests/nest_tests/resources/{ => includes}/include_statement_model_test_update_block.nestml (100%) diff --git a/pynestml/grammars/PyNestMLLexer.g4 b/pynestml/grammars/PyNestMLLexer.g4 index 280c22b7a..a489ad7e5 100644 --- a/pynestml/grammars/PyNestMLLexer.g4 +++ b/pynestml/grammars/PyNestMLLexer.g4 @@ -43,7 +43,7 @@ lexer grammar PyNestMLLexer; DOCSTRING : DOCSTRING_TRIPLEQUOTE .*? DOCSTRING_TRIPLEQUOTE NEWLINE_FRAG+? -> channel(2); - SL_COMMENT: ('#' (~('\n' |'\r' ))*) -> channel(2); + SL_COMMENT: ('#' (~('\n' |'\r' ))*) ('\n' | '\r' | '\n\r')? -> channel(2); // newline is defined as a token NEWLINE diff --git a/pynestml/grammars/PyNestMLParser.g4 b/pynestml/grammars/PyNestMLParser.g4 index 4f122c731..d489093b9 100644 --- a/pynestml/grammars/PyNestMLParser.g4 +++ b/pynestml/grammars/PyNestMLParser.g4 @@ -226,7 +226,7 @@ parser grammar PyNestMLParser; @attribute Name: The name of the model, e.g., ht_neuron. @attribute body: The body of the model consisting of several sub-blocks. */ - model : MODEL_KEYWORD NAME modelBody; + model : MODEL_KEYWORD NAME modelBody COLON; /** ASTBody The body of the model, e.g. internal, state, parameter... @attribute blockWithVariables: A single block of variables, e.g. the state block. @@ -236,8 +236,7 @@ parser grammar PyNestMLParser; @attribute updateBlock: A single update block containing the dynamic behavior. @attribute function: A block declaring a user-defined function. */ - modelBody: COLON - NEWLINE INDENT ( includeStmt_newline | blockWithVariables | equationsBlock | inputBlock | outputBlock | function | onReceiveBlock | onConditionBlock | updateBlock )+ DEDENT; + modelBody: NEWLINE INDENT ( includeStmt_newline | blockWithVariables | equationsBlock | inputBlock | outputBlock | function | onReceiveBlock | onConditionBlock | updateBlock )+ DEDENT; /** ASTOnReceiveBlock @attribute block implementation of the dynamics diff --git a/pynestml/utils/model_parser.py b/pynestml/utils/model_parser.py index 7b2b26fe2..01708124d 100644 --- a/pynestml/utils/model_parser.py +++ b/pynestml/utils/model_parser.py @@ -185,7 +185,7 @@ def parse_stmt(cls, string: str) -> Union[ASTStmt, List[ASTStmt]]: except ParseCancellationException: if not stmts: # this is the only the first statement to be visited, and it failed, so there is nothing here that can be parsed as a statement - raise ParseCancellationException() + raise ParseCancellationException("Cannot parse as a statement") # no more statements left to parse break diff --git a/tests/nest_tests/resources/IncludeStatementTest.nestml b/tests/nest_tests/resources/IncludeStatementTest.nestml index 301184ec1..f0e8e001c 100644 --- a/tests/nest_tests/resources/IncludeStatementTest.nestml +++ b/tests/nest_tests/resources/IncludeStatementTest.nestml @@ -35,4 +35,4 @@ model include_statement: v mV = 42 mV update: - include "ModelA.nestml" + include "includes/ModelA.nestml" diff --git a/tests/nest_tests/resources/IncludeStatementTest2.nestml b/tests/nest_tests/resources/IncludeStatementTest2.nestml index 9d5409242..ef12d68a2 100644 --- a/tests/nest_tests/resources/IncludeStatementTest2.nestml +++ b/tests/nest_tests/resources/IncludeStatementTest2.nestml @@ -35,4 +35,4 @@ model include_statement2: v mV = 42 mV update: - include "ModelB.nestml" + include "includes/ModelB.nestml" diff --git a/tests/nest_tests/resources/IncludeStatementTest3.nestml b/tests/nest_tests/resources/IncludeStatementTest3.nestml index 70999709a..4031387fb 100644 --- a/tests/nest_tests/resources/IncludeStatementTest3.nestml +++ b/tests/nest_tests/resources/IncludeStatementTest3.nestml @@ -35,4 +35,4 @@ model include_statement3: v mV = 42 mV update: - include "ModelC.nestml" + include "includes/ModelC.nestml" diff --git a/tests/nest_tests/resources/IncludeStatementTest4.nestml b/tests/nest_tests/resources/IncludeStatementTest4.nestml index 7f8d9598e..687663f98 100644 --- a/tests/nest_tests/resources/IncludeStatementTest4.nestml +++ b/tests/nest_tests/resources/IncludeStatementTest4.nestml @@ -35,4 +35,4 @@ model include_statement4: v mV = 42 mV update: - include "ModelD.nestml" + include "includes/ModelD.nestml" diff --git a/tests/nest_tests/resources/IncludeStatementTest5.nestml b/tests/nest_tests/resources/IncludeStatementTest5.nestml index 627362958..60dd23ec7 100644 --- a/tests/nest_tests/resources/IncludeStatementTest5.nestml +++ b/tests/nest_tests/resources/IncludeStatementTest5.nestml @@ -30,7 +30,7 @@ along with NEST. If not, see . """ model include_statement5: - include "include_statement_model_test_state_block.nestml" - include "include_statement_model_test_parameters_block.nestml" - include "include_statement_model_test_update_block.nestml" - include "include_statement_model_test_equations_block.nestml" + include "includes/include_statement_model_test_state_block.nestml" + include "includes/include_statement_model_test_parameters_block.nestml" + include "includes/include_statement_model_test_update_block.nestml" + include "includes/include_statement_model_test_equations_block.nestml" diff --git a/tests/nest_tests/resources/ModelA.nestml b/tests/nest_tests/resources/includes/ModelA.nestml similarity index 100% rename from tests/nest_tests/resources/ModelA.nestml rename to tests/nest_tests/resources/includes/ModelA.nestml diff --git a/tests/nest_tests/resources/ModelB.nestml b/tests/nest_tests/resources/includes/ModelB.nestml similarity index 100% rename from tests/nest_tests/resources/ModelB.nestml rename to tests/nest_tests/resources/includes/ModelB.nestml diff --git a/tests/nest_tests/resources/ModelC.nestml b/tests/nest_tests/resources/includes/ModelC.nestml similarity index 100% rename from tests/nest_tests/resources/ModelC.nestml rename to tests/nest_tests/resources/includes/ModelC.nestml diff --git a/tests/nest_tests/resources/ModelD.nestml b/tests/nest_tests/resources/includes/ModelD.nestml similarity index 100% rename from tests/nest_tests/resources/ModelD.nestml rename to tests/nest_tests/resources/includes/ModelD.nestml diff --git a/tests/nest_tests/resources/include_statement_model_test_equations_block.nestml b/tests/nest_tests/resources/includes/include_statement_model_test_equations_block.nestml similarity index 100% rename from tests/nest_tests/resources/include_statement_model_test_equations_block.nestml rename to tests/nest_tests/resources/includes/include_statement_model_test_equations_block.nestml diff --git a/tests/nest_tests/resources/include_statement_model_test_parameters_block.nestml b/tests/nest_tests/resources/includes/include_statement_model_test_parameters_block.nestml similarity index 100% rename from tests/nest_tests/resources/include_statement_model_test_parameters_block.nestml rename to tests/nest_tests/resources/includes/include_statement_model_test_parameters_block.nestml diff --git a/tests/nest_tests/resources/include_statement_model_test_state_block.nestml b/tests/nest_tests/resources/includes/include_statement_model_test_state_block.nestml similarity index 100% rename from tests/nest_tests/resources/include_statement_model_test_state_block.nestml rename to tests/nest_tests/resources/includes/include_statement_model_test_state_block.nestml diff --git a/tests/nest_tests/resources/include_statement_model_test_update_block.nestml b/tests/nest_tests/resources/includes/include_statement_model_test_update_block.nestml similarity index 100% rename from tests/nest_tests/resources/include_statement_model_test_update_block.nestml rename to tests/nest_tests/resources/includes/include_statement_model_test_update_block.nestml diff --git a/tests/nestml_printer_test.py b/tests/nestml_printer_test.py index 2ac258a3e..b65792be5 100644 --- a/tests/nestml_printer_test.py +++ b/tests/nestml_printer_test.py @@ -74,7 +74,7 @@ def test_block_with_variables_without_comments(self): def test_assignment_with_comments(self): assignment = " # pre\n" \ " a = b # in\n" - model = ModelParser.parse_block(assignment) + model = ModelParser.parse_assignment(assignment) model_printer = NESTMLPrinter() self.assertEqual(assignment, model_printer.print(model)) From 16e99135f618ebd8d7396eeed0cec6e0978e84a9 Mon Sep 17 00:00:00 2001 From: "C.A.P. Linssen" Date: Thu, 28 Nov 2024 22:05:43 +0100 Subject: [PATCH 14/25] add include statement --- pynestml/grammars/PyNestMLParser.g4 | 2 +- pynestml/visitors/ast_builder_visitor.py | 8 ++++---- pynestml/visitors/ast_include_statement_visitor.py | 6 +++--- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/pynestml/grammars/PyNestMLParser.g4 b/pynestml/grammars/PyNestMLParser.g4 index 4f56dcdf6..260f47528 100644 --- a/pynestml/grammars/PyNestMLParser.g4 +++ b/pynestml/grammars/PyNestMLParser.g4 @@ -205,7 +205,7 @@ parser grammar PyNestMLParser; ifStmt : ifClause elifClause* (elseClause)?; - ifClause : IF_KEYWORD expression COLON + ifClause : IF_KEYWORD expression COLON NEWLINE INDENT stmtsBody DEDENT; elifClause : ELIF_KEYWORD expression COLON diff --git a/pynestml/visitors/ast_builder_visitor.py b/pynestml/visitors/ast_builder_visitor.py index 85df12f7a..26f144a3f 100644 --- a/pynestml/visitors/ast_builder_visitor.py +++ b/pynestml/visitors/ast_builder_visitor.py @@ -348,7 +348,7 @@ def visitSmallStmt(self, ctx): function_call = self.visit(ctx.functionCall()) if ctx.functionCall() is not None else None declaration = self.visit(ctx.declaration()) if ctx.declaration() is not None else None return_stmt = self.visit(ctx.returnStmt()) if ctx.returnStmt() is not None else None - include_stmt = self.visit(ctx.includeStmt()) if ctx.includeStmt() is not None else None + include_stmt = None#self.visit(ctx.includeStmt()) if ctx.includeStmt() is not None else None node = ASTNodeFactory.create_ast_small_stmt(assignment=assignment, function_call=function_call, declaration=declaration, return_stmt=return_stmt, include_stmt=include_stmt, @@ -523,9 +523,9 @@ def visitModelBody(self, ctx): """ body_elements = list() # visit all var_block children - if ctx.includeStmt_newline() is not None: - for child in ctx.includeStmt_newline(): - body_elements.append(child) + # if ctx.includeStmt_newline() is not None: + # for child in ctx.includeStmt_newline(): + # body_elements.append(child) if ctx.onReceiveBlock() is not None: for child in ctx.onReceiveBlock(): body_elements.append(child) diff --git a/pynestml/visitors/ast_include_statement_visitor.py b/pynestml/visitors/ast_include_statement_visitor.py index b1b7a5e12..e35359d74 100644 --- a/pynestml/visitors/ast_include_statement_visitor.py +++ b/pynestml/visitors/ast_include_statement_visitor.py @@ -23,7 +23,6 @@ import os -from pynestml.meta_model.ast_block import ASTBlock from pynestml.meta_model.ast_block_with_variables import ASTBlockWithVariables from pynestml.meta_model.ast_equations_block import ASTEquationsBlock from pynestml.meta_model.ast_expression import ASTExpression @@ -31,6 +30,7 @@ from pynestml.meta_model.ast_model_body import ASTModelBody from pynestml.meta_model.ast_small_stmt import ASTSmallStmt from pynestml.meta_model.ast_stmt import ASTStmt +from pynestml.meta_model.ast_stmts_body import ASTStmtsBody from pynestml.meta_model.ast_update_block import ASTUpdateBlock from pynestml.symbols.boolean_type_symbol import BooleanTypeSymbol from pynestml.symbols.error_type_symbol import ErrorTypeSymbol @@ -82,7 +82,7 @@ def _handle_include_stmt(self, node: ASTIncludeStmt): new_stmts = parsed_included_file include_stmt = node.get_parent().get_parent() - if isinstance(include_stmt.get_parent(), ASTBlock): + if isinstance(include_stmt.get_parent(), ASTStmtsBody): self._replace_statements(include_stmt, new_stmts) elif isinstance(node.get_parent().get_parent(), ASTEquationsBlock): @@ -93,7 +93,7 @@ def _handle_include_stmt(self, node: ASTIncludeStmt): new_stmt = parsed_included_file include_stmt = node.get_parent().get_parent() - if isinstance(include_stmt.get_parent(), ASTBlock): + if isinstance(include_stmt.get_parent(), ASTStmtsBody): self._replace_statements(include_stmt, [new_stmt]) # elif isinstance(node.get_parent().get_parent(), ASTEquationsBlock): From 8076f2ce9165dfd1d1214286747d8a4279361f4c Mon Sep 17 00:00:00 2001 From: "C.A.P. Linssen" Date: Sat, 30 Nov 2024 13:30:09 +0100 Subject: [PATCH 15/25] add include statement --- pynestml/cocos/co_co_all_variables_defined.py | 1 + ...ernals_assigned_only_in_internals_block.py | 5 +- pynestml/cocos/co_cos_manager.py | 1 - .../spinnaker_code_generator.py | 1 - pynestml/frontend/pynestml_frontend.py | 5 +- pynestml/meta_model/ast_small_stmt.py | 1 + pynestml/symbol_table/scope.py | 1 + pynestml/utils/ast_source_location.py | 21 +- ...or_parameter_setter_and_printer_factory.py | 6 - pynestml/utils/messages.py | 5 + pynestml/utils/model_parser.py | 358 ++++++++---------- pynestml/visitors/ast_builder_visitor.py | 8 +- .../visitors/ast_include_statement_visitor.py | 32 +- tests/test_cocos.py | 20 +- tests/test_function_parameter_templating.py | 2 +- 15 files changed, 216 insertions(+), 251 deletions(-) diff --git a/pynestml/cocos/co_co_all_variables_defined.py b/pynestml/cocos/co_co_all_variables_defined.py index bcf102c32..16000ab29 100644 --- a/pynestml/cocos/co_co_all_variables_defined.py +++ b/pynestml/cocos/co_co_all_variables_defined.py @@ -113,6 +113,7 @@ def check_co_co(cls, node: ASTModel): # now check that they are not defined recursively, e.g. V_m mV = V_m + 1 # todo: we should not check this for invariants if (symbol.get_referenced_object().get_source_position().encloses(var.get_source_position()) + and not symbol.get_referenced_object().get_source_position().included_file and not symbol.get_referenced_object().get_source_position().is_added_source_position()): code, message = Messages.get_variable_defined_recursively(var.get_name()) Logger.log_message(code=code, message=message, error_position=symbol.get_referenced_object(). diff --git a/pynestml/cocos/co_co_internals_assigned_only_in_internals_block.py b/pynestml/cocos/co_co_internals_assigned_only_in_internals_block.py index 5e7ff0519..9720abf09 100644 --- a/pynestml/cocos/co_co_internals_assigned_only_in_internals_block.py +++ b/pynestml/cocos/co_co_internals_assigned_only_in_internals_block.py @@ -19,12 +19,9 @@ # You should have received a copy of the GNU General Public License # along with NEST. If not, see . +from pynestml.cocos.co_co import CoCo from pynestml.meta_model.ast_assignment import ASTAssignment from pynestml.meta_model.ast_model import ASTModel -from pynestml.cocos.co_co import CoCo -from pynestml.symbol_table.scope import ScopeType -from pynestml.symbols.symbol import SymbolKind -from pynestml.symbols.variable_symbol import BlockType from pynestml.utils.ast_utils import ASTUtils from pynestml.utils.logger import LoggingLevel, Logger from pynestml.utils.messages import Messages diff --git a/pynestml/cocos/co_cos_manager.py b/pynestml/cocos/co_cos_manager.py index fe2a23ed7..6858151f0 100644 --- a/pynestml/cocos/co_cos_manager.py +++ b/pynestml/cocos/co_cos_manager.py @@ -70,7 +70,6 @@ from pynestml.cocos.co_co_vector_parameter_declared_in_right_block import CoCoVectorParameterDeclaredInRightBlock from pynestml.cocos.co_co_vector_variable_in_non_vector_declaration import CoCoVectorVariableInNonVectorDeclaration from pynestml.frontend.frontend_configuration import FrontendConfiguration -from pynestml.utils.logger import Logger from pynestml.meta_model.ast_model import ASTModel from pynestml.utils.logger import Logger diff --git a/pynestml/codegeneration/spinnaker_code_generator.py b/pynestml/codegeneration/spinnaker_code_generator.py index f7ff7752f..0fab611ed 100644 --- a/pynestml/codegeneration/spinnaker_code_generator.py +++ b/pynestml/codegeneration/spinnaker_code_generator.py @@ -219,5 +219,4 @@ def generate_code(self, models: Sequence[ASTModel]) -> None: cloned_models.append(cloned_model) self.codegen_cpp.generate_code(cloned_models) - CoCosManager.check_cocos(cloned_model) self.codegen_py.generate_code(cloned_models) diff --git a/pynestml/frontend/pynestml_frontend.py b/pynestml/frontend/pynestml_frontend.py index 60441e054..6eee8b45e 100644 --- a/pynestml/frontend/pynestml_frontend.py +++ b/pynestml/frontend/pynestml_frontend.py @@ -497,15 +497,14 @@ def process() -> bool: # validation -- check cocos for models that do not have errors already excluded_models = [] for model in models: - if not Logger.has_errors(model.name): - CoCosManager.check_cocos(model) - if Logger.has_errors(model.name): code, message = Messages.get_model_contains_errors(model.get_name()) Logger.log_message(node=model, code=code, message=message, error_position=model.get_source_position(), log_level=LoggingLevel.WARNING) excluded_models.append(model) + else: + CoCosManager.check_cocos(model) # exclude models that have errors models = list(set(models) - set(excluded_models)) diff --git a/pynestml/meta_model/ast_small_stmt.py b/pynestml/meta_model/ast_small_stmt.py index 84e5e08d5..5e63b7dc0 100644 --- a/pynestml/meta_model/ast_small_stmt.py +++ b/pynestml/meta_model/ast_small_stmt.py @@ -57,6 +57,7 @@ def __init__(self, assignment: Optional[ASTAssignment] = None, function_call: Op self.declaration = declaration self.return_stmt = return_stmt self.include_stmt = include_stmt + assert self.assignment or self.function_call or self.declaration or self.return_stmt or self.include_stmt def clone(self): """ diff --git a/pynestml/symbol_table/scope.py b/pynestml/symbol_table/scope.py index 650c0bd59..0ff7cd5f3 100644 --- a/pynestml/symbol_table/scope.py +++ b/pynestml/symbol_table/scope.py @@ -41,6 +41,7 @@ class ScopeType(Enum): FUNCTION = 3 ON_RECEIVE = 4 ON_CONDITION = 5 + INCLUDED_FILE = 6 class Scope: diff --git a/pynestml/utils/ast_source_location.py b/pynestml/utils/ast_source_location.py index 35a6e55fd..3134b9ba2 100644 --- a/pynestml/utils/ast_source_location.py +++ b/pynestml/utils/ast_source_location.py @@ -18,6 +18,7 @@ # # You should have received a copy of the GNU General Public License # along with NEST. If not, see . + import sys @@ -47,6 +48,7 @@ def __init__(self, start_line, start_column, end_line, end_column): self.start_column = start_column self.end_line = end_line self.end_column = end_column + self.included_file = None @classmethod def make_ast_source_position(cls, start_line, start_column, end_line, end_column): @@ -197,16 +199,23 @@ def encloses(self, source_position): else: return False - def __str__(self): + def __str__(self) -> str: """ A string representation of this source position. :return: a string representation - :rtype: str """ + s = "[" + if self.included_file: + s += "In code included from '" + self.included_file + "': " + if self.is_added_source_position(): - return '' + s += "ADDED_BY_SOLVER" elif self.is_predefined_source_position(): - return '' + s += "PREDEFINED" else: - return '[' + str(self.get_start_line()) + ':' + str(self.get_start_column()) + ';' + \ - str(self.get_end_line()) + ':' + str(self.get_end_column()) + ']' + s += str(self.get_start_line()) + ':' + str(self.get_start_column()) + ';' \ + + str(self.get_end_line()) + ':' + str(self.get_end_column()) + + s += "]" + + return s diff --git a/pynestml/utils/ast_vector_parameter_setter_and_printer_factory.py b/pynestml/utils/ast_vector_parameter_setter_and_printer_factory.py index 13c3b08d5..4deabb691 100644 --- a/pynestml/utils/ast_vector_parameter_setter_and_printer_factory.py +++ b/pynestml/utils/ast_vector_parameter_setter_and_printer_factory.py @@ -20,12 +20,6 @@ # along with NEST. If not, see . from pynestml.utils.ast_vector_parameter_setter_and_printer import ASTVectorParameterSetterAndPrinter -from pynestml.visitors.ast_visitor import ASTVisitor - -from pynestml.utils.model_parser import ModelParser -from pynestml.visitors.ast_symbol_table_visitor import ASTSymbolTableVisitor -from pynestml.symbol_table.scope import Scope, ScopeType, Symbol, SymbolKind -from pynestml.symbols.variable_symbol import VariableSymbol class ASTVectorParameterSetterAndPrinterFactory: diff --git a/pynestml/utils/messages.py b/pynestml/utils/messages.py index ce2913c7b..f6451751b 100644 --- a/pynestml/utils/messages.py +++ b/pynestml/utils/messages.py @@ -195,6 +195,11 @@ def get_parser_error(cls): message = 'Error occurred during parsing: abort' return MessageCode.PARSER_ERROR, message + @classmethod + def get_parser_error_verbose(cls, string: str): + message = 'Parse error: ' + string + return MessageCode.PARSER_ERROR, message + @classmethod def get_binary_operation_not_defined(cls, lhs, operator, rhs): message = 'Operation %s %s %s is not defined!' % (lhs, operator, rhs) diff --git a/pynestml/utils/model_parser.py b/pynestml/utils/model_parser.py index cc1235a30..4e7f60682 100644 --- a/pynestml/utils/model_parser.py +++ b/pynestml/utils/model_parser.py @@ -50,6 +50,7 @@ from pynestml.meta_model.ast_input_block import ASTInputBlock from pynestml.meta_model.ast_input_port import ASTInputPort from pynestml.meta_model.ast_input_qualifier import ASTInputQualifier +from pynestml.meta_model.ast_kernel import ASTKernel from pynestml.meta_model.ast_logical_operator import ASTLogicalOperator from pynestml.meta_model.ast_nestml_compilation_unit import ASTNestMLCompilationUnit from pynestml.meta_model.ast_model import ASTModel @@ -69,7 +70,11 @@ from pynestml.meta_model.ast_update_block import ASTUpdateBlock from pynestml.meta_model.ast_variable import ASTVariable from pynestml.meta_model.ast_while_stmt import ASTWhileStmt +from pynestml.symbol_table.scope import Scope, ScopeType from pynestml.symbol_table.symbol_table import SymbolTable +from pynestml.symbols.predefined_functions import PredefinedFunctions +from pynestml.symbols.predefined_types import PredefinedTypes +from pynestml.symbols.predefined_variables import PredefinedVariables from pynestml.utils.ast_source_location import ASTSourceLocation from pynestml.utils.error_listener import NestMLErrorListener from pynestml.utils.logger import Logger, LoggingLevel @@ -149,6 +154,10 @@ def parse_file(cls, file_path=None): model.accept(ASTSymbolTableVisitor()) SymbolTable.add_model_scope(model.get_name(), model.get_scope()) + # ....... + for model in ast.get_model_list(): + model.accept(AssignImplicitConversionFactorsVisitor()) + # store source paths for model in ast.get_model_list(): model.file_path = file_path @@ -158,334 +167,283 @@ def parse_file(cls, file_path=None): return ast @classmethod - def parse_expression(cls, string): - # type: (str) -> ASTExpression - (builder, parser) = tokenize(string) + def parse_expression(cls, string: str, verbose: bool = True) -> ASTExpression: + (builder, parser) = tokenize(string, verbose=verbose) ret = builder.visit(parser.expression()) - ret.accept(ASTHigherOrderVisitor(log_set_added_source_position)) + return ret @classmethod - def parse_declaration(cls, string): - # type: (str) -> ASTDeclaration - (builder, parser) = tokenize(string) + def parse_declaration(cls, string: str, verbose: bool = True) -> ASTDeclaration: + (builder, parser) = tokenize(string, verbose=verbose) ret = builder.visit(parser.declaration()) - ret.accept(ASTHigherOrderVisitor(log_set_added_source_position)) + return ret @classmethod - def parse_stmt(cls, string: str) -> Union[ASTStmt, List[ASTStmt]]: - # type: (str) -> ASTStmt - stmts = [] - (builder, parser) = tokenize(string) - while True: - try: - stmt = builder.visit(parser.stmt()) - stmts.append(stmt) - except ParseCancellationException: - if not stmts: - # this is the only the first statement to be visited, and it failed, so there is nothing here that can be parsed as a statement - raise ParseCancellationException("Cannot parse as a statement") - - # no more statements left to parse - break - - if len(stmts) == 1: - return stmts[0] + def parse_stmt(cls, string: str, verbose: bool = True) -> ASTStmt: + (builder, parser) = tokenize(string, verbose=verbose) + ret = builder.visit(parser.stmt()) - return stmts + return ret @classmethod - def parse_assignment(cls, string): - # type: (str) -> ASTAssignment - (builder, parser) = tokenize(string) + def parse_assignment(cls, string: str, verbose: bool = True) -> ASTAssignment: + (builder, parser) = tokenize(string, verbose=verbose) ret = builder.visit(parser.assignment()) - ret.accept(ASTHigherOrderVisitor(log_set_added_source_position)) + return ret @classmethod - def parse_bit_operator(cls, string): - # type: (str) -> ASTArithmeticOperator - builder, parser = tokenize(string) + def parse_bit_operator(cls, string: str, verbose: bool = True) -> ASTArithmeticOperator: + builder, parser = tokenize(string, verbose=verbose) ret = builder.visit(parser.bitOperator()) - ret.accept(ASTHigherOrderVisitor(log_set_added_source_position)) + return ret @classmethod - def parse_block_with_variables(cls, string): - # type: (str) -> ASTBlockWithVariables - (builder, parser) = tokenize(string) + def parse_block_with_variables(cls, string: str, verbose: bool = True) -> ASTBlockWithVariables: + (builder, parser) = tokenize(string, verbose=verbose) ret = builder.visit(parser.blockWithVariables()) - ret.accept(ASTHigherOrderVisitor(log_set_added_source_position)) + return ret @classmethod - def parse_model_body(cls, string: str) -> ASTModelBody: - (builder, parser) = tokenize(string) + def parse_model_body(cls, string: str, verbose: bool = True) -> ASTModelBody: + (builder, parser) = tokenize(string, verbose=verbose) ret = builder.visit(parser.modelBody()) - ret.accept(ASTHigherOrderVisitor(log_set_added_source_position)) + return ret @classmethod - def parse_comparison_operator(cls, string): - # type: (str) -> ASTComparisonOperator - (builder, parser) = tokenize(string) + def parse_comparison_operator(cls, string: str, verbose: bool = True) -> ASTComparisonOperator: + (builder, parser) = tokenize(string, verbose=verbose) ret = builder.visit(parser.comparisonOperator()) - ret.accept(ASTHigherOrderVisitor(log_set_added_source_position)) + return ret @classmethod - def parse_compound_stmt(cls, string): - # type: (str) -> ASTCompoundStmt - (builder, parser) = tokenize(string) + def parse_compound_stmt(cls, string: str, verbose: bool = True) -> ASTCompoundStmt: + (builder, parser) = tokenize(string, verbose=verbose) ret = builder.visit(parser.compoundStmt()) - ret.accept(ASTHigherOrderVisitor(log_set_added_source_position)) + return ret @classmethod - def parse_data_type(cls, string): - # type: (str) -> ASTDataType - (builder, parser) = tokenize(string) + def parse_data_type(cls, string: str, verbose: bool = True) -> ASTDataType: + (builder, parser) = tokenize(string, verbose=verbose) ret = builder.visit(parser.dataType()) - ret.accept(ASTHigherOrderVisitor(log_set_added_source_position)) + return ret @classmethod - def parse_elif_clause(cls, string): - # type: (str) -> ASTElifClause - (builder, parser) = tokenize(string) + def parse_elif_clause(cls, string: str, verbose: bool = True) -> ASTElifClause: + (builder, parser) = tokenize(string, verbose=verbose) ret = builder.visit(parser.elifClause()) - ret.accept(ASTHigherOrderVisitor(log_set_added_source_position)) + return ret @classmethod - def parse_else_clause(cls, string): - # type: (str) -> ASTElseClause - (builder, parser) = tokenize(string) + def parse_else_clause(cls, string: str, verbose: bool = True) -> ASTElseClause: + (builder, parser) = tokenize(string, verbose=verbose) ret = builder.visit(parser.elseClause()) - ret.accept(ASTHigherOrderVisitor(log_set_added_source_position)) + return ret @classmethod - def parse_equations_block(cls, string): - # type: (str) -> ASTEquationsBlock - (builder, parser) = tokenize(string) + def parse_equations_block(cls, string: str, verbose: bool = True) -> ASTEquationsBlock: + (builder, parser) = tokenize(string, verbose=verbose) ret = builder.visit(parser.equationsBlock()) - ret.accept(ASTHigherOrderVisitor(log_set_added_source_position)) + return ret @classmethod - def parse_for_stmt(cls, string): - # type: (str) -> ASTForStmt - (builder, parser) = tokenize(string) + def parse_for_stmt(cls, string: str, verbose: bool = True) -> ASTForStmt: + (builder, parser) = tokenize(string, verbose=verbose) ret = builder.visit(parser.forStmt()) - ret.accept(ASTHigherOrderVisitor(log_set_added_source_position)) + return ret @classmethod - def parse_function(cls, string): - # type: (str) -> ASTFunction - (builder, parser) = tokenize(string) + def parse_function(cls, string: str, verbose: bool = True) -> ASTFunction: + (builder, parser) = tokenize(string, verbose=verbose) ret = builder.visit(parser.function()) - ret.accept(ASTHigherOrderVisitor(log_set_added_source_position)) + return ret @classmethod - def parse_function_call(cls, string): - # type: (str) -> ASTFunctionCall - (builder, parser) = tokenize(string) + def parse_function_call(cls, string: str, verbose: bool = True) -> ASTFunctionCall: + (builder, parser) = tokenize(string, verbose=verbose) ret = builder.visit(parser.functionCall()) - ret.accept(ASTHigherOrderVisitor(log_set_added_source_position)) + return ret @classmethod - def parse_if_clause(cls, string): - # type: (str) -> ASTIfClause - (builder, parser) = tokenize(string) + def parse_if_clause(cls, string: str, verbose: bool = True) -> ASTIfClause: + (builder, parser) = tokenize(string, verbose=verbose) ret = builder.visit(parser.ifClause()) - ret.accept(ASTHigherOrderVisitor(log_set_added_source_position)) + return ret @classmethod - def parse_if_stmt(cls, string): - # type: (str) -> ASTIfStmt - (builder, parser) = tokenize(string) + def parse_if_stmt(cls, string: str, verbose: bool = True) -> ASTIfStmt: + (builder, parser) = tokenize(string, verbose=verbose) ret = builder.visit(parser.ifStmt()) - ret.accept(ASTHigherOrderVisitor(log_set_added_source_position)) + return ret @classmethod - def parse_input_block(cls, string): - # type: (str) -> ASTInputBlock - (builder, parser) = tokenize(string) + def parse_input_block(cls, string: str, verbose: bool = True) -> ASTInputBlock: + (builder, parser) = tokenize(string, verbose=verbose) ret = builder.visit(parser.inputBlock()) - ret.accept(ASTHigherOrderVisitor(log_set_added_source_position)) + return ret @classmethod - def parse_input_port(cls, string): - # type: (str) -> ASTInputPort - (builder, parser) = tokenize(string) + def parse_input_port(cls, string: str, verbose: bool = True) -> ASTInputPort: + (builder, parser) = tokenize(string, verbose=verbose) ret = builder.visit(parser.inputPort()) - ret.accept(ASTHigherOrderVisitor(log_set_added_source_position)) + return ret @classmethod - def parse_input_qualifier(cls, string): - # type: (str) -> ASTInputQualifier - (builder, parser) = tokenize(string) + def parse_input_qualifier(cls, string: str, verbose: bool = True) -> ASTInputQualifier: + (builder, parser) = tokenize(string, verbose=verbose) ret = builder.visit(parser.inputQualifier()) - ret.accept(ASTHigherOrderVisitor(log_set_added_source_position)) + return ret @classmethod - def parse_logic_operator(cls, string): - # type: (str) -> ASTLogicalOperator - (builder, parser) = tokenize(string) + def parse_logic_operator(cls, string: str, verbose: bool = True) -> ASTLogicalOperator: + (builder, parser) = tokenize(string, verbose=verbose) ret = builder.visit(parser.logicalOperator()) - ret.accept(ASTHigherOrderVisitor(log_set_added_source_position)) + return ret @classmethod - def parse_nestml_compilation_unit(cls, string): - # type: (str) -> ASTNestMLCompilationUnit - (builder, parser) = tokenize(string) + def parse_nestml_compilation_unit(cls, string: str, verbose: bool = True) -> ASTNestMLCompilationUnit: + (builder, parser) = tokenize(string, verbose=verbose) ret = builder.visit(parser.nestMLCompilationUnit()) - ret.accept(ASTHigherOrderVisitor(log_set_added_source_position)) + return ret @classmethod - def parse_model(cls, string): - # type: (str) -> ASTModel - (builder, parser) = tokenize(string) + def parse_model(cls, string: str, verbose: bool = True) -> ASTModel: + (builder, parser) = tokenize(string, verbose=verbose) ret = builder.visit(parser.model()) - ret.accept(ASTHigherOrderVisitor(log_set_added_source_position)) + return ret @classmethod - def parse_ode_equation(cls, string): - # type: (str) -> ASTOdeEquation - (builder, parser) = tokenize(string) + def parse_ode_equation(cls, string: str, verbose: bool = True) -> ASTOdeEquation: + (builder, parser) = tokenize(string, verbose=verbose) ret = builder.visit(parser.odeEquation()) - ret.accept(ASTHigherOrderVisitor(log_set_added_source_position)) + return ret @classmethod - def parse_inline_expression(cls, string): - # type: (str) -> ASTInlineExpression - (builder, parser) = tokenize(string) + def parse_inline_expression(cls, string: str, verbose: bool = True) -> ASTInlineExpression: + (builder, parser) = tokenize(string, verbose=verbose) ret = builder.visit(parser.inlineExpression()) - ret.accept(ASTHigherOrderVisitor(log_set_added_source_position)) + return ret @classmethod - def parse_kernel(cls, string): - # type: (str) -> ASTKernel - (builder, parser) = tokenize(string) + def parse_kernel(cls, string: str, verbose: bool = True) -> ASTKernel: + (builder, parser) = tokenize(string, verbose=verbose) ret = builder.visit(parser.kernel()) - ret.accept(ASTHigherOrderVisitor(log_set_added_source_position)) + return ret @classmethod - def parse_output_block(cls, string): - # type: (str) -> ASTOutputBlock - (builder, parser) = tokenize(string) + def parse_output_block(cls, string: str, verbose: bool = True) -> ASTOutputBlock: + (builder, parser) = tokenize(string, verbose=verbose) ret = builder.visit(parser.outputBlock()) - ret.accept(ASTHigherOrderVisitor(log_set_added_source_position)) + return ret @classmethod - def parse_on_receive_block(cls, string: str) -> ASTOnReceiveBlock: - (builder, parser) = tokenize(string) + def parse_on_receive_block(cls, string: str, verbose: bool = True) -> ASTOnReceiveBlock: + (builder, parser) = tokenize(string, verbose=verbose) ret = builder.visit(parser.onReceiveBlock()) - ret.accept(ASTHigherOrderVisitor(log_set_added_source_position)) + return ret @classmethod - def parse_on_condition_block(cls, string: str) -> ASTOnConditionBlock: - (builder, parser) = tokenize(string) + def parse_on_condition_block(cls, string: str, verbose: bool = True) -> ASTOnConditionBlock: + (builder, parser) = tokenize(string, verbose=verbose) ret = builder.visit(parser.onConditionBlock()) - ret.accept(ASTHigherOrderVisitor(log_set_added_source_position)) + return ret @classmethod - def parse_parameter(cls, string): - # type: (str) -> ASTParameter - (builder, parser) = tokenize(string) + def parse_parameter(cls, string: str, verbose: bool = True) -> ASTParameter: + (builder, parser) = tokenize(string, verbose=verbose) ret = builder.visit(parser.parameter()) - ret.accept(ASTHigherOrderVisitor(log_set_added_source_position)) + return ret @classmethod - def parse_return_stmt(cls, string): - # type: (str) -> ASTReturnStmt - (builder, parser) = tokenize(string) + def parse_return_stmt(cls, string: str, verbose: bool = True) -> ASTReturnStmt: + (builder, parser) = tokenize(string, verbose=verbose) ret = builder.visit(parser.returnStmt()) - ret.accept(ASTHigherOrderVisitor(log_set_added_source_position)) + return ret @classmethod - def parse_simple_expression(cls, string): - # type: (str) -> ASTSimpleExpression - (builder, parser) = tokenize(string) + def parse_simple_expression(cls, string: str, verbose: bool = True) -> ASTSimpleExpression: + (builder, parser) = tokenize(string, verbose=verbose) ret = builder.visit(parser.simpleExpression()) - ret.accept(ASTHigherOrderVisitor(log_set_added_source_position)) + return ret @classmethod - def parse_small_stmt(cls, string): - # type: (str) -> ASTSmallStmt - (builder, parser) = tokenize(string) + def parse_small_stmt(cls, string: str, verbose: bool = True) -> ASTSmallStmt: + (builder, parser) = tokenize(string, verbose=verbose) ret = builder.visit(parser.smallStmt()) - ret.accept(ASTHigherOrderVisitor(log_set_added_source_position)) + return ret @classmethod - def parse_unary_operator(cls, string): - # type: (str) -> ASTUnaryOperator - (builder, parser) = tokenize(string) + def parse_unary_operator(cls, string: str, verbose: bool = True) -> ASTUnaryOperator: + (builder, parser) = tokenize(string, verbose=verbose) ret = builder.visit(parser.unaryOperator()) - ret.accept(ASTHigherOrderVisitor(log_set_added_source_position)) + return ret @classmethod - def parse_unit_type(cls, string): - # type: (str) -> ASTUnitType - (builder, parser) = tokenize(string) + def parse_unit_type(cls, string: str, verbose: bool = True) -> ASTUnitType: + (builder, parser) = tokenize(string, verbose=verbose) ret = builder.visit(parser.unitType()) - ret.accept(ASTHigherOrderVisitor(log_set_added_source_position)) + return ret @classmethod - def parse_update_block(cls, string): - # type: (str) -> ASTUpdateBlock - (builder, parser) = tokenize(string) + def parse_update_block(cls, string: str, verbose: bool = True) -> ASTUpdateBlock: + (builder, parser) = tokenize(string, verbose=verbose) ret = builder.visit(parser.updateBlock()) - ret.accept(ASTHigherOrderVisitor(log_set_added_source_position)) + return ret @classmethod - def parse_variable(cls, string): - # type: (str) -> ASTVariable - (builder, parser) = tokenize(string) + def parse_variable(cls, string: str, verbose: bool = True) -> ASTVariable: + (builder, parser) = tokenize(string, verbose=verbose) ret = builder.visit(parser.variable()) - ret.accept(ASTHigherOrderVisitor(log_set_added_source_position)) + return ret @classmethod - def parse_while_stmt(cls, string): - # type: (str) -> ASTWhileStmt - (builder, parser) = tokenize(string) + def parse_while_stmt(cls, string: str, verbose: bool = True) -> ASTWhileStmt: + (builder, parser) = tokenize(string, verbose=verbose) ret = builder.visit(parser.whileStmt()) - ret.accept(ASTHigherOrderVisitor(log_set_added_source_position)) + return ret @classmethod - def parse_stmts_body(cls, string): - # type: (str) -> ASTStmtsBody - (builder, parser) = tokenize(string) + def parse_stmts_body(cls, string: str, verbose: bool = True) -> ASTStmtsBody: + (builder, parser) = tokenize(string, verbose=verbose) ret = builder.visit(parser.stmtsBody()) - ret.accept(ASTHigherOrderVisitor(log_set_added_source_position)) + return ret @classmethod @@ -494,73 +452,73 @@ def parse_included_file(cls, filename: str) -> Union[ASTNode, List[ASTNode]]: lines = file.read() ast = None try: - ast = ModelParser.parse_model(lines) + ast = ModelParser.parse_model(lines, verbose=False) except (ParseCancellationException, AttributeError): pass if not ast: try: - ast = ModelParser.parse_model_body(lines) + ast = ModelParser.parse_model_body(lines, verbose=False) except (ParseCancellationException, AttributeError): pass if not ast: try: - ast = ModelParser.parse_block_with_variables(lines) + ast = ModelParser.parse_block_with_variables(lines, verbose=False) except (ParseCancellationException, AttributeError): pass if not ast: try: - ast = ModelParser.parse_equations_block(lines) + ast = ModelParser.parse_equations_block(lines, verbose=False) except (ParseCancellationException, AttributeError): pass if not ast: try: - ast = ModelParser.parse_input_block(lines) + ast = ModelParser.parse_input_block(lines, verbose=False) except (ParseCancellationException, AttributeError): pass if not ast: try: - ast = ModelParser.parse_output_block(lines) + ast = ModelParser.parse_output_block(lines, verbose=False) except (ParseCancellationException, AttributeError): pass if not ast: try: - ast = ModelParser.parse_on_receive_block(lines) + ast = ModelParser.parse_on_receive_block(lines, verbose=False) except (ParseCancellationException, AttributeError): pass if not ast: try: - ast = ModelParser.parse_on_condition_block(lines) + ast = ModelParser.parse_on_condition_block(lines, verbose=False) except (ParseCancellationException, AttributeError): pass if not ast: try: - ast = ModelParser.parse_update_block(lines) + ast = ModelParser.parse_update_block(lines, verbose=False) except (ParseCancellationException, AttributeError): pass if not ast: try: - ast = ModelParser.parse_block(lines) + ast = ModelParser.parse_stmts_body(lines, verbose=False) except (ParseCancellationException, AttributeError): pass if not ast: try: - ast = ModelParser.parse_stmt(lines) + ast = ModelParser.parse_stmt(lines, verbose=False) except (ParseCancellationException, AttributeError): pass if not ast: try: - ast = ModelParser.parse_small_stmt(lines) + ast = ModelParser.parse_small_stmt(lines, verbose=False) except (ParseCancellationException, AttributeError): pass @@ -569,25 +527,29 @@ def parse_included_file(cls, filename: str) -> Union[ASTNode, List[ASTNode]]: return ast -class BailConsoleErrorListener(ErrorListener): - """Print error message to the console as well as bail""" - def syntaxError(self, recognizer, offendingSymbol, line, column, msg, e): - s = "line " + str(line) + ":" + str(column) + " " + msg - print(s) - raise ParseCancellationException(s) - - -def tokenize(string: str) -> Tuple[ASTBuilderVisitor, PyNestMLParser]: - lexer = PyNestMLLexer() +def tokenize(string: str, verbose: bool = True) -> Tuple[ASTBuilderVisitor, PyNestMLParser]: + lexer = PyNestMLLexer(InputStream(string)) + # create a token stream stream = CommonTokenStream(lexer) stream.fill() - - parser.addErrorListener(BailConsoleErrorListener()) + parser = PyNestMLParser(stream) + if verbose: + parser.addErrorListener(BailConsoleErrorListener()) + else: + parser._errHandler = BailErrorStrategy() + parser._errHandler.reset(parser) builder = ASTBuilderVisitor(stream.tokens) return builder, parser -def log_set_added_source_position(node): - node.set_source_position(ASTSourceLocation.get_added_source_position()) +class BailConsoleErrorListener(ErrorListener): + """Print error message to the console as well as bail""" + def syntaxError(self, recognizer, offendingSymbol, line, column, msg, e): + code, message = Messages.get_parser_error_verbose(msg) + Logger.log_message(message=message, + error_position=ASTSourceLocation(start_line=line, start_column=column, end_line=line, end_column=column + 1), + code=code, + log_level=LoggingLevel.ERROR) + raise ParseCancellationException(message) diff --git a/pynestml/visitors/ast_builder_visitor.py b/pynestml/visitors/ast_builder_visitor.py index 26f144a3f..85df12f7a 100644 --- a/pynestml/visitors/ast_builder_visitor.py +++ b/pynestml/visitors/ast_builder_visitor.py @@ -348,7 +348,7 @@ def visitSmallStmt(self, ctx): function_call = self.visit(ctx.functionCall()) if ctx.functionCall() is not None else None declaration = self.visit(ctx.declaration()) if ctx.declaration() is not None else None return_stmt = self.visit(ctx.returnStmt()) if ctx.returnStmt() is not None else None - include_stmt = None#self.visit(ctx.includeStmt()) if ctx.includeStmt() is not None else None + include_stmt = self.visit(ctx.includeStmt()) if ctx.includeStmt() is not None else None node = ASTNodeFactory.create_ast_small_stmt(assignment=assignment, function_call=function_call, declaration=declaration, return_stmt=return_stmt, include_stmt=include_stmt, @@ -523,9 +523,9 @@ def visitModelBody(self, ctx): """ body_elements = list() # visit all var_block children - # if ctx.includeStmt_newline() is not None: - # for child in ctx.includeStmt_newline(): - # body_elements.append(child) + if ctx.includeStmt_newline() is not None: + for child in ctx.includeStmt_newline(): + body_elements.append(child) if ctx.onReceiveBlock() is not None: for child in ctx.onReceiveBlock(): body_elements.append(child) diff --git a/pynestml/visitors/ast_include_statement_visitor.py b/pynestml/visitors/ast_include_statement_visitor.py index e35359d74..adeaff88a 100644 --- a/pynestml/visitors/ast_include_statement_visitor.py +++ b/pynestml/visitors/ast_include_statement_visitor.py @@ -19,7 +19,7 @@ # You should have received a copy of the GNU General Public License # along with NEST. If not, see . -from typing import Optional +from typing import List, Optional import os @@ -28,6 +28,7 @@ from pynestml.meta_model.ast_expression import ASTExpression from pynestml.meta_model.ast_include_stmt import ASTIncludeStmt from pynestml.meta_model.ast_model_body import ASTModelBody +from pynestml.meta_model.ast_node import ASTNode from pynestml.meta_model.ast_small_stmt import ASTSmallStmt from pynestml.meta_model.ast_stmt import ASTStmt from pynestml.meta_model.ast_stmts_body import ASTStmtsBody @@ -37,6 +38,7 @@ from pynestml.symbols.predefined_types import PredefinedTypes from pynestml.symbols.string_type_symbol import StringTypeSymbol from pynestml.symbols.unit_type_symbol import UnitTypeSymbol +from pynestml.utils.ast_source_location import ASTSourceLocation from pynestml.utils.logger import Logger, LoggingLevel from pynestml.utils.messages import MessageCode, Messages from pynestml.utils.model_parser import ModelParser @@ -62,7 +64,7 @@ def visit_small_stmt(self, node: ASTSmallStmt): if node.is_include_stmt(): self._handle_include_stmt(node.get_include_stmt()) - def _replace_statements(self, include_stmt, new_stmts): + def _replace_statements(self, include_stmt: ASTIncludeStmt, new_stmts: List[ASTStmt]): blk = include_stmt.get_parent() idx = blk.get_stmts().index(include_stmt) blk.get_stmts().pop(idx) @@ -70,6 +72,7 @@ def _replace_statements(self, include_stmt, new_stmts): for new_stmt in new_stmts: new_stmt.parent_ = blk blk.accept(ASTParentVisitor()) + new_stmt.source_position.included_file = include_stmt.small_stmt.get_include_stmt().get_filename() def _handle_include_stmt(self, node: ASTIncludeStmt): filename = node.get_filename() @@ -78,28 +81,23 @@ def _handle_include_stmt(self, node: ASTIncludeStmt): parsed_included_file = ModelParser.parse_included_file(filename) - if isinstance(parsed_included_file, list): - new_stmts = parsed_included_file - include_stmt = node.get_parent().get_parent() + class IncludedFileSourcePositionVisitor(ASTVisitor): + def visit(self, node: ASTNode): + node.source_position.included_file = filename - if isinstance(include_stmt.get_parent(), ASTStmtsBody): - self._replace_statements(include_stmt, new_stmts) + parsed_included_file.accept(IncludedFileSourcePositionVisitor()) - elif isinstance(node.get_parent().get_parent(), ASTEquationsBlock): - print("not handled yet 4") - assert False + if isinstance(parsed_included_file, ASTStmtsBody): + new_stmts = parsed_included_file.get_stmts() + include_stmt = node.get_parent().get_parent() + + self._replace_statements(include_stmt, new_stmts) elif isinstance(parsed_included_file, ASTStmt): new_stmt = parsed_included_file include_stmt = node.get_parent().get_parent() - if isinstance(include_stmt.get_parent(), ASTStmtsBody): - self._replace_statements(include_stmt, [new_stmt]) - - # elif isinstance(node.get_parent().get_parent(), ASTEquationsBlock): - else: - print("not handled yet 1") - assert False + self._replace_statements(include_stmt, [new_stmt]) elif isinstance(parsed_included_file, ASTBlockWithVariables) or isinstance(parsed_included_file, ASTUpdateBlock) or isinstance(parsed_included_file, ASTEquationsBlock): new_blk = parsed_included_file diff --git a/tests/test_cocos.py b/tests/test_cocos.py index 63a862a7a..e654c98c8 100644 --- a/tests/test_cocos.py +++ b/tests/test_cocos.py @@ -78,7 +78,7 @@ def test_valid_integrate_odes_called_if_equations_defined(self): def test_invalid_element_not_defined_in_scope(self): model = self._parse_and_validate_model(os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'invalid')), 'CoCoVariableNotDefined.nestml')) - assert len(Logger.get_all_messages_of_level_and_or_node(model, LoggingLevel.ERROR)) == 6 + assert len(Logger.get_all_messages_of_level_and_or_node(model, LoggingLevel.ERROR)) == 7 def test_valid_element_not_defined_in_scope(self): model = self._parse_and_validate_model(os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'valid')), 'CoCoVariableNotDefined.nestml')) @@ -107,7 +107,7 @@ def test_valid_each_block_unique(self): def test_invalid_function_unique_and_defined(self): model = self._parse_and_validate_model(os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'invalid')), 'CoCoFunctionNotUnique.nestml')) - assert len(Logger.get_all_messages_of_level_and_or_node(model, LoggingLevel.ERROR)) == 8 + assert len(Logger.get_all_messages_of_level_and_or_node(model, LoggingLevel.ERROR)) == 12 def test_valid_function_unique_and_defined(self): model = self._parse_and_validate_model(os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'valid')), 'CoCoFunctionNotUnique.nestml')) @@ -147,7 +147,7 @@ def test_valid_order_of_equations_correct(self): def test_invalid_numerator_of_unit_one(self): model = self._parse_and_validate_model(os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'invalid')), 'CoCoUnitNumeratorNotOne.nestml')) - assert len(Logger.get_all_messages_of_level_and_or_node(model, LoggingLevel.ERROR)) == 2 + assert len(Logger.get_all_messages_of_level_and_or_node(model, LoggingLevel.ERROR)) == 3 def test_valid_numerator_of_unit_one(self): model = self._parse_and_validate_model(os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'valid')), 'CoCoUnitNumeratorNotOne.nestml')) @@ -199,7 +199,7 @@ def test_valid_internals_assigned_only_in_internals_block(self): def test_invalid_function_with_wrong_arg_number_detected(self): model = self._parse_and_validate_model(os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'invalid')), 'CoCoFunctionCallNotConsistentWrongArgNumber.nestml')) - assert len(Logger.get_all_messages_of_level_and_or_node(model, LoggingLevel.ERROR)) == 2 + assert len(Logger.get_all_messages_of_level_and_or_node(model, LoggingLevel.ERROR)) == 3 def test_valid_function_with_wrong_arg_number_detected(self): model = self._parse_and_validate_model(os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'valid')), 'CoCoFunctionCallNotConsistentWrongArgNumber.nestml')) @@ -211,11 +211,11 @@ def test_invalid_init_values_have_rhs_and_ode(self): def test_valid_init_values_have_rhs_and_ode(self): model = self._parse_and_validate_model(os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'valid')), 'CoCoInitValuesWithoutOde.nestml')) - assert len(Logger.get_all_messages_of_level_and_or_node(model, LoggingLevel.WARNING)) == 3 + assert len(Logger.get_all_messages_of_level_and_or_node(model, LoggingLevel.WARNING)) == 2 def test_invalid_incorrect_return_stmt_detected(self): model = self._parse_and_validate_model(os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'invalid')), 'CoCoIncorrectReturnStatement.nestml')) - assert len(Logger.get_all_messages_of_level_and_or_node(model, LoggingLevel.ERROR)) == 8 + assert len(Logger.get_all_messages_of_level_and_or_node(model, LoggingLevel.ERROR)) == 12 def test_valid_incorrect_return_stmt_detected(self): model = self._parse_and_validate_model(os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'valid')), 'CoCoIncorrectReturnStatement.nestml')) @@ -231,7 +231,7 @@ def test_valid_ode_vars_outside_init_block_detected(self): def test_invalid_convolve_correctly_defined(self): model = self._parse_and_validate_model(os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'invalid')), 'CoCoConvolveNotCorrectlyProvided.nestml')) - assert len(Logger.get_all_messages_of_level_and_or_node(model, LoggingLevel.ERROR)) == 2 + assert len(Logger.get_all_messages_of_level_and_or_node(model, LoggingLevel.ERROR)) == 1 def test_valid_convolve_correctly_defined(self): model = self._parse_and_validate_model(os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'valid')), 'CoCoConvolveNotCorrectlyProvided.nestml')) @@ -271,7 +271,7 @@ def test_valid_vector_parameter_size(self): def test_invalid_convolve_correctly_parameterized(self): model = self._parse_and_validate_model(os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'invalid')), 'CoCoConvolveNotCorrectlyParametrized.nestml')) - assert len(Logger.get_all_messages_of_level_and_or_node(model, LoggingLevel.ERROR)) == 2 + assert len(Logger.get_all_messages_of_level_and_or_node(model, LoggingLevel.ERROR)) == 3 def test_valid_convolve_correctly_parameterized(self): model = self._parse_and_validate_model(os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'valid')), 'CoCoConvolveNotCorrectlyParametrized.nestml')) @@ -287,7 +287,7 @@ def test_valid_invariant_correctly_typed(self): def test_invalid_expression_correctly_typed(self): model = self._parse_and_validate_model(os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'invalid')), 'CoCoIllegalExpression.nestml')) - assert len(Logger.get_all_messages_of_level_and_or_node(model, LoggingLevel.ERROR)) == 2 + assert len(Logger.get_all_messages_of_level_and_or_node(model, LoggingLevel.ERROR)) == 3 def test_valid_expression_correctly_typed(self): model = self._parse_and_validate_model(os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'valid')), 'CoCoIllegalExpression.nestml')) @@ -295,7 +295,7 @@ def test_valid_expression_correctly_typed(self): def test_invalid_compound_expression_correctly_typed(self): model = self._parse_and_validate_model(os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'invalid')), 'CompoundOperatorWithDifferentButCompatibleUnits.nestml')) - assert len(Logger.get_all_messages_of_level_and_or_node(model, LoggingLevel.ERROR)) == 10 + assert len(Logger.get_all_messages_of_level_and_or_node(model, LoggingLevel.ERROR)) == 15 def test_valid_compound_expression_correctly_typed(self): model = self._parse_and_validate_model(os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'valid')), 'CompoundOperatorWithDifferentButCompatibleUnits.nestml')) diff --git a/tests/test_function_parameter_templating.py b/tests/test_function_parameter_templating.py index b93e06780..090a6e18e 100644 --- a/tests/test_function_parameter_templating.py +++ b/tests/test_function_parameter_templating.py @@ -33,4 +33,4 @@ class TestFunctionParameterTemplating: def test(self): fname = os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), "resources", "FunctionParameterTemplatingTest.nestml"))) generate_target(input_path=fname, target_platform="NONE", logging_level="DEBUG") - assert len(Logger.get_all_messages_of_level_and_or_node("templated_function_parameters_type_test", LoggingLevel.ERROR)) == 5 + assert len(Logger.get_all_messages_of_level_and_or_node("templated_function_parameters_type_test", LoggingLevel.ERROR)) == 8 From f8052c7bbd452400228354a9d5b395a57ca46983 Mon Sep 17 00:00:00 2001 From: "C.A.P. Linssen" Date: Sat, 30 Nov 2024 17:05:07 +0100 Subject: [PATCH 16/25] add include statement --- tests/test_cocos.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_cocos.py b/tests/test_cocos.py index e654c98c8..b8081e088 100644 --- a/tests/test_cocos.py +++ b/tests/test_cocos.py @@ -231,7 +231,7 @@ def test_valid_ode_vars_outside_init_block_detected(self): def test_invalid_convolve_correctly_defined(self): model = self._parse_and_validate_model(os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'invalid')), 'CoCoConvolveNotCorrectlyProvided.nestml')) - assert len(Logger.get_all_messages_of_level_and_or_node(model, LoggingLevel.ERROR)) == 1 + assert len(Logger.get_all_messages_of_level_and_or_node(model, LoggingLevel.ERROR)) == 3 def test_valid_convolve_correctly_defined(self): model = self._parse_and_validate_model(os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'valid')), 'CoCoConvolveNotCorrectlyProvided.nestml')) From 5dfd3fc593d538877c44d303124ee89bd1246bcc Mon Sep 17 00:00:00 2001 From: "C.A.P. Linssen" Date: Mon, 2 Dec 2024 13:24:28 +0100 Subject: [PATCH 17/25] add include statement --- pynestml/cocos/co_cos_manager.py | 4 ++-- tests/test_cocos.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/pynestml/cocos/co_cos_manager.py b/pynestml/cocos/co_cos_manager.py index 6858151f0..e4c5393e8 100644 --- a/pynestml/cocos/co_cos_manager.py +++ b/pynestml/cocos/co_cos_manager.py @@ -440,7 +440,6 @@ def check_cocos(cls, model: ASTModel, after_ast_rewrite: bool = False): cls.check_variables_unique_in_scope(model) cls.check_inline_expression_not_assigned_to(model) cls.check_state_variables_initialized(model) - cls.check_variables_defined_before_usage(model) if FrontendConfiguration.get_target_platform().upper() == 'NEST_COMPARTMENTAL': # XXX: TODO: refactor this out; define a ``cocos_from_target_name()`` in the frontend instead. cls.check_v_comp_requirement(model) @@ -461,6 +460,7 @@ def check_cocos(cls, model: ASTModel, after_ast_rewrite: bool = False): cls.check_integrate_odes_params_correct(model) cls.check_output_port_defined_if_emit_call(model) if not after_ast_rewrite: + cls.check_variables_defined_before_usage(model) # units might be incorrect due to e.g. refactoring convolve call (Real type assigned) cls.check_odes_have_consistent_units(model) # ODE functions have been removed at this point @@ -468,12 +468,12 @@ def check_cocos(cls, model: ASTModel, after_ast_rewrite: bool = False): cls.check_ode_functions_have_consistent_units(model) cls.check_correct_usage_of_kernels(model) cls.check_resolution_func_used(model) # ``__h = resolution()`` is added after transformations; put this check inside the ``if`` to make sure it's not always triggered + cls.check_expression_correct(model) if FrontendConfiguration.get_target_platform().upper() != 'NEST_COMPARTMENTAL': cls.check_integrate_odes_called_if_equations_defined(model) cls.check_invariant_type_correct(model) cls.check_vector_in_non_vector_declaration_detected(model) cls.check_convolve_has_correct_parameter(model) - cls.check_expression_correct(model) cls.check_simple_delta_function(model) cls.check_function_argument_template_types_consistent(model) cls.check_vector_parameter_declaration(model) diff --git a/tests/test_cocos.py b/tests/test_cocos.py index b8081e088..99105362e 100644 --- a/tests/test_cocos.py +++ b/tests/test_cocos.py @@ -339,7 +339,7 @@ def test_valid_output_port_type_if_emit_call(self): model = self._parse_and_validate_model(os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'invalid')), 'CoCoOutputPortTypeIfEmitCall-3.nestml')) assert model is not None assert len(Logger.get_all_messages_of_level_and_or_node(model, LoggingLevel.ERROR)) == 0 - assert len(Logger.get_all_messages_of_level_and_or_node(model, LoggingLevel.WARNING)) > 0 + assert any(["Implicit casting from (compatible) type 'real' to 'ms'." in log_entry[2] for log_entry in Logger.get_all_messages_of_level_and_or_node(model, LoggingLevel.WARNING)]) def test_invalid_output_port_type_continuous(self): """test that an error is raised when a continous-time output port is defined as having attributes.""" From 03bb7da27778d74a0991fad965cbdc1a2f5e2ace Mon Sep 17 00:00:00 2001 From: "C.A.P. Linssen" Date: Mon, 2 Dec 2024 22:15:32 +0100 Subject: [PATCH 18/25] add include statement --- pynestml/utils/model_parser.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/pynestml/utils/model_parser.py b/pynestml/utils/model_parser.py index fcb119fac..4c8f78df9 100644 --- a/pynestml/utils/model_parser.py +++ b/pynestml/utils/model_parser.py @@ -199,6 +199,7 @@ def parse_bit_operator(cls, string: str, verbose: bool = True) -> ASTArithmeticO builder, parser = tokenize(string, verbose=verbose) ret = builder.visit(parser.bitOperator()) + @classmethod def parse_block_with_variables(cls, string: str, verbose: bool = True) -> ASTBlockWithVariables: (builder, parser) = tokenize(string, verbose=verbose) ret = builder.visit(parser.blockWithVariables()) @@ -440,8 +441,9 @@ def parse_while_stmt(cls, string: str, verbose: bool = True) -> ASTWhileStmt: def parse_stmts_body(cls, string: str, verbose: bool = True) -> ASTStmtsBody: (builder, parser) = tokenize(string, verbose=verbose) ret = builder.visit(parser.stmtsBody()) - ret.accept(ASTHigherOrderVisitor(log_set_added_source_position)) + return ret + @classmethod def parse_included_file(cls, filename: str) -> Union[ASTNode, List[ASTNode]]: with open(filename, 'r') as file: From d89fa28b95ecd0d633984e855eacf3808378ce41 Mon Sep 17 00:00:00 2001 From: "C.A.P. Linssen" Date: Tue, 3 Dec 2024 01:52:17 +0100 Subject: [PATCH 19/25] add include statement --- tests/nest_tests/resources/nest_codegen_opts.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/nest_tests/resources/nest_codegen_opts.json b/tests/nest_tests/resources/nest_codegen_opts.json index a9d228d36..6425aeaa8 100644 --- a/tests/nest_tests/resources/nest_codegen_opts.json +++ b/tests/nest_tests/resources/nest_codegen_opts.json @@ -1,4 +1,4 @@ { - "nest_path": "/home/charl/julich/nest-simulator-install", - "nest_version": "master" + "nest_path": "%NEST_PATH%", + "nest_version": "%NEST_VERSION%" } From bd3c03f7351b47a5a2321b4960fb372e540209bc Mon Sep 17 00:00:00 2001 From: "C.A.P. Linssen" Date: Tue, 3 Dec 2024 12:52:09 +0100 Subject: [PATCH 20/25] add include statement --- .../nestml_language_concepts.rst | 40 +++++++++++++++++++ tests/nest_tests/test_integrate_odes.py | 2 +- 2 files changed, 41 insertions(+), 1 deletion(-) diff --git a/doc/nestml_language/nestml_language_concepts.rst b/doc/nestml_language/nestml_language_concepts.rst index f2c658d05..bbf69a3f2 100644 --- a/doc/nestml_language/nestml_language_concepts.rst +++ b/doc/nestml_language/nestml_language_concepts.rst @@ -1185,6 +1185,46 @@ The numeric results of a typical simulation run are shown below. Consider a leak On the left, both pre-synaptic spikes are only processed at the end of the interval in which they occur. The statements in the ``update`` block are run every timestep for a fixed timestep of :math:`1~\text{ms}`, alternating with the statements in the ``onReceive`` handler for the spiking input port. Note that this means that the effect of the spikes becomes visible at the end of the timestep in :math:`I_\text{syn}`, but it takes another timestep before ``integrate_odes()`` is called again and consequently for the effect of the spikes to become visible in the membrane potential. This results in a threshold crossing and the neuron firing a spike. On the right half of the figure, the same presynaptic spike timing is used, but events are processed at their exact time of occurrence. In this case, the ``update`` statements are called once to update the neuron from time 0 to :math:`1~\text{ms}`, then again to update from :math:`1~\text{ms}` to the time of the first spike, then the spike is processed by running the statements in its ``onReceive`` block, then ``update`` is called to update from the time of the first spike to the second spike, and so on. The time courses of :math:`I_\text{syn}` and :math:`V_\text{m}` are such that the threshold is not reached and the neuron does not fire, illustrating the numerical differences that can occur when the same model is simulated using different strategies. +Including files +--------------- + +To make models more modular, the contents of one NESTML file can be "included" into another, akin to the C ``#include`` directive. In NESTML, ``include`` is a statement taking one parameter, which gives the filename of the file to be included. The filename may include an absolute or relative path, with directories separated by a forward slash. Contents of the included file are interpreted as appearing at the point of the include statement (akin to the C ``#include``), but with indentation automatically adjusted to the indentation level of the ``include`` statement itself. + +For example, if the contents of a to-be included file ``includes/my_equations_block.nestml`` are + +.. code-block:: nestml + + equations: + x' = A + +then this file can be included as follows: + +.. code-block:: nestml + + model my_neuron_model: + include "includes/my_equations_block.nestml" + +The include statement can appear at any indentation level, for example, if the file ``my_included_stmts.nestml`` contains a list of statements: + +.. code-block:: nestml + + println(i) + # check i + if i < 21: + i += 5 + else: + i *= 2 + +then these can be included as follows: + +.. code-block:: nestml + + model my_neuron_model: + update: + while i < 42: + include "my_included_smts.nestml" + + Guards ------ diff --git a/tests/nest_tests/test_integrate_odes.py b/tests/nest_tests/test_integrate_odes.py index ae4002062..7722ccbe6 100644 --- a/tests/nest_tests/test_integrate_odes.py +++ b/tests/nest_tests/test_integrate_odes.py @@ -229,7 +229,7 @@ def test_integrate_odes_params2(self): fname = os.path.realpath(os.path.join(os.path.dirname(__file__), os.path.join("resources", "integrate_odes_test_params2.nestml"))) generate_target(input_path=fname, target_platform="NONE", logging_level="DEBUG") - assert len(Logger.get_all_messages_of_level_and_or_node("integrate_odes_test", LoggingLevel.ERROR)) == 2 + assert any(["Type of 'test_3' could not be derived" in log_entry[2] for log_entry in Logger.get_all_messages_of_level_and_or_node("integrate_odes_test", LoggingLevel.ERROR)]) def test_integrate_odes_higher_order(self): r""" From f00fdb7df638be193b689002559be9d98a73465c Mon Sep 17 00:00:00 2001 From: Pooja Babu Date: Wed, 4 Dec 2024 14:51:24 +0100 Subject: [PATCH 21/25] Include file with multiple blocks --- pynestml/generated/PyNestMLLexer.py | 4 +- pynestml/generated/PyNestMLParser.py | 541 +++++++++--------- pynestml/generated/PyNestMLParserVisitor.py | 2 +- pynestml/grammars/PyNestMLParser.g4 | 5 +- .../visitors/ast_include_statement_visitor.py | 18 +- .../IncludeStatementRefractory.nestml | 33 ++ .../resources/IncludeStatementTest6.nestml | 34 ++ .../include_refractory_mechanism.nestml | 20 + ...e_statement_model_oncondition_block.nestml | 5 + ...ude_statement_model_onreceive_block.nestml | 2 + tests/nest_tests/test_include_statement.py | 34 ++ 11 files changed, 421 insertions(+), 277 deletions(-) create mode 100644 tests/nest_tests/resources/IncludeStatementRefractory.nestml create mode 100644 tests/nest_tests/resources/IncludeStatementTest6.nestml create mode 100644 tests/nest_tests/resources/includes/include_refractory_mechanism.nestml create mode 100644 tests/nest_tests/resources/includes/include_statement_model_oncondition_block.nestml create mode 100644 tests/nest_tests/resources/includes/include_statement_model_onreceive_block.nestml diff --git a/pynestml/generated/PyNestMLLexer.py b/pynestml/generated/PyNestMLLexer.py index 4ccb46d59..10204b9fe 100644 --- a/pynestml/generated/PyNestMLLexer.py +++ b/pynestml/generated/PyNestMLLexer.py @@ -1,4 +1,4 @@ -# Generated from PyNestMLLexer.g4 by ANTLR 4.13.2 +# Generated from PyNestMLLexer.g4 by ANTLR 4.13.0 from antlr4 import * from io import StringIO import sys @@ -447,7 +447,7 @@ class PyNestMLLexer(PyNestMLLexerBase): def __init__(self, input=None, output:TextIO = sys.stdout): super().__init__(input, output) - self.checkVersion("4.13.2") + self.checkVersion("4.13.0") self._interp = LexerATNSimulator(self, self.atn, self.decisionsToDFA, PredictionContextCache()) self._actions = None self._predicates = None diff --git a/pynestml/generated/PyNestMLParser.py b/pynestml/generated/PyNestMLParser.py index 92f0d8b04..6ea8726b7 100644 --- a/pynestml/generated/PyNestMLParser.py +++ b/pynestml/generated/PyNestMLParser.py @@ -1,4 +1,4 @@ -# Generated from PyNestMLParser.g4 by ANTLR 4.13.2 +# Generated from PyNestMLParser.g4 by ANTLR 4.13.0 # encoding: utf-8 from antlr4 import * from io import StringIO @@ -10,7 +10,7 @@ def serializedATN(): return [ - 4,1,92,671,2,0,7,0,2,1,7,1,2,2,7,2,2,3,7,3,2,4,7,4,2,5,7,5,2,6,7, + 4,1,92,670,2,0,7,0,2,1,7,1,2,2,7,2,2,3,7,3,2,4,7,4,2,5,7,5,2,6,7, 6,2,7,7,7,2,8,7,8,2,9,7,9,2,10,7,10,2,11,7,11,2,12,7,12,2,13,7,13, 2,14,7,14,2,15,7,15,2,16,7,16,2,17,7,17,2,18,7,18,2,19,7,19,2,20, 7,20,2,21,7,21,2,22,7,22,2,23,7,23,2,24,7,24,2,25,7,25,2,26,7,26, @@ -48,46 +48,46 @@ def serializedATN(): 31,1,31,1,31,1,31,1,31,1,31,1,31,1,31,3,31,441,8,31,1,31,1,31,1, 31,1,31,1,31,1,31,1,31,1,32,1,32,1,32,1,32,1,32,1,32,1,32,1,32,1, 33,1,33,4,33,460,8,33,11,33,12,33,461,1,33,1,33,1,34,1,34,1,34,1, - 34,1,34,1,35,1,35,1,35,1,35,1,35,1,35,1,35,1,35,1,35,1,35,1,35,4, - 35,482,8,35,11,35,12,35,483,1,35,1,35,1,36,1,36,1,36,1,36,1,36,5, - 36,493,8,36,10,36,12,36,496,9,36,1,36,1,36,1,36,1,36,1,36,1,36,1, - 36,1,37,1,37,1,37,1,37,1,37,5,37,510,8,37,10,37,12,37,513,9,37,1, - 37,1,37,1,37,1,37,1,37,1,37,1,37,1,38,1,38,1,38,1,38,1,38,1,38,4, - 38,528,8,38,11,38,12,38,529,1,38,1,38,1,39,1,39,1,39,1,39,1,39,1, - 39,1,39,1,40,1,40,1,40,1,40,1,40,1,40,1,40,1,40,4,40,549,8,40,11, - 40,12,40,550,1,40,1,40,1,41,1,41,1,41,1,41,1,41,1,41,3,41,561,8, - 41,1,41,1,41,1,41,1,41,5,41,567,8,41,10,41,12,41,570,9,41,3,41,572, - 8,41,1,41,3,41,575,8,41,4,41,577,8,41,11,41,12,41,578,1,41,1,41, - 1,42,1,42,1,42,1,42,1,42,3,42,588,8,42,1,42,1,42,5,42,592,8,42,10, - 42,12,42,595,9,42,1,42,1,42,1,42,1,43,1,43,1,43,1,43,1,43,3,43,605, - 8,43,1,43,1,43,1,43,1,43,1,43,1,44,1,44,3,44,614,8,44,1,45,1,45, - 1,45,1,45,1,45,1,45,1,45,1,45,1,45,5,45,625,8,45,10,45,12,45,628, - 9,45,3,45,630,8,45,1,45,3,45,633,8,45,1,45,3,45,636,8,45,1,45,1, - 45,1,45,1,46,1,46,1,46,1,46,1,46,1,46,5,46,647,8,46,10,46,12,46, - 650,9,46,3,46,652,8,46,1,46,1,46,3,46,656,8,46,1,46,1,46,1,46,1, - 46,1,46,1,46,1,47,1,47,1,47,1,48,1,48,1,48,1,48,1,48,0,2,2,12,49, - 0,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32,34,36,38,40,42,44, - 46,48,50,52,54,56,58,60,62,64,66,68,70,72,74,76,78,80,82,84,86,88, - 90,92,94,96,0,4,2,0,52,52,76,76,1,0,91,92,1,0,33,35,3,0,25,25,88, - 89,91,92,736,0,104,1,0,0,0,2,115,1,0,0,0,4,132,1,0,0,0,6,143,1,0, - 0,0,8,145,1,0,0,0,10,147,1,0,0,0,12,160,1,0,0,0,14,210,1,0,0,0,16, - 215,1,0,0,0,18,222,1,0,0,0,20,231,1,0,0,0,22,235,1,0,0,0,24,237, - 1,0,0,0,26,250,1,0,0,0,28,265,1,0,0,0,30,283,1,0,0,0,32,297,1,0, - 0,0,34,318,1,0,0,0,36,323,1,0,0,0,38,330,1,0,0,0,40,334,1,0,0,0, - 42,344,1,0,0,0,44,347,1,0,0,0,46,351,1,0,0,0,48,381,1,0,0,0,50,385, - 1,0,0,0,52,395,1,0,0,0,54,399,1,0,0,0,56,409,1,0,0,0,58,417,1,0, - 0,0,60,425,1,0,0,0,62,432,1,0,0,0,64,449,1,0,0,0,66,459,1,0,0,0, - 68,465,1,0,0,0,70,470,1,0,0,0,72,487,1,0,0,0,74,504,1,0,0,0,76,521, - 1,0,0,0,78,533,1,0,0,0,80,540,1,0,0,0,82,554,1,0,0,0,84,582,1,0, - 0,0,86,599,1,0,0,0,88,613,1,0,0,0,90,615,1,0,0,0,92,640,1,0,0,0, - 94,663,1,0,0,0,96,666,1,0,0,0,98,105,5,10,0,0,99,105,5,11,0,0,100, - 105,5,12,0,0,101,105,5,13,0,0,102,105,5,14,0,0,103,105,3,2,1,0,104, - 98,1,0,0,0,104,99,1,0,0,0,104,100,1,0,0,0,104,101,1,0,0,0,104,102, - 1,0,0,0,104,103,1,0,0,0,105,1,1,0,0,0,106,107,6,1,-1,0,107,108,5, - 50,0,0,108,109,3,2,1,0,109,110,5,51,0,0,110,116,1,0,0,0,111,112, - 5,91,0,0,112,113,5,80,0,0,113,116,3,2,1,2,114,116,5,90,0,0,115,106, - 1,0,0,0,115,111,1,0,0,0,115,114,1,0,0,0,116,128,1,0,0,0,117,120, - 10,3,0,0,118,121,5,78,0,0,119,121,5,80,0,0,120,118,1,0,0,0,120,119, + 34,1,34,1,34,1,34,1,34,1,35,1,35,1,35,1,35,1,35,1,35,1,35,1,35,1, + 35,4,35,483,8,35,11,35,12,35,484,1,36,1,36,1,36,1,36,1,36,5,36,492, + 8,36,10,36,12,36,495,9,36,1,36,1,36,1,36,1,36,1,36,1,36,1,36,1,37, + 1,37,1,37,1,37,1,37,5,37,509,8,37,10,37,12,37,512,9,37,1,37,1,37, + 1,37,1,37,1,37,1,37,1,37,1,38,1,38,1,38,1,38,1,38,1,38,4,38,527, + 8,38,11,38,12,38,528,1,38,1,38,1,39,1,39,1,39,1,39,1,39,1,39,1,39, + 1,40,1,40,1,40,1,40,1,40,1,40,1,40,1,40,4,40,548,8,40,11,40,12,40, + 549,1,40,1,40,1,41,1,41,1,41,1,41,1,41,1,41,3,41,560,8,41,1,41,1, + 41,1,41,1,41,5,41,566,8,41,10,41,12,41,569,9,41,3,41,571,8,41,1, + 41,3,41,574,8,41,4,41,576,8,41,11,41,12,41,577,1,41,1,41,1,42,1, + 42,1,42,1,42,1,42,3,42,587,8,42,1,42,1,42,5,42,591,8,42,10,42,12, + 42,594,9,42,1,42,1,42,1,42,1,43,1,43,1,43,1,43,1,43,3,43,604,8,43, + 1,43,1,43,1,43,1,43,1,43,1,44,1,44,3,44,613,8,44,1,45,1,45,1,45, + 1,45,1,45,1,45,1,45,1,45,1,45,5,45,624,8,45,10,45,12,45,627,9,45, + 3,45,629,8,45,1,45,3,45,632,8,45,1,45,3,45,635,8,45,1,45,1,45,1, + 45,1,46,1,46,1,46,1,46,1,46,1,46,5,46,646,8,46,10,46,12,46,649,9, + 46,3,46,651,8,46,1,46,1,46,3,46,655,8,46,1,46,1,46,1,46,1,46,1,46, + 1,46,1,47,1,47,1,47,1,48,1,48,1,48,1,48,1,48,0,2,2,12,49,0,2,4,6, + 8,10,12,14,16,18,20,22,24,26,28,30,32,34,36,38,40,42,44,46,48,50, + 52,54,56,58,60,62,64,66,68,70,72,74,76,78,80,82,84,86,88,90,92,94, + 96,0,4,2,0,52,52,76,76,1,0,91,92,1,0,33,35,3,0,25,25,88,89,91,92, + 735,0,104,1,0,0,0,2,115,1,0,0,0,4,132,1,0,0,0,6,143,1,0,0,0,8,145, + 1,0,0,0,10,147,1,0,0,0,12,160,1,0,0,0,14,210,1,0,0,0,16,215,1,0, + 0,0,18,222,1,0,0,0,20,231,1,0,0,0,22,235,1,0,0,0,24,237,1,0,0,0, + 26,250,1,0,0,0,28,265,1,0,0,0,30,283,1,0,0,0,32,297,1,0,0,0,34,318, + 1,0,0,0,36,323,1,0,0,0,38,330,1,0,0,0,40,334,1,0,0,0,42,344,1,0, + 0,0,44,347,1,0,0,0,46,351,1,0,0,0,48,381,1,0,0,0,50,385,1,0,0,0, + 52,395,1,0,0,0,54,399,1,0,0,0,56,409,1,0,0,0,58,417,1,0,0,0,60,425, + 1,0,0,0,62,432,1,0,0,0,64,449,1,0,0,0,66,459,1,0,0,0,68,465,1,0, + 0,0,70,482,1,0,0,0,72,486,1,0,0,0,74,503,1,0,0,0,76,520,1,0,0,0, + 78,532,1,0,0,0,80,539,1,0,0,0,82,553,1,0,0,0,84,581,1,0,0,0,86,598, + 1,0,0,0,88,612,1,0,0,0,90,614,1,0,0,0,92,639,1,0,0,0,94,662,1,0, + 0,0,96,665,1,0,0,0,98,105,5,10,0,0,99,105,5,11,0,0,100,105,5,12, + 0,0,101,105,5,13,0,0,102,105,5,14,0,0,103,105,3,2,1,0,104,98,1,0, + 0,0,104,99,1,0,0,0,104,100,1,0,0,0,104,101,1,0,0,0,104,102,1,0,0, + 0,104,103,1,0,0,0,105,1,1,0,0,0,106,107,6,1,-1,0,107,108,5,50,0, + 0,108,109,3,2,1,0,109,110,5,51,0,0,110,116,1,0,0,0,111,112,5,91, + 0,0,112,113,5,80,0,0,113,116,3,2,1,2,114,116,5,90,0,0,115,106,1, + 0,0,0,115,111,1,0,0,0,115,114,1,0,0,0,116,128,1,0,0,0,117,120,10, + 3,0,0,118,121,5,78,0,0,119,121,5,80,0,0,120,118,1,0,0,0,120,119, 1,0,0,0,121,122,1,0,0,0,122,127,3,2,1,4,123,124,10,4,0,0,124,125, 5,79,0,0,125,127,3,4,2,0,126,117,1,0,0,0,126,123,1,0,0,0,127,130, 1,0,0,0,128,126,1,0,0,0,128,129,1,0,0,0,129,3,1,0,0,0,130,128,1, @@ -194,71 +194,70 @@ def serializedATN(): 460,3,68,34,0,458,460,5,9,0,0,459,457,1,0,0,0,459,458,1,0,0,0,460, 461,1,0,0,0,461,459,1,0,0,0,461,462,1,0,0,0,462,463,1,0,0,0,463, 464,5,0,0,1,464,67,1,0,0,0,465,466,5,32,0,0,466,467,5,90,0,0,467, - 468,5,83,0,0,468,469,3,70,35,0,469,69,1,0,0,0,470,471,5,9,0,0,471, - 481,5,1,0,0,472,482,3,44,22,0,473,482,3,76,38,0,474,482,3,80,40, - 0,475,482,3,82,41,0,476,482,3,90,45,0,477,482,3,92,46,0,478,482, - 3,72,36,0,479,482,3,74,37,0,480,482,3,78,39,0,481,472,1,0,0,0,481, - 473,1,0,0,0,481,474,1,0,0,0,481,475,1,0,0,0,481,476,1,0,0,0,481, - 477,1,0,0,0,481,478,1,0,0,0,481,479,1,0,0,0,481,480,1,0,0,0,482, - 483,1,0,0,0,483,481,1,0,0,0,483,484,1,0,0,0,484,485,1,0,0,0,485, - 486,5,2,0,0,486,71,1,0,0,0,487,488,5,41,0,0,488,489,5,50,0,0,489, - 494,5,90,0,0,490,491,5,75,0,0,491,493,3,96,48,0,492,490,1,0,0,0, - 493,496,1,0,0,0,494,492,1,0,0,0,494,495,1,0,0,0,495,497,1,0,0,0, - 496,494,1,0,0,0,497,498,5,51,0,0,498,499,5,83,0,0,499,500,5,9,0, - 0,500,501,5,1,0,0,501,502,3,50,25,0,502,503,5,2,0,0,503,73,1,0,0, - 0,504,505,5,42,0,0,505,506,5,50,0,0,506,511,3,12,6,0,507,508,5,75, - 0,0,508,510,3,96,48,0,509,507,1,0,0,0,510,513,1,0,0,0,511,509,1, - 0,0,0,511,512,1,0,0,0,512,514,1,0,0,0,513,511,1,0,0,0,514,515,5, - 51,0,0,515,516,5,83,0,0,516,517,5,9,0,0,517,518,5,1,0,0,518,519, - 3,50,25,0,519,520,5,2,0,0,520,75,1,0,0,0,521,522,7,2,0,0,522,523, - 5,83,0,0,523,524,5,9,0,0,524,527,5,1,0,0,525,528,3,44,22,0,526,528, - 3,48,24,0,527,525,1,0,0,0,527,526,1,0,0,0,528,529,1,0,0,0,529,527, - 1,0,0,0,529,530,1,0,0,0,530,531,1,0,0,0,531,532,5,2,0,0,532,77,1, - 0,0,0,533,534,5,36,0,0,534,535,5,83,0,0,535,536,5,9,0,0,536,537, - 5,1,0,0,537,538,3,50,25,0,538,539,5,2,0,0,539,79,1,0,0,0,540,541, - 5,37,0,0,541,542,5,83,0,0,542,543,5,9,0,0,543,548,5,1,0,0,544,549, - 3,44,22,0,545,549,3,28,14,0,546,549,3,30,15,0,547,549,3,32,16,0, - 548,544,1,0,0,0,548,545,1,0,0,0,548,546,1,0,0,0,548,547,1,0,0,0, - 549,550,1,0,0,0,550,548,1,0,0,0,550,551,1,0,0,0,551,552,1,0,0,0, - 552,553,5,2,0,0,553,81,1,0,0,0,554,555,5,38,0,0,555,556,5,83,0,0, - 556,557,5,9,0,0,557,576,5,1,0,0,558,561,3,84,42,0,559,561,3,86,43, - 0,560,558,1,0,0,0,560,559,1,0,0,0,561,574,1,0,0,0,562,571,5,50,0, - 0,563,568,3,94,47,0,564,565,5,75,0,0,565,567,3,94,47,0,566,564,1, - 0,0,0,567,570,1,0,0,0,568,566,1,0,0,0,568,569,1,0,0,0,569,572,1, - 0,0,0,570,568,1,0,0,0,571,563,1,0,0,0,571,572,1,0,0,0,572,573,1, - 0,0,0,573,575,5,51,0,0,574,562,1,0,0,0,574,575,1,0,0,0,575,577,1, - 0,0,0,576,560,1,0,0,0,577,578,1,0,0,0,578,576,1,0,0,0,578,579,1, - 0,0,0,579,580,1,0,0,0,580,581,5,2,0,0,581,83,1,0,0,0,582,587,5,90, - 0,0,583,584,5,57,0,0,584,585,3,12,6,0,585,586,5,59,0,0,586,588,1, - 0,0,0,587,583,1,0,0,0,587,588,1,0,0,0,588,589,1,0,0,0,589,593,5, - 58,0,0,590,592,3,88,44,0,591,590,1,0,0,0,592,595,1,0,0,0,593,591, - 1,0,0,0,593,594,1,0,0,0,594,596,1,0,0,0,595,593,1,0,0,0,596,597, - 5,43,0,0,597,598,5,9,0,0,598,85,1,0,0,0,599,604,5,90,0,0,600,601, - 5,57,0,0,601,602,3,12,6,0,602,603,5,59,0,0,603,605,1,0,0,0,604,600, - 1,0,0,0,604,605,1,0,0,0,605,606,1,0,0,0,606,607,3,0,0,0,607,608, - 5,58,0,0,608,609,5,40,0,0,609,610,5,9,0,0,610,87,1,0,0,0,611,614, - 5,44,0,0,612,614,5,45,0,0,613,611,1,0,0,0,613,612,1,0,0,0,614,89, - 1,0,0,0,615,616,5,39,0,0,616,617,5,83,0,0,617,618,5,9,0,0,618,635, - 5,1,0,0,619,632,5,43,0,0,620,629,5,50,0,0,621,626,3,94,47,0,622, - 623,5,75,0,0,623,625,3,94,47,0,624,622,1,0,0,0,625,628,1,0,0,0,626, - 624,1,0,0,0,626,627,1,0,0,0,627,630,1,0,0,0,628,626,1,0,0,0,629, - 621,1,0,0,0,629,630,1,0,0,0,630,631,1,0,0,0,631,633,5,51,0,0,632, - 620,1,0,0,0,632,633,1,0,0,0,633,636,1,0,0,0,634,636,5,40,0,0,635, - 619,1,0,0,0,635,634,1,0,0,0,636,637,1,0,0,0,637,638,5,9,0,0,638, - 639,5,2,0,0,639,91,1,0,0,0,640,641,5,15,0,0,641,642,5,90,0,0,642, - 651,5,50,0,0,643,648,3,94,47,0,644,645,5,75,0,0,645,647,3,94,47, - 0,646,644,1,0,0,0,647,650,1,0,0,0,648,646,1,0,0,0,648,649,1,0,0, - 0,649,652,1,0,0,0,650,648,1,0,0,0,651,643,1,0,0,0,651,652,1,0,0, - 0,652,653,1,0,0,0,653,655,5,51,0,0,654,656,3,0,0,0,655,654,1,0,0, - 0,655,656,1,0,0,0,656,657,1,0,0,0,657,658,5,83,0,0,658,659,5,9,0, - 0,659,660,5,1,0,0,660,661,3,50,25,0,661,662,5,2,0,0,662,93,1,0,0, - 0,663,664,5,90,0,0,664,665,3,0,0,0,665,95,1,0,0,0,666,667,5,90,0, - 0,667,668,5,77,0,0,668,669,7,3,0,0,669,97,1,0,0,0,72,104,115,120, - 126,128,132,143,160,169,175,196,198,205,210,215,222,231,235,242, - 247,257,260,265,273,278,287,292,308,312,318,323,330,340,351,354, - 361,367,373,378,385,390,392,397,403,407,440,459,461,481,483,494, - 511,527,529,548,550,560,568,571,574,578,587,593,604,613,626,629, - 632,635,648,651,655 + 468,5,83,0,0,468,469,5,9,0,0,469,470,5,1,0,0,470,471,3,70,35,0,471, + 472,5,2,0,0,472,69,1,0,0,0,473,483,3,44,22,0,474,483,3,76,38,0,475, + 483,3,80,40,0,476,483,3,82,41,0,477,483,3,90,45,0,478,483,3,92,46, + 0,479,483,3,72,36,0,480,483,3,74,37,0,481,483,3,78,39,0,482,473, + 1,0,0,0,482,474,1,0,0,0,482,475,1,0,0,0,482,476,1,0,0,0,482,477, + 1,0,0,0,482,478,1,0,0,0,482,479,1,0,0,0,482,480,1,0,0,0,482,481, + 1,0,0,0,483,484,1,0,0,0,484,482,1,0,0,0,484,485,1,0,0,0,485,71,1, + 0,0,0,486,487,5,41,0,0,487,488,5,50,0,0,488,493,5,90,0,0,489,490, + 5,75,0,0,490,492,3,96,48,0,491,489,1,0,0,0,492,495,1,0,0,0,493,491, + 1,0,0,0,493,494,1,0,0,0,494,496,1,0,0,0,495,493,1,0,0,0,496,497, + 5,51,0,0,497,498,5,83,0,0,498,499,5,9,0,0,499,500,5,1,0,0,500,501, + 3,50,25,0,501,502,5,2,0,0,502,73,1,0,0,0,503,504,5,42,0,0,504,505, + 5,50,0,0,505,510,3,12,6,0,506,507,5,75,0,0,507,509,3,96,48,0,508, + 506,1,0,0,0,509,512,1,0,0,0,510,508,1,0,0,0,510,511,1,0,0,0,511, + 513,1,0,0,0,512,510,1,0,0,0,513,514,5,51,0,0,514,515,5,83,0,0,515, + 516,5,9,0,0,516,517,5,1,0,0,517,518,3,50,25,0,518,519,5,2,0,0,519, + 75,1,0,0,0,520,521,7,2,0,0,521,522,5,83,0,0,522,523,5,9,0,0,523, + 526,5,1,0,0,524,527,3,44,22,0,525,527,3,48,24,0,526,524,1,0,0,0, + 526,525,1,0,0,0,527,528,1,0,0,0,528,526,1,0,0,0,528,529,1,0,0,0, + 529,530,1,0,0,0,530,531,5,2,0,0,531,77,1,0,0,0,532,533,5,36,0,0, + 533,534,5,83,0,0,534,535,5,9,0,0,535,536,5,1,0,0,536,537,3,50,25, + 0,537,538,5,2,0,0,538,79,1,0,0,0,539,540,5,37,0,0,540,541,5,83,0, + 0,541,542,5,9,0,0,542,547,5,1,0,0,543,548,3,44,22,0,544,548,3,28, + 14,0,545,548,3,30,15,0,546,548,3,32,16,0,547,543,1,0,0,0,547,544, + 1,0,0,0,547,545,1,0,0,0,547,546,1,0,0,0,548,549,1,0,0,0,549,547, + 1,0,0,0,549,550,1,0,0,0,550,551,1,0,0,0,551,552,5,2,0,0,552,81,1, + 0,0,0,553,554,5,38,0,0,554,555,5,83,0,0,555,556,5,9,0,0,556,575, + 5,1,0,0,557,560,3,84,42,0,558,560,3,86,43,0,559,557,1,0,0,0,559, + 558,1,0,0,0,560,573,1,0,0,0,561,570,5,50,0,0,562,567,3,94,47,0,563, + 564,5,75,0,0,564,566,3,94,47,0,565,563,1,0,0,0,566,569,1,0,0,0,567, + 565,1,0,0,0,567,568,1,0,0,0,568,571,1,0,0,0,569,567,1,0,0,0,570, + 562,1,0,0,0,570,571,1,0,0,0,571,572,1,0,0,0,572,574,5,51,0,0,573, + 561,1,0,0,0,573,574,1,0,0,0,574,576,1,0,0,0,575,559,1,0,0,0,576, + 577,1,0,0,0,577,575,1,0,0,0,577,578,1,0,0,0,578,579,1,0,0,0,579, + 580,5,2,0,0,580,83,1,0,0,0,581,586,5,90,0,0,582,583,5,57,0,0,583, + 584,3,12,6,0,584,585,5,59,0,0,585,587,1,0,0,0,586,582,1,0,0,0,586, + 587,1,0,0,0,587,588,1,0,0,0,588,592,5,58,0,0,589,591,3,88,44,0,590, + 589,1,0,0,0,591,594,1,0,0,0,592,590,1,0,0,0,592,593,1,0,0,0,593, + 595,1,0,0,0,594,592,1,0,0,0,595,596,5,43,0,0,596,597,5,9,0,0,597, + 85,1,0,0,0,598,603,5,90,0,0,599,600,5,57,0,0,600,601,3,12,6,0,601, + 602,5,59,0,0,602,604,1,0,0,0,603,599,1,0,0,0,603,604,1,0,0,0,604, + 605,1,0,0,0,605,606,3,0,0,0,606,607,5,58,0,0,607,608,5,40,0,0,608, + 609,5,9,0,0,609,87,1,0,0,0,610,613,5,44,0,0,611,613,5,45,0,0,612, + 610,1,0,0,0,612,611,1,0,0,0,613,89,1,0,0,0,614,615,5,39,0,0,615, + 616,5,83,0,0,616,617,5,9,0,0,617,634,5,1,0,0,618,631,5,43,0,0,619, + 628,5,50,0,0,620,625,3,94,47,0,621,622,5,75,0,0,622,624,3,94,47, + 0,623,621,1,0,0,0,624,627,1,0,0,0,625,623,1,0,0,0,625,626,1,0,0, + 0,626,629,1,0,0,0,627,625,1,0,0,0,628,620,1,0,0,0,628,629,1,0,0, + 0,629,630,1,0,0,0,630,632,5,51,0,0,631,619,1,0,0,0,631,632,1,0,0, + 0,632,635,1,0,0,0,633,635,5,40,0,0,634,618,1,0,0,0,634,633,1,0,0, + 0,635,636,1,0,0,0,636,637,5,9,0,0,637,638,5,2,0,0,638,91,1,0,0,0, + 639,640,5,15,0,0,640,641,5,90,0,0,641,650,5,50,0,0,642,647,3,94, + 47,0,643,644,5,75,0,0,644,646,3,94,47,0,645,643,1,0,0,0,646,649, + 1,0,0,0,647,645,1,0,0,0,647,648,1,0,0,0,648,651,1,0,0,0,649,647, + 1,0,0,0,650,642,1,0,0,0,650,651,1,0,0,0,651,652,1,0,0,0,652,654, + 5,51,0,0,653,655,3,0,0,0,654,653,1,0,0,0,654,655,1,0,0,0,655,656, + 1,0,0,0,656,657,5,83,0,0,657,658,5,9,0,0,658,659,5,1,0,0,659,660, + 3,50,25,0,660,661,5,2,0,0,661,93,1,0,0,0,662,663,5,90,0,0,663,664, + 3,0,0,0,664,95,1,0,0,0,665,666,5,90,0,0,666,667,5,77,0,0,667,668, + 7,3,0,0,668,97,1,0,0,0,72,104,115,120,126,128,132,143,160,169,175, + 196,198,205,210,215,222,231,235,242,247,257,260,265,273,278,287, + 292,308,312,318,323,330,340,351,354,361,367,373,378,385,390,392, + 397,403,407,440,459,461,482,484,493,510,526,528,547,549,559,567, + 570,573,577,586,592,603,612,625,628,631,634,647,650,654 ] class PyNestMLParser ( Parser ): @@ -476,7 +475,7 @@ class PyNestMLParser ( Parser ): def __init__(self, input:TokenStream, output:TextIO = sys.stdout): super().__init__(input, output) - self.checkVersion("4.13.2") + self.checkVersion("4.13.0") self._interp = ParserATNSimulator(self, self.atn, self.decisionsToDFA, self.sharedContextCache) self._predicates = None @@ -3421,10 +3420,19 @@ def NAME(self): def COLON(self): return self.getToken(PyNestMLParser.COLON, 0) + def NEWLINE(self): + return self.getToken(PyNestMLParser.NEWLINE, 0) + + def INDENT(self): + return self.getToken(PyNestMLParser.INDENT, 0) + def modelBody(self): return self.getTypedRuleContext(PyNestMLParser.ModelBodyContext,0) + def DEDENT(self): + return self.getToken(PyNestMLParser.DEDENT, 0) + def getRuleIndex(self): return PyNestMLParser.RULE_model @@ -3450,7 +3458,13 @@ def model(self): self.state = 467 self.match(PyNestMLParser.COLON) self.state = 468 + self.match(PyNestMLParser.NEWLINE) + self.state = 469 + self.match(PyNestMLParser.INDENT) + self.state = 470 self.modelBody() + self.state = 471 + self.match(PyNestMLParser.DEDENT) except RecognitionException as re: localctx.exception = re self._errHandler.reportError(self, re) @@ -3467,15 +3481,6 @@ def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): super().__init__(parent, invokingState) self.parser = parser - def NEWLINE(self): - return self.getToken(PyNestMLParser.NEWLINE, 0) - - def INDENT(self): - return self.getToken(PyNestMLParser.INDENT, 0) - - def DEDENT(self): - return self.getToken(PyNestMLParser.DEDENT, 0) - def includeStmt_newline(self, i:int=None): if i is None: return self.getTypedRuleContexts(PyNestMLParser.IncludeStmt_newlineContext) @@ -3558,64 +3563,58 @@ def modelBody(self): self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 470 - self.match(PyNestMLParser.NEWLINE) - self.state = 471 - self.match(PyNestMLParser.INDENT) - self.state = 481 + self.state = 482 self._errHandler.sync(self) _la = self._input.LA(1) while True: - self.state = 481 + self.state = 482 self._errHandler.sync(self) token = self._input.LA(1) if token in [29]: - self.state = 472 + self.state = 473 self.includeStmt_newline() pass elif token in [33, 34, 35]: - self.state = 473 + self.state = 474 self.blockWithVariables() pass elif token in [37]: - self.state = 474 + self.state = 475 self.equationsBlock() pass elif token in [38]: - self.state = 475 + self.state = 476 self.inputBlock() pass elif token in [39]: - self.state = 476 + self.state = 477 self.outputBlock() pass elif token in [15]: - self.state = 477 + self.state = 478 self.function() pass elif token in [41]: - self.state = 478 + self.state = 479 self.onReceiveBlock() pass elif token in [42]: - self.state = 479 + self.state = 480 self.onConditionBlock() pass elif token in [36]: - self.state = 480 + self.state = 481 self.updateBlock() pass else: raise NoViableAltException(self) - self.state = 483 + self.state = 484 self._errHandler.sync(self) _la = self._input.LA(1) if not ((((_la) & ~0x3f) == 0 and ((1 << _la) & 7688528363520) != 0)): break - self.state = 485 - self.match(PyNestMLParser.DEDENT) except RecognitionException as re: localctx.exception = re self._errHandler.reportError(self, re) @@ -3693,35 +3692,35 @@ def onReceiveBlock(self): self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 487 + self.state = 486 self.match(PyNestMLParser.ON_RECEIVE_KEYWORD) - self.state = 488 + self.state = 487 self.match(PyNestMLParser.LEFT_PAREN) - self.state = 489 + self.state = 488 localctx.inputPortName = self.match(PyNestMLParser.NAME) - self.state = 494 + self.state = 493 self._errHandler.sync(self) _la = self._input.LA(1) while _la==75: - self.state = 490 + self.state = 489 self.match(PyNestMLParser.COMMA) - self.state = 491 + self.state = 490 self.constParameter() - self.state = 496 + self.state = 495 self._errHandler.sync(self) _la = self._input.LA(1) - self.state = 497 + self.state = 496 self.match(PyNestMLParser.RIGHT_PAREN) - self.state = 498 + self.state = 497 self.match(PyNestMLParser.COLON) - self.state = 499 + self.state = 498 self.match(PyNestMLParser.NEWLINE) - self.state = 500 + self.state = 499 self.match(PyNestMLParser.INDENT) - self.state = 501 + self.state = 500 self.stmtsBody() - self.state = 502 + self.state = 501 self.match(PyNestMLParser.DEDENT) except RecognitionException as re: localctx.exception = re @@ -3801,35 +3800,35 @@ def onConditionBlock(self): self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 504 + self.state = 503 self.match(PyNestMLParser.ON_CONDITION_KEYWORD) - self.state = 505 + self.state = 504 self.match(PyNestMLParser.LEFT_PAREN) - self.state = 506 + self.state = 505 localctx.condition = self.expression(0) - self.state = 511 + self.state = 510 self._errHandler.sync(self) _la = self._input.LA(1) while _la==75: - self.state = 507 + self.state = 506 self.match(PyNestMLParser.COMMA) - self.state = 508 + self.state = 507 self.constParameter() - self.state = 513 + self.state = 512 self._errHandler.sync(self) _la = self._input.LA(1) - self.state = 514 + self.state = 513 self.match(PyNestMLParser.RIGHT_PAREN) - self.state = 515 + self.state = 514 self.match(PyNestMLParser.COLON) - self.state = 516 + self.state = 515 self.match(PyNestMLParser.NEWLINE) - self.state = 517 + self.state = 516 self.match(PyNestMLParser.INDENT) - self.state = 518 + self.state = 517 self.stmtsBody() - self.state = 519 + self.state = 518 self.match(PyNestMLParser.DEDENT) except RecognitionException as re: localctx.exception = re @@ -3902,7 +3901,7 @@ def blockWithVariables(self): self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 521 + self.state = 520 localctx.blockType = self._input.LT(1) _la = self._input.LA(1) if not((((_la) & ~0x3f) == 0 and ((1 << _la) & 60129542144) != 0)): @@ -3910,37 +3909,37 @@ def blockWithVariables(self): else: self._errHandler.reportMatch(self) self.consume() - self.state = 522 + self.state = 521 self.match(PyNestMLParser.COLON) - self.state = 523 + self.state = 522 self.match(PyNestMLParser.NEWLINE) - self.state = 524 + self.state = 523 self.match(PyNestMLParser.INDENT) - self.state = 527 + self.state = 526 self._errHandler.sync(self) _la = self._input.LA(1) while True: - self.state = 527 + self.state = 526 self._errHandler.sync(self) token = self._input.LA(1) if token in [29]: - self.state = 525 + self.state = 524 self.includeStmt_newline() pass elif token in [16, 30, 90]: - self.state = 526 + self.state = 525 self.declaration_newline() pass else: raise NoViableAltException(self) - self.state = 529 + self.state = 528 self._errHandler.sync(self) _la = self._input.LA(1) if not ((((_la) & ~0x3f) == 0 and ((1 << _la) & 1610678272) != 0) or _la==90): break - self.state = 531 + self.state = 530 self.match(PyNestMLParser.DEDENT) except RecognitionException as re: localctx.exception = re @@ -3995,17 +3994,17 @@ def updateBlock(self): self.enterRule(localctx, 78, self.RULE_updateBlock) try: self.enterOuterAlt(localctx, 1) - self.state = 533 + self.state = 532 self.match(PyNestMLParser.UPDATE_KEYWORD) - self.state = 534 + self.state = 533 self.match(PyNestMLParser.COLON) - self.state = 535 + self.state = 534 self.match(PyNestMLParser.NEWLINE) - self.state = 536 + self.state = 535 self.match(PyNestMLParser.INDENT) - self.state = 537 + self.state = 536 self.stmtsBody() - self.state = 538 + self.state = 537 self.match(PyNestMLParser.DEDENT) except RecognitionException as re: localctx.exception = re @@ -4085,47 +4084,47 @@ def equationsBlock(self): self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 540 + self.state = 539 self.match(PyNestMLParser.EQUATIONS_KEYWORD) - self.state = 541 + self.state = 540 self.match(PyNestMLParser.COLON) - self.state = 542 + self.state = 541 self.match(PyNestMLParser.NEWLINE) - self.state = 543 + self.state = 542 self.match(PyNestMLParser.INDENT) - self.state = 548 + self.state = 547 self._errHandler.sync(self) _la = self._input.LA(1) while True: - self.state = 548 + self.state = 547 self._errHandler.sync(self) token = self._input.LA(1) if token in [29]: - self.state = 544 + self.state = 543 self.includeStmt_newline() pass elif token in [16, 30]: - self.state = 545 + self.state = 544 self.inlineExpression() pass elif token in [90]: - self.state = 546 + self.state = 545 self.odeEquation() pass elif token in [31]: - self.state = 547 + self.state = 546 self.kernel() pass else: raise NoViableAltException(self) - self.state = 550 + self.state = 549 self._errHandler.sync(self) _la = self._input.LA(1) if not ((((_la) & ~0x3f) == 0 and ((1 << _la) & 3758161920) != 0) or _la==90): break - self.state = 552 + self.state = 551 self.match(PyNestMLParser.DEDENT) except RecognitionException as re: localctx.exception = re @@ -4216,69 +4215,69 @@ def inputBlock(self): self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 554 + self.state = 553 self.match(PyNestMLParser.INPUT_KEYWORD) - self.state = 555 + self.state = 554 self.match(PyNestMLParser.COLON) - self.state = 556 + self.state = 555 self.match(PyNestMLParser.NEWLINE) - self.state = 557 + self.state = 556 self.match(PyNestMLParser.INDENT) - self.state = 576 + self.state = 575 self._errHandler.sync(self) _la = self._input.LA(1) while True: - self.state = 560 + self.state = 559 self._errHandler.sync(self) la_ = self._interp.adaptivePredict(self._input,56,self._ctx) if la_ == 1: - self.state = 558 + self.state = 557 self.spikeInputPort() pass elif la_ == 2: - self.state = 559 + self.state = 558 self.continuousInputPort() pass - self.state = 574 + self.state = 573 self._errHandler.sync(self) _la = self._input.LA(1) if _la==50: - self.state = 562 + self.state = 561 self.match(PyNestMLParser.LEFT_PAREN) - self.state = 571 + self.state = 570 self._errHandler.sync(self) _la = self._input.LA(1) if _la==90: - self.state = 563 + self.state = 562 self.parameter() - self.state = 568 + self.state = 567 self._errHandler.sync(self) _la = self._input.LA(1) while _la==75: - self.state = 564 + self.state = 563 self.match(PyNestMLParser.COMMA) - self.state = 565 + self.state = 564 self.parameter() - self.state = 570 + self.state = 569 self._errHandler.sync(self) _la = self._input.LA(1) - self.state = 573 + self.state = 572 self.match(PyNestMLParser.RIGHT_PAREN) - self.state = 578 + self.state = 577 self._errHandler.sync(self) _la = self._input.LA(1) if not (_la==90): break - self.state = 580 + self.state = 579 self.match(PyNestMLParser.DEDENT) except RecognitionException as re: localctx.exception = re @@ -4346,35 +4345,35 @@ def spikeInputPort(self): self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 582 + self.state = 581 localctx.name = self.match(PyNestMLParser.NAME) - self.state = 587 + self.state = 586 self._errHandler.sync(self) _la = self._input.LA(1) if _la==57: - self.state = 583 + self.state = 582 self.match(PyNestMLParser.LEFT_SQUARE_BRACKET) - self.state = 584 + self.state = 583 localctx.sizeParameter = self.expression(0) - self.state = 585 + self.state = 584 self.match(PyNestMLParser.RIGHT_SQUARE_BRACKET) - self.state = 589 + self.state = 588 self.match(PyNestMLParser.LEFT_ANGLE_MINUS) - self.state = 593 + self.state = 592 self._errHandler.sync(self) _la = self._input.LA(1) while _la==44 or _la==45: - self.state = 590 + self.state = 589 self.inputQualifier() - self.state = 595 + self.state = 594 self._errHandler.sync(self) _la = self._input.LA(1) - self.state = 596 + self.state = 595 self.match(PyNestMLParser.SPIKE_KEYWORD) - self.state = 597 + self.state = 596 self.match(PyNestMLParser.NEWLINE) except RecognitionException as re: localctx.exception = re @@ -4439,27 +4438,27 @@ def continuousInputPort(self): self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 599 + self.state = 598 localctx.name = self.match(PyNestMLParser.NAME) - self.state = 604 + self.state = 603 self._errHandler.sync(self) _la = self._input.LA(1) if _la==57: - self.state = 600 + self.state = 599 self.match(PyNestMLParser.LEFT_SQUARE_BRACKET) - self.state = 601 + self.state = 600 localctx.sizeParameter = self.expression(0) - self.state = 602 + self.state = 601 self.match(PyNestMLParser.RIGHT_SQUARE_BRACKET) - self.state = 606 + self.state = 605 self.dataType() - self.state = 607 + self.state = 606 self.match(PyNestMLParser.LEFT_ANGLE_MINUS) - self.state = 608 + self.state = 607 self.match(PyNestMLParser.CONTINUOUS_KEYWORD) - self.state = 609 + self.state = 608 self.match(PyNestMLParser.NEWLINE) except RecognitionException as re: localctx.exception = re @@ -4502,17 +4501,17 @@ def inputQualifier(self): localctx = PyNestMLParser.InputQualifierContext(self, self._ctx, self.state) self.enterRule(localctx, 88, self.RULE_inputQualifier) try: - self.state = 613 + self.state = 612 self._errHandler.sync(self) token = self._input.LA(1) if token in [44]: self.enterOuterAlt(localctx, 1) - self.state = 611 + self.state = 610 localctx.isInhibitory = self.match(PyNestMLParser.INHIBITORY_KEYWORD) pass elif token in [45]: self.enterOuterAlt(localctx, 2) - self.state = 612 + self.state = 611 localctx.isExcitatory = self.match(PyNestMLParser.EXCITATORY_KEYWORD) pass else: @@ -4599,61 +4598,61 @@ def outputBlock(self): self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 615 + self.state = 614 self.match(PyNestMLParser.OUTPUT_KEYWORD) - self.state = 616 + self.state = 615 self.match(PyNestMLParser.COLON) - self.state = 617 + self.state = 616 self.match(PyNestMLParser.NEWLINE) - self.state = 618 + self.state = 617 self.match(PyNestMLParser.INDENT) - self.state = 635 + self.state = 634 self._errHandler.sync(self) token = self._input.LA(1) if token in [43]: - self.state = 619 + self.state = 618 localctx.isSpike = self.match(PyNestMLParser.SPIKE_KEYWORD) - self.state = 632 + self.state = 631 self._errHandler.sync(self) _la = self._input.LA(1) if _la==50: - self.state = 620 + self.state = 619 self.match(PyNestMLParser.LEFT_PAREN) - self.state = 629 + self.state = 628 self._errHandler.sync(self) _la = self._input.LA(1) if _la==90: - self.state = 621 + self.state = 620 localctx.attribute = self.parameter() - self.state = 626 + self.state = 625 self._errHandler.sync(self) _la = self._input.LA(1) while _la==75: - self.state = 622 + self.state = 621 self.match(PyNestMLParser.COMMA) - self.state = 623 + self.state = 622 localctx.attribute = self.parameter() - self.state = 628 + self.state = 627 self._errHandler.sync(self) _la = self._input.LA(1) - self.state = 631 + self.state = 630 self.match(PyNestMLParser.RIGHT_PAREN) pass elif token in [40]: - self.state = 634 + self.state = 633 localctx.isContinuous = self.match(PyNestMLParser.CONTINUOUS_KEYWORD) pass else: raise NoViableAltException(self) - self.state = 637 + self.state = 636 self.match(PyNestMLParser.NEWLINE) - self.state = 638 + self.state = 637 self.match(PyNestMLParser.DEDENT) except RecognitionException as re: localctx.exception = re @@ -4736,51 +4735,51 @@ def function(self): self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 640 + self.state = 639 self.match(PyNestMLParser.FUNCTION_KEYWORD) - self.state = 641 + self.state = 640 self.match(PyNestMLParser.NAME) - self.state = 642 + self.state = 641 self.match(PyNestMLParser.LEFT_PAREN) - self.state = 651 + self.state = 650 self._errHandler.sync(self) _la = self._input.LA(1) if _la==90: - self.state = 643 + self.state = 642 self.parameter() - self.state = 648 + self.state = 647 self._errHandler.sync(self) _la = self._input.LA(1) while _la==75: - self.state = 644 + self.state = 643 self.match(PyNestMLParser.COMMA) - self.state = 645 + self.state = 644 self.parameter() - self.state = 650 + self.state = 649 self._errHandler.sync(self) _la = self._input.LA(1) - self.state = 653 + self.state = 652 self.match(PyNestMLParser.RIGHT_PAREN) - self.state = 655 + self.state = 654 self._errHandler.sync(self) _la = self._input.LA(1) if (((_la) & ~0x3f) == 0 and ((1 << _la) & 1125899906874368) != 0) or _la==90 or _la==91: - self.state = 654 + self.state = 653 localctx.returnType = self.dataType() - self.state = 657 + self.state = 656 self.match(PyNestMLParser.COLON) - self.state = 658 + self.state = 657 self.match(PyNestMLParser.NEWLINE) - self.state = 659 + self.state = 658 self.match(PyNestMLParser.INDENT) - self.state = 660 + self.state = 659 self.stmtsBody() - self.state = 661 + self.state = 660 self.match(PyNestMLParser.DEDENT) except RecognitionException as re: localctx.exception = re @@ -4823,9 +4822,9 @@ def parameter(self): self.enterRule(localctx, 94, self.RULE_parameter) try: self.enterOuterAlt(localctx, 1) - self.state = 663 + self.state = 662 self.match(PyNestMLParser.NAME) - self.state = 664 + self.state = 663 self.dataType() except RecognitionException as re: localctx.exception = re @@ -4885,11 +4884,11 @@ def constParameter(self): self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 666 + self.state = 665 localctx.name = self.match(PyNestMLParser.NAME) - self.state = 667 + self.state = 666 self.match(PyNestMLParser.EQUALS) - self.state = 668 + self.state = 667 localctx.value = self._input.LT(1) _la = self._input.LA(1) if not(_la==25 or ((((_la - 88)) & ~0x3f) == 0 and ((1 << (_la - 88)) & 27) != 0)): diff --git a/pynestml/generated/PyNestMLParserVisitor.py b/pynestml/generated/PyNestMLParserVisitor.py index 45cabc6b4..05985bce1 100644 --- a/pynestml/generated/PyNestMLParserVisitor.py +++ b/pynestml/generated/PyNestMLParserVisitor.py @@ -1,4 +1,4 @@ -# Generated from PyNestMLParser.g4 by ANTLR 4.13.2 +# Generated from PyNestMLParser.g4 by ANTLR 4.13.0 from antlr4 import * if "." in __name__: from .PyNestMLParser import PyNestMLParser diff --git a/pynestml/grammars/PyNestMLParser.g4 b/pynestml/grammars/PyNestMLParser.g4 index 849984fb8..7b805d2f5 100644 --- a/pynestml/grammars/PyNestMLParser.g4 +++ b/pynestml/grammars/PyNestMLParser.g4 @@ -240,7 +240,7 @@ parser grammar PyNestMLParser; * @attribute modelBody: The body of the model consisting of several sub-blocks. **/ model : MODEL_KEYWORD NAME COLON - modelBody; + NEWLINE INDENT modelBody DEDENT; /** * ASTBody The body of the model, e.g. internal, state, parameter... @@ -253,8 +253,9 @@ parser grammar PyNestMLParser; * @attribute onConditionBlock: A block declaring condition statements. * @attribute updateBlock: A single update block containing the dynamic behavior. **/ - modelBody : NEWLINE INDENT ( includeStmt_newline | blockWithVariables | equationsBlock | inputBlock | outputBlock | function | onReceiveBlock | onConditionBlock | updateBlock )+ DEDENT; + modelBody : ( includeStmt_newline | blockWithVariables | equationsBlock | inputBlock | outputBlock | function | onReceiveBlock | onConditionBlock | updateBlock )+; +// modelBlocks : NEWLINE? ( blockWithVariables | equationsBlock | inputBlock | outputBlock | function | onReceiveBlock | onConditionBlock | updateBlock )+ /** * ASTOnReceiveBlock * @attribute stmtsBody implementation of the dynamics diff --git a/pynestml/visitors/ast_include_statement_visitor.py b/pynestml/visitors/ast_include_statement_visitor.py index adeaff88a..794b000e1 100644 --- a/pynestml/visitors/ast_include_statement_visitor.py +++ b/pynestml/visitors/ast_include_statement_visitor.py @@ -27,8 +27,11 @@ from pynestml.meta_model.ast_equations_block import ASTEquationsBlock from pynestml.meta_model.ast_expression import ASTExpression from pynestml.meta_model.ast_include_stmt import ASTIncludeStmt +from pynestml.meta_model.ast_model import ASTModel from pynestml.meta_model.ast_model_body import ASTModelBody from pynestml.meta_model.ast_node import ASTNode +from pynestml.meta_model.ast_on_condition_block import ASTOnConditionBlock +from pynestml.meta_model.ast_on_receive_block import ASTOnReceiveBlock from pynestml.meta_model.ast_small_stmt import ASTSmallStmt from pynestml.meta_model.ast_stmt import ASTStmt from pynestml.meta_model.ast_stmts_body import ASTStmtsBody @@ -99,7 +102,8 @@ def visit(self, node: ASTNode): self._replace_statements(include_stmt, [new_stmt]) - elif isinstance(parsed_included_file, ASTBlockWithVariables) or isinstance(parsed_included_file, ASTUpdateBlock) or isinstance(parsed_included_file, ASTEquationsBlock): + elif isinstance(parsed_included_file, ASTBlockWithVariables) or isinstance(parsed_included_file, ASTUpdateBlock) \ + or isinstance(parsed_included_file, ASTEquationsBlock) or isinstance(parsed_included_file, ASTOnReceiveBlock) or isinstance(parsed_included_file, ASTOnConditionBlock): new_blk = parsed_included_file if isinstance(node.get_parent(), ASTModelBody): idx = node.get_parent().get_body_elements().index(node) @@ -111,5 +115,17 @@ def visit(self, node: ASTNode): print("not handled yet 2") assert False + elif isinstance(parsed_included_file, ASTModelBody): + new_model_body = parsed_included_file + model_body = node.get_parent() + if isinstance(model_body.get_parent(), ASTModel): + idx = model_body.get_body_elements().index(node) + model_body.get_body_elements().pop(idx) + model_body.body_elements = model_body.body_elements[:idx] + new_model_body.get_body_elements() + model_body.body_elements[idx:] + node.accept(ASTParentVisitor()) + new_model_body.accept(ASTParentVisitor()) + else: + assert False + else: assert False diff --git a/tests/nest_tests/resources/IncludeStatementRefractory.nestml b/tests/nest_tests/resources/IncludeStatementRefractory.nestml new file mode 100644 index 000000000..24b1b6432 --- /dev/null +++ b/tests/nest_tests/resources/IncludeStatementRefractory.nestml @@ -0,0 +1,33 @@ +""" +IncludeStatementRefractory.nestml +################################# + + +Description ++++++++++++ + +Test whether the include statement works as intended. + +Copyright statement ++++++++++++++++++++ + +This file is part of NEST. + +Copyright (C) 2004 The NEST Initiative + +NEST is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +NEST is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with NEST. If not, see . +""" + +model include_statement_refractory: + include "includes/include_refractory_mechanism.nestml" diff --git a/tests/nest_tests/resources/IncludeStatementTest6.nestml b/tests/nest_tests/resources/IncludeStatementTest6.nestml new file mode 100644 index 000000000..92236a197 --- /dev/null +++ b/tests/nest_tests/resources/IncludeStatementTest6.nestml @@ -0,0 +1,34 @@ +""" +IncludeStatementTest6.nestml +########################### + + +Description ++++++++++++ + +Test whether the include statement works as intended. + +Copyright statement ++++++++++++++++++++ + +This file is part of NEST. + +Copyright (C) 2004 The NEST Initiative + +NEST is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +NEST is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with NEST. If not, see . +""" + +model include_statement6: + include "includes/include_statement_model_oncondition_block.nestml" + include "includes/include_statement_model_onreceive_block.nestml" diff --git a/tests/nest_tests/resources/includes/include_refractory_mechanism.nestml b/tests/nest_tests/resources/includes/include_refractory_mechanism.nestml new file mode 100644 index 000000000..22b2182f7 --- /dev/null +++ b/tests/nest_tests/resources/includes/include_refractory_mechanism.nestml @@ -0,0 +1,20 @@ +state: + refr_t ms = 0 ms + +parameters: + refr_T ms = 1 ms + +equations: + refr_t' = -1e3 * ms/s + +onCondition(refr_t <= 0 ms and V_m >= V_th): + # threshold crossing + refr_t = refr_T # start of the refractory period + V_m = V_reset + emit_spike() + +#function is_refractory() boolean: +# if refr_t > 0: +# return true +# +# return false \ No newline at end of file diff --git a/tests/nest_tests/resources/includes/include_statement_model_oncondition_block.nestml b/tests/nest_tests/resources/includes/include_statement_model_oncondition_block.nestml new file mode 100644 index 000000000..d72c38285 --- /dev/null +++ b/tests/nest_tests/resources/includes/include_statement_model_oncondition_block.nestml @@ -0,0 +1,5 @@ +onCondition(refr_t <= 0 ms and V_m >= V_th): + # threshold crossing + refr_t = refr_T # start of the refractory period + V_m = V_reset + emit_spike() \ No newline at end of file diff --git a/tests/nest_tests/resources/includes/include_statement_model_onreceive_block.nestml b/tests/nest_tests/resources/includes/include_statement_model_onreceive_block.nestml new file mode 100644 index 000000000..2d8be77e4 --- /dev/null +++ b/tests/nest_tests/resources/includes/include_statement_model_onreceive_block.nestml @@ -0,0 +1,2 @@ +onReceive(exc_spikes): + I_syn_exc += exc_spikes * pA * s \ No newline at end of file diff --git a/tests/nest_tests/test_include_statement.py b/tests/nest_tests/test_include_statement.py index 7e8d6019e..a1fd3e477 100644 --- a/tests/nest_tests/test_include_statement.py +++ b/tests/nest_tests/test_include_statement.py @@ -166,3 +166,37 @@ def test_include_statement5(self): np.testing.assert_allclose(x[-1], 50.4) np.testing.assert_allclose(y[-1], 62.) + + def test_include_statement6(self): + input_path = os.path.join( + os.path.realpath(os.path.join(os.path.dirname(__file__), "resources", "IncludeStatementTest6.nestml"))) + target_path = "target" + logging_level = "DEBUG" + module_name = "nestmlmodule" + suffix = "_nestml" + + nest.set_verbosity("M_ALL") + generate_nest_target(input_path, + target_path=target_path, + logging_level=logging_level, + module_name=module_name, + suffix=suffix) + nest.ResetKernel() + nest.Install("nestmlmodule") + + def test_include_refractory_mechanism(self): + input_path = os.path.join( + os.path.realpath(os.path.join(os.path.dirname(__file__), "resources", "IncludeStatementRefractory.nestml"))) + target_path = "target" + logging_level = "DEBUG" + module_name = "nestmlmodule" + suffix = "_nestml" + + nest.set_verbosity("M_ALL") + generate_nest_target(input_path, + target_path=target_path, + logging_level=logging_level, + module_name=module_name, + suffix=suffix) + nest.ResetKernel() + nest.Install("nestmlmodule") From a963e2886171bb000a90998e766ec68c29ff4718 Mon Sep 17 00:00:00 2001 From: Pooja Babu Date: Thu, 5 Dec 2024 10:35:25 +0100 Subject: [PATCH 22/25] Include statement with multiple blocks --- pynestml/grammars/PyNestMLParser.g4 | 1 - .../includes/include_refractory_mechanism.nestml | 10 +++++----- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/pynestml/grammars/PyNestMLParser.g4 b/pynestml/grammars/PyNestMLParser.g4 index 7b805d2f5..a2c861882 100644 --- a/pynestml/grammars/PyNestMLParser.g4 +++ b/pynestml/grammars/PyNestMLParser.g4 @@ -255,7 +255,6 @@ parser grammar PyNestMLParser; **/ modelBody : ( includeStmt_newline | blockWithVariables | equationsBlock | inputBlock | outputBlock | function | onReceiveBlock | onConditionBlock | updateBlock )+; -// modelBlocks : NEWLINE? ( blockWithVariables | equationsBlock | inputBlock | outputBlock | function | onReceiveBlock | onConditionBlock | updateBlock )+ /** * ASTOnReceiveBlock * @attribute stmtsBody implementation of the dynamics diff --git a/tests/nest_tests/resources/includes/include_refractory_mechanism.nestml b/tests/nest_tests/resources/includes/include_refractory_mechanism.nestml index 22b2182f7..1f15b0db9 100644 --- a/tests/nest_tests/resources/includes/include_refractory_mechanism.nestml +++ b/tests/nest_tests/resources/includes/include_refractory_mechanism.nestml @@ -13,8 +13,8 @@ onCondition(refr_t <= 0 ms and V_m >= V_th): V_m = V_reset emit_spike() -#function is_refractory() boolean: -# if refr_t > 0: -# return true -# -# return false \ No newline at end of file +function is_refractory() boolean: + if refr_t > 0: + return true + + return false \ No newline at end of file From a17677856455e1551489bdd98cc507806799a2cb Mon Sep 17 00:00:00 2001 From: Pooja Babu Date: Mon, 9 Dec 2024 11:19:42 +0100 Subject: [PATCH 23/25] Add include statement with multiple blocks and statements --- .../codegeneration/printers/nestml_printer.py | 13 +- pynestml/generated/PyNestMLParser.py | 733 +++++++++--------- pynestml/grammars/PyNestMLParser.g4 | 4 +- .../visitors/ast_include_statement_visitor.py | 2 +- pynestml/visitors/ast_visitor.py | 23 +- .../resources/IncludeStatementTest4.nestml | 1 + ...de_statement_model_test_state_block.nestml | 2 +- tests/nest_tests/test_include_statement.py | 2 +- tests/test_nestml_printer.py | 42 +- 9 files changed, 424 insertions(+), 398 deletions(-) diff --git a/pynestml/codegeneration/printers/nestml_printer.py b/pynestml/codegeneration/printers/nestml_printer.py index 4a6550e3c..bce872c59 100644 --- a/pynestml/codegeneration/printers/nestml_printer.py +++ b/pynestml/codegeneration/printers/nestml_printer.py @@ -77,12 +77,13 @@ def __init__(self): def print_model(self, node: ASTModel) -> str: ret = print_ml_comments(node.pre_comments, self.indent, False) - ret += "model " + node.get_name() + ":" + print_sl_comment(node.in_comment) - ret += "\n" + self.print(node.get_body()) - + ret += "model " + node.get_name() + ":" + print_sl_comment(node.in_comment) + "\n" + self.inc_indent() + ret += self.print(node.get_body()) + self.dec_indent() return ret - def print_arithmetic_operator(celf, node: ASTArithmeticOperator) -> str: + def print_arithmetic_operator(self, node: ASTArithmeticOperator) -> str: if node.is_times_op: return " * " @@ -169,12 +170,12 @@ def print_block_with_variables(self, node: ASTBlockWithVariables) -> str: return ret def print_model_body(self, node: ASTModelBody) -> str: - self.inc_indent() + # self.inc_indent() ret = "" for elem in node.body_elements: ret += self.print(elem) - self.dec_indent() + # self.dec_indent() return ret diff --git a/pynestml/generated/PyNestMLParser.py b/pynestml/generated/PyNestMLParser.py index 6ea8726b7..0dd829496 100644 --- a/pynestml/generated/PyNestMLParser.py +++ b/pynestml/generated/PyNestMLParser.py @@ -10,7 +10,7 @@ def serializedATN(): return [ - 4,1,92,670,2,0,7,0,2,1,7,1,2,2,7,2,2,3,7,3,2,4,7,4,2,5,7,5,2,6,7, + 4,1,92,673,2,0,7,0,2,1,7,1,2,2,7,2,2,3,7,3,2,4,7,4,2,5,7,5,2,6,7, 6,2,7,7,7,2,8,7,8,2,9,7,9,2,10,7,10,2,11,7,11,2,12,7,12,2,13,7,13, 2,14,7,14,2,15,7,15,2,16,7,16,2,17,7,17,2,18,7,18,2,19,7,19,2,20, 7,20,2,21,7,21,2,22,7,22,2,23,7,23,2,24,7,24,2,25,7,25,2,26,7,26, @@ -48,216 +48,218 @@ def serializedATN(): 31,1,31,1,31,1,31,1,31,1,31,1,31,1,31,3,31,441,8,31,1,31,1,31,1, 31,1,31,1,31,1,31,1,31,1,32,1,32,1,32,1,32,1,32,1,32,1,32,1,32,1, 33,1,33,4,33,460,8,33,11,33,12,33,461,1,33,1,33,1,34,1,34,1,34,1, - 34,1,34,1,34,1,34,1,34,1,35,1,35,1,35,1,35,1,35,1,35,1,35,1,35,1, - 35,4,35,483,8,35,11,35,12,35,484,1,36,1,36,1,36,1,36,1,36,5,36,492, - 8,36,10,36,12,36,495,9,36,1,36,1,36,1,36,1,36,1,36,1,36,1,36,1,37, - 1,37,1,37,1,37,1,37,5,37,509,8,37,10,37,12,37,512,9,37,1,37,1,37, - 1,37,1,37,1,37,1,37,1,37,1,38,1,38,1,38,1,38,1,38,1,38,4,38,527, - 8,38,11,38,12,38,528,1,38,1,38,1,39,1,39,1,39,1,39,1,39,1,39,1,39, - 1,40,1,40,1,40,1,40,1,40,1,40,1,40,1,40,4,40,548,8,40,11,40,12,40, - 549,1,40,1,40,1,41,1,41,1,41,1,41,1,41,1,41,3,41,560,8,41,1,41,1, - 41,1,41,1,41,5,41,566,8,41,10,41,12,41,569,9,41,3,41,571,8,41,1, - 41,3,41,574,8,41,4,41,576,8,41,11,41,12,41,577,1,41,1,41,1,42,1, - 42,1,42,1,42,1,42,3,42,587,8,42,1,42,1,42,5,42,591,8,42,10,42,12, - 42,594,9,42,1,42,1,42,1,42,1,43,1,43,1,43,1,43,1,43,3,43,604,8,43, - 1,43,1,43,1,43,1,43,1,43,1,44,1,44,3,44,613,8,44,1,45,1,45,1,45, - 1,45,1,45,1,45,1,45,1,45,1,45,5,45,624,8,45,10,45,12,45,627,9,45, - 3,45,629,8,45,1,45,3,45,632,8,45,1,45,3,45,635,8,45,1,45,1,45,1, - 45,1,46,1,46,1,46,1,46,1,46,1,46,5,46,646,8,46,10,46,12,46,649,9, - 46,3,46,651,8,46,1,46,1,46,3,46,655,8,46,1,46,1,46,1,46,1,46,1,46, - 1,46,1,47,1,47,1,47,1,48,1,48,1,48,1,48,1,48,0,2,2,12,49,0,2,4,6, - 8,10,12,14,16,18,20,22,24,26,28,30,32,34,36,38,40,42,44,46,48,50, - 52,54,56,58,60,62,64,66,68,70,72,74,76,78,80,82,84,86,88,90,92,94, - 96,0,4,2,0,52,52,76,76,1,0,91,92,1,0,33,35,3,0,25,25,88,89,91,92, - 735,0,104,1,0,0,0,2,115,1,0,0,0,4,132,1,0,0,0,6,143,1,0,0,0,8,145, - 1,0,0,0,10,147,1,0,0,0,12,160,1,0,0,0,14,210,1,0,0,0,16,215,1,0, - 0,0,18,222,1,0,0,0,20,231,1,0,0,0,22,235,1,0,0,0,24,237,1,0,0,0, - 26,250,1,0,0,0,28,265,1,0,0,0,30,283,1,0,0,0,32,297,1,0,0,0,34,318, - 1,0,0,0,36,323,1,0,0,0,38,330,1,0,0,0,40,334,1,0,0,0,42,344,1,0, - 0,0,44,347,1,0,0,0,46,351,1,0,0,0,48,381,1,0,0,0,50,385,1,0,0,0, - 52,395,1,0,0,0,54,399,1,0,0,0,56,409,1,0,0,0,58,417,1,0,0,0,60,425, - 1,0,0,0,62,432,1,0,0,0,64,449,1,0,0,0,66,459,1,0,0,0,68,465,1,0, - 0,0,70,482,1,0,0,0,72,486,1,0,0,0,74,503,1,0,0,0,76,520,1,0,0,0, - 78,532,1,0,0,0,80,539,1,0,0,0,82,553,1,0,0,0,84,581,1,0,0,0,86,598, - 1,0,0,0,88,612,1,0,0,0,90,614,1,0,0,0,92,639,1,0,0,0,94,662,1,0, - 0,0,96,665,1,0,0,0,98,105,5,10,0,0,99,105,5,11,0,0,100,105,5,12, - 0,0,101,105,5,13,0,0,102,105,5,14,0,0,103,105,3,2,1,0,104,98,1,0, - 0,0,104,99,1,0,0,0,104,100,1,0,0,0,104,101,1,0,0,0,104,102,1,0,0, - 0,104,103,1,0,0,0,105,1,1,0,0,0,106,107,6,1,-1,0,107,108,5,50,0, - 0,108,109,3,2,1,0,109,110,5,51,0,0,110,116,1,0,0,0,111,112,5,91, - 0,0,112,113,5,80,0,0,113,116,3,2,1,2,114,116,5,90,0,0,115,106,1, - 0,0,0,115,111,1,0,0,0,115,114,1,0,0,0,116,128,1,0,0,0,117,120,10, - 3,0,0,118,121,5,78,0,0,119,121,5,80,0,0,120,118,1,0,0,0,120,119, - 1,0,0,0,121,122,1,0,0,0,122,127,3,2,1,4,123,124,10,4,0,0,124,125, - 5,79,0,0,125,127,3,4,2,0,126,117,1,0,0,0,126,123,1,0,0,0,127,130, - 1,0,0,0,128,126,1,0,0,0,128,129,1,0,0,0,129,3,1,0,0,0,130,128,1, - 0,0,0,131,133,7,0,0,0,132,131,1,0,0,0,132,133,1,0,0,0,133,134,1, - 0,0,0,134,135,5,91,0,0,135,5,1,0,0,0,136,144,5,46,0,0,137,144,5, - 47,0,0,138,139,5,48,0,0,139,140,3,8,4,0,140,141,5,84,0,0,141,142, - 3,10,5,0,142,144,1,0,0,0,143,136,1,0,0,0,143,137,1,0,0,0,143,138, - 1,0,0,0,144,7,1,0,0,0,145,146,5,90,0,0,146,9,1,0,0,0,147,148,5,90, - 0,0,148,11,1,0,0,0,149,150,6,6,-1,0,150,151,5,50,0,0,151,152,3,12, - 6,0,152,153,5,51,0,0,153,161,1,0,0,0,154,155,3,16,8,0,155,156,3, - 12,6,9,156,161,1,0,0,0,157,158,5,28,0,0,158,161,3,12,6,4,159,161, - 3,14,7,0,160,149,1,0,0,0,160,154,1,0,0,0,160,157,1,0,0,0,160,159, - 1,0,0,0,161,198,1,0,0,0,162,163,10,10,0,0,163,164,5,79,0,0,164,197, - 3,12,6,10,165,169,10,8,0,0,166,170,5,78,0,0,167,170,5,80,0,0,168, - 170,5,81,0,0,169,166,1,0,0,0,169,167,1,0,0,0,169,168,1,0,0,0,170, - 171,1,0,0,0,171,197,3,12,6,9,172,175,10,7,0,0,173,176,5,52,0,0,174, - 176,5,76,0,0,175,173,1,0,0,0,175,174,1,0,0,0,176,177,1,0,0,0,177, - 197,3,12,6,8,178,179,10,6,0,0,179,180,3,18,9,0,180,181,3,12,6,7, - 181,197,1,0,0,0,182,183,10,5,0,0,183,184,3,20,10,0,184,185,3,12, - 6,6,185,197,1,0,0,0,186,187,10,3,0,0,187,188,3,22,11,0,188,189,3, - 12,6,4,189,197,1,0,0,0,190,191,10,2,0,0,191,192,5,82,0,0,192,193, - 3,12,6,0,193,194,5,83,0,0,194,195,3,12,6,3,195,197,1,0,0,0,196,162, - 1,0,0,0,196,165,1,0,0,0,196,172,1,0,0,0,196,178,1,0,0,0,196,182, - 1,0,0,0,196,186,1,0,0,0,196,190,1,0,0,0,197,200,1,0,0,0,198,196, - 1,0,0,0,198,199,1,0,0,0,199,13,1,0,0,0,200,198,1,0,0,0,201,211,3, - 26,13,0,202,211,5,88,0,0,203,205,7,1,0,0,204,206,3,24,12,0,205,204, - 1,0,0,0,205,206,1,0,0,0,206,211,1,0,0,0,207,211,5,89,0,0,208,211, - 5,25,0,0,209,211,3,24,12,0,210,201,1,0,0,0,210,202,1,0,0,0,210,203, - 1,0,0,0,210,207,1,0,0,0,210,208,1,0,0,0,210,209,1,0,0,0,211,15,1, - 0,0,0,212,216,5,52,0,0,213,216,5,76,0,0,214,216,5,53,0,0,215,212, - 1,0,0,0,215,213,1,0,0,0,215,214,1,0,0,0,216,17,1,0,0,0,217,223,5, - 56,0,0,218,223,5,55,0,0,219,223,5,54,0,0,220,223,5,62,0,0,221,223, - 5,63,0,0,222,217,1,0,0,0,222,218,1,0,0,0,222,219,1,0,0,0,222,220, - 1,0,0,0,222,221,1,0,0,0,223,19,1,0,0,0,224,232,5,64,0,0,225,232, - 5,66,0,0,226,232,5,71,0,0,227,232,5,72,0,0,228,232,5,73,0,0,229, - 232,5,74,0,0,230,232,5,65,0,0,231,224,1,0,0,0,231,225,1,0,0,0,231, - 226,1,0,0,0,231,227,1,0,0,0,231,228,1,0,0,0,231,229,1,0,0,0,231, - 230,1,0,0,0,232,21,1,0,0,0,233,236,5,26,0,0,234,236,5,27,0,0,235, - 233,1,0,0,0,235,234,1,0,0,0,236,23,1,0,0,0,237,242,5,90,0,0,238, - 239,5,57,0,0,239,240,3,12,6,0,240,241,5,59,0,0,241,243,1,0,0,0,242, - 238,1,0,0,0,242,243,1,0,0,0,243,247,1,0,0,0,244,246,5,86,0,0,245, - 244,1,0,0,0,246,249,1,0,0,0,247,245,1,0,0,0,247,248,1,0,0,0,248, - 25,1,0,0,0,249,247,1,0,0,0,250,251,5,90,0,0,251,260,5,50,0,0,252, - 257,3,12,6,0,253,254,5,75,0,0,254,256,3,12,6,0,255,253,1,0,0,0,256, - 259,1,0,0,0,257,255,1,0,0,0,257,258,1,0,0,0,258,261,1,0,0,0,259, - 257,1,0,0,0,260,252,1,0,0,0,260,261,1,0,0,0,261,262,1,0,0,0,262, - 263,5,51,0,0,263,27,1,0,0,0,264,266,5,30,0,0,265,264,1,0,0,0,265, - 266,1,0,0,0,266,267,1,0,0,0,267,268,5,16,0,0,268,269,5,90,0,0,269, - 270,3,0,0,0,270,271,5,77,0,0,271,273,3,12,6,0,272,274,5,85,0,0,273, - 272,1,0,0,0,273,274,1,0,0,0,274,278,1,0,0,0,275,277,3,6,3,0,276, - 275,1,0,0,0,277,280,1,0,0,0,278,276,1,0,0,0,278,279,1,0,0,0,279, - 281,1,0,0,0,280,278,1,0,0,0,281,282,5,9,0,0,282,29,1,0,0,0,283,284, - 3,24,12,0,284,285,5,77,0,0,285,287,3,12,6,0,286,288,5,85,0,0,287, - 286,1,0,0,0,287,288,1,0,0,0,288,292,1,0,0,0,289,291,3,6,3,0,290, - 289,1,0,0,0,291,294,1,0,0,0,292,290,1,0,0,0,292,293,1,0,0,0,293, - 295,1,0,0,0,294,292,1,0,0,0,295,296,5,9,0,0,296,31,1,0,0,0,297,298, - 5,31,0,0,298,299,3,24,12,0,299,300,5,77,0,0,300,308,3,12,6,0,301, - 302,5,4,0,0,302,303,3,24,12,0,303,304,5,77,0,0,304,305,3,12,6,0, - 305,307,1,0,0,0,306,301,1,0,0,0,307,310,1,0,0,0,308,306,1,0,0,0, - 308,309,1,0,0,0,309,312,1,0,0,0,310,308,1,0,0,0,311,313,5,85,0,0, - 312,311,1,0,0,0,312,313,1,0,0,0,313,314,1,0,0,0,314,315,5,9,0,0, - 315,33,1,0,0,0,316,319,3,38,19,0,317,319,3,36,18,0,318,316,1,0,0, - 0,318,317,1,0,0,0,319,35,1,0,0,0,320,324,3,54,27,0,321,324,3,62, - 31,0,322,324,3,64,32,0,323,320,1,0,0,0,323,321,1,0,0,0,323,322,1, - 0,0,0,324,37,1,0,0,0,325,331,3,40,20,0,326,331,3,26,13,0,327,331, - 3,46,23,0,328,331,3,52,26,0,329,331,3,42,21,0,330,325,1,0,0,0,330, - 326,1,0,0,0,330,327,1,0,0,0,330,328,1,0,0,0,330,329,1,0,0,0,331, - 332,1,0,0,0,332,333,5,9,0,0,333,39,1,0,0,0,334,340,3,24,12,0,335, - 341,5,77,0,0,336,341,5,67,0,0,337,341,5,68,0,0,338,341,5,69,0,0, - 339,341,5,70,0,0,340,335,1,0,0,0,340,336,1,0,0,0,340,337,1,0,0,0, - 340,338,1,0,0,0,340,339,1,0,0,0,341,342,1,0,0,0,342,343,3,12,6,0, - 343,41,1,0,0,0,344,345,5,29,0,0,345,346,5,89,0,0,346,43,1,0,0,0, - 347,348,3,42,21,0,348,349,5,9,0,0,349,45,1,0,0,0,350,352,5,30,0, - 0,351,350,1,0,0,0,351,352,1,0,0,0,352,354,1,0,0,0,353,355,5,16,0, - 0,354,353,1,0,0,0,354,355,1,0,0,0,355,356,1,0,0,0,356,361,3,24,12, - 0,357,358,5,75,0,0,358,360,3,24,12,0,359,357,1,0,0,0,360,363,1,0, - 0,0,361,359,1,0,0,0,361,362,1,0,0,0,362,364,1,0,0,0,363,361,1,0, - 0,0,364,367,3,0,0,0,365,366,5,77,0,0,366,368,3,12,6,0,367,365,1, - 0,0,0,367,368,1,0,0,0,368,373,1,0,0,0,369,370,5,60,0,0,370,371,3, - 12,6,0,371,372,5,61,0,0,372,374,1,0,0,0,373,369,1,0,0,0,373,374, - 1,0,0,0,374,378,1,0,0,0,375,377,3,6,3,0,376,375,1,0,0,0,377,380, - 1,0,0,0,378,376,1,0,0,0,378,379,1,0,0,0,379,47,1,0,0,0,380,378,1, - 0,0,0,381,382,3,46,23,0,382,383,5,9,0,0,383,49,1,0,0,0,384,386,5, - 9,0,0,385,384,1,0,0,0,385,386,1,0,0,0,386,387,1,0,0,0,387,392,3, - 34,17,0,388,391,5,9,0,0,389,391,3,34,17,0,390,388,1,0,0,0,390,389, - 1,0,0,0,391,394,1,0,0,0,392,390,1,0,0,0,392,393,1,0,0,0,393,51,1, - 0,0,0,394,392,1,0,0,0,395,397,5,17,0,0,396,398,3,12,6,0,397,396, - 1,0,0,0,397,398,1,0,0,0,398,53,1,0,0,0,399,403,3,56,28,0,400,402, - 3,58,29,0,401,400,1,0,0,0,402,405,1,0,0,0,403,401,1,0,0,0,403,404, - 1,0,0,0,404,407,1,0,0,0,405,403,1,0,0,0,406,408,3,60,30,0,407,406, - 1,0,0,0,407,408,1,0,0,0,408,55,1,0,0,0,409,410,5,18,0,0,410,411, - 3,12,6,0,411,412,5,83,0,0,412,413,5,9,0,0,413,414,5,1,0,0,414,415, - 3,50,25,0,415,416,5,2,0,0,416,57,1,0,0,0,417,418,5,19,0,0,418,419, - 3,12,6,0,419,420,5,83,0,0,420,421,5,9,0,0,421,422,5,1,0,0,422,423, - 3,50,25,0,423,424,5,2,0,0,424,59,1,0,0,0,425,426,5,20,0,0,426,427, - 5,83,0,0,427,428,5,9,0,0,428,429,5,1,0,0,429,430,3,50,25,0,430,431, - 5,2,0,0,431,61,1,0,0,0,432,433,5,21,0,0,433,434,5,90,0,0,434,435, - 5,23,0,0,435,436,3,12,6,0,436,437,5,49,0,0,437,438,3,12,6,0,438, - 440,5,24,0,0,439,441,5,76,0,0,440,439,1,0,0,0,440,441,1,0,0,0,441, - 442,1,0,0,0,442,443,7,1,0,0,443,444,5,83,0,0,444,445,5,9,0,0,445, - 446,5,1,0,0,446,447,3,50,25,0,447,448,5,2,0,0,448,63,1,0,0,0,449, - 450,5,22,0,0,450,451,3,12,6,0,451,452,5,83,0,0,452,453,5,9,0,0,453, - 454,5,1,0,0,454,455,3,50,25,0,455,456,5,2,0,0,456,65,1,0,0,0,457, - 460,3,68,34,0,458,460,5,9,0,0,459,457,1,0,0,0,459,458,1,0,0,0,460, - 461,1,0,0,0,461,459,1,0,0,0,461,462,1,0,0,0,462,463,1,0,0,0,463, - 464,5,0,0,1,464,67,1,0,0,0,465,466,5,32,0,0,466,467,5,90,0,0,467, - 468,5,83,0,0,468,469,5,9,0,0,469,470,5,1,0,0,470,471,3,70,35,0,471, - 472,5,2,0,0,472,69,1,0,0,0,473,483,3,44,22,0,474,483,3,76,38,0,475, - 483,3,80,40,0,476,483,3,82,41,0,477,483,3,90,45,0,478,483,3,92,46, - 0,479,483,3,72,36,0,480,483,3,74,37,0,481,483,3,78,39,0,482,473, - 1,0,0,0,482,474,1,0,0,0,482,475,1,0,0,0,482,476,1,0,0,0,482,477, - 1,0,0,0,482,478,1,0,0,0,482,479,1,0,0,0,482,480,1,0,0,0,482,481, - 1,0,0,0,483,484,1,0,0,0,484,482,1,0,0,0,484,485,1,0,0,0,485,71,1, - 0,0,0,486,487,5,41,0,0,487,488,5,50,0,0,488,493,5,90,0,0,489,490, - 5,75,0,0,490,492,3,96,48,0,491,489,1,0,0,0,492,495,1,0,0,0,493,491, - 1,0,0,0,493,494,1,0,0,0,494,496,1,0,0,0,495,493,1,0,0,0,496,497, - 5,51,0,0,497,498,5,83,0,0,498,499,5,9,0,0,499,500,5,1,0,0,500,501, - 3,50,25,0,501,502,5,2,0,0,502,73,1,0,0,0,503,504,5,42,0,0,504,505, - 5,50,0,0,505,510,3,12,6,0,506,507,5,75,0,0,507,509,3,96,48,0,508, - 506,1,0,0,0,509,512,1,0,0,0,510,508,1,0,0,0,510,511,1,0,0,0,511, - 513,1,0,0,0,512,510,1,0,0,0,513,514,5,51,0,0,514,515,5,83,0,0,515, - 516,5,9,0,0,516,517,5,1,0,0,517,518,3,50,25,0,518,519,5,2,0,0,519, - 75,1,0,0,0,520,521,7,2,0,0,521,522,5,83,0,0,522,523,5,9,0,0,523, - 526,5,1,0,0,524,527,3,44,22,0,525,527,3,48,24,0,526,524,1,0,0,0, - 526,525,1,0,0,0,527,528,1,0,0,0,528,526,1,0,0,0,528,529,1,0,0,0, - 529,530,1,0,0,0,530,531,5,2,0,0,531,77,1,0,0,0,532,533,5,36,0,0, - 533,534,5,83,0,0,534,535,5,9,0,0,535,536,5,1,0,0,536,537,3,50,25, - 0,537,538,5,2,0,0,538,79,1,0,0,0,539,540,5,37,0,0,540,541,5,83,0, - 0,541,542,5,9,0,0,542,547,5,1,0,0,543,548,3,44,22,0,544,548,3,28, - 14,0,545,548,3,30,15,0,546,548,3,32,16,0,547,543,1,0,0,0,547,544, - 1,0,0,0,547,545,1,0,0,0,547,546,1,0,0,0,548,549,1,0,0,0,549,547, - 1,0,0,0,549,550,1,0,0,0,550,551,1,0,0,0,551,552,5,2,0,0,552,81,1, - 0,0,0,553,554,5,38,0,0,554,555,5,83,0,0,555,556,5,9,0,0,556,575, - 5,1,0,0,557,560,3,84,42,0,558,560,3,86,43,0,559,557,1,0,0,0,559, - 558,1,0,0,0,560,573,1,0,0,0,561,570,5,50,0,0,562,567,3,94,47,0,563, - 564,5,75,0,0,564,566,3,94,47,0,565,563,1,0,0,0,566,569,1,0,0,0,567, - 565,1,0,0,0,567,568,1,0,0,0,568,571,1,0,0,0,569,567,1,0,0,0,570, - 562,1,0,0,0,570,571,1,0,0,0,571,572,1,0,0,0,572,574,5,51,0,0,573, - 561,1,0,0,0,573,574,1,0,0,0,574,576,1,0,0,0,575,559,1,0,0,0,576, - 577,1,0,0,0,577,575,1,0,0,0,577,578,1,0,0,0,578,579,1,0,0,0,579, - 580,5,2,0,0,580,83,1,0,0,0,581,586,5,90,0,0,582,583,5,57,0,0,583, - 584,3,12,6,0,584,585,5,59,0,0,585,587,1,0,0,0,586,582,1,0,0,0,586, - 587,1,0,0,0,587,588,1,0,0,0,588,592,5,58,0,0,589,591,3,88,44,0,590, - 589,1,0,0,0,591,594,1,0,0,0,592,590,1,0,0,0,592,593,1,0,0,0,593, - 595,1,0,0,0,594,592,1,0,0,0,595,596,5,43,0,0,596,597,5,9,0,0,597, - 85,1,0,0,0,598,603,5,90,0,0,599,600,5,57,0,0,600,601,3,12,6,0,601, - 602,5,59,0,0,602,604,1,0,0,0,603,599,1,0,0,0,603,604,1,0,0,0,604, - 605,1,0,0,0,605,606,3,0,0,0,606,607,5,58,0,0,607,608,5,40,0,0,608, - 609,5,9,0,0,609,87,1,0,0,0,610,613,5,44,0,0,611,613,5,45,0,0,612, - 610,1,0,0,0,612,611,1,0,0,0,613,89,1,0,0,0,614,615,5,39,0,0,615, - 616,5,83,0,0,616,617,5,9,0,0,617,634,5,1,0,0,618,631,5,43,0,0,619, - 628,5,50,0,0,620,625,3,94,47,0,621,622,5,75,0,0,622,624,3,94,47, - 0,623,621,1,0,0,0,624,627,1,0,0,0,625,623,1,0,0,0,625,626,1,0,0, - 0,626,629,1,0,0,0,627,625,1,0,0,0,628,620,1,0,0,0,628,629,1,0,0, - 0,629,630,1,0,0,0,630,632,5,51,0,0,631,619,1,0,0,0,631,632,1,0,0, - 0,632,635,1,0,0,0,633,635,5,40,0,0,634,618,1,0,0,0,634,633,1,0,0, - 0,635,636,1,0,0,0,636,637,5,9,0,0,637,638,5,2,0,0,638,91,1,0,0,0, - 639,640,5,15,0,0,640,641,5,90,0,0,641,650,5,50,0,0,642,647,3,94, - 47,0,643,644,5,75,0,0,644,646,3,94,47,0,645,643,1,0,0,0,646,649, - 1,0,0,0,647,645,1,0,0,0,647,648,1,0,0,0,648,651,1,0,0,0,649,647, - 1,0,0,0,650,642,1,0,0,0,650,651,1,0,0,0,651,652,1,0,0,0,652,654, - 5,51,0,0,653,655,3,0,0,0,654,653,1,0,0,0,654,655,1,0,0,0,655,656, - 1,0,0,0,656,657,5,83,0,0,657,658,5,9,0,0,658,659,5,1,0,0,659,660, - 3,50,25,0,660,661,5,2,0,0,661,93,1,0,0,0,662,663,5,90,0,0,663,664, - 3,0,0,0,664,95,1,0,0,0,665,666,5,90,0,0,666,667,5,77,0,0,667,668, - 7,3,0,0,668,97,1,0,0,0,72,104,115,120,126,128,132,143,160,169,175, - 196,198,205,210,215,222,231,235,242,247,257,260,265,273,278,287, - 292,308,312,318,323,330,340,351,354,361,367,373,378,385,390,392, - 397,403,407,440,459,461,482,484,493,510,526,528,547,549,559,567, - 570,573,577,586,592,603,612,625,628,631,634,647,650,654 + 34,1,34,1,34,1,34,1,34,1,35,3,35,475,8,35,1,35,1,35,1,35,1,35,1, + 35,1,35,1,35,1,35,1,35,4,35,486,8,35,11,35,12,35,487,1,36,1,36,1, + 36,1,36,1,36,5,36,495,8,36,10,36,12,36,498,9,36,1,36,1,36,1,36,1, + 36,1,36,1,36,1,36,1,37,1,37,1,37,1,37,1,37,5,37,512,8,37,10,37,12, + 37,515,9,37,1,37,1,37,1,37,1,37,1,37,1,37,1,37,1,38,1,38,1,38,1, + 38,1,38,1,38,4,38,530,8,38,11,38,12,38,531,1,38,1,38,1,39,1,39,1, + 39,1,39,1,39,1,39,1,39,1,40,1,40,1,40,1,40,1,40,1,40,1,40,1,40,4, + 40,551,8,40,11,40,12,40,552,1,40,1,40,1,41,1,41,1,41,1,41,1,41,1, + 41,3,41,563,8,41,1,41,1,41,1,41,1,41,5,41,569,8,41,10,41,12,41,572, + 9,41,3,41,574,8,41,1,41,3,41,577,8,41,4,41,579,8,41,11,41,12,41, + 580,1,41,1,41,1,42,1,42,1,42,1,42,1,42,3,42,590,8,42,1,42,1,42,5, + 42,594,8,42,10,42,12,42,597,9,42,1,42,1,42,1,42,1,43,1,43,1,43,1, + 43,1,43,3,43,607,8,43,1,43,1,43,1,43,1,43,1,43,1,44,1,44,3,44,616, + 8,44,1,45,1,45,1,45,1,45,1,45,1,45,1,45,1,45,1,45,5,45,627,8,45, + 10,45,12,45,630,9,45,3,45,632,8,45,1,45,3,45,635,8,45,1,45,3,45, + 638,8,45,1,45,1,45,1,45,1,46,1,46,1,46,1,46,1,46,1,46,5,46,649,8, + 46,10,46,12,46,652,9,46,3,46,654,8,46,1,46,1,46,3,46,658,8,46,1, + 46,1,46,1,46,1,46,1,46,1,46,1,47,1,47,1,47,1,48,1,48,1,48,1,48,1, + 48,0,2,2,12,49,0,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32,34, + 36,38,40,42,44,46,48,50,52,54,56,58,60,62,64,66,68,70,72,74,76,78, + 80,82,84,86,88,90,92,94,96,0,4,2,0,52,52,76,76,1,0,91,92,1,0,33, + 35,3,0,25,25,88,89,91,92,739,0,104,1,0,0,0,2,115,1,0,0,0,4,132,1, + 0,0,0,6,143,1,0,0,0,8,145,1,0,0,0,10,147,1,0,0,0,12,160,1,0,0,0, + 14,210,1,0,0,0,16,215,1,0,0,0,18,222,1,0,0,0,20,231,1,0,0,0,22,235, + 1,0,0,0,24,237,1,0,0,0,26,250,1,0,0,0,28,265,1,0,0,0,30,283,1,0, + 0,0,32,297,1,0,0,0,34,318,1,0,0,0,36,323,1,0,0,0,38,330,1,0,0,0, + 40,334,1,0,0,0,42,344,1,0,0,0,44,347,1,0,0,0,46,351,1,0,0,0,48,381, + 1,0,0,0,50,385,1,0,0,0,52,395,1,0,0,0,54,399,1,0,0,0,56,409,1,0, + 0,0,58,417,1,0,0,0,60,425,1,0,0,0,62,432,1,0,0,0,64,449,1,0,0,0, + 66,459,1,0,0,0,68,465,1,0,0,0,70,474,1,0,0,0,72,489,1,0,0,0,74,506, + 1,0,0,0,76,523,1,0,0,0,78,535,1,0,0,0,80,542,1,0,0,0,82,556,1,0, + 0,0,84,584,1,0,0,0,86,601,1,0,0,0,88,615,1,0,0,0,90,617,1,0,0,0, + 92,642,1,0,0,0,94,665,1,0,0,0,96,668,1,0,0,0,98,105,5,10,0,0,99, + 105,5,11,0,0,100,105,5,12,0,0,101,105,5,13,0,0,102,105,5,14,0,0, + 103,105,3,2,1,0,104,98,1,0,0,0,104,99,1,0,0,0,104,100,1,0,0,0,104, + 101,1,0,0,0,104,102,1,0,0,0,104,103,1,0,0,0,105,1,1,0,0,0,106,107, + 6,1,-1,0,107,108,5,50,0,0,108,109,3,2,1,0,109,110,5,51,0,0,110,116, + 1,0,0,0,111,112,5,91,0,0,112,113,5,80,0,0,113,116,3,2,1,2,114,116, + 5,90,0,0,115,106,1,0,0,0,115,111,1,0,0,0,115,114,1,0,0,0,116,128, + 1,0,0,0,117,120,10,3,0,0,118,121,5,78,0,0,119,121,5,80,0,0,120,118, + 1,0,0,0,120,119,1,0,0,0,121,122,1,0,0,0,122,127,3,2,1,4,123,124, + 10,4,0,0,124,125,5,79,0,0,125,127,3,4,2,0,126,117,1,0,0,0,126,123, + 1,0,0,0,127,130,1,0,0,0,128,126,1,0,0,0,128,129,1,0,0,0,129,3,1, + 0,0,0,130,128,1,0,0,0,131,133,7,0,0,0,132,131,1,0,0,0,132,133,1, + 0,0,0,133,134,1,0,0,0,134,135,5,91,0,0,135,5,1,0,0,0,136,144,5,46, + 0,0,137,144,5,47,0,0,138,139,5,48,0,0,139,140,3,8,4,0,140,141,5, + 84,0,0,141,142,3,10,5,0,142,144,1,0,0,0,143,136,1,0,0,0,143,137, + 1,0,0,0,143,138,1,0,0,0,144,7,1,0,0,0,145,146,5,90,0,0,146,9,1,0, + 0,0,147,148,5,90,0,0,148,11,1,0,0,0,149,150,6,6,-1,0,150,151,5,50, + 0,0,151,152,3,12,6,0,152,153,5,51,0,0,153,161,1,0,0,0,154,155,3, + 16,8,0,155,156,3,12,6,9,156,161,1,0,0,0,157,158,5,28,0,0,158,161, + 3,12,6,4,159,161,3,14,7,0,160,149,1,0,0,0,160,154,1,0,0,0,160,157, + 1,0,0,0,160,159,1,0,0,0,161,198,1,0,0,0,162,163,10,10,0,0,163,164, + 5,79,0,0,164,197,3,12,6,10,165,169,10,8,0,0,166,170,5,78,0,0,167, + 170,5,80,0,0,168,170,5,81,0,0,169,166,1,0,0,0,169,167,1,0,0,0,169, + 168,1,0,0,0,170,171,1,0,0,0,171,197,3,12,6,9,172,175,10,7,0,0,173, + 176,5,52,0,0,174,176,5,76,0,0,175,173,1,0,0,0,175,174,1,0,0,0,176, + 177,1,0,0,0,177,197,3,12,6,8,178,179,10,6,0,0,179,180,3,18,9,0,180, + 181,3,12,6,7,181,197,1,0,0,0,182,183,10,5,0,0,183,184,3,20,10,0, + 184,185,3,12,6,6,185,197,1,0,0,0,186,187,10,3,0,0,187,188,3,22,11, + 0,188,189,3,12,6,4,189,197,1,0,0,0,190,191,10,2,0,0,191,192,5,82, + 0,0,192,193,3,12,6,0,193,194,5,83,0,0,194,195,3,12,6,3,195,197,1, + 0,0,0,196,162,1,0,0,0,196,165,1,0,0,0,196,172,1,0,0,0,196,178,1, + 0,0,0,196,182,1,0,0,0,196,186,1,0,0,0,196,190,1,0,0,0,197,200,1, + 0,0,0,198,196,1,0,0,0,198,199,1,0,0,0,199,13,1,0,0,0,200,198,1,0, + 0,0,201,211,3,26,13,0,202,211,5,88,0,0,203,205,7,1,0,0,204,206,3, + 24,12,0,205,204,1,0,0,0,205,206,1,0,0,0,206,211,1,0,0,0,207,211, + 5,89,0,0,208,211,5,25,0,0,209,211,3,24,12,0,210,201,1,0,0,0,210, + 202,1,0,0,0,210,203,1,0,0,0,210,207,1,0,0,0,210,208,1,0,0,0,210, + 209,1,0,0,0,211,15,1,0,0,0,212,216,5,52,0,0,213,216,5,76,0,0,214, + 216,5,53,0,0,215,212,1,0,0,0,215,213,1,0,0,0,215,214,1,0,0,0,216, + 17,1,0,0,0,217,223,5,56,0,0,218,223,5,55,0,0,219,223,5,54,0,0,220, + 223,5,62,0,0,221,223,5,63,0,0,222,217,1,0,0,0,222,218,1,0,0,0,222, + 219,1,0,0,0,222,220,1,0,0,0,222,221,1,0,0,0,223,19,1,0,0,0,224,232, + 5,64,0,0,225,232,5,66,0,0,226,232,5,71,0,0,227,232,5,72,0,0,228, + 232,5,73,0,0,229,232,5,74,0,0,230,232,5,65,0,0,231,224,1,0,0,0,231, + 225,1,0,0,0,231,226,1,0,0,0,231,227,1,0,0,0,231,228,1,0,0,0,231, + 229,1,0,0,0,231,230,1,0,0,0,232,21,1,0,0,0,233,236,5,26,0,0,234, + 236,5,27,0,0,235,233,1,0,0,0,235,234,1,0,0,0,236,23,1,0,0,0,237, + 242,5,90,0,0,238,239,5,57,0,0,239,240,3,12,6,0,240,241,5,59,0,0, + 241,243,1,0,0,0,242,238,1,0,0,0,242,243,1,0,0,0,243,247,1,0,0,0, + 244,246,5,86,0,0,245,244,1,0,0,0,246,249,1,0,0,0,247,245,1,0,0,0, + 247,248,1,0,0,0,248,25,1,0,0,0,249,247,1,0,0,0,250,251,5,90,0,0, + 251,260,5,50,0,0,252,257,3,12,6,0,253,254,5,75,0,0,254,256,3,12, + 6,0,255,253,1,0,0,0,256,259,1,0,0,0,257,255,1,0,0,0,257,258,1,0, + 0,0,258,261,1,0,0,0,259,257,1,0,0,0,260,252,1,0,0,0,260,261,1,0, + 0,0,261,262,1,0,0,0,262,263,5,51,0,0,263,27,1,0,0,0,264,266,5,30, + 0,0,265,264,1,0,0,0,265,266,1,0,0,0,266,267,1,0,0,0,267,268,5,16, + 0,0,268,269,5,90,0,0,269,270,3,0,0,0,270,271,5,77,0,0,271,273,3, + 12,6,0,272,274,5,85,0,0,273,272,1,0,0,0,273,274,1,0,0,0,274,278, + 1,0,0,0,275,277,3,6,3,0,276,275,1,0,0,0,277,280,1,0,0,0,278,276, + 1,0,0,0,278,279,1,0,0,0,279,281,1,0,0,0,280,278,1,0,0,0,281,282, + 5,9,0,0,282,29,1,0,0,0,283,284,3,24,12,0,284,285,5,77,0,0,285,287, + 3,12,6,0,286,288,5,85,0,0,287,286,1,0,0,0,287,288,1,0,0,0,288,292, + 1,0,0,0,289,291,3,6,3,0,290,289,1,0,0,0,291,294,1,0,0,0,292,290, + 1,0,0,0,292,293,1,0,0,0,293,295,1,0,0,0,294,292,1,0,0,0,295,296, + 5,9,0,0,296,31,1,0,0,0,297,298,5,31,0,0,298,299,3,24,12,0,299,300, + 5,77,0,0,300,308,3,12,6,0,301,302,5,4,0,0,302,303,3,24,12,0,303, + 304,5,77,0,0,304,305,3,12,6,0,305,307,1,0,0,0,306,301,1,0,0,0,307, + 310,1,0,0,0,308,306,1,0,0,0,308,309,1,0,0,0,309,312,1,0,0,0,310, + 308,1,0,0,0,311,313,5,85,0,0,312,311,1,0,0,0,312,313,1,0,0,0,313, + 314,1,0,0,0,314,315,5,9,0,0,315,33,1,0,0,0,316,319,3,38,19,0,317, + 319,3,36,18,0,318,316,1,0,0,0,318,317,1,0,0,0,319,35,1,0,0,0,320, + 324,3,54,27,0,321,324,3,62,31,0,322,324,3,64,32,0,323,320,1,0,0, + 0,323,321,1,0,0,0,323,322,1,0,0,0,324,37,1,0,0,0,325,331,3,40,20, + 0,326,331,3,26,13,0,327,331,3,46,23,0,328,331,3,52,26,0,329,331, + 3,42,21,0,330,325,1,0,0,0,330,326,1,0,0,0,330,327,1,0,0,0,330,328, + 1,0,0,0,330,329,1,0,0,0,331,332,1,0,0,0,332,333,5,9,0,0,333,39,1, + 0,0,0,334,340,3,24,12,0,335,341,5,77,0,0,336,341,5,67,0,0,337,341, + 5,68,0,0,338,341,5,69,0,0,339,341,5,70,0,0,340,335,1,0,0,0,340,336, + 1,0,0,0,340,337,1,0,0,0,340,338,1,0,0,0,340,339,1,0,0,0,341,342, + 1,0,0,0,342,343,3,12,6,0,343,41,1,0,0,0,344,345,5,29,0,0,345,346, + 5,89,0,0,346,43,1,0,0,0,347,348,3,42,21,0,348,349,5,9,0,0,349,45, + 1,0,0,0,350,352,5,30,0,0,351,350,1,0,0,0,351,352,1,0,0,0,352,354, + 1,0,0,0,353,355,5,16,0,0,354,353,1,0,0,0,354,355,1,0,0,0,355,356, + 1,0,0,0,356,361,3,24,12,0,357,358,5,75,0,0,358,360,3,24,12,0,359, + 357,1,0,0,0,360,363,1,0,0,0,361,359,1,0,0,0,361,362,1,0,0,0,362, + 364,1,0,0,0,363,361,1,0,0,0,364,367,3,0,0,0,365,366,5,77,0,0,366, + 368,3,12,6,0,367,365,1,0,0,0,367,368,1,0,0,0,368,373,1,0,0,0,369, + 370,5,60,0,0,370,371,3,12,6,0,371,372,5,61,0,0,372,374,1,0,0,0,373, + 369,1,0,0,0,373,374,1,0,0,0,374,378,1,0,0,0,375,377,3,6,3,0,376, + 375,1,0,0,0,377,380,1,0,0,0,378,376,1,0,0,0,378,379,1,0,0,0,379, + 47,1,0,0,0,380,378,1,0,0,0,381,382,3,46,23,0,382,383,5,9,0,0,383, + 49,1,0,0,0,384,386,5,9,0,0,385,384,1,0,0,0,385,386,1,0,0,0,386,387, + 1,0,0,0,387,392,3,34,17,0,388,391,5,9,0,0,389,391,3,34,17,0,390, + 388,1,0,0,0,390,389,1,0,0,0,391,394,1,0,0,0,392,390,1,0,0,0,392, + 393,1,0,0,0,393,51,1,0,0,0,394,392,1,0,0,0,395,397,5,17,0,0,396, + 398,3,12,6,0,397,396,1,0,0,0,397,398,1,0,0,0,398,53,1,0,0,0,399, + 403,3,56,28,0,400,402,3,58,29,0,401,400,1,0,0,0,402,405,1,0,0,0, + 403,401,1,0,0,0,403,404,1,0,0,0,404,407,1,0,0,0,405,403,1,0,0,0, + 406,408,3,60,30,0,407,406,1,0,0,0,407,408,1,0,0,0,408,55,1,0,0,0, + 409,410,5,18,0,0,410,411,3,12,6,0,411,412,5,83,0,0,412,413,5,9,0, + 0,413,414,5,1,0,0,414,415,3,50,25,0,415,416,5,2,0,0,416,57,1,0,0, + 0,417,418,5,19,0,0,418,419,3,12,6,0,419,420,5,83,0,0,420,421,5,9, + 0,0,421,422,5,1,0,0,422,423,3,50,25,0,423,424,5,2,0,0,424,59,1,0, + 0,0,425,426,5,20,0,0,426,427,5,83,0,0,427,428,5,9,0,0,428,429,5, + 1,0,0,429,430,3,50,25,0,430,431,5,2,0,0,431,61,1,0,0,0,432,433,5, + 21,0,0,433,434,5,90,0,0,434,435,5,23,0,0,435,436,3,12,6,0,436,437, + 5,49,0,0,437,438,3,12,6,0,438,440,5,24,0,0,439,441,5,76,0,0,440, + 439,1,0,0,0,440,441,1,0,0,0,441,442,1,0,0,0,442,443,7,1,0,0,443, + 444,5,83,0,0,444,445,5,9,0,0,445,446,5,1,0,0,446,447,3,50,25,0,447, + 448,5,2,0,0,448,63,1,0,0,0,449,450,5,22,0,0,450,451,3,12,6,0,451, + 452,5,83,0,0,452,453,5,9,0,0,453,454,5,1,0,0,454,455,3,50,25,0,455, + 456,5,2,0,0,456,65,1,0,0,0,457,460,3,68,34,0,458,460,5,9,0,0,459, + 457,1,0,0,0,459,458,1,0,0,0,460,461,1,0,0,0,461,459,1,0,0,0,461, + 462,1,0,0,0,462,463,1,0,0,0,463,464,5,0,0,1,464,67,1,0,0,0,465,466, + 5,32,0,0,466,467,5,90,0,0,467,468,5,83,0,0,468,469,5,9,0,0,469,470, + 5,1,0,0,470,471,3,70,35,0,471,472,5,2,0,0,472,69,1,0,0,0,473,475, + 5,9,0,0,474,473,1,0,0,0,474,475,1,0,0,0,475,485,1,0,0,0,476,486, + 3,44,22,0,477,486,3,76,38,0,478,486,3,80,40,0,479,486,3,82,41,0, + 480,486,3,90,45,0,481,486,3,92,46,0,482,486,3,72,36,0,483,486,3, + 74,37,0,484,486,3,78,39,0,485,476,1,0,0,0,485,477,1,0,0,0,485,478, + 1,0,0,0,485,479,1,0,0,0,485,480,1,0,0,0,485,481,1,0,0,0,485,482, + 1,0,0,0,485,483,1,0,0,0,485,484,1,0,0,0,486,487,1,0,0,0,487,485, + 1,0,0,0,487,488,1,0,0,0,488,71,1,0,0,0,489,490,5,41,0,0,490,491, + 5,50,0,0,491,496,5,90,0,0,492,493,5,75,0,0,493,495,3,96,48,0,494, + 492,1,0,0,0,495,498,1,0,0,0,496,494,1,0,0,0,496,497,1,0,0,0,497, + 499,1,0,0,0,498,496,1,0,0,0,499,500,5,51,0,0,500,501,5,83,0,0,501, + 502,5,9,0,0,502,503,5,1,0,0,503,504,3,50,25,0,504,505,5,2,0,0,505, + 73,1,0,0,0,506,507,5,42,0,0,507,508,5,50,0,0,508,513,3,12,6,0,509, + 510,5,75,0,0,510,512,3,96,48,0,511,509,1,0,0,0,512,515,1,0,0,0,513, + 511,1,0,0,0,513,514,1,0,0,0,514,516,1,0,0,0,515,513,1,0,0,0,516, + 517,5,51,0,0,517,518,5,83,0,0,518,519,5,9,0,0,519,520,5,1,0,0,520, + 521,3,50,25,0,521,522,5,2,0,0,522,75,1,0,0,0,523,524,7,2,0,0,524, + 525,5,83,0,0,525,526,5,9,0,0,526,529,5,1,0,0,527,530,3,44,22,0,528, + 530,3,48,24,0,529,527,1,0,0,0,529,528,1,0,0,0,530,531,1,0,0,0,531, + 529,1,0,0,0,531,532,1,0,0,0,532,533,1,0,0,0,533,534,5,2,0,0,534, + 77,1,0,0,0,535,536,5,36,0,0,536,537,5,83,0,0,537,538,5,9,0,0,538, + 539,5,1,0,0,539,540,3,50,25,0,540,541,5,2,0,0,541,79,1,0,0,0,542, + 543,5,37,0,0,543,544,5,83,0,0,544,545,5,9,0,0,545,550,5,1,0,0,546, + 551,3,44,22,0,547,551,3,28,14,0,548,551,3,30,15,0,549,551,3,32,16, + 0,550,546,1,0,0,0,550,547,1,0,0,0,550,548,1,0,0,0,550,549,1,0,0, + 0,551,552,1,0,0,0,552,550,1,0,0,0,552,553,1,0,0,0,553,554,1,0,0, + 0,554,555,5,2,0,0,555,81,1,0,0,0,556,557,5,38,0,0,557,558,5,83,0, + 0,558,559,5,9,0,0,559,578,5,1,0,0,560,563,3,84,42,0,561,563,3,86, + 43,0,562,560,1,0,0,0,562,561,1,0,0,0,563,576,1,0,0,0,564,573,5,50, + 0,0,565,570,3,94,47,0,566,567,5,75,0,0,567,569,3,94,47,0,568,566, + 1,0,0,0,569,572,1,0,0,0,570,568,1,0,0,0,570,571,1,0,0,0,571,574, + 1,0,0,0,572,570,1,0,0,0,573,565,1,0,0,0,573,574,1,0,0,0,574,575, + 1,0,0,0,575,577,5,51,0,0,576,564,1,0,0,0,576,577,1,0,0,0,577,579, + 1,0,0,0,578,562,1,0,0,0,579,580,1,0,0,0,580,578,1,0,0,0,580,581, + 1,0,0,0,581,582,1,0,0,0,582,583,5,2,0,0,583,83,1,0,0,0,584,589,5, + 90,0,0,585,586,5,57,0,0,586,587,3,12,6,0,587,588,5,59,0,0,588,590, + 1,0,0,0,589,585,1,0,0,0,589,590,1,0,0,0,590,591,1,0,0,0,591,595, + 5,58,0,0,592,594,3,88,44,0,593,592,1,0,0,0,594,597,1,0,0,0,595,593, + 1,0,0,0,595,596,1,0,0,0,596,598,1,0,0,0,597,595,1,0,0,0,598,599, + 5,43,0,0,599,600,5,9,0,0,600,85,1,0,0,0,601,606,5,90,0,0,602,603, + 5,57,0,0,603,604,3,12,6,0,604,605,5,59,0,0,605,607,1,0,0,0,606,602, + 1,0,0,0,606,607,1,0,0,0,607,608,1,0,0,0,608,609,3,0,0,0,609,610, + 5,58,0,0,610,611,5,40,0,0,611,612,5,9,0,0,612,87,1,0,0,0,613,616, + 5,44,0,0,614,616,5,45,0,0,615,613,1,0,0,0,615,614,1,0,0,0,616,89, + 1,0,0,0,617,618,5,39,0,0,618,619,5,83,0,0,619,620,5,9,0,0,620,637, + 5,1,0,0,621,634,5,43,0,0,622,631,5,50,0,0,623,628,3,94,47,0,624, + 625,5,75,0,0,625,627,3,94,47,0,626,624,1,0,0,0,627,630,1,0,0,0,628, + 626,1,0,0,0,628,629,1,0,0,0,629,632,1,0,0,0,630,628,1,0,0,0,631, + 623,1,0,0,0,631,632,1,0,0,0,632,633,1,0,0,0,633,635,5,51,0,0,634, + 622,1,0,0,0,634,635,1,0,0,0,635,638,1,0,0,0,636,638,5,40,0,0,637, + 621,1,0,0,0,637,636,1,0,0,0,638,639,1,0,0,0,639,640,5,9,0,0,640, + 641,5,2,0,0,641,91,1,0,0,0,642,643,5,15,0,0,643,644,5,90,0,0,644, + 653,5,50,0,0,645,650,3,94,47,0,646,647,5,75,0,0,647,649,3,94,47, + 0,648,646,1,0,0,0,649,652,1,0,0,0,650,648,1,0,0,0,650,651,1,0,0, + 0,651,654,1,0,0,0,652,650,1,0,0,0,653,645,1,0,0,0,653,654,1,0,0, + 0,654,655,1,0,0,0,655,657,5,51,0,0,656,658,3,0,0,0,657,656,1,0,0, + 0,657,658,1,0,0,0,658,659,1,0,0,0,659,660,5,83,0,0,660,661,5,9,0, + 0,661,662,5,1,0,0,662,663,3,50,25,0,663,664,5,2,0,0,664,93,1,0,0, + 0,665,666,5,90,0,0,666,667,3,0,0,0,667,95,1,0,0,0,668,669,5,90,0, + 0,669,670,5,77,0,0,670,671,7,3,0,0,671,97,1,0,0,0,73,104,115,120, + 126,128,132,143,160,169,175,196,198,205,210,215,222,231,235,242, + 247,257,260,265,273,278,287,292,308,312,318,323,330,340,351,354, + 361,367,373,378,385,390,392,397,403,407,440,459,461,474,485,487, + 496,513,529,531,550,552,562,570,573,576,580,589,595,606,615,628, + 631,634,637,650,653,657 ] class PyNestMLParser ( Parser ): @@ -3481,6 +3483,9 @@ def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): super().__init__(parent, invokingState) self.parser = parser + def NEWLINE(self): + return self.getToken(PyNestMLParser.NEWLINE, 0) + def includeStmt_newline(self, i:int=None): if i is None: return self.getTypedRuleContexts(PyNestMLParser.IncludeStmt_newlineContext) @@ -3563,53 +3568,61 @@ def modelBody(self): self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 482 + self.state = 474 + self._errHandler.sync(self) + _la = self._input.LA(1) + if _la==9: + self.state = 473 + self.match(PyNestMLParser.NEWLINE) + + + self.state = 485 self._errHandler.sync(self) _la = self._input.LA(1) while True: - self.state = 482 + self.state = 485 self._errHandler.sync(self) token = self._input.LA(1) if token in [29]: - self.state = 473 + self.state = 476 self.includeStmt_newline() pass elif token in [33, 34, 35]: - self.state = 474 + self.state = 477 self.blockWithVariables() pass elif token in [37]: - self.state = 475 + self.state = 478 self.equationsBlock() pass elif token in [38]: - self.state = 476 + self.state = 479 self.inputBlock() pass elif token in [39]: - self.state = 477 + self.state = 480 self.outputBlock() pass elif token in [15]: - self.state = 478 + self.state = 481 self.function() pass elif token in [41]: - self.state = 479 + self.state = 482 self.onReceiveBlock() pass elif token in [42]: - self.state = 480 + self.state = 483 self.onConditionBlock() pass elif token in [36]: - self.state = 481 + self.state = 484 self.updateBlock() pass else: raise NoViableAltException(self) - self.state = 484 + self.state = 487 self._errHandler.sync(self) _la = self._input.LA(1) if not ((((_la) & ~0x3f) == 0 and ((1 << _la) & 7688528363520) != 0)): @@ -3692,35 +3705,35 @@ def onReceiveBlock(self): self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 486 + self.state = 489 self.match(PyNestMLParser.ON_RECEIVE_KEYWORD) - self.state = 487 + self.state = 490 self.match(PyNestMLParser.LEFT_PAREN) - self.state = 488 + self.state = 491 localctx.inputPortName = self.match(PyNestMLParser.NAME) - self.state = 493 + self.state = 496 self._errHandler.sync(self) _la = self._input.LA(1) while _la==75: - self.state = 489 + self.state = 492 self.match(PyNestMLParser.COMMA) - self.state = 490 + self.state = 493 self.constParameter() - self.state = 495 + self.state = 498 self._errHandler.sync(self) _la = self._input.LA(1) - self.state = 496 + self.state = 499 self.match(PyNestMLParser.RIGHT_PAREN) - self.state = 497 + self.state = 500 self.match(PyNestMLParser.COLON) - self.state = 498 + self.state = 501 self.match(PyNestMLParser.NEWLINE) - self.state = 499 + self.state = 502 self.match(PyNestMLParser.INDENT) - self.state = 500 + self.state = 503 self.stmtsBody() - self.state = 501 + self.state = 504 self.match(PyNestMLParser.DEDENT) except RecognitionException as re: localctx.exception = re @@ -3800,35 +3813,35 @@ def onConditionBlock(self): self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 503 + self.state = 506 self.match(PyNestMLParser.ON_CONDITION_KEYWORD) - self.state = 504 + self.state = 507 self.match(PyNestMLParser.LEFT_PAREN) - self.state = 505 + self.state = 508 localctx.condition = self.expression(0) - self.state = 510 + self.state = 513 self._errHandler.sync(self) _la = self._input.LA(1) while _la==75: - self.state = 506 + self.state = 509 self.match(PyNestMLParser.COMMA) - self.state = 507 + self.state = 510 self.constParameter() - self.state = 512 + self.state = 515 self._errHandler.sync(self) _la = self._input.LA(1) - self.state = 513 + self.state = 516 self.match(PyNestMLParser.RIGHT_PAREN) - self.state = 514 + self.state = 517 self.match(PyNestMLParser.COLON) - self.state = 515 + self.state = 518 self.match(PyNestMLParser.NEWLINE) - self.state = 516 + self.state = 519 self.match(PyNestMLParser.INDENT) - self.state = 517 + self.state = 520 self.stmtsBody() - self.state = 518 + self.state = 521 self.match(PyNestMLParser.DEDENT) except RecognitionException as re: localctx.exception = re @@ -3901,7 +3914,7 @@ def blockWithVariables(self): self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 520 + self.state = 523 localctx.blockType = self._input.LT(1) _la = self._input.LA(1) if not((((_la) & ~0x3f) == 0 and ((1 << _la) & 60129542144) != 0)): @@ -3909,37 +3922,37 @@ def blockWithVariables(self): else: self._errHandler.reportMatch(self) self.consume() - self.state = 521 + self.state = 524 self.match(PyNestMLParser.COLON) - self.state = 522 + self.state = 525 self.match(PyNestMLParser.NEWLINE) - self.state = 523 + self.state = 526 self.match(PyNestMLParser.INDENT) - self.state = 526 + self.state = 529 self._errHandler.sync(self) _la = self._input.LA(1) while True: - self.state = 526 + self.state = 529 self._errHandler.sync(self) token = self._input.LA(1) if token in [29]: - self.state = 524 + self.state = 527 self.includeStmt_newline() pass elif token in [16, 30, 90]: - self.state = 525 + self.state = 528 self.declaration_newline() pass else: raise NoViableAltException(self) - self.state = 528 + self.state = 531 self._errHandler.sync(self) _la = self._input.LA(1) if not ((((_la) & ~0x3f) == 0 and ((1 << _la) & 1610678272) != 0) or _la==90): break - self.state = 530 + self.state = 533 self.match(PyNestMLParser.DEDENT) except RecognitionException as re: localctx.exception = re @@ -3994,17 +4007,17 @@ def updateBlock(self): self.enterRule(localctx, 78, self.RULE_updateBlock) try: self.enterOuterAlt(localctx, 1) - self.state = 532 + self.state = 535 self.match(PyNestMLParser.UPDATE_KEYWORD) - self.state = 533 + self.state = 536 self.match(PyNestMLParser.COLON) - self.state = 534 + self.state = 537 self.match(PyNestMLParser.NEWLINE) - self.state = 535 + self.state = 538 self.match(PyNestMLParser.INDENT) - self.state = 536 + self.state = 539 self.stmtsBody() - self.state = 537 + self.state = 540 self.match(PyNestMLParser.DEDENT) except RecognitionException as re: localctx.exception = re @@ -4084,47 +4097,47 @@ def equationsBlock(self): self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 539 + self.state = 542 self.match(PyNestMLParser.EQUATIONS_KEYWORD) - self.state = 540 + self.state = 543 self.match(PyNestMLParser.COLON) - self.state = 541 + self.state = 544 self.match(PyNestMLParser.NEWLINE) - self.state = 542 + self.state = 545 self.match(PyNestMLParser.INDENT) - self.state = 547 + self.state = 550 self._errHandler.sync(self) _la = self._input.LA(1) while True: - self.state = 547 + self.state = 550 self._errHandler.sync(self) token = self._input.LA(1) if token in [29]: - self.state = 543 + self.state = 546 self.includeStmt_newline() pass elif token in [16, 30]: - self.state = 544 + self.state = 547 self.inlineExpression() pass elif token in [90]: - self.state = 545 + self.state = 548 self.odeEquation() pass elif token in [31]: - self.state = 546 + self.state = 549 self.kernel() pass else: raise NoViableAltException(self) - self.state = 549 + self.state = 552 self._errHandler.sync(self) _la = self._input.LA(1) if not ((((_la) & ~0x3f) == 0 and ((1 << _la) & 3758161920) != 0) or _la==90): break - self.state = 551 + self.state = 554 self.match(PyNestMLParser.DEDENT) except RecognitionException as re: localctx.exception = re @@ -4215,69 +4228,69 @@ def inputBlock(self): self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 553 + self.state = 556 self.match(PyNestMLParser.INPUT_KEYWORD) - self.state = 554 + self.state = 557 self.match(PyNestMLParser.COLON) - self.state = 555 + self.state = 558 self.match(PyNestMLParser.NEWLINE) - self.state = 556 + self.state = 559 self.match(PyNestMLParser.INDENT) - self.state = 575 + self.state = 578 self._errHandler.sync(self) _la = self._input.LA(1) while True: - self.state = 559 + self.state = 562 self._errHandler.sync(self) - la_ = self._interp.adaptivePredict(self._input,56,self._ctx) + la_ = self._interp.adaptivePredict(self._input,57,self._ctx) if la_ == 1: - self.state = 557 + self.state = 560 self.spikeInputPort() pass elif la_ == 2: - self.state = 558 + self.state = 561 self.continuousInputPort() pass - self.state = 573 + self.state = 576 self._errHandler.sync(self) _la = self._input.LA(1) if _la==50: - self.state = 561 + self.state = 564 self.match(PyNestMLParser.LEFT_PAREN) - self.state = 570 + self.state = 573 self._errHandler.sync(self) _la = self._input.LA(1) if _la==90: - self.state = 562 + self.state = 565 self.parameter() - self.state = 567 + self.state = 570 self._errHandler.sync(self) _la = self._input.LA(1) while _la==75: - self.state = 563 + self.state = 566 self.match(PyNestMLParser.COMMA) - self.state = 564 + self.state = 567 self.parameter() - self.state = 569 + self.state = 572 self._errHandler.sync(self) _la = self._input.LA(1) - self.state = 572 + self.state = 575 self.match(PyNestMLParser.RIGHT_PAREN) - self.state = 577 + self.state = 580 self._errHandler.sync(self) _la = self._input.LA(1) if not (_la==90): break - self.state = 579 + self.state = 582 self.match(PyNestMLParser.DEDENT) except RecognitionException as re: localctx.exception = re @@ -4345,35 +4358,35 @@ def spikeInputPort(self): self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 581 + self.state = 584 localctx.name = self.match(PyNestMLParser.NAME) - self.state = 586 + self.state = 589 self._errHandler.sync(self) _la = self._input.LA(1) if _la==57: - self.state = 582 + self.state = 585 self.match(PyNestMLParser.LEFT_SQUARE_BRACKET) - self.state = 583 + self.state = 586 localctx.sizeParameter = self.expression(0) - self.state = 584 + self.state = 587 self.match(PyNestMLParser.RIGHT_SQUARE_BRACKET) - self.state = 588 + self.state = 591 self.match(PyNestMLParser.LEFT_ANGLE_MINUS) - self.state = 592 + self.state = 595 self._errHandler.sync(self) _la = self._input.LA(1) while _la==44 or _la==45: - self.state = 589 + self.state = 592 self.inputQualifier() - self.state = 594 + self.state = 597 self._errHandler.sync(self) _la = self._input.LA(1) - self.state = 595 + self.state = 598 self.match(PyNestMLParser.SPIKE_KEYWORD) - self.state = 596 + self.state = 599 self.match(PyNestMLParser.NEWLINE) except RecognitionException as re: localctx.exception = re @@ -4438,27 +4451,27 @@ def continuousInputPort(self): self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 598 + self.state = 601 localctx.name = self.match(PyNestMLParser.NAME) - self.state = 603 + self.state = 606 self._errHandler.sync(self) _la = self._input.LA(1) if _la==57: - self.state = 599 + self.state = 602 self.match(PyNestMLParser.LEFT_SQUARE_BRACKET) - self.state = 600 + self.state = 603 localctx.sizeParameter = self.expression(0) - self.state = 601 + self.state = 604 self.match(PyNestMLParser.RIGHT_SQUARE_BRACKET) - self.state = 605 + self.state = 608 self.dataType() - self.state = 606 + self.state = 609 self.match(PyNestMLParser.LEFT_ANGLE_MINUS) - self.state = 607 + self.state = 610 self.match(PyNestMLParser.CONTINUOUS_KEYWORD) - self.state = 608 + self.state = 611 self.match(PyNestMLParser.NEWLINE) except RecognitionException as re: localctx.exception = re @@ -4501,17 +4514,17 @@ def inputQualifier(self): localctx = PyNestMLParser.InputQualifierContext(self, self._ctx, self.state) self.enterRule(localctx, 88, self.RULE_inputQualifier) try: - self.state = 612 + self.state = 615 self._errHandler.sync(self) token = self._input.LA(1) if token in [44]: self.enterOuterAlt(localctx, 1) - self.state = 610 + self.state = 613 localctx.isInhibitory = self.match(PyNestMLParser.INHIBITORY_KEYWORD) pass elif token in [45]: self.enterOuterAlt(localctx, 2) - self.state = 611 + self.state = 614 localctx.isExcitatory = self.match(PyNestMLParser.EXCITATORY_KEYWORD) pass else: @@ -4598,61 +4611,61 @@ def outputBlock(self): self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 614 + self.state = 617 self.match(PyNestMLParser.OUTPUT_KEYWORD) - self.state = 615 + self.state = 618 self.match(PyNestMLParser.COLON) - self.state = 616 + self.state = 619 self.match(PyNestMLParser.NEWLINE) - self.state = 617 + self.state = 620 self.match(PyNestMLParser.INDENT) - self.state = 634 + self.state = 637 self._errHandler.sync(self) token = self._input.LA(1) if token in [43]: - self.state = 618 + self.state = 621 localctx.isSpike = self.match(PyNestMLParser.SPIKE_KEYWORD) - self.state = 631 + self.state = 634 self._errHandler.sync(self) _la = self._input.LA(1) if _la==50: - self.state = 619 + self.state = 622 self.match(PyNestMLParser.LEFT_PAREN) - self.state = 628 + self.state = 631 self._errHandler.sync(self) _la = self._input.LA(1) if _la==90: - self.state = 620 + self.state = 623 localctx.attribute = self.parameter() - self.state = 625 + self.state = 628 self._errHandler.sync(self) _la = self._input.LA(1) while _la==75: - self.state = 621 + self.state = 624 self.match(PyNestMLParser.COMMA) - self.state = 622 + self.state = 625 localctx.attribute = self.parameter() - self.state = 627 + self.state = 630 self._errHandler.sync(self) _la = self._input.LA(1) - self.state = 630 + self.state = 633 self.match(PyNestMLParser.RIGHT_PAREN) pass elif token in [40]: - self.state = 633 + self.state = 636 localctx.isContinuous = self.match(PyNestMLParser.CONTINUOUS_KEYWORD) pass else: raise NoViableAltException(self) - self.state = 636 + self.state = 639 self.match(PyNestMLParser.NEWLINE) - self.state = 637 + self.state = 640 self.match(PyNestMLParser.DEDENT) except RecognitionException as re: localctx.exception = re @@ -4735,51 +4748,51 @@ def function(self): self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 639 + self.state = 642 self.match(PyNestMLParser.FUNCTION_KEYWORD) - self.state = 640 + self.state = 643 self.match(PyNestMLParser.NAME) - self.state = 641 + self.state = 644 self.match(PyNestMLParser.LEFT_PAREN) - self.state = 650 + self.state = 653 self._errHandler.sync(self) _la = self._input.LA(1) if _la==90: - self.state = 642 + self.state = 645 self.parameter() - self.state = 647 + self.state = 650 self._errHandler.sync(self) _la = self._input.LA(1) while _la==75: - self.state = 643 + self.state = 646 self.match(PyNestMLParser.COMMA) - self.state = 644 + self.state = 647 self.parameter() - self.state = 649 + self.state = 652 self._errHandler.sync(self) _la = self._input.LA(1) - self.state = 652 + self.state = 655 self.match(PyNestMLParser.RIGHT_PAREN) - self.state = 654 + self.state = 657 self._errHandler.sync(self) _la = self._input.LA(1) if (((_la) & ~0x3f) == 0 and ((1 << _la) & 1125899906874368) != 0) or _la==90 or _la==91: - self.state = 653 + self.state = 656 localctx.returnType = self.dataType() - self.state = 656 + self.state = 659 self.match(PyNestMLParser.COLON) - self.state = 657 + self.state = 660 self.match(PyNestMLParser.NEWLINE) - self.state = 658 + self.state = 661 self.match(PyNestMLParser.INDENT) - self.state = 659 + self.state = 662 self.stmtsBody() - self.state = 660 + self.state = 663 self.match(PyNestMLParser.DEDENT) except RecognitionException as re: localctx.exception = re @@ -4822,9 +4835,9 @@ def parameter(self): self.enterRule(localctx, 94, self.RULE_parameter) try: self.enterOuterAlt(localctx, 1) - self.state = 662 + self.state = 665 self.match(PyNestMLParser.NAME) - self.state = 663 + self.state = 666 self.dataType() except RecognitionException as re: localctx.exception = re @@ -4884,11 +4897,11 @@ def constParameter(self): self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 665 + self.state = 668 localctx.name = self.match(PyNestMLParser.NAME) - self.state = 666 + self.state = 669 self.match(PyNestMLParser.EQUALS) - self.state = 667 + self.state = 670 localctx.value = self._input.LT(1) _la = self._input.LA(1) if not(_la==25 or ((((_la - 88)) & ~0x3f) == 0 and ((1 << (_la - 88)) & 27) != 0)): diff --git a/pynestml/grammars/PyNestMLParser.g4 b/pynestml/grammars/PyNestMLParser.g4 index a2c861882..6ee979160 100644 --- a/pynestml/grammars/PyNestMLParser.g4 +++ b/pynestml/grammars/PyNestMLParser.g4 @@ -195,7 +195,7 @@ parser grammar PyNestMLParser; /** * ASTStmtsBody A sequence of statements. **/ - stmtsBody : NEWLINE? stmt (NEWLINE | stmt)*; + stmtsBody : NEWLINE? stmt+; /** * ASTReturnStmt Models the return statement in a function. @@ -253,7 +253,7 @@ parser grammar PyNestMLParser; * @attribute onConditionBlock: A block declaring condition statements. * @attribute updateBlock: A single update block containing the dynamic behavior. **/ - modelBody : ( includeStmt_newline | blockWithVariables | equationsBlock | inputBlock | outputBlock | function | onReceiveBlock | onConditionBlock | updateBlock )+; + modelBody : NEWLINE* ( includeStmt_newline | blockWithVariables | equationsBlock | inputBlock | outputBlock | function | onReceiveBlock | onConditionBlock | updateBlock )+; /** * ASTOnReceiveBlock diff --git a/pynestml/visitors/ast_include_statement_visitor.py b/pynestml/visitors/ast_include_statement_visitor.py index 794b000e1..210c1bf68 100644 --- a/pynestml/visitors/ast_include_statement_visitor.py +++ b/pynestml/visitors/ast_include_statement_visitor.py @@ -122,7 +122,7 @@ def visit(self, node: ASTNode): idx = model_body.get_body_elements().index(node) model_body.get_body_elements().pop(idx) model_body.body_elements = model_body.body_elements[:idx] + new_model_body.get_body_elements() + model_body.body_elements[idx:] - node.accept(ASTParentVisitor()) + # node.accept(ASTParentVisitor()) new_model_body.accept(ASTParentVisitor()) else: assert False diff --git a/pynestml/visitors/ast_visitor.py b/pynestml/visitors/ast_visitor.py index dc0dc709f..74925ba41 100644 --- a/pynestml/visitors/ast_visitor.py +++ b/pynestml/visitors/ast_visitor.py @@ -18,6 +18,7 @@ # # You should have received a copy of the GNU General Public License # along with NEST. If not, see . +import copy from pynestml.meta_model.ast_arithmetic_operator import ASTArithmeticOperator from pynestml.meta_model.ast_assignment import ASTAssignment @@ -897,7 +898,7 @@ def traverse(self, node): self.traverse_bit_operator(node) return if isinstance(node, ASTStmtsBody): - self.traverse_block(node) + self.traverse_stmts_body(node) return if isinstance(node, ASTBlockWithVariables): self.traverse_block_with_variables(node) @@ -1160,10 +1161,15 @@ def traverse_assignment(self, node): def traverse_bit_operator(self, node): return - def traverse_block(self, node): + def traverse_stmts_body(self, node): + # Check if all statements are visited in case of an include statement if node.get_stmts() is not None: - for sub_node in node.get_stmts(): - sub_node.accept(self.get_real_self()) + visited_stmts = [] + while len(visited_stmts) < len(node.get_stmts()): + for sub_node in node.get_stmts(): + if sub_node not in visited_stmts: + sub_node.accept(self.get_real_self()) + visited_stmts.append(sub_node) def traverse_block_with_variables(self, _node): if _node.get_declarations() is not None: @@ -1171,9 +1177,14 @@ def traverse_block_with_variables(self, _node): sub_node.accept(self.get_real_self()) def traverse_model_body(self, node): + # Check if all the body elements are processed in case of an include statement if node.get_body_elements() is not None: - for sub_node in node.get_body_elements(): - sub_node.accept(self.get_real_self()) + visited_elements = [] + while len(visited_elements) < len(node.get_body_elements()): + for sub_node in node.get_body_elements(): + if sub_node not in visited_elements: + sub_node.accept(self.get_real_self()) + visited_elements.append(sub_node) def traverse_comparison_operator(self, node): return diff --git a/tests/nest_tests/resources/IncludeStatementTest4.nestml b/tests/nest_tests/resources/IncludeStatementTest4.nestml index 687663f98..bd33bcea9 100644 --- a/tests/nest_tests/resources/IncludeStatementTest4.nestml +++ b/tests/nest_tests/resources/IncludeStatementTest4.nestml @@ -35,4 +35,5 @@ model include_statement4: v mV = 42 mV update: + include "includes/ModelA.nestml" include "includes/ModelD.nestml" diff --git a/tests/nest_tests/resources/includes/include_statement_model_test_state_block.nestml b/tests/nest_tests/resources/includes/include_statement_model_test_state_block.nestml index c139af335..cd79324b2 100644 --- a/tests/nest_tests/resources/includes/include_statement_model_test_state_block.nestml +++ b/tests/nest_tests/resources/includes/include_statement_model_test_state_block.nestml @@ -1,3 +1,3 @@ state: x real = 0. - y real = 0 \ No newline at end of file + y real = 0 diff --git a/tests/nest_tests/test_include_statement.py b/tests/nest_tests/test_include_statement.py index a1fd3e477..11c0bed04 100644 --- a/tests/nest_tests/test_include_statement.py +++ b/tests/nest_tests/test_include_statement.py @@ -132,7 +132,7 @@ def test_include_statement4(self): nest.Simulate(151.) v = mm.get("events")["v"] - np.testing.assert_allclose(v[-1], 27.) + np.testing.assert_allclose(v[-1], 3.71) def test_include_statement5(self): input_path = os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), "resources", "IncludeStatementTest5.nestml"))) diff --git a/tests/test_nestml_printer.py b/tests/test_nestml_printer.py index b8c48b7d3..d976604cc 100644 --- a/tests/test_nestml_printer.py +++ b/tests/test_nestml_printer.py @@ -48,19 +48,19 @@ def setUp(self): Logger.init_logger(LoggingLevel.INFO) def test_block_with_variables_with_comments(self): - block = " # pre1\n" \ - " state: # in\n" \ - " # real pre\n" \ - " # real pre2\n" \ - " r real = 0\n" + block = "# pre1\n" \ + "state: # in\n" \ + " # real pre\n" \ + " # real pre2\n" \ + " r real = 0\n" model = ModelParser.parse_model_body(block) model_printer = NESTMLPrinter() assert block == model_printer.print(model) def test_block_with_variables_with_in_comments(self): - block = " # pre1\n" \ - " state:\n" \ - " r real = 0 # in comment\n" + block = "# pre1\n" \ + "state:\n" \ + " r real = 0 # in comment\n" model = ModelParser.parse_model_body(block) model_printer = NESTMLPrinter() assert block == model_printer.print(model) @@ -86,11 +86,11 @@ def test_assignment_without_comments(self): assert assignment == model_printer.print(model) def test_function_with_comments(self): - t_function = " # pre func\n" \ - " function test(Tau_1 ms) real: # in func\n" \ - " # decl pre\n" \ - " exact_integration_adjustment real = ((1 / Tau_2) - (1 / Tau_1)) * ms # decl in\n" \ - " return normalisation_factor\n" + t_function = "# pre func\n" \ + "function test(Tau_1 ms) real: # in func\n" \ + " # decl pre\n" \ + " exact_integration_adjustment real = ((1 / Tau_2) - (1 / Tau_1)) * ms # decl in\n" \ + " return normalisation_factor\n" model = ModelParser.parse_model_body(t_function) model_printer = NESTMLPrinter() assert t_function == model_printer.print(model) @@ -150,11 +150,11 @@ def test_declaration_without_comments(self): assert declaration == model_printer.print(model) def test_equations_block_with_comments(self): - block = " # pre\n" \ - " equations: # in\n" \ - " # pre1 v\n" \ - " # pre2 v\n" \ - " v' = -v / t\n" + block = "# pre\n" \ + "equations: # in\n" \ + " # pre1 v\n" \ + " # pre2 v\n" \ + " v' = -v / t\n" model = ModelParser.parse_model_body(block) model_printer = NESTMLPrinter() assert block == model_printer.print(model) @@ -197,9 +197,9 @@ def test_while_stmt_without_comments(self): assert stmt == model_printer.print(model) def test_update_block_with_comments(self): - block = " # pre\n" \ - " update: # in\n" \ - " j = 0\n" + block = "# pre\n" \ + "update: # in\n" \ + " j = 0\n" model = ModelParser.parse_model_body(block) model_printer = NESTMLPrinter() assert block == model_printer.print(model) From cc5e187069c9557854358ee8f2556e83d91be50f Mon Sep 17 00:00:00 2001 From: "C.A.P. Linssen" Date: Thu, 13 Feb 2025 01:43:01 +0100 Subject: [PATCH 24/25] use single-line comment characters for docstrings --- .../nestml_language_concepts.rst | 56 +- .../inhomogeneous_poisson.nestml | 50 +- .../izhikevich/izhikevich_solution.nestml | 1 + .../izhikevich/izhikevich_task.nestml | 1 + ...af_psc_exp_nonlineardendrite_neuron.nestml | 50 +- .../models/iaf_psc_alpha.nestml | 115 ++- .../models/iaf_psc_alpha_adapt_curr.nestml | 119 ++- .../models/iaf_psc_alpha_adapt_thresh.nestml | 119 ++- .../iaf_psc_alpha_adapt_thresh_OU.nestml | 121 ++- .../nestml/language-configuration.json | 6 +- models/neurons/aeif_cond_alpha_neuron.nestml | 96 +-- models/neurons/aeif_cond_exp_neuron.nestml | 98 +-- .../hh_cond_exp_destexhe_neuron.nestml | 64 +- .../neurons/hh_cond_exp_traub_neuron.nestml | 98 +-- models/neurons/hh_moto_5ht_neuron.nestml | 64 +- models/neurons/hh_psc_alpha_neuron.nestml | 90 +-- models/neurons/hill_tononi_neuron.nestml | 72 +- models/neurons/iaf_chxk_2008_neuron.nestml | 70 +- models/neurons/iaf_cond_alpha_neuron.nestml | 74 +- models/neurons/iaf_cond_beta_neuron.nestml | 90 +-- models/neurons/iaf_cond_exp_neuron.nestml | 54 +- .../neurons/iaf_cond_exp_sfa_rr_neuron.nestml | 70 +- models/neurons/iaf_psc_alpha_neuron.nestml | 116 +-- ...iaf_psc_delta_fixed_timestep_neuron.nestml | 64 +- models/neurons/iaf_psc_delta_neuron.nestml | 84 +- models/neurons/iaf_psc_exp_htum_neuron.nestml | 104 +-- models/neurons/iaf_psc_exp_neuron.nestml | 108 +-- models/neurons/ignore_and_fire_neuron.nestml | 48 +- models/neurons/izhikevich_neuron.nestml | 76 +- .../izhikevich_psc_alpha_neuron.nestml | 76 +- models/neurons/mat2_psc_exp_neuron.nestml | 88 +- models/neurons/terub_gpe_neuron.nestml | 62 +- models/neurons/terub_stn_neuron.nestml | 54 +- .../neurons/traub_cond_multisyn_neuron.nestml | 54 +- models/neurons/traub_psc_alpha_neuron.nestml | 44 +- models/neurons/wb_cond_exp_neuron.nestml | 56 +- models/neurons/wb_cond_multisyn_neuron.nestml | 56 +- .../neuromodulated_stdp_synapse.nestml | 50 +- models/synapses/noisy_synapse.nestml | 18 +- models/synapses/static_synapse.nestml | 16 +- .../stdp_nn_pre_centered_synapse.nestml | 104 +-- .../stdp_nn_restr_symm_synapse.nestml | 88 +- models/synapses/stdp_nn_symm_synapse.nestml | 98 +-- models/synapses/stdp_synapse.nestml | 70 +- models/synapses/stdp_triplet_synapse.nestml | 44 +- models/synapses/stdsp_synapse.nestml | 22 +- pynestml/codegeneration/autodoc_builder.py | 2 +- .../codegeneration/printers/nestml_printer.py | 17 +- pynestml/generated/PyNestMLLexer.py | 757 +++++++++--------- pynestml/generated/PyNestMLParser.py | 663 ++++++++------- pynestml/grammars/PyNestMLLexer.g4 | 3 - .../visitors/comment_collector_visitor.py | 63 +- tests/docstring_comment_test.py | 29 +- .../CoCoAssignmentToInlineExpression.nestml | 49 +- ...oCoConvolveNotCorrectlyParametrized.nestml | 65 +- .../CoCoConvolveNotCorrectlyProvided.nestml | 65 +- tests/invalid/CoCoEachBlockUnique.nestml | 65 +- tests/invalid/CoCoElementInSameLine.nestml | 67 +- tests/invalid/CoCoElementNotDefined.nestml | 67 +- ...tionCallNotConsistentWrongArgNumber.nestml | 65 +- tests/invalid/CoCoFunctionNotUnique.nestml | 67 +- tests/invalid/CoCoFunctionRedeclared.nestml | 67 +- tests/invalid/CoCoIllegalExpression.nestml | 67 +- .../CoCoIncorrectReturnStatement.nestml | 67 +- tests/invalid/CoCoInitValuesWithoutOde.nestml | 67 +- .../CoCoInlineExpressionHasNoRhs.nestml | 65 +- .../CoCoInlineExpressionWithSeveralLhs.nestml | 65 +- .../CoCoInputPortWithRedundantTypes.nestml | 65 +- ...tegrateOdesCalledIfEquationsDefined.nestml | 65 +- .../CoCoInternalAssignedOutsideBlock.nestml | 67 +- tests/invalid/CoCoInvariantNotBool.nestml | 67 +- tests/invalid/CoCoKernelType.nestml | 69 +- .../CoCoKernelTypeInitialValues.nestml | 69 +- .../CoCoMultipleNeuronsWithEqualName.nestml | 68 +- .../invalid/CoCoNestNamespaceCollision.nestml | 67 +- tests/invalid/CoCoNoOrderOfEquations.nestml | 65 +- tests/invalid/CoCoOdeIncorrectlyTyped.nestml | 71 +- .../CoCoOdeVarNotInInitialValues.nestml | 65 +- .../CoCoOutputPortDefinedIfEmitCall-2.nestml | 65 +- .../CoCoOutputPortDefinedIfEmitCall.nestml | 65 +- .../CoCoOutputPortTypeContinuous.nestml | 61 +- .../CoCoOutputPortTypeIfEmitCall-2.nestml | 61 +- .../CoCoOutputPortTypeIfEmitCall-3.nestml | 61 +- .../CoCoOutputPortTypeIfEmitCall.nestml | 61 +- .../CoCoParameterAssignedOutsideBlock.nestml | 67 +- .../CoCoPrioritiesCorrectlySpecified.nestml | 61 +- .../invalid/CoCoResolutionLegallyUsed.nestml | 61 +- .../CoCoSpikeInputPortWithoutType.nestml | 65 +- .../CoCoStateVariablesInitialized.nestml | 63 +- tests/invalid/CoCoUnitNumeratorNotOne.nestml | 67 +- .../CoCoValueAssignedToInputPort.nestml | 65 +- .../CoCoVariableDefinedAfterUsage.nestml | 65 +- tests/invalid/CoCoVariableNotDefined.nestml | 65 +- tests/invalid/CoCoVariableRedeclared.nestml | 65 +- .../CoCoVariableRedeclaredInSameScope.nestml | 67 +- .../invalid/CoCoVectorDeclarationSize.nestml | 69 +- .../CoCoVectorInNonVectorDeclaration.nestml | 67 +- .../CoCoVectorInputPortSizeAndType.nestml | 67 +- .../CoCoVectorParameterDeclaration.nestml | 69 +- tests/invalid/CoCoVectorParameterType.nestml | 69 +- ...atorWithDifferentButCompatibleUnits.nestml | 49 +- tests/invalid/DocstringCommentTest.nestml | 67 +- ...tdp_synapse_missing_delay_decorator.nestml | 69 +- .../resources/cm_default.nestml | 57 +- .../resources/concmech.nestml | 43 +- .../resources/continuous_test.nestml | 43 +- .../invalid/CoCoCmVariableHasRhs.nestml | 69 +- .../invalid/CoCoCmVariableMultiUse.nestml | 69 +- .../invalid/CoCoCmVariablesDeclared.nestml | 69 +- .../invalid/CoCoCmVcompExists.nestml | 69 +- .../valid/CoCoCmVariableHasRhs.nestml | 69 +- .../valid/CoCoCmVariableMultiUse.nestml | 69 +- .../valid/CoCoCmVariablesDeclared.nestml | 69 +- .../resources/valid/CoCoCmVcompExists.nestml | 69 +- tests/nest_tests/nest_integration_test.py | 2 +- .../BiexponentialPostSynapticResponse.nestml | 61 +- .../resources/CppVariableNames.nestml | 55 +- ...erentialEquationsWithAnalyticSolver.nestml | 51 +- ...ifferentialEquationsWithMixedSolver.nestml | 47 +- ...ferentialEquationsWithNumericSolver.nestml | 47 +- tests/nest_tests/resources/FIR_filter.nestml | 61 +- tests/nest_tests/resources/ForLoop.nestml | 51 +- .../resources/MathFunctionTest.nestml | 49 +- .../resources/PrintStatementInFunction.nestml | 49 +- .../PrintStatementWithVariables.nestml | 49 +- .../resources/PrintVariables.nestml | 49 +- ...blesWithDifferentButCompatibleUnits.nestml | 49 +- .../resources/RecordableVariables.nestml | 59 +- .../resources/SimplePrintStatement.nestml | 49 +- .../resources/SimpleVectorsModel.nestml | 53 +- .../resources/StringHandlingTest.nestml | 49 +- .../resources/TimeVariableNeuron.nestml | 49 +- .../TimeVariablePrePostSynapse.nestml | 49 +- .../resources/TimeVariableSynapse.nestml | 49 +- tests/nest_tests/resources/Vectors.nestml | 63 +- .../VectorsDeclarationAndAssignment.nestml | 71 +- .../nest_tests/resources/VectorsResize.nestml | 61 +- tests/nest_tests/resources/WhileLoop.nestml | 51 +- .../resources/add_spikes_to_ode.nestml | 51 +- .../aeif_cond_alpha_alt_neuron.nestml | 81 +- ...alpha_function_2nd_order_ode_neuron.nestml | 51 +- ...ction_with_inline_expression_neuron.nestml | 57 +- .../delay_test_assigned_delay2_synapse.nestml | 7 +- .../delay_test_assigned_delay_synapse.nestml | 7 +- .../delay_test_assigned_synapse.nestml | 7 +- .../delay_test_plastic_synapse.nestml | 7 +- .../resources/delay_test_synapse.nestml | 7 +- .../dopa_second_order_synapse.nestml | 63 +- .../homogeneous_parameters_synapse.nestml | 15 +- .../iaf_cond_exp_Istep_neuron.nestml | 45 +- .../resources/iaf_psc_exp_multisynapse.nestml | 25 +- .../iaf_psc_exp_multisynapse_vectors.nestml | 25 +- .../iaf_psc_exp_nonlineardendrite.nestml | 65 +- .../iaf_psc_exp_resolution_test.nestml | 17 +- tests/nest_tests/resources/input_ports.nestml | 61 +- .../resources/input_ports_in_loop.nestml | 61 +- .../integrate_odes_nonlinear_test.nestml | 5 +- .../resources/integrate_odes_test.nestml | 5 +- .../integrate_odes_test_params.nestml | 5 +- .../integrate_odes_test_params2.nestml | 5 +- .../resources/minimal_neuron.nestml | 55 +- .../random_functions_illegal_neuron.nestml | 51 +- .../random_functions_illegal_synapse.nestml | 51 +- .../resources/test_delta_kernel_neuron.nestml | 17 +- .../test_plasticity_dynamics_neuron.nestml | 61 +- .../test_plasticity_dynamics_synapse.nestml | 57 +- .../weight_test_assigned_synapse.nestml | 7 +- .../weight_test_plastic_synapse.nestml | 7 +- tests/resources/BlockTest.nestml | 71 +- tests/resources/CommentTest.nestml | 63 +- ...mentWithDifferentButCompatibleUnits.nestml | 49 +- ...DifferentButCompatibleUnitMagnitude.nestml | 49 +- ...tionWithDifferentButCompatibleUnits.nestml | 49 +- ...clarationWithSameVariableNameAsUnit.nestml | 49 +- ...thDifferentButCompatibleNestedUnits.nestml | 49 +- ...mentWithDifferentButCompatibleUnits.nestml | 49 +- tests/resources/ExpressionCollection.nestml | 65 +- tests/resources/ExpressionTypeTest.nestml | 83 +- ...mentWithDifferentButCompatibleUnits.nestml | 49 +- ...CallWithDifferentButCompatibleUnits.nestml | 49 +- .../FunctionParameterTemplatingTest.nestml | 61 +- .../MagnitudeCompatibilityTest.nestml | 61 +- tests/resources/NestMLPrinterTest.nestml | 61 +- tests/resources/ResolutionTest.nestml | 61 +- ...CallWithDifferentButCompatibleUnits.nestml | 49 +- .../neuron_event_inv_priority_test.nestml | 61 +- .../neuron_event_priority_test.nestml | 61 +- .../random_number_generators_test.nestml | 49 +- .../synapse_event_inv_priority_test.nestml | 61 +- .../synapse_event_priority_test.nestml | 61 +- tests/test_nestml_printer.py | 8 +- ...oCoConvolveNotCorrectlyParametrized.nestml | 65 +- .../CoCoConvolveNotCorrectlyProvided.nestml | 65 +- tests/valid/CoCoEachBlockUnique.nestml | 61 +- tests/valid/CoCoElementInSameLine.nestml | 67 +- tests/valid/CoCoElementNotDefined.nestml | 67 +- ...tionCallNotConsistentWrongArgNumber.nestml | 65 +- tests/valid/CoCoFunctionNotUnique.nestml | 67 +- tests/valid/CoCoFunctionRedeclared.nestml | 67 +- tests/valid/CoCoIllegalExpression.nestml | 67 +- .../valid/CoCoIncorrectReturnStatement.nestml | 67 +- tests/valid/CoCoInitValuesWithoutOde.nestml | 67 +- .../valid/CoCoInlineExpressionHasNoRhs.nestml | 65 +- .../CoCoInlineExpressionWithSeveralLhs.nestml | 65 +- .../CoCoInputPortWithRedundantTypes.nestml | 65 +- ...tegrateOdesCalledIfEquationsDefined.nestml | 65 +- .../CoCoInternalAssignedOutsideBlock.nestml | 67 +- tests/valid/CoCoInvariantNotBool.nestml | 67 +- tests/valid/CoCoKernelType.nestml | 69 +- .../CoCoMultipleNeuronsWithEqualName.nestml | 68 +- tests/valid/CoCoNestNamespaceCollision.nestml | 65 +- tests/valid/CoCoNoOrderOfEquations.nestml | 65 +- tests/valid/CoCoOdeCorrectlyTyped.nestml | 69 +- .../valid/CoCoOdeVarNotInInitialValues.nestml | 67 +- .../CoCoOutputPortDefinedIfEmitCall.nestml | 65 +- .../CoCoParameterAssignedOutsideBlock.nestml | 67 +- .../CoCoPrioritiesCorrectlySpecified.nestml | 61 +- tests/valid/CoCoResolutionLegallyUsed.nestml | 61 +- .../CoCoSpikeInputPortWithoutType.nestml | 65 +- .../CoCoStateVariablesInitialized.nestml | 63 +- tests/valid/CoCoUnitNumeratorNotOne.nestml | 67 +- .../valid/CoCoValueAssignedToInputPort.nestml | 65 +- .../CoCoVariableDefinedAfterUsage.nestml | 65 +- tests/valid/CoCoVariableNotDefined.nestml | 65 +- tests/valid/CoCoVariableRedeclared.nestml | 65 +- .../CoCoVariableRedeclaredInSameScope.nestml | 67 +- .../CoCoVariableWithSameNameAsUnit.nestml | 65 +- tests/valid/CoCoVectorDeclarationSize.nestml | 68 +- .../CoCoVectorInNonVectorDeclaration.nestml | 67 +- .../CoCoVectorInputPortSizeAndType.nestml | 67 +- .../CoCoVectorParameterDeclaration.nestml | 69 +- tests/valid/CoCoVectorParameterType.nestml | 69 +- ...atorWithDifferentButCompatibleUnits.nestml | 49 +- tests/valid/DocstringCommentTest.nestml | 65 +- 234 files changed, 7377 insertions(+), 7573 deletions(-) diff --git a/doc/nestml_language/nestml_language_concepts.rst b/doc/nestml_language/nestml_language_concepts.rst index f2c658d05..00cdcf553 100644 --- a/doc/nestml_language/nestml_language_concepts.rst +++ b/doc/nestml_language/nestml_language_concepts.rst @@ -299,37 +299,10 @@ For example, the following model will result in one warning and one error: foo = 42 ms # ERROR: Actual type different from expected. Expected: 's', got: 'mA'! -Documentation string -~~~~~~~~~~~~~~~~~~~~ - -Each model may be documented by a block of text in reStructuredText format. Following `PEP 257 "Docstring Conventions" `_, this block should be enclosed in triple double quotes (``""" ... """``) and appear directly before the definition of the neuron. For example: - -.. code-block:: nestml - - """ - my_custom_neuron: My customized version of a Hodgkin-Huxley model - ################################################################# - - Description - +++++++++++ - - Long description follows here. We can typeset LaTeX math: - - .. math:: - - E = mc^2 - - """ - model my_custom_neuron: - # [...] - -This documentation block is rendered as HTML on the :doc:`models library `. - - Comments in the model ~~~~~~~~~~~~~~~~~~~~~ -When the character ``#`` appears as the first character on a line (ignoring whitespace), the remainder of that line is allowed to contain any comment string. Comments are not interpreted as part of the model specification, but when a comment is placed in a strategic location, it will be printed into the generated NEST code. +When the character ``#`` appears as the first character on a line (ignoring whitespace), the remainder of that line is allowed to contain any comment string. Comments are not interpreted as part of the model specification, but when a comment is placed in a strategic location, it may be printed into the generated code. Example of single or multi-line comments: @@ -341,22 +314,19 @@ Example of single or multi-line comments: # a comment # over several lines. -To enable NESTML to recognize which element a comment belongs to, the following approach has to be used: there should be no white line separating the comment and its target and the comment should be placed before the target line or on the same line as the target. For example: +To enable NESTML to recognize which element a comment belongs to, the following approach is used: there should be no white line separating the comment and its target, and the comment should be placed before the target line or on the same line as the target. For example: .. code-block:: nestml # I am a comment of the membrane potential V_m mV = -55 mV # I am a comment of the membrane potential - # I am not a comment of the membrane potential. A white line separates us. - If a comment shall be attached to an element, no white lines are allowed. .. code-block:: nestml # I am not a comment of the membrane potential. - # I am a comment of the membrane potential. V_m mV = -55 mV # I am a comment of the membrane potential Whitelines are therefore used to separate comment targets: @@ -369,6 +339,28 @@ Whitelines are therefore used to separate comment targets: # I am a comment of the resting potential. V_rest mV = -60 mV +The text of each comment is interpreted as `Sphinx reStructuredText format `_. + +Documentation for a model may appear directly in front of the model definition, akin to Python "docstrings" (see `PEP 257 "Docstring Conventions" `_). For example: + +.. code-block:: nestml + + # my_custom_neuron: My customized version of a Hodgkin-Huxley model + # ################################################################# + # + # Description + # +++++++++++ + # + # Long description follows here. We can typeset LaTeX math: + # + # .. math:: + # + # E = mc^2 + # + model my_custom_neuron: + # [...] + +The documentation block is rendered as HTML on the :doc:`models library `. Assignments ~~~~~~~~~~~ diff --git a/doc/tutorials/inhomogeneous_poisson/inhomogeneous_poisson.nestml b/doc/tutorials/inhomogeneous_poisson/inhomogeneous_poisson.nestml index 483ccd9e0..23d987a0a 100644 --- a/doc/tutorials/inhomogeneous_poisson/inhomogeneous_poisson.nestml +++ b/doc/tutorials/inhomogeneous_poisson/inhomogeneous_poisson.nestml @@ -1,28 +1,28 @@ -""" -inhomogeneous_poisson - Inhomogeneous Poisson process model -########################################################### - -Description -+++++++++++ - -Inhomogeneous Poisson process model. - -The rate of the model is piecewise constant and is defined by an array containing desired rates (in units of 1/s) and an array of equal length containing the corresponding times (in units of ms). Please see the documentation for the NEST built-in inhomogeneous_poisson_generator for more details [2]. - - -See also -++++++++ - -See the inhomogeneous Poisson generator NESTML tutorial for a usage example. - - -References -++++++++++ - -[1] Wikipedia contributors. 'Poisson Point Process.' Wikipedia, The Free Encyclopedia. Accessed on February 23, 2024. https://en.wikipedia.org/wiki/Poisson_point_process. - -[2] https://nest-simulator.readthedocs.io/en/stable/models/inhomogeneous_poisson_generator.html -""" +# inhomogeneous_poisson - Inhomogeneous Poisson process model +# ########################################################### +# +# Description +# +++++++++++ +# +# Inhomogeneous Poisson process model. +# +# The rate of the model is piecewise constant and is defined by an array containing desired rates (in units of 1/s) and an array of equal length containing the corresponding times (in units of ms). Please see the documentation for the NEST built-in inhomogeneous_poisson_generator for more details [2]. +# +# +# See also +# ++++++++ +# +# See the inhomogeneous Poisson generator NESTML tutorial for a usage example. +# +# +# References +# ++++++++++ +# +# [1] Wikipedia contributors. 'Poisson Point Process.' Wikipedia, The Free Encyclopedia. Accessed on February 23, 2024. https://en.wikipedia.org/wiki/Poisson_point_process. +# +# [2] https://nest-simulator.readthedocs.io/en/stable/models/inhomogeneous_poisson_generator.html +# +# model inhomogeneous_poisson_neuron: state: diff --git a/doc/tutorials/izhikevich/izhikevich_solution.nestml b/doc/tutorials/izhikevich/izhikevich_solution.nestml index c7f99b877..cc8ae9e86 100644 --- a/doc/tutorials/izhikevich/izhikevich_solution.nestml +++ b/doc/tutorials/izhikevich/izhikevich_solution.nestml @@ -1,3 +1,4 @@ +# model izhikevich_tutorial_neuron: state: diff --git a/doc/tutorials/izhikevich/izhikevich_task.nestml b/doc/tutorials/izhikevich/izhikevich_task.nestml index c26c304c7..37ab7b7f8 100644 --- a/doc/tutorials/izhikevich/izhikevich_task.nestml +++ b/doc/tutorials/izhikevich/izhikevich_task.nestml @@ -1,3 +1,4 @@ +# model izhikevich_tutorial_neuron: state: diff --git a/doc/tutorials/sequence_learning/iaf_psc_exp_nonlineardendrite_neuron.nestml b/doc/tutorials/sequence_learning/iaf_psc_exp_nonlineardendrite_neuron.nestml index 790ef7391..a01bdadd9 100644 --- a/doc/tutorials/sequence_learning/iaf_psc_exp_nonlineardendrite_neuron.nestml +++ b/doc/tutorials/sequence_learning/iaf_psc_exp_nonlineardendrite_neuron.nestml @@ -1,29 +1,27 @@ -""" -iaf_psc_exp_nonlineardendrite_neuron -#################################### - - -Copyright statement -+++++++++++++++++++ - -This file is part of NEST. - -Copyright (C) 2004 The NEST Initiative - -NEST is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -NEST is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with NEST. If not, see . -""" - +# iaf_psc_exp_nonlineardendrite_neuron +# #################################### +# +# +# Copyright statement +# +++++++++++++++++++ +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . +# model iaf_psc_exp_nonlineardendrite_neuron: state: diff --git a/doc/tutorials/spike_frequency_adaptation/models/iaf_psc_alpha.nestml b/doc/tutorials/spike_frequency_adaptation/models/iaf_psc_alpha.nestml index 5a6bcd84e..5da652ad0 100644 --- a/doc/tutorials/spike_frequency_adaptation/models/iaf_psc_alpha.nestml +++ b/doc/tutorials/spike_frequency_adaptation/models/iaf_psc_alpha.nestml @@ -1,61 +1,60 @@ -""" -iaf_psc_alpha - Leaky integrate-and-fire neuron model -##################################################### - -Description -+++++++++++ - -iaf_psc_alpha is an implementation of a leaky integrate-and-fire model -with alpha-function kernel synaptic currents. Thus, synaptic currents -and the resulting post-synaptic potentials have a finite rise time. - -The threshold crossing is followed by an absolute refractory period -during which the membrane potential is clamped to the resting potential. - -The general framework for the consistent formulation of systems with -neuron like dynamics interacting by point events is described in -[1]_. A flow chart can be found in [2]_. - -Critical tests for the formulation of the neuron model are the -comparisons of simulation results for different computation step -sizes. - -The iaf_psc_alpha is the standard model used to check the consistency -of the nest simulation kernel because it is at the same time complex -enough to exhibit non-trivial dynamics and simple enough compute -relevant measures analytically. - -.. note:: - If tau_m is very close to tau_syn_exc or tau_syn_inh, numerical problems - may arise due to singularities in the propagator matrics. If this is - the case, replace equal-valued parameters by a single parameter. - - For details, please see ``IAF_neurons_singularity.ipynb`` in - the NEST source code (``docs/model_details``). - - -References -++++++++++ - -.. [1] Rotter S, Diesmann M (1999). Exact simulation of - time-invariant linear systems with applications to neuronal - modeling. Biologial Cybernetics 81:381-402. - DOI: https://doi.org/10.1007/s004220050570 -.. [2] Diesmann M, Gewaltig M-O, Rotter S, & Aertsen A (2001). State - space analysis of synchronous spiking in cortical neural - networks. Neurocomputing 38-40:565-571. - DOI: https://doi.org/10.1016/S0925-2312(01)00409-X -.. [3] Morrison A, Straube S, Plesser H E, Diesmann M (2006). Exact - subthreshold integration with continuous spike times in discrete time - neural network simulations. Neural Computation, in press - DOI: https://doi.org/10.1162/neco.2007.19.1.47 - - -See also -++++++++ - -iaf_psc_delta, iaf_psc_exp, iaf_cond_alpha -""" +# iaf_psc_alpha - Leaky integrate-and-fire neuron model +# ##################################################### +# +# Description +# +++++++++++ +# +# iaf_psc_alpha is an implementation of a leaky integrate-and-fire model +# with alpha-function kernel synaptic currents. Thus, synaptic currents +# and the resulting post-synaptic potentials have a finite rise time. +# +# The threshold crossing is followed by an absolute refractory period +# during which the membrane potential is clamped to the resting potential. +# +# The general framework for the consistent formulation of systems with +# neuron like dynamics interacting by point events is described in +# [1]_. A flow chart can be found in [2]_. +# +# Critical tests for the formulation of the neuron model are the +# comparisons of simulation results for different computation step +# sizes. +# +# The iaf_psc_alpha is the standard model used to check the consistency +# of the nest simulation kernel because it is at the same time complex +# enough to exhibit non-trivial dynamics and simple enough compute +# relevant measures analytically. +# +# .. note:: +# If tau_m is very close to tau_syn_exc or tau_syn_inh, numerical problems +# may arise due to singularities in the propagator matrics. If this is +# the case, replace equal-valued parameters by a single parameter. +# +# For details, please see ``IAF_neurons_singularity.ipynb`` in +# the NEST source code (``docs/model_details``). +# +# +# References +# ++++++++++ +# +# .. [1] Rotter S, Diesmann M (1999). Exact simulation of +# time-invariant linear systems with applications to neuronal +# modeling. Biologial Cybernetics 81:381-402. +# DOI: https://doi.org/10.1007/s004220050570 +# .. [2] Diesmann M, Gewaltig M-O, Rotter S, & Aertsen A (2001). State +# space analysis of synchronous spiking in cortical neural +# networks. Neurocomputing 38-40:565-571. +# DOI: https://doi.org/10.1016/S0925-2312(01)00409-X +# .. [3] Morrison A, Straube S, Plesser H E, Diesmann M (2006). Exact +# subthreshold integration with continuous spike times in discrete time +# neural network simulations. Neural Computation, in press +# DOI: https://doi.org/10.1162/neco.2007.19.1.47 +# +# +# See also +# ++++++++ +# +# iaf_psc_delta, iaf_psc_exp, iaf_cond_alpha +# model iaf_psc_alpha_neuron: state: diff --git a/doc/tutorials/spike_frequency_adaptation/models/iaf_psc_alpha_adapt_curr.nestml b/doc/tutorials/spike_frequency_adaptation/models/iaf_psc_alpha_adapt_curr.nestml index 7d9887075..7b7f572cb 100644 --- a/doc/tutorials/spike_frequency_adaptation/models/iaf_psc_alpha_adapt_curr.nestml +++ b/doc/tutorials/spike_frequency_adaptation/models/iaf_psc_alpha_adapt_curr.nestml @@ -1,63 +1,62 @@ -""" -iaf_psc_alpha_adapt_curr - Leaky integrate-and-fire neuron model -################################################################ - -Description -+++++++++++ - -This model augments iaf_psc_alpha with an adaptation current. - -iaf_psc_alpha is an implementation of a leaky integrate-and-fire model -with alpha-function kernel synaptic currents. Thus, synaptic currents -and the resulting post-synaptic potentials have a finite rise time. - -The threshold crossing is followed by an absolute refractory period -during which the membrane potential is clamped to the resting potential. - -The general framework for the consistent formulation of systems with -neuron like dynamics interacting by point events is described in -[1]_. A flow chart can be found in [2]_. - -Critical tests for the formulation of the neuron model are the -comparisons of simulation results for different computation step -sizes. - -The iaf_psc_alpha is the standard model used to check the consistency -of the nest simulation kernel because it is at the same time complex -enough to exhibit non-trivial dynamics and simple enough compute -relevant measures analytically. - -.. note:: - If tau_m is very close to tau_syn_exc or tau_syn_inh, numerical problems - may arise due to singularities in the propagator matrics. If this is - the case, replace equal-valued parameters by a single parameter. - - For details, please see ``IAF_neurons_singularity.ipynb`` in - the NEST source code (``docs/model_details``). - - -References -++++++++++ - -.. [1] Rotter S, Diesmann M (1999). Exact simulation of - time-invariant linear systems with applications to neuronal - modeling. Biologial Cybernetics 81:381-402. - DOI: https://doi.org/10.1007/s004220050570 -.. [2] Diesmann M, Gewaltig M-O, Rotter S, & Aertsen A (2001). State - space analysis of synchronous spiking in cortical neural - networks. Neurocomputing 38-40:565-571. - DOI: https://doi.org/10.1016/S0925-2312(01)00409-X -.. [3] Morrison A, Straube S, Plesser H E, Diesmann M (2006). Exact - subthreshold integration with continuous spike times in discrete time - neural network simulations. Neural Computation, in press - DOI: https://doi.org/10.1162/neco.2007.19.1.47 - - -See also -++++++++ - -iaf_psc_delta, iaf_psc_exp, iaf_cond_alpha -""" +# iaf_psc_alpha_adapt_curr - Leaky integrate-and-fire neuron model +# ################################################################ +# +# Description +# +++++++++++ +# +# This model augments iaf_psc_alpha with an adaptation current. +# +# iaf_psc_alpha is an implementation of a leaky integrate-and-fire model +# with alpha-function kernel synaptic currents. Thus, synaptic currents +# and the resulting post-synaptic potentials have a finite rise time. +# +# The threshold crossing is followed by an absolute refractory period +# during which the membrane potential is clamped to the resting potential. +# +# The general framework for the consistent formulation of systems with +# neuron like dynamics interacting by point events is described in +# [1]_. A flow chart can be found in [2]_. +# +# Critical tests for the formulation of the neuron model are the +# comparisons of simulation results for different computation step +# sizes. +# +# The iaf_psc_alpha is the standard model used to check the consistency +# of the nest simulation kernel because it is at the same time complex +# enough to exhibit non-trivial dynamics and simple enough compute +# relevant measures analytically. +# +# .. note:: +# If tau_m is very close to tau_syn_exc or tau_syn_inh, numerical problems +# may arise due to singularities in the propagator matrics. If this is +# the case, replace equal-valued parameters by a single parameter. +# +# For details, please see ``IAF_neurons_singularity.ipynb`` in +# the NEST source code (``docs/model_details``). +# +# +# References +# ++++++++++ +# +# .. [1] Rotter S, Diesmann M (1999). Exact simulation of +# time-invariant linear systems with applications to neuronal +# modeling. Biologial Cybernetics 81:381-402. +# DOI: https://doi.org/10.1007/s004220050570 +# .. [2] Diesmann M, Gewaltig M-O, Rotter S, & Aertsen A (2001). State +# space analysis of synchronous spiking in cortical neural +# networks. Neurocomputing 38-40:565-571. +# DOI: https://doi.org/10.1016/S0925-2312(01)00409-X +# .. [3] Morrison A, Straube S, Plesser H E, Diesmann M (2006). Exact +# subthreshold integration with continuous spike times in discrete time +# neural network simulations. Neural Computation, in press +# DOI: https://doi.org/10.1162/neco.2007.19.1.47 +# +# +# See also +# ++++++++ +# +# iaf_psc_delta, iaf_psc_exp, iaf_cond_alpha +# model iaf_psc_alpha_adapt_curr_neuron: state: diff --git a/doc/tutorials/spike_frequency_adaptation/models/iaf_psc_alpha_adapt_thresh.nestml b/doc/tutorials/spike_frequency_adaptation/models/iaf_psc_alpha_adapt_thresh.nestml index ec0f42c50..89c1344a9 100644 --- a/doc/tutorials/spike_frequency_adaptation/models/iaf_psc_alpha_adapt_thresh.nestml +++ b/doc/tutorials/spike_frequency_adaptation/models/iaf_psc_alpha_adapt_thresh.nestml @@ -1,63 +1,62 @@ -""" -iaf_psc_alpha_adapt_thresh - Leaky integrate-and-fire neuron model -################################################################## - -Description -+++++++++++ - -This model augments iaf_psc_alpha with threshold adaptation. - -iaf_psc_alpha is an implementation of a leaky integrate-and-fire model -with alpha-function kernel synaptic currents. Thus, synaptic currents -and the resulting post-synaptic potentials have a finite rise time. - -The threshold crossing is followed by an absolute refractory period -during which the membrane potential is clamped to the resting potential. - -The general framework for the consistent formulation of systems with -neuron like dynamics interacting by point events is described in -[1]_. A flow chart can be found in [2]_. - -Critical tests for the formulation of the neuron model are the -comparisons of simulation results for different computation step -sizes. - -The iaf_psc_alpha is the standard model used to check the consistency -of the nest simulation kernel because it is at the same time complex -enough to exhibit non-trivial dynamics and simple enough compute -relevant measures analytically. - -.. note:: - If tau_m is very close to tau_syn_exc or tau_syn_inh, numerical problems - may arise due to singularities in the propagator matrics. If this is - the case, replace equal-valued parameters by a single parameter. - - For details, please see ``IAF_neurons_singularity.ipynb`` in - the NEST source code (``docs/model_details``). - - -References -++++++++++ - -.. [1] Rotter S, Diesmann M (1999). Exact simulation of - time-invariant linear systems with applications to neuronal - modeling. Biologial Cybernetics 81:381-402. - DOI: https://doi.org/10.1007/s004220050570 -.. [2] Diesmann M, Gewaltig M-O, Rotter S, & Aertsen A (2001). State - space analysis of synchronous spiking in cortical neural - networks. Neurocomputing 38-40:565-571. - DOI: https://doi.org/10.1016/S0925-2312(01)00409-X -.. [3] Morrison A, Straube S, Plesser H E, Diesmann M (2006). Exact - subthreshold integration with continuous spike times in discrete time - neural network simulations. Neural Computation, in press - DOI: https://doi.org/10.1162/neco.2007.19.1.47 - - -See also -++++++++ - -iaf_psc_delta, iaf_psc_exp, iaf_cond_alpha -""" +# iaf_psc_alpha_adapt_thresh - Leaky integrate-and-fire neuron model +# ################################################################## +# +# Description +# +++++++++++ +# +# This model augments iaf_psc_alpha with threshold adaptation. +# +# iaf_psc_alpha is an implementation of a leaky integrate-and-fire model +# with alpha-function kernel synaptic currents. Thus, synaptic currents +# and the resulting post-synaptic potentials have a finite rise time. +# +# The threshold crossing is followed by an absolute refractory period +# during which the membrane potential is clamped to the resting potential. +# +# The general framework for the consistent formulation of systems with +# neuron like dynamics interacting by point events is described in +# [1]_. A flow chart can be found in [2]_. +# +# Critical tests for the formulation of the neuron model are the +# comparisons of simulation results for different computation step +# sizes. +# +# The iaf_psc_alpha is the standard model used to check the consistency +# of the nest simulation kernel because it is at the same time complex +# enough to exhibit non-trivial dynamics and simple enough compute +# relevant measures analytically. +# +# .. note:: +# If tau_m is very close to tau_syn_exc or tau_syn_inh, numerical problems +# may arise due to singularities in the propagator matrics. If this is +# the case, replace equal-valued parameters by a single parameter. +# +# For details, please see ``IAF_neurons_singularity.ipynb`` in +# the NEST source code (``docs/model_details``). +# +# +# References +# ++++++++++ +# +# .. [1] Rotter S, Diesmann M (1999). Exact simulation of +# time-invariant linear systems with applications to neuronal +# modeling. Biologial Cybernetics 81:381-402. +# DOI: https://doi.org/10.1007/s004220050570 +# .. [2] Diesmann M, Gewaltig M-O, Rotter S, & Aertsen A (2001). State +# space analysis of synchronous spiking in cortical neural +# networks. Neurocomputing 38-40:565-571. +# DOI: https://doi.org/10.1016/S0925-2312(01)00409-X +# .. [3] Morrison A, Straube S, Plesser H E, Diesmann M (2006). Exact +# subthreshold integration with continuous spike times in discrete time +# neural network simulations. Neural Computation, in press +# DOI: https://doi.org/10.1162/neco.2007.19.1.47 +# +# +# See also +# ++++++++ +# +# iaf_psc_delta, iaf_psc_exp, iaf_cond_alpha +# model iaf_psc_alpha_adapt_thresh_neuron: state: diff --git a/doc/tutorials/spike_frequency_adaptation/models/iaf_psc_alpha_adapt_thresh_OU.nestml b/doc/tutorials/spike_frequency_adaptation/models/iaf_psc_alpha_adapt_thresh_OU.nestml index 96bd2f5a3..67fa0d04d 100644 --- a/doc/tutorials/spike_frequency_adaptation/models/iaf_psc_alpha_adapt_thresh_OU.nestml +++ b/doc/tutorials/spike_frequency_adaptation/models/iaf_psc_alpha_adapt_thresh_OU.nestml @@ -1,64 +1,63 @@ -""" -iaf_psc_alpha_adapt_thresh_OU - Leaky integrate-and-fire neuron model -##################################################################### - -Description -+++++++++++ - -This model augments iaf_psc_alpha with an adaptive threshold and additive -Ornstein-Uhlenbeck noise. - -iaf_psc_alpha is an implementation of a leaky integrate-and-fire model -with alpha-function kernel synaptic currents. Thus, synaptic currents -and the resulting post-synaptic potentials have a finite rise time. - -The threshold crossing is followed by an absolute refractory period -during which the membrane potential is clamped to the resting potential. - -The general framework for the consistent formulation of systems with -neuron like dynamics interacting by point events is described in -[1]_. A flow chart can be found in [2]_. - -Critical tests for the formulation of the neuron model are the -comparisons of simulation results for different computation step -sizes. - -The iaf_psc_alpha is the standard model used to check the consistency -of the nest simulation kernel because it is at the same time complex -enough to exhibit non-trivial dynamics and simple enough compute -relevant measures analytically. - -.. note:: - If tau_m is very close to tau_syn_exc or tau_syn_inh, numerical problems - may arise due to singularities in the propagator matrics. If this is - the case, replace equal-valued parameters by a single parameter. - - For details, please see ``IAF_neurons_singularity.ipynb`` in - the NEST source code (``docs/model_details``). - - -References -++++++++++ - -.. [1] Rotter S, Diesmann M (1999). Exact simulation of - time-invariant linear systems with applications to neuronal - modeling. Biologial Cybernetics 81:381-402. - DOI: https://doi.org/10.1007/s004220050570 -.. [2] Diesmann M, Gewaltig M-O, Rotter S, & Aertsen A (2001). State - space analysis of synchronous spiking in cortical neural - networks. Neurocomputing 38-40:565-571. - DOI: https://doi.org/10.1016/S0925-2312(01)00409-X -.. [3] Morrison A, Straube S, Plesser H E, Diesmann M (2006). Exact - subthreshold integration with continuous spike times in discrete time - neural network simulations. Neural Computation, in press - DOI: https://doi.org/10.1162/neco.2007.19.1.47 - - -See also -++++++++ - -iaf_psc_delta, iaf_psc_exp, iaf_cond_alpha -""" +# iaf_psc_alpha_adapt_thresh_OU - Leaky integrate-and-fire neuron model +# ##################################################################### +# +# Description +# +++++++++++ +# +# This model augments iaf_psc_alpha with an adaptive threshold and additive +# Ornstein-Uhlenbeck noise. +# +# iaf_psc_alpha is an implementation of a leaky integrate-and-fire model +# with alpha-function kernel synaptic currents. Thus, synaptic currents +# and the resulting post-synaptic potentials have a finite rise time. +# +# The threshold crossing is followed by an absolute refractory period +# during which the membrane potential is clamped to the resting potential. +# +# The general framework for the consistent formulation of systems with +# neuron like dynamics interacting by point events is described in +# [1]_. A flow chart can be found in [2]_. +# +# Critical tests for the formulation of the neuron model are the +# comparisons of simulation results for different computation step +# sizes. +# +# The iaf_psc_alpha is the standard model used to check the consistency +# of the nest simulation kernel because it is at the same time complex +# enough to exhibit non-trivial dynamics and simple enough compute +# relevant measures analytically. +# +# .. note:: +# If tau_m is very close to tau_syn_exc or tau_syn_inh, numerical problems +# may arise due to singularities in the propagator matrics. If this is +# the case, replace equal-valued parameters by a single parameter. +# +# For details, please see ``IAF_neurons_singularity.ipynb`` in +# the NEST source code (``docs/model_details``). +# +# +# References +# ++++++++++ +# +# .. [1] Rotter S, Diesmann M (1999). Exact simulation of +# time-invariant linear systems with applications to neuronal +# modeling. Biologial Cybernetics 81:381-402. +# DOI: https://doi.org/10.1007/s004220050570 +# .. [2] Diesmann M, Gewaltig M-O, Rotter S, & Aertsen A (2001). State +# space analysis of synchronous spiking in cortical neural +# networks. Neurocomputing 38-40:565-571. +# DOI: https://doi.org/10.1016/S0925-2312(01)00409-X +# .. [3] Morrison A, Straube S, Plesser H E, Diesmann M (2006). Exact +# subthreshold integration with continuous spike times in discrete time +# neural network simulations. Neural Computation, in press +# DOI: https://doi.org/10.1162/neco.2007.19.1.47 +# +# +# See also +# ++++++++ +# +# iaf_psc_delta, iaf_psc_exp, iaf_cond_alpha +# model iaf_psc_alpha_adapt_thresh_OU_neuron: state: diff --git a/extras/syntax-highlighting/visual-code/nestml/language-configuration.json b/extras/syntax-highlighting/visual-code/nestml/language-configuration.json index 5c292a088..20d5aa10d 100644 --- a/extras/syntax-highlighting/visual-code/nestml/language-configuration.json +++ b/extras/syntax-highlighting/visual-code/nestml/language-configuration.json @@ -1,7 +1,6 @@ { "comments": { - "lineComment": "#", - "blockComment": [ "\"\"\"", "\"\"\"" ] + "lineComment": "#" }, "brackets": [ ["{", "}"], @@ -12,8 +11,7 @@ { "open": "{", "close": "}" }, { "open": "[", "close": "]" }, { "open": "(", "close": ")" }, - { "open": "\"", "close": "\"", "notIn": ["string"] }, - { "open": "\"\"\"", "close": " \"\"\"", "notIn": ["string"] } + { "open": "\"", "close": "\"", "notIn": ["string"] } ], "surroundingPairs": [ ["{", "}"], diff --git a/models/neurons/aeif_cond_alpha_neuron.nestml b/models/neurons/aeif_cond_alpha_neuron.nestml index bb3fdbdf7..0ac6a6de4 100644 --- a/models/neurons/aeif_cond_alpha_neuron.nestml +++ b/models/neurons/aeif_cond_alpha_neuron.nestml @@ -1,51 +1,51 @@ -""" -aeif_cond_alpha - Conductance based exponential integrate-and-fire neuron model -############################################################################### - -Description -+++++++++++ - -aeif_cond_alpha is the adaptive exponential integrate and fire neuron according to Brette and Gerstner (2005), with post-synaptic conductances in the form of a bi-exponential ("alpha") function. - -The membrane potential is given by the following differential equation: - -.. math:: - - C_m \frac{dV_m}{dt} = - -g_L(V_m-E_L)+g_L\Delta_T\exp\left(\frac{V_m-V_{th}}{\Delta_T}\right) - - g_e(t)(V_m-E_e) \\ - -g_i(t)(V_m-E_i)-w + I_e - -and - -.. math:: - - \tau_w \frac{dw}{dt} = a(V_m-E_L) - w - -Note that the membrane potential can diverge to positive infinity due to the exponential term. To avoid numerical instabilities, instead of :math:`V_m`, the value :math:`\min(V_m,V_{peak})` is used in the dynamical equations. - -.. note:: - - The default refractory period for ``aeif`` models is zero, consistent with the model definition in - Brette & Gerstner [1]_. Thus, an ``aeif`` neuron with default parameters can fire multiple spikes in a single - time step, which can lead to exploding spike numbers and extreme slow-down of simulations. - To avoid such unphysiological behavior, you should set a refractory time ``refr_t > 0``. - - -References -++++++++++ - -.. [1] Brette R and Gerstner W (2005). Adaptive exponential - integrate-and-fire model as an effective description of neuronal - activity. Journal of Neurophysiology. 943637-3642 - DOI: https://doi.org/10.1152/jn.00686.2005 - - -See also -++++++++ - -iaf_cond_alpha, aeif_cond_exp -""" +# aeif_cond_alpha - Conductance based exponential integrate-and-fire neuron model +# ############################################################################### +# +# Description +# +++++++++++ +# +# aeif_cond_alpha is the adaptive exponential integrate and fire neuron according to Brette and Gerstner (2005), with post-synaptic conductances in the form of a bi-exponential ("alpha") function. +# +# The membrane potential is given by the following differential equation: +# +# .. math:: +# +# C_m \frac{dV_m}{dt} = +# -g_L(V_m-E_L)+g_L\Delta_T\exp\left(\frac{V_m-V_{th}}{\Delta_T}\right) - +# g_e(t)(V_m-E_e) \\ +# -g_i(t)(V_m-E_i)-w + I_e +# +# and +# +# .. math:: +# +# \tau_w \frac{dw}{dt} = a(V_m-E_L) - w +# +# Note that the membrane potential can diverge to positive infinity due to the exponential term. To avoid numerical instabilities, instead of :math:`V_m`, the value :math:`\min(V_m,V_{peak})` is used in the dynamical equations. +# +# .. note:: +# +# The default refractory period for ``aeif`` models is zero, consistent with the model definition in +# Brette & Gerstner [1]_. Thus, an ``aeif`` neuron with default parameters can fire multiple spikes in a single +# time step, which can lead to exploding spike numbers and extreme slow-down of simulations. +# To avoid such unphysiological behavior, you should set a refractory time ``refr_t > 0``. +# +# +# References +# ++++++++++ +# +# .. [1] Brette R and Gerstner W (2005). Adaptive exponential +# integrate-and-fire model as an effective description of neuronal +# activity. Journal of Neurophysiology. 943637-3642 +# DOI: https://doi.org/10.1152/jn.00686.2005 +# +# +# See also +# ++++++++ +# +# iaf_cond_alpha, aeif_cond_exp +# +# model aeif_cond_alpha_neuron: state: diff --git a/models/neurons/aeif_cond_exp_neuron.nestml b/models/neurons/aeif_cond_exp_neuron.nestml index bab6e4e0a..bfc6d0f5c 100644 --- a/models/neurons/aeif_cond_exp_neuron.nestml +++ b/models/neurons/aeif_cond_exp_neuron.nestml @@ -1,52 +1,52 @@ -""" -aeif_cond_exp - Conductance based exponential integrate-and-fire neuron model -############################################################################# - -Description -+++++++++++ - -aeif_cond_exp is the adaptive exponential integrate and fire neuron -according to Brette and Gerstner (2005), with post-synaptic -conductances in the form of truncated exponentials. - -The membrane potential is given by the following differential equation: - -.. math:: - - C_m \frac{dV_m}{dt} = - -g_L(V_m-E_L)+g_L\Delta_T\exp\left(\frac{V_m-V_{th}}{\Delta_T}\right) - g_e(t)(V_m-E_e) \\ - -g_i(t)(V_m-E_i)-w +I_e - -and - -.. math:: - - \tau_w \frac{dw}{dt} = a(V_m-E_L) - w - -Note that the membrane potential can diverge to positive infinity due to the exponential term. To avoid numerical instabilities, instead of :math:`V_m`, the value :math:`\min(V_m,V_{peak})` is used in the dynamical equations. - -.. note:: - - The default refractory period for ``aeif`` models is zero, consistent with the model definition in - Brette & Gerstner [1]_. Thus, an ``aeif`` neuron with default parameters can fire multiple spikes in a single - time step, which can lead to exploding spike numbers and extreme slow-down of simulations. - To avoid such unphysiological behavior, you should set a refractory time ``refr_t > 0``. - - -References -++++++++++ - -.. [1] Brette R and Gerstner W (2005). Adaptive exponential - integrate-and-fire model as an effective description of neuronal - activity. Journal of Neurophysiology. 943637-3642 - DOI: https://doi.org/10.1152/jn.00686.2005 - - -See also -++++++++ - -iaf_cond_exp, aeif_cond_alpha -""" +# aeif_cond_exp - Conductance based exponential integrate-and-fire neuron model +# ############################################################################# +# +# Description +# +++++++++++ +# +# aeif_cond_exp is the adaptive exponential integrate and fire neuron +# according to Brette and Gerstner (2005), with post-synaptic +# conductances in the form of truncated exponentials. +# +# The membrane potential is given by the following differential equation: +# +# .. math:: +# +# C_m \frac{dV_m}{dt} = +# -g_L(V_m-E_L)+g_L\Delta_T\exp\left(\frac{V_m-V_{th}}{\Delta_T}\right) - g_e(t)(V_m-E_e) \\ +# -g_i(t)(V_m-E_i)-w +I_e +# +# and +# +# .. math:: +# +# \tau_w \frac{dw}{dt} = a(V_m-E_L) - w +# +# Note that the membrane potential can diverge to positive infinity due to the exponential term. To avoid numerical instabilities, instead of :math:`V_m`, the value :math:`\min(V_m,V_{peak})` is used in the dynamical equations. +# +# .. note:: +# +# The default refractory period for ``aeif`` models is zero, consistent with the model definition in +# Brette & Gerstner [1]_. Thus, an ``aeif`` neuron with default parameters can fire multiple spikes in a single +# time step, which can lead to exploding spike numbers and extreme slow-down of simulations. +# To avoid such unphysiological behavior, you should set a refractory time ``refr_t > 0``. +# +# +# References +# ++++++++++ +# +# .. [1] Brette R and Gerstner W (2005). Adaptive exponential +# integrate-and-fire model as an effective description of neuronal +# activity. Journal of Neurophysiology. 943637-3642 +# DOI: https://doi.org/10.1152/jn.00686.2005 +# +# +# See also +# ++++++++ +# +# iaf_cond_exp, aeif_cond_alpha +# +# model aeif_cond_exp_neuron: state: diff --git a/models/neurons/hh_cond_exp_destexhe_neuron.nestml b/models/neurons/hh_cond_exp_destexhe_neuron.nestml index c2bfced5a..c77024be0 100644 --- a/models/neurons/hh_cond_exp_destexhe_neuron.nestml +++ b/models/neurons/hh_cond_exp_destexhe_neuron.nestml @@ -1,35 +1,35 @@ -""" -hh_cond_exp_destexhe - Hodgin Huxley based model, Traub, Destexhe and Mainen modified -##################################################################################### - -Description -+++++++++++ - -hh_cond_exp_destexhe is an implementation of a modified Hodkin-Huxley model, which is based on the hh_cond_exp_traub model. - -Differences to hh_cond_exp_traub: - -(1) **Additional background noise:** A background current whose conductances were modeled as an Ornstein-Uhlenbeck process is injected into the neuron. -(2) **Additional non-inactivating K+ current:** A non-inactivating K+ current was included, which is responsible for spike frequency adaptation. - - -References -++++++++++ - -.. [1] Traub, R.D. and Miles, R. (1991) Neuronal Networks of the Hippocampus. Cambridge University Press, Cambridge UK. - -.. [2] Destexhe, A. and Pare, D. (1999) Impact of Network Activity on the Integrative Properties of Neocortical Pyramidal Neurons In Vivo. Journal of Neurophysiology - -.. [3] A. Destexhe, M. Rudolph, J.-M. Fellous and T. J. Sejnowski (2001) Fluctuating synaptic conductances recreate in vivo-like activity in neocortical neurons. Neuroscience - -.. [4] Z. Mainen, J. Joerges, J. R. Huguenard and T. J. Sejnowski (1995) A Model of Spike Initiation in Neocortical Pyramidal Neurons. Neuron - - -See also -++++++++ - -hh_cond_exp_traub -""" +# hh_cond_exp_destexhe - Hodgin Huxley based model, Traub, Destexhe and Mainen modified +# ##################################################################################### +# +# Description +# +++++++++++ +# +# hh_cond_exp_destexhe is an implementation of a modified Hodkin-Huxley model, which is based on the hh_cond_exp_traub model. +# +# Differences to hh_cond_exp_traub: +# +# (1) **Additional background noise:** A background current whose conductances were modeled as an Ornstein-Uhlenbeck process is injected into the neuron. +# (2) **Additional non-inactivating K+ current:** A non-inactivating K+ current was included, which is responsible for spike frequency adaptation. +# +# +# References +# ++++++++++ +# +# .. [1] Traub, R.D. and Miles, R. (1991) Neuronal Networks of the Hippocampus. Cambridge University Press, Cambridge UK. +# +# .. [2] Destexhe, A. and Pare, D. (1999) Impact of Network Activity on the Integrative Properties of Neocortical Pyramidal Neurons In Vivo. Journal of Neurophysiology +# +# .. [3] A. Destexhe, M. Rudolph, J.-M. Fellous and T. J. Sejnowski (2001) Fluctuating synaptic conductances recreate in vivo-like activity in neocortical neurons. Neuroscience +# +# .. [4] Z. Mainen, J. Joerges, J. R. Huguenard and T. J. Sejnowski (1995) A Model of Spike Initiation in Neocortical Pyramidal Neurons. Neuron +# +# +# See also +# ++++++++ +# +# hh_cond_exp_traub +# +# model hh_cond_exp_destexhe_neuron: state: diff --git a/models/neurons/hh_cond_exp_traub_neuron.nestml b/models/neurons/hh_cond_exp_traub_neuron.nestml index 7d9c7ab33..1e20e85d4 100644 --- a/models/neurons/hh_cond_exp_traub_neuron.nestml +++ b/models/neurons/hh_cond_exp_traub_neuron.nestml @@ -1,52 +1,52 @@ -""" -hh_cond_exp_traub - Hodgkin-Huxley model for Brette et al (2007) review -####################################################################### - -Description -+++++++++++ - -hh_cond_exp_traub is an implementation of a modified Hodgkin-Huxley model. - -This model was specifically developed for a major review of simulators [1]_, -based on a model of hippocampal pyramidal cells by Traub and Miles [2]_. -The key differences between the current model and the model in [2]_ are: - -- This model is a point neuron, not a compartmental model. -- This model includes only I_Na and I_K, with simpler I_K dynamics than - in [2]_, so it has only three instead of eight gating variables; - in particular, all Ca dynamics have been removed. -- Incoming spikes induce an instantaneous conductance change followed by - exponential decay instead of activation over time. - -This model is primarily provided as reference implementation for hh_coba -example of the Brette et al (2007) review. Default parameter values are chosen -to match those used with NEST 1.9.10 when preparing data for [1]_. Code for all -simulators covered is available from ModelDB [3]_. - -Note: In this model, a spike is emitted if :math:`V_m >= V_T + 30` mV and -:math:`V_m` has fallen during the current time step. - -To avoid that this leads to multiple spikes during the falling flank of a -spike, it is essential to choose a sufficiently long refractory period. -Traub and Miles used :math:`t_{ref} = 3` ms [2, p 118], while we used -:math:`t_{ref} = 2` ms in [2]_. - -References -++++++++++ - -.. [1] Brette R et al. (2007). Simulation of networks of spiking neurons: A - review of tools and strategies. Journal of Computational Neuroscience - 23:349-98. DOI: https://doi.org/10.1007/s10827-007-0038-6 -.. [2] Traub RD and Miles R (1991). Neuronal networks of the hippocampus. - Cambridge University Press, Cambridge UK. -.. [3] http://modeldb.yale.edu/83319 - - -See also -++++++++ - -hh_psc_alpha -""" +# hh_cond_exp_traub - Hodgkin-Huxley model for Brette et al (2007) review +# ####################################################################### +# +# Description +# +++++++++++ +# +# hh_cond_exp_traub is an implementation of a modified Hodgkin-Huxley model. +# +# This model was specifically developed for a major review of simulators [1]_, +# based on a model of hippocampal pyramidal cells by Traub and Miles [2]_. +# The key differences between the current model and the model in [2]_ are: +# +# - This model is a point neuron, not a compartmental model. +# - This model includes only I_Na and I_K, with simpler I_K dynamics than +# in [2]_, so it has only three instead of eight gating variables; +# in particular, all Ca dynamics have been removed. +# - Incoming spikes induce an instantaneous conductance change followed by +# exponential decay instead of activation over time. +# +# This model is primarily provided as reference implementation for hh_coba +# example of the Brette et al (2007) review. Default parameter values are chosen +# to match those used with NEST 1.9.10 when preparing data for [1]_. Code for all +# simulators covered is available from ModelDB [3]_. +# +# Note: In this model, a spike is emitted if :math:`V_m >= V_T + 30` mV and +# :math:`V_m` has fallen during the current time step. +# +# To avoid that this leads to multiple spikes during the falling flank of a +# spike, it is essential to choose a sufficiently long refractory period. +# Traub and Miles used :math:`t_{ref} = 3` ms [2, p 118], while we used +# :math:`t_{ref} = 2` ms in [2]_. +# +# References +# ++++++++++ +# +# .. [1] Brette R et al. (2007). Simulation of networks of spiking neurons: A +# review of tools and strategies. Journal of Computational Neuroscience +# 23:349-98. DOI: https://doi.org/10.1007/s10827-007-0038-6 +# .. [2] Traub RD and Miles R (1991). Neuronal networks of the hippocampus. +# Cambridge University Press, Cambridge UK. +# .. [3] http://modeldb.yale.edu/83319 +# +# +# See also +# ++++++++ +# +# hh_psc_alpha +# +# model hh_cond_exp_traub_neuron: state: diff --git a/models/neurons/hh_moto_5ht_neuron.nestml b/models/neurons/hh_moto_5ht_neuron.nestml index 5fa861a1f..67d603acf 100644 --- a/models/neurons/hh_moto_5ht_neuron.nestml +++ b/models/neurons/hh_moto_5ht_neuron.nestml @@ -1,35 +1,35 @@ -""" -hh_moto_5ht_nestml - a motor neuron model in HH formalism with 5HT modulation -############################################################################# - -Description -+++++++++++ - -hh_moto_5ht is an implementation of a spiking motor neuron using the Hodgkin-Huxley formalism according to [2]_. Basically this model is an implementation of the existing NEURON model [1]_. - -The parameter that represents 5HT modulation is ``g_K_Ca_5ht``. When it equals 1, no modulation happens. An application of 5HT corresponds to its decrease. The default value for it is 0.6. This value was used in the Neuron simulator model. The range of this parameter is (0, 1] but you are free to play with any value. - -Post-synaptic currents and spike detection are the same as in hh_psc_alpha. - - -References -++++++++++ - -.. [1] Muscle spindle feedback circuit by Moraud EM and Capogrosso M. - https://senselab.med.yale.edu/ModelDB/showmodel.cshtml?model=189786 - -.. [2] Compartmental model of vertebrate motoneurons for Ca2+-dependent spiking and plateau potentials under pharmacological treatment. - Booth V, Rinzel J, Kiehn O. - http://refhub.elsevier.com/S0896-6273(16)00010-6/sref4 - -.. [3] Repository: https://github.com/research-team/hh-moto-5ht - - -See also -++++++++ - -hh_psc_alpha -""" +# hh_moto_5ht_nestml - a motor neuron model in HH formalism with 5HT modulation +# ############################################################################# +# +# Description +# +++++++++++ +# +# hh_moto_5ht is an implementation of a spiking motor neuron using the Hodgkin-Huxley formalism according to [2]_. Basically this model is an implementation of the existing NEURON model [1]_. +# +# The parameter that represents 5HT modulation is ``g_K_Ca_5ht``. When it equals 1, no modulation happens. An application of 5HT corresponds to its decrease. The default value for it is 0.6. This value was used in the Neuron simulator model. The range of this parameter is (0, 1] but you are free to play with any value. +# +# Post-synaptic currents and spike detection are the same as in hh_psc_alpha. +# +# +# References +# ++++++++++ +# +# .. [1] Muscle spindle feedback circuit by Moraud EM and Capogrosso M. +# https://senselab.med.yale.edu/ModelDB/showmodel.cshtml?model=189786 +# +# .. [2] Compartmental model of vertebrate motoneurons for Ca2+-dependent spiking and plateau potentials under pharmacological treatment. +# Booth V, Rinzel J, Kiehn O. +# http://refhub.elsevier.com/S0896-6273(16)00010-6/sref4 +# +# .. [3] Repository: https://github.com/research-team/hh-moto-5ht +# +# +# See also +# ++++++++ +# +# hh_psc_alpha +# +# model hh_moto_5ht_neuron: state: V_m mV = V_m_init # Membrane potential diff --git a/models/neurons/hh_psc_alpha_neuron.nestml b/models/neurons/hh_psc_alpha_neuron.nestml index 7b53cbf71..2055057c1 100644 --- a/models/neurons/hh_psc_alpha_neuron.nestml +++ b/models/neurons/hh_psc_alpha_neuron.nestml @@ -1,48 +1,48 @@ -""" -hh_psc_alpha - Hodgkin-Huxley neuron model -########################################## - -Description -+++++++++++ - -hh_psc_alpha is an implementation of a spiking neuron using the Hodgkin-Huxley -formalism. - -Incoming spike events induce a post-synaptic change of current modelled -by an alpha function. The alpha function is normalised such that an event of -weight 1.0 results in a peak current of 1 pA. - -Spike detection is done by a combined threshold-and-local-maximum search: if -there is a local maximum above a certain threshold of the membrane potential, -it is considered a spike. - - -Problems/Todo -+++++++++++++ - -- better spike detection -- initial wavelet/spike at simulation onset - - -References -++++++++++ - -.. [1] Gerstner W, Kistler W (2002). Spiking neuron models: Single neurons, - populations, plasticity. New York: Cambridge University Press -.. [2] Dayan P, Abbott LF (2001). Theoretical neuroscience: Computational and - mathematical modeling of neural systems. Cambridge, MA: MIT Press. - https://pure.mpg.de/pubman/faces/ViewItemOverviewPage.jsp?itemId=item_3006127> -.. [3] Hodgkin AL and Huxley A F (1952). A quantitative description of - membrane current and its application to conduction and excitation in - nerve. The Journal of Physiology 117. - DOI: https://doi.org/10.1113/jphysiol.1952.sp004764 - - -See also -++++++++ - -hh_cond_exp_traub -""" +# hh_psc_alpha - Hodgkin-Huxley neuron model +# ########################################## +# +# Description +# +++++++++++ +# +# hh_psc_alpha is an implementation of a spiking neuron using the Hodgkin-Huxley +# formalism. +# +# Incoming spike events induce a post-synaptic change of current modelled +# by an alpha function. The alpha function is normalised such that an event of +# weight 1.0 results in a peak current of 1 pA. +# +# Spike detection is done by a combined threshold-and-local-maximum search: if +# there is a local maximum above a certain threshold of the membrane potential, +# it is considered a spike. +# +# +# Problems/Todo +# +++++++++++++ +# +# - better spike detection +# - initial wavelet/spike at simulation onset +# +# +# References +# ++++++++++ +# +# .. [1] Gerstner W, Kistler W (2002). Spiking neuron models: Single neurons, +# populations, plasticity. New York: Cambridge University Press +# .. [2] Dayan P, Abbott LF (2001). Theoretical neuroscience: Computational and +# mathematical modeling of neural systems. Cambridge, MA: MIT Press. +# https://pure.mpg.de/pubman/faces/ViewItemOverviewPage.jsp?itemId=item_3006127> +# .. [3] Hodgkin AL and Huxley A F (1952). A quantitative description of +# membrane current and its application to conduction and excitation in +# nerve. The Journal of Physiology 117. +# DOI: https://doi.org/10.1113/jphysiol.1952.sp004764 +# +# +# See also +# ++++++++ +# +# hh_cond_exp_traub +# +# model hh_psc_alpha_neuron: state: V_m mV = V_m_init # Membrane potential diff --git a/models/neurons/hill_tononi_neuron.nestml b/models/neurons/hill_tononi_neuron.nestml index 6d7b0f22a..5ded64b06 100644 --- a/models/neurons/hill_tononi_neuron.nestml +++ b/models/neurons/hill_tononi_neuron.nestml @@ -1,39 +1,39 @@ -""" -hill_tononi - Neuron model after Hill & Tononi (2005) -##################################################### - -Description -+++++++++++ - -This model neuron implements a slightly modified version of the -neuron model described in [1]_. The most important properties are: - -- Integrate-and-fire with threshold adaptive threshold. -- Repolarizing potassium current instead of hard reset. -- AMPA, NMDA, GABA_A, and GABA_B conductance-based synapses with - beta-function (difference of exponentials) time course. -- Voltage-dependent NMDA with instantaneous or two-stage unblocking [1]_, [2]_. -- Intrinsic currents I_h, I_T, I_Na(p), and I_KNa. -- Synaptic "minis" are not implemented. - -Documentation and examples can be found on the NEST Simulator repository -(https://github.com/nest/nest-simulator/) at the following paths: -- docs/model_details/HillTononiModels.ipynb -- pynest/examples/intrinsic_currents_spiking.py -- pynest/examples/intrinsic_currents_subthreshold.py - - -References -++++++++++ - -.. [1] Hill S, Tononi G (2005). Modeling sleep and wakefulness in the - thalamocortical system. Journal of Neurophysiology. 93:1671-1698. - DOI: https://doi.org/10.1152/jn.00915.2004 -.. [2] Vargas-Caballero M, Robinson HPC (2003). A slow fraction of Mg2+ - unblock of NMDA receptors limits their contribution to spike generation - in cortical pyramidal neurons. Journal of Neurophysiology 89:2778-2783. - DOI: https://doi.org/10.1152/jn.01038.2002 -""" +# hill_tononi - Neuron model after Hill & Tononi (2005) +# ##################################################### +# +# Description +# +++++++++++ +# +# This model neuron implements a slightly modified version of the +# neuron model described in [1]_. The most important properties are: +# +# - Integrate-and-fire with threshold adaptive threshold. +# - Repolarizing potassium current instead of hard reset. +# - AMPA, NMDA, GABA_A, and GABA_B conductance-based synapses with +# beta-function (difference of exponentials) time course. +# - Voltage-dependent NMDA with instantaneous or two-stage unblocking [1]_, [2]_. +# - Intrinsic currents I_h, I_T, I_Na(p), and I_KNa. +# - Synaptic "minis" are not implemented. +# +# Documentation and examples can be found on the NEST Simulator repository +# (https://github.com/nest/nest-simulator/) at the following paths: +# - docs/model_details/HillTononiModels.ipynb +# - pynest/examples/intrinsic_currents_spiking.py +# - pynest/examples/intrinsic_currents_subthreshold.py +# +# +# References +# ++++++++++ +# +# .. [1] Hill S, Tononi G (2005). Modeling sleep and wakefulness in the +# thalamocortical system. Journal of Neurophysiology. 93:1671-1698. +# DOI: https://doi.org/10.1152/jn.00915.2004 +# .. [2] Vargas-Caballero M, Robinson HPC (2003). A slow fraction of Mg2+ +# unblock of NMDA receptors limits their contribution to spike generation +# in cortical pyramidal neurons. Journal of Neurophysiology 89:2778-2783. +# DOI: https://doi.org/10.1152/jn.01038.2002 +# +# model hill_tononi_neuron: state: potassium_refr_t ms = 0 ms diff --git a/models/neurons/iaf_chxk_2008_neuron.nestml b/models/neurons/iaf_chxk_2008_neuron.nestml index ea8bc6eb4..71219c5b1 100644 --- a/models/neurons/iaf_chxk_2008_neuron.nestml +++ b/models/neurons/iaf_chxk_2008_neuron.nestml @@ -1,38 +1,38 @@ -""" -iaf_chxk_2008 - Conductance based leaky integrate-and-fire neuron model used in Casti et al. 2008 -################################################################################################# - -Description -+++++++++++ - -iaf_chxk_2008 is an implementation of a spiking neuron using IAF dynamics with -conductance-based synapses [1]_. A spike is emitted when the membrane potential -is crossed from below. After a spike, an afterhyperpolarizing (AHP) conductance -is activated which repolarizes the neuron over time. Membrane potential is not -reset explicitly and the model also has no explicit refractory time. - -The AHP conductance and excitatory and inhibitory synaptic input conductances -follow alpha-function time courses as in the iaf_cond_alpha model. - -.. note :: - In the original Fortran implementation underlying [1]_, all previous AHP activation was discarded when a new spike - occurred, leading to reduced AHP currents in particular during periods of high spiking activity. Set ``ahp_bug`` to - ``true`` to obtain this behavior in the model. - - -References -++++++++++ - -.. [1] Casti A, Hayot F, Xiao Y, Kaplan E (2008) A simple model of retina-LGN - transmission. Journal of Computational Neuroscience 24:235-252. - DOI: https://doi.org/10.1007/s10827-007-0053-7 - - -See also -++++++++ - -iaf_cond_alpha -""" +# iaf_chxk_2008 - Conductance based leaky integrate-and-fire neuron model used in Casti et al. 2008 +# ################################################################################################# +# +# Description +# +++++++++++ +# +# iaf_chxk_2008 is an implementation of a spiking neuron using IAF dynamics with +# conductance-based synapses [1]_. A spike is emitted when the membrane potential +# is crossed from below. After a spike, an afterhyperpolarizing (AHP) conductance +# is activated which repolarizes the neuron over time. Membrane potential is not +# reset explicitly and the model also has no explicit refractory time. +# +# The AHP conductance and excitatory and inhibitory synaptic input conductances +# follow alpha-function time courses as in the iaf_cond_alpha model. +# +# .. note :: +# In the original Fortran implementation underlying [1]_, all previous AHP activation was discarded when a new spike +# occurred, leading to reduced AHP currents in particular during periods of high spiking activity. Set ``ahp_bug`` to +# ``true`` to obtain this behavior in the model. +# +# +# References +# ++++++++++ +# +# .. [1] Casti A, Hayot F, Xiao Y, Kaplan E (2008) A simple model of retina-LGN +# transmission. Journal of Computational Neuroscience 24:235-252. +# DOI: https://doi.org/10.1007/s10827-007-0053-7 +# +# +# See also +# ++++++++ +# +# iaf_cond_alpha +# +# model iaf_chxk_2008_neuron: state: diff --git a/models/neurons/iaf_cond_alpha_neuron.nestml b/models/neurons/iaf_cond_alpha_neuron.nestml index a7b4ac265..c89521b67 100644 --- a/models/neurons/iaf_cond_alpha_neuron.nestml +++ b/models/neurons/iaf_cond_alpha_neuron.nestml @@ -1,40 +1,40 @@ -""" -iaf_cond_alpha - Simple conductance based leaky integrate-and-fire neuron model -############################################################################### - -Description -+++++++++++ - -iaf_cond_alpha is an implementation of a spiking neuron using IAF dynamics with -conductance-based synapses. Incoming spike events induce a post-synaptic change -of conductance modelled by an alpha function. The alpha function -is normalised such that an event of weight 1.0 results in a peak current of 1 nS -at :math:`t = \tau_{syn}`. - - -References -++++++++++ - -.. [1] Meffin H, Burkitt AN, Grayden DB (2004). An analytical - model for the large, fluctuating synaptic conductance state typical of - neocortical neurons in vivo. Journal of Computational Neuroscience, - 16:159-175. - DOI: https://doi.org/10.1023/B:JCNS.0000014108.03012.81 -.. [2] Bernander O, Douglas RJ, Martin KAC, Koch C (1991). Synaptic background - activity influences spatiotemporal integration in single pyramidal - cells. Proceedings of the National Academy of Science USA, - 88(24):11569-11573. - DOI: https://doi.org/10.1073/pnas.88.24.11569 -.. [3] Kuhn A, Rotter S (2004) Neuronal integration of synaptic input in - the fluctuation- driven regime. Journal of Neuroscience, - 24(10):2345-2356 - DOI: https://doi.org/10.1523/JNEUROSCI.3349-03.2004 - -See also -++++++++ - -iaf_cond_exp -""" +# iaf_cond_alpha - Simple conductance based leaky integrate-and-fire neuron model +# ############################################################################### +# +# Description +# +++++++++++ +# +# iaf_cond_alpha is an implementation of a spiking neuron using IAF dynamics with +# conductance-based synapses. Incoming spike events induce a post-synaptic change +# of conductance modelled by an alpha function. The alpha function +# is normalised such that an event of weight 1.0 results in a peak current of 1 nS +# at :math:`t = \tau_{syn}`. +# +# +# References +# ++++++++++ +# +# .. [1] Meffin H, Burkitt AN, Grayden DB (2004). An analytical +# model for the large, fluctuating synaptic conductance state typical of +# neocortical neurons in vivo. Journal of Computational Neuroscience, +# 16:159-175. +# DOI: https://doi.org/10.1023/B:JCNS.0000014108.03012.81 +# .. [2] Bernander O, Douglas RJ, Martin KAC, Koch C (1991). Synaptic background +# activity influences spatiotemporal integration in single pyramidal +# cells. Proceedings of the National Academy of Science USA, +# 88(24):11569-11573. +# DOI: https://doi.org/10.1073/pnas.88.24.11569 +# .. [3] Kuhn A, Rotter S (2004) Neuronal integration of synaptic input in +# the fluctuation- driven regime. Journal of Neuroscience, +# 24(10):2345-2356 +# DOI: https://doi.org/10.1523/JNEUROSCI.3349-03.2004 +# +# See also +# ++++++++ +# +# iaf_cond_exp +# +# model iaf_cond_alpha_neuron: state: V_m mV = E_L # Membrane potential diff --git a/models/neurons/iaf_cond_beta_neuron.nestml b/models/neurons/iaf_cond_beta_neuron.nestml index 6b6d8abf0..2ee482a21 100644 --- a/models/neurons/iaf_cond_beta_neuron.nestml +++ b/models/neurons/iaf_cond_beta_neuron.nestml @@ -1,48 +1,48 @@ -""" -iaf_cond_beta - Simple conductance based leaky integrate-and-fire neuron model -############################################################################## - -Description -+++++++++++ - -iaf_cond_beta is an implementation of a spiking neuron using IAF dynamics with -conductance-based synapses. Incoming spike events induce a post-synaptic change -of conductance modelled by a beta function. The beta function -is normalised such that an event of weight 1.0 results in a peak current of -1 nS at :math:`t = \tau_{rise\_[ex|in]}`. - - -References -++++++++++ - -.. [1] Meffin H, Burkitt AN, Grayden DB (2004). An analytical - model for the large, fluctuating synaptic conductance state typical of - neocortical neurons in vivo. Journal of Computational Neuroscience, - 16:159-175. - DOI: https://doi.org/10.1023/B:JCNS.0000014108.03012.81 -.. [2] Bernander O, Douglas RJ, Martin KAC, Koch C (1991). Synaptic background - activity influences spatiotemporal integration in single pyramidal - cells. Proceedings of the National Academy of Science USA, - 88(24):11569-11573. - DOI: https://doi.org/10.1073/pnas.88.24.11569 -.. [3] Kuhn A, Rotter S (2004) Neuronal integration of synaptic input in - the fluctuation- driven regime. Journal of Neuroscience, - 24(10):2345-2356 - DOI: https://doi.org/10.1523/JNEUROSCI.3349-03.2004 -.. [4] Rotter S, Diesmann M (1999). Exact simulation of time-invariant linear - systems with applications to neuronal modeling. Biologial Cybernetics - 81:381-402. - DOI: https://doi.org/10.1007/s004220050570 -.. [5] Roth A and van Rossum M (2010). Chapter 6: Modeling synapses. - in De Schutter, Computational Modeling Methods for Neuroscientists, - MIT Press. - - -See also -++++++++ - -iaf_cond_exp, iaf_cond_alpha -""" +# iaf_cond_beta - Simple conductance based leaky integrate-and-fire neuron model +# ############################################################################## +# +# Description +# +++++++++++ +# +# iaf_cond_beta is an implementation of a spiking neuron using IAF dynamics with +# conductance-based synapses. Incoming spike events induce a post-synaptic change +# of conductance modelled by a beta function. The beta function +# is normalised such that an event of weight 1.0 results in a peak current of +# 1 nS at :math:`t = \tau_{rise\_[ex|in]}`. +# +# +# References +# ++++++++++ +# +# .. [1] Meffin H, Burkitt AN, Grayden DB (2004). An analytical +# model for the large, fluctuating synaptic conductance state typical of +# neocortical neurons in vivo. Journal of Computational Neuroscience, +# 16:159-175. +# DOI: https://doi.org/10.1023/B:JCNS.0000014108.03012.81 +# .. [2] Bernander O, Douglas RJ, Martin KAC, Koch C (1991). Synaptic background +# activity influences spatiotemporal integration in single pyramidal +# cells. Proceedings of the National Academy of Science USA, +# 88(24):11569-11573. +# DOI: https://doi.org/10.1073/pnas.88.24.11569 +# .. [3] Kuhn A, Rotter S (2004) Neuronal integration of synaptic input in +# the fluctuation- driven regime. Journal of Neuroscience, +# 24(10):2345-2356 +# DOI: https://doi.org/10.1523/JNEUROSCI.3349-03.2004 +# .. [4] Rotter S, Diesmann M (1999). Exact simulation of time-invariant linear +# systems with applications to neuronal modeling. Biologial Cybernetics +# 81:381-402. +# DOI: https://doi.org/10.1007/s004220050570 +# .. [5] Roth A and van Rossum M (2010). Chapter 6: Modeling synapses. +# in De Schutter, Computational Modeling Methods for Neuroscientists, +# MIT Press. +# +# +# See also +# ++++++++ +# +# iaf_cond_exp, iaf_cond_alpha +# +# model iaf_cond_beta_neuron: state: V_m mV = E_L # Membrane potential diff --git a/models/neurons/iaf_cond_exp_neuron.nestml b/models/neurons/iaf_cond_exp_neuron.nestml index 86616b1ea..7315f546d 100644 --- a/models/neurons/iaf_cond_exp_neuron.nestml +++ b/models/neurons/iaf_cond_exp_neuron.nestml @@ -1,30 +1,30 @@ -""" -iaf_cond_exp - Simple conductance based leaky integrate-and-fire neuron model -############################################################################# - -Description -+++++++++++ - -iaf_cond_exp is an implementation of a spiking neuron using IAF dynamics with -conductance-based synapses. Incoming spike events induce a post-synaptic change -of conductance modelled by an exponential function. The exponential function -is normalised such that an event of weight 1.0 results in a peak conductance of -1 nS. - -References -++++++++++ - -.. [1] Meffin H, Burkitt AN, Grayden DB (2004). An analytical - model for the large, fluctuating synaptic conductance state typical of - neocortical neurons in vivo. Journal of Computational Neuroscience, - 16:159-175. - DOI: https://doi.org/10.1023/B:JCNS.0000014108.03012.81 - -See also -++++++++ - -iaf_psc_delta, iaf_psc_exp, iaf_cond_exp -""" +# iaf_cond_exp - Simple conductance based leaky integrate-and-fire neuron model +# ############################################################################# +# +# Description +# +++++++++++ +# +# iaf_cond_exp is an implementation of a spiking neuron using IAF dynamics with +# conductance-based synapses. Incoming spike events induce a post-synaptic change +# of conductance modelled by an exponential function. The exponential function +# is normalised such that an event of weight 1.0 results in a peak conductance of +# 1 nS. +# +# References +# ++++++++++ +# +# .. [1] Meffin H, Burkitt AN, Grayden DB (2004). An analytical +# model for the large, fluctuating synaptic conductance state typical of +# neocortical neurons in vivo. Journal of Computational Neuroscience, +# 16:159-175. +# DOI: https://doi.org/10.1023/B:JCNS.0000014108.03012.81 +# +# See also +# ++++++++ +# +# iaf_psc_delta, iaf_psc_exp, iaf_cond_exp +# +# model iaf_cond_exp_neuron: state: diff --git a/models/neurons/iaf_cond_exp_sfa_rr_neuron.nestml b/models/neurons/iaf_cond_exp_sfa_rr_neuron.nestml index c360f17e6..50dfdcd55 100644 --- a/models/neurons/iaf_cond_exp_sfa_rr_neuron.nestml +++ b/models/neurons/iaf_cond_exp_sfa_rr_neuron.nestml @@ -1,38 +1,38 @@ -""" -iaf_cond_exp_sfa_rr - Conductance based leaky integrate-and-fire model with spike-frequency adaptation and relative refractory mechanisms -######################################################################################################################################### - -Description -+++++++++++ - -iaf_cond_exp_sfa_rr is an implementation of a spiking neuron using integrate-and-fire dynamics with conductance-based -synapses, with additional spike-frequency adaptation and relative refractory mechanisms as described in [2]_, page 166. - -Incoming spike events induce a post-synaptic change of conductance modelled by an exponential function. The exponential -function is normalised such that an event of weight 1.0 results in a peak current of 1 nS. - -Outgoing spike events induce a change of the adaptation and relative refractory conductances by q_sfa and q_rr, -respectively. Otherwise these conductances decay exponentially with time constants tau_sfa and tau_rr, respectively. - - -References -++++++++++ - -.. [1] Meffin H, Burkitt AN, Grayden DB (2004). An analytical - model for the large, fluctuating synaptic conductance state typical of - neocortical neurons in vivo. Journal of Computational Neuroscience, - 16:159-175. - DOI: https://doi.org/10.1023/B:JCNS.0000014108.03012.81 -.. [2] Dayan P, Abbott LF (2001). Theoretical neuroscience: Computational and - mathematical modeling of neural systems. Cambridge, MA: MIT Press. - https://pure.mpg.de/pubman/faces/ViewItemOverviewPage.jsp?itemId=item_3006127 - - -See also -++++++++ - -aeif_cond_alpha, aeif_cond_exp, iaf_chxk_2008 -""" +# iaf_cond_exp_sfa_rr - Conductance based leaky integrate-and-fire model with spike-frequency adaptation and relative refractory mechanisms +# ######################################################################################################################################### +# +# Description +# +++++++++++ +# +# iaf_cond_exp_sfa_rr is an implementation of a spiking neuron using integrate-and-fire dynamics with conductance-based +# synapses, with additional spike-frequency adaptation and relative refractory mechanisms as described in [2]_, page 166. +# +# Incoming spike events induce a post-synaptic change of conductance modelled by an exponential function. The exponential +# function is normalised such that an event of weight 1.0 results in a peak current of 1 nS. +# +# Outgoing spike events induce a change of the adaptation and relative refractory conductances by q_sfa and q_rr, +# respectively. Otherwise these conductances decay exponentially with time constants tau_sfa and tau_rr, respectively. +# +# +# References +# ++++++++++ +# +# .. [1] Meffin H, Burkitt AN, Grayden DB (2004). An analytical +# model for the large, fluctuating synaptic conductance state typical of +# neocortical neurons in vivo. Journal of Computational Neuroscience, +# 16:159-175. +# DOI: https://doi.org/10.1023/B:JCNS.0000014108.03012.81 +# .. [2] Dayan P, Abbott LF (2001). Theoretical neuroscience: Computational and +# mathematical modeling of neural systems. Cambridge, MA: MIT Press. +# https://pure.mpg.de/pubman/faces/ViewItemOverviewPage.jsp?itemId=item_3006127 +# +# +# See also +# ++++++++ +# +# aeif_cond_alpha, aeif_cond_exp, iaf_chxk_2008 +# +# model iaf_cond_exp_sfa_rr_neuron: state: diff --git a/models/neurons/iaf_psc_alpha_neuron.nestml b/models/neurons/iaf_psc_alpha_neuron.nestml index ef68e438c..9e8c1e91c 100644 --- a/models/neurons/iaf_psc_alpha_neuron.nestml +++ b/models/neurons/iaf_psc_alpha_neuron.nestml @@ -1,61 +1,61 @@ -""" -iaf_psc_alpha - Leaky integrate-and-fire neuron model -##################################################### - -Description -+++++++++++ - -iaf_psc_alpha is an implementation of a leaky integrate-and-fire model -with alpha-function kernel synaptic currents. Thus, synaptic currents -and the resulting post-synaptic potentials have a finite rise time. - -The threshold crossing is followed by an absolute refractory period -during which the membrane potential is clamped to the resting potential. - -The general framework for the consistent formulation of systems with -neuron like dynamics interacting by point events is described in -[1]_. A flow chart can be found in [2]_. - -Critical tests for the formulation of the neuron model are the -comparisons of simulation results for different computation step -sizes. - -The iaf_psc_alpha is the standard model used to check the consistency -of the nest simulation kernel because it is at the same time complex -enough to exhibit non-trivial dynamics and simple enough compute -relevant measures analytically. - -.. note:: - If tau_m is very close to tau_syn_exc or tau_syn_inh, numerical problems - may arise due to singularities in the propagator matrics. If this is - the case, replace equal-valued parameters by a single parameter. - - For details, please see ``IAF_neurons_singularity.ipynb`` in - the NEST source code (``docs/model_details``). - - -References -++++++++++ - -.. [1] Rotter S, Diesmann M (1999). Exact simulation of - time-invariant linear systems with applications to neuronal - modeling. Biologial Cybernetics 81:381-402. - DOI: https://doi.org/10.1007/s004220050570 -.. [2] Diesmann M, Gewaltig M-O, Rotter S, & Aertsen A (2001). State - space analysis of synchronous spiking in cortical neural - networks. Neurocomputing 38-40:565-571. - DOI: https://doi.org/10.1016/S0925-2312(01)00409-X -.. [3] Morrison A, Straube S, Plesser H E, Diesmann M (2006). Exact - subthreshold integration with continuous spike times in discrete time - neural network simulations. Neural Computation, in press - DOI: https://doi.org/10.1162/neco.2007.19.1.47 - - -See also -++++++++ - -iaf_psc_delta, iaf_psc_exp, iaf_cond_alpha -""" +# iaf_psc_alpha - Leaky integrate-and-fire neuron model +# ##################################################### +# +# Description +# +++++++++++ +# +# iaf_psc_alpha is an implementation of a leaky integrate-and-fire model +# with alpha-function kernel synaptic currents. Thus, synaptic currents +# and the resulting post-synaptic potentials have a finite rise time. +# +# The threshold crossing is followed by an absolute refractory period +# during which the membrane potential is clamped to the resting potential. +# +# The general framework for the consistent formulation of systems with +# neuron like dynamics interacting by point events is described in +# [1]_. A flow chart can be found in [2]_. +# +# Critical tests for the formulation of the neuron model are the +# comparisons of simulation results for different computation step +# sizes. +# +# The iaf_psc_alpha is the standard model used to check the consistency +# of the nest simulation kernel because it is at the same time complex +# enough to exhibit non-trivial dynamics and simple enough compute +# relevant measures analytically. +# +# .. note:: +# If tau_m is very close to tau_syn_exc or tau_syn_inh, numerical problems +# may arise due to singularities in the propagator matrics. If this is +# the case, replace equal-valued parameters by a single parameter. +# +# For details, please see ``IAF_neurons_singularity.ipynb`` in +# the NEST source code (``docs/model_details``). +# +# +# References +# ++++++++++ +# +# .. [1] Rotter S, Diesmann M (1999). Exact simulation of +# time-invariant linear systems with applications to neuronal +# modeling. Biologial Cybernetics 81:381-402. +# DOI: https://doi.org/10.1007/s004220050570 +# .. [2] Diesmann M, Gewaltig M-O, Rotter S, & Aertsen A (2001). State +# space analysis of synchronous spiking in cortical neural +# networks. Neurocomputing 38-40:565-571. +# DOI: https://doi.org/10.1016/S0925-2312(01)00409-X +# .. [3] Morrison A, Straube S, Plesser H E, Diesmann M (2006). Exact +# subthreshold integration with continuous spike times in discrete time +# neural network simulations. Neural Computation, in press +# DOI: https://doi.org/10.1162/neco.2007.19.1.47 +# +# +# See also +# ++++++++ +# +# iaf_psc_delta, iaf_psc_exp, iaf_cond_alpha +# +# model iaf_psc_alpha_neuron: state: diff --git a/models/neurons/iaf_psc_delta_fixed_timestep_neuron.nestml b/models/neurons/iaf_psc_delta_fixed_timestep_neuron.nestml index 75a53489a..623e0dc6b 100644 --- a/models/neurons/iaf_psc_delta_fixed_timestep_neuron.nestml +++ b/models/neurons/iaf_psc_delta_fixed_timestep_neuron.nestml @@ -1,35 +1,35 @@ -""" -iaf_psc_delta_fixed_timestep - Current-based leaky integrate-and-fire neuron model with delta-kernel post-synaptic currents -########################################################################################################################### - -Description -+++++++++++ - -An implementation of a leaky integrate-and-fire model where the potential jumps on each spike arrival. The threshold crossing is followed by an absolute refractory period during which the membrane potential is clamped to the resting potential. Spikes arriving while the neuron is refractory are discarded. - -The general framework for the consistent formulation of systems with neuron-like dynamics interacting by point events is described in [1]_. A flow chart can be found in [2]_. - -This model differs from ``iaf_psc_delta`` in that it assumes a fixed-timestep simulator, so the functions ``resolution()`` and ``steps()`` can be used. - - -References -++++++++++ - -.. [1] Rotter S, Diesmann M (1999). Exact simulation of - time-invariant linear systems with applications to neuronal - modeling. Biologial Cybernetics 81:381-402. - DOI: https://doi.org/10.1007/s004220050570 -.. [2] Diesmann M, Gewaltig M-O, Rotter S, & Aertsen A (2001). State - space analysis of synchronous spiking in cortical neural - networks. Neurocomputing 38-40:565-571. - DOI: https://doi.org/10.1016/S0925-2312(01)00409-X - - -See also -++++++++ - -iaf_psc_alpha, iaf_psc_exp -""" +# iaf_psc_delta_fixed_timestep - Current-based leaky integrate-and-fire neuron model with delta-kernel post-synaptic currents +# ########################################################################################################################### +# +# Description +# +++++++++++ +# +# An implementation of a leaky integrate-and-fire model where the potential jumps on each spike arrival. The threshold crossing is followed by an absolute refractory period during which the membrane potential is clamped to the resting potential. Spikes arriving while the neuron is refractory are discarded. +# +# The general framework for the consistent formulation of systems with neuron-like dynamics interacting by point events is described in [1]_. A flow chart can be found in [2]_. +# +# This model differs from ``iaf_psc_delta`` in that it assumes a fixed-timestep simulator, so the functions ``resolution()`` and ``steps()`` can be used. +# +# +# References +# ++++++++++ +# +# .. [1] Rotter S, Diesmann M (1999). Exact simulation of +# time-invariant linear systems with applications to neuronal +# modeling. Biologial Cybernetics 81:381-402. +# DOI: https://doi.org/10.1007/s004220050570 +# .. [2] Diesmann M, Gewaltig M-O, Rotter S, & Aertsen A (2001). State +# space analysis of synchronous spiking in cortical neural +# networks. Neurocomputing 38-40:565-571. +# DOI: https://doi.org/10.1016/S0925-2312(01)00409-X +# +# +# See also +# ++++++++ +# +# iaf_psc_alpha, iaf_psc_exp +# +# model iaf_psc_delta_fixed_timestep_neuron: state: V_m mV = E_L # Membrane potential diff --git a/models/neurons/iaf_psc_delta_neuron.nestml b/models/neurons/iaf_psc_delta_neuron.nestml index 0c5012fea..a02ceb7ef 100644 --- a/models/neurons/iaf_psc_delta_neuron.nestml +++ b/models/neurons/iaf_psc_delta_neuron.nestml @@ -1,45 +1,45 @@ -""" -iaf_psc_delta - Current-based leaky integrate-and-fire neuron model with delta-kernel post-synaptic currents -############################################################################################################ - -Description -+++++++++++ - -iaf_psc_delta is an implementation of a leaky integrate-and-fire model -where the potential jumps on each spike arrival. - -The threshold crossing is followed by an absolute refractory period -during which the membrane potential is clamped to the resting potential. - -Spikes arriving while the neuron is refractory, are discarded by -default. If the property ``with_refr_input`` is set to true, such -spikes are added to the membrane potential at the end of the -refractory period, dampened according to the interval between -arrival and end of refractoriness. - -The general framework for the consistent formulation of systems with -neuron like dynamics interacting by point events is described in -[1]_. A flow chart can be found in [2]_. - - -References -++++++++++ - -.. [1] Rotter S, Diesmann M (1999). Exact simulation of - time-invariant linear systems with applications to neuronal - modeling. Biologial Cybernetics 81:381-402. - DOI: https://doi.org/10.1007/s004220050570 -.. [2] Diesmann M, Gewaltig M-O, Rotter S, & Aertsen A (2001). State - space analysis of synchronous spiking in cortical neural - networks. Neurocomputing 38-40:565-571. - DOI: https://doi.org/10.1016/S0925-2312(01)00409-X - - -See also -++++++++ - -iaf_psc_alpha, iaf_psc_exp -""" +# iaf_psc_delta - Current-based leaky integrate-and-fire neuron model with delta-kernel post-synaptic currents +# ############################################################################################################ +# +# Description +# +++++++++++ +# +# iaf_psc_delta is an implementation of a leaky integrate-and-fire model +# where the potential jumps on each spike arrival. +# +# The threshold crossing is followed by an absolute refractory period +# during which the membrane potential is clamped to the resting potential. +# +# Spikes arriving while the neuron is refractory, are discarded by +# default. If the property ``with_refr_input`` is set to true, such +# spikes are added to the membrane potential at the end of the +# refractory period, dampened according to the interval between +# arrival and end of refractoriness. +# +# The general framework for the consistent formulation of systems with +# neuron like dynamics interacting by point events is described in +# [1]_. A flow chart can be found in [2]_. +# +# +# References +# ++++++++++ +# +# .. [1] Rotter S, Diesmann M (1999). Exact simulation of +# time-invariant linear systems with applications to neuronal +# modeling. Biologial Cybernetics 81:381-402. +# DOI: https://doi.org/10.1007/s004220050570 +# .. [2] Diesmann M, Gewaltig M-O, Rotter S, & Aertsen A (2001). State +# space analysis of synchronous spiking in cortical neural +# networks. Neurocomputing 38-40:565-571. +# DOI: https://doi.org/10.1016/S0925-2312(01)00409-X +# +# +# See also +# ++++++++ +# +# iaf_psc_alpha, iaf_psc_exp +# +# model iaf_psc_delta_neuron: state: V_m mV = E_L # Membrane potential diff --git a/models/neurons/iaf_psc_exp_htum_neuron.nestml b/models/neurons/iaf_psc_exp_htum_neuron.nestml index c79da9558..3ae4113ae 100644 --- a/models/neurons/iaf_psc_exp_htum_neuron.nestml +++ b/models/neurons/iaf_psc_exp_htum_neuron.nestml @@ -1,55 +1,55 @@ -""" -iaf_psc_exp_htum - Leaky integrate-and-fire model with separate relative and absolute refractory period -####################################################################################################### - -Description -+++++++++++ - -iaf_psc_exp_htum is an implementation of a leaky integrate-and-fire model -with exponential-kernel postsynaptic currents (PSCs) according to [1]_. -The postsynaptic currents have an infinitely short rise time. -In particular, this model allows setting an absolute and relative -refractory time separately, as required by [1]_. - -The threshold crossing is followed by an absolute refractory period -(t_ref_abs) during which the membrane potential is clamped to the resting -potential. During the total refractory period (t_ref_tot), the membrane -potential evolves, but the neuron will not emit a spike, even if the -membrane potential reaches threshold. The total refractory time must be -larger or equal to the absolute refractory time. If equal, the -refractoriness of the model if equivalent to the other models of NEST. - -.. note:: - This neuron model can only be used in combination with a fixed - simulation resolution (timestep size). - -.. note:: - If tau_m is very close to tau_syn_exc or tau_syn_inh, numerical problems - may arise due to singularities in the propagator matrics. If this is - the case, replace equal-valued parameters by a single parameter. - - For details, please see ``IAF_neurons_singularity.ipynb`` in - the NEST source code (``docs/model_details``). - - -References -++++++++++ - -.. [1] Tsodyks M, Uziel A, Markram H (2000). Synchrony generation in recurrent - networks with frequency-dependent synapses. The Journal of Neuroscience, - 20,RC50:1-5. URL: https://infoscience.epfl.ch/record/183402 -.. [2] Hill, A. V. (1936). Excitation and accommodation in nerve. Proceedings of - the Royal Society of London. Series B-Biological Sciences, 119(814), 305-355. - DOI: https://doi.org/10.1098/rspb.1936.0012 -.. [3] Rotter S, Diesmann M (1999). Exact simulation of - time-invariant linear systems with applications to neuronal - modeling. Biologial Cybernetics 81:381-402. - DOI: https://doi.org/10.1007/s004220050570 -.. [4] Diesmann M, Gewaltig M-O, Rotter S, & Aertsen A (2001). State - space analysis of synchronous spiking in cortical neural - networks. Neurocomputing 38-40:565-571. - DOI: https://doi.org/10.1016/S0925-2312(01)00409-X -""" +# iaf_psc_exp_htum - Leaky integrate-and-fire model with separate relative and absolute refractory period +# ####################################################################################################### +# +# Description +# +++++++++++ +# +# iaf_psc_exp_htum is an implementation of a leaky integrate-and-fire model +# with exponential-kernel postsynaptic currents (PSCs) according to [1]_. +# The postsynaptic currents have an infinitely short rise time. +# In particular, this model allows setting an absolute and relative +# refractory time separately, as required by [1]_. +# +# The threshold crossing is followed by an absolute refractory period +# (t_ref_abs) during which the membrane potential is clamped to the resting +# potential. During the total refractory period (t_ref_tot), the membrane +# potential evolves, but the neuron will not emit a spike, even if the +# membrane potential reaches threshold. The total refractory time must be +# larger or equal to the absolute refractory time. If equal, the +# refractoriness of the model if equivalent to the other models of NEST. +# +# .. note:: +# This neuron model can only be used in combination with a fixed +# simulation resolution (timestep size). +# +# .. note:: +# If tau_m is very close to tau_syn_exc or tau_syn_inh, numerical problems +# may arise due to singularities in the propagator matrics. If this is +# the case, replace equal-valued parameters by a single parameter. +# +# For details, please see ``IAF_neurons_singularity.ipynb`` in +# the NEST source code (``docs/model_details``). +# +# +# References +# ++++++++++ +# +# .. [1] Tsodyks M, Uziel A, Markram H (2000). Synchrony generation in recurrent +# networks with frequency-dependent synapses. The Journal of Neuroscience, +# 20,RC50:1-5. URL: https://infoscience.epfl.ch/record/183402 +# .. [2] Hill, A. V. (1936). Excitation and accommodation in nerve. Proceedings of +# the Royal Society of London. Series B-Biological Sciences, 119(814), 305-355. +# DOI: https://doi.org/10.1098/rspb.1936.0012 +# .. [3] Rotter S, Diesmann M (1999). Exact simulation of +# time-invariant linear systems with applications to neuronal +# modeling. Biologial Cybernetics 81:381-402. +# DOI: https://doi.org/10.1007/s004220050570 +# .. [4] Diesmann M, Gewaltig M-O, Rotter S, & Aertsen A (2001). State +# space analysis of synchronous spiking in cortical neural +# networks. Neurocomputing 38-40:565-571. +# DOI: https://doi.org/10.1016/S0925-2312(01)00409-X +# +# model iaf_psc_exp_htum_neuron: state: r_tot integer = 0 diff --git a/models/neurons/iaf_psc_exp_neuron.nestml b/models/neurons/iaf_psc_exp_neuron.nestml index c153f4fc5..73f6fe1ff 100644 --- a/models/neurons/iaf_psc_exp_neuron.nestml +++ b/models/neurons/iaf_psc_exp_neuron.nestml @@ -1,57 +1,57 @@ -""" -iaf_psc_exp - Leaky integrate-and-fire neuron model -################################################### - -Description -+++++++++++ - -iaf_psc_exp is an implementation of a leaky integrate-and-fire model -with exponentially decaying synaptic currents according to [1]_. -Thus, postsynaptic currents have an infinitely short rise time. - -The threshold crossing is followed by an absolute refractory period -during which the membrane potential is clamped to the resting potential -and spiking is prohibited. - -The general framework for the consistent formulation of systems with -neuron like dynamics interacting by point events is described in -[1]_. A flow chart can be found in [2]_. - -Critical tests for the formulation of the neuron model are the -comparisons of simulation results for different computation step -sizes. - -.. note:: - If tau_m is very close to tau_syn_exc or tau_syn_inh, numerical problems - may arise due to singularities in the propagator matrics. If this is - the case, replace equal-valued parameters by a single parameter. - - For details, please see ``IAF_neurons_singularity.ipynb`` in - the NEST source code (``docs/model_details``). - - -References -++++++++++ - -.. [1] Rotter S, Diesmann M (1999). Exact simulation of - time-invariant linear systems with applications to neuronal - modeling. Biologial Cybernetics 81:381-402. - DOI: https://doi.org/10.1007/s004220050570 -.. [2] Diesmann M, Gewaltig M-O, Rotter S, & Aertsen A (2001). State - space analysis of synchronous spiking in cortical neural - networks. Neurocomputing 38-40:565-571. - DOI: https://doi.org/10.1016/S0925-2312(01)00409-X -.. [3] Morrison A, Straube S, Plesser H E, Diesmann M (2006). Exact - subthreshold integration with continuous spike times in discrete time - neural network simulations. Neural Computation, in press - DOI: https://doi.org/10.1162/neco.2007.19.1.47 - - -See also -++++++++ - -iaf_psc_delta, iaf_psc_alpha, iaf_cond_exp -""" +# iaf_psc_exp - Leaky integrate-and-fire neuron model +# ################################################### +# +# Description +# +++++++++++ +# +# iaf_psc_exp is an implementation of a leaky integrate-and-fire model +# with exponentially decaying synaptic currents according to [1]_. +# Thus, postsynaptic currents have an infinitely short rise time. +# +# The threshold crossing is followed by an absolute refractory period +# during which the membrane potential is clamped to the resting potential +# and spiking is prohibited. +# +# The general framework for the consistent formulation of systems with +# neuron like dynamics interacting by point events is described in +# [1]_. A flow chart can be found in [2]_. +# +# Critical tests for the formulation of the neuron model are the +# comparisons of simulation results for different computation step +# sizes. +# +# .. note:: +# If tau_m is very close to tau_syn_exc or tau_syn_inh, numerical problems +# may arise due to singularities in the propagator matrics. If this is +# the case, replace equal-valued parameters by a single parameter. +# +# For details, please see ``IAF_neurons_singularity.ipynb`` in +# the NEST source code (``docs/model_details``). +# +# +# References +# ++++++++++ +# +# .. [1] Rotter S, Diesmann M (1999). Exact simulation of +# time-invariant linear systems with applications to neuronal +# modeling. Biologial Cybernetics 81:381-402. +# DOI: https://doi.org/10.1007/s004220050570 +# .. [2] Diesmann M, Gewaltig M-O, Rotter S, & Aertsen A (2001). State +# space analysis of synchronous spiking in cortical neural +# networks. Neurocomputing 38-40:565-571. +# DOI: https://doi.org/10.1016/S0925-2312(01)00409-X +# .. [3] Morrison A, Straube S, Plesser H E, Diesmann M (2006). Exact +# subthreshold integration with continuous spike times in discrete time +# neural network simulations. Neural Computation, in press +# DOI: https://doi.org/10.1162/neco.2007.19.1.47 +# +# +# See also +# ++++++++ +# +# iaf_psc_delta, iaf_psc_alpha, iaf_cond_exp +# +# model iaf_psc_exp_neuron: state: diff --git a/models/neurons/ignore_and_fire_neuron.nestml b/models/neurons/ignore_and_fire_neuron.nestml index cde1df36d..8359396bc 100644 --- a/models/neurons/ignore_and_fire_neuron.nestml +++ b/models/neurons/ignore_and_fire_neuron.nestml @@ -1,27 +1,27 @@ -""" -ignore_and_fire - Neuron generating spikes at fixed intervals irrespective of inputs -###################################################################################### - -Description -+++++++++++ - -The ``ignore_and_fire`` neuron is a neuron model generating spikes at a predefined ``firing_rate`` with a constant inter-spike interval ("fire"), irrespective of its inputs ("ignore"). In this simplest version of the ``ignore_and_fire`` neuron, the inputs from other neurons or devices are not processed at all (*). The ``ignore_and_fire`` neuron is primarily used for neuronal-network model verification and validation purposes, in particular, to evaluate the correctness and performance of connectivity generation and inter-neuron communication. It permits an easy scaling of the network size and/or connectivity without affecting the output spike statistics. The amount of network traffic is predefined by the user, and therefore fully controllable and predictable, irrespective of the network size and structure. - -To create asynchronous activity for a population of ``ignore_and_fire`` neurons, the firing ``phase``s can be randomly initialised. Note that the firing ``phase`` is a real number, defined as the time to the next spike relative to the firing period. - -(*) The model can easily be extended and equipped with any arbitrary input processing (such as calculating input currents with alpha-function shaped PSC kernels or updating the gating variables in the Hodgkin-Huxley model) or (after-) spike generation dynamics to make it more similar and comparable to other non-ignorant neuron models. In such extended ignore_and_fire models, the spike emission process would still be decoupled from the intrinsic neuron dynamics. - -.. note:: - This neuron model can only be used in combination with a fixed - simulation resolution (timestep size). - -Authors -+++++++ - -Tetzlaff (February 2021; January 2022) - -""" - +# ignore_and_fire - Neuron generating spikes at fixed intervals irrespective of inputs +# ###################################################################################### +# +# Description +# +++++++++++ +# +# The ``ignore_and_fire`` neuron is a neuron model generating spikes at a predefined ``firing_rate`` with a constant inter-spike interval ("fire"), irrespective of its inputs ("ignore"). In this simplest version of the ``ignore_and_fire`` neuron, the inputs from other neurons or devices are not processed at all (*). The ``ignore_and_fire`` neuron is primarily used for neuronal-network model verification and validation purposes, in particular, to evaluate the correctness and performance of connectivity generation and inter-neuron communication. It permits an easy scaling of the network size and/or connectivity without affecting the output spike statistics. The amount of network traffic is predefined by the user, and therefore fully controllable and predictable, irrespective of the network size and structure. +# +# To create asynchronous activity for a population of ``ignore_and_fire`` neurons, the firing ``phase``s can be randomly initialised. Note that the firing ``phase`` is a real number, defined as the time to the next spike relative to the firing period. +# +# (*) The model can easily be extended and equipped with any arbitrary input processing (such as calculating input currents with alpha-function shaped PSC kernels or updating the gating variables in the Hodgkin-Huxley model) or (after-) spike generation dynamics to make it more similar and comparable to other non-ignorant neuron models. In such extended ignore_and_fire models, the spike emission process would still be decoupled from the intrinsic neuron dynamics. +# +# .. note:: +# This neuron model can only be used in combination with a fixed +# simulation resolution (timestep size). +# +# Authors +# +++++++ +# +# Tetzlaff (February 2021; January 2022) +# + +# +# model ignore_and_fire_neuron: state: diff --git a/models/neurons/izhikevich_neuron.nestml b/models/neurons/izhikevich_neuron.nestml index 1b43e8155..3ffbf9a84 100644 --- a/models/neurons/izhikevich_neuron.nestml +++ b/models/neurons/izhikevich_neuron.nestml @@ -1,41 +1,41 @@ -""" -izhikevich - Izhikevich neuron model -#################################### - -Description -+++++++++++ - -Implementation of the simple spiking neuron model introduced by Izhikevich [1]_. The dynamics are given by: - -.. math:: - - dV_{m}/dt &= 0.04 V_{m}^2 + 5 V_{m} + 140 - U_{m} + I\\ - dU_{m}/dt &= a (b V_{m} - U_{m}) - - -.. math:: - - &\text{if}\;\; V_{m} \geq V_{th}:\\ - &\;\;\;\; V_{m} \text{ is set to } c\\ - &\;\;\;\; U_{m} \text{ is incremented by } d\\ - & \, \\ - &V_{m} \text{ jumps on each spike arrival by the weight of the spike} - -Incoming spikes cause an instantaneous jump in the membrane potential proportional to the strength of the synapse. - -As published in [1]_, the numerics differs from the standard forward Euler technique in two ways: - -1) the new value of :math:`U_{m}` is calculated based on the new value of :math:`V_{m}`, rather than the previous value -2) the variable :math:`V_{m}` is updated using a time step half the size of that used to update variable :math:`U_{m}`. - -This model will instead be simulated using the numerical solver that is recommended by ODE-toolbox during code generation. - - -References -++++++++++ - -.. [1] Izhikevich, Simple Model of Spiking Neurons, IEEE Transactions on Neural Networks (2003) 14:1569-1572 -""" +# izhikevich - Izhikevich neuron model +# #################################### +# +# Description +# +++++++++++ +# +# Implementation of the simple spiking neuron model introduced by Izhikevich [1]_. The dynamics are given by: +# +# .. math:: +# +# dV_{m}/dt &= 0.04 V_{m}^2 + 5 V_{m} + 140 - U_{m} + I\\ +# dU_{m}/dt &= a (b V_{m} - U_{m}) +# +# +# .. math:: +# +# &\text{if}\;\; V_{m} \geq V_{th}:\\ +# &\;\;\;\; V_{m} \text{ is set to } c\\ +# &\;\;\;\; U_{m} \text{ is incremented by } d\\ +# & \, \\ +# &V_{m} \text{ jumps on each spike arrival by the weight of the spike} +# +# Incoming spikes cause an instantaneous jump in the membrane potential proportional to the strength of the synapse. +# +# As published in [1]_, the numerics differs from the standard forward Euler technique in two ways: +# +# 1) the new value of :math:`U_{m}` is calculated based on the new value of :math:`V_{m}`, rather than the previous value +# 2) the variable :math:`V_{m}` is updated using a time step half the size of that used to update variable :math:`U_{m}`. +# +# This model will instead be simulated using the numerical solver that is recommended by ODE-toolbox during code generation. +# +# +# References +# ++++++++++ +# +# .. [1] Izhikevich, Simple Model of Spiking Neurons, IEEE Transactions on Neural Networks (2003) 14:1569-1572 +# +# model izhikevich_neuron: state: V_m mV = V_m_init # Membrane potential diff --git a/models/neurons/izhikevich_psc_alpha_neuron.nestml b/models/neurons/izhikevich_psc_alpha_neuron.nestml index d372f03c7..0b7923416 100644 --- a/models/neurons/izhikevich_psc_alpha_neuron.nestml +++ b/models/neurons/izhikevich_psc_alpha_neuron.nestml @@ -1,41 +1,41 @@ -""" -izhikevich_psc_alpha - Detailed Izhikevich neuron model with alpha-kernel post-synaptic current -############################################################################################### - -Description -+++++++++++ - -Implementation of the simple spiking neuron model introduced by Izhikevich [1]_, with membrane potential in (milli)volt -and current-based synapses. - -The dynamics are given by: - -.. math:: - - C_m \frac{dV_m}{dt} = k (V - V_t)(V - V_t) - u + I + I_{syn,ex} + I_{syn,in} - \frac{dU_m}{dt} = a(b(V_m - E_L) - U_m) - - &\text{if}\;\;\; V_m \geq V_{th}:\\ - &\;\;\;\; V_m \text{ is set to } c - &\;\;\;\; U_m \text{ is incremented by } d - -On each spike arrival, the membrane potential is subject to an alpha-kernel current of the form: - -.. math:: - - I_syn = I_0 \cdot t \cdot \exp\left(-t/\tau_{syn}\right) / \tau_{syn} - -See also -++++++++ - -izhikevich, iaf_psc_alpha - - -References -++++++++++ - -.. [1] Izhikevich, Simple Model of Spiking Neurons, IEEE Transactions on Neural Networks (2003) 14:1569-1572 -""" +# izhikevich_psc_alpha - Detailed Izhikevich neuron model with alpha-kernel post-synaptic current +# ############################################################################################### +# +# Description +# +++++++++++ +# +# Implementation of the simple spiking neuron model introduced by Izhikevich [1]_, with membrane potential in (milli)volt +# and current-based synapses. +# +# The dynamics are given by: +# +# .. math:: +# +# C_m \frac{dV_m}{dt} = k (V - V_t)(V - V_t) - u + I + I_{syn,ex} + I_{syn,in} +# \frac{dU_m}{dt} = a(b(V_m - E_L) - U_m) +# +# &\text{if}\;\;\; V_m \geq V_{th}:\\ +# &\;\;\;\; V_m \text{ is set to } c +# &\;\;\;\; U_m \text{ is incremented by } d +# +# On each spike arrival, the membrane potential is subject to an alpha-kernel current of the form: +# +# .. math:: +# +# I_syn = I_0 \cdot t \cdot \exp\left(-t/\tau_{syn}\right) / \tau_{syn} +# +# See also +# ++++++++ +# +# izhikevich, iaf_psc_alpha +# +# +# References +# ++++++++++ +# +# .. [1] Izhikevich, Simple Model of Spiking Neurons, IEEE Transactions on Neural Networks (2003) 14:1569-1572 +# +# model izhikevich_psc_alpha_neuron: state: V_m mV = -65 mV # Membrane potential diff --git a/models/neurons/mat2_psc_exp_neuron.nestml b/models/neurons/mat2_psc_exp_neuron.nestml index 11c039d83..f4d71b9f6 100644 --- a/models/neurons/mat2_psc_exp_neuron.nestml +++ b/models/neurons/mat2_psc_exp_neuron.nestml @@ -1,47 +1,47 @@ -""" -mat2_psc_exp - Non-resetting leaky integrate-and-fire neuron model with exponential PSCs and adaptive threshold -############################################################################################################### - -Description -+++++++++++ - -mat2_psc_exp is an implementation of a leaky integrate-and-fire model -with exponential-kernel postsynaptic currents (PSCs). Thus, postsynaptic -currents have an infinitely short rise time. - -The threshold is lifted when the neuron is fired and then decreases in a -fixed time scale toward a fixed level [3]_. - -The threshold crossing is followed by a total refractory period -during which the neuron is not allowed to fire, even if the membrane -potential exceeds the threshold. The membrane potential is NOT reset, -but continuously integrated. - -.. note:: - If tau_m is very close to tau_syn_exc or tau_syn_inh, numerical problems - may arise due to singularities in the propagator matrics. If this is - the case, replace equal-valued parameters by a single parameter. - - For details, please see ``IAF_neurons_singularity.ipynb`` in - the NEST source code (``docs/model_details``). - - -References -++++++++++ - -.. [1] Rotter S and Diesmann M (1999). Exact simulation of - time-invariant linear systems with applications to neuronal - modeling. Biologial Cybernetics 81:381-402. - DOI: https://doi.org/10.1007/s004220050570 -.. [2] Diesmann M, Gewaltig M-O, Rotter S, Aertsen A (2001). State - space analysis of synchronous spiking in cortical neural - networks. Neurocomputing 38-40:565-571. - DOI:https://doi.org/10.1016/S0925-2312(01)00409-X -.. [3] Kobayashi R, Tsubo Y and Shinomoto S (2009). Made-to-order - spiking neuron model equipped with a multi-timescale adaptive - threshold. Frontiers in Computuational Neuroscience 3:9. - DOI: https://doi.org/10.3389/neuro.10.009.2009 -""" +# mat2_psc_exp - Non-resetting leaky integrate-and-fire neuron model with exponential PSCs and adaptive threshold +# ############################################################################################################### +# +# Description +# +++++++++++ +# +# mat2_psc_exp is an implementation of a leaky integrate-and-fire model +# with exponential-kernel postsynaptic currents (PSCs). Thus, postsynaptic +# currents have an infinitely short rise time. +# +# The threshold is lifted when the neuron is fired and then decreases in a +# fixed time scale toward a fixed level [3]_. +# +# The threshold crossing is followed by a total refractory period +# during which the neuron is not allowed to fire, even if the membrane +# potential exceeds the threshold. The membrane potential is NOT reset, +# but continuously integrated. +# +# .. note:: +# If tau_m is very close to tau_syn_exc or tau_syn_inh, numerical problems +# may arise due to singularities in the propagator matrics. If this is +# the case, replace equal-valued parameters by a single parameter. +# +# For details, please see ``IAF_neurons_singularity.ipynb`` in +# the NEST source code (``docs/model_details``). +# +# +# References +# ++++++++++ +# +# .. [1] Rotter S and Diesmann M (1999). Exact simulation of +# time-invariant linear systems with applications to neuronal +# modeling. Biologial Cybernetics 81:381-402. +# DOI: https://doi.org/10.1007/s004220050570 +# .. [2] Diesmann M, Gewaltig M-O, Rotter S, Aertsen A (2001). State +# space analysis of synchronous spiking in cortical neural +# networks. Neurocomputing 38-40:565-571. +# DOI:https://doi.org/10.1016/S0925-2312(01)00409-X +# .. [3] Kobayashi R, Tsubo Y and Shinomoto S (2009). Made-to-order +# spiking neuron model equipped with a multi-timescale adaptive +# threshold. Frontiers in Computuational Neuroscience 3:9. +# DOI: https://doi.org/10.3389/neuro.10.009.2009 +# +# model mat2_psc_exp_neuron: state: V_th_alpha_1 mV = 0 mV # Two-timescale adaptive threshold diff --git a/models/neurons/terub_gpe_neuron.nestml b/models/neurons/terub_gpe_neuron.nestml index 6d138245a..a84be4a20 100644 --- a/models/neurons/terub_gpe_neuron.nestml +++ b/models/neurons/terub_gpe_neuron.nestml @@ -1,34 +1,34 @@ -""" -terub_gpe - Terman Rubin neuron model -##################################### - -Description -+++++++++++ - -terub_gpe is an implementation of a spiking neuron using the Terman Rubin model -based on the Hodgkin-Huxley formalism. - -(1) **Post-syaptic currents:** Incoming spike events induce a post-synaptic change of current modelled - by an alpha function. The alpha function is normalised such that an event of - weight 1.0 results in a peak current of 1 pA. - -(2) **Spike Detection:** Spike detection is done by a combined threshold-and-local-maximum search: if there - is a local maximum above a certain threshold of the membrane potential, it is considered a spike. - - -References -++++++++++ - -.. [1] Terman, D. and Rubin, J.E. and Yew, A. C. and Wilson, C.J. - Activity Patterns in a Model for the Subthalamopallidal Network - of the Basal Ganglia - The Journal of Neuroscience, 22(7), 2963-2976 (2002) - -.. [2] Rubin, J.E. and Terman, D. - High Frequency Stimulation of the Subthalamic Nucleus Eliminates - Pathological Thalamic Rhythmicity in a Computational Model - Journal of Computational Neuroscience, 16, 211-235 (2004) -""" +# terub_gpe - Terman Rubin neuron model +# ##################################### +# +# Description +# +++++++++++ +# +# terub_gpe is an implementation of a spiking neuron using the Terman Rubin model +# based on the Hodgkin-Huxley formalism. +# +# (1) **Post-syaptic currents:** Incoming spike events induce a post-synaptic change of current modelled +# by an alpha function. The alpha function is normalised such that an event of +# weight 1.0 results in a peak current of 1 pA. +# +# (2) **Spike Detection:** Spike detection is done by a combined threshold-and-local-maximum search: if there +# is a local maximum above a certain threshold of the membrane potential, it is considered a spike. +# +# +# References +# ++++++++++ +# +# .. [1] Terman, D. and Rubin, J.E. and Yew, A. C. and Wilson, C.J. +# Activity Patterns in a Model for the Subthalamopallidal Network +# of the Basal Ganglia +# The Journal of Neuroscience, 22(7), 2963-2976 (2002) +# +# .. [2] Rubin, J.E. and Terman, D. +# High Frequency Stimulation of the Subthalamic Nucleus Eliminates +# Pathological Thalamic Rhythmicity in a Computational Model +# Journal of Computational Neuroscience, 16, 211-235 (2004) +# +# model terub_gpe_neuron: state: V_m mV = E_L # Membrane potential diff --git a/models/neurons/terub_stn_neuron.nestml b/models/neurons/terub_stn_neuron.nestml index 495273012..16e662b66 100644 --- a/models/neurons/terub_stn_neuron.nestml +++ b/models/neurons/terub_stn_neuron.nestml @@ -1,30 +1,30 @@ -""" -terub_stn - Terman Rubin neuron model -##################################### - -Description -+++++++++++ - -terub_stn is an implementation of a spiking neuron using the Terman Rubin model -based on the Hodgkin-Huxley formalism. - -(1) **Post-syaptic currents:** Incoming spike events induce a post-synaptic change of current modelled - by an alpha function. The alpha function is normalised such that an event of - weight 1.0 results in a peak current of 1 pA. - -(2) **Spike Detection:** Spike detection is done by a combined threshold-and-local-maximum search: if there - is a local maximum above a certain threshold of the membrane potential, it is considered a spike. - - -References -++++++++++ - -.. [1] Terman, D. and Rubin, J.E. and Yew, A.C. and Wilson, C.J. Activity Patterns in a Model for the Subthalamopallidal Network - of the Basal Ganglia. The Journal of Neuroscience, 22(7), 2963-2976 (2002) - -.. [2] Rubin, J.E. and Terman, D. High Frequency Stimulation of the Subthalamic Nucleus Eliminates - Pathological Thalamic Rhythmicity in a Computational Model Journal of Computational Neuroscience, 16, 211-235 (2004) -""" +# terub_stn - Terman Rubin neuron model +# ##################################### +# +# Description +# +++++++++++ +# +# terub_stn is an implementation of a spiking neuron using the Terman Rubin model +# based on the Hodgkin-Huxley formalism. +# +# (1) **Post-syaptic currents:** Incoming spike events induce a post-synaptic change of current modelled +# by an alpha function. The alpha function is normalised such that an event of +# weight 1.0 results in a peak current of 1 pA. +# +# (2) **Spike Detection:** Spike detection is done by a combined threshold-and-local-maximum search: if there +# is a local maximum above a certain threshold of the membrane potential, it is considered a spike. +# +# +# References +# ++++++++++ +# +# .. [1] Terman, D. and Rubin, J.E. and Yew, A.C. and Wilson, C.J. Activity Patterns in a Model for the Subthalamopallidal Network +# of the Basal Ganglia. The Journal of Neuroscience, 22(7), 2963-2976 (2002) +# +# .. [2] Rubin, J.E. and Terman, D. High Frequency Stimulation of the Subthalamic Nucleus Eliminates +# Pathological Thalamic Rhythmicity in a Computational Model Journal of Computational Neuroscience, 16, 211-235 (2004) +# +# model terub_stn_neuron: state: V_m mV = E_L # Membrane potential diff --git a/models/neurons/traub_cond_multisyn_neuron.nestml b/models/neurons/traub_cond_multisyn_neuron.nestml index 26b122b37..f9d2df650 100644 --- a/models/neurons/traub_cond_multisyn_neuron.nestml +++ b/models/neurons/traub_cond_multisyn_neuron.nestml @@ -1,30 +1,30 @@ -""" -traub_cond_multisyn - Traub model according to Borgers 2017 -########################################################### - -Description -+++++++++++ - -Reduced Traub-Miles Model of a Pyramidal Neuron in Rat Hippocampus [1]_. -parameters got from reference [2]_ chapter 5. - -AMPA, NMDA, GABA_A, and GABA_B conductance-based synapses with -beta-function (difference of two exponentials) time course corresponding -to "hill_tononi" model. - - -References -++++++++++ - -.. [1] R. D. Traub and R. Miles, Neuronal Networks of the Hippocampus,Cam- bridge University Press, Cambridge, UK, 1991. -.. [2] Borgers, C., 2017. An introduction to modeling neuronal dynamics (Vol. 66). Cham: Springer. - - -See also -++++++++ - -hh_cond_exp_traub -""" +# traub_cond_multisyn - Traub model according to Borgers 2017 +# ########################################################### +# +# Description +# +++++++++++ +# +# Reduced Traub-Miles Model of a Pyramidal Neuron in Rat Hippocampus [1]_. +# parameters got from reference [2]_ chapter 5. +# +# AMPA, NMDA, GABA_A, and GABA_B conductance-based synapses with +# beta-function (difference of two exponentials) time course corresponding +# to "hill_tononi" model. +# +# +# References +# ++++++++++ +# +# .. [1] R. D. Traub and R. Miles, Neuronal Networks of the Hippocampus,Cam- bridge University Press, Cambridge, UK, 1991. +# .. [2] Borgers, C., 2017. An introduction to modeling neuronal dynamics (Vol. 66). Cham: Springer. +# +# +# See also +# ++++++++ +# +# hh_cond_exp_traub +# +# model traub_cond_multisyn_neuron: state: V_m mV = -70. mV # Membrane potential diff --git a/models/neurons/traub_psc_alpha_neuron.nestml b/models/neurons/traub_psc_alpha_neuron.nestml index 7803fa6db..c2723c73c 100644 --- a/models/neurons/traub_psc_alpha_neuron.nestml +++ b/models/neurons/traub_psc_alpha_neuron.nestml @@ -1,25 +1,25 @@ -""" -traub_psc_alpha - Traub model according to Borgers 2017 -####################################################### - -Reduced Traub-Miles Model of a Pyramidal Neuron in Rat Hippocampus [1]_. -parameters got from reference [2]_. - -Incoming spike events induce a post-synaptic change of current modelled -by an alpha function. - -References -++++++++++ - -.. [1] R. D. Traub and R. Miles, Neuronal Networks of the Hippocampus,Cam- bridge University Press, Cambridge, UK, 1991. -.. [2] Borgers, C., 2017. An introduction to modeling neuronal dynamics (Vol. 66). Cham: Springer. - - -See also -++++++++ - -hh_cond_exp_traub -""" +# traub_psc_alpha - Traub model according to Borgers 2017 +# ####################################################### +# +# Reduced Traub-Miles Model of a Pyramidal Neuron in Rat Hippocampus [1]_. +# parameters got from reference [2]_. +# +# Incoming spike events induce a post-synaptic change of current modelled +# by an alpha function. +# +# References +# ++++++++++ +# +# .. [1] R. D. Traub and R. Miles, Neuronal Networks of the Hippocampus,Cam- bridge University Press, Cambridge, UK, 1991. +# .. [2] Borgers, C., 2017. An introduction to modeling neuronal dynamics (Vol. 66). Cham: Springer. +# +# +# See also +# ++++++++ +# +# hh_cond_exp_traub +# +# model traub_psc_alpha_neuron: state: V_m mV = V_m_init # Membrane potential diff --git a/models/neurons/wb_cond_exp_neuron.nestml b/models/neurons/wb_cond_exp_neuron.nestml index fe9232947..69507f273 100644 --- a/models/neurons/wb_cond_exp_neuron.nestml +++ b/models/neurons/wb_cond_exp_neuron.nestml @@ -1,31 +1,31 @@ -""" -wb_cond_exp - Wang-Buzsaki model -################################ - -Description -+++++++++++ - -wb_cond_exp is an implementation of a modified Hodkin-Huxley model. - -(1) Post-synaptic currents: Incoming spike events induce a post-synaptic change - of conductance modeled by an exponential function. - -(2) Spike Detection: Spike detection is done by a combined threshold-and-local- - maximum search: if there is a local maximum above a certain threshold of - the membrane potential, it is considered a spike. - -References -++++++++++ - -.. [1] Wang, X.J. and Buzsaki, G., (1996) Gamma oscillation by synaptic - inhibition in a hippocampal interneuronal network model. Journal of - neuroscience, 16(20), pp.6402-6413. - -See Also -++++++++ - -hh_cond_exp_traub, wb_cond_multisyn -""" +# wb_cond_exp - Wang-Buzsaki model +# ################################ +# +# Description +# +++++++++++ +# +# wb_cond_exp is an implementation of a modified Hodkin-Huxley model. +# +# (1) Post-synaptic currents: Incoming spike events induce a post-synaptic change +# of conductance modeled by an exponential function. +# +# (2) Spike Detection: Spike detection is done by a combined threshold-and-local- +# maximum search: if there is a local maximum above a certain threshold of +# the membrane potential, it is considered a spike. +# +# References +# ++++++++++ +# +# .. [1] Wang, X.J. and Buzsaki, G., (1996) Gamma oscillation by synaptic +# inhibition in a hippocampal interneuronal network model. Journal of +# neuroscience, 16(20), pp.6402-6413. +# +# See Also +# ++++++++ +# +# hh_cond_exp_traub, wb_cond_multisyn +# +# model wb_cond_exp_neuron: state: V_m mV = E_L # Membrane potential diff --git a/models/neurons/wb_cond_multisyn_neuron.nestml b/models/neurons/wb_cond_multisyn_neuron.nestml index ff88dcb06..179bde81e 100644 --- a/models/neurons/wb_cond_multisyn_neuron.nestml +++ b/models/neurons/wb_cond_multisyn_neuron.nestml @@ -1,31 +1,31 @@ -""" -wb_cond_multisyn - Wang-Buzsaki model with multiple synapses -############################################################ - -Description -+++++++++++ - -wb_cond_multisyn is an implementation of a modified Hodkin-Huxley model. - -Spike detection is done by a combined threshold-and-local-maximum search: if -there is a local maximum above a certain threshold of the membrane potential, -it is considered a spike. - -AMPA, NMDA, GABA_A, and GABA_B conductance-based synapses with -beta-function (difference of two exponentials) time course. - -References -++++++++++ - -.. [1] Wang, X.J. and Buzsaki, G., (1996) Gamma oscillation by synaptic - inhibition in a hippocampal interneuronal network model. Journal of - Neuroscience, 16(20), pp.6402-6413. - -See also -++++++++ - -wb_cond_multisyn -""" +# wb_cond_multisyn - Wang-Buzsaki model with multiple synapses +# ############################################################ +# +# Description +# +++++++++++ +# +# wb_cond_multisyn is an implementation of a modified Hodkin-Huxley model. +# +# Spike detection is done by a combined threshold-and-local-maximum search: if +# there is a local maximum above a certain threshold of the membrane potential, +# it is considered a spike. +# +# AMPA, NMDA, GABA_A, and GABA_B conductance-based synapses with +# beta-function (difference of two exponentials) time course. +# +# References +# ++++++++++ +# +# .. [1] Wang, X.J. and Buzsaki, G., (1996) Gamma oscillation by synaptic +# inhibition in a hippocampal interneuronal network model. Journal of +# Neuroscience, 16(20), pp.6402-6413. +# +# See also +# ++++++++ +# +# wb_cond_multisyn +# +# model wb_cond_multisyn_neuron: state: V_m mV = -65. mV # Membrane potential diff --git a/models/synapses/neuromodulated_stdp_synapse.nestml b/models/synapses/neuromodulated_stdp_synapse.nestml index 236968417..bfba13c6c 100644 --- a/models/synapses/neuromodulated_stdp_synapse.nestml +++ b/models/synapses/neuromodulated_stdp_synapse.nestml @@ -1,28 +1,28 @@ -""" -neuromodulated_stdp - Synapse model for spike-timing dependent plasticity modulated by a neurotransmitter such as dopamine -########################################################################################################################## - -Description -+++++++++++ - -stdp_dopamine_synapse is a connection to create synapses with -dopamine-modulated spike-timing dependent plasticity (used as a -benchmark model in [1]_, based on [2]_). The dopaminergic signal is a -low-pass filtered version of the spike rate of a user-specific pool -of neurons. The spikes emitted by the pool of dopamine neurons are -delivered to the synapse via the assigned volume transmitter. The -dopaminergic dynamics is calculated in the synapse itself. - -References -++++++++++ -.. [1] Potjans W, Morrison A, Diesmann M (2010). Enabling functional neural - circuit simulations with distributed computing of neuromodulated - plasticity. Frontiers in Computational Neuroscience, 4:141. - DOI: https://doi.org/10.3389/fncom.2010.00141 -.. [2] Izhikevich EM (2007). Solving the distal reward problem through linkage - of STDP and dopamine signaling. Cerebral Cortex, 17(10):2443-2452. - DOI: https://doi.org/10.1093/cercor/bhl152 -""" +# neuromodulated_stdp - Synapse model for spike-timing dependent plasticity modulated by a neurotransmitter such as dopamine +# ########################################################################################################################## +# +# Description +# +++++++++++ +# +# stdp_dopamine_synapse is a connection to create synapses with +# dopamine-modulated spike-timing dependent plasticity (used as a +# benchmark model in [1]_, based on [2]_). The dopaminergic signal is a +# low-pass filtered version of the spike rate of a user-specific pool +# of neurons. The spikes emitted by the pool of dopamine neurons are +# delivered to the synapse via the assigned volume transmitter. The +# dopaminergic dynamics is calculated in the synapse itself. +# +# References +# ++++++++++ +# .. [1] Potjans W, Morrison A, Diesmann M (2010). Enabling functional neural +# circuit simulations with distributed computing of neuromodulated +# plasticity. Frontiers in Computational Neuroscience, 4:141. +# DOI: https://doi.org/10.3389/fncom.2010.00141 +# .. [2] Izhikevich EM (2007). Solving the distal reward problem through linkage +# of STDP and dopamine signaling. Cerebral Cortex, 17(10):2443-2452. +# DOI: https://doi.org/10.1093/cercor/bhl152 +# +# model neuromodulated_stdp_synapse: state: w real = 1. diff --git a/models/synapses/noisy_synapse.nestml b/models/synapses/noisy_synapse.nestml index 3f776fc1d..47c099511 100644 --- a/models/synapses/noisy_synapse.nestml +++ b/models/synapses/noisy_synapse.nestml @@ -1,12 +1,12 @@ -""" -noisy_synapse - Static synapse with Gaussian noise -################################################## - -Description -+++++++++++ - -Each presynaptic spike is passed to the postsynaptic partner with a weight sampled as :math:`w + A_\text{noise} \mathcal{N}(0, 1)`. -""" +# noisy_synapse - Static synapse with Gaussian noise +# ################################################## +# +# Description +# +++++++++++ +# +# Each presynaptic spike is passed to the postsynaptic partner with a weight sampled as :math:`w + A_\text{noise} \mathcal{N}(0, 1)`. +# +# model noisy_synapse: parameters: w real = 1 # Synaptic weight diff --git a/models/synapses/static_synapse.nestml b/models/synapses/static_synapse.nestml index 043a9463f..3474018c2 100644 --- a/models/synapses/static_synapse.nestml +++ b/models/synapses/static_synapse.nestml @@ -1,11 +1,11 @@ -""" -Static synapse -############## - -Description -+++++++++++ -A synapse where the synaptic strength (weight) does not evolve with simulated time, but is defined as a (constant) parameter. -""" +# Static synapse +# ############## +# +# Description +# +++++++++++ +# A synapse where the synaptic strength (weight) does not evolve with simulated time, but is defined as a (constant) parameter. +# +# model static_synapse: parameters: w real = 1 # Synaptic weight diff --git a/models/synapses/stdp_nn_pre_centered_synapse.nestml b/models/synapses/stdp_nn_pre_centered_synapse.nestml index 1d51bb481..91d09228a 100644 --- a/models/synapses/stdp_nn_pre_centered_synapse.nestml +++ b/models/synapses/stdp_nn_pre_centered_synapse.nestml @@ -1,55 +1,55 @@ -""" -stdp_nn_pre_centered - Synapse type for spike-timing dependent plasticity, with nearest-neighbour spike pairing -############################################################################################################### - -Description -+++++++++++ - -stdp_nn_pre_centered_synapse is a connector to create synapses with spike -time dependent plasticity with the presynaptic-centered nearest-neighbour -spike pairing scheme, as described in [1]_. - -Each presynaptic spike is taken into account in the STDP weight change rule -with the nearest preceding postsynaptic one and the nearest succeeding -postsynaptic one (instead of pairing with all spikes, like in stdp_synapse). -So, when a presynaptic spike occurs, it is accounted in the depression rule -with the nearest preceding postsynaptic one; and when a postsynaptic spike -occurs, it is accounted in the facilitation rule with all preceding -presynaptic spikes that were not earlier than the previous postsynaptic -spike. For a clear illustration of this scheme see fig. 7B in [2]_. - -The pairs exactly coinciding (so that presynaptic_spike == postsynaptic_spike -+ dendritic_delay), leading to zero delta_t, are discarded. In this case the -concerned pre/postsynaptic spike is paired with the second latest preceding -post/presynaptic one (for example, pre=={10 ms; 20 ms} and post=={20 ms} will -result in a potentiation pair 20-to-10). - -The implementation involves two additional variables - presynaptic and -postsynaptic traces [2]_. The presynaptic trace decays exponentially over -time with the time constant tau_plus, increases by 1 on a pre-spike -occurrence, and is reset to 0 on a post-spike occurrence. The postsynaptic -trace (implemented on the postsynaptic neuron side) decays with the time -constant tau_minus and increases to 1 on a post-spike occurrence. - -.. figure:: https://raw.githubusercontent.com/nest/nestml/master/doc/fig/stdp-nearest-neighbour.png - - Figure 7 from Morrison, Diesmann and Gerstner - - Original caption: - - Phenomenological models of synaptic plasticity based on spike timing", Biological Cybernetics 98 (2008). "Examples of nearest neighbor spike pairing schemes for a pre-synaptic neuron j and a postsynaptic neuron i. In each case, the dark gray indicate which pairings contribute toward depression of a synapse, and light gray indicate which pairings contribute toward potentiation. **(a)** Symmetric interpretation: each presynaptic spike is paired with the last postsynaptic spike, and each postsynaptic spike is paired with the last presynaptic spike (Morrison et al. 2007). **(b)** Presynaptic centered interpretation: each presynaptic spike is paired with the last postsynaptic spike and the next postsynaptic spike (Izhikevich and Desai 2003; Burkitt et al. 2004: Model II). **(c)** Reduced symmetric interpretation: as in **(b)** but only for immediate pairings (Burkitt et al. 2004: Model IV, also implemented in hardware by Schemmel et al. 2006) - - -References -++++++++++ - -.. [1] Izhikevich E. M., Desai N. S. (2003) Relating STDP to BCM, - Neural Comput. 15, 1511--1523 - -.. [2] Morrison A., Diesmann M., and Gerstner W. (2008) Phenomenological - models of synaptic plasticity based on spike timing, - Biol. Cybern. 98, 459--478 -""" +# stdp_nn_pre_centered - Synapse type for spike-timing dependent plasticity, with nearest-neighbour spike pairing +# ############################################################################################################### +# +# Description +# +++++++++++ +# +# stdp_nn_pre_centered_synapse is a connector to create synapses with spike +# time dependent plasticity with the presynaptic-centered nearest-neighbour +# spike pairing scheme, as described in [1]_. +# +# Each presynaptic spike is taken into account in the STDP weight change rule +# with the nearest preceding postsynaptic one and the nearest succeeding +# postsynaptic one (instead of pairing with all spikes, like in stdp_synapse). +# So, when a presynaptic spike occurs, it is accounted in the depression rule +# with the nearest preceding postsynaptic one; and when a postsynaptic spike +# occurs, it is accounted in the facilitation rule with all preceding +# presynaptic spikes that were not earlier than the previous postsynaptic +# spike. For a clear illustration of this scheme see fig. 7B in [2]_. +# +# The pairs exactly coinciding (so that presynaptic_spike == postsynaptic_spike +# + dendritic_delay), leading to zero delta_t, are discarded. In this case the +# concerned pre/postsynaptic spike is paired with the second latest preceding +# post/presynaptic one (for example, pre=={10 ms; 20 ms} and post=={20 ms} will +# result in a potentiation pair 20-to-10). +# +# The implementation involves two additional variables - presynaptic and +# postsynaptic traces [2]_. The presynaptic trace decays exponentially over +# time with the time constant tau_plus, increases by 1 on a pre-spike +# occurrence, and is reset to 0 on a post-spike occurrence. The postsynaptic +# trace (implemented on the postsynaptic neuron side) decays with the time +# constant tau_minus and increases to 1 on a post-spike occurrence. +# +# .. figure:: https://raw.githubusercontent.com/nest/nestml/master/doc/fig/stdp-nearest-neighbour.png +# +# Figure 7 from Morrison, Diesmann and Gerstner +# +# Original caption: +# +# Phenomenological models of synaptic plasticity based on spike timing", Biological Cybernetics 98 (2008). "Examples of nearest neighbor spike pairing schemes for a pre-synaptic neuron j and a postsynaptic neuron i. In each case, the dark gray indicate which pairings contribute toward depression of a synapse, and light gray indicate which pairings contribute toward potentiation. **(a)** Symmetric interpretation: each presynaptic spike is paired with the last postsynaptic spike, and each postsynaptic spike is paired with the last presynaptic spike (Morrison et al. 2007). **(b)** Presynaptic centered interpretation: each presynaptic spike is paired with the last postsynaptic spike and the next postsynaptic spike (Izhikevich and Desai 2003; Burkitt et al. 2004: Model II). **(c)** Reduced symmetric interpretation: as in **(b)** but only for immediate pairings (Burkitt et al. 2004: Model IV, also implemented in hardware by Schemmel et al. 2006) +# +# +# References +# ++++++++++ +# +# .. [1] Izhikevich E. M., Desai N. S. (2003) Relating STDP to BCM, +# Neural Comput. 15, 1511--1523 +# +# .. [2] Morrison A., Diesmann M., and Gerstner W. (2008) Phenomenological +# models of synaptic plasticity based on spike timing, +# Biol. Cybern. 98, 459--478 +# +# model stdp_nn_pre_centered_synapse: state: w real = 1 # Synaptic weight diff --git a/models/synapses/stdp_nn_restr_symm_synapse.nestml b/models/synapses/stdp_nn_restr_symm_synapse.nestml index 9ca9e6360..089a4f2c0 100644 --- a/models/synapses/stdp_nn_restr_symm_synapse.nestml +++ b/models/synapses/stdp_nn_restr_symm_synapse.nestml @@ -1,47 +1,47 @@ -""" -Synapse type for spike-timing dependent plasticity with restricted symmetric nearest-neighbour spike pairing scheme -################################################################################################################### - -Description -+++++++++++ - -stdp_nn_restr_synapse is a connector to create synapses with spike time -dependent plasticity with the restricted symmetric nearest-neighbour spike -pairing scheme (fig. 7C in [1]_). - -When a presynaptic spike occurs, it is taken into account in the depression -part of the STDP weight change rule with the nearest preceding postsynaptic -one, but only if the latter occured not earlier than the previous presynaptic -one. When a postsynaptic spike occurs, it is accounted in the facilitation -rule with the nearest preceding presynaptic one, but only if the latter -occured not earlier than the previous postsynaptic one. So, a spike can -participate neither in two depression pairs nor in two potentiation pairs. -The pairs exactly coinciding (so that presynaptic_spike == postsynaptic_spike -+ dendritic_delay), leading to zero delta_t, are discarded. In this case the -concerned pre/postsynaptic spike is paired with the second latest preceding -post/presynaptic one (for example, pre=={10 ms; 20 ms} and post=={20 ms} will -result in a potentiation pair 20-to-10). - -The implementation relies on an additional variable - the postsynaptic -eligibility trace [1]_ (implemented on the postsynaptic neuron side). It -decays exponentially with the time constant tau_minus and increases to 1 on -a post-spike occurrence (instead of increasing by 1 as in stdp_synapse). - -.. figure:: https://raw.githubusercontent.com/nest/nestml/master/doc/fig/stdp-nearest-neighbour.png - - Figure 7 from Morrison, Diesmann and Gerstner - - Original caption: - - Phenomenological models of synaptic plasticity based on spike timing", Biological Cybernetics 98 (2008). "Examples of nearest neighbor spike pairing schemes for a pre-synaptic neuron j and a postsynaptic neuron i. In each case, the dark gray indicate which pairings contribute toward depression of a synapse, and light gray indicate which pairings contribute toward potentiation. **(a)** Symmetric interpretation: each presynaptic spike is paired with the last postsynaptic spike, and each postsynaptic spike is paired with the last presynaptic spike (Morrison et al. 2007). **(b)** Presynaptic centered interpretation: each presynaptic spike is paired with the last postsynaptic spike and the next postsynaptic spike (Izhikevich and Desai 2003; Burkitt et al. 2004: Model II). **(c)** Reduced symmetric interpretation: as in **(b)** but only for immediate pairings (Burkitt et al. 2004: Model IV, also implemented in hardware by Schemmel et al. 2006) - -References -++++++++++ - -.. [1] Morrison A., Diesmann M., and Gerstner W. (2008) Phenomenological - models of synaptic plasticity based on spike timing, - Biol. Cybern. 98, 459--478 -""" +# Synapse type for spike-timing dependent plasticity with restricted symmetric nearest-neighbour spike pairing scheme +# ################################################################################################################### +# +# Description +# +++++++++++ +# +# stdp_nn_restr_synapse is a connector to create synapses with spike time +# dependent plasticity with the restricted symmetric nearest-neighbour spike +# pairing scheme (fig. 7C in [1]_). +# +# When a presynaptic spike occurs, it is taken into account in the depression +# part of the STDP weight change rule with the nearest preceding postsynaptic +# one, but only if the latter occured not earlier than the previous presynaptic +# one. When a postsynaptic spike occurs, it is accounted in the facilitation +# rule with the nearest preceding presynaptic one, but only if the latter +# occured not earlier than the previous postsynaptic one. So, a spike can +# participate neither in two depression pairs nor in two potentiation pairs. +# The pairs exactly coinciding (so that presynaptic_spike == postsynaptic_spike +# + dendritic_delay), leading to zero delta_t, are discarded. In this case the +# concerned pre/postsynaptic spike is paired with the second latest preceding +# post/presynaptic one (for example, pre=={10 ms; 20 ms} and post=={20 ms} will +# result in a potentiation pair 20-to-10). +# +# The implementation relies on an additional variable - the postsynaptic +# eligibility trace [1]_ (implemented on the postsynaptic neuron side). It +# decays exponentially with the time constant tau_minus and increases to 1 on +# a post-spike occurrence (instead of increasing by 1 as in stdp_synapse). +# +# .. figure:: https://raw.githubusercontent.com/nest/nestml/master/doc/fig/stdp-nearest-neighbour.png +# +# Figure 7 from Morrison, Diesmann and Gerstner +# +# Original caption: +# +# Phenomenological models of synaptic plasticity based on spike timing", Biological Cybernetics 98 (2008). "Examples of nearest neighbor spike pairing schemes for a pre-synaptic neuron j and a postsynaptic neuron i. In each case, the dark gray indicate which pairings contribute toward depression of a synapse, and light gray indicate which pairings contribute toward potentiation. **(a)** Symmetric interpretation: each presynaptic spike is paired with the last postsynaptic spike, and each postsynaptic spike is paired with the last presynaptic spike (Morrison et al. 2007). **(b)** Presynaptic centered interpretation: each presynaptic spike is paired with the last postsynaptic spike and the next postsynaptic spike (Izhikevich and Desai 2003; Burkitt et al. 2004: Model II). **(c)** Reduced symmetric interpretation: as in **(b)** but only for immediate pairings (Burkitt et al. 2004: Model IV, also implemented in hardware by Schemmel et al. 2006) +# +# References +# ++++++++++ +# +# .. [1] Morrison A., Diesmann M., and Gerstner W. (2008) Phenomenological +# models of synaptic plasticity based on spike timing, +# Biol. Cybern. 98, 459--478 +# +# model stdp_nn_restr_symm_synapse: state: w real = 1. # Synaptic weight diff --git a/models/synapses/stdp_nn_symm_synapse.nestml b/models/synapses/stdp_nn_symm_synapse.nestml index 55bc413a5..56c114617 100644 --- a/models/synapses/stdp_nn_symm_synapse.nestml +++ b/models/synapses/stdp_nn_symm_synapse.nestml @@ -1,52 +1,52 @@ -""" -Synapse type for spike-timing dependent plasticity with symmetric nearest-neighbour spike pairing scheme -######################################################################################################## - -Description -+++++++++++ - -stdp_nn_symm_synapse is a connector to create synapses with spike time -dependent plasticity with the symmetric nearest-neighbour spike pairing -scheme [1]_. - -When a presynaptic spike occurs, it is taken into account in the depression -part of the STDP weight change rule with the nearest preceding postsynaptic -one, and when a postsynaptic spike occurs, it is accounted in the -facilitation rule with the nearest preceding presynaptic one (instead of -pairing with all spikes, like in stdp_synapse). For a clear illustration of -this scheme see fig. 7A in [2]_. - -The pairs exactly coinciding (so that presynaptic_spike == postsynaptic_spike -+ dendritic_delay), leading to zero delta_t, are discarded. In this case the -concerned pre/postsynaptic spike is paired with the second latest preceding -post/presynaptic one (for example, pre=={10 ms; 20 ms} and post=={20 ms} will -result in a potentiation pair 20-to-10). - -The implementation involves two additional variables - presynaptic and -postsynaptic traces [2]_. The presynaptic trace decays exponentially over -time with the time constant tau_plus and increases to 1 on a pre-spike -occurrence. The postsynaptic trace (implemented on the postsynaptic neuron -side) decays with the time constant tau_minus and increases to 1 on a -post-spike occurrence. - -.. figure:: https://raw.githubusercontent.com/nest/nestml/master/doc/fig/stdp-nearest-neighbour.png - - Figure 7 from Morrison, Diesmann and Gerstner - - Original caption: - - Phenomenological models of synaptic plasticity based on spike timing", Biological Cybernetics 98 (2008). "Examples of nearest neighbor spike pairing schemes for a pre-synaptic neuron j and a postsynaptic neuron i. In each case, the dark gray indicate which pairings contribute toward depression of a synapse, and light gray indicate which pairings contribute toward potentiation. **(a)** Symmetric interpretation: each presynaptic spike is paired with the last postsynaptic spike, and each postsynaptic spike is paired with the last presynaptic spike (Morrison et al. 2007). **(b)** Presynaptic centered interpretation: each presynaptic spike is paired with the last postsynaptic spike and the next postsynaptic spike (Izhikevich and Desai 2003; Burkitt et al. 2004: Model II). **(c)** Reduced symmetric interpretation: as in **(b)** but only for immediate pairings (Burkitt et al. 2004: Model IV, also implemented in hardware by Schemmel et al. 2006) - -References -++++++++++ - -.. [1] Morrison A., Aertsen A., Diesmann M. (2007) Spike-timing dependent - plasticity in balanced random networks, Neural Comput. 19:1437--1467 - -.. [2] Morrison A., Diesmann M., and Gerstner W. (2008) Phenomenological - models of synaptic plasticity based on spike timing, - Biol. Cybern. 98, 459--478 -""" +# Synapse type for spike-timing dependent plasticity with symmetric nearest-neighbour spike pairing scheme +# ######################################################################################################## +# +# Description +# +++++++++++ +# +# stdp_nn_symm_synapse is a connector to create synapses with spike time +# dependent plasticity with the symmetric nearest-neighbour spike pairing +# scheme [1]_. +# +# When a presynaptic spike occurs, it is taken into account in the depression +# part of the STDP weight change rule with the nearest preceding postsynaptic +# one, and when a postsynaptic spike occurs, it is accounted in the +# facilitation rule with the nearest preceding presynaptic one (instead of +# pairing with all spikes, like in stdp_synapse). For a clear illustration of +# this scheme see fig. 7A in [2]_. +# +# The pairs exactly coinciding (so that presynaptic_spike == postsynaptic_spike +# + dendritic_delay), leading to zero delta_t, are discarded. In this case the +# concerned pre/postsynaptic spike is paired with the second latest preceding +# post/presynaptic one (for example, pre=={10 ms; 20 ms} and post=={20 ms} will +# result in a potentiation pair 20-to-10). +# +# The implementation involves two additional variables - presynaptic and +# postsynaptic traces [2]_. The presynaptic trace decays exponentially over +# time with the time constant tau_plus and increases to 1 on a pre-spike +# occurrence. The postsynaptic trace (implemented on the postsynaptic neuron +# side) decays with the time constant tau_minus and increases to 1 on a +# post-spike occurrence. +# +# .. figure:: https://raw.githubusercontent.com/nest/nestml/master/doc/fig/stdp-nearest-neighbour.png +# +# Figure 7 from Morrison, Diesmann and Gerstner +# +# Original caption: +# +# Phenomenological models of synaptic plasticity based on spike timing", Biological Cybernetics 98 (2008). "Examples of nearest neighbor spike pairing schemes for a pre-synaptic neuron j and a postsynaptic neuron i. In each case, the dark gray indicate which pairings contribute toward depression of a synapse, and light gray indicate which pairings contribute toward potentiation. **(a)** Symmetric interpretation: each presynaptic spike is paired with the last postsynaptic spike, and each postsynaptic spike is paired with the last presynaptic spike (Morrison et al. 2007). **(b)** Presynaptic centered interpretation: each presynaptic spike is paired with the last postsynaptic spike and the next postsynaptic spike (Izhikevich and Desai 2003; Burkitt et al. 2004: Model II). **(c)** Reduced symmetric interpretation: as in **(b)** but only for immediate pairings (Burkitt et al. 2004: Model IV, also implemented in hardware by Schemmel et al. 2006) +# +# References +# ++++++++++ +# +# .. [1] Morrison A., Aertsen A., Diesmann M. (2007) Spike-timing dependent +# plasticity in balanced random networks, Neural Comput. 19:1437--1467 +# +# .. [2] Morrison A., Diesmann M., and Gerstner W. (2008) Phenomenological +# models of synaptic plasticity based on spike timing, +# Biol. Cybern. 98, 459--478 +# +# model stdp_nn_symm_synapse: state: w real = 1 # Synaptic weight diff --git a/models/synapses/stdp_synapse.nestml b/models/synapses/stdp_synapse.nestml index da2893391..ff518e24d 100644 --- a/models/synapses/stdp_synapse.nestml +++ b/models/synapses/stdp_synapse.nestml @@ -1,38 +1,38 @@ -""" -stdp - Synapse model for spike-timing dependent plasticity -######################################################### - -Description -+++++++++++ - -stdp_synapse is a synapse with spike-timing dependent plasticity (as defined in [1]_). Here the weight dependence exponent can be set separately for potentiation and depression. Examples: - -=================== ==== ============================= -Multiplicative STDP [2]_ mu_plus = mu_minus = 1 -Additive STDP [3]_ mu_plus = mu_minus = 0 -Guetig STDP [1]_ mu_plus, mu_minus in [0, 1] -Van Rossum STDP [4]_ mu_plus = 0 mu_minus = 1 -=================== ==== ============================= - - -References -++++++++++ - -.. [1] Guetig et al. (2003) Learning Input Correlations through Nonlinear - Temporally Asymmetric Hebbian Plasticity. Journal of Neuroscience - -.. [2] Rubin, J., Lee, D. and Sompolinsky, H. (2001). Equilibrium - properties of temporally asymmetric Hebbian plasticity, PRL - 86,364-367 - -.. [3] Song, S., Miller, K. D. and Abbott, L. F. (2000). Competitive - Hebbian learning through spike-timing-dependent synaptic - plasticity,Nature Neuroscience 3:9,919--926 - -.. [4] van Rossum, M. C. W., Bi, G-Q and Turrigiano, G. G. (2000). - Stable Hebbian learning from spike timing-dependent - plasticity, Journal of Neuroscience, 20:23,8812--8821 -""" +# stdp - Synapse model for spike-timing dependent plasticity +# ######################################################### +# +# Description +# +++++++++++ +# +# stdp_synapse is a synapse with spike-timing dependent plasticity (as defined in [1]_). Here the weight dependence exponent can be set separately for potentiation and depression. Examples: +# +# =================== ==== ============================= +# Multiplicative STDP [2]_ mu_plus = mu_minus = 1 +# Additive STDP [3]_ mu_plus = mu_minus = 0 +# Guetig STDP [1]_ mu_plus, mu_minus in [0, 1] +# Van Rossum STDP [4]_ mu_plus = 0 mu_minus = 1 +# =================== ==== ============================= +# +# +# References +# ++++++++++ +# +# .. [1] Guetig et al. (2003) Learning Input Correlations through Nonlinear +# Temporally Asymmetric Hebbian Plasticity. Journal of Neuroscience +# +# .. [2] Rubin, J., Lee, D. and Sompolinsky, H. (2001). Equilibrium +# properties of temporally asymmetric Hebbian plasticity, PRL +# 86,364-367 +# +# .. [3] Song, S., Miller, K. D. and Abbott, L. F. (2000). Competitive +# Hebbian learning through spike-timing-dependent synaptic +# plasticity,Nature Neuroscience 3:9,919--926 +# +# .. [4] van Rossum, M. C. W., Bi, G-Q and Turrigiano, G. G. (2000). +# Stable Hebbian learning from spike timing-dependent +# plasticity, Journal of Neuroscience, 20:23,8812--8821 +# +# model stdp_synapse: state: w real = 1 # Synaptic weight diff --git a/models/synapses/stdp_triplet_synapse.nestml b/models/synapses/stdp_triplet_synapse.nestml index bef9c8c54..aa117b92a 100644 --- a/models/synapses/stdp_triplet_synapse.nestml +++ b/models/synapses/stdp_triplet_synapse.nestml @@ -1,25 +1,25 @@ -""" -stdp_triplet_synapse - Synapse type with triplet spike-timing dependent plasticity -################################################################################## - -Description -+++++++++++ - -A connection with spike time dependent plasticity accounting for spike triplet effects (as defined in [1]_). - -Nearest-neighbour variant of pre- and postsynaptic spike coupling. - -.. note:: - - See https://github.com/nest/nestml/issues/703 for a potential edge-case issue with this model. - - -References -++++++++++ -.. [1] Pfister JP, Gerstner W (2006). Triplets of spikes in a model - of spike timing-dependent plasticity. The Journal of Neuroscience - 26(38):9673-9682. DOI: https://doi.org/10.1523/JNEUROSCI.1425-06.2006 -""" +# stdp_triplet_synapse - Synapse type with triplet spike-timing dependent plasticity +# ################################################################################## +# +# Description +# +++++++++++ +# +# A connection with spike time dependent plasticity accounting for spike triplet effects (as defined in [1]_). +# +# Nearest-neighbour variant of pre- and postsynaptic spike coupling. +# +# .. note:: +# +# See https://github.com/nest/nestml/issues/703 for a potential edge-case issue with this model. +# +# +# References +# ++++++++++ +# .. [1] Pfister JP, Gerstner W (2006). Triplets of spikes in a model +# of spike timing-dependent plasticity. The Journal of Neuroscience +# 26(38):9673-9682. DOI: https://doi.org/10.1523/JNEUROSCI.1425-06.2006 +# +# model stdp_triplet_synapse: state: w nS = 1 nS # Synaptic weight diff --git a/models/synapses/stdsp_synapse.nestml b/models/synapses/stdsp_synapse.nestml index c1ce19b3e..095369a5f 100644 --- a/models/synapses/stdsp_synapse.nestml +++ b/models/synapses/stdsp_synapse.nestml @@ -1,14 +1,14 @@ -""" -stdsp_synapse - Synapse model for spike-timing dependent plasticity with postsynaptic third-factor modulation -############################################################################################################# - -Description -+++++++++++ - -References -++++++++++ - -""" +# stdsp_synapse - Synapse model for spike-timing dependent plasticity with postsynaptic third-factor modulation +# ############################################################################################################# +# +# Description +# +++++++++++ +# +# References +# ++++++++++ +# +# +# model stdsp_synapse: state: permanence real = 1. diff --git a/pynestml/codegeneration/autodoc_builder.py b/pynestml/codegeneration/autodoc_builder.py index 6a411e3a2..f1ccf7124 100644 --- a/pynestml/codegeneration/autodoc_builder.py +++ b/pynestml/codegeneration/autodoc_builder.py @@ -33,7 +33,7 @@ def get_model_doc_title(model_fname: str): with open(model_fname) as f: model = f.read() - return re.compile(r'\"\"\"[^#]*###').search(model).group()[3:-3].strip() + return re.compile(r'[^#]*###').search(model).group()[3:-3].strip() class AutodocBuilder(Builder): diff --git a/pynestml/codegeneration/printers/nestml_printer.py b/pynestml/codegeneration/printers/nestml_printer.py index 3703ed6c5..99c7bbfbc 100644 --- a/pynestml/codegeneration/printers/nestml_printer.py +++ b/pynestml/codegeneration/printers/nestml_printer.py @@ -613,22 +613,27 @@ def print_n_spaces(n) -> str: def print_ml_comments(comments, indent=0, newline=False) -> str: if comments is None or len(list(comments)) == 0: return "" + ret = "" for comment in comments: - if "\"\"\"" in comment: - return comment + "\n" + if comment.lstrip() == "": + ret += "# \n" + for c_line in comment.splitlines(True): if c_line == "\n": - ret += print_n_spaces(indent) + "#" + "\n" - continue - elif c_line.lstrip() == "": + ret += print_n_spaces(indent) + "# " + "\n" continue + ret += print_n_spaces(indent) + if c_line[len(c_line) - len(c_line.lstrip())] != "#": - ret += "#" + ret += "# " + ret += c_line + "\n" + if len(comment.splitlines(True)) > 1: ret += print_n_spaces(indent) + if len(comments) > 0 and newline: ret += "\n" diff --git a/pynestml/generated/PyNestMLLexer.py b/pynestml/generated/PyNestMLLexer.py index 426cb4ae6..9dcd9588e 100644 --- a/pynestml/generated/PyNestMLLexer.py +++ b/pynestml/generated/PyNestMLLexer.py @@ -15,7 +15,7 @@ def serializedATN(): return [ - 4,0,91,707,6,-1,2,0,7,0,2,1,7,1,2,2,7,2,2,3,7,3,2,4,7,4,2,5,7,5, + 4,0,89,684,6,-1,2,0,7,0,2,1,7,1,2,2,7,2,2,3,7,3,2,4,7,4,2,5,7,5, 2,6,7,6,2,7,7,7,2,8,7,8,2,9,7,9,2,10,7,10,2,11,7,11,2,12,7,12,2, 13,7,13,2,14,7,14,2,15,7,15,2,16,7,16,2,17,7,17,2,18,7,18,2,19,7, 19,2,20,7,20,2,21,7,21,2,22,7,22,2,23,7,23,2,24,7,24,2,25,7,25,2, @@ -28,245 +28,237 @@ def serializedATN(): 65,7,65,2,66,7,66,2,67,7,67,2,68,7,68,2,69,7,69,2,70,7,70,2,71,7, 71,2,72,7,72,2,73,7,73,2,74,7,74,2,75,7,75,2,76,7,76,2,77,7,77,2, 78,7,78,2,79,7,79,2,80,7,80,2,81,7,81,2,82,7,82,2,83,7,83,2,84,7, - 84,2,85,7,85,2,86,7,86,2,87,7,87,2,88,7,88,2,89,7,89,2,90,7,90,2, - 91,7,91,2,92,7,92,1,0,1,0,1,0,1,0,1,1,3,1,193,8,1,1,1,1,1,1,2,1, - 2,1,2,3,2,200,8,2,1,3,4,3,203,8,3,11,3,12,3,204,1,3,1,3,1,4,1,4, - 1,4,1,4,1,4,1,5,1,5,5,5,216,8,5,10,5,12,5,219,9,5,1,5,1,5,4,5,223, - 8,5,11,5,12,5,224,1,5,1,5,1,6,1,6,5,6,231,8,6,10,6,12,6,234,9,6, - 1,6,1,6,1,7,1,7,1,7,3,7,241,8,7,1,7,1,7,1,7,3,7,246,8,7,3,7,248, - 8,7,1,7,1,7,1,8,1,8,1,8,1,8,1,8,1,8,1,8,1,8,1,9,1,9,1,9,1,9,1,9, - 1,10,1,10,1,10,1,10,1,10,1,10,1,10,1,11,1,11,1,11,1,11,1,11,1,11, - 1,11,1,11,1,12,1,12,1,12,1,12,1,12,1,13,1,13,1,13,1,13,1,13,1,13, - 1,13,1,13,1,13,1,14,1,14,1,14,1,14,1,14,1,14,1,14,1,15,1,15,1,15, - 1,15,1,15,1,15,1,15,1,16,1,16,1,16,1,17,1,17,1,17,1,17,1,17,1,18, - 1,18,1,18,1,18,1,18,1,19,1,19,1,19,1,19,1,20,1,20,1,20,1,20,1,20, - 1,20,1,21,1,21,1,21,1,22,1,22,1,22,1,22,1,22,1,23,1,23,1,23,1,23, - 1,24,1,24,1,24,1,24,1,25,1,25,1,25,1,26,1,26,1,26,1,26,1,27,1,27, - 1,27,1,27,1,27,1,27,1,27,1,27,1,27,1,27,1,27,1,28,1,28,1,28,1,28, - 1,28,1,28,1,28,1,29,1,29,1,29,1,29,1,29,1,29,1,30,1,30,1,30,1,30, - 1,30,1,30,1,31,1,31,1,31,1,31,1,31,1,31,1,31,1,31,1,31,1,31,1,31, - 1,32,1,32,1,32,1,32,1,32,1,32,1,32,1,32,1,32,1,32,1,33,1,33,1,33, - 1,33,1,33,1,33,1,33,1,34,1,34,1,34,1,34,1,34,1,34,1,34,1,34,1,34, - 1,34,1,35,1,35,1,35,1,35,1,35,1,35,1,36,1,36,1,36,1,36,1,36,1,36, - 1,36,1,37,1,37,1,37,1,37,1,37,1,37,1,37,1,37,1,37,1,37,1,37,1,38, - 1,38,1,38,1,38,1,38,1,38,1,38,1,38,1,38,1,38,1,39,1,39,1,39,1,39, - 1,39,1,39,1,39,1,39,1,39,1,39,1,39,1,39,1,40,1,40,1,40,1,40,1,40, - 1,40,1,41,1,41,1,41,1,41,1,41,1,41,1,41,1,41,1,41,1,41,1,41,1,42, - 1,42,1,42,1,42,1,42,1,42,1,42,1,42,1,42,1,42,1,42,1,43,1,43,1,43, - 1,43,1,43,1,43,1,43,1,43,1,43,1,43,1,43,1,43,1,43,1,44,1,44,1,44, - 1,44,1,44,1,44,1,44,1,44,1,44,1,44,1,44,1,44,1,44,1,44,1,44,1,45, - 1,45,1,46,1,46,1,46,1,46,1,47,1,47,1,48,1,48,1,49,1,49,1,50,1,50, - 1,51,1,51,1,52,1,52,1,53,1,53,1,54,1,54,1,55,1,55,1,55,1,56,1,56, - 1,57,1,57,1,57,1,58,1,58,1,58,1,59,1,59,1,59,1,60,1,60,1,60,1,61, - 1,61,1,62,1,62,1,63,1,63,1,63,1,64,1,64,1,64,1,65,1,65,1,65,1,66, - 1,66,1,66,1,67,1,67,1,67,1,68,1,68,1,68,1,69,1,69,1,69,1,70,1,70, - 1,70,1,71,1,71,1,71,1,72,1,72,1,73,1,73,1,74,1,74,1,75,1,75,1,76, - 1,76,1,76,1,77,1,77,1,78,1,78,1,79,1,79,1,80,1,80,1,81,1,81,1,81, - 1,82,1,82,1,83,1,83,1,84,1,84,1,85,1,85,1,85,1,85,1,85,1,85,1,85, - 1,85,1,85,1,85,1,85,1,85,1,85,1,85,1,85,1,85,1,85,1,85,3,85,640, - 8,85,1,86,1,86,1,86,4,86,645,8,86,11,86,12,86,646,1,86,3,86,650, - 8,86,1,86,3,86,653,8,86,1,86,3,86,656,8,86,1,86,5,86,659,8,86,10, - 86,12,86,662,9,86,1,86,1,86,1,87,3,87,667,8,87,1,87,5,87,670,8,87, - 10,87,12,87,673,9,87,1,88,4,88,676,8,88,11,88,12,88,677,1,89,1,89, - 3,89,682,8,89,1,90,3,90,685,8,90,1,90,1,90,1,90,1,90,1,90,1,90,3, - 90,693,8,90,1,91,1,91,3,91,697,8,91,1,91,1,91,1,91,1,92,1,92,3,92, - 704,8,92,1,92,1,92,2,217,224,0,93,1,3,3,0,5,4,7,5,9,6,11,7,13,8, - 15,9,17,10,19,11,21,12,23,13,25,14,27,15,29,16,31,17,33,18,35,19, - 37,20,39,21,41,22,43,23,45,24,47,25,49,26,51,27,53,28,55,29,57,30, - 59,31,61,32,63,33,65,34,67,35,69,36,71,37,73,38,75,39,77,40,79,41, - 81,42,83,43,85,44,87,45,89,46,91,47,93,48,95,49,97,50,99,51,101, - 52,103,53,105,54,107,55,109,56,111,57,113,58,115,59,117,60,119,61, - 121,62,123,63,125,64,127,65,129,66,131,67,133,68,135,69,137,70,139, - 71,141,72,143,73,145,74,147,75,149,76,151,77,153,78,155,79,157,80, - 159,81,161,82,163,83,165,84,167,85,169,86,171,87,173,88,175,89,177, - 90,179,91,181,0,183,0,185,0,1,0,7,2,0,9,9,32,32,2,0,10,10,13,13, - 4,0,10,10,13,13,34,34,92,92,4,0,36,36,65,90,95,95,97,122,5,0,36, - 36,48,57,65,90,95,95,97,122,1,0,48,57,2,0,69,69,101,101,728,0,1, - 1,0,0,0,0,5,1,0,0,0,0,7,1,0,0,0,0,9,1,0,0,0,0,11,1,0,0,0,0,13,1, - 0,0,0,0,15,1,0,0,0,0,17,1,0,0,0,0,19,1,0,0,0,0,21,1,0,0,0,0,23,1, - 0,0,0,0,25,1,0,0,0,0,27,1,0,0,0,0,29,1,0,0,0,0,31,1,0,0,0,0,33,1, - 0,0,0,0,35,1,0,0,0,0,37,1,0,0,0,0,39,1,0,0,0,0,41,1,0,0,0,0,43,1, - 0,0,0,0,45,1,0,0,0,0,47,1,0,0,0,0,49,1,0,0,0,0,51,1,0,0,0,0,53,1, - 0,0,0,0,55,1,0,0,0,0,57,1,0,0,0,0,59,1,0,0,0,0,61,1,0,0,0,0,63,1, - 0,0,0,0,65,1,0,0,0,0,67,1,0,0,0,0,69,1,0,0,0,0,71,1,0,0,0,0,73,1, - 0,0,0,0,75,1,0,0,0,0,77,1,0,0,0,0,79,1,0,0,0,0,81,1,0,0,0,0,83,1, - 0,0,0,0,85,1,0,0,0,0,87,1,0,0,0,0,89,1,0,0,0,0,91,1,0,0,0,0,93,1, - 0,0,0,0,95,1,0,0,0,0,97,1,0,0,0,0,99,1,0,0,0,0,101,1,0,0,0,0,103, - 1,0,0,0,0,105,1,0,0,0,0,107,1,0,0,0,0,109,1,0,0,0,0,111,1,0,0,0, - 0,113,1,0,0,0,0,115,1,0,0,0,0,117,1,0,0,0,0,119,1,0,0,0,0,121,1, - 0,0,0,0,123,1,0,0,0,0,125,1,0,0,0,0,127,1,0,0,0,0,129,1,0,0,0,0, - 131,1,0,0,0,0,133,1,0,0,0,0,135,1,0,0,0,0,137,1,0,0,0,0,139,1,0, - 0,0,0,141,1,0,0,0,0,143,1,0,0,0,0,145,1,0,0,0,0,147,1,0,0,0,0,149, - 1,0,0,0,0,151,1,0,0,0,0,153,1,0,0,0,0,155,1,0,0,0,0,157,1,0,0,0, - 0,159,1,0,0,0,0,161,1,0,0,0,0,163,1,0,0,0,0,165,1,0,0,0,0,167,1, - 0,0,0,0,169,1,0,0,0,0,171,1,0,0,0,0,173,1,0,0,0,0,175,1,0,0,0,0, - 177,1,0,0,0,0,179,1,0,0,0,1,187,1,0,0,0,3,192,1,0,0,0,5,196,1,0, - 0,0,7,202,1,0,0,0,9,208,1,0,0,0,11,213,1,0,0,0,13,228,1,0,0,0,15, - 247,1,0,0,0,17,251,1,0,0,0,19,259,1,0,0,0,21,264,1,0,0,0,23,271, - 1,0,0,0,25,279,1,0,0,0,27,284,1,0,0,0,29,293,1,0,0,0,31,300,1,0, - 0,0,33,307,1,0,0,0,35,310,1,0,0,0,37,315,1,0,0,0,39,320,1,0,0,0, - 41,324,1,0,0,0,43,330,1,0,0,0,45,333,1,0,0,0,47,338,1,0,0,0,49,342, - 1,0,0,0,51,346,1,0,0,0,53,349,1,0,0,0,55,353,1,0,0,0,57,364,1,0, - 0,0,59,371,1,0,0,0,61,377,1,0,0,0,63,383,1,0,0,0,65,394,1,0,0,0, - 67,404,1,0,0,0,69,411,1,0,0,0,71,421,1,0,0,0,73,427,1,0,0,0,75,434, - 1,0,0,0,77,445,1,0,0,0,79,455,1,0,0,0,81,467,1,0,0,0,83,473,1,0, - 0,0,85,484,1,0,0,0,87,495,1,0,0,0,89,508,1,0,0,0,91,523,1,0,0,0, - 93,525,1,0,0,0,95,529,1,0,0,0,97,531,1,0,0,0,99,533,1,0,0,0,101, - 535,1,0,0,0,103,537,1,0,0,0,105,539,1,0,0,0,107,541,1,0,0,0,109, - 543,1,0,0,0,111,545,1,0,0,0,113,548,1,0,0,0,115,550,1,0,0,0,117, - 553,1,0,0,0,119,556,1,0,0,0,121,559,1,0,0,0,123,562,1,0,0,0,125, - 564,1,0,0,0,127,566,1,0,0,0,129,569,1,0,0,0,131,572,1,0,0,0,133, - 575,1,0,0,0,135,578,1,0,0,0,137,581,1,0,0,0,139,584,1,0,0,0,141, - 587,1,0,0,0,143,590,1,0,0,0,145,593,1,0,0,0,147,595,1,0,0,0,149, - 597,1,0,0,0,151,599,1,0,0,0,153,601,1,0,0,0,155,604,1,0,0,0,157, - 606,1,0,0,0,159,608,1,0,0,0,161,610,1,0,0,0,163,612,1,0,0,0,165, - 615,1,0,0,0,167,617,1,0,0,0,169,619,1,0,0,0,171,639,1,0,0,0,173, - 641,1,0,0,0,175,666,1,0,0,0,177,675,1,0,0,0,179,681,1,0,0,0,181, - 692,1,0,0,0,183,696,1,0,0,0,185,703,1,0,0,0,187,188,5,34,0,0,188, - 189,5,34,0,0,189,190,5,34,0,0,190,2,1,0,0,0,191,193,5,13,0,0,192, - 191,1,0,0,0,192,193,1,0,0,0,193,194,1,0,0,0,194,195,5,10,0,0,195, - 4,1,0,0,0,196,197,3,145,72,0,197,199,3,3,1,0,198,200,3,7,3,0,199, - 198,1,0,0,0,199,200,1,0,0,0,200,6,1,0,0,0,201,203,7,0,0,0,202,201, - 1,0,0,0,203,204,1,0,0,0,204,202,1,0,0,0,204,205,1,0,0,0,205,206, - 1,0,0,0,206,207,6,3,0,0,207,8,1,0,0,0,208,209,5,92,0,0,209,210,3, - 3,1,0,210,211,1,0,0,0,211,212,6,4,0,0,212,10,1,0,0,0,213,217,3,1, - 0,0,214,216,9,0,0,0,215,214,1,0,0,0,216,219,1,0,0,0,217,218,1,0, - 0,0,217,215,1,0,0,0,218,220,1,0,0,0,219,217,1,0,0,0,220,222,3,1, - 0,0,221,223,3,3,1,0,222,221,1,0,0,0,223,224,1,0,0,0,224,225,1,0, - 0,0,224,222,1,0,0,0,225,226,1,0,0,0,226,227,6,5,1,0,227,12,1,0,0, - 0,228,232,5,35,0,0,229,231,8,1,0,0,230,229,1,0,0,0,231,234,1,0,0, - 0,232,230,1,0,0,0,232,233,1,0,0,0,233,235,1,0,0,0,234,232,1,0,0, - 0,235,236,6,6,1,0,236,14,1,0,0,0,237,238,4,7,0,0,238,248,3,7,3,0, - 239,241,5,13,0,0,240,239,1,0,0,0,240,241,1,0,0,0,241,242,1,0,0,0, - 242,243,5,10,0,0,243,245,1,0,0,0,244,246,3,7,3,0,245,244,1,0,0,0, - 245,246,1,0,0,0,246,248,1,0,0,0,247,237,1,0,0,0,247,240,1,0,0,0, - 248,249,1,0,0,0,249,250,6,7,2,0,250,16,1,0,0,0,251,252,5,105,0,0, - 252,253,5,110,0,0,253,254,5,116,0,0,254,255,5,101,0,0,255,256,5, - 103,0,0,256,257,5,101,0,0,257,258,5,114,0,0,258,18,1,0,0,0,259,260, - 5,114,0,0,260,261,5,101,0,0,261,262,5,97,0,0,262,263,5,108,0,0,263, - 20,1,0,0,0,264,265,5,115,0,0,265,266,5,116,0,0,266,267,5,114,0,0, - 267,268,5,105,0,0,268,269,5,110,0,0,269,270,5,103,0,0,270,22,1,0, - 0,0,271,272,5,98,0,0,272,273,5,111,0,0,273,274,5,111,0,0,274,275, - 5,108,0,0,275,276,5,101,0,0,276,277,5,97,0,0,277,278,5,110,0,0,278, - 24,1,0,0,0,279,280,5,118,0,0,280,281,5,111,0,0,281,282,5,105,0,0, - 282,283,5,100,0,0,283,26,1,0,0,0,284,285,5,102,0,0,285,286,5,117, - 0,0,286,287,5,110,0,0,287,288,5,99,0,0,288,289,5,116,0,0,289,290, - 5,105,0,0,290,291,5,111,0,0,291,292,5,110,0,0,292,28,1,0,0,0,293, - 294,5,105,0,0,294,295,5,110,0,0,295,296,5,108,0,0,296,297,5,105, - 0,0,297,298,5,110,0,0,298,299,5,101,0,0,299,30,1,0,0,0,300,301,5, - 114,0,0,301,302,5,101,0,0,302,303,5,116,0,0,303,304,5,117,0,0,304, - 305,5,114,0,0,305,306,5,110,0,0,306,32,1,0,0,0,307,308,5,105,0,0, - 308,309,5,102,0,0,309,34,1,0,0,0,310,311,5,101,0,0,311,312,5,108, - 0,0,312,313,5,105,0,0,313,314,5,102,0,0,314,36,1,0,0,0,315,316,5, - 101,0,0,316,317,5,108,0,0,317,318,5,115,0,0,318,319,5,101,0,0,319, - 38,1,0,0,0,320,321,5,102,0,0,321,322,5,111,0,0,322,323,5,114,0,0, - 323,40,1,0,0,0,324,325,5,119,0,0,325,326,5,104,0,0,326,327,5,105, - 0,0,327,328,5,108,0,0,328,329,5,101,0,0,329,42,1,0,0,0,330,331,5, - 105,0,0,331,332,5,110,0,0,332,44,1,0,0,0,333,334,5,115,0,0,334,335, - 5,116,0,0,335,336,5,101,0,0,336,337,5,112,0,0,337,46,1,0,0,0,338, - 339,5,105,0,0,339,340,5,110,0,0,340,341,5,102,0,0,341,48,1,0,0,0, - 342,343,5,97,0,0,343,344,5,110,0,0,344,345,5,100,0,0,345,50,1,0, - 0,0,346,347,5,111,0,0,347,348,5,114,0,0,348,52,1,0,0,0,349,350,5, - 110,0,0,350,351,5,111,0,0,351,352,5,116,0,0,352,54,1,0,0,0,353,354, - 5,114,0,0,354,355,5,101,0,0,355,356,5,99,0,0,356,357,5,111,0,0,357, - 358,5,114,0,0,358,359,5,100,0,0,359,360,5,97,0,0,360,361,5,98,0, - 0,361,362,5,108,0,0,362,363,5,101,0,0,363,56,1,0,0,0,364,365,5,107, - 0,0,365,366,5,101,0,0,366,367,5,114,0,0,367,368,5,110,0,0,368,369, - 5,101,0,0,369,370,5,108,0,0,370,58,1,0,0,0,371,372,5,109,0,0,372, - 373,5,111,0,0,373,374,5,100,0,0,374,375,5,101,0,0,375,376,5,108, - 0,0,376,60,1,0,0,0,377,378,5,115,0,0,378,379,5,116,0,0,379,380,5, - 97,0,0,380,381,5,116,0,0,381,382,5,101,0,0,382,62,1,0,0,0,383,384, - 5,112,0,0,384,385,5,97,0,0,385,386,5,114,0,0,386,387,5,97,0,0,387, - 388,5,109,0,0,388,389,5,101,0,0,389,390,5,116,0,0,390,391,5,101, - 0,0,391,392,5,114,0,0,392,393,5,115,0,0,393,64,1,0,0,0,394,395,5, - 105,0,0,395,396,5,110,0,0,396,397,5,116,0,0,397,398,5,101,0,0,398, - 399,5,114,0,0,399,400,5,110,0,0,400,401,5,97,0,0,401,402,5,108,0, - 0,402,403,5,115,0,0,403,66,1,0,0,0,404,405,5,117,0,0,405,406,5,112, - 0,0,406,407,5,100,0,0,407,408,5,97,0,0,408,409,5,116,0,0,409,410, - 5,101,0,0,410,68,1,0,0,0,411,412,5,101,0,0,412,413,5,113,0,0,413, - 414,5,117,0,0,414,415,5,97,0,0,415,416,5,116,0,0,416,417,5,105,0, - 0,417,418,5,111,0,0,418,419,5,110,0,0,419,420,5,115,0,0,420,70,1, - 0,0,0,421,422,5,105,0,0,422,423,5,110,0,0,423,424,5,112,0,0,424, - 425,5,117,0,0,425,426,5,116,0,0,426,72,1,0,0,0,427,428,5,111,0,0, - 428,429,5,117,0,0,429,430,5,116,0,0,430,431,5,112,0,0,431,432,5, - 117,0,0,432,433,5,116,0,0,433,74,1,0,0,0,434,435,5,99,0,0,435,436, - 5,111,0,0,436,437,5,110,0,0,437,438,5,116,0,0,438,439,5,105,0,0, - 439,440,5,110,0,0,440,441,5,117,0,0,441,442,5,111,0,0,442,443,5, - 117,0,0,443,444,5,115,0,0,444,76,1,0,0,0,445,446,5,111,0,0,446,447, - 5,110,0,0,447,448,5,82,0,0,448,449,5,101,0,0,449,450,5,99,0,0,450, - 451,5,101,0,0,451,452,5,105,0,0,452,453,5,118,0,0,453,454,5,101, - 0,0,454,78,1,0,0,0,455,456,5,111,0,0,456,457,5,110,0,0,457,458,5, - 67,0,0,458,459,5,111,0,0,459,460,5,110,0,0,460,461,5,100,0,0,461, - 462,5,105,0,0,462,463,5,116,0,0,463,464,5,105,0,0,464,465,5,111, - 0,0,465,466,5,110,0,0,466,80,1,0,0,0,467,468,5,115,0,0,468,469,5, - 112,0,0,469,470,5,105,0,0,470,471,5,107,0,0,471,472,5,101,0,0,472, - 82,1,0,0,0,473,474,5,105,0,0,474,475,5,110,0,0,475,476,5,104,0,0, - 476,477,5,105,0,0,477,478,5,98,0,0,478,479,5,105,0,0,479,480,5,116, - 0,0,480,481,5,111,0,0,481,482,5,114,0,0,482,483,5,121,0,0,483,84, - 1,0,0,0,484,485,5,101,0,0,485,486,5,120,0,0,486,487,5,99,0,0,487, - 488,5,105,0,0,488,489,5,116,0,0,489,490,5,97,0,0,490,491,5,116,0, - 0,491,492,5,111,0,0,492,493,5,114,0,0,493,494,5,121,0,0,494,86,1, - 0,0,0,495,496,5,64,0,0,496,497,5,104,0,0,497,498,5,111,0,0,498,499, - 5,109,0,0,499,500,5,111,0,0,500,501,5,103,0,0,501,502,5,101,0,0, - 502,503,5,110,0,0,503,504,5,101,0,0,504,505,5,111,0,0,505,506,5, - 117,0,0,506,507,5,115,0,0,507,88,1,0,0,0,508,509,5,64,0,0,509,510, - 5,104,0,0,510,511,5,101,0,0,511,512,5,116,0,0,512,513,5,101,0,0, - 513,514,5,114,0,0,514,515,5,111,0,0,515,516,5,103,0,0,516,517,5, - 101,0,0,517,518,5,110,0,0,518,519,5,101,0,0,519,520,5,111,0,0,520, - 521,5,117,0,0,521,522,5,115,0,0,522,90,1,0,0,0,523,524,5,64,0,0, - 524,92,1,0,0,0,525,526,5,46,0,0,526,527,5,46,0,0,527,528,5,46,0, - 0,528,94,1,0,0,0,529,530,5,40,0,0,530,96,1,0,0,0,531,532,5,41,0, - 0,532,98,1,0,0,0,533,534,5,43,0,0,534,100,1,0,0,0,535,536,5,126, - 0,0,536,102,1,0,0,0,537,538,5,124,0,0,538,104,1,0,0,0,539,540,5, - 94,0,0,540,106,1,0,0,0,541,542,5,38,0,0,542,108,1,0,0,0,543,544, - 5,91,0,0,544,110,1,0,0,0,545,546,5,60,0,0,546,547,5,45,0,0,547,112, - 1,0,0,0,548,549,5,93,0,0,549,114,1,0,0,0,550,551,5,91,0,0,551,552, - 5,91,0,0,552,116,1,0,0,0,553,554,5,93,0,0,554,555,5,93,0,0,555,118, - 1,0,0,0,556,557,5,60,0,0,557,558,5,60,0,0,558,120,1,0,0,0,559,560, - 5,62,0,0,560,561,5,62,0,0,561,122,1,0,0,0,562,563,5,60,0,0,563,124, - 1,0,0,0,564,565,5,62,0,0,565,126,1,0,0,0,566,567,5,60,0,0,567,568, - 5,61,0,0,568,128,1,0,0,0,569,570,5,43,0,0,570,571,5,61,0,0,571,130, - 1,0,0,0,572,573,5,45,0,0,573,574,5,61,0,0,574,132,1,0,0,0,575,576, - 5,42,0,0,576,577,5,61,0,0,577,134,1,0,0,0,578,579,5,47,0,0,579,580, - 5,61,0,0,580,136,1,0,0,0,581,582,5,61,0,0,582,583,5,61,0,0,583,138, - 1,0,0,0,584,585,5,33,0,0,585,586,5,61,0,0,586,140,1,0,0,0,587,588, - 5,60,0,0,588,589,5,62,0,0,589,142,1,0,0,0,590,591,5,62,0,0,591,592, - 5,61,0,0,592,144,1,0,0,0,593,594,5,44,0,0,594,146,1,0,0,0,595,596, - 5,45,0,0,596,148,1,0,0,0,597,598,5,61,0,0,598,150,1,0,0,0,599,600, - 5,42,0,0,600,152,1,0,0,0,601,602,5,42,0,0,602,603,5,42,0,0,603,154, - 1,0,0,0,604,605,5,47,0,0,605,156,1,0,0,0,606,607,5,37,0,0,607,158, - 1,0,0,0,608,609,5,63,0,0,609,160,1,0,0,0,610,611,5,58,0,0,611,162, - 1,0,0,0,612,613,5,58,0,0,613,614,5,58,0,0,614,164,1,0,0,0,615,616, - 5,59,0,0,616,166,1,0,0,0,617,618,5,39,0,0,618,168,1,0,0,0,619,620, - 5,46,0,0,620,170,1,0,0,0,621,622,5,116,0,0,622,623,5,114,0,0,623, - 624,5,117,0,0,624,640,5,101,0,0,625,626,5,84,0,0,626,627,5,114,0, - 0,627,628,5,117,0,0,628,640,5,101,0,0,629,630,5,102,0,0,630,631, - 5,97,0,0,631,632,5,108,0,0,632,633,5,115,0,0,633,640,5,101,0,0,634, - 635,5,70,0,0,635,636,5,97,0,0,636,637,5,108,0,0,637,638,5,115,0, - 0,638,640,5,101,0,0,639,621,1,0,0,0,639,625,1,0,0,0,639,629,1,0, - 0,0,639,634,1,0,0,0,640,172,1,0,0,0,641,660,5,34,0,0,642,655,5,92, - 0,0,643,645,7,0,0,0,644,643,1,0,0,0,645,646,1,0,0,0,646,644,1,0, - 0,0,646,647,1,0,0,0,647,652,1,0,0,0,648,650,5,13,0,0,649,648,1,0, - 0,0,649,650,1,0,0,0,650,651,1,0,0,0,651,653,5,10,0,0,652,649,1,0, - 0,0,652,653,1,0,0,0,653,656,1,0,0,0,654,656,9,0,0,0,655,644,1,0, - 0,0,655,654,1,0,0,0,656,659,1,0,0,0,657,659,8,2,0,0,658,642,1,0, - 0,0,658,657,1,0,0,0,659,662,1,0,0,0,660,658,1,0,0,0,660,661,1,0, - 0,0,661,663,1,0,0,0,662,660,1,0,0,0,663,664,5,34,0,0,664,174,1,0, - 0,0,665,667,7,3,0,0,666,665,1,0,0,0,667,671,1,0,0,0,668,670,7,4, - 0,0,669,668,1,0,0,0,670,673,1,0,0,0,671,669,1,0,0,0,671,672,1,0, - 0,0,672,176,1,0,0,0,673,671,1,0,0,0,674,676,7,5,0,0,675,674,1,0, - 0,0,676,677,1,0,0,0,677,675,1,0,0,0,677,678,1,0,0,0,678,178,1,0, - 0,0,679,682,3,181,90,0,680,682,3,183,91,0,681,679,1,0,0,0,681,680, - 1,0,0,0,682,180,1,0,0,0,683,685,3,177,88,0,684,683,1,0,0,0,684,685, - 1,0,0,0,685,686,1,0,0,0,686,687,3,169,84,0,687,688,3,177,88,0,688, - 693,1,0,0,0,689,690,3,177,88,0,690,691,3,169,84,0,691,693,1,0,0, - 0,692,684,1,0,0,0,692,689,1,0,0,0,693,182,1,0,0,0,694,697,3,177, - 88,0,695,697,3,181,90,0,696,694,1,0,0,0,696,695,1,0,0,0,697,698, - 1,0,0,0,698,699,7,6,0,0,699,700,3,185,92,0,700,184,1,0,0,0,701,704, - 3,99,49,0,702,704,3,147,73,0,703,701,1,0,0,0,703,702,1,0,0,0,703, - 704,1,0,0,0,704,705,1,0,0,0,705,706,3,177,88,0,706,186,1,0,0,0,26, - 0,192,199,204,217,224,232,240,245,247,639,646,649,652,655,658,660, - 666,669,671,677,681,684,692,696,703,3,0,1,0,0,2,0,1,7,0 + 84,2,85,7,85,2,86,7,86,2,87,7,87,2,88,7,88,2,89,7,89,2,90,7,90,1, + 0,3,0,185,8,0,1,0,1,0,1,1,1,1,1,1,3,1,192,8,1,1,2,4,2,195,8,2,11, + 2,12,2,196,1,2,1,2,1,3,1,3,1,3,1,3,1,3,1,4,1,4,5,4,208,8,4,10,4, + 12,4,211,9,4,1,4,1,4,1,5,1,5,1,5,3,5,218,8,5,1,5,1,5,1,5,3,5,223, + 8,5,3,5,225,8,5,1,5,1,5,1,6,1,6,1,6,1,6,1,6,1,6,1,6,1,6,1,7,1,7, + 1,7,1,7,1,7,1,8,1,8,1,8,1,8,1,8,1,8,1,8,1,9,1,9,1,9,1,9,1,9,1,9, + 1,9,1,9,1,10,1,10,1,10,1,10,1,10,1,11,1,11,1,11,1,11,1,11,1,11,1, + 11,1,11,1,11,1,12,1,12,1,12,1,12,1,12,1,12,1,12,1,13,1,13,1,13,1, + 13,1,13,1,13,1,13,1,14,1,14,1,14,1,15,1,15,1,15,1,15,1,15,1,16,1, + 16,1,16,1,16,1,16,1,17,1,17,1,17,1,17,1,18,1,18,1,18,1,18,1,18,1, + 18,1,19,1,19,1,19,1,20,1,20,1,20,1,20,1,20,1,21,1,21,1,21,1,21,1, + 22,1,22,1,22,1,22,1,23,1,23,1,23,1,24,1,24,1,24,1,24,1,25,1,25,1, + 25,1,25,1,25,1,25,1,25,1,25,1,25,1,25,1,25,1,26,1,26,1,26,1,26,1, + 26,1,26,1,26,1,27,1,27,1,27,1,27,1,27,1,27,1,28,1,28,1,28,1,28,1, + 28,1,28,1,29,1,29,1,29,1,29,1,29,1,29,1,29,1,29,1,29,1,29,1,29,1, + 30,1,30,1,30,1,30,1,30,1,30,1,30,1,30,1,30,1,30,1,31,1,31,1,31,1, + 31,1,31,1,31,1,31,1,32,1,32,1,32,1,32,1,32,1,32,1,32,1,32,1,32,1, + 32,1,33,1,33,1,33,1,33,1,33,1,33,1,34,1,34,1,34,1,34,1,34,1,34,1, + 34,1,35,1,35,1,35,1,35,1,35,1,35,1,35,1,35,1,35,1,35,1,35,1,36,1, + 36,1,36,1,36,1,36,1,36,1,36,1,36,1,36,1,36,1,37,1,37,1,37,1,37,1, + 37,1,37,1,37,1,37,1,37,1,37,1,37,1,37,1,38,1,38,1,38,1,38,1,38,1, + 38,1,39,1,39,1,39,1,39,1,39,1,39,1,39,1,39,1,39,1,39,1,39,1,40,1, + 40,1,40,1,40,1,40,1,40,1,40,1,40,1,40,1,40,1,40,1,41,1,41,1,41,1, + 41,1,41,1,41,1,41,1,41,1,41,1,41,1,41,1,41,1,41,1,42,1,42,1,42,1, + 42,1,42,1,42,1,42,1,42,1,42,1,42,1,42,1,42,1,42,1,42,1,42,1,43,1, + 43,1,44,1,44,1,44,1,44,1,45,1,45,1,46,1,46,1,47,1,47,1,48,1,48,1, + 49,1,49,1,50,1,50,1,51,1,51,1,52,1,52,1,53,1,53,1,53,1,54,1,54,1, + 55,1,55,1,55,1,56,1,56,1,56,1,57,1,57,1,57,1,58,1,58,1,58,1,59,1, + 59,1,60,1,60,1,61,1,61,1,61,1,62,1,62,1,62,1,63,1,63,1,63,1,64,1, + 64,1,64,1,65,1,65,1,65,1,66,1,66,1,66,1,67,1,67,1,67,1,68,1,68,1, + 68,1,69,1,69,1,69,1,70,1,70,1,71,1,71,1,72,1,72,1,73,1,73,1,74,1, + 74,1,74,1,75,1,75,1,76,1,76,1,77,1,77,1,78,1,78,1,79,1,79,1,79,1, + 80,1,80,1,81,1,81,1,82,1,82,1,83,1,83,1,83,1,83,1,83,1,83,1,83,1, + 83,1,83,1,83,1,83,1,83,1,83,1,83,1,83,1,83,1,83,1,83,3,83,617,8, + 83,1,84,1,84,1,84,4,84,622,8,84,11,84,12,84,623,1,84,3,84,627,8, + 84,1,84,3,84,630,8,84,1,84,3,84,633,8,84,1,84,5,84,636,8,84,10,84, + 12,84,639,9,84,1,84,1,84,1,85,3,85,644,8,85,1,85,5,85,647,8,85,10, + 85,12,85,650,9,85,1,86,4,86,653,8,86,11,86,12,86,654,1,87,1,87,3, + 87,659,8,87,1,88,3,88,662,8,88,1,88,1,88,1,88,1,88,1,88,1,88,3,88, + 670,8,88,1,89,1,89,3,89,674,8,89,1,89,1,89,1,89,1,90,1,90,3,90,681, + 8,90,1,90,1,90,0,0,91,1,0,3,3,5,4,7,5,9,6,11,7,13,8,15,9,17,10,19, + 11,21,12,23,13,25,14,27,15,29,16,31,17,33,18,35,19,37,20,39,21,41, + 22,43,23,45,24,47,25,49,26,51,27,53,28,55,29,57,30,59,31,61,32,63, + 33,65,34,67,35,69,36,71,37,73,38,75,39,77,40,79,41,81,42,83,43,85, + 44,87,45,89,46,91,47,93,48,95,49,97,50,99,51,101,52,103,53,105,54, + 107,55,109,56,111,57,113,58,115,59,117,60,119,61,121,62,123,63,125, + 64,127,65,129,66,131,67,133,68,135,69,137,70,139,71,141,72,143,73, + 145,74,147,75,149,76,151,77,153,78,155,79,157,80,159,81,161,82,163, + 83,165,84,167,85,169,86,171,87,173,88,175,89,177,0,179,0,181,0,1, + 0,7,2,0,9,9,32,32,2,0,10,10,13,13,4,0,10,10,13,13,34,34,92,92,4, + 0,36,36,65,90,95,95,97,122,5,0,36,36,48,57,65,90,95,95,97,122,1, + 0,48,57,2,0,69,69,101,101,703,0,3,1,0,0,0,0,5,1,0,0,0,0,7,1,0,0, + 0,0,9,1,0,0,0,0,11,1,0,0,0,0,13,1,0,0,0,0,15,1,0,0,0,0,17,1,0,0, + 0,0,19,1,0,0,0,0,21,1,0,0,0,0,23,1,0,0,0,0,25,1,0,0,0,0,27,1,0,0, + 0,0,29,1,0,0,0,0,31,1,0,0,0,0,33,1,0,0,0,0,35,1,0,0,0,0,37,1,0,0, + 0,0,39,1,0,0,0,0,41,1,0,0,0,0,43,1,0,0,0,0,45,1,0,0,0,0,47,1,0,0, + 0,0,49,1,0,0,0,0,51,1,0,0,0,0,53,1,0,0,0,0,55,1,0,0,0,0,57,1,0,0, + 0,0,59,1,0,0,0,0,61,1,0,0,0,0,63,1,0,0,0,0,65,1,0,0,0,0,67,1,0,0, + 0,0,69,1,0,0,0,0,71,1,0,0,0,0,73,1,0,0,0,0,75,1,0,0,0,0,77,1,0,0, + 0,0,79,1,0,0,0,0,81,1,0,0,0,0,83,1,0,0,0,0,85,1,0,0,0,0,87,1,0,0, + 0,0,89,1,0,0,0,0,91,1,0,0,0,0,93,1,0,0,0,0,95,1,0,0,0,0,97,1,0,0, + 0,0,99,1,0,0,0,0,101,1,0,0,0,0,103,1,0,0,0,0,105,1,0,0,0,0,107,1, + 0,0,0,0,109,1,0,0,0,0,111,1,0,0,0,0,113,1,0,0,0,0,115,1,0,0,0,0, + 117,1,0,0,0,0,119,1,0,0,0,0,121,1,0,0,0,0,123,1,0,0,0,0,125,1,0, + 0,0,0,127,1,0,0,0,0,129,1,0,0,0,0,131,1,0,0,0,0,133,1,0,0,0,0,135, + 1,0,0,0,0,137,1,0,0,0,0,139,1,0,0,0,0,141,1,0,0,0,0,143,1,0,0,0, + 0,145,1,0,0,0,0,147,1,0,0,0,0,149,1,0,0,0,0,151,1,0,0,0,0,153,1, + 0,0,0,0,155,1,0,0,0,0,157,1,0,0,0,0,159,1,0,0,0,0,161,1,0,0,0,0, + 163,1,0,0,0,0,165,1,0,0,0,0,167,1,0,0,0,0,169,1,0,0,0,0,171,1,0, + 0,0,0,173,1,0,0,0,0,175,1,0,0,0,1,184,1,0,0,0,3,188,1,0,0,0,5,194, + 1,0,0,0,7,200,1,0,0,0,9,205,1,0,0,0,11,224,1,0,0,0,13,228,1,0,0, + 0,15,236,1,0,0,0,17,241,1,0,0,0,19,248,1,0,0,0,21,256,1,0,0,0,23, + 261,1,0,0,0,25,270,1,0,0,0,27,277,1,0,0,0,29,284,1,0,0,0,31,287, + 1,0,0,0,33,292,1,0,0,0,35,297,1,0,0,0,37,301,1,0,0,0,39,307,1,0, + 0,0,41,310,1,0,0,0,43,315,1,0,0,0,45,319,1,0,0,0,47,323,1,0,0,0, + 49,326,1,0,0,0,51,330,1,0,0,0,53,341,1,0,0,0,55,348,1,0,0,0,57,354, + 1,0,0,0,59,360,1,0,0,0,61,371,1,0,0,0,63,381,1,0,0,0,65,388,1,0, + 0,0,67,398,1,0,0,0,69,404,1,0,0,0,71,411,1,0,0,0,73,422,1,0,0,0, + 75,432,1,0,0,0,77,444,1,0,0,0,79,450,1,0,0,0,81,461,1,0,0,0,83,472, + 1,0,0,0,85,485,1,0,0,0,87,500,1,0,0,0,89,502,1,0,0,0,91,506,1,0, + 0,0,93,508,1,0,0,0,95,510,1,0,0,0,97,512,1,0,0,0,99,514,1,0,0,0, + 101,516,1,0,0,0,103,518,1,0,0,0,105,520,1,0,0,0,107,522,1,0,0,0, + 109,525,1,0,0,0,111,527,1,0,0,0,113,530,1,0,0,0,115,533,1,0,0,0, + 117,536,1,0,0,0,119,539,1,0,0,0,121,541,1,0,0,0,123,543,1,0,0,0, + 125,546,1,0,0,0,127,549,1,0,0,0,129,552,1,0,0,0,131,555,1,0,0,0, + 133,558,1,0,0,0,135,561,1,0,0,0,137,564,1,0,0,0,139,567,1,0,0,0, + 141,570,1,0,0,0,143,572,1,0,0,0,145,574,1,0,0,0,147,576,1,0,0,0, + 149,578,1,0,0,0,151,581,1,0,0,0,153,583,1,0,0,0,155,585,1,0,0,0, + 157,587,1,0,0,0,159,589,1,0,0,0,161,592,1,0,0,0,163,594,1,0,0,0, + 165,596,1,0,0,0,167,616,1,0,0,0,169,618,1,0,0,0,171,643,1,0,0,0, + 173,652,1,0,0,0,175,658,1,0,0,0,177,669,1,0,0,0,179,673,1,0,0,0, + 181,680,1,0,0,0,183,185,5,13,0,0,184,183,1,0,0,0,184,185,1,0,0,0, + 185,186,1,0,0,0,186,187,5,10,0,0,187,2,1,0,0,0,188,189,3,141,70, + 0,189,191,3,1,0,0,190,192,3,5,2,0,191,190,1,0,0,0,191,192,1,0,0, + 0,192,4,1,0,0,0,193,195,7,0,0,0,194,193,1,0,0,0,195,196,1,0,0,0, + 196,194,1,0,0,0,196,197,1,0,0,0,197,198,1,0,0,0,198,199,6,2,0,0, + 199,6,1,0,0,0,200,201,5,92,0,0,201,202,3,1,0,0,202,203,1,0,0,0,203, + 204,6,3,0,0,204,8,1,0,0,0,205,209,5,35,0,0,206,208,8,1,0,0,207,206, + 1,0,0,0,208,211,1,0,0,0,209,207,1,0,0,0,209,210,1,0,0,0,210,212, + 1,0,0,0,211,209,1,0,0,0,212,213,6,4,1,0,213,10,1,0,0,0,214,215,4, + 5,0,0,215,225,3,5,2,0,216,218,5,13,0,0,217,216,1,0,0,0,217,218,1, + 0,0,0,218,219,1,0,0,0,219,220,5,10,0,0,220,222,1,0,0,0,221,223,3, + 5,2,0,222,221,1,0,0,0,222,223,1,0,0,0,223,225,1,0,0,0,224,214,1, + 0,0,0,224,217,1,0,0,0,225,226,1,0,0,0,226,227,6,5,2,0,227,12,1,0, + 0,0,228,229,5,105,0,0,229,230,5,110,0,0,230,231,5,116,0,0,231,232, + 5,101,0,0,232,233,5,103,0,0,233,234,5,101,0,0,234,235,5,114,0,0, + 235,14,1,0,0,0,236,237,5,114,0,0,237,238,5,101,0,0,238,239,5,97, + 0,0,239,240,5,108,0,0,240,16,1,0,0,0,241,242,5,115,0,0,242,243,5, + 116,0,0,243,244,5,114,0,0,244,245,5,105,0,0,245,246,5,110,0,0,246, + 247,5,103,0,0,247,18,1,0,0,0,248,249,5,98,0,0,249,250,5,111,0,0, + 250,251,5,111,0,0,251,252,5,108,0,0,252,253,5,101,0,0,253,254,5, + 97,0,0,254,255,5,110,0,0,255,20,1,0,0,0,256,257,5,118,0,0,257,258, + 5,111,0,0,258,259,5,105,0,0,259,260,5,100,0,0,260,22,1,0,0,0,261, + 262,5,102,0,0,262,263,5,117,0,0,263,264,5,110,0,0,264,265,5,99,0, + 0,265,266,5,116,0,0,266,267,5,105,0,0,267,268,5,111,0,0,268,269, + 5,110,0,0,269,24,1,0,0,0,270,271,5,105,0,0,271,272,5,110,0,0,272, + 273,5,108,0,0,273,274,5,105,0,0,274,275,5,110,0,0,275,276,5,101, + 0,0,276,26,1,0,0,0,277,278,5,114,0,0,278,279,5,101,0,0,279,280,5, + 116,0,0,280,281,5,117,0,0,281,282,5,114,0,0,282,283,5,110,0,0,283, + 28,1,0,0,0,284,285,5,105,0,0,285,286,5,102,0,0,286,30,1,0,0,0,287, + 288,5,101,0,0,288,289,5,108,0,0,289,290,5,105,0,0,290,291,5,102, + 0,0,291,32,1,0,0,0,292,293,5,101,0,0,293,294,5,108,0,0,294,295,5, + 115,0,0,295,296,5,101,0,0,296,34,1,0,0,0,297,298,5,102,0,0,298,299, + 5,111,0,0,299,300,5,114,0,0,300,36,1,0,0,0,301,302,5,119,0,0,302, + 303,5,104,0,0,303,304,5,105,0,0,304,305,5,108,0,0,305,306,5,101, + 0,0,306,38,1,0,0,0,307,308,5,105,0,0,308,309,5,110,0,0,309,40,1, + 0,0,0,310,311,5,115,0,0,311,312,5,116,0,0,312,313,5,101,0,0,313, + 314,5,112,0,0,314,42,1,0,0,0,315,316,5,105,0,0,316,317,5,110,0,0, + 317,318,5,102,0,0,318,44,1,0,0,0,319,320,5,97,0,0,320,321,5,110, + 0,0,321,322,5,100,0,0,322,46,1,0,0,0,323,324,5,111,0,0,324,325,5, + 114,0,0,325,48,1,0,0,0,326,327,5,110,0,0,327,328,5,111,0,0,328,329, + 5,116,0,0,329,50,1,0,0,0,330,331,5,114,0,0,331,332,5,101,0,0,332, + 333,5,99,0,0,333,334,5,111,0,0,334,335,5,114,0,0,335,336,5,100,0, + 0,336,337,5,97,0,0,337,338,5,98,0,0,338,339,5,108,0,0,339,340,5, + 101,0,0,340,52,1,0,0,0,341,342,5,107,0,0,342,343,5,101,0,0,343,344, + 5,114,0,0,344,345,5,110,0,0,345,346,5,101,0,0,346,347,5,108,0,0, + 347,54,1,0,0,0,348,349,5,109,0,0,349,350,5,111,0,0,350,351,5,100, + 0,0,351,352,5,101,0,0,352,353,5,108,0,0,353,56,1,0,0,0,354,355,5, + 115,0,0,355,356,5,116,0,0,356,357,5,97,0,0,357,358,5,116,0,0,358, + 359,5,101,0,0,359,58,1,0,0,0,360,361,5,112,0,0,361,362,5,97,0,0, + 362,363,5,114,0,0,363,364,5,97,0,0,364,365,5,109,0,0,365,366,5,101, + 0,0,366,367,5,116,0,0,367,368,5,101,0,0,368,369,5,114,0,0,369,370, + 5,115,0,0,370,60,1,0,0,0,371,372,5,105,0,0,372,373,5,110,0,0,373, + 374,5,116,0,0,374,375,5,101,0,0,375,376,5,114,0,0,376,377,5,110, + 0,0,377,378,5,97,0,0,378,379,5,108,0,0,379,380,5,115,0,0,380,62, + 1,0,0,0,381,382,5,117,0,0,382,383,5,112,0,0,383,384,5,100,0,0,384, + 385,5,97,0,0,385,386,5,116,0,0,386,387,5,101,0,0,387,64,1,0,0,0, + 388,389,5,101,0,0,389,390,5,113,0,0,390,391,5,117,0,0,391,392,5, + 97,0,0,392,393,5,116,0,0,393,394,5,105,0,0,394,395,5,111,0,0,395, + 396,5,110,0,0,396,397,5,115,0,0,397,66,1,0,0,0,398,399,5,105,0,0, + 399,400,5,110,0,0,400,401,5,112,0,0,401,402,5,117,0,0,402,403,5, + 116,0,0,403,68,1,0,0,0,404,405,5,111,0,0,405,406,5,117,0,0,406,407, + 5,116,0,0,407,408,5,112,0,0,408,409,5,117,0,0,409,410,5,116,0,0, + 410,70,1,0,0,0,411,412,5,99,0,0,412,413,5,111,0,0,413,414,5,110, + 0,0,414,415,5,116,0,0,415,416,5,105,0,0,416,417,5,110,0,0,417,418, + 5,117,0,0,418,419,5,111,0,0,419,420,5,117,0,0,420,421,5,115,0,0, + 421,72,1,0,0,0,422,423,5,111,0,0,423,424,5,110,0,0,424,425,5,82, + 0,0,425,426,5,101,0,0,426,427,5,99,0,0,427,428,5,101,0,0,428,429, + 5,105,0,0,429,430,5,118,0,0,430,431,5,101,0,0,431,74,1,0,0,0,432, + 433,5,111,0,0,433,434,5,110,0,0,434,435,5,67,0,0,435,436,5,111,0, + 0,436,437,5,110,0,0,437,438,5,100,0,0,438,439,5,105,0,0,439,440, + 5,116,0,0,440,441,5,105,0,0,441,442,5,111,0,0,442,443,5,110,0,0, + 443,76,1,0,0,0,444,445,5,115,0,0,445,446,5,112,0,0,446,447,5,105, + 0,0,447,448,5,107,0,0,448,449,5,101,0,0,449,78,1,0,0,0,450,451,5, + 105,0,0,451,452,5,110,0,0,452,453,5,104,0,0,453,454,5,105,0,0,454, + 455,5,98,0,0,455,456,5,105,0,0,456,457,5,116,0,0,457,458,5,111,0, + 0,458,459,5,114,0,0,459,460,5,121,0,0,460,80,1,0,0,0,461,462,5,101, + 0,0,462,463,5,120,0,0,463,464,5,99,0,0,464,465,5,105,0,0,465,466, + 5,116,0,0,466,467,5,97,0,0,467,468,5,116,0,0,468,469,5,111,0,0,469, + 470,5,114,0,0,470,471,5,121,0,0,471,82,1,0,0,0,472,473,5,64,0,0, + 473,474,5,104,0,0,474,475,5,111,0,0,475,476,5,109,0,0,476,477,5, + 111,0,0,477,478,5,103,0,0,478,479,5,101,0,0,479,480,5,110,0,0,480, + 481,5,101,0,0,481,482,5,111,0,0,482,483,5,117,0,0,483,484,5,115, + 0,0,484,84,1,0,0,0,485,486,5,64,0,0,486,487,5,104,0,0,487,488,5, + 101,0,0,488,489,5,116,0,0,489,490,5,101,0,0,490,491,5,114,0,0,491, + 492,5,111,0,0,492,493,5,103,0,0,493,494,5,101,0,0,494,495,5,110, + 0,0,495,496,5,101,0,0,496,497,5,111,0,0,497,498,5,117,0,0,498,499, + 5,115,0,0,499,86,1,0,0,0,500,501,5,64,0,0,501,88,1,0,0,0,502,503, + 5,46,0,0,503,504,5,46,0,0,504,505,5,46,0,0,505,90,1,0,0,0,506,507, + 5,40,0,0,507,92,1,0,0,0,508,509,5,41,0,0,509,94,1,0,0,0,510,511, + 5,43,0,0,511,96,1,0,0,0,512,513,5,126,0,0,513,98,1,0,0,0,514,515, + 5,124,0,0,515,100,1,0,0,0,516,517,5,94,0,0,517,102,1,0,0,0,518,519, + 5,38,0,0,519,104,1,0,0,0,520,521,5,91,0,0,521,106,1,0,0,0,522,523, + 5,60,0,0,523,524,5,45,0,0,524,108,1,0,0,0,525,526,5,93,0,0,526,110, + 1,0,0,0,527,528,5,91,0,0,528,529,5,91,0,0,529,112,1,0,0,0,530,531, + 5,93,0,0,531,532,5,93,0,0,532,114,1,0,0,0,533,534,5,60,0,0,534,535, + 5,60,0,0,535,116,1,0,0,0,536,537,5,62,0,0,537,538,5,62,0,0,538,118, + 1,0,0,0,539,540,5,60,0,0,540,120,1,0,0,0,541,542,5,62,0,0,542,122, + 1,0,0,0,543,544,5,60,0,0,544,545,5,61,0,0,545,124,1,0,0,0,546,547, + 5,43,0,0,547,548,5,61,0,0,548,126,1,0,0,0,549,550,5,45,0,0,550,551, + 5,61,0,0,551,128,1,0,0,0,552,553,5,42,0,0,553,554,5,61,0,0,554,130, + 1,0,0,0,555,556,5,47,0,0,556,557,5,61,0,0,557,132,1,0,0,0,558,559, + 5,61,0,0,559,560,5,61,0,0,560,134,1,0,0,0,561,562,5,33,0,0,562,563, + 5,61,0,0,563,136,1,0,0,0,564,565,5,60,0,0,565,566,5,62,0,0,566,138, + 1,0,0,0,567,568,5,62,0,0,568,569,5,61,0,0,569,140,1,0,0,0,570,571, + 5,44,0,0,571,142,1,0,0,0,572,573,5,45,0,0,573,144,1,0,0,0,574,575, + 5,61,0,0,575,146,1,0,0,0,576,577,5,42,0,0,577,148,1,0,0,0,578,579, + 5,42,0,0,579,580,5,42,0,0,580,150,1,0,0,0,581,582,5,47,0,0,582,152, + 1,0,0,0,583,584,5,37,0,0,584,154,1,0,0,0,585,586,5,63,0,0,586,156, + 1,0,0,0,587,588,5,58,0,0,588,158,1,0,0,0,589,590,5,58,0,0,590,591, + 5,58,0,0,591,160,1,0,0,0,592,593,5,59,0,0,593,162,1,0,0,0,594,595, + 5,39,0,0,595,164,1,0,0,0,596,597,5,46,0,0,597,166,1,0,0,0,598,599, + 5,116,0,0,599,600,5,114,0,0,600,601,5,117,0,0,601,617,5,101,0,0, + 602,603,5,84,0,0,603,604,5,114,0,0,604,605,5,117,0,0,605,617,5,101, + 0,0,606,607,5,102,0,0,607,608,5,97,0,0,608,609,5,108,0,0,609,610, + 5,115,0,0,610,617,5,101,0,0,611,612,5,70,0,0,612,613,5,97,0,0,613, + 614,5,108,0,0,614,615,5,115,0,0,615,617,5,101,0,0,616,598,1,0,0, + 0,616,602,1,0,0,0,616,606,1,0,0,0,616,611,1,0,0,0,617,168,1,0,0, + 0,618,637,5,34,0,0,619,632,5,92,0,0,620,622,7,0,0,0,621,620,1,0, + 0,0,622,623,1,0,0,0,623,621,1,0,0,0,623,624,1,0,0,0,624,629,1,0, + 0,0,625,627,5,13,0,0,626,625,1,0,0,0,626,627,1,0,0,0,627,628,1,0, + 0,0,628,630,5,10,0,0,629,626,1,0,0,0,629,630,1,0,0,0,630,633,1,0, + 0,0,631,633,9,0,0,0,632,621,1,0,0,0,632,631,1,0,0,0,633,636,1,0, + 0,0,634,636,8,2,0,0,635,619,1,0,0,0,635,634,1,0,0,0,636,639,1,0, + 0,0,637,635,1,0,0,0,637,638,1,0,0,0,638,640,1,0,0,0,639,637,1,0, + 0,0,640,641,5,34,0,0,641,170,1,0,0,0,642,644,7,3,0,0,643,642,1,0, + 0,0,644,648,1,0,0,0,645,647,7,4,0,0,646,645,1,0,0,0,647,650,1,0, + 0,0,648,646,1,0,0,0,648,649,1,0,0,0,649,172,1,0,0,0,650,648,1,0, + 0,0,651,653,7,5,0,0,652,651,1,0,0,0,653,654,1,0,0,0,654,652,1,0, + 0,0,654,655,1,0,0,0,655,174,1,0,0,0,656,659,3,177,88,0,657,659,3, + 179,89,0,658,656,1,0,0,0,658,657,1,0,0,0,659,176,1,0,0,0,660,662, + 3,173,86,0,661,660,1,0,0,0,661,662,1,0,0,0,662,663,1,0,0,0,663,664, + 3,165,82,0,664,665,3,173,86,0,665,670,1,0,0,0,666,667,3,173,86,0, + 667,668,3,165,82,0,668,670,1,0,0,0,669,661,1,0,0,0,669,666,1,0,0, + 0,670,178,1,0,0,0,671,674,3,173,86,0,672,674,3,177,88,0,673,671, + 1,0,0,0,673,672,1,0,0,0,674,675,1,0,0,0,675,676,7,6,0,0,676,677, + 3,181,90,0,677,180,1,0,0,0,678,681,3,95,47,0,679,681,3,143,71,0, + 680,678,1,0,0,0,680,679,1,0,0,0,680,681,1,0,0,0,681,682,1,0,0,0, + 682,683,3,173,86,0,683,182,1,0,0,0,24,0,184,191,196,209,217,222, + 224,616,623,626,629,632,635,637,643,646,648,654,658,661,669,673, + 680,3,0,1,0,0,2,0,1,5,0 ] class PyNestMLLexer(PyNestMLLexerBase): @@ -279,157 +271,154 @@ class PyNestMLLexer(PyNestMLLexerBase): INDENT = 1 DEDENT = 2 - DOCSTRING_TRIPLEQUOTE = 3 - KERNEL_JOINING = 4 - WS = 5 - LINE_ESCAPE = 6 - DOCSTRING = 7 - SL_COMMENT = 8 - NEWLINE = 9 - INTEGER_KEYWORD = 10 - REAL_KEYWORD = 11 - STRING_KEYWORD = 12 - BOOLEAN_KEYWORD = 13 - VOID_KEYWORD = 14 - FUNCTION_KEYWORD = 15 - INLINE_KEYWORD = 16 - RETURN_KEYWORD = 17 - IF_KEYWORD = 18 - ELIF_KEYWORD = 19 - ELSE_KEYWORD = 20 - FOR_KEYWORD = 21 - WHILE_KEYWORD = 22 - IN_KEYWORD = 23 - STEP_KEYWORD = 24 - INF_KEYWORD = 25 - AND_KEYWORD = 26 - OR_KEYWORD = 27 - NOT_KEYWORD = 28 - RECORDABLE_KEYWORD = 29 - KERNEL_KEYWORD = 30 - MODEL_KEYWORD = 31 - STATE_KEYWORD = 32 - PARAMETERS_KEYWORD = 33 - INTERNALS_KEYWORD = 34 - UPDATE_KEYWORD = 35 - EQUATIONS_KEYWORD = 36 - INPUT_KEYWORD = 37 - OUTPUT_KEYWORD = 38 - CONTINUOUS_KEYWORD = 39 - ON_RECEIVE_KEYWORD = 40 - ON_CONDITION_KEYWORD = 41 - SPIKE_KEYWORD = 42 - INHIBITORY_KEYWORD = 43 - EXCITATORY_KEYWORD = 44 - DECORATOR_HOMOGENEOUS = 45 - DECORATOR_HETEROGENEOUS = 46 - AT = 47 - ELLIPSIS = 48 - LEFT_PAREN = 49 - RIGHT_PAREN = 50 - PLUS = 51 - TILDE = 52 - PIPE = 53 - CARET = 54 - AMPERSAND = 55 - LEFT_SQUARE_BRACKET = 56 - LEFT_ANGLE_MINUS = 57 - RIGHT_SQUARE_BRACKET = 58 - LEFT_LEFT_SQUARE = 59 - RIGHT_RIGHT_SQUARE = 60 - LEFT_LEFT_ANGLE = 61 - RIGHT_RIGHT_ANGLE = 62 - LEFT_ANGLE = 63 - RIGHT_ANGLE = 64 - LEFT_ANGLE_EQUALS = 65 - PLUS_EQUALS = 66 - MINUS_EQUALS = 67 - STAR_EQUALS = 68 - FORWARD_SLASH_EQUALS = 69 - EQUALS_EQUALS = 70 - EXCLAMATION_EQUALS = 71 - LEFT_ANGLE_RIGHT_ANGLE = 72 - RIGHT_ANGLE_EQUALS = 73 - COMMA = 74 - MINUS = 75 - EQUALS = 76 - STAR = 77 - STAR_STAR = 78 - FORWARD_SLASH = 79 - PERCENT = 80 - QUESTION = 81 - COLON = 82 - DOUBLE_COLON = 83 - SEMICOLON = 84 - DIFFERENTIAL_ORDER = 85 - FULLSTOP = 86 - BOOLEAN_LITERAL = 87 - STRING_LITERAL = 88 - NAME = 89 - UNSIGNED_INTEGER = 90 - FLOAT = 91 + KERNEL_JOINING = 3 + WS = 4 + LINE_ESCAPE = 5 + SL_COMMENT = 6 + NEWLINE = 7 + INTEGER_KEYWORD = 8 + REAL_KEYWORD = 9 + STRING_KEYWORD = 10 + BOOLEAN_KEYWORD = 11 + VOID_KEYWORD = 12 + FUNCTION_KEYWORD = 13 + INLINE_KEYWORD = 14 + RETURN_KEYWORD = 15 + IF_KEYWORD = 16 + ELIF_KEYWORD = 17 + ELSE_KEYWORD = 18 + FOR_KEYWORD = 19 + WHILE_KEYWORD = 20 + IN_KEYWORD = 21 + STEP_KEYWORD = 22 + INF_KEYWORD = 23 + AND_KEYWORD = 24 + OR_KEYWORD = 25 + NOT_KEYWORD = 26 + RECORDABLE_KEYWORD = 27 + KERNEL_KEYWORD = 28 + MODEL_KEYWORD = 29 + STATE_KEYWORD = 30 + PARAMETERS_KEYWORD = 31 + INTERNALS_KEYWORD = 32 + UPDATE_KEYWORD = 33 + EQUATIONS_KEYWORD = 34 + INPUT_KEYWORD = 35 + OUTPUT_KEYWORD = 36 + CONTINUOUS_KEYWORD = 37 + ON_RECEIVE_KEYWORD = 38 + ON_CONDITION_KEYWORD = 39 + SPIKE_KEYWORD = 40 + INHIBITORY_KEYWORD = 41 + EXCITATORY_KEYWORD = 42 + DECORATOR_HOMOGENEOUS = 43 + DECORATOR_HETEROGENEOUS = 44 + AT = 45 + ELLIPSIS = 46 + LEFT_PAREN = 47 + RIGHT_PAREN = 48 + PLUS = 49 + TILDE = 50 + PIPE = 51 + CARET = 52 + AMPERSAND = 53 + LEFT_SQUARE_BRACKET = 54 + LEFT_ANGLE_MINUS = 55 + RIGHT_SQUARE_BRACKET = 56 + LEFT_LEFT_SQUARE = 57 + RIGHT_RIGHT_SQUARE = 58 + LEFT_LEFT_ANGLE = 59 + RIGHT_RIGHT_ANGLE = 60 + LEFT_ANGLE = 61 + RIGHT_ANGLE = 62 + LEFT_ANGLE_EQUALS = 63 + PLUS_EQUALS = 64 + MINUS_EQUALS = 65 + STAR_EQUALS = 66 + FORWARD_SLASH_EQUALS = 67 + EQUALS_EQUALS = 68 + EXCLAMATION_EQUALS = 69 + LEFT_ANGLE_RIGHT_ANGLE = 70 + RIGHT_ANGLE_EQUALS = 71 + COMMA = 72 + MINUS = 73 + EQUALS = 74 + STAR = 75 + STAR_STAR = 76 + FORWARD_SLASH = 77 + PERCENT = 78 + QUESTION = 79 + COLON = 80 + DOUBLE_COLON = 81 + SEMICOLON = 82 + DIFFERENTIAL_ORDER = 83 + FULLSTOP = 84 + BOOLEAN_LITERAL = 85 + STRING_LITERAL = 86 + NAME = 87 + UNSIGNED_INTEGER = 88 + FLOAT = 89 channelNames = [ u"DEFAULT_TOKEN_CHANNEL", u"HIDDEN", u"COMMENT" ] modeNames = [ "DEFAULT_MODE" ] literalNames = [ "", - "'\"\"\"'", "'integer'", "'real'", "'string'", "'boolean'", - "'void'", "'function'", "'inline'", "'return'", "'if'", "'elif'", - "'else'", "'for'", "'while'", "'in'", "'step'", "'inf'", "'and'", - "'or'", "'not'", "'recordable'", "'kernel'", "'model'", "'state'", - "'parameters'", "'internals'", "'update'", "'equations'", "'input'", - "'output'", "'continuous'", "'onReceive'", "'onCondition'", - "'spike'", "'inhibitory'", "'excitatory'", "'@homogeneous'", - "'@heterogeneous'", "'@'", "'...'", "'('", "')'", "'+'", "'~'", - "'|'", "'^'", "'&'", "'['", "'<-'", "']'", "'[['", "']]'", "'<<'", - "'>>'", "'<'", "'>'", "'<='", "'+='", "'-='", "'*='", "'/='", - "'=='", "'!='", "'<>'", "'>='", "','", "'-'", "'='", "'*'", - "'**'", "'/'", "'%'", "'?'", "':'", "'::'", "';'", "'''", "'.'" ] + "'integer'", "'real'", "'string'", "'boolean'", "'void'", "'function'", + "'inline'", "'return'", "'if'", "'elif'", "'else'", "'for'", + "'while'", "'in'", "'step'", "'inf'", "'and'", "'or'", "'not'", + "'recordable'", "'kernel'", "'model'", "'state'", "'parameters'", + "'internals'", "'update'", "'equations'", "'input'", "'output'", + "'continuous'", "'onReceive'", "'onCondition'", "'spike'", "'inhibitory'", + "'excitatory'", "'@homogeneous'", "'@heterogeneous'", "'@'", + "'...'", "'('", "')'", "'+'", "'~'", "'|'", "'^'", "'&'", "'['", + "'<-'", "']'", "'[['", "']]'", "'<<'", "'>>'", "'<'", "'>'", + "'<='", "'+='", "'-='", "'*='", "'/='", "'=='", "'!='", "'<>'", + "'>='", "','", "'-'", "'='", "'*'", "'**'", "'/'", "'%'", "'?'", + "':'", "'::'", "';'", "'''", "'.'" ] symbolicNames = [ "", - "INDENT", "DEDENT", "DOCSTRING_TRIPLEQUOTE", "KERNEL_JOINING", - "WS", "LINE_ESCAPE", "DOCSTRING", "SL_COMMENT", "NEWLINE", "INTEGER_KEYWORD", - "REAL_KEYWORD", "STRING_KEYWORD", "BOOLEAN_KEYWORD", "VOID_KEYWORD", - "FUNCTION_KEYWORD", "INLINE_KEYWORD", "RETURN_KEYWORD", "IF_KEYWORD", - "ELIF_KEYWORD", "ELSE_KEYWORD", "FOR_KEYWORD", "WHILE_KEYWORD", - "IN_KEYWORD", "STEP_KEYWORD", "INF_KEYWORD", "AND_KEYWORD", - "OR_KEYWORD", "NOT_KEYWORD", "RECORDABLE_KEYWORD", "KERNEL_KEYWORD", - "MODEL_KEYWORD", "STATE_KEYWORD", "PARAMETERS_KEYWORD", "INTERNALS_KEYWORD", - "UPDATE_KEYWORD", "EQUATIONS_KEYWORD", "INPUT_KEYWORD", "OUTPUT_KEYWORD", - "CONTINUOUS_KEYWORD", "ON_RECEIVE_KEYWORD", "ON_CONDITION_KEYWORD", - "SPIKE_KEYWORD", "INHIBITORY_KEYWORD", "EXCITATORY_KEYWORD", - "DECORATOR_HOMOGENEOUS", "DECORATOR_HETEROGENEOUS", "AT", "ELLIPSIS", - "LEFT_PAREN", "RIGHT_PAREN", "PLUS", "TILDE", "PIPE", "CARET", - "AMPERSAND", "LEFT_SQUARE_BRACKET", "LEFT_ANGLE_MINUS", "RIGHT_SQUARE_BRACKET", - "LEFT_LEFT_SQUARE", "RIGHT_RIGHT_SQUARE", "LEFT_LEFT_ANGLE", - "RIGHT_RIGHT_ANGLE", "LEFT_ANGLE", "RIGHT_ANGLE", "LEFT_ANGLE_EQUALS", - "PLUS_EQUALS", "MINUS_EQUALS", "STAR_EQUALS", "FORWARD_SLASH_EQUALS", - "EQUALS_EQUALS", "EXCLAMATION_EQUALS", "LEFT_ANGLE_RIGHT_ANGLE", - "RIGHT_ANGLE_EQUALS", "COMMA", "MINUS", "EQUALS", "STAR", "STAR_STAR", - "FORWARD_SLASH", "PERCENT", "QUESTION", "COLON", "DOUBLE_COLON", - "SEMICOLON", "DIFFERENTIAL_ORDER", "FULLSTOP", "BOOLEAN_LITERAL", - "STRING_LITERAL", "NAME", "UNSIGNED_INTEGER", "FLOAT" ] + "INDENT", "DEDENT", "KERNEL_JOINING", "WS", "LINE_ESCAPE", "SL_COMMENT", + "NEWLINE", "INTEGER_KEYWORD", "REAL_KEYWORD", "STRING_KEYWORD", + "BOOLEAN_KEYWORD", "VOID_KEYWORD", "FUNCTION_KEYWORD", "INLINE_KEYWORD", + "RETURN_KEYWORD", "IF_KEYWORD", "ELIF_KEYWORD", "ELSE_KEYWORD", + "FOR_KEYWORD", "WHILE_KEYWORD", "IN_KEYWORD", "STEP_KEYWORD", + "INF_KEYWORD", "AND_KEYWORD", "OR_KEYWORD", "NOT_KEYWORD", "RECORDABLE_KEYWORD", + "KERNEL_KEYWORD", "MODEL_KEYWORD", "STATE_KEYWORD", "PARAMETERS_KEYWORD", + "INTERNALS_KEYWORD", "UPDATE_KEYWORD", "EQUATIONS_KEYWORD", + "INPUT_KEYWORD", "OUTPUT_KEYWORD", "CONTINUOUS_KEYWORD", "ON_RECEIVE_KEYWORD", + "ON_CONDITION_KEYWORD", "SPIKE_KEYWORD", "INHIBITORY_KEYWORD", + "EXCITATORY_KEYWORD", "DECORATOR_HOMOGENEOUS", "DECORATOR_HETEROGENEOUS", + "AT", "ELLIPSIS", "LEFT_PAREN", "RIGHT_PAREN", "PLUS", "TILDE", + "PIPE", "CARET", "AMPERSAND", "LEFT_SQUARE_BRACKET", "LEFT_ANGLE_MINUS", + "RIGHT_SQUARE_BRACKET", "LEFT_LEFT_SQUARE", "RIGHT_RIGHT_SQUARE", + "LEFT_LEFT_ANGLE", "RIGHT_RIGHT_ANGLE", "LEFT_ANGLE", "RIGHT_ANGLE", + "LEFT_ANGLE_EQUALS", "PLUS_EQUALS", "MINUS_EQUALS", "STAR_EQUALS", + "FORWARD_SLASH_EQUALS", "EQUALS_EQUALS", "EXCLAMATION_EQUALS", + "LEFT_ANGLE_RIGHT_ANGLE", "RIGHT_ANGLE_EQUALS", "COMMA", "MINUS", + "EQUALS", "STAR", "STAR_STAR", "FORWARD_SLASH", "PERCENT", "QUESTION", + "COLON", "DOUBLE_COLON", "SEMICOLON", "DIFFERENTIAL_ORDER", + "FULLSTOP", "BOOLEAN_LITERAL", "STRING_LITERAL", "NAME", "UNSIGNED_INTEGER", + "FLOAT" ] - ruleNames = [ "DOCSTRING_TRIPLEQUOTE", "NEWLINE_FRAG", "KERNEL_JOINING", - "WS", "LINE_ESCAPE", "DOCSTRING", "SL_COMMENT", "NEWLINE", - "INTEGER_KEYWORD", "REAL_KEYWORD", "STRING_KEYWORD", "BOOLEAN_KEYWORD", - "VOID_KEYWORD", "FUNCTION_KEYWORD", "INLINE_KEYWORD", - "RETURN_KEYWORD", "IF_KEYWORD", "ELIF_KEYWORD", "ELSE_KEYWORD", - "FOR_KEYWORD", "WHILE_KEYWORD", "IN_KEYWORD", "STEP_KEYWORD", - "INF_KEYWORD", "AND_KEYWORD", "OR_KEYWORD", "NOT_KEYWORD", - "RECORDABLE_KEYWORD", "KERNEL_KEYWORD", "MODEL_KEYWORD", - "STATE_KEYWORD", "PARAMETERS_KEYWORD", "INTERNALS_KEYWORD", - "UPDATE_KEYWORD", "EQUATIONS_KEYWORD", "INPUT_KEYWORD", - "OUTPUT_KEYWORD", "CONTINUOUS_KEYWORD", "ON_RECEIVE_KEYWORD", - "ON_CONDITION_KEYWORD", "SPIKE_KEYWORD", "INHIBITORY_KEYWORD", - "EXCITATORY_KEYWORD", "DECORATOR_HOMOGENEOUS", "DECORATOR_HETEROGENEOUS", - "AT", "ELLIPSIS", "LEFT_PAREN", "RIGHT_PAREN", "PLUS", - "TILDE", "PIPE", "CARET", "AMPERSAND", "LEFT_SQUARE_BRACKET", - "LEFT_ANGLE_MINUS", "RIGHT_SQUARE_BRACKET", "LEFT_LEFT_SQUARE", - "RIGHT_RIGHT_SQUARE", "LEFT_LEFT_ANGLE", "RIGHT_RIGHT_ANGLE", - "LEFT_ANGLE", "RIGHT_ANGLE", "LEFT_ANGLE_EQUALS", "PLUS_EQUALS", - "MINUS_EQUALS", "STAR_EQUALS", "FORWARD_SLASH_EQUALS", + ruleNames = [ "NEWLINE_FRAG", "KERNEL_JOINING", "WS", "LINE_ESCAPE", + "SL_COMMENT", "NEWLINE", "INTEGER_KEYWORD", "REAL_KEYWORD", + "STRING_KEYWORD", "BOOLEAN_KEYWORD", "VOID_KEYWORD", "FUNCTION_KEYWORD", + "INLINE_KEYWORD", "RETURN_KEYWORD", "IF_KEYWORD", "ELIF_KEYWORD", + "ELSE_KEYWORD", "FOR_KEYWORD", "WHILE_KEYWORD", "IN_KEYWORD", + "STEP_KEYWORD", "INF_KEYWORD", "AND_KEYWORD", "OR_KEYWORD", + "NOT_KEYWORD", "RECORDABLE_KEYWORD", "KERNEL_KEYWORD", + "MODEL_KEYWORD", "STATE_KEYWORD", "PARAMETERS_KEYWORD", + "INTERNALS_KEYWORD", "UPDATE_KEYWORD", "EQUATIONS_KEYWORD", + "INPUT_KEYWORD", "OUTPUT_KEYWORD", "CONTINUOUS_KEYWORD", + "ON_RECEIVE_KEYWORD", "ON_CONDITION_KEYWORD", "SPIKE_KEYWORD", + "INHIBITORY_KEYWORD", "EXCITATORY_KEYWORD", "DECORATOR_HOMOGENEOUS", + "DECORATOR_HETEROGENEOUS", "AT", "ELLIPSIS", "LEFT_PAREN", + "RIGHT_PAREN", "PLUS", "TILDE", "PIPE", "CARET", "AMPERSAND", + "LEFT_SQUARE_BRACKET", "LEFT_ANGLE_MINUS", "RIGHT_SQUARE_BRACKET", + "LEFT_LEFT_SQUARE", "RIGHT_RIGHT_SQUARE", "LEFT_LEFT_ANGLE", + "RIGHT_RIGHT_ANGLE", "LEFT_ANGLE", "RIGHT_ANGLE", "LEFT_ANGLE_EQUALS", + "PLUS_EQUALS", "MINUS_EQUALS", "STAR_EQUALS", "FORWARD_SLASH_EQUALS", "EQUALS_EQUALS", "EXCLAMATION_EQUALS", "LEFT_ANGLE_RIGHT_ANGLE", "RIGHT_ANGLE_EQUALS", "COMMA", "MINUS", "EQUALS", "STAR", "STAR_STAR", "FORWARD_SLASH", "PERCENT", "QUESTION", "COLON", @@ -450,7 +439,7 @@ def __init__(self, input=None, output:TextIO = sys.stdout): def action(self, localctx:RuleContext, ruleIndex:int, actionIndex:int): if self._actions is None: actions = dict() - actions[7] = self.NEWLINE_action + actions[5] = self.NEWLINE_action self._actions = actions action = self._actions.get(ruleIndex, None) if action is not None: @@ -467,7 +456,7 @@ def NEWLINE_action(self, localctx:RuleContext , actionIndex:int): def sempred(self, localctx:RuleContext, ruleIndex:int, predIndex:int): if self._predicates is None: preds = dict() - preds[7] = self.NEWLINE_sempred + preds[5] = self.NEWLINE_sempred self._predicates = preds pred = self._predicates.get(ruleIndex, None) if pred is not None: diff --git a/pynestml/generated/PyNestMLParser.py b/pynestml/generated/PyNestMLParser.py index dc2a43d73..6477d25b0 100644 --- a/pynestml/generated/PyNestMLParser.py +++ b/pynestml/generated/PyNestMLParser.py @@ -10,7 +10,7 @@ def serializedATN(): return [ - 4,1,91,657,2,0,7,0,2,1,7,1,2,2,7,2,2,3,7,3,2,4,7,4,2,5,7,5,2,6,7, + 4,1,89,657,2,0,7,0,2,1,7,1,2,2,7,2,2,3,7,3,2,4,7,4,2,5,7,5,2,6,7, 6,2,7,7,7,2,8,7,8,2,9,7,9,2,10,7,10,2,11,7,11,2,12,7,12,2,13,7,13, 2,14,7,14,2,15,7,15,2,16,7,16,2,17,7,17,2,18,7,18,2,19,7,19,2,20, 7,20,2,21,7,21,2,22,7,22,2,23,7,23,2,24,7,24,2,25,7,25,2,26,7,26, @@ -67,7 +67,7 @@ def serializedATN(): 1,44,1,45,1,45,1,45,1,46,1,46,1,46,1,46,1,46,0,2,2,12,47,0,2,4,6, 8,10,12,14,16,18,20,22,24,26,28,30,32,34,36,38,40,42,44,46,48,50, 52,54,56,58,60,62,64,66,68,70,72,74,76,78,80,82,84,86,88,90,92,0, - 4,2,0,51,51,75,75,1,0,90,91,1,0,32,34,3,0,25,25,87,88,90,91,720, + 4,2,0,49,49,73,73,1,0,88,89,1,0,30,32,3,0,23,23,85,86,88,89,720, 0,100,1,0,0,0,2,111,1,0,0,0,4,128,1,0,0,0,6,139,1,0,0,0,8,141,1, 0,0,0,10,143,1,0,0,0,12,156,1,0,0,0,14,206,1,0,0,0,16,211,1,0,0, 0,18,218,1,0,0,0,20,227,1,0,0,0,22,231,1,0,0,0,24,233,1,0,0,0,26, @@ -78,177 +78,177 @@ def serializedATN(): 1,0,0,0,62,448,1,0,0,0,64,454,1,0,0,0,66,459,1,0,0,0,68,475,1,0, 0,0,70,492,1,0,0,0,72,509,1,0,0,0,74,520,1,0,0,0,76,527,1,0,0,0, 78,540,1,0,0,0,80,568,1,0,0,0,82,585,1,0,0,0,84,599,1,0,0,0,86,601, - 1,0,0,0,88,626,1,0,0,0,90,649,1,0,0,0,92,652,1,0,0,0,94,101,5,10, - 0,0,95,101,5,11,0,0,96,101,5,12,0,0,97,101,5,13,0,0,98,101,5,14, - 0,0,99,101,3,2,1,0,100,94,1,0,0,0,100,95,1,0,0,0,100,96,1,0,0,0, - 100,97,1,0,0,0,100,98,1,0,0,0,100,99,1,0,0,0,101,1,1,0,0,0,102,103, - 6,1,-1,0,103,104,5,49,0,0,104,105,3,2,1,0,105,106,5,50,0,0,106,112, - 1,0,0,0,107,108,5,90,0,0,108,109,5,79,0,0,109,112,3,2,1,2,110,112, - 5,89,0,0,111,102,1,0,0,0,111,107,1,0,0,0,111,110,1,0,0,0,112,124, - 1,0,0,0,113,116,10,3,0,0,114,117,5,77,0,0,115,117,5,79,0,0,116,114, + 1,0,0,0,88,626,1,0,0,0,90,649,1,0,0,0,92,652,1,0,0,0,94,101,5,8, + 0,0,95,101,5,9,0,0,96,101,5,10,0,0,97,101,5,11,0,0,98,101,5,12,0, + 0,99,101,3,2,1,0,100,94,1,0,0,0,100,95,1,0,0,0,100,96,1,0,0,0,100, + 97,1,0,0,0,100,98,1,0,0,0,100,99,1,0,0,0,101,1,1,0,0,0,102,103,6, + 1,-1,0,103,104,5,47,0,0,104,105,3,2,1,0,105,106,5,48,0,0,106,112, + 1,0,0,0,107,108,5,88,0,0,108,109,5,77,0,0,109,112,3,2,1,2,110,112, + 5,87,0,0,111,102,1,0,0,0,111,107,1,0,0,0,111,110,1,0,0,0,112,124, + 1,0,0,0,113,116,10,3,0,0,114,117,5,75,0,0,115,117,5,77,0,0,116,114, 1,0,0,0,116,115,1,0,0,0,117,118,1,0,0,0,118,123,3,2,1,4,119,120, - 10,4,0,0,120,121,5,78,0,0,121,123,3,4,2,0,122,113,1,0,0,0,122,119, + 10,4,0,0,120,121,5,76,0,0,121,123,3,4,2,0,122,113,1,0,0,0,122,119, 1,0,0,0,123,126,1,0,0,0,124,122,1,0,0,0,124,125,1,0,0,0,125,3,1, 0,0,0,126,124,1,0,0,0,127,129,7,0,0,0,128,127,1,0,0,0,128,129,1, - 0,0,0,129,130,1,0,0,0,130,131,5,90,0,0,131,5,1,0,0,0,132,140,5,45, - 0,0,133,140,5,46,0,0,134,135,5,47,0,0,135,136,3,8,4,0,136,137,5, - 83,0,0,137,138,3,10,5,0,138,140,1,0,0,0,139,132,1,0,0,0,139,133, - 1,0,0,0,139,134,1,0,0,0,140,7,1,0,0,0,141,142,5,89,0,0,142,9,1,0, - 0,0,143,144,5,89,0,0,144,11,1,0,0,0,145,146,6,6,-1,0,146,147,5,49, - 0,0,147,148,3,12,6,0,148,149,5,50,0,0,149,157,1,0,0,0,150,151,3, - 16,8,0,151,152,3,12,6,9,152,157,1,0,0,0,153,154,5,28,0,0,154,157, + 0,0,0,129,130,1,0,0,0,130,131,5,88,0,0,131,5,1,0,0,0,132,140,5,43, + 0,0,133,140,5,44,0,0,134,135,5,45,0,0,135,136,3,8,4,0,136,137,5, + 81,0,0,137,138,3,10,5,0,138,140,1,0,0,0,139,132,1,0,0,0,139,133, + 1,0,0,0,139,134,1,0,0,0,140,7,1,0,0,0,141,142,5,87,0,0,142,9,1,0, + 0,0,143,144,5,87,0,0,144,11,1,0,0,0,145,146,6,6,-1,0,146,147,5,47, + 0,0,147,148,3,12,6,0,148,149,5,48,0,0,149,157,1,0,0,0,150,151,3, + 16,8,0,151,152,3,12,6,9,152,157,1,0,0,0,153,154,5,26,0,0,154,157, 3,12,6,4,155,157,3,14,7,0,156,145,1,0,0,0,156,150,1,0,0,0,156,153, 1,0,0,0,156,155,1,0,0,0,157,194,1,0,0,0,158,159,10,10,0,0,159,160, - 5,78,0,0,160,193,3,12,6,10,161,165,10,8,0,0,162,166,5,77,0,0,163, - 166,5,79,0,0,164,166,5,80,0,0,165,162,1,0,0,0,165,163,1,0,0,0,165, + 5,76,0,0,160,193,3,12,6,10,161,165,10,8,0,0,162,166,5,75,0,0,163, + 166,5,77,0,0,164,166,5,78,0,0,165,162,1,0,0,0,165,163,1,0,0,0,165, 164,1,0,0,0,166,167,1,0,0,0,167,193,3,12,6,9,168,171,10,7,0,0,169, - 172,5,51,0,0,170,172,5,75,0,0,171,169,1,0,0,0,171,170,1,0,0,0,172, + 172,5,49,0,0,170,172,5,73,0,0,171,169,1,0,0,0,171,170,1,0,0,0,172, 173,1,0,0,0,173,193,3,12,6,8,174,175,10,6,0,0,175,176,3,18,9,0,176, 177,3,12,6,7,177,193,1,0,0,0,178,179,10,5,0,0,179,180,3,20,10,0, 180,181,3,12,6,6,181,193,1,0,0,0,182,183,10,3,0,0,183,184,3,22,11, - 0,184,185,3,12,6,4,185,193,1,0,0,0,186,187,10,2,0,0,187,188,5,81, - 0,0,188,189,3,12,6,0,189,190,5,82,0,0,190,191,3,12,6,3,191,193,1, + 0,184,185,3,12,6,4,185,193,1,0,0,0,186,187,10,2,0,0,187,188,5,79, + 0,0,188,189,3,12,6,0,189,190,5,80,0,0,190,191,3,12,6,3,191,193,1, 0,0,0,192,158,1,0,0,0,192,161,1,0,0,0,192,168,1,0,0,0,192,174,1, 0,0,0,192,178,1,0,0,0,192,182,1,0,0,0,192,186,1,0,0,0,193,196,1, 0,0,0,194,192,1,0,0,0,194,195,1,0,0,0,195,13,1,0,0,0,196,194,1,0, - 0,0,197,207,3,26,13,0,198,207,5,87,0,0,199,201,7,1,0,0,200,202,3, + 0,0,197,207,3,26,13,0,198,207,5,85,0,0,199,201,7,1,0,0,200,202,3, 24,12,0,201,200,1,0,0,0,201,202,1,0,0,0,202,207,1,0,0,0,203,207, - 5,88,0,0,204,207,5,25,0,0,205,207,3,24,12,0,206,197,1,0,0,0,206, + 5,86,0,0,204,207,5,23,0,0,205,207,3,24,12,0,206,197,1,0,0,0,206, 198,1,0,0,0,206,199,1,0,0,0,206,203,1,0,0,0,206,204,1,0,0,0,206, - 205,1,0,0,0,207,15,1,0,0,0,208,212,5,51,0,0,209,212,5,75,0,0,210, - 212,5,52,0,0,211,208,1,0,0,0,211,209,1,0,0,0,211,210,1,0,0,0,212, - 17,1,0,0,0,213,219,5,55,0,0,214,219,5,54,0,0,215,219,5,53,0,0,216, - 219,5,61,0,0,217,219,5,62,0,0,218,213,1,0,0,0,218,214,1,0,0,0,218, + 205,1,0,0,0,207,15,1,0,0,0,208,212,5,49,0,0,209,212,5,73,0,0,210, + 212,5,50,0,0,211,208,1,0,0,0,211,209,1,0,0,0,211,210,1,0,0,0,212, + 17,1,0,0,0,213,219,5,53,0,0,214,219,5,52,0,0,215,219,5,51,0,0,216, + 219,5,59,0,0,217,219,5,60,0,0,218,213,1,0,0,0,218,214,1,0,0,0,218, 215,1,0,0,0,218,216,1,0,0,0,218,217,1,0,0,0,219,19,1,0,0,0,220,228, - 5,63,0,0,221,228,5,65,0,0,222,228,5,70,0,0,223,228,5,71,0,0,224, - 228,5,72,0,0,225,228,5,73,0,0,226,228,5,64,0,0,227,220,1,0,0,0,227, + 5,61,0,0,221,228,5,63,0,0,222,228,5,68,0,0,223,228,5,69,0,0,224, + 228,5,70,0,0,225,228,5,71,0,0,226,228,5,62,0,0,227,220,1,0,0,0,227, 221,1,0,0,0,227,222,1,0,0,0,227,223,1,0,0,0,227,224,1,0,0,0,227, - 225,1,0,0,0,227,226,1,0,0,0,228,21,1,0,0,0,229,232,5,26,0,0,230, - 232,5,27,0,0,231,229,1,0,0,0,231,230,1,0,0,0,232,23,1,0,0,0,233, - 238,5,89,0,0,234,235,5,56,0,0,235,236,3,12,6,0,236,237,5,58,0,0, + 225,1,0,0,0,227,226,1,0,0,0,228,21,1,0,0,0,229,232,5,24,0,0,230, + 232,5,25,0,0,231,229,1,0,0,0,231,230,1,0,0,0,232,23,1,0,0,0,233, + 238,5,87,0,0,234,235,5,54,0,0,235,236,3,12,6,0,236,237,5,56,0,0, 237,239,1,0,0,0,238,234,1,0,0,0,238,239,1,0,0,0,239,243,1,0,0,0, - 240,242,5,85,0,0,241,240,1,0,0,0,242,245,1,0,0,0,243,241,1,0,0,0, - 243,244,1,0,0,0,244,25,1,0,0,0,245,243,1,0,0,0,246,247,5,89,0,0, - 247,256,5,49,0,0,248,253,3,12,6,0,249,250,5,74,0,0,250,252,3,12, + 240,242,5,83,0,0,241,240,1,0,0,0,242,245,1,0,0,0,243,241,1,0,0,0, + 243,244,1,0,0,0,244,25,1,0,0,0,245,243,1,0,0,0,246,247,5,87,0,0, + 247,256,5,47,0,0,248,253,3,12,6,0,249,250,5,72,0,0,250,252,3,12, 6,0,251,249,1,0,0,0,252,255,1,0,0,0,253,251,1,0,0,0,253,254,1,0, 0,0,254,257,1,0,0,0,255,253,1,0,0,0,256,248,1,0,0,0,256,257,1,0, - 0,0,257,258,1,0,0,0,258,259,5,50,0,0,259,27,1,0,0,0,260,262,5,29, - 0,0,261,260,1,0,0,0,261,262,1,0,0,0,262,263,1,0,0,0,263,264,5,16, - 0,0,264,265,5,89,0,0,265,266,3,0,0,0,266,267,5,76,0,0,267,269,3, - 12,6,0,268,270,5,84,0,0,269,268,1,0,0,0,269,270,1,0,0,0,270,274, + 0,0,257,258,1,0,0,0,258,259,5,48,0,0,259,27,1,0,0,0,260,262,5,27, + 0,0,261,260,1,0,0,0,261,262,1,0,0,0,262,263,1,0,0,0,263,264,5,14, + 0,0,264,265,5,87,0,0,265,266,3,0,0,0,266,267,5,74,0,0,267,269,3, + 12,6,0,268,270,5,82,0,0,269,268,1,0,0,0,269,270,1,0,0,0,270,274, 1,0,0,0,271,273,3,6,3,0,272,271,1,0,0,0,273,276,1,0,0,0,274,272, 1,0,0,0,274,275,1,0,0,0,275,277,1,0,0,0,276,274,1,0,0,0,277,278, - 5,9,0,0,278,29,1,0,0,0,279,280,3,24,12,0,280,281,5,76,0,0,281,283, - 3,12,6,0,282,284,5,84,0,0,283,282,1,0,0,0,283,284,1,0,0,0,284,288, + 5,7,0,0,278,29,1,0,0,0,279,280,3,24,12,0,280,281,5,74,0,0,281,283, + 3,12,6,0,282,284,5,82,0,0,283,282,1,0,0,0,283,284,1,0,0,0,284,288, 1,0,0,0,285,287,3,6,3,0,286,285,1,0,0,0,287,290,1,0,0,0,288,286, 1,0,0,0,288,289,1,0,0,0,289,291,1,0,0,0,290,288,1,0,0,0,291,292, - 5,9,0,0,292,31,1,0,0,0,293,294,5,30,0,0,294,295,3,24,12,0,295,296, - 5,76,0,0,296,304,3,12,6,0,297,298,5,4,0,0,298,299,3,24,12,0,299, - 300,5,76,0,0,300,301,3,12,6,0,301,303,1,0,0,0,302,297,1,0,0,0,303, + 5,7,0,0,292,31,1,0,0,0,293,294,5,28,0,0,294,295,3,24,12,0,295,296, + 5,74,0,0,296,304,3,12,6,0,297,298,5,3,0,0,298,299,3,24,12,0,299, + 300,5,74,0,0,300,301,3,12,6,0,301,303,1,0,0,0,302,297,1,0,0,0,303, 306,1,0,0,0,304,302,1,0,0,0,304,305,1,0,0,0,305,308,1,0,0,0,306, - 304,1,0,0,0,307,309,5,84,0,0,308,307,1,0,0,0,308,309,1,0,0,0,309, - 310,1,0,0,0,310,311,5,9,0,0,311,33,1,0,0,0,312,315,3,38,19,0,313, + 304,1,0,0,0,307,309,5,82,0,0,308,307,1,0,0,0,308,309,1,0,0,0,309, + 310,1,0,0,0,310,311,5,7,0,0,311,33,1,0,0,0,312,315,3,38,19,0,313, 315,3,36,18,0,314,312,1,0,0,0,314,313,1,0,0,0,315,35,1,0,0,0,316, 320,3,50,25,0,317,320,3,58,29,0,318,320,3,60,30,0,319,316,1,0,0, 0,319,317,1,0,0,0,319,318,1,0,0,0,320,37,1,0,0,0,321,326,3,40,20, 0,322,326,3,26,13,0,323,326,3,42,21,0,324,326,3,48,24,0,325,321, 1,0,0,0,325,322,1,0,0,0,325,323,1,0,0,0,325,324,1,0,0,0,326,327, - 1,0,0,0,327,328,5,9,0,0,328,39,1,0,0,0,329,335,3,24,12,0,330,336, - 5,76,0,0,331,336,5,66,0,0,332,336,5,67,0,0,333,336,5,68,0,0,334, - 336,5,69,0,0,335,330,1,0,0,0,335,331,1,0,0,0,335,332,1,0,0,0,335, + 1,0,0,0,327,328,5,7,0,0,328,39,1,0,0,0,329,335,3,24,12,0,330,336, + 5,74,0,0,331,336,5,64,0,0,332,336,5,65,0,0,333,336,5,66,0,0,334, + 336,5,67,0,0,335,330,1,0,0,0,335,331,1,0,0,0,335,332,1,0,0,0,335, 333,1,0,0,0,335,334,1,0,0,0,336,337,1,0,0,0,337,338,3,12,6,0,338, - 41,1,0,0,0,339,341,5,29,0,0,340,339,1,0,0,0,340,341,1,0,0,0,341, - 343,1,0,0,0,342,344,5,16,0,0,343,342,1,0,0,0,343,344,1,0,0,0,344, - 345,1,0,0,0,345,350,3,24,12,0,346,347,5,74,0,0,347,349,3,24,12,0, + 41,1,0,0,0,339,341,5,27,0,0,340,339,1,0,0,0,340,341,1,0,0,0,341, + 343,1,0,0,0,342,344,5,14,0,0,343,342,1,0,0,0,343,344,1,0,0,0,344, + 345,1,0,0,0,345,350,3,24,12,0,346,347,5,72,0,0,347,349,3,24,12,0, 348,346,1,0,0,0,349,352,1,0,0,0,350,348,1,0,0,0,350,351,1,0,0,0, - 351,353,1,0,0,0,352,350,1,0,0,0,353,356,3,0,0,0,354,355,5,76,0,0, + 351,353,1,0,0,0,352,350,1,0,0,0,353,356,3,0,0,0,354,355,5,74,0,0, 355,357,3,12,6,0,356,354,1,0,0,0,356,357,1,0,0,0,357,362,1,0,0,0, - 358,359,5,59,0,0,359,360,3,12,6,0,360,361,5,60,0,0,361,363,1,0,0, + 358,359,5,57,0,0,359,360,3,12,6,0,360,361,5,58,0,0,361,363,1,0,0, 0,362,358,1,0,0,0,362,363,1,0,0,0,363,367,1,0,0,0,364,366,3,6,3, 0,365,364,1,0,0,0,366,369,1,0,0,0,367,365,1,0,0,0,367,368,1,0,0, - 0,368,43,1,0,0,0,369,367,1,0,0,0,370,371,3,42,21,0,371,372,5,9,0, - 0,372,45,1,0,0,0,373,375,5,9,0,0,374,373,1,0,0,0,374,375,1,0,0,0, - 375,376,1,0,0,0,376,381,3,34,17,0,377,380,5,9,0,0,378,380,3,34,17, + 0,368,43,1,0,0,0,369,367,1,0,0,0,370,371,3,42,21,0,371,372,5,7,0, + 0,372,45,1,0,0,0,373,375,5,7,0,0,374,373,1,0,0,0,374,375,1,0,0,0, + 375,376,1,0,0,0,376,381,3,34,17,0,377,380,5,7,0,0,378,380,3,34,17, 0,379,377,1,0,0,0,379,378,1,0,0,0,380,383,1,0,0,0,381,379,1,0,0, - 0,381,382,1,0,0,0,382,47,1,0,0,0,383,381,1,0,0,0,384,386,5,17,0, + 0,381,382,1,0,0,0,382,47,1,0,0,0,383,381,1,0,0,0,384,386,5,15,0, 0,385,387,3,12,6,0,386,385,1,0,0,0,386,387,1,0,0,0,387,49,1,0,0, 0,388,392,3,52,26,0,389,391,3,54,27,0,390,389,1,0,0,0,391,394,1, 0,0,0,392,390,1,0,0,0,392,393,1,0,0,0,393,396,1,0,0,0,394,392,1, 0,0,0,395,397,3,56,28,0,396,395,1,0,0,0,396,397,1,0,0,0,397,51,1, - 0,0,0,398,399,5,18,0,0,399,400,3,12,6,0,400,401,5,82,0,0,401,402, - 5,9,0,0,402,403,5,1,0,0,403,404,3,46,23,0,404,405,5,2,0,0,405,53, - 1,0,0,0,406,407,5,19,0,0,407,408,3,12,6,0,408,409,5,82,0,0,409,410, - 5,9,0,0,410,411,5,1,0,0,411,412,3,46,23,0,412,413,5,2,0,0,413,55, - 1,0,0,0,414,415,5,20,0,0,415,416,5,82,0,0,416,417,5,9,0,0,417,418, + 0,0,0,398,399,5,16,0,0,399,400,3,12,6,0,400,401,5,80,0,0,401,402, + 5,7,0,0,402,403,5,1,0,0,403,404,3,46,23,0,404,405,5,2,0,0,405,53, + 1,0,0,0,406,407,5,17,0,0,407,408,3,12,6,0,408,409,5,80,0,0,409,410, + 5,7,0,0,410,411,5,1,0,0,411,412,3,46,23,0,412,413,5,2,0,0,413,55, + 1,0,0,0,414,415,5,18,0,0,415,416,5,80,0,0,416,417,5,7,0,0,417,418, 5,1,0,0,418,419,3,46,23,0,419,420,5,2,0,0,420,57,1,0,0,0,421,422, - 5,21,0,0,422,423,5,89,0,0,423,424,5,23,0,0,424,425,3,12,6,0,425, - 426,5,48,0,0,426,427,3,12,6,0,427,429,5,24,0,0,428,430,5,75,0,0, + 5,19,0,0,422,423,5,87,0,0,423,424,5,21,0,0,424,425,3,12,6,0,425, + 426,5,46,0,0,426,427,3,12,6,0,427,429,5,22,0,0,428,430,5,73,0,0, 429,428,1,0,0,0,429,430,1,0,0,0,430,431,1,0,0,0,431,432,7,1,0,0, - 432,433,5,82,0,0,433,434,5,9,0,0,434,435,5,1,0,0,435,436,3,46,23, - 0,436,437,5,2,0,0,437,59,1,0,0,0,438,439,5,22,0,0,439,440,3,12,6, - 0,440,441,5,82,0,0,441,442,5,9,0,0,442,443,5,1,0,0,443,444,3,46, + 432,433,5,80,0,0,433,434,5,7,0,0,434,435,5,1,0,0,435,436,3,46,23, + 0,436,437,5,2,0,0,437,59,1,0,0,0,438,439,5,20,0,0,439,440,3,12,6, + 0,440,441,5,80,0,0,441,442,5,7,0,0,442,443,5,1,0,0,443,444,3,46, 23,0,444,445,5,2,0,0,445,61,1,0,0,0,446,449,3,64,32,0,447,449,5, - 9,0,0,448,446,1,0,0,0,448,447,1,0,0,0,449,450,1,0,0,0,450,448,1, + 7,0,0,448,446,1,0,0,0,448,447,1,0,0,0,449,450,1,0,0,0,450,448,1, 0,0,0,450,451,1,0,0,0,451,452,1,0,0,0,452,453,5,0,0,1,453,63,1,0, - 0,0,454,455,5,31,0,0,455,456,5,89,0,0,456,457,5,82,0,0,457,458,3, - 66,33,0,458,65,1,0,0,0,459,460,5,9,0,0,460,469,5,1,0,0,461,470,3, + 0,0,454,455,5,29,0,0,455,456,5,87,0,0,456,457,5,80,0,0,457,458,3, + 66,33,0,458,65,1,0,0,0,459,460,5,7,0,0,460,469,5,1,0,0,461,470,3, 72,36,0,462,470,3,76,38,0,463,470,3,78,39,0,464,470,3,86,43,0,465, 470,3,88,44,0,466,470,3,68,34,0,467,470,3,70,35,0,468,470,3,74,37, 0,469,461,1,0,0,0,469,462,1,0,0,0,469,463,1,0,0,0,469,464,1,0,0, 0,469,465,1,0,0,0,469,466,1,0,0,0,469,467,1,0,0,0,469,468,1,0,0, 0,470,471,1,0,0,0,471,469,1,0,0,0,471,472,1,0,0,0,472,473,1,0,0, - 0,473,474,5,2,0,0,474,67,1,0,0,0,475,476,5,40,0,0,476,477,5,49,0, - 0,477,482,5,89,0,0,478,479,5,74,0,0,479,481,3,92,46,0,480,478,1, + 0,473,474,5,2,0,0,474,67,1,0,0,0,475,476,5,38,0,0,476,477,5,47,0, + 0,477,482,5,87,0,0,478,479,5,72,0,0,479,481,3,92,46,0,480,478,1, 0,0,0,481,484,1,0,0,0,482,480,1,0,0,0,482,483,1,0,0,0,483,485,1, - 0,0,0,484,482,1,0,0,0,485,486,5,50,0,0,486,487,5,82,0,0,487,488, - 5,9,0,0,488,489,5,1,0,0,489,490,3,46,23,0,490,491,5,2,0,0,491,69, - 1,0,0,0,492,493,5,41,0,0,493,494,5,49,0,0,494,499,3,12,6,0,495,496, - 5,74,0,0,496,498,3,92,46,0,497,495,1,0,0,0,498,501,1,0,0,0,499,497, + 0,0,0,484,482,1,0,0,0,485,486,5,48,0,0,486,487,5,80,0,0,487,488, + 5,7,0,0,488,489,5,1,0,0,489,490,3,46,23,0,490,491,5,2,0,0,491,69, + 1,0,0,0,492,493,5,39,0,0,493,494,5,47,0,0,494,499,3,12,6,0,495,496, + 5,72,0,0,496,498,3,92,46,0,497,495,1,0,0,0,498,501,1,0,0,0,499,497, 1,0,0,0,499,500,1,0,0,0,500,502,1,0,0,0,501,499,1,0,0,0,502,503, - 5,50,0,0,503,504,5,82,0,0,504,505,5,9,0,0,505,506,5,1,0,0,506,507, + 5,48,0,0,503,504,5,80,0,0,504,505,5,7,0,0,505,506,5,1,0,0,506,507, 3,46,23,0,507,508,5,2,0,0,508,71,1,0,0,0,509,510,7,2,0,0,510,511, - 5,82,0,0,511,512,5,9,0,0,512,514,5,1,0,0,513,515,3,44,22,0,514,513, + 5,80,0,0,511,512,5,7,0,0,512,514,5,1,0,0,513,515,3,44,22,0,514,513, 1,0,0,0,515,516,1,0,0,0,516,514,1,0,0,0,516,517,1,0,0,0,517,518, - 1,0,0,0,518,519,5,2,0,0,519,73,1,0,0,0,520,521,5,35,0,0,521,522, - 5,82,0,0,522,523,5,9,0,0,523,524,5,1,0,0,524,525,3,46,23,0,525,526, - 5,2,0,0,526,75,1,0,0,0,527,528,5,36,0,0,528,529,5,82,0,0,529,530, - 5,9,0,0,530,534,5,1,0,0,531,535,3,28,14,0,532,535,3,30,15,0,533, + 1,0,0,0,518,519,5,2,0,0,519,73,1,0,0,0,520,521,5,33,0,0,521,522, + 5,80,0,0,522,523,5,7,0,0,523,524,5,1,0,0,524,525,3,46,23,0,525,526, + 5,2,0,0,526,75,1,0,0,0,527,528,5,34,0,0,528,529,5,80,0,0,529,530, + 5,7,0,0,530,534,5,1,0,0,531,535,3,28,14,0,532,535,3,30,15,0,533, 535,3,32,16,0,534,531,1,0,0,0,534,532,1,0,0,0,534,533,1,0,0,0,535, 536,1,0,0,0,536,534,1,0,0,0,536,537,1,0,0,0,537,538,1,0,0,0,538, - 539,5,2,0,0,539,77,1,0,0,0,540,541,5,37,0,0,541,542,5,82,0,0,542, - 543,5,9,0,0,543,562,5,1,0,0,544,547,3,80,40,0,545,547,3,82,41,0, - 546,544,1,0,0,0,546,545,1,0,0,0,547,560,1,0,0,0,548,557,5,49,0,0, - 549,554,3,90,45,0,550,551,5,74,0,0,551,553,3,90,45,0,552,550,1,0, + 539,5,2,0,0,539,77,1,0,0,0,540,541,5,35,0,0,541,542,5,80,0,0,542, + 543,5,7,0,0,543,562,5,1,0,0,544,547,3,80,40,0,545,547,3,82,41,0, + 546,544,1,0,0,0,546,545,1,0,0,0,547,560,1,0,0,0,548,557,5,47,0,0, + 549,554,3,90,45,0,550,551,5,72,0,0,551,553,3,90,45,0,552,550,1,0, 0,0,553,556,1,0,0,0,554,552,1,0,0,0,554,555,1,0,0,0,555,558,1,0, 0,0,556,554,1,0,0,0,557,549,1,0,0,0,557,558,1,0,0,0,558,559,1,0, - 0,0,559,561,5,50,0,0,560,548,1,0,0,0,560,561,1,0,0,0,561,563,1,0, + 0,0,559,561,5,48,0,0,560,548,1,0,0,0,560,561,1,0,0,0,561,563,1,0, 0,0,562,546,1,0,0,0,563,564,1,0,0,0,564,562,1,0,0,0,564,565,1,0, - 0,0,565,566,1,0,0,0,566,567,5,2,0,0,567,79,1,0,0,0,568,573,5,89, - 0,0,569,570,5,56,0,0,570,571,3,12,6,0,571,572,5,58,0,0,572,574,1, + 0,0,565,566,1,0,0,0,566,567,5,2,0,0,567,79,1,0,0,0,568,573,5,87, + 0,0,569,570,5,54,0,0,570,571,3,12,6,0,571,572,5,56,0,0,572,574,1, 0,0,0,573,569,1,0,0,0,573,574,1,0,0,0,574,575,1,0,0,0,575,579,5, - 57,0,0,576,578,3,84,42,0,577,576,1,0,0,0,578,581,1,0,0,0,579,577, + 55,0,0,576,578,3,84,42,0,577,576,1,0,0,0,578,581,1,0,0,0,579,577, 1,0,0,0,579,580,1,0,0,0,580,582,1,0,0,0,581,579,1,0,0,0,582,583, - 5,42,0,0,583,584,5,9,0,0,584,81,1,0,0,0,585,590,5,89,0,0,586,587, - 5,56,0,0,587,588,3,12,6,0,588,589,5,58,0,0,589,591,1,0,0,0,590,586, + 5,40,0,0,583,584,5,7,0,0,584,81,1,0,0,0,585,590,5,87,0,0,586,587, + 5,54,0,0,587,588,3,12,6,0,588,589,5,56,0,0,589,591,1,0,0,0,590,586, 1,0,0,0,590,591,1,0,0,0,591,592,1,0,0,0,592,593,3,0,0,0,593,594, - 5,57,0,0,594,595,5,39,0,0,595,596,5,9,0,0,596,83,1,0,0,0,597,600, - 5,43,0,0,598,600,5,44,0,0,599,597,1,0,0,0,599,598,1,0,0,0,600,85, - 1,0,0,0,601,602,5,38,0,0,602,603,5,82,0,0,603,604,5,9,0,0,604,621, - 5,1,0,0,605,618,5,42,0,0,606,615,5,49,0,0,607,612,3,90,45,0,608, - 609,5,74,0,0,609,611,3,90,45,0,610,608,1,0,0,0,611,614,1,0,0,0,612, + 5,55,0,0,594,595,5,37,0,0,595,596,5,7,0,0,596,83,1,0,0,0,597,600, + 5,41,0,0,598,600,5,42,0,0,599,597,1,0,0,0,599,598,1,0,0,0,600,85, + 1,0,0,0,601,602,5,36,0,0,602,603,5,80,0,0,603,604,5,7,0,0,604,621, + 5,1,0,0,605,618,5,40,0,0,606,615,5,47,0,0,607,612,3,90,45,0,608, + 609,5,72,0,0,609,611,3,90,45,0,610,608,1,0,0,0,611,614,1,0,0,0,612, 610,1,0,0,0,612,613,1,0,0,0,613,616,1,0,0,0,614,612,1,0,0,0,615, - 607,1,0,0,0,615,616,1,0,0,0,616,617,1,0,0,0,617,619,5,50,0,0,618, - 606,1,0,0,0,618,619,1,0,0,0,619,622,1,0,0,0,620,622,5,39,0,0,621, - 605,1,0,0,0,621,620,1,0,0,0,622,623,1,0,0,0,623,624,5,9,0,0,624, - 625,5,2,0,0,625,87,1,0,0,0,626,627,5,15,0,0,627,628,5,89,0,0,628, - 637,5,49,0,0,629,634,3,90,45,0,630,631,5,74,0,0,631,633,3,90,45, + 607,1,0,0,0,615,616,1,0,0,0,616,617,1,0,0,0,617,619,5,48,0,0,618, + 606,1,0,0,0,618,619,1,0,0,0,619,622,1,0,0,0,620,622,5,37,0,0,621, + 605,1,0,0,0,621,620,1,0,0,0,622,623,1,0,0,0,623,624,5,7,0,0,624, + 625,5,2,0,0,625,87,1,0,0,0,626,627,5,13,0,0,627,628,5,87,0,0,628, + 637,5,47,0,0,629,634,3,90,45,0,630,631,5,72,0,0,631,633,3,90,45, 0,632,630,1,0,0,0,633,636,1,0,0,0,634,632,1,0,0,0,634,635,1,0,0, 0,635,638,1,0,0,0,636,634,1,0,0,0,637,629,1,0,0,0,637,638,1,0,0, - 0,638,639,1,0,0,0,639,641,5,50,0,0,640,642,3,0,0,0,641,640,1,0,0, - 0,641,642,1,0,0,0,642,643,1,0,0,0,643,644,5,82,0,0,644,645,5,9,0, + 0,638,639,1,0,0,0,639,641,5,48,0,0,640,642,3,0,0,0,641,640,1,0,0, + 0,641,642,1,0,0,0,642,643,1,0,0,0,643,644,5,80,0,0,644,645,5,7,0, 0,645,646,5,1,0,0,646,647,3,46,23,0,647,648,5,2,0,0,648,89,1,0,0, - 0,649,650,5,89,0,0,650,651,3,0,0,0,651,91,1,0,0,0,652,653,5,89,0, - 0,653,654,5,76,0,0,654,655,7,3,0,0,655,93,1,0,0,0,71,100,111,116, + 0,649,650,5,87,0,0,650,651,3,0,0,0,651,91,1,0,0,0,652,653,5,87,0, + 0,653,654,5,74,0,0,654,655,7,3,0,0,655,93,1,0,0,0,71,100,111,116, 122,124,128,139,156,165,171,192,194,201,206,211,218,227,231,238, 243,253,256,261,269,274,283,288,304,308,314,319,325,335,340,343, 350,356,362,367,374,379,381,386,392,396,429,448,450,469,471,482, @@ -266,13 +266,13 @@ class PyNestMLParser ( Parser ): sharedContextCache = PredictionContextCache() - literalNames = [ "", "", "", "'\"\"\"'", + literalNames = [ "", "", "", "", "", "", "", "", - "", "", "'integer'", "'real'", "'string'", - "'boolean'", "'void'", "'function'", "'inline'", "'return'", - "'if'", "'elif'", "'else'", "'for'", "'while'", "'in'", - "'step'", "'inf'", "'and'", "'or'", "'not'", "'recordable'", - "'kernel'", "'model'", "'state'", "'parameters'", "'internals'", + "'integer'", "'real'", "'string'", "'boolean'", "'void'", + "'function'", "'inline'", "'return'", "'if'", "'elif'", + "'else'", "'for'", "'while'", "'in'", "'step'", "'inf'", + "'and'", "'or'", "'not'", "'recordable'", "'kernel'", + "'model'", "'state'", "'parameters'", "'internals'", "'update'", "'equations'", "'input'", "'output'", "'continuous'", "'onReceive'", "'onCondition'", "'spike'", "'inhibitory'", "'excitatory'", "'@homogeneous'", "'@heterogeneous'", @@ -283,20 +283,19 @@ class PyNestMLParser ( Parser ): "'-'", "'='", "'*'", "'**'", "'/'", "'%'", "'?'", "':'", "'::'", "';'", "'''", "'.'" ] - symbolicNames = [ "", "INDENT", "DEDENT", "DOCSTRING_TRIPLEQUOTE", - "KERNEL_JOINING", "WS", "LINE_ESCAPE", "DOCSTRING", - "SL_COMMENT", "NEWLINE", "INTEGER_KEYWORD", "REAL_KEYWORD", - "STRING_KEYWORD", "BOOLEAN_KEYWORD", "VOID_KEYWORD", - "FUNCTION_KEYWORD", "INLINE_KEYWORD", "RETURN_KEYWORD", - "IF_KEYWORD", "ELIF_KEYWORD", "ELSE_KEYWORD", "FOR_KEYWORD", - "WHILE_KEYWORD", "IN_KEYWORD", "STEP_KEYWORD", "INF_KEYWORD", - "AND_KEYWORD", "OR_KEYWORD", "NOT_KEYWORD", "RECORDABLE_KEYWORD", - "KERNEL_KEYWORD", "MODEL_KEYWORD", "STATE_KEYWORD", - "PARAMETERS_KEYWORD", "INTERNALS_KEYWORD", "UPDATE_KEYWORD", - "EQUATIONS_KEYWORD", "INPUT_KEYWORD", "OUTPUT_KEYWORD", - "CONTINUOUS_KEYWORD", "ON_RECEIVE_KEYWORD", "ON_CONDITION_KEYWORD", - "SPIKE_KEYWORD", "INHIBITORY_KEYWORD", "EXCITATORY_KEYWORD", - "DECORATOR_HOMOGENEOUS", "DECORATOR_HETEROGENEOUS", + symbolicNames = [ "", "INDENT", "DEDENT", "KERNEL_JOINING", + "WS", "LINE_ESCAPE", "SL_COMMENT", "NEWLINE", "INTEGER_KEYWORD", + "REAL_KEYWORD", "STRING_KEYWORD", "BOOLEAN_KEYWORD", + "VOID_KEYWORD", "FUNCTION_KEYWORD", "INLINE_KEYWORD", + "RETURN_KEYWORD", "IF_KEYWORD", "ELIF_KEYWORD", "ELSE_KEYWORD", + "FOR_KEYWORD", "WHILE_KEYWORD", "IN_KEYWORD", "STEP_KEYWORD", + "INF_KEYWORD", "AND_KEYWORD", "OR_KEYWORD", "NOT_KEYWORD", + "RECORDABLE_KEYWORD", "KERNEL_KEYWORD", "MODEL_KEYWORD", + "STATE_KEYWORD", "PARAMETERS_KEYWORD", "INTERNALS_KEYWORD", + "UPDATE_KEYWORD", "EQUATIONS_KEYWORD", "INPUT_KEYWORD", + "OUTPUT_KEYWORD", "CONTINUOUS_KEYWORD", "ON_RECEIVE_KEYWORD", + "ON_CONDITION_KEYWORD", "SPIKE_KEYWORD", "INHIBITORY_KEYWORD", + "EXCITATORY_KEYWORD", "DECORATOR_HOMOGENEOUS", "DECORATOR_HETEROGENEOUS", "AT", "ELLIPSIS", "LEFT_PAREN", "RIGHT_PAREN", "PLUS", "TILDE", "PIPE", "CARET", "AMPERSAND", "LEFT_SQUARE_BRACKET", "LEFT_ANGLE_MINUS", "RIGHT_SQUARE_BRACKET", "LEFT_LEFT_SQUARE", @@ -375,95 +374,93 @@ class PyNestMLParser ( Parser ): EOF = Token.EOF INDENT=1 DEDENT=2 - DOCSTRING_TRIPLEQUOTE=3 - KERNEL_JOINING=4 - WS=5 - LINE_ESCAPE=6 - DOCSTRING=7 - SL_COMMENT=8 - NEWLINE=9 - INTEGER_KEYWORD=10 - REAL_KEYWORD=11 - STRING_KEYWORD=12 - BOOLEAN_KEYWORD=13 - VOID_KEYWORD=14 - FUNCTION_KEYWORD=15 - INLINE_KEYWORD=16 - RETURN_KEYWORD=17 - IF_KEYWORD=18 - ELIF_KEYWORD=19 - ELSE_KEYWORD=20 - FOR_KEYWORD=21 - WHILE_KEYWORD=22 - IN_KEYWORD=23 - STEP_KEYWORD=24 - INF_KEYWORD=25 - AND_KEYWORD=26 - OR_KEYWORD=27 - NOT_KEYWORD=28 - RECORDABLE_KEYWORD=29 - KERNEL_KEYWORD=30 - MODEL_KEYWORD=31 - STATE_KEYWORD=32 - PARAMETERS_KEYWORD=33 - INTERNALS_KEYWORD=34 - UPDATE_KEYWORD=35 - EQUATIONS_KEYWORD=36 - INPUT_KEYWORD=37 - OUTPUT_KEYWORD=38 - CONTINUOUS_KEYWORD=39 - ON_RECEIVE_KEYWORD=40 - ON_CONDITION_KEYWORD=41 - SPIKE_KEYWORD=42 - INHIBITORY_KEYWORD=43 - EXCITATORY_KEYWORD=44 - DECORATOR_HOMOGENEOUS=45 - DECORATOR_HETEROGENEOUS=46 - AT=47 - ELLIPSIS=48 - LEFT_PAREN=49 - RIGHT_PAREN=50 - PLUS=51 - TILDE=52 - PIPE=53 - CARET=54 - AMPERSAND=55 - LEFT_SQUARE_BRACKET=56 - LEFT_ANGLE_MINUS=57 - RIGHT_SQUARE_BRACKET=58 - LEFT_LEFT_SQUARE=59 - RIGHT_RIGHT_SQUARE=60 - LEFT_LEFT_ANGLE=61 - RIGHT_RIGHT_ANGLE=62 - LEFT_ANGLE=63 - RIGHT_ANGLE=64 - LEFT_ANGLE_EQUALS=65 - PLUS_EQUALS=66 - MINUS_EQUALS=67 - STAR_EQUALS=68 - FORWARD_SLASH_EQUALS=69 - EQUALS_EQUALS=70 - EXCLAMATION_EQUALS=71 - LEFT_ANGLE_RIGHT_ANGLE=72 - RIGHT_ANGLE_EQUALS=73 - COMMA=74 - MINUS=75 - EQUALS=76 - STAR=77 - STAR_STAR=78 - FORWARD_SLASH=79 - PERCENT=80 - QUESTION=81 - COLON=82 - DOUBLE_COLON=83 - SEMICOLON=84 - DIFFERENTIAL_ORDER=85 - FULLSTOP=86 - BOOLEAN_LITERAL=87 - STRING_LITERAL=88 - NAME=89 - UNSIGNED_INTEGER=90 - FLOAT=91 + KERNEL_JOINING=3 + WS=4 + LINE_ESCAPE=5 + SL_COMMENT=6 + NEWLINE=7 + INTEGER_KEYWORD=8 + REAL_KEYWORD=9 + STRING_KEYWORD=10 + BOOLEAN_KEYWORD=11 + VOID_KEYWORD=12 + FUNCTION_KEYWORD=13 + INLINE_KEYWORD=14 + RETURN_KEYWORD=15 + IF_KEYWORD=16 + ELIF_KEYWORD=17 + ELSE_KEYWORD=18 + FOR_KEYWORD=19 + WHILE_KEYWORD=20 + IN_KEYWORD=21 + STEP_KEYWORD=22 + INF_KEYWORD=23 + AND_KEYWORD=24 + OR_KEYWORD=25 + NOT_KEYWORD=26 + RECORDABLE_KEYWORD=27 + KERNEL_KEYWORD=28 + MODEL_KEYWORD=29 + STATE_KEYWORD=30 + PARAMETERS_KEYWORD=31 + INTERNALS_KEYWORD=32 + UPDATE_KEYWORD=33 + EQUATIONS_KEYWORD=34 + INPUT_KEYWORD=35 + OUTPUT_KEYWORD=36 + CONTINUOUS_KEYWORD=37 + ON_RECEIVE_KEYWORD=38 + ON_CONDITION_KEYWORD=39 + SPIKE_KEYWORD=40 + INHIBITORY_KEYWORD=41 + EXCITATORY_KEYWORD=42 + DECORATOR_HOMOGENEOUS=43 + DECORATOR_HETEROGENEOUS=44 + AT=45 + ELLIPSIS=46 + LEFT_PAREN=47 + RIGHT_PAREN=48 + PLUS=49 + TILDE=50 + PIPE=51 + CARET=52 + AMPERSAND=53 + LEFT_SQUARE_BRACKET=54 + LEFT_ANGLE_MINUS=55 + RIGHT_SQUARE_BRACKET=56 + LEFT_LEFT_SQUARE=57 + RIGHT_RIGHT_SQUARE=58 + LEFT_LEFT_ANGLE=59 + RIGHT_RIGHT_ANGLE=60 + LEFT_ANGLE=61 + RIGHT_ANGLE=62 + LEFT_ANGLE_EQUALS=63 + PLUS_EQUALS=64 + MINUS_EQUALS=65 + STAR_EQUALS=66 + FORWARD_SLASH_EQUALS=67 + EQUALS_EQUALS=68 + EXCLAMATION_EQUALS=69 + LEFT_ANGLE_RIGHT_ANGLE=70 + RIGHT_ANGLE_EQUALS=71 + COMMA=72 + MINUS=73 + EQUALS=74 + STAR=75 + STAR_STAR=76 + FORWARD_SLASH=77 + PERCENT=78 + QUESTION=79 + COLON=80 + DOUBLE_COLON=81 + SEMICOLON=82 + DIFFERENTIAL_ORDER=83 + FULLSTOP=84 + BOOLEAN_LITERAL=85 + STRING_LITERAL=86 + NAME=87 + UNSIGNED_INTEGER=88 + FLOAT=89 def __init__(self, input:TokenStream, output:TextIO = sys.stdout): super().__init__(input, output) @@ -526,32 +523,32 @@ def dataType(self): self.state = 100 self._errHandler.sync(self) token = self._input.LA(1) - if token in [10]: + if token in [8]: self.enterOuterAlt(localctx, 1) self.state = 94 localctx.isInt = self.match(PyNestMLParser.INTEGER_KEYWORD) pass - elif token in [11]: + elif token in [9]: self.enterOuterAlt(localctx, 2) self.state = 95 localctx.isReal = self.match(PyNestMLParser.REAL_KEYWORD) pass - elif token in [12]: + elif token in [10]: self.enterOuterAlt(localctx, 3) self.state = 96 localctx.isString = self.match(PyNestMLParser.STRING_KEYWORD) pass - elif token in [13]: + elif token in [11]: self.enterOuterAlt(localctx, 4) self.state = 97 localctx.isBool = self.match(PyNestMLParser.BOOLEAN_KEYWORD) pass - elif token in [14]: + elif token in [12]: self.enterOuterAlt(localctx, 5) self.state = 98 localctx.isVoid = self.match(PyNestMLParser.VOID_KEYWORD) pass - elif token in [49, 89, 90]: + elif token in [47, 87, 88]: self.enterOuterAlt(localctx, 6) self.state = 99 localctx.unit = self.unitType(0) @@ -642,7 +639,7 @@ def unitType(self, _p:int=0): self.state = 111 self._errHandler.sync(self) token = self._input.LA(1) - if token in [49]: + if token in [47]: self.state = 103 localctx.leftParentheses = self.match(PyNestMLParser.LEFT_PAREN) self.state = 104 @@ -650,7 +647,7 @@ def unitType(self, _p:int=0): self.state = 105 localctx.rightParentheses = self.match(PyNestMLParser.RIGHT_PAREN) pass - elif token in [90]: + elif token in [88]: self.state = 107 localctx.unitlessLiteral = self.match(PyNestMLParser.UNSIGNED_INTEGER) self.state = 108 @@ -658,7 +655,7 @@ def unitType(self, _p:int=0): self.state = 109 localctx.right = self.unitType(2) pass - elif token in [89]: + elif token in [87]: self.state = 110 localctx.unit = self.match(PyNestMLParser.NAME) pass @@ -688,11 +685,11 @@ def unitType(self, _p:int=0): self.state = 116 self._errHandler.sync(self) token = self._input.LA(1) - if token in [77]: + if token in [75]: self.state = 114 localctx.timesOp = self.match(PyNestMLParser.STAR) pass - elif token in [79]: + elif token in [77]: self.state = 115 localctx.divOp = self.match(PyNestMLParser.FORWARD_SLASH) pass @@ -769,10 +766,10 @@ def unitTypeExponent(self): self.state = 128 self._errHandler.sync(self) _la = self._input.LA(1) - if _la==51 or _la==75: + if _la==49 or _la==73: self.state = 127 _la = self._input.LA(1) - if not(_la==51 or _la==75): + if not(_la==49 or _la==73): self._errHandler.recoverInline(self) else: self._errHandler.reportMatch(self) @@ -837,17 +834,17 @@ def anyDecorator(self): self.state = 139 self._errHandler.sync(self) token = self._input.LA(1) - if token in [45]: + if token in [43]: self.enterOuterAlt(localctx, 1) self.state = 132 self.match(PyNestMLParser.DECORATOR_HOMOGENEOUS) pass - elif token in [46]: + elif token in [44]: self.enterOuterAlt(localctx, 2) self.state = 133 self.match(PyNestMLParser.DECORATOR_HETEROGENEOUS) pass - elif token in [47]: + elif token in [45]: self.enterOuterAlt(localctx, 3) self.state = 134 self.match(PyNestMLParser.AT) @@ -1055,7 +1052,7 @@ def expression(self, _p:int=0): self.state = 156 self._errHandler.sync(self) token = self._input.LA(1) - if token in [49]: + if token in [47]: self.state = 146 localctx.leftParentheses = self.match(PyNestMLParser.LEFT_PAREN) self.state = 147 @@ -1063,19 +1060,19 @@ def expression(self, _p:int=0): self.state = 148 localctx.rightParentheses = self.match(PyNestMLParser.RIGHT_PAREN) pass - elif token in [51, 52, 75]: + elif token in [49, 50, 73]: self.state = 150 self.unaryOperator() self.state = 151 localctx.term = self.expression(9) pass - elif token in [28]: + elif token in [26]: self.state = 153 localctx.logicalNot = self.match(PyNestMLParser.NOT_KEYWORD) self.state = 154 localctx.term = self.expression(4) pass - elif token in [25, 87, 88, 89, 90, 91]: + elif token in [23, 85, 86, 87, 88, 89]: self.state = 155 self.simpleExpression() pass @@ -1119,15 +1116,15 @@ def expression(self, _p:int=0): self.state = 165 self._errHandler.sync(self) token = self._input.LA(1) - if token in [77]: + if token in [75]: self.state = 162 localctx.timesOp = self.match(PyNestMLParser.STAR) pass - elif token in [79]: + elif token in [77]: self.state = 163 localctx.divOp = self.match(PyNestMLParser.FORWARD_SLASH) pass - elif token in [80]: + elif token in [78]: self.state = 164 localctx.moduloOp = self.match(PyNestMLParser.PERCENT) pass @@ -1149,11 +1146,11 @@ def expression(self, _p:int=0): self.state = 171 self._errHandler.sync(self) token = self._input.LA(1) - if token in [51]: + if token in [49]: self.state = 169 localctx.plusOp = self.match(PyNestMLParser.PLUS) pass - elif token in [75]: + elif token in [73]: self.state = 170 localctx.minusOp = self.match(PyNestMLParser.MINUS) pass @@ -1307,7 +1304,7 @@ def simpleExpression(self): self.enterOuterAlt(localctx, 3) self.state = 199 _la = self._input.LA(1) - if not(_la==90 or _la==91): + if not(_la==88 or _la==89): self._errHandler.recoverInline(self) else: self._errHandler.reportMatch(self) @@ -1389,17 +1386,17 @@ def unaryOperator(self): self.state = 211 self._errHandler.sync(self) token = self._input.LA(1) - if token in [51]: + if token in [49]: self.enterOuterAlt(localctx, 1) self.state = 208 localctx.unaryPlus = self.match(PyNestMLParser.PLUS) pass - elif token in [75]: + elif token in [73]: self.enterOuterAlt(localctx, 2) self.state = 209 localctx.unaryMinus = self.match(PyNestMLParser.MINUS) pass - elif token in [52]: + elif token in [50]: self.enterOuterAlt(localctx, 3) self.state = 210 localctx.unaryTilde = self.match(PyNestMLParser.TILDE) @@ -1463,27 +1460,27 @@ def bitOperator(self): self.state = 218 self._errHandler.sync(self) token = self._input.LA(1) - if token in [55]: + if token in [53]: self.enterOuterAlt(localctx, 1) self.state = 213 localctx.bitAnd = self.match(PyNestMLParser.AMPERSAND) pass - elif token in [54]: + elif token in [52]: self.enterOuterAlt(localctx, 2) self.state = 214 localctx.bitXor = self.match(PyNestMLParser.CARET) pass - elif token in [53]: + elif token in [51]: self.enterOuterAlt(localctx, 3) self.state = 215 localctx.bitOr = self.match(PyNestMLParser.PIPE) pass - elif token in [61]: + elif token in [59]: self.enterOuterAlt(localctx, 4) self.state = 216 localctx.bitShiftLeft = self.match(PyNestMLParser.LEFT_LEFT_ANGLE) pass - elif token in [62]: + elif token in [60]: self.enterOuterAlt(localctx, 5) self.state = 217 localctx.bitShiftRight = self.match(PyNestMLParser.RIGHT_RIGHT_ANGLE) @@ -1555,37 +1552,37 @@ def comparisonOperator(self): self.state = 227 self._errHandler.sync(self) token = self._input.LA(1) - if token in [63]: + if token in [61]: self.enterOuterAlt(localctx, 1) self.state = 220 localctx.lt = self.match(PyNestMLParser.LEFT_ANGLE) pass - elif token in [65]: + elif token in [63]: self.enterOuterAlt(localctx, 2) self.state = 221 localctx.le = self.match(PyNestMLParser.LEFT_ANGLE_EQUALS) pass - elif token in [70]: + elif token in [68]: self.enterOuterAlt(localctx, 3) self.state = 222 localctx.eq = self.match(PyNestMLParser.EQUALS_EQUALS) pass - elif token in [71]: + elif token in [69]: self.enterOuterAlt(localctx, 4) self.state = 223 localctx.ne = self.match(PyNestMLParser.EXCLAMATION_EQUALS) pass - elif token in [72]: + elif token in [70]: self.enterOuterAlt(localctx, 5) self.state = 224 localctx.ne2 = self.match(PyNestMLParser.LEFT_ANGLE_RIGHT_ANGLE) pass - elif token in [73]: + elif token in [71]: self.enterOuterAlt(localctx, 6) self.state = 225 localctx.ge = self.match(PyNestMLParser.RIGHT_ANGLE_EQUALS) pass - elif token in [64]: + elif token in [62]: self.enterOuterAlt(localctx, 7) self.state = 226 localctx.gt = self.match(PyNestMLParser.RIGHT_ANGLE) @@ -1637,12 +1634,12 @@ def logicalOperator(self): self.state = 231 self._errHandler.sync(self) token = self._input.LA(1) - if token in [26]: + if token in [24]: self.enterOuterAlt(localctx, 1) self.state = 229 localctx.logicalAnd = self.match(PyNestMLParser.AND_KEYWORD) pass - elif token in [27]: + elif token in [25]: self.enterOuterAlt(localctx, 2) self.state = 230 localctx.logicalOr = self.match(PyNestMLParser.OR_KEYWORD) @@ -1795,13 +1792,13 @@ def functionCall(self): self.state = 256 self._errHandler.sync(self) _la = self._input.LA(1) - if (((_la) & ~0x3f) == 0 and ((1 << _la) & 7318349696466944) != 0) or ((((_la - 75)) & ~0x3f) == 0 and ((1 << (_la - 75)) & 126977) != 0): + if (((_la) & ~0x3f) == 0 and ((1 << _la) & 1829587424116736) != 0) or ((((_la - 73)) & ~0x3f) == 0 and ((1 << (_la - 73)) & 126977) != 0): self.state = 248 self.expression(0) self.state = 253 self._errHandler.sync(self) _la = self._input.LA(1) - while _la==74: + while _la==72: self.state = 249 self.match(PyNestMLParser.COMMA) self.state = 250 @@ -1888,7 +1885,7 @@ def inlineExpression(self): self.state = 261 self._errHandler.sync(self) _la = self._input.LA(1) - if _la==29: + if _la==27: self.state = 260 localctx.recordable = self.match(PyNestMLParser.RECORDABLE_KEYWORD) @@ -1906,7 +1903,7 @@ def inlineExpression(self): self.state = 269 self._errHandler.sync(self) _la = self._input.LA(1) - if _la==84: + if _la==82: self.state = 268 self.match(PyNestMLParser.SEMICOLON) @@ -1914,7 +1911,7 @@ def inlineExpression(self): self.state = 274 self._errHandler.sync(self) _la = self._input.LA(1) - while (((_la) & ~0x3f) == 0 and ((1 << _la) & 246290604621824) != 0): + while (((_la) & ~0x3f) == 0 and ((1 << _la) & 61572651155456) != 0): self.state = 271 localctx.decorator = self.anyDecorator() self.state = 276 @@ -1994,7 +1991,7 @@ def odeEquation(self): self.state = 283 self._errHandler.sync(self) _la = self._input.LA(1) - if _la==84: + if _la==82: self.state = 282 self.match(PyNestMLParser.SEMICOLON) @@ -2002,7 +1999,7 @@ def odeEquation(self): self.state = 288 self._errHandler.sync(self) _la = self._input.LA(1) - while (((_la) & ~0x3f) == 0 and ((1 << _la) & 246290604621824) != 0): + while (((_la) & ~0x3f) == 0 and ((1 << _la) & 61572651155456) != 0): self.state = 285 localctx.decorator = self.anyDecorator() self.state = 290 @@ -2092,7 +2089,7 @@ def kernel(self): self.state = 304 self._errHandler.sync(self) _la = self._input.LA(1) - while _la==4: + while _la==3: self.state = 297 self.match(PyNestMLParser.KERNEL_JOINING) self.state = 298 @@ -2108,7 +2105,7 @@ def kernel(self): self.state = 308 self._errHandler.sync(self) _la = self._input.LA(1) - if _la==84: + if _la==82: self.state = 307 self.match(PyNestMLParser.SEMICOLON) @@ -2159,12 +2156,12 @@ def stmt(self): self.state = 314 self._errHandler.sync(self) token = self._input.LA(1) - if token in [16, 17, 29, 89]: + if token in [14, 15, 27, 87]: self.enterOuterAlt(localctx, 1) self.state = 312 self.smallStmt() pass - elif token in [18, 21, 22]: + elif token in [16, 19, 20]: self.enterOuterAlt(localctx, 2) self.state = 313 self.compoundStmt() @@ -2220,17 +2217,17 @@ def compoundStmt(self): self.state = 319 self._errHandler.sync(self) token = self._input.LA(1) - if token in [18]: + if token in [16]: self.enterOuterAlt(localctx, 1) self.state = 316 self.ifStmt() pass - elif token in [21]: + elif token in [19]: self.enterOuterAlt(localctx, 2) self.state = 317 self.forStmt() pass - elif token in [22]: + elif token in [20]: self.enterOuterAlt(localctx, 3) self.state = 318 self.whileStmt() @@ -2385,23 +2382,23 @@ def assignment(self): self.state = 335 self._errHandler.sync(self) token = self._input.LA(1) - if token in [76]: + if token in [74]: self.state = 330 localctx.directAssignment = self.match(PyNestMLParser.EQUALS) pass - elif token in [66]: + elif token in [64]: self.state = 331 localctx.compoundSum = self.match(PyNestMLParser.PLUS_EQUALS) pass - elif token in [67]: + elif token in [65]: self.state = 332 localctx.compoundMinus = self.match(PyNestMLParser.MINUS_EQUALS) pass - elif token in [68]: + elif token in [66]: self.state = 333 localctx.compoundProduct = self.match(PyNestMLParser.STAR_EQUALS) pass - elif token in [69]: + elif token in [67]: self.state = 334 localctx.compoundQuotient = self.match(PyNestMLParser.FORWARD_SLASH_EQUALS) pass @@ -2499,7 +2496,7 @@ def declaration(self): self.state = 340 self._errHandler.sync(self) _la = self._input.LA(1) - if _la==29: + if _la==27: self.state = 339 localctx.isRecordable = self.match(PyNestMLParser.RECORDABLE_KEYWORD) @@ -2507,7 +2504,7 @@ def declaration(self): self.state = 343 self._errHandler.sync(self) _la = self._input.LA(1) - if _la==16: + if _la==14: self.state = 342 localctx.isInlineExpression = self.match(PyNestMLParser.INLINE_KEYWORD) @@ -2517,7 +2514,7 @@ def declaration(self): self.state = 350 self._errHandler.sync(self) _la = self._input.LA(1) - while _la==74: + while _la==72: self.state = 346 self.match(PyNestMLParser.COMMA) self.state = 347 @@ -2531,7 +2528,7 @@ def declaration(self): self.state = 356 self._errHandler.sync(self) _la = self._input.LA(1) - if _la==76: + if _la==74: self.state = 354 self.match(PyNestMLParser.EQUALS) self.state = 355 @@ -2541,7 +2538,7 @@ def declaration(self): self.state = 362 self._errHandler.sync(self) _la = self._input.LA(1) - if _la==59: + if _la==57: self.state = 358 self.match(PyNestMLParser.LEFT_LEFT_SQUARE) self.state = 359 @@ -2553,7 +2550,7 @@ def declaration(self): self.state = 367 self._errHandler.sync(self) _la = self._input.LA(1) - while (((_la) & ~0x3f) == 0 and ((1 << _la) & 246290604621824) != 0): + while (((_la) & ~0x3f) == 0 and ((1 << _la) & 61572651155456) != 0): self.state = 364 localctx.decorator = self.anyDecorator() self.state = 369 @@ -2656,7 +2653,7 @@ def stmtsBody(self): self.state = 374 self._errHandler.sync(self) _la = self._input.LA(1) - if _la==9: + if _la==7: self.state = 373 self.match(PyNestMLParser.NEWLINE) @@ -2666,15 +2663,15 @@ def stmtsBody(self): self.state = 381 self._errHandler.sync(self) _la = self._input.LA(1) - while (((_la) & ~0x3f) == 0 and ((1 << _la) & 543621632) != 0) or _la==89: + while (((_la) & ~0x3f) == 0 and ((1 << _la) & 135905408) != 0) or _la==87: self.state = 379 self._errHandler.sync(self) token = self._input.LA(1) - if token in [9]: + if token in [7]: self.state = 377 self.match(PyNestMLParser.NEWLINE) pass - elif token in [16, 17, 18, 21, 22, 29, 89]: + elif token in [14, 15, 16, 19, 20, 27, 87]: self.state = 378 self.stmt() pass @@ -2732,7 +2729,7 @@ def returnStmt(self): self.state = 386 self._errHandler.sync(self) _la = self._input.LA(1) - if (((_la) & ~0x3f) == 0 and ((1 << _la) & 7318349696466944) != 0) or ((((_la - 75)) & ~0x3f) == 0 and ((1 << (_la - 75)) & 126977) != 0): + if (((_la) & ~0x3f) == 0 and ((1 << _la) & 1829587424116736) != 0) or ((((_la - 73)) & ~0x3f) == 0 and ((1 << (_la - 73)) & 126977) != 0): self.state = 385 self.expression(0) @@ -2792,7 +2789,7 @@ def ifStmt(self): self.state = 392 self._errHandler.sync(self) _la = self._input.LA(1) - while _la==19: + while _la==17: self.state = 389 self.elifClause() self.state = 394 @@ -2802,7 +2799,7 @@ def ifStmt(self): self.state = 396 self._errHandler.sync(self) _la = self._input.LA(1) - if _la==20: + if _la==18: self.state = 395 self.elseClause() @@ -3118,14 +3115,14 @@ def forStmt(self): self.state = 429 self._errHandler.sync(self) _la = self._input.LA(1) - if _la==75: + if _la==73: self.state = 428 localctx.negative = self.match(PyNestMLParser.MINUS) self.state = 431 _la = self._input.LA(1) - if not(_la==90 or _la==91): + if not(_la==88 or _la==89): self._errHandler.recoverInline(self) else: self._errHandler.reportMatch(self) @@ -3269,11 +3266,11 @@ def nestMLCompilationUnit(self): self.state = 448 self._errHandler.sync(self) token = self._input.LA(1) - if token in [31]: + if token in [29]: self.state = 446 self.model() pass - elif token in [9]: + elif token in [7]: self.state = 447 self.match(PyNestMLParser.NEWLINE) pass @@ -3283,7 +3280,7 @@ def nestMLCompilationUnit(self): self.state = 450 self._errHandler.sync(self) _la = self._input.LA(1) - if not (_la==9 or _la==31): + if not (_la==7 or _la==29): break self.state = 452 @@ -3454,35 +3451,35 @@ def modelBody(self): self.state = 469 self._errHandler.sync(self) token = self._input.LA(1) - if token in [32, 33, 34]: + if token in [30, 31, 32]: self.state = 461 self.blockWithVariables() pass - elif token in [36]: + elif token in [34]: self.state = 462 self.equationsBlock() pass - elif token in [37]: + elif token in [35]: self.state = 463 self.inputBlock() pass - elif token in [38]: + elif token in [36]: self.state = 464 self.outputBlock() pass - elif token in [15]: + elif token in [13]: self.state = 465 self.function() pass - elif token in [40]: + elif token in [38]: self.state = 466 self.onReceiveBlock() pass - elif token in [41]: + elif token in [39]: self.state = 467 self.onConditionBlock() pass - elif token in [35]: + elif token in [33]: self.state = 468 self.updateBlock() pass @@ -3492,7 +3489,7 @@ def modelBody(self): self.state = 471 self._errHandler.sync(self) _la = self._input.LA(1) - if not ((((_la) & ~0x3f) == 0 and ((1 << _la) & 3843995762688) != 0)): + if not ((((_la) & ~0x3f) == 0 and ((1 << _la) & 960998940672) != 0)): break self.state = 473 @@ -3583,7 +3580,7 @@ def onReceiveBlock(self): self.state = 482 self._errHandler.sync(self) _la = self._input.LA(1) - while _la==74: + while _la==72: self.state = 478 self.match(PyNestMLParser.COMMA) self.state = 479 @@ -3691,7 +3688,7 @@ def onConditionBlock(self): self.state = 499 self._errHandler.sync(self) _la = self._input.LA(1) - while _la==74: + while _la==72: self.state = 495 self.match(PyNestMLParser.COMMA) self.state = 496 @@ -3779,7 +3776,7 @@ def blockWithVariables(self): self.state = 509 localctx.blockType = self._input.LT(1) _la = self._input.LA(1) - if not((((_la) & ~0x3f) == 0 and ((1 << _la) & 30064771072) != 0)): + if not((((_la) & ~0x3f) == 0 and ((1 << _la) & 7516192768) != 0)): localctx.blockType = self._errHandler.recoverInline(self) else: self._errHandler.reportMatch(self) @@ -3799,7 +3796,7 @@ def blockWithVariables(self): self.state = 516 self._errHandler.sync(self) _la = self._input.LA(1) - if not (_la==16 or _la==29 or _la==89): + if not (_la==14 or _la==27 or _la==87): break self.state = 518 @@ -3955,15 +3952,15 @@ def equationsBlock(self): self.state = 534 self._errHandler.sync(self) token = self._input.LA(1) - if token in [16, 29]: + if token in [14, 27]: self.state = 531 self.inlineExpression() pass - elif token in [89]: + elif token in [87]: self.state = 532 self.odeEquation() pass - elif token in [30]: + elif token in [28]: self.state = 533 self.kernel() pass @@ -3973,7 +3970,7 @@ def equationsBlock(self): self.state = 536 self._errHandler.sync(self) _la = self._input.LA(1) - if not ((((_la) & ~0x3f) == 0 and ((1 << _la) & 1610678272) != 0) or _la==89): + if not ((((_la) & ~0x3f) == 0 and ((1 << _la) & 402669568) != 0) or _la==87): break self.state = 538 @@ -4096,19 +4093,19 @@ def inputBlock(self): self.state = 560 self._errHandler.sync(self) _la = self._input.LA(1) - if _la==49: + if _la==47: self.state = 548 self.match(PyNestMLParser.LEFT_PAREN) self.state = 557 self._errHandler.sync(self) _la = self._input.LA(1) - if _la==89: + if _la==87: self.state = 549 self.parameter() self.state = 554 self._errHandler.sync(self) _la = self._input.LA(1) - while _la==74: + while _la==72: self.state = 550 self.match(PyNestMLParser.COMMA) self.state = 551 @@ -4126,7 +4123,7 @@ def inputBlock(self): self.state = 564 self._errHandler.sync(self) _la = self._input.LA(1) - if not (_la==89): + if not (_la==87): break self.state = 566 @@ -4202,7 +4199,7 @@ def spikeInputPort(self): self.state = 573 self._errHandler.sync(self) _la = self._input.LA(1) - if _la==56: + if _la==54: self.state = 569 self.match(PyNestMLParser.LEFT_SQUARE_BRACKET) self.state = 570 @@ -4216,7 +4213,7 @@ def spikeInputPort(self): self.state = 579 self._errHandler.sync(self) _la = self._input.LA(1) - while _la==43 or _la==44: + while _la==41 or _la==42: self.state = 576 self.inputQualifier() self.state = 581 @@ -4295,7 +4292,7 @@ def continuousInputPort(self): self.state = 590 self._errHandler.sync(self) _la = self._input.LA(1) - if _la==56: + if _la==54: self.state = 586 self.match(PyNestMLParser.LEFT_SQUARE_BRACKET) self.state = 587 @@ -4356,12 +4353,12 @@ def inputQualifier(self): self.state = 599 self._errHandler.sync(self) token = self._input.LA(1) - if token in [43]: + if token in [41]: self.enterOuterAlt(localctx, 1) self.state = 597 localctx.isInhibitory = self.match(PyNestMLParser.INHIBITORY_KEYWORD) pass - elif token in [44]: + elif token in [42]: self.enterOuterAlt(localctx, 2) self.state = 598 localctx.isExcitatory = self.match(PyNestMLParser.EXCITATORY_KEYWORD) @@ -4461,25 +4458,25 @@ def outputBlock(self): self.state = 621 self._errHandler.sync(self) token = self._input.LA(1) - if token in [42]: + if token in [40]: self.state = 605 localctx.isSpike = self.match(PyNestMLParser.SPIKE_KEYWORD) self.state = 618 self._errHandler.sync(self) _la = self._input.LA(1) - if _la==49: + if _la==47: self.state = 606 self.match(PyNestMLParser.LEFT_PAREN) self.state = 615 self._errHandler.sync(self) _la = self._input.LA(1) - if _la==89: + if _la==87: self.state = 607 localctx.attribute = self.parameter() self.state = 612 self._errHandler.sync(self) _la = self._input.LA(1) - while _la==74: + while _la==72: self.state = 608 self.match(PyNestMLParser.COMMA) self.state = 609 @@ -4495,7 +4492,7 @@ def outputBlock(self): pass - elif token in [39]: + elif token in [37]: self.state = 620 localctx.isContinuous = self.match(PyNestMLParser.CONTINUOUS_KEYWORD) pass @@ -4596,13 +4593,13 @@ def function(self): self.state = 637 self._errHandler.sync(self) _la = self._input.LA(1) - if _la==89: + if _la==87: self.state = 629 self.parameter() self.state = 634 self._errHandler.sync(self) _la = self._input.LA(1) - while _la==74: + while _la==72: self.state = 630 self.match(PyNestMLParser.COMMA) self.state = 631 @@ -4618,7 +4615,7 @@ def function(self): self.state = 641 self._errHandler.sync(self) _la = self._input.LA(1) - if (((_la) & ~0x3f) == 0 and ((1 << _la) & 562949953453056) != 0) or _la==89 or _la==90: + if (((_la) & ~0x3f) == 0 and ((1 << _la) & 140737488363264) != 0) or _la==87 or _la==88: self.state = 640 localctx.returnType = self.dataType() @@ -4743,7 +4740,7 @@ def constParameter(self): self.state = 654 localctx.value = self._input.LT(1) _la = self._input.LA(1) - if not(_la==25 or ((((_la - 87)) & ~0x3f) == 0 and ((1 << (_la - 87)) & 27) != 0)): + if not(_la==23 or ((((_la - 85)) & ~0x3f) == 0 and ((1 << (_la - 85)) & 27) != 0)): localctx.value = self._errHandler.recoverInline(self) else: self._errHandler.reportMatch(self) diff --git a/pynestml/grammars/PyNestMLLexer.g4 b/pynestml/grammars/PyNestMLLexer.g4 index 9b562117d..591fc56ab 100644 --- a/pynestml/grammars/PyNestMLLexer.g4 +++ b/pynestml/grammars/PyNestMLLexer.g4 @@ -31,7 +31,6 @@ lexer grammar PyNestMLLexer; // N.B. the zeroth channel is the normal channel, the first is HIDDEN, so COMMENT=2 channels { COMMENT } - DOCSTRING_TRIPLEQUOTE : '"""'; fragment NEWLINE_FRAG : '\r'? '\n'; // non-capturing newline, as a helper to define the channel rules KERNEL_JOINING : COMMA NEWLINE_FRAG WS?; @@ -41,8 +40,6 @@ lexer grammar PyNestMLLexer; // this token enables an expression that stretches over multiple lines. The first line ends with a `\` character LINE_ESCAPE : '\\' NEWLINE_FRAG -> channel(1); - DOCSTRING : DOCSTRING_TRIPLEQUOTE .*? DOCSTRING_TRIPLEQUOTE NEWLINE_FRAG+? -> channel(2); - SL_COMMENT : ('#' (~('\n' | '\r'))* ) -> channel(2); // we cannot capture the final \n here, because the comment might appear to the right of an expression // newline is handled inside the ``onNewLine()`` method of the PyNestMLLexerBase class diff --git a/pynestml/visitors/comment_collector_visitor.py b/pynestml/visitors/comment_collector_visitor.py index 326e5c67a..1bd9ac517 100644 --- a/pynestml/visitors/comment_collector_visitor.py +++ b/pynestml/visitors/comment_collector_visitor.py @@ -22,6 +22,7 @@ from typing import List, Optional from pynestml.generated.PyNestMLParserVisitor import PyNestMLParserVisitor +from pynestml.generated.PyNestMLParser import PyNestMLParser class CommentCollectorVisitor(PyNestMLParserVisitor): @@ -38,12 +39,30 @@ def __init__(self, tokens, strip_delim: bool = True): tokens A list of all tokens representing the model. strip_delim - Whether to strip the comment delimiters (``#`` and ``\"\"\"``...``\"\"\"``). + Whether to strip the comment delimiters (``#``). """ self.__tokens = tokens self.__strip_delim = strip_delim + @classmethod + def dedent(cls, strings): + # Find the minimum leading spaces among all non-empty lines + min_indent = None + for s in strings: + stripped = s.lstrip() + if stripped: # ignore fully blank or whitespace-only lines for indent calculation + indent = len(s) - len(stripped) + if min_indent is None or indent < min_indent: + min_indent = indent + + # If all lines are empty or whitespace-only, set min_indent to 0 + if min_indent is None: + min_indent = 0 + + # Dedent each line by the minimum indent found + return [s[min_indent:] for s in strings] + def visitBlockWithVariables(self, ctx): return (get_comments(ctx, self.__tokens, self.__strip_delim), get_pre_comments(ctx, self.__tokens, self.__strip_delim), get_in_comment(ctx, self.__tokens, self.__strip_delim)) @@ -163,15 +182,15 @@ def visitElseClause(self, ctx): def is_newline(tok): - return tok.type == 9 # NEWLINE token + return tok.type == PyNestMLParser.NEWLINE def is_indent(tok): - return tok.type == 1 # INDENT token + return tok.type == PyNestMLParser.INDENT def is_dedent(tok): - return tok.type == 2 # DEDENT token + return tok.type == PyNestMLParser.DEDENT def get_comments(ctx, tokens, strip_delim: bool = True) -> List[str]: @@ -202,9 +221,10 @@ def get_pre_comments(ctx, tokens, strip_delim: bool = True) -> List[str]: :type tokens: list(Tokens) :return: the corresponding comments """ - # first find the position of this token in the stream comments = list() empty_before = __no_definitions_before(ctx, tokens) + + # first find the position of this token in the stream temp = None lastToken = None for possibleCommentToken in reversed(tokens[0:tokens.index(ctx.start)]): @@ -212,19 +232,21 @@ def get_pre_comments(ctx, tokens, strip_delim: bool = True) -> List[str]: if possibleCommentToken.channel == 0 \ and not (is_newline(possibleCommentToken) or is_indent(possibleCommentToken) or is_dedent(possibleCommentToken)): + # This is to omit the inline comments that are parsed - if is_newline(lastToken) and temp is not None: + if lastToken is not None and is_newline(lastToken) and temp is not None: comments.append(temp) + break # a newline on comment channel (2) by itself separates elements if possibleCommentToken.channel == 2 and is_newline(possibleCommentToken) and is_newline(lastToken): if temp is not None: comments.append(temp) + break - # if we have found a comment, put it on the "stack". we now have to check if there is an element defined - # in the same line, since in this case, the comments does not belong to us + # if we have found a comment, put it on the "stack". we now have to check if there is an element defined in the same line, since in this case, the comments does not belong to us if possibleCommentToken.channel == 2 and not is_newline(possibleCommentToken): if temp is not None: comments.append(temp) @@ -232,25 +254,18 @@ def get_pre_comments(ctx, tokens, strip_delim: bool = True) -> List[str]: temp = replace_delimiters(possibleCommentToken.text) else: temp = possibleCommentToken.text + lastToken = possibleCommentToken # this last part is required in the case, that the very first token is a comment if empty_before and temp is not None and temp not in comments: comments.append(temp) - # strip leading newlines -- this removes the newline after an opening ``"""`` if present - for i, comment in enumerate(comments): - if len(comment) > 0 and comment[0] == '\n': - comments[i] = comment[1:] - if len(comment) > 1 and comment[0] == '\r' and comment[1] == '\n': - comments[i] = comment[2:] - # strip trailing newlines - for i, comment in enumerate(comments): - if len(comment) > 0 and comment[-1] == '\n': - comments[i] = comment[:-1] - if len(comment) > 1 and comment[-1] == '\n' and comment[-2] == '\r': - comments[i] = comment[:-2] + + if strip_delim: + comments = CommentCollectorVisitor.dedent(comments) + # we reverse it in order to get the right order of comments - return list(reversed(comments)) if len(comments) > 0 else list() + return list(reversed(comments)) def __no_definitions_before(ctx, tokens): @@ -303,13 +318,11 @@ def get_in_comment(ctx, tokens, strip_delim: bool = True) -> Optional[str]: def replace_delimiters(comment: str) -> str: """ - Returns the raw comment, i.e., without the comment delimiters (``#`` or ``\"\"\"``...``\"\"\"``). + Returns the raw comment, i.e., without the comment delimiters (``#``). """ - if len(comment) > 2 and comment[:2] == "\"\"\"": - # it's a docstring comment - return comment.replace("\"\"\"", "") # it's a hash comment if len(comment) > 0 and comment[0] == "#": # strip initial character hash comment = comment[1:] + return comment.replace('\n#', '').replace('\r\n#', '') diff --git a/tests/docstring_comment_test.py b/tests/docstring_comment_test.py index c31c42449..1b80c3de0 100644 --- a/tests/docstring_comment_test.py +++ b/tests/docstring_comment_test.py @@ -21,11 +21,9 @@ import os import pytest -import unittest from antlr4 import * from antlr4.error.ErrorStrategy import BailErrorStrategy -from antlr4.error.Errors import ParseCancellationException from pynestml.generated.PyNestMLLexer import PyNestMLLexer from pynestml.generated.PyNestMLParser import PyNestMLParser @@ -39,25 +37,26 @@ from pynestml.visitors.ast_builder_visitor import ASTBuilderVisitor -# setups the infrastructure -PredefinedUnits.register_units() -PredefinedTypes.register_types() -PredefinedFunctions.register_functions() -PredefinedVariables.register_variables() -SymbolTable.initialize_symbol_table(ASTSourceLocation(start_line=0, start_column=0, end_line=0, end_column=0)) -Logger.init_logger(LoggingLevel.ERROR) - - class DocstringCommentException(Exception): pass -class DocstringCommentTest(unittest.TestCase): +class TestDocstringComment: + + @pytest.fixture(scope="module", autouse=True) + def setUp(self): + r"""sets up the infrastructure""" + PredefinedUnits.register_units() + PredefinedTypes.register_types() + PredefinedFunctions.register_functions() + PredefinedVariables.register_variables() + SymbolTable.initialize_symbol_table(ASTSourceLocation(start_line=0, start_column=0, end_line=0, end_column=0)) + Logger.init_logger(LoggingLevel.ERROR) def test_docstring_success(self): self.run_docstring_test('valid') - @pytest.mark.xfail(strict=True, raises=ParseCancellationException) + @pytest.mark.xfail(strict=True) def test_docstring_failure(self): self.run_docstring_test('invalid') @@ -83,6 +82,4 @@ def run_docstring_test(self, case: str): assert len(ast.get_model_list()) == 1, "Model failed to load correctly" - -if __name__ == '__main__': - unittest.main() + assert "\n".join(ast.get_model_list()[0].pre_comments) == "DocstringCommentTest.nestml\n###########################\n\n\nDescription\n+++++++++++\n\nThis model is used to test whether docstring comments are detected.\n\nPositive case.\n\n\nCopyright statement\n+++++++++++++++++++\n\nThis file is part of NEST.\n\nCopyright (C) 2004 The NEST Initiative\n\nNEST is free software: you can redistribute it and/or modify\nit under the terms of the GNU General Public License as published by\nthe Free Software Foundation, either version 2 of the License, or\n(at your option) any later version.\n\nNEST is distributed in the hope that it will be useful,\nbut WITHOUT ANY WARRANTY; without even the implied warranty of\nMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\nGNU General Public License for more details.\n\nYou should have received a copy of the GNU General Public License\nalong with NEST. If not, see .\n" diff --git a/tests/invalid/CoCoAssignmentToInlineExpression.nestml b/tests/invalid/CoCoAssignmentToInlineExpression.nestml index 2f807328d..3484b87f2 100644 --- a/tests/invalid/CoCoAssignmentToInlineExpression.nestml +++ b/tests/invalid/CoCoAssignmentToInlineExpression.nestml @@ -1,28 +1,27 @@ -""" -CoCoAssignmentToInlineExpression.nestml -####################################### - - -Copyright statement -+++++++++++++++++++ - -This file is part of NEST. - -Copyright (C) 2004 The NEST Initiative - -NEST is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -NEST is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with NEST. If not, see . -""" +# CoCoAssignmentToInlineExpression.nestml +# ####################################### +# +# +# Copyright statement +# +++++++++++++++++++ +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . +# model CoCoAssignmentToInlineExpression: parameters: tau_syn ms = 10 ms diff --git a/tests/invalid/CoCoConvolveNotCorrectlyParametrized.nestml b/tests/invalid/CoCoConvolveNotCorrectlyParametrized.nestml index 2a0a760eb..1ca5cf78a 100644 --- a/tests/invalid/CoCoConvolveNotCorrectlyParametrized.nestml +++ b/tests/invalid/CoCoConvolveNotCorrectlyParametrized.nestml @@ -1,36 +1,35 @@ -""" -CoCoConvolveNotCorrectlyParametrized.nestml -########################################### - - -Description -+++++++++++ - -This model is used to test if broken CoCos are identified correctly. Here, if convolve has been correctly provided with a state block defined variable and a spike input port. - -Negative case. - - -Copyright statement -+++++++++++++++++++ - -This file is part of NEST. - -Copyright (C) 2004 The NEST Initiative - -NEST is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -NEST is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with NEST. If not, see . -""" +# CoCoConvolveNotCorrectlyParametrized.nestml +# ########################################### +# +# +# Description +# +++++++++++ +# +# This model is used to test if broken CoCos are identified correctly. Here, if convolve has been correctly provided with a state block defined variable and a spike input port. +# +# Negative case. +# +# +# Copyright statement +# +++++++++++++++++++ +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . +# model CoCoConvolveNotCorrectlyParametrized: state: V_m mV = 10mV diff --git a/tests/invalid/CoCoConvolveNotCorrectlyProvided.nestml b/tests/invalid/CoCoConvolveNotCorrectlyProvided.nestml index 85fc57159..7e44fdaec 100644 --- a/tests/invalid/CoCoConvolveNotCorrectlyProvided.nestml +++ b/tests/invalid/CoCoConvolveNotCorrectlyProvided.nestml @@ -1,36 +1,35 @@ -""" -CoCoConvolveNotCorrectlyProvided.nestml -####################################### - - -Description -+++++++++++ - -This model is used to test if broken CoCos are identified correctly. Here, if convolve has been correctly provided with a state block defined variable and a spike input port. - -Negative case. - - -Copyright statement -+++++++++++++++++++ - -This file is part of NEST. - -Copyright (C) 2004 The NEST Initiative - -NEST is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -NEST is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with NEST. If not, see . -""" +# CoCoConvolveNotCorrectlyProvided.nestml +# ####################################### +# +# +# Description +# +++++++++++ +# +# This model is used to test if broken CoCos are identified correctly. Here, if convolve has been correctly provided with a state block defined variable and a spike input port. +# +# Negative case. +# +# +# Copyright statement +# +++++++++++++++++++ +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . +# model CoCoConvolveNotCorrectlyProvided: state: V_m mV = 10mV diff --git a/tests/invalid/CoCoEachBlockUnique.nestml b/tests/invalid/CoCoEachBlockUnique.nestml index 7ad8eb54d..3a84dd5c9 100644 --- a/tests/invalid/CoCoEachBlockUnique.nestml +++ b/tests/invalid/CoCoEachBlockUnique.nestml @@ -1,36 +1,35 @@ -""" -CoCoEachBlockUnique.nestml -########################## - - -Description -+++++++++++ - -This model is used to test if broken CoCos are identified correctly. Here, if each block is defined at most once. - -Negative case. - - -Copyright statement -+++++++++++++++++++ - -This file is part of NEST. - -Copyright (C) 2004 The NEST Initiative - -NEST is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -NEST is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with NEST. If not, see . -""" +# CoCoEachBlockUnique.nestml +# ########################## +# +# +# Description +# +++++++++++ +# +# This model is used to test if broken CoCos are identified correctly. Here, if each block is defined at most once. +# +# Negative case. +# +# +# Copyright statement +# +++++++++++++++++++ +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . +# model CoCoEachBlockUnique: state: test1 integer = 0 diff --git a/tests/invalid/CoCoElementInSameLine.nestml b/tests/invalid/CoCoElementInSameLine.nestml index 32a65c4f2..85b749f6f 100644 --- a/tests/invalid/CoCoElementInSameLine.nestml +++ b/tests/invalid/CoCoElementInSameLine.nestml @@ -1,37 +1,36 @@ -""" -CoCoElementInSameLine.nestml -############################ - - -Description -+++++++++++ - -This model is used to check if all cocos work correctly by detecting corresponding broken context. Here, if -recursive definition is detected. - -Negative case. - - -Copyright statement -+++++++++++++++++++ - -This file is part of NEST. - -Copyright (C) 2004 The NEST Initiative - -NEST is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -NEST is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with NEST. If not, see . -""" +# CoCoElementInSameLine.nestml +# ############################ +# +# +# Description +# +++++++++++ +# +# This model is used to check if all cocos work correctly by detecting corresponding broken context. Here, if +# recursive definition is detected. +# +# Negative case. +# +# +# Copyright statement +# +++++++++++++++++++ +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . +# model CoCoElementInSameLine: state: test1 integer = test1 # case 1: variable set to value as currently declared diff --git a/tests/invalid/CoCoElementNotDefined.nestml b/tests/invalid/CoCoElementNotDefined.nestml index 116997d0b..dc83c4f67 100644 --- a/tests/invalid/CoCoElementNotDefined.nestml +++ b/tests/invalid/CoCoElementNotDefined.nestml @@ -1,37 +1,36 @@ -""" -CoCoElementNotDefined.nestml -############################ - - -Description -+++++++++++ - -This model is used to check if all cocos work correctly by detecting corresponding broken context. Here, if -definition with not defined references is detected. - -Negative case. - - -Copyright statement -+++++++++++++++++++ - -This file is part of NEST. - -Copyright (C) 2004 The NEST Initiative - -NEST is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -NEST is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with NEST. If not, see . -""" +# CoCoElementNotDefined.nestml +# ############################ +# +# +# Description +# +++++++++++ +# +# This model is used to check if all cocos work correctly by detecting corresponding broken context. Here, if +# definition with not defined references is detected. +# +# Negative case. +# +# +# Copyright statement +# +++++++++++++++++++ +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . +# model CoCoElementNotDefined: state: test1 integer = test2 # case 1: variable set to a not defined value diff --git a/tests/invalid/CoCoFunctionCallNotConsistentWrongArgNumber.nestml b/tests/invalid/CoCoFunctionCallNotConsistentWrongArgNumber.nestml index 4c968ce12..673d0abd0 100644 --- a/tests/invalid/CoCoFunctionCallNotConsistentWrongArgNumber.nestml +++ b/tests/invalid/CoCoFunctionCallNotConsistentWrongArgNumber.nestml @@ -1,36 +1,35 @@ -""" -CoCoFunctionCallNotConsistentWrongArgNumber.nestml -################################################## - - -Description -+++++++++++ - -This model is used to test if broken CoCos are identified correctly. Here, if function calls have the right number of arguments. - -Negative case. - - -Copyright statement -+++++++++++++++++++ - -This file is part of NEST. - -Copyright (C) 2004 The NEST Initiative - -NEST is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -NEST is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with NEST. If not, see . -""" +# CoCoFunctionCallNotConsistentWrongArgNumber.nestml +# ################################################## +# +# +# Description +# +++++++++++ +# +# This model is used to test if broken CoCos are identified correctly. Here, if function calls have the right number of arguments. +# +# Negative case. +# +# +# Copyright statement +# +++++++++++++++++++ +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . +# model CoCoFunctionCallNotConsistentWrongArgNumber: state: test integer = max(1,2,3) # wrong number of args diff --git a/tests/invalid/CoCoFunctionNotUnique.nestml b/tests/invalid/CoCoFunctionNotUnique.nestml index 0bdd513f1..294ba64b4 100644 --- a/tests/invalid/CoCoFunctionNotUnique.nestml +++ b/tests/invalid/CoCoFunctionNotUnique.nestml @@ -1,37 +1,36 @@ -""" -CoCoFunctionNotUnique.nestml -############################ - - -Description -+++++++++++ - -This model is used to test if broken CoCos are identified correctly. Here, if redeclaration of predefined functions -is detected. - -Negative case. - - -Copyright statement -+++++++++++++++++++ - -This file is part of NEST. - -Copyright (C) 2004 The NEST Initiative - -NEST is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -NEST is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with NEST. If not, see . -""" +# CoCoFunctionNotUnique.nestml +# ############################ +# +# +# Description +# +++++++++++ +# +# This model is used to test if broken CoCos are identified correctly. Here, if redeclaration of predefined functions +# is detected. +# +# Negative case. +# +# +# Copyright statement +# +++++++++++++++++++ +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . +# model CoCoFunctionNotUnique: function max(Tau_a ms,Tau_b ms) real: # redeclaration should be detected test real = 1 diff --git a/tests/invalid/CoCoFunctionRedeclared.nestml b/tests/invalid/CoCoFunctionRedeclared.nestml index de5a2ccdf..9983fc2b0 100644 --- a/tests/invalid/CoCoFunctionRedeclared.nestml +++ b/tests/invalid/CoCoFunctionRedeclared.nestml @@ -1,37 +1,36 @@ -""" -CoCoFunctionRedeclared.nestml -############################# - - -Description -+++++++++++ - -This model is used to check if all cocos work correctly by detecting corresponding broken context. -Here, if redeclaration of functions has been detected. - -Negative case. - - -Copyright statement -+++++++++++++++++++ - -This file is part of NEST. - -Copyright (C) 2004 The NEST Initiative - -NEST is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -NEST is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with NEST. If not, see . -""" +# CoCoFunctionRedeclared.nestml +# ############################# +# +# +# Description +# +++++++++++ +# +# This model is used to check if all cocos work correctly by detecting corresponding broken context. +# Here, if redeclaration of functions has been detected. +# +# Negative case. +# +# +# Copyright statement +# +++++++++++++++++++ +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . +# model CoCoFunctionRedeclared: function max(arg1 integer,arg2 integer) integer: if arg1>arg2: diff --git a/tests/invalid/CoCoIllegalExpression.nestml b/tests/invalid/CoCoIllegalExpression.nestml index 7e54c5e01..36ac44331 100644 --- a/tests/invalid/CoCoIllegalExpression.nestml +++ b/tests/invalid/CoCoIllegalExpression.nestml @@ -1,37 +1,36 @@ -""" -CoCoIllegalExpression.nestml -############################ - - -Description -+++++++++++ - -This model is used to test if broken CoCos are identified correctly. Here, illegal expressions, e.g. -type(lhs)!= type(rhs) are detected. - -Negative case. - - -Copyright statement -+++++++++++++++++++ - -This file is part of NEST. - -Copyright (C) 2004 The NEST Initiative - -NEST is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -NEST is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with NEST. If not, see . -""" +# CoCoIllegalExpression.nestml +# ############################ +# +# +# Description +# +++++++++++ +# +# This model is used to test if broken CoCos are identified correctly. Here, illegal expressions, e.g. +# type(lhs)!= type(rhs) are detected. +# +# Negative case. +# +# +# Copyright statement +# +++++++++++++++++++ +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . +# model CoCoIllegalExpression: state: test boolean = True diff --git a/tests/invalid/CoCoIncorrectReturnStatement.nestml b/tests/invalid/CoCoIncorrectReturnStatement.nestml index f42e8bab8..c3f1c1463 100644 --- a/tests/invalid/CoCoIncorrectReturnStatement.nestml +++ b/tests/invalid/CoCoIncorrectReturnStatement.nestml @@ -1,37 +1,36 @@ -""" -CoCoIncorrectReturnStatement.nestml -################################### - - -Description -+++++++++++ - -This model is used to test if broken CoCos are identified correctly. Here, if user defined functions without -a proper return statement and wrong type are detected. - -Negative case. - - -Copyright statement -+++++++++++++++++++ - -This file is part of NEST. - -Copyright (C) 2004 The NEST Initiative - -NEST is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -NEST is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with NEST. If not, see . -""" +# CoCoIncorrectReturnStatement.nestml +# ################################### +# +# +# Description +# +++++++++++ +# +# This model is used to test if broken CoCos are identified correctly. Here, if user defined functions without +# a proper return statement and wrong type are detected. +# +# Negative case. +# +# +# Copyright statement +# +++++++++++++++++++ +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . +# model CoCoIncorrectReturnStatement: function foo() mV: test mV = 10mV diff --git a/tests/invalid/CoCoInitValuesWithoutOde.nestml b/tests/invalid/CoCoInitValuesWithoutOde.nestml index 27ab5b7de..d43bdf52f 100644 --- a/tests/invalid/CoCoInitValuesWithoutOde.nestml +++ b/tests/invalid/CoCoInitValuesWithoutOde.nestml @@ -1,37 +1,36 @@ -""" -CoCoInitValuesWithoutOde.nestml -############################### - - -Description -+++++++++++ - -This model is used to test if broken CoCos are identified correctly. Here, if initial block variables without ode -declarations are detected. Moreover, if initial values without a right-hand side are detected. - -Negative case. - - -Copyright statement -+++++++++++++++++++ - -This file is part of NEST. - -Copyright (C) 2004 The NEST Initiative - -NEST is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -NEST is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with NEST. If not, see . -""" +# CoCoInitValuesWithoutOde.nestml +# ############################### +# +# +# Description +# +++++++++++ +# +# This model is used to test if broken CoCos are identified correctly. Here, if initial block variables without ode +# declarations are detected. Moreover, if initial values without a right-hand side are detected. +# +# Negative case. +# +# +# Copyright statement +# +++++++++++++++++++ +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . +# model CoCoInitValuesWithoutOde: state: V_m mV = 10 mV diff --git a/tests/invalid/CoCoInlineExpressionHasNoRhs.nestml b/tests/invalid/CoCoInlineExpressionHasNoRhs.nestml index 6be931451..58c86b163 100644 --- a/tests/invalid/CoCoInlineExpressionHasNoRhs.nestml +++ b/tests/invalid/CoCoInlineExpressionHasNoRhs.nestml @@ -1,36 +1,35 @@ -""" -CoCoInlineExpressionHasNoRhs.nestml -################################### - - -Description -+++++++++++ - -This model is used to check if all cocos work correctly by detecting corresponding broken context. Here, if a inline does not a rhs. - -Negative case. - - -Copyright statement -+++++++++++++++++++ - -This file is part of NEST. - -Copyright (C) 2004 The NEST Initiative - -NEST is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -NEST is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with NEST. If not, see . -""" +# CoCoInlineExpressionHasNoRhs.nestml +# ################################### +# +# +# Description +# +++++++++++ +# +# This model is used to check if all cocos work correctly by detecting corresponding broken context. Here, if a inline does not a rhs. +# +# Negative case. +# +# +# Copyright statement +# +++++++++++++++++++ +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . +# model CoCoInlineExpressionHasNoRhs: equations: inline V_rest mV # the missing rhs should be detected diff --git a/tests/invalid/CoCoInlineExpressionWithSeveralLhs.nestml b/tests/invalid/CoCoInlineExpressionWithSeveralLhs.nestml index 8ba8c8dd5..e2a8e27ca 100644 --- a/tests/invalid/CoCoInlineExpressionWithSeveralLhs.nestml +++ b/tests/invalid/CoCoInlineExpressionWithSeveralLhs.nestml @@ -1,36 +1,35 @@ -""" -CoCoInlineExpressionWithSeveralLhs.nestml -######################################### - - -Description -+++++++++++ - -This model is used to check if all cocos work correctly by detecting corresponding broken context. Here, if a inline with several lhs is detected. - -Negative case. - - -Copyright statement -+++++++++++++++++++ - -This file is part of NEST. - -Copyright (C) 2004 The NEST Initiative - -NEST is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -NEST is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with NEST. If not, see . -""" +# CoCoInlineExpressionWithSeveralLhs.nestml +# ######################################### +# +# +# Description +# +++++++++++ +# +# This model is used to check if all cocos work correctly by detecting corresponding broken context. Here, if a inline with several lhs is detected. +# +# Negative case. +# +# +# Copyright statement +# +++++++++++++++++++ +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . +# model CoCoInlineExpressionWithSeveralLhs: equations: inline V_rest,V_reset mV = 10mV # several lhs's should be detected diff --git a/tests/invalid/CoCoInputPortWithRedundantTypes.nestml b/tests/invalid/CoCoInputPortWithRedundantTypes.nestml index 8d3809c1b..811cd63c4 100644 --- a/tests/invalid/CoCoInputPortWithRedundantTypes.nestml +++ b/tests/invalid/CoCoInputPortWithRedundantTypes.nestml @@ -1,36 +1,35 @@ -""" -CoCoInputPortWithRedundantTypes.nestml -###################################### - - -Description -+++++++++++ - -This model is used to test if broken CoCos are identified correctly. Here, if each input port is defined uniquely, i.e., no redundant keywords are used. - -Negative case. - - -Copyright statement -+++++++++++++++++++ - -This file is part of NEST. - -Copyright (C) 2004 The NEST Initiative - -NEST is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -NEST is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with NEST. If not, see . -""" +# CoCoInputPortWithRedundantTypes.nestml +# ###################################### +# +# +# Description +# +++++++++++ +# +# This model is used to test if broken CoCos are identified correctly. Here, if each input port is defined uniquely, i.e., no redundant keywords are used. +# +# Negative case. +# +# +# Copyright statement +# +++++++++++++++++++ +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . +# model CoCoInputPortWithRedundantTypes: input: spikeInhX2 <- inhibitory inhibitory spike # spike redundant keywords used diff --git a/tests/invalid/CoCoIntegrateOdesCalledIfEquationsDefined.nestml b/tests/invalid/CoCoIntegrateOdesCalledIfEquationsDefined.nestml index 8318c30b4..1af586c72 100644 --- a/tests/invalid/CoCoIntegrateOdesCalledIfEquationsDefined.nestml +++ b/tests/invalid/CoCoIntegrateOdesCalledIfEquationsDefined.nestml @@ -1,36 +1,35 @@ -""" -CoCoIntegrateOdesCalledIfEquationsDefined.nestml -################################################ - - -Description -+++++++++++ - -This model is used to test the check that integrate_odes() is called if one or more dynamical equations are defined. - -Negative case. - - -Copyright statement -+++++++++++++++++++ - -This file is part of NEST. - -Copyright (C) 2004 The NEST Initiative - -NEST is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -NEST is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with NEST. If not, see . -""" +# CoCoIntegrateOdesCalledIfEquationsDefined.nestml +# ################################################ +# +# +# Description +# +++++++++++ +# +# This model is used to test the check that integrate_odes() is called if one or more dynamical equations are defined. +# +# Negative case. +# +# +# Copyright statement +# +++++++++++++++++++ +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . +# model CoCoIntegrateOdesCalledIfEquationsDefined: state: x real = 1. diff --git a/tests/invalid/CoCoInternalAssignedOutsideBlock.nestml b/tests/invalid/CoCoInternalAssignedOutsideBlock.nestml index 8a8f65bbd..1cf73fef2 100644 --- a/tests/invalid/CoCoInternalAssignedOutsideBlock.nestml +++ b/tests/invalid/CoCoInternalAssignedOutsideBlock.nestml @@ -1,37 +1,36 @@ -""" -CoCoInternalAssignedOutsideBlock.nestml -######################################## - - -Description -+++++++++++ - -This model is used to check if all cocos work correctly by detecting corresponding broken context. Here, if -assignment of values to internals outside of internals blocks is detected. - -Negative case. - - -Copyright statement -+++++++++++++++++++ - -This file is part of NEST. - -Copyright (C) 2004 The NEST Initiative - -NEST is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -NEST is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with NEST. If not, see . -""" +# CoCoInternalAssignedOutsideBlock.nestml +# ######################################## +# +# +# Description +# +++++++++++ +# +# This model is used to check if all cocos work correctly by detecting corresponding broken context. Here, if +# assignment of values to internals outside of internals blocks is detected. +# +# Negative case. +# +# +# Copyright statement +# +++++++++++++++++++ +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . +# model CoCoInternalAssignedOutsideBlock: internals: test mV = 10 mV diff --git a/tests/invalid/CoCoInvariantNotBool.nestml b/tests/invalid/CoCoInvariantNotBool.nestml index 7ba1ad35c..a51f20b5e 100644 --- a/tests/invalid/CoCoInvariantNotBool.nestml +++ b/tests/invalid/CoCoInvariantNotBool.nestml @@ -1,37 +1,36 @@ -""" -CoCoInvariantNotBool.nestml -########################### - - -Description -+++++++++++ - -This model is used to test if broken CoCos are identified correctly. Here, if the correct type of invariants -is detected and invariants are correctly constructed. - -Negative case. - - -Copyright statement -+++++++++++++++++++ - -This file is part of NEST. - -Copyright (C) 2004 The NEST Initiative - -NEST is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -NEST is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with NEST. If not, see . -""" +# CoCoInvariantNotBool.nestml +# ########################### +# +# +# Description +# +++++++++++ +# +# This model is used to test if broken CoCos are identified correctly. Here, if the correct type of invariants +# is detected and invariants are correctly constructed. +# +# Negative case. +# +# +# Copyright statement +# +++++++++++++++++++ +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . +# model CoCoInvariantNotBool: state: V_notBool mV = 10mV [[V_notBool + V_notBool]] # here a non boolean invariant should be detected diff --git a/tests/invalid/CoCoKernelType.nestml b/tests/invalid/CoCoKernelType.nestml index 12bb23273..a33d92c13 100644 --- a/tests/invalid/CoCoKernelType.nestml +++ b/tests/invalid/CoCoKernelType.nestml @@ -1,38 +1,37 @@ -""" -CoCoKernelCorrectlyTyped.nestml -############################### - - -Description -+++++++++++ - -This model is used to test if broken CoCos are identified correctly. - -Here, the kernel is defined with an incorrect type. - -Negative case. - - -Copyright statement -+++++++++++++++++++ - -This file is part of NEST. - -Copyright (C) 2004 The NEST Initiative - -NEST is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -NEST is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with NEST. If not, see . -""" +# CoCoKernelCorrectlyTyped.nestml +# ############################### +# +# +# Description +# +++++++++++ +# +# This model is used to test if broken CoCos are identified correctly. +# +# Here, the kernel is defined with an incorrect type. +# +# Negative case. +# +# +# Copyright statement +# +++++++++++++++++++ +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . +# model CoCoKernelCorrectlyTyped: parameters: tau ms = 10 ms diff --git a/tests/invalid/CoCoKernelTypeInitialValues.nestml b/tests/invalid/CoCoKernelTypeInitialValues.nestml index 4b13da364..84d871c53 100644 --- a/tests/invalid/CoCoKernelTypeInitialValues.nestml +++ b/tests/invalid/CoCoKernelTypeInitialValues.nestml @@ -1,38 +1,37 @@ -""" -CoCoKernelCorrectlyTyped.nestml -############################### - - -Description -+++++++++++ - -This model is used to test if broken CoCos are identified correctly. - -Here, the kernel is defined with an incorrect type. - -Negative case. - - -Copyright statement -+++++++++++++++++++ - -This file is part of NEST. - -Copyright (C) 2004 The NEST Initiative - -NEST is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -NEST is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with NEST. If not, see . -""" +# CoCoKernelCorrectlyTyped.nestml +# ############################### +# +# +# Description +# +++++++++++ +# +# This model is used to test if broken CoCos are identified correctly. +# +# Here, the kernel is defined with an incorrect type. +# +# Negative case. +# +# +# Copyright statement +# +++++++++++++++++++ +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . +# model CoCoKernelCorrectlyTyped: parameters: tau ms = 10 ms diff --git a/tests/invalid/CoCoMultipleNeuronsWithEqualName.nestml b/tests/invalid/CoCoMultipleNeuronsWithEqualName.nestml index 084488ed4..5ee88b3d4 100644 --- a/tests/invalid/CoCoMultipleNeuronsWithEqualName.nestml +++ b/tests/invalid/CoCoMultipleNeuronsWithEqualName.nestml @@ -1,41 +1,41 @@ -""" -CoCoMultipleNeuronsWithEqualName.nestml -####################################### - - -Description -+++++++++++ - -This model is used to test if broken CoCos are identified correctly. Here, if several neurons with equal name -are detected. - -Negative case. - - -Copyright statement -+++++++++++++++++++ - -This file is part of NEST. - -Copyright (C) 2004 The NEST Initiative - -NEST is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -NEST is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with NEST. If not, see . -""" +# CoCoMultipleNeuronsWithEqualName.nestml +# ####################################### +# +# +# Description +# +++++++++++ +# +# This model is used to test if broken CoCos are identified correctly. Here, if several neurons with equal name +# are detected. +# +# Negative case. +# +# +# Copyright statement +# +++++++++++++++++++ +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . +# model CoCoMultipleNeuronsWithEqualName: state: v_m mV = -10 mV +# model CoCoMultipleNeuronsWithEqualName: state: v_m mV = -55 mV diff --git a/tests/invalid/CoCoNestNamespaceCollision.nestml b/tests/invalid/CoCoNestNamespaceCollision.nestml index ab6140b06..126d50a72 100644 --- a/tests/invalid/CoCoNestNamespaceCollision.nestml +++ b/tests/invalid/CoCoNestNamespaceCollision.nestml @@ -1,37 +1,36 @@ -""" -CoCoNestNamespaceCollision.nestml -################################# - - -Description -+++++++++++ - -This model is used to test if broken CoCos are identified correctly. Here, if the collision with the nest namespace -is detected. - -Negative case. - - -Copyright statement -+++++++++++++++++++ - -This file is part of NEST. - -Copyright (C) 2004 The NEST Initiative - -NEST is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -NEST is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with NEST. If not, see . -""" +# CoCoNestNamespaceCollision.nestml +# ################################# +# +# +# Description +# +++++++++++ +# +# This model is used to test if broken CoCos are identified correctly. Here, if the collision with the nest namespace +# is detected. +# +# Negative case. +# +# +# Copyright statement +# +++++++++++++++++++ +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . +# model CoCoNestNamespaceCollision: function handle(Tau_1 mV):# <- function 'handle' already in nest namespace return diff --git a/tests/invalid/CoCoNoOrderOfEquations.nestml b/tests/invalid/CoCoNoOrderOfEquations.nestml index 619da5657..3d255a1e7 100644 --- a/tests/invalid/CoCoNoOrderOfEquations.nestml +++ b/tests/invalid/CoCoNoOrderOfEquations.nestml @@ -1,36 +1,35 @@ -""" -CoCoNoOrderOfEquations.nestml -############################# - - -Description -+++++++++++ - -This model is used to test if broken CoCos are identified correctly. Here, if the order of equations is correct. - -Negative case. - - -Copyright statement -+++++++++++++++++++ - -This file is part of NEST. - -Copyright (C) 2004 The NEST Initiative - -NEST is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -NEST is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with NEST. If not, see . -""" +# CoCoNoOrderOfEquations.nestml +# ############################# +# +# +# Description +# +++++++++++ +# +# This model is used to test if broken CoCos are identified correctly. Here, if the order of equations is correct. +# +# Negative case. +# +# +# Copyright statement +# +++++++++++++++++++ +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . +# model CoCoNoOrderOfEquations: state: V_m mV = 10mV diff --git a/tests/invalid/CoCoOdeIncorrectlyTyped.nestml b/tests/invalid/CoCoOdeIncorrectlyTyped.nestml index 5aebaf778..fd9ed5e9c 100644 --- a/tests/invalid/CoCoOdeIncorrectlyTyped.nestml +++ b/tests/invalid/CoCoOdeIncorrectlyTyped.nestml @@ -1,39 +1,38 @@ -""" -CoCoOdeIncorrectlyTyped.nestml -############################## - - -Description -+++++++++++ - -This model is used to test if broken CoCos are identified correctly. - -Here, an ODE is defined with incorrect units. - -Negative case. - - -Copyright statement -+++++++++++++++++++ - -This file is part of NEST. - -Copyright (C) 2004 The NEST Initiative - -NEST is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -NEST is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with NEST. If not, see . -""" - +# CoCoOdeIncorrectlyTyped.nestml +# ############################## +# +# +# Description +# +++++++++++ +# +# This model is used to test if broken CoCos are identified correctly. +# +# Here, an ODE is defined with incorrect units. +# +# Negative case. +# +# +# Copyright statement +# +++++++++++++++++++ +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . + +# model CoCoOdeIncorrectlyTyped: state: V_m mV = 10mV diff --git a/tests/invalid/CoCoOdeVarNotInInitialValues.nestml b/tests/invalid/CoCoOdeVarNotInInitialValues.nestml index 270ff3bd3..aaa2b0cbc 100644 --- a/tests/invalid/CoCoOdeVarNotInInitialValues.nestml +++ b/tests/invalid/CoCoOdeVarNotInInitialValues.nestml @@ -1,36 +1,35 @@ -""" -CoCoOdeVarNotInInitialValues.nestml -################################### - - -Description -+++++++++++ - -This model is used to test if broken CoCos are identified correctly. Here, if each ODE variable is specified with initial values. - -Negative case. - - -Copyright statement -+++++++++++++++++++ - -This file is part of NEST. - -Copyright (C) 2004 The NEST Initiative - -NEST is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -NEST is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with NEST. If not, see . -""" +# CoCoOdeVarNotInInitialValues.nestml +# ################################### +# +# +# Description +# +++++++++++ +# +# This model is used to test if broken CoCos are identified correctly. Here, if each ODE variable is specified with initial values. +# +# Negative case. +# +# +# Copyright statement +# +++++++++++++++++++ +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . +# model CoCoOdeVarNotInInitialValues: parameters: V_m mV = -50 mV diff --git a/tests/invalid/CoCoOutputPortDefinedIfEmitCall-2.nestml b/tests/invalid/CoCoOutputPortDefinedIfEmitCall-2.nestml index 509b1b010..36a5d1028 100644 --- a/tests/invalid/CoCoOutputPortDefinedIfEmitCall-2.nestml +++ b/tests/invalid/CoCoOutputPortDefinedIfEmitCall-2.nestml @@ -1,36 +1,35 @@ -""" -CoCoOutputPortDefinedIfEmitCall-2.nestml -######################################## - - -Description -+++++++++++ - -This model is used to test if broken CoCos are identified correctly. Here, if the output port has the wrong type. - -Negative case. - - -Copyright statement -+++++++++++++++++++ - -This file is part of NEST. - -Copyright (C) 2004 The NEST Initiative - -NEST is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -NEST is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with NEST. If not, see . -""" +# CoCoOutputPortDefinedIfEmitCall-2.nestml +# ######################################## +# +# +# Description +# +++++++++++ +# +# This model is used to test if broken CoCos are identified correctly. Here, if the output port has the wrong type. +# +# Negative case. +# +# +# Copyright statement +# +++++++++++++++++++ +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . +# model spiking_output_port_is_defined2: output: continuous # inappropriate diff --git a/tests/invalid/CoCoOutputPortDefinedIfEmitCall.nestml b/tests/invalid/CoCoOutputPortDefinedIfEmitCall.nestml index 3c8ac6c49..c5e761491 100644 --- a/tests/invalid/CoCoOutputPortDefinedIfEmitCall.nestml +++ b/tests/invalid/CoCoOutputPortDefinedIfEmitCall.nestml @@ -1,36 +1,35 @@ -""" -CoCoOutputPortDefinedIfEmitCall.nestml -###################################### - - -Description -+++++++++++ - -This model is used to test if broken CoCos are identified correctly. Here, if the output port is not defined. - -Negative case. - - -Copyright statement -+++++++++++++++++++ - -This file is part of NEST. - -Copyright (C) 2004 The NEST Initiative - -NEST is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -NEST is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with NEST. If not, see . -""" +# CoCoOutputPortDefinedIfEmitCall.nestml +# ###################################### +# +# +# Description +# +++++++++++ +# +# This model is used to test if broken CoCos are identified correctly. Here, if the output port is not defined. +# +# Negative case. +# +# +# Copyright statement +# +++++++++++++++++++ +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . +# model spiking_output_port_is_defined: update: emit_spike() diff --git a/tests/invalid/CoCoOutputPortTypeContinuous.nestml b/tests/invalid/CoCoOutputPortTypeContinuous.nestml index d5486a730..12ed45d23 100644 --- a/tests/invalid/CoCoOutputPortTypeContinuous.nestml +++ b/tests/invalid/CoCoOutputPortTypeContinuous.nestml @@ -1,34 +1,33 @@ -""" -CoCoOutputPortTypeContinuous.nestml -################################### - - -Description -+++++++++++ - -This model is used to test if broken CoCos are identified correctly. Here, test that an error is raised when a continous-time output port is defined as having attributes. - - -Copyright statement -+++++++++++++++++++ - -This file is part of NEST. - -Copyright (C) 2004 The NEST Initiative - -NEST is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -NEST is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with NEST. If not, see . -""" +# CoCoOutputPortTypeContinuous.nestml +# ################################### +# +# +# Description +# +++++++++++ +# +# This model is used to test if broken CoCos are identified correctly. Here, test that an error is raised when a continous-time output port is defined as having attributes. +# +# +# Copyright statement +# +++++++++++++++++++ +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . +# model output_port_types_neuron: output: continuous(foo real) diff --git a/tests/invalid/CoCoOutputPortTypeIfEmitCall-2.nestml b/tests/invalid/CoCoOutputPortTypeIfEmitCall-2.nestml index c8ddcbdc6..91ac9506e 100644 --- a/tests/invalid/CoCoOutputPortTypeIfEmitCall-2.nestml +++ b/tests/invalid/CoCoOutputPortTypeIfEmitCall-2.nestml @@ -1,34 +1,33 @@ -""" -CoCoOutputPortTypeIfEmitCall.nestml -################################### - - -Description -+++++++++++ - -This model is used to test if broken CoCos are identified correctly. Here, test that an error is raised when the emit_spike() function is called with different parameter types than are defined in the spiking output port. - - -Copyright statement -+++++++++++++++++++ - -This file is part of NEST. - -Copyright (C) 2004 The NEST Initiative - -NEST is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -NEST is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with NEST. If not, see . -""" +# CoCoOutputPortTypeIfEmitCall.nestml +# ################################### +# +# +# Description +# +++++++++++ +# +# This model is used to test if broken CoCos are identified correctly. Here, test that an error is raised when the emit_spike() function is called with different parameter types than are defined in the spiking output port. +# +# +# Copyright statement +# +++++++++++++++++++ +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . +# model output_port_types_neuron: output: spike(foo real) diff --git a/tests/invalid/CoCoOutputPortTypeIfEmitCall-3.nestml b/tests/invalid/CoCoOutputPortTypeIfEmitCall-3.nestml index 0e3c5a26f..187943b35 100644 --- a/tests/invalid/CoCoOutputPortTypeIfEmitCall-3.nestml +++ b/tests/invalid/CoCoOutputPortTypeIfEmitCall-3.nestml @@ -1,34 +1,33 @@ -""" -CoCoOutputPortTypeIfEmitCall.nestml -################################### - - -Description -+++++++++++ - -This model is used to test if broken CoCos are identified correctly. Here, test that an error is raised when the emit_spike() function is called with different parameter types than are defined in the spiking output port. - - -Copyright statement -+++++++++++++++++++ - -This file is part of NEST. - -Copyright (C) 2004 The NEST Initiative - -NEST is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -NEST is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with NEST. If not, see . -""" +# CoCoOutputPortTypeIfEmitCall.nestml +# ################################### +# +# +# Description +# +++++++++++ +# +# This model is used to test if broken CoCos are identified correctly. Here, test that an error is raised when the emit_spike() function is called with different parameter types than are defined in the spiking output port. +# +# +# Copyright statement +# +++++++++++++++++++ +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . +# model output_port_types_neuron: output: spike(foo real) diff --git a/tests/invalid/CoCoOutputPortTypeIfEmitCall.nestml b/tests/invalid/CoCoOutputPortTypeIfEmitCall.nestml index d9fc459f0..226265708 100644 --- a/tests/invalid/CoCoOutputPortTypeIfEmitCall.nestml +++ b/tests/invalid/CoCoOutputPortTypeIfEmitCall.nestml @@ -1,34 +1,33 @@ -""" -CoCoOutputPortTypeIfEmitCall.nestml -################################### - - -Description -+++++++++++ - -This model is used to test if broken CoCos are identified correctly. Here, test that an error is raised when the emit_spike() function is called with different parameter types than are defined in the spiking output port. - - -Copyright statement -+++++++++++++++++++ - -This file is part of NEST. - -Copyright (C) 2004 The NEST Initiative - -NEST is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -NEST is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with NEST. If not, see . -""" +# CoCoOutputPortTypeIfEmitCall.nestml +# ################################### +# +# +# Description +# +++++++++++ +# +# This model is used to test if broken CoCos are identified correctly. Here, test that an error is raised when the emit_spike() function is called with different parameter types than are defined in the spiking output port. +# +# +# Copyright statement +# +++++++++++++++++++ +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . +# model output_port_types_neuron: output: spike diff --git a/tests/invalid/CoCoParameterAssignedOutsideBlock.nestml b/tests/invalid/CoCoParameterAssignedOutsideBlock.nestml index 69e23b4dc..7cc8836c6 100644 --- a/tests/invalid/CoCoParameterAssignedOutsideBlock.nestml +++ b/tests/invalid/CoCoParameterAssignedOutsideBlock.nestml @@ -1,37 +1,36 @@ -""" -CoCoParameterAssignedOutsideBlock.nestml -######################################## - - -Description -+++++++++++ - -This model is used to check if all cocos work correctly by detecting corresponding broken context. Here, if -assignment of values to parameters outside of parameter blocks is detected. - -Negative case. - - -Copyright statement -+++++++++++++++++++ - -This file is part of NEST. - -Copyright (C) 2004 The NEST Initiative - -NEST is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -NEST is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with NEST. If not, see . -""" +# CoCoParameterAssignedOutsideBlock.nestml +# ######################################## +# +# +# Description +# +++++++++++ +# +# This model is used to check if all cocos work correctly by detecting corresponding broken context. Here, if +# assignment of values to parameters outside of parameter blocks is detected. +# +# Negative case. +# +# +# Copyright statement +# +++++++++++++++++++ +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . +# model CoCoParameterAssignedOutsideBlock: parameters: test mV = 10mV diff --git a/tests/invalid/CoCoPrioritiesCorrectlySpecified.nestml b/tests/invalid/CoCoPrioritiesCorrectlySpecified.nestml index dbe08e3b3..f8b494cb7 100644 --- a/tests/invalid/CoCoPrioritiesCorrectlySpecified.nestml +++ b/tests/invalid/CoCoPrioritiesCorrectlySpecified.nestml @@ -1,34 +1,33 @@ -""" -CoCoPrioritiesCorrectlySpecified.nestml -####################################### - - -Description -+++++++++++ - -This model is used to test the sequencing of event handlers in synapse models. - - -Copyright statement -+++++++++++++++++++ - -This file is part of NEST. - -Copyright (C) 2004 The NEST Initiative - -NEST is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -NEST is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with NEST. If not, see . -""" +# CoCoPrioritiesCorrectlySpecified.nestml +# ####################################### +# +# +# Description +# +++++++++++ +# +# This model is used to test the sequencing of event handlers in synapse models. +# +# +# Copyright statement +# +++++++++++++++++++ +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . +# model prioritites_correctly_specified_synapse: input: pre_spikes <- spike diff --git a/tests/invalid/CoCoResolutionLegallyUsed.nestml b/tests/invalid/CoCoResolutionLegallyUsed.nestml index c7090282a..cd30ea377 100644 --- a/tests/invalid/CoCoResolutionLegallyUsed.nestml +++ b/tests/invalid/CoCoResolutionLegallyUsed.nestml @@ -1,34 +1,33 @@ -""" -CoCoResolutionLegallyUsed.nestml -################################ - - -Description -+++++++++++ - -This model is used to test the use of the predefined ``resolution()`` function. - - -Copyright statement -+++++++++++++++++++ - -This file is part of NEST. - -Copyright (C) 2004 The NEST Initiative - -NEST is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -NEST is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with NEST. If not, see . -""" +# CoCoResolutionLegallyUsed.nestml +# ################################ +# +# +# Description +# +++++++++++ +# +# This model is used to test the use of the predefined ``resolution()`` function. +# +# +# Copyright statement +# +++++++++++++++++++ +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . +# model resolution_legally_used_synapse: state: x real = 0. diff --git a/tests/invalid/CoCoSpikeInputPortWithoutType.nestml b/tests/invalid/CoCoSpikeInputPortWithoutType.nestml index 5afbef118..c80c3aba2 100644 --- a/tests/invalid/CoCoSpikeInputPortWithoutType.nestml +++ b/tests/invalid/CoCoSpikeInputPortWithoutType.nestml @@ -1,36 +1,35 @@ -""" -CoCoSpikeInputPortWithoutType.nestml -#################################### - - -Description -+++++++++++ - -This model is used to test if broken CoCos are identified correctly. Here, if spike input ports without a data-type are detected. - -Negative case. - - -Copyright statement -+++++++++++++++++++ - -This file is part of NEST. - -Copyright (C) 2004 The NEST Initiative - -NEST is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -NEST is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with NEST. If not, see . -""" +# CoCoSpikeInputPortWithoutType.nestml +# #################################### +# +# +# Description +# +++++++++++ +# +# This model is used to test if broken CoCos are identified correctly. Here, if spike input ports without a data-type are detected. +# +# Negative case. +# +# +# Copyright statement +# +++++++++++++++++++ +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . +# model CoCoSpikeInputPortWithoutType: input: spikeAll <- spike # type not specified diff --git a/tests/invalid/CoCoStateVariablesInitialized.nestml b/tests/invalid/CoCoStateVariablesInitialized.nestml index 6791b4d60..f88dc29ef 100644 --- a/tests/invalid/CoCoStateVariablesInitialized.nestml +++ b/tests/invalid/CoCoStateVariablesInitialized.nestml @@ -1,35 +1,34 @@ -""" -CoCoStateVariablesInitialized.nestml -#################################### - -Description -+++++++++++ - -This model is used to test if broken CoCos are identified correctly. Here, if initial values are provided for all state variables declared in the ``state`` block. - -Negative case. - - -Copyright statement -+++++++++++++++++++ - -This file is part of NEST. - -Copyright (C) 2004 The NEST Initiative - -NEST is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -NEST is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with NEST. If not, see . -""" +# CoCoStateVariablesInitialized.nestml +# #################################### +# +# Description +# +++++++++++ +# +# This model is used to test if broken CoCos are identified correctly. Here, if initial values are provided for all state variables declared in the ``state`` block. +# +# Negative case. +# +# +# Copyright statement +# +++++++++++++++++++ +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . +# model CoCoStateVariablesInitialized: state: V_m mV diff --git a/tests/invalid/CoCoUnitNumeratorNotOne.nestml b/tests/invalid/CoCoUnitNumeratorNotOne.nestml index a72cc95d6..27fdab0fe 100644 --- a/tests/invalid/CoCoUnitNumeratorNotOne.nestml +++ b/tests/invalid/CoCoUnitNumeratorNotOne.nestml @@ -1,37 +1,36 @@ -""" -CoCoUnitNumeratorNotOne.nestml -############################## - - -Description -+++++++++++ - -This model is used to check if all cocos work correctly by detecting corresponding broken context. Here, if the -incorrect numerator of the unit is detected. - -Negative case. - - -Copyright statement -+++++++++++++++++++ - -This file is part of NEST. - -Copyright (C) 2004 The NEST Initiative - -NEST is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -NEST is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with NEST. If not, see . -""" +# CoCoUnitNumeratorNotOne.nestml +# ############################## +# +# +# Description +# +++++++++++ +# +# This model is used to check if all cocos work correctly by detecting corresponding broken context. Here, if the +# incorrect numerator of the unit is detected. +# +# Negative case. +# +# +# Copyright statement +# +++++++++++++++++++ +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . +# model CoCoUnitNumeratorNotOne: state: test1 2/s = 10 / s diff --git a/tests/invalid/CoCoValueAssignedToInputPort.nestml b/tests/invalid/CoCoValueAssignedToInputPort.nestml index e915c2ecc..5444cf65c 100644 --- a/tests/invalid/CoCoValueAssignedToInputPort.nestml +++ b/tests/invalid/CoCoValueAssignedToInputPort.nestml @@ -1,36 +1,35 @@ -""" -CoCoValueAssignedToInputPort.nestml -################################### - - -Description -+++++++++++ - -This model is used to test if broken CoCos are identified correctly. Here, if assignment of values to input ports is detected. - -Negative case. - - -Copyright statement -+++++++++++++++++++ - -This file is part of NEST. - -Copyright (C) 2004 The NEST Initiative - -NEST is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -NEST is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with NEST. If not, see . -""" +# CoCoValueAssignedToInputPort.nestml +# ################################### +# +# +# Description +# +++++++++++ +# +# This model is used to test if broken CoCos are identified correctly. Here, if assignment of values to input ports is detected. +# +# Negative case. +# +# +# Copyright statement +# +++++++++++++++++++ +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . +# model CoCoValueAssignedToInputPort: input: spikeInh <- inhibitory spike diff --git a/tests/invalid/CoCoVariableDefinedAfterUsage.nestml b/tests/invalid/CoCoVariableDefinedAfterUsage.nestml index df1138008..48948c351 100644 --- a/tests/invalid/CoCoVariableDefinedAfterUsage.nestml +++ b/tests/invalid/CoCoVariableDefinedAfterUsage.nestml @@ -1,36 +1,35 @@ -""" -CoCoVariableDefinedAfterUsage.nestml -#################################### - - -Description -+++++++++++ - -This model is used to test if broken CoCos are identified correctly. Here, if usage before declaration is detected. - -Negative case. - - -Copyright statement -+++++++++++++++++++ - -This file is part of NEST. - -Copyright (C) 2004 The NEST Initiative - -NEST is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -NEST is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with NEST. If not, see . -""" +# CoCoVariableDefinedAfterUsage.nestml +# #################################### +# +# +# Description +# +++++++++++ +# +# This model is used to test if broken CoCos are identified correctly. Here, if usage before declaration is detected. +# +# Negative case. +# +# +# Copyright statement +# +++++++++++++++++++ +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . +# model CoCoVariableDefinedAfterUsage: state: test2 integer = 10 diff --git a/tests/invalid/CoCoVariableNotDefined.nestml b/tests/invalid/CoCoVariableNotDefined.nestml index c35404959..939a86cbc 100644 --- a/tests/invalid/CoCoVariableNotDefined.nestml +++ b/tests/invalid/CoCoVariableNotDefined.nestml @@ -1,36 +1,35 @@ -""" -CoCoVariableNotDefined.nestml -############################# - - -Description -+++++++++++ - -This model is used to test if broken CoCos are identified correctly. Here, if not defined variables are detected. - -Negative case. - - -Copyright statement -+++++++++++++++++++ - -This file is part of NEST. - -Copyright (C) 2004 The NEST Initiative - -NEST is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -NEST is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with NEST. If not, see . -""" +# CoCoVariableNotDefined.nestml +# ############################# +# +# +# Description +# +++++++++++ +# +# This model is used to test if broken CoCos are identified correctly. Here, if not defined variables are detected. +# +# Negative case. +# +# +# Copyright statement +# +++++++++++++++++++ +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . +# model CoCoVariableNotDefined: update: test1 = test2 + 1 diff --git a/tests/invalid/CoCoVariableRedeclared.nestml b/tests/invalid/CoCoVariableRedeclared.nestml index 222a5623b..59aa1af0e 100644 --- a/tests/invalid/CoCoVariableRedeclared.nestml +++ b/tests/invalid/CoCoVariableRedeclared.nestml @@ -1,36 +1,35 @@ -""" -CoCoVariableRedeclared.nestml -############################# - - -Description -+++++++++++ - -This model is used to test if broken CoCos are identified correctly. Here, if redeclaration of symbols is detected. - -Negative case. - - -Copyright statement -+++++++++++++++++++ - -This file is part of NEST. - -Copyright (C) 2004 The NEST Initiative - -NEST is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -NEST is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with NEST. If not, see . -""" +# CoCoVariableRedeclared.nestml +# ############################# +# +# +# Description +# +++++++++++ +# +# This model is used to test if broken CoCos are identified correctly. Here, if redeclaration of symbols is detected. +# +# Negative case. +# +# +# Copyright statement +# +++++++++++++++++++ +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . +# model CoCoVariableRedeclared: state: test1 mV = 20mV # should not be detected as redeclared, since in global scope diff --git a/tests/invalid/CoCoVariableRedeclaredInSameScope.nestml b/tests/invalid/CoCoVariableRedeclaredInSameScope.nestml index 2f3eb5cc8..32f4c3b55 100644 --- a/tests/invalid/CoCoVariableRedeclaredInSameScope.nestml +++ b/tests/invalid/CoCoVariableRedeclaredInSameScope.nestml @@ -1,37 +1,36 @@ -""" -CoCoVariableRedeclaredInSameScope.nestml -######################################## - - -Description -+++++++++++ - -This model is used to check if all cocos work correctly by detecting corresponding broken context. Here, if -a variable has been redeclared in a single scope. - -Negative case. - - -Copyright statement -+++++++++++++++++++ - -This file is part of NEST. - -Copyright (C) 2004 The NEST Initiative - -NEST is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -NEST is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with NEST. If not, see . -""" +# CoCoVariableRedeclaredInSameScope.nestml +# ######################################## +# +# +# Description +# +++++++++++ +# +# This model is used to check if all cocos work correctly by detecting corresponding broken context. Here, if +# a variable has been redeclared in a single scope. +# +# Negative case. +# +# +# Copyright statement +# +++++++++++++++++++ +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . +# model CoCoVariableRedeclaredInSameScope: state: test1 integer = 10 diff --git a/tests/invalid/CoCoVectorDeclarationSize.nestml b/tests/invalid/CoCoVectorDeclarationSize.nestml index 4a0860b1d..e31bbd4c4 100644 --- a/tests/invalid/CoCoVectorDeclarationSize.nestml +++ b/tests/invalid/CoCoVectorDeclarationSize.nestml @@ -1,38 +1,37 @@ -""" -CoCoVectorParameterSize.nestml -############################## - - -Description -+++++++++++ - -This model is used to test if broken CoCos are identified correctly. -Here, if the vector parameter or the size of the vector is greater than 0. - -Negative case. - - -Copyright statement -+++++++++++++++++++ - -This file is part of NEST. - -Copyright (C) 2004 The NEST Initiative - -NEST is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -NEST is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with NEST. If not, see . -""" - +# CoCoVectorParameterSize.nestml +# ############################## +# +# +# Description +# +++++++++++ +# +# This model is used to test if broken CoCos are identified correctly. +# Here, if the vector parameter or the size of the vector is greater than 0. +# +# Negative case. +# +# +# Copyright statement +# +++++++++++++++++++ +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . + +# model CoCoVectorParameterSize: state: V_m [0] mV = -10. mV diff --git a/tests/invalid/CoCoVectorInNonVectorDeclaration.nestml b/tests/invalid/CoCoVectorInNonVectorDeclaration.nestml index e068e8b54..c2b12ac9a 100644 --- a/tests/invalid/CoCoVectorInNonVectorDeclaration.nestml +++ b/tests/invalid/CoCoVectorInNonVectorDeclaration.nestml @@ -1,37 +1,36 @@ -""" -CoCoVectorInNonVectorDeclaration.nestml -####################################### - - -Description -+++++++++++ - -This model is used to test if broken CoCos are identified correctly. Here, if vectors in non-vector declaration -are detected. - -Negative case. - - -Copyright statement -+++++++++++++++++++ - -This file is part of NEST. - -Copyright (C) 2004 The NEST Initiative - -NEST is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -NEST is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with NEST. If not, see . -""" +# CoCoVectorInNonVectorDeclaration.nestml +# ####################################### +# +# +# Description +# +++++++++++ +# +# This model is used to test if broken CoCos are identified correctly. Here, if vectors in non-vector declaration +# are detected. +# +# Negative case. +# +# +# Copyright statement +# +++++++++++++++++++ +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . +# model CoCoVectorInNonVectorDeclaration: state: g_ex [ten] mV = 10mV diff --git a/tests/invalid/CoCoVectorInputPortSizeAndType.nestml b/tests/invalid/CoCoVectorInputPortSizeAndType.nestml index 374ef9d2a..9c52780ce 100644 --- a/tests/invalid/CoCoVectorInputPortSizeAndType.nestml +++ b/tests/invalid/CoCoVectorInputPortSizeAndType.nestml @@ -1,37 +1,36 @@ -""" -CoCoVectorInputPortSizeAndType.nestml -##################################### - - -Description -+++++++++++ - -This model is used to test if broken CoCos are identified correctly. -Here, if the size parameter in the input port is of the type integer and is greater than 0. - -Negative case. - - -Copyright statement -+++++++++++++++++++ - -This file is part of NEST. - -Copyright (C) 2004 The NEST Initiative - -NEST is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -NEST is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with NEST. If not, see . -""" +# CoCoVectorInputPortSizeAndType.nestml +# ##################################### +# +# +# Description +# +++++++++++ +# +# This model is used to test if broken CoCos are identified correctly. +# Here, if the size parameter in the input port is of the type integer and is greater than 0. +# +# Negative case. +# +# +# Copyright statement +# +++++++++++++++++++ +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . +# model CoCoVectorInputPortSizeAndType: parameters: TWO integer = 2 diff --git a/tests/invalid/CoCoVectorParameterDeclaration.nestml b/tests/invalid/CoCoVectorParameterDeclaration.nestml index 9ada472b2..aac324495 100644 --- a/tests/invalid/CoCoVectorParameterDeclaration.nestml +++ b/tests/invalid/CoCoVectorParameterDeclaration.nestml @@ -1,38 +1,37 @@ -""" -CoCoVectorParameterDeclaration.nestml -##################################### - - -Description -+++++++++++ - -This model is used to test if broken CoCos are identified correctly. -Here, if the vector parameter is declared in the correct block. - -Negative case. - - -Copyright statement -+++++++++++++++++++ - -This file is part of NEST. - -Copyright (C) 2004 The NEST Initiative - -NEST is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -NEST is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with NEST. If not, see . -""" - +# CoCoVectorParameterDeclaration.nestml +# ##################################### +# +# +# Description +# +++++++++++ +# +# This model is used to test if broken CoCos are identified correctly. +# Here, if the vector parameter is declared in the correct block. +# +# Negative case. +# +# +# Copyright statement +# +++++++++++++++++++ +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . + +# model CoCoVectorParameterDeclaration: state: size integer = 20 diff --git a/tests/invalid/CoCoVectorParameterType.nestml b/tests/invalid/CoCoVectorParameterType.nestml index f1508badc..f37cafec8 100644 --- a/tests/invalid/CoCoVectorParameterType.nestml +++ b/tests/invalid/CoCoVectorParameterType.nestml @@ -1,38 +1,37 @@ -""" -CoCoVectorParameterType.nestml -############################## - - -Description -+++++++++++ - -This model is used to test if broken CoCos are identified correctly. -Here, if the vector parameter is of the type integer. - -Negative case. - - -Copyright statement -+++++++++++++++++++ - -This file is part of NEST. - -Copyright (C) 2004 The NEST Initiative - -NEST is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -NEST is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with NEST. If not, see . -""" - +# CoCoVectorParameterType.nestml +# ############################## +# +# +# Description +# +++++++++++ +# +# This model is used to test if broken CoCos are identified correctly. +# Here, if the vector parameter is of the type integer. +# +# Negative case. +# +# +# Copyright statement +# +++++++++++++++++++ +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . + +# model CoCoVectorParameterType: state: v_m [size] mV = -55 mV diff --git a/tests/invalid/CompoundOperatorWithDifferentButCompatibleUnits.nestml b/tests/invalid/CompoundOperatorWithDifferentButCompatibleUnits.nestml index bbf2f3e9c..92adbec26 100644 --- a/tests/invalid/CompoundOperatorWithDifferentButCompatibleUnits.nestml +++ b/tests/invalid/CompoundOperatorWithDifferentButCompatibleUnits.nestml @@ -1,28 +1,27 @@ -""" -CompoundOperatorWithDifferentButCompatibleUnits.nestml -###################################################### - - -Copyright statement -+++++++++++++++++++ - -This file is part of NEST. - -Copyright (C) 2004 The NEST Initiative - -NEST is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -NEST is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with NEST. If not, see . -""" +# CompoundOperatorWithDifferentButCompatibleUnits.nestml +# ###################################################### +# +# +# Copyright statement +# +++++++++++++++++++ +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . +# model CompoundOperatorTest: state: lhs V = 1 V diff --git a/tests/invalid/DocstringCommentTest.nestml b/tests/invalid/DocstringCommentTest.nestml index 3abcdc67f..963eda13d 100644 --- a/tests/invalid/DocstringCommentTest.nestml +++ b/tests/invalid/DocstringCommentTest.nestml @@ -1,40 +1,37 @@ -""" -DocstringCommentTest.nestml -########################### +# DocstringCommentTest.nestml +# ########################### +# +# +# Description +# +++++++++++ +# +# This model is used to test whether docstring comments are detected. +# +# Negative case. +# +# +# Copyright statement +# +++++++++++++++++++ +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . - -Description -+++++++++++ - -This model is used to test whether docstring comments are detected at any place other than just before the model keyword. - -Negative case. - - -Copyright statement -+++++++++++++++++++ - -This file is part of NEST. - -Copyright (C) 2004 The NEST Initiative - -NEST is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -NEST is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with NEST. If not, see . -""" model docstringCommentTest: state: - """hello""" # foo + test boolean = True #inline comment ok - # foo - # bar diff --git a/tests/invalid/stdp_synapse_missing_delay_decorator.nestml b/tests/invalid/stdp_synapse_missing_delay_decorator.nestml index 8c6c03589..8e7104cd6 100644 --- a/tests/invalid/stdp_synapse_missing_delay_decorator.nestml +++ b/tests/invalid/stdp_synapse_missing_delay_decorator.nestml @@ -1,38 +1,37 @@ -""" -stdp - Synapse model for spike-timing dependent plasticity -######################################################### - -Description -+++++++++++ - -stdp_synapse is a synapse with spike-timing dependent plasticity (as defined in [1]_). Here the weight dependence exponent can be set separately for potentiation and depression. Examples: - -=================== ==== ============================= -Multiplicative STDP [2]_ mu_plus = mu_minus = 1 -Additive STDP [3]_ mu_plus = mu_minus = 0 -Guetig STDP [1]_ mu_plus, mu_minus in [0, 1] -Van Rossum STDP [4]_ mu_plus = 0 mu_minus = 1 -=================== ==== ============================= - - -References -++++++++++ - -.. [1] Guetig et al. (2003) Learning Input Correlations through Nonlinear - Temporally Asymmetric Hebbian Plasticity. Journal of Neuroscience - -.. [2] Rubin, J., Lee, D. and Sompolinsky, H. (2001). Equilibrium - properties of temporally asymmetric Hebbian plasticity, PRL - 86,364-367 - -.. [3] Song, S., Miller, K. D. and Abbott, L. F. (2000). Competitive - Hebbian learning through spike-timing-dependent synaptic - plasticity,Nature Neuroscience 3:9,919--926 - -.. [4] van Rossum, M. C. W., Bi, G-Q and Turrigiano, G. G. (2000). - Stable Hebbian learning from spike timing-dependent - plasticity, Journal of Neuroscience, 20:23,8812--8821 -""" +# stdp - Synapse model for spike-timing dependent plasticity +# ######################################################### +# +# Description +# +++++++++++ +# +# stdp_synapse is a synapse with spike-timing dependent plasticity (as defined in [1]_). Here the weight dependence exponent can be set separately for potentiation and depression. Examples: +# +# =================== ==== ============================= +# Multiplicative STDP [2]_ mu_plus = mu_minus = 1 +# Additive STDP [3]_ mu_plus = mu_minus = 0 +# Guetig STDP [1]_ mu_plus, mu_minus in [0, 1] +# Van Rossum STDP [4]_ mu_plus = 0 mu_minus = 1 +# =================== ==== ============================= +# +# +# References +# ++++++++++ +# +# .. [1] Guetig et al. (2003) Learning Input Correlations through Nonlinear +# Temporally Asymmetric Hebbian Plasticity. Journal of Neuroscience +# +# .. [2] Rubin, J., Lee, D. and Sompolinsky, H. (2001). Equilibrium +# properties of temporally asymmetric Hebbian plasticity, PRL +# 86,364-367 +# +# .. [3] Song, S., Miller, K. D. and Abbott, L. F. (2000). Competitive +# Hebbian learning through spike-timing-dependent synaptic +# plasticity,Nature Neuroscience 3:9,919--926 +# +# .. [4] van Rossum, M. C. W., Bi, G-Q and Turrigiano, G. G. (2000). +# Stable Hebbian learning from spike timing-dependent +# plasticity, Journal of Neuroscience, 20:23,8812--8821 +# model stdp_synapse: state: w real = 1 # Synaptic weight diff --git a/tests/nest_compartmental_tests/resources/cm_default.nestml b/tests/nest_compartmental_tests/resources/cm_default.nestml index dadf1dab3..4736bc227 100644 --- a/tests/nest_compartmental_tests/resources/cm_default.nestml +++ b/tests/nest_compartmental_tests/resources/cm_default.nestml @@ -1,32 +1,31 @@ -""" -Example compartmental model for NESTML - -Description -+++++++++++ -Corresponds to standard compartmental model implemented in NEST. - - -Copyright statement -+++++++++++++++++++ - -This file is part of NEST. - -Copyright (C) 2004 The NEST Initiative - -NEST is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -NEST is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with NEST. If not, see . -""" - +# Example compartmental model for NESTML +# +# Description +# +++++++++++ +# Corresponds to standard compartmental model implemented in NEST. +# +# +# Copyright statement +# +++++++++++++++++++ +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . + +# model cm_default: state: diff --git a/tests/nest_compartmental_tests/resources/concmech.nestml b/tests/nest_compartmental_tests/resources/concmech.nestml index 486403661..d9944188e 100644 --- a/tests/nest_compartmental_tests/resources/concmech.nestml +++ b/tests/nest_compartmental_tests/resources/concmech.nestml @@ -1,25 +1,24 @@ -""" -Copyright statement -+++++++++++++++++++ - -This file is part of NEST. - -Copyright (C) 2004 The NEST Initiative - -NEST is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -NEST is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with NEST. If not, see . -""" - +# Copyright statement +# +++++++++++++++++++ +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . + +# model multichannel_test_model: parameters: e_AMPA real = 0 mV diff --git a/tests/nest_compartmental_tests/resources/continuous_test.nestml b/tests/nest_compartmental_tests/resources/continuous_test.nestml index 2f1387d7e..30d397422 100644 --- a/tests/nest_compartmental_tests/resources/continuous_test.nestml +++ b/tests/nest_compartmental_tests/resources/continuous_test.nestml @@ -1,25 +1,24 @@ -""" -Copyright statement -+++++++++++++++++++ - -This file is part of NEST. - -Copyright (C) 2004 The NEST Initiative - -NEST is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -NEST is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with NEST. If not, see . -""" - +# Copyright statement +# +++++++++++++++++++ +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . + +# model continuous_test_model: state: v_comp real = 0 diff --git a/tests/nest_compartmental_tests/resources/invalid/CoCoCmVariableHasRhs.nestml b/tests/nest_compartmental_tests/resources/invalid/CoCoCmVariableHasRhs.nestml index 6eb9de85c..d2a1e0470 100644 --- a/tests/nest_compartmental_tests/resources/invalid/CoCoCmVariableHasRhs.nestml +++ b/tests/nest_compartmental_tests/resources/invalid/CoCoCmVariableHasRhs.nestml @@ -1,38 +1,37 @@ -""" -CoCoCmVariableHasRhs.nestml -########################### - - -Description -+++++++++++ - -This model is used to test whether the all variable declarations of the -compartmental model contain a right hand side expression - -Negative case. - - -Copyright statement -+++++++++++++++++++ - -This file is part of NEST. - -Copyright (C) 2004 The NEST Initiative - -NEST is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -NEST is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with NEST. If not, see . -""" - +# CoCoCmVariableHasRhs.nestml +# ########################### +# +# +# Description +# +++++++++++ +# +# This model is used to test whether the all variable declarations of the +# compartmental model contain a right hand side expression +# +# Negative case. +# +# +# Copyright statement +# +++++++++++++++++++ +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . + +# model cm_model_four_invalid: state: diff --git a/tests/nest_compartmental_tests/resources/invalid/CoCoCmVariableMultiUse.nestml b/tests/nest_compartmental_tests/resources/invalid/CoCoCmVariableMultiUse.nestml index cf3e449b9..09e3687f4 100644 --- a/tests/nest_compartmental_tests/resources/invalid/CoCoCmVariableMultiUse.nestml +++ b/tests/nest_compartmental_tests/resources/invalid/CoCoCmVariableMultiUse.nestml @@ -1,38 +1,37 @@ -""" -CoCoCmVariableMultiUse.nestml -########################### - - -Description -+++++++++++ - -This model is used to test whether the inline expression that characterizes -a channel uses each variable exactly once - -Negative case. - - -Copyright statement -+++++++++++++++++++ - -This file is part of NEST. - -Copyright (C) 2004 The NEST Initiative - -NEST is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -NEST is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with NEST. If not, see . -""" - +# CoCoCmVariableMultiUse.nestml +# ########################### +# +# +# Description +# +++++++++++ +# +# This model is used to test whether the inline expression that characterizes +# a channel uses each variable exactly once +# +# Negative case. +# +# +# Copyright statement +# +++++++++++++++++++ +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . + +# model cm_model_five_invalid: state: diff --git a/tests/nest_compartmental_tests/resources/invalid/CoCoCmVariablesDeclared.nestml b/tests/nest_compartmental_tests/resources/invalid/CoCoCmVariablesDeclared.nestml index 91f8148fa..e67dec20a 100644 --- a/tests/nest_compartmental_tests/resources/invalid/CoCoCmVariablesDeclared.nestml +++ b/tests/nest_compartmental_tests/resources/invalid/CoCoCmVariablesDeclared.nestml @@ -1,38 +1,37 @@ -""" -CoCoCmVariablesDeclared.nestml -########################### - - -Description -+++++++++++ - -This model is used to test whether compartmental variables used in the inline expression -are also declared in the corresponding state / parameter block - -Negative case. - - -Copyright statement -+++++++++++++++++++ - -This file is part of NEST. - -Copyright (C) 2004 The NEST Initiative - -NEST is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -NEST is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with NEST. If not, see . -""" - +# CoCoCmVariablesDeclared.nestml +# ########################### +# +# +# Description +# +++++++++++ +# +# This model is used to test whether compartmental variables used in the inline expression +# are also declared in the corresponding state / parameter block +# +# Negative case. +# +# +# Copyright statement +# +++++++++++++++++++ +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . + +# model cm_model_seven_invalid: state: diff --git a/tests/nest_compartmental_tests/resources/invalid/CoCoCmVcompExists.nestml b/tests/nest_compartmental_tests/resources/invalid/CoCoCmVcompExists.nestml index 518e6b4a2..6eba3dd2b 100644 --- a/tests/nest_compartmental_tests/resources/invalid/CoCoCmVcompExists.nestml +++ b/tests/nest_compartmental_tests/resources/invalid/CoCoCmVcompExists.nestml @@ -1,38 +1,37 @@ -""" -CoCoCmVcompExists.nestml -########################### - - -Description -+++++++++++ - -This model is used to test whether, in case of a compartmental model ("NEST_COMPARTMENTAL"), -there is the required variable called v_comp defined in the state block - -Negative case. - - -Copyright statement -+++++++++++++++++++ - -This file is part of NEST. - -Copyright (C) 2004 The NEST Initiative - -NEST is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -NEST is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with NEST. If not, see . -""" - +# CoCoCmVcompExists.nestml +# ########################### +# +# +# Description +# +++++++++++ +# +# This model is used to test whether, in case of a compartmental model ("NEST_COMPARTMENTAL"), +# there is the required variable called v_comp defined in the state block +# +# Negative case. +# +# +# Copyright statement +# +++++++++++++++++++ +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . + +# model cm_model_eight_invalid: state: diff --git a/tests/nest_compartmental_tests/resources/valid/CoCoCmVariableHasRhs.nestml b/tests/nest_compartmental_tests/resources/valid/CoCoCmVariableHasRhs.nestml index e2e01e329..0fa4f9af9 100644 --- a/tests/nest_compartmental_tests/resources/valid/CoCoCmVariableHasRhs.nestml +++ b/tests/nest_compartmental_tests/resources/valid/CoCoCmVariableHasRhs.nestml @@ -1,38 +1,37 @@ -""" -CoCoCmVariableHasRhs.nestml -########################### - - -Description -+++++++++++ - -This model is used to test whether the all variable declarations of the -compartmental model contain a right hand side expression - -Positive case. - - -Copyright statement -+++++++++++++++++++ - -This file is part of NEST. - -Copyright (C) 2004 The NEST Initiative - -NEST is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -NEST is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with NEST. If not, see . -""" - +# CoCoCmVariableHasRhs.nestml +# ########################### +# +# +# Description +# +++++++++++ +# +# This model is used to test whether the all variable declarations of the +# compartmental model contain a right hand side expression +# +# Positive case. +# +# +# Copyright statement +# +++++++++++++++++++ +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . + +# model cm_model_four: state: diff --git a/tests/nest_compartmental_tests/resources/valid/CoCoCmVariableMultiUse.nestml b/tests/nest_compartmental_tests/resources/valid/CoCoCmVariableMultiUse.nestml index 770a7baac..58c6908bd 100644 --- a/tests/nest_compartmental_tests/resources/valid/CoCoCmVariableMultiUse.nestml +++ b/tests/nest_compartmental_tests/resources/valid/CoCoCmVariableMultiUse.nestml @@ -1,38 +1,37 @@ -""" -CoCoCmVariableMultiUse.nestml -########################### - - -Description -+++++++++++ - -This model is used to test whether the inline expression that characterizes -a channel uses each variable exactly once - -Positive case. - - -Copyright statement -+++++++++++++++++++ - -This file is part of NEST. - -Copyright (C) 2004 The NEST Initiative - -NEST is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -NEST is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with NEST. If not, see . -""" - +# CoCoCmVariableMultiUse.nestml +# ########################### +# +# +# Description +# +++++++++++ +# +# This model is used to test whether the inline expression that characterizes +# a channel uses each variable exactly once +# +# Positive case. +# +# +# Copyright statement +# +++++++++++++++++++ +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . + +# model cm_model_five: state: diff --git a/tests/nest_compartmental_tests/resources/valid/CoCoCmVariablesDeclared.nestml b/tests/nest_compartmental_tests/resources/valid/CoCoCmVariablesDeclared.nestml index b7ba594f7..b38c1a1bc 100644 --- a/tests/nest_compartmental_tests/resources/valid/CoCoCmVariablesDeclared.nestml +++ b/tests/nest_compartmental_tests/resources/valid/CoCoCmVariablesDeclared.nestml @@ -1,38 +1,37 @@ -""" -CoCoCmVariablesDeclared.nestml -########################### - - -Description -+++++++++++ - -This model is used to test whether compartmental variables used in the inline expression -are also declared in the corresponding state / parameter block - -Positive case. - - -Copyright statement -+++++++++++++++++++ - -This file is part of NEST. - -Copyright (C) 2004 The NEST Initiative - -NEST is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -NEST is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with NEST. If not, see . -""" - +# CoCoCmVariablesDeclared.nestml +# ########################### +# +# +# Description +# +++++++++++ +# +# This model is used to test whether compartmental variables used in the inline expression +# are also declared in the corresponding state / parameter block +# +# Positive case. +# +# +# Copyright statement +# +++++++++++++++++++ +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . + +# model cm_model_seven: state: diff --git a/tests/nest_compartmental_tests/resources/valid/CoCoCmVcompExists.nestml b/tests/nest_compartmental_tests/resources/valid/CoCoCmVcompExists.nestml index 4a25c1f90..633be6ea1 100644 --- a/tests/nest_compartmental_tests/resources/valid/CoCoCmVcompExists.nestml +++ b/tests/nest_compartmental_tests/resources/valid/CoCoCmVcompExists.nestml @@ -1,38 +1,37 @@ -""" -CoCoCmVcompExists.nestml -########################### - - -Description -+++++++++++ - -This model is used to test whether, in case of a compartmental model ("NEST_COMPARTMENTAL"), -there is the required variable called v_comp defined in the state block - -Positive case. - - -Copyright statement -+++++++++++++++++++ - -This file is part of NEST. - -Copyright (C) 2004 The NEST Initiative - -NEST is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -NEST is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with NEST. If not, see . -""" - +# CoCoCmVcompExists.nestml +# ########################### +# +# +# Description +# +++++++++++ +# +# This model is used to test whether, in case of a compartmental model ("NEST_COMPARTMENTAL"), +# there is the required variable called v_comp defined in the state block +# +# Positive case. +# +# +# Copyright statement +# +++++++++++++++++++ +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . + +# model cm_model_eight_valid: state: diff --git a/tests/nest_tests/nest_integration_test.py b/tests/nest_tests/nest_integration_test.py index abfa47ea1..441e4916e 100644 --- a/tests/nest_tests/nest_integration_test.py +++ b/tests/nest_tests/nest_integration_test.py @@ -40,7 +40,7 @@ def get_model_doc_title(model_fname: str): with open(model_fname) as f: model = f.read() - return re.compile(r'\"\"\"[^#]*###').search(model).group()[3:-3].strip() + return re.compile(r'[^#]*###').search(model).group()[3:-3].strip() @pytest.mark.skipif(NESTTools.detect_nest_version().startswith("v2"), diff --git a/tests/nest_tests/resources/BiexponentialPostSynapticResponse.nestml b/tests/nest_tests/resources/BiexponentialPostSynapticResponse.nestml index 2fd3f13ca..388a1246b 100644 --- a/tests/nest_tests/resources/BiexponentialPostSynapticResponse.nestml +++ b/tests/nest_tests/resources/BiexponentialPostSynapticResponse.nestml @@ -1,34 +1,33 @@ -""" -BiexponentialPostSynapticResponse.nestml -######################################## - - -Description -+++++++++++ - -Bi-exponential ("beta function") postsynaptic response - - -Copyright statement -+++++++++++++++++++ - -This file is part of NEST. - -Copyright (C) 2004 The NEST Initiative - -NEST is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -NEST is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with NEST. If not, see . -""" +# BiexponentialPostSynapticResponse.nestml +# ######################################## +# +# +# Description +# +++++++++++ +# +# Bi-exponential ("beta function") postsynaptic response +# +# +# Copyright statement +# +++++++++++++++++++ +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . +# model biexp_postsynaptic_response_neuron: state: refr_t ms = 0 ms # Refractory period timer diff --git a/tests/nest_tests/resources/CppVariableNames.nestml b/tests/nest_tests/resources/CppVariableNames.nestml index df3c7e57c..c868e22b7 100644 --- a/tests/nest_tests/resources/CppVariableNames.nestml +++ b/tests/nest_tests/resources/CppVariableNames.nestml @@ -1,31 +1,30 @@ -""" -CppVariableNames.nestml -####################### - -Contains some C++ keyword-named variables. - - -Copyright statement -+++++++++++++++++++ - -This file is part of NEST. - -Copyright (C) 2004 The NEST Initiative - -NEST is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -NEST is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with NEST. If not, see . -""" - +# CppVariableNames.nestml +# ####################### +# +# Contains some C++ keyword-named variables. +# +# +# Copyright statement +# +++++++++++++++++++ +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . + +# model cpp_variable_names_test: state: static real = 0. diff --git a/tests/nest_tests/resources/DelayDifferentialEquationsWithAnalyticSolver.nestml b/tests/nest_tests/resources/DelayDifferentialEquationsWithAnalyticSolver.nestml index 9f0d5af98..1eb6ae8ee 100644 --- a/tests/nest_tests/resources/DelayDifferentialEquationsWithAnalyticSolver.nestml +++ b/tests/nest_tests/resources/DelayDifferentialEquationsWithAnalyticSolver.nestml @@ -1,29 +1,28 @@ -""" -DelayBasedVariablesWithAnalyticSolver.nestml -############################################ - - -Copyright statement -+++++++++++++++++++ - -This file is part of NEST. - -Copyright (C) 2004 The NEST Initiative - -NEST is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -NEST is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with NEST. If not, see . -""" - +# DelayBasedVariablesWithAnalyticSolver.nestml +# ############################################ +# +# +# Copyright statement +# +++++++++++++++++++ +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . + +# model dde_analytic: state: u_bar_plus real = -70. diff --git a/tests/nest_tests/resources/DelayDifferentialEquationsWithMixedSolver.nestml b/tests/nest_tests/resources/DelayDifferentialEquationsWithMixedSolver.nestml index 487bdf79d..62f4bd36a 100644 --- a/tests/nest_tests/resources/DelayDifferentialEquationsWithMixedSolver.nestml +++ b/tests/nest_tests/resources/DelayDifferentialEquationsWithMixedSolver.nestml @@ -1,27 +1,26 @@ -""" -DelayDifferentialEquationsWithMixedSolver.nestml -################################################ - -Copyright statement -+++++++++++++++++++ - -This file is part of NEST. - -Copyright (C) 2004 The NEST Initiative - -NEST is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -NEST is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with NEST. If not, see . -""" +# DelayDifferentialEquationsWithMixedSolver.nestml +# ################################################ +# +# Copyright statement +# +++++++++++++++++++ +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . +# model dde_mixed: state: x real = 0.01 diff --git a/tests/nest_tests/resources/DelayDifferentialEquationsWithNumericSolver.nestml b/tests/nest_tests/resources/DelayDifferentialEquationsWithNumericSolver.nestml index 92468d77e..6eb9521a1 100644 --- a/tests/nest_tests/resources/DelayDifferentialEquationsWithNumericSolver.nestml +++ b/tests/nest_tests/resources/DelayDifferentialEquationsWithNumericSolver.nestml @@ -1,27 +1,26 @@ -""" -DelayDifferentialEquationsWithNumericSolver.nestml -################################################## - -Copyright statement -+++++++++++++++++++ - -This file is part of NEST. - -Copyright (C) 2004 The NEST Initiative - -NEST is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -NEST is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with NEST. If not, see . -""" +# DelayDifferentialEquationsWithNumericSolver.nestml +# ################################################## +# +# Copyright statement +# +++++++++++++++++++ +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . +# model dde_numeric: state: x real = 0 diff --git a/tests/nest_tests/resources/FIR_filter.nestml b/tests/nest_tests/resources/FIR_filter.nestml index 21387d50e..d116b43fb 100644 --- a/tests/nest_tests/resources/FIR_filter.nestml +++ b/tests/nest_tests/resources/FIR_filter.nestml @@ -1,34 +1,33 @@ -""" -FIR_filter.nestml -################ - - -Description -+++++++++++ - -Model for Finite Impulse Response (FIR) filter - - -Copyright statement -+++++++++++++++++++ - -This file is part of NEST. - -Copyright (C) 2004 The NEST Initiative - -NEST is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -NEST is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with NEST. If not, see . -""" +# FIR_filter.nestml +# ################ +# +# +# Description +# +++++++++++ +# +# Model for Finite Impulse Response (FIR) filter +# +# +# Copyright statement +# +++++++++++++++++++ +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . +# model fir_filter: state: # FIR filter output (to be recorded by NEST multimeter) diff --git a/tests/nest_tests/resources/ForLoop.nestml b/tests/nest_tests/resources/ForLoop.nestml index 214e55c50..b9316c748 100644 --- a/tests/nest_tests/resources/ForLoop.nestml +++ b/tests/nest_tests/resources/ForLoop.nestml @@ -1,29 +1,28 @@ -""" -ForLoop.nestml -############## - - -Copyright statement -+++++++++++++++++++ - -This file is part of NEST. - -Copyright (C) 2004 The NEST Initiative - -NEST is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -NEST is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with NEST. If not, see . -""" - +# ForLoop.nestml +# ############## +# +# +# Copyright statement +# +++++++++++++++++++ +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . + +# model for_loop: state: V_m mV = -0.20 mV diff --git a/tests/nest_tests/resources/MathFunctionTest.nestml b/tests/nest_tests/resources/MathFunctionTest.nestml index cd18e11df..f5a99d252 100644 --- a/tests/nest_tests/resources/MathFunctionTest.nestml +++ b/tests/nest_tests/resources/MathFunctionTest.nestml @@ -1,28 +1,27 @@ -""" -MathFunctionTest.nestml -####################### - - -Copyright statement -+++++++++++++++++++ - -This file is part of NEST. - -Copyright (C) 2004 The NEST Initiative - -NEST is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -NEST is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with NEST. If not, see . -""" +# MathFunctionTest.nestml +# ####################### +# +# +# Copyright statement +# +++++++++++++++++++ +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . +# model math_function_test: state: x real = 0. diff --git a/tests/nest_tests/resources/PrintStatementInFunction.nestml b/tests/nest_tests/resources/PrintStatementInFunction.nestml index 5dd5a9f2b..b466d3554 100644 --- a/tests/nest_tests/resources/PrintStatementInFunction.nestml +++ b/tests/nest_tests/resources/PrintStatementInFunction.nestml @@ -1,28 +1,27 @@ -""" -PrintStatementInFunction.nestml -############################### - - -Copyright statement -+++++++++++++++++++ - -This file is part of NEST. - -Copyright (C) 2004 The NEST Initiative - -NEST is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -NEST is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with NEST. If not, see . -""" +# PrintStatementInFunction.nestml +# ############################### +# +# +# Copyright statement +# +++++++++++++++++++ +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . +# model print_test_function: function print_function(): print("A statement inside a function") diff --git a/tests/nest_tests/resources/PrintStatementWithVariables.nestml b/tests/nest_tests/resources/PrintStatementWithVariables.nestml index 944e0a926..46cdf69b2 100644 --- a/tests/nest_tests/resources/PrintStatementWithVariables.nestml +++ b/tests/nest_tests/resources/PrintStatementWithVariables.nestml @@ -1,28 +1,27 @@ -""" -PrintStatementWithVariables.nestml -################################## - - -Copyright statement -+++++++++++++++++++ - -This file is part of NEST. - -Copyright (C) 2004 The NEST Initiative - -NEST is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -NEST is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with NEST. If not, see . -""" +# PrintStatementWithVariables.nestml +# ################################## +# +# +# Copyright statement +# +++++++++++++++++++ +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . +# model print_test_variables: state: V_m mV = -50 mV diff --git a/tests/nest_tests/resources/PrintVariables.nestml b/tests/nest_tests/resources/PrintVariables.nestml index 6132dc9c3..e13f93e73 100644 --- a/tests/nest_tests/resources/PrintVariables.nestml +++ b/tests/nest_tests/resources/PrintVariables.nestml @@ -1,28 +1,27 @@ -""" -PrintVariables.nestml -##################### - - -Copyright statement -+++++++++++++++++++ - -This file is part of NEST. - -Copyright (C) 2004 The NEST Initiative - -NEST is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -NEST is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with NEST. If not, see . -""" +# PrintVariables.nestml +# ##################### +# +# +# Copyright statement +# +++++++++++++++++++ +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . +# model print_variable: state: V_m V = -50 mV diff --git a/tests/nest_tests/resources/PrintVariablesWithDifferentButCompatibleUnits.nestml b/tests/nest_tests/resources/PrintVariablesWithDifferentButCompatibleUnits.nestml index 9edabad8f..f46cc8dc6 100644 --- a/tests/nest_tests/resources/PrintVariablesWithDifferentButCompatibleUnits.nestml +++ b/tests/nest_tests/resources/PrintVariablesWithDifferentButCompatibleUnits.nestml @@ -1,28 +1,27 @@ -""" -PrintVariablesWithDifferentButCompatibleUnits.nestml -#################################################### - - -Copyright statement -+++++++++++++++++++ - -This file is part of NEST. - -Copyright (C) 2004 The NEST Initiative - -NEST is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -NEST is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with NEST. If not, see . -""" +# PrintVariablesWithDifferentButCompatibleUnits.nestml +# #################################################### +# +# +# Copyright statement +# +++++++++++++++++++ +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . +# model print_variable: state: V_m V = -50 mV diff --git a/tests/nest_tests/resources/RecordableVariables.nestml b/tests/nest_tests/resources/RecordableVariables.nestml index d31496002..2339a1d60 100644 --- a/tests/nest_tests/resources/RecordableVariables.nestml +++ b/tests/nest_tests/resources/RecordableVariables.nestml @@ -1,33 +1,32 @@ -""" -RecordableVariables.nestml -########################## - -Description -+++++++++++ - -This model is used to test recording of variables and inline expressions. - - -Copyright statement -+++++++++++++++++++ - -This file is part of NEST. - -Copyright (C) 2004 The NEST Initiative - -NEST is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -NEST is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with NEST. If not, see . -""" +# RecordableVariables.nestml +# ########################## +# +# Description +# +++++++++++ +# +# This model is used to test recording of variables and inline expressions. +# +# +# Copyright statement +# +++++++++++++++++++ +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . +# model recordable_variables: state: V_ex mV = -5 mV diff --git a/tests/nest_tests/resources/SimplePrintStatement.nestml b/tests/nest_tests/resources/SimplePrintStatement.nestml index f23116088..6ebc5dd2e 100644 --- a/tests/nest_tests/resources/SimplePrintStatement.nestml +++ b/tests/nest_tests/resources/SimplePrintStatement.nestml @@ -1,28 +1,27 @@ -""" -SimplePrintStatement.nestml -########################### - - -Copyright statement -+++++++++++++++++++ - -This file is part of NEST. - -Copyright (C) 2004 The NEST Initiative - -NEST is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -NEST is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with NEST. If not, see . -""" +# SimplePrintStatement.nestml +# ########################### +# +# +# Copyright statement +# +++++++++++++++++++ +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . +# model simple_print_test: update: print("This is a simple print statement") diff --git a/tests/nest_tests/resources/SimpleVectorsModel.nestml b/tests/nest_tests/resources/SimpleVectorsModel.nestml index 7783aed9e..0309669e1 100644 --- a/tests/nest_tests/resources/SimpleVectorsModel.nestml +++ b/tests/nest_tests/resources/SimpleVectorsModel.nestml @@ -1,30 +1,29 @@ -""" - -SimpleVectorsModel.nestml -######################### - -Copyright statement -+++++++++++++++++++ - -This file is part of NEST. - -Copyright (C) 2004 The NEST Initiative - -NEST is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -NEST is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with NEST. If not, see . - -""" - +# +# SimpleVectorsModel.nestml +# ######################### +# +# Copyright statement +# +++++++++++++++++++ +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . +# + +# model simple_vectors_model: state: g_ex [20] real = 1.2 diff --git a/tests/nest_tests/resources/StringHandlingTest.nestml b/tests/nest_tests/resources/StringHandlingTest.nestml index 8949c8154..c13977a39 100644 --- a/tests/nest_tests/resources/StringHandlingTest.nestml +++ b/tests/nest_tests/resources/StringHandlingTest.nestml @@ -1,28 +1,27 @@ -""" -StringHandlingTest.nestml -######################### - - -Copyright statement -+++++++++++++++++++ - -This file is part of NEST. - -Copyright (C) 2004 The NEST Initiative - -NEST is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -NEST is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with NEST. If not, see . -""" +# StringHandlingTest.nestml +# ######################### +# +# +# Copyright statement +# +++++++++++++++++++ +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . +# model string_handling_test: state: s1 string = "abc" diff --git a/tests/nest_tests/resources/TimeVariableNeuron.nestml b/tests/nest_tests/resources/TimeVariableNeuron.nestml index 69450ae3e..2d9dbd2a7 100644 --- a/tests/nest_tests/resources/TimeVariableNeuron.nestml +++ b/tests/nest_tests/resources/TimeVariableNeuron.nestml @@ -1,28 +1,27 @@ -""" -TimeVariableNeuron.nestml -######################### - - -Copyright statement -+++++++++++++++++++ - -This file is part of NEST. - -Copyright (C) 2004 The NEST Initiative - -NEST is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -NEST is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with NEST. If not, see . -""" +# TimeVariableNeuron.nestml +# ######################### +# +# +# Copyright statement +# +++++++++++++++++++ +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . +# model time_variable_neuron: state: x ms = 0. ms diff --git a/tests/nest_tests/resources/TimeVariablePrePostSynapse.nestml b/tests/nest_tests/resources/TimeVariablePrePostSynapse.nestml index fafb74d21..9a828dd8c 100644 --- a/tests/nest_tests/resources/TimeVariablePrePostSynapse.nestml +++ b/tests/nest_tests/resources/TimeVariablePrePostSynapse.nestml @@ -1,28 +1,27 @@ -""" -TimeVariablePrePostSynapse.nestml -################################# - - -Copyright statement -+++++++++++++++++++ - -This file is part of NEST. - -Copyright (C) 2004 The NEST Initiative - -NEST is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -NEST is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with NEST. If not, see . -""" +# TimeVariablePrePostSynapse.nestml +# ################################# +# +# +# Copyright statement +# +++++++++++++++++++ +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . +# model time_variable_pre_post_synapse: state: x ms = 0 ms diff --git a/tests/nest_tests/resources/TimeVariableSynapse.nestml b/tests/nest_tests/resources/TimeVariableSynapse.nestml index 79a8fedaa..ea38bde3c 100644 --- a/tests/nest_tests/resources/TimeVariableSynapse.nestml +++ b/tests/nest_tests/resources/TimeVariableSynapse.nestml @@ -1,28 +1,27 @@ -""" -TimeVariableSynapse.nestml -########################## - - -Copyright statement -+++++++++++++++++++ - -This file is part of NEST. - -Copyright (C) 2004 The NEST Initiative - -NEST is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -NEST is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with NEST. If not, see . -""" +# TimeVariableSynapse.nestml +# ########################## +# +# +# Copyright statement +# +++++++++++++++++++ +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . +# model time_variable_synapse: state: x ms = 0. ms diff --git a/tests/nest_tests/resources/Vectors.nestml b/tests/nest_tests/resources/Vectors.nestml index 066372073..94c70347d 100644 --- a/tests/nest_tests/resources/Vectors.nestml +++ b/tests/nest_tests/resources/Vectors.nestml @@ -1,35 +1,34 @@ -""" -Vectors.nestml -############## - - -Description -+++++++++++ - -This model is used to test vector operations with NEST. - - -Copyright statement -+++++++++++++++++++ - -This file is part of NEST. - -Copyright (C) 2004 The NEST Initiative - -NEST is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -NEST is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with NEST. If not, see . -""" - +# Vectors.nestml +# ############## +# +# +# Description +# +++++++++++ +# +# This model is used to test vector operations with NEST. +# +# +# Copyright statement +# +++++++++++++++++++ +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . + +# model vectors: state: V_m mV = 0 mV diff --git a/tests/nest_tests/resources/VectorsDeclarationAndAssignment.nestml b/tests/nest_tests/resources/VectorsDeclarationAndAssignment.nestml index 02c85ddbb..a6a6fc481 100644 --- a/tests/nest_tests/resources/VectorsDeclarationAndAssignment.nestml +++ b/tests/nest_tests/resources/VectorsDeclarationAndAssignment.nestml @@ -1,39 +1,38 @@ -""" - -VectorsDeclarationAndAssignment.nestml -###################################### - - -Description -+++++++++++ - -This model is used to test if broken CoCos are identified correctly. Here, if vectors in non-vector declaration -are detected. -Positive case. - - -Copyright statement -+++++++++++++++++++ - -This file is part of NEST. - -Copyright (C) 2004 The NEST Initiative - -NEST is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -NEST is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with NEST. If not, see . - -""" - +# +# VectorsDeclarationAndAssignment.nestml +# ###################################### +# +# +# Description +# +++++++++++ +# +# This model is used to test if broken CoCos are identified correctly. Here, if vectors in non-vector declaration +# are detected. +# Positive case. +# +# +# Copyright statement +# +++++++++++++++++++ +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . +# + +# model vector_declaration: state: g_in [20] mV = 11mV diff --git a/tests/nest_tests/resources/VectorsResize.nestml b/tests/nest_tests/resources/VectorsResize.nestml index 6ebfdf8db..bc8657c87 100644 --- a/tests/nest_tests/resources/VectorsResize.nestml +++ b/tests/nest_tests/resources/VectorsResize.nestml @@ -1,34 +1,33 @@ -""" -VectorsResize.nestml -#################### - - -Description -+++++++++++ - -This model is used to test vector operations with NEST. - - -Copyright statement -+++++++++++++++++++ - -This file is part of NEST. - -Copyright (C) 2004 The NEST Initiative - -NEST is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -NEST is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with NEST. If not, see . -""" +# VectorsResize.nestml +# #################### +# +# +# Description +# +++++++++++ +# +# This model is used to test vector operations with NEST. +# +# +# Copyright statement +# +++++++++++++++++++ +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . +# model vector_resize: state: # accumulator for x values diff --git a/tests/nest_tests/resources/WhileLoop.nestml b/tests/nest_tests/resources/WhileLoop.nestml index e6d42c007..4cd4020d2 100644 --- a/tests/nest_tests/resources/WhileLoop.nestml +++ b/tests/nest_tests/resources/WhileLoop.nestml @@ -1,29 +1,28 @@ -""" -WhileLoop.nestml -################ - - -Copyright statement -+++++++++++++++++++ - -This file is part of NEST. - -Copyright (C) 2004 The NEST Initiative - -NEST is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -NEST is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with NEST. If not, see . -""" - +# WhileLoop.nestml +# ################ +# +# +# Copyright statement +# +++++++++++++++++++ +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . + +# model while_loop: state: y real = 0.025 diff --git a/tests/nest_tests/resources/add_spikes_to_ode.nestml b/tests/nest_tests/resources/add_spikes_to_ode.nestml index 9801faa02..3dc74fd56 100644 --- a/tests/nest_tests/resources/add_spikes_to_ode.nestml +++ b/tests/nest_tests/resources/add_spikes_to_ode.nestml @@ -1,29 +1,28 @@ -""" -add_spikes_to_ode.nestml -######################## - -Test that spikes from an input port can be directly added to a linear (propagator-solved) and nonlinear (numeric solver) ODE. - -Copyright statement -+++++++++++++++++++ - -This file is part of NEST. - -Copyright (C) 2004 The NEST Initiative - -NEST is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -NEST is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with NEST. If not, see . -""" +# add_spikes_to_ode.nestml +# ######################## +# +# Test that spikes from an input port can be directly added to a linear (propagator-solved) and nonlinear (numeric solver) ODE. +# +# Copyright statement +# +++++++++++++++++++ +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . +# model add_spikes_to_ode: state: x real = 0 diff --git a/tests/nest_tests/resources/aeif_cond_alpha_alt_neuron.nestml b/tests/nest_tests/resources/aeif_cond_alpha_alt_neuron.nestml index 9121ef2b9..7428601ab 100644 --- a/tests/nest_tests/resources/aeif_cond_alpha_alt_neuron.nestml +++ b/tests/nest_tests/resources/aeif_cond_alpha_alt_neuron.nestml @@ -1,44 +1,43 @@ -""" -aeif_cond_alpha - Conductance based exponential integrate-and-fire neuron model -############################################################################### - -Description -+++++++++++ - -aeif_psc_alpha is the adaptive exponential integrate and fire neuron according to Brette and Gerstner (2005), with post-synaptic conductances in the form of a bi-exponential ("alpha") function. - -The membrane potential is given by the following differential equation: - -.. math:: - - C_m \frac{dV_m}{dt} = - -g_L(V_m-E_L)+g_L\Delta_T\exp\left(\frac{V_m-V_{th}}{\Delta_T}\right) - - g_e(t)(V_m-E_e) \\ - -g_i(t)(V_m-E_i)-w + I_e - -and - -.. math:: - - \tau_w \frac{dw}{dt} = a(V_m-E_L) - w - -Note that the membrane potential can diverge to positive infinity due to the exponential term. To avoid numerical instabilities, instead of :math:`V_m`, the value :math:`\min(V_m,V_{peak})` is used in the dynamical equations. - - -References -++++++++++ - -.. [1] Brette R and Gerstner W (2005). Adaptive exponential - integrate-and-fire model as an effective description of neuronal - activity. Journal of Neurophysiology. 943637-3642 - DOI: https://doi.org/10.1152/jn.00686.2005 - - -See also -++++++++ - -iaf_psc_alpha, aeif_psc_exp -""" +# aeif_cond_alpha - Conductance based exponential integrate-and-fire neuron model +# ############################################################################### +# +# Description +# +++++++++++ +# +# aeif_psc_alpha is the adaptive exponential integrate and fire neuron according to Brette and Gerstner (2005), with post-synaptic conductances in the form of a bi-exponential ("alpha") function. +# +# The membrane potential is given by the following differential equation: +# +# .. math:: +# +# C_m \frac{dV_m}{dt} = +# -g_L(V_m-E_L)+g_L\Delta_T\exp\left(\frac{V_m-V_{th}}{\Delta_T}\right) - +# g_e(t)(V_m-E_e) \\ +# -g_i(t)(V_m-E_i)-w + I_e +# +# and +# +# .. math:: +# +# \tau_w \frac{dw}{dt} = a(V_m-E_L) - w +# +# Note that the membrane potential can diverge to positive infinity due to the exponential term. To avoid numerical instabilities, instead of :math:`V_m`, the value :math:`\min(V_m,V_{peak})` is used in the dynamical equations. +# +# +# References +# ++++++++++ +# +# .. [1] Brette R and Gerstner W (2005). Adaptive exponential +# integrate-and-fire model as an effective description of neuronal +# activity. Journal of Neurophysiology. 943637-3642 +# DOI: https://doi.org/10.1152/jn.00686.2005 +# +# +# See also +# ++++++++ +# +# iaf_psc_alpha, aeif_psc_exp +# model aeif_cond_alpha_alt_neuron: state: diff --git a/tests/nest_tests/resources/alpha_function_2nd_order_ode_neuron.nestml b/tests/nest_tests/resources/alpha_function_2nd_order_ode_neuron.nestml index fa0d1ef88..82111c9cc 100644 --- a/tests/nest_tests/resources/alpha_function_2nd_order_ode_neuron.nestml +++ b/tests/nest_tests/resources/alpha_function_2nd_order_ode_neuron.nestml @@ -1,29 +1,28 @@ -""" -alpha_function_2nd_order_ode_neuron.nestml -########################################## - -Tests that for a system of higher-oder ODEs of the form F(x'',x',x)=0, integrate_odes(x) includes the integration of all the higher-order variables involved of the system. - -Copyright statement -+++++++++++++++++++ - -This file is part of NEST. - -Copyright (C) 2004 The NEST Initiative - -NEST is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -NEST is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with NEST. If not, see . -""" +# alpha_function_2nd_order_ode_neuron.nestml +# ########################################## +# +# Tests that for a system of higher-oder ODEs of the form F(x'',x',x)=0, integrate_odes(x) includes the integration of all the higher-order variables involved of the system. +# +# Copyright statement +# +++++++++++++++++++ +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . +# model alpha_function_2nd_order_ode_neuron: state: x real = 0 diff --git a/tests/nest_tests/resources/beta_function_with_inline_expression_neuron.nestml b/tests/nest_tests/resources/beta_function_with_inline_expression_neuron.nestml index 753576852..51af5512b 100644 --- a/tests/nest_tests/resources/beta_function_with_inline_expression_neuron.nestml +++ b/tests/nest_tests/resources/beta_function_with_inline_expression_neuron.nestml @@ -1,32 +1,31 @@ -""" -beta_function_with_inline_expression_neuron -########################################### - -Description -+++++++++++ - -Used for testing processing of inline expressions. - - -Copyright -+++++++++ - -This file is part of NEST. - -Copyright (C) 2004 The NEST Initiative - -NEST is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -NEST is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. -You should have received a copy of the GNU General Public License -along with NEST. If not, see . -""" +# beta_function_with_inline_expression_neuron +# ########################################### +# +# Description +# +++++++++++ +# +# Used for testing processing of inline expressions. +# +# +# Copyright +# +++++++++ +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . +# model beta_function_with_inline_expression_neuron: parameters: diff --git a/tests/nest_tests/resources/delay_test_assigned_delay2_synapse.nestml b/tests/nest_tests/resources/delay_test_assigned_delay2_synapse.nestml index 6373a19a9..ff0110fe1 100644 --- a/tests/nest_tests/resources/delay_test_assigned_delay2_synapse.nestml +++ b/tests/nest_tests/resources/delay_test_assigned_delay2_synapse.nestml @@ -1,7 +1,6 @@ -""" -delay_test_assigned_delay2_synapse -################################## -""" +# delay_test_assigned_delay2_synapse +# ################################## +# model delay_test_assigned_delay2_synapse: state: w real = 1 # Synaptic weight diff --git a/tests/nest_tests/resources/delay_test_assigned_delay_synapse.nestml b/tests/nest_tests/resources/delay_test_assigned_delay_synapse.nestml index 3c7866319..32b6b04c6 100644 --- a/tests/nest_tests/resources/delay_test_assigned_delay_synapse.nestml +++ b/tests/nest_tests/resources/delay_test_assigned_delay_synapse.nestml @@ -1,7 +1,6 @@ -""" -delay_test_assigned_delay_synapse -################################# -""" +# delay_test_assigned_delay_synapse +# ################################# +# model delay_test_assigned_delay_synapse: state: w real = 1 # Synaptic weight diff --git a/tests/nest_tests/resources/delay_test_assigned_synapse.nestml b/tests/nest_tests/resources/delay_test_assigned_synapse.nestml index 04e451613..1f875fcfc 100644 --- a/tests/nest_tests/resources/delay_test_assigned_synapse.nestml +++ b/tests/nest_tests/resources/delay_test_assigned_synapse.nestml @@ -1,7 +1,6 @@ -""" -delay_test_assigned_synapse -########################### -""" +# delay_test_assigned_synapse +# ########################### +# model delay_test_assigned_synapse: state: w real = 1 # Synaptic weight diff --git a/tests/nest_tests/resources/delay_test_plastic_synapse.nestml b/tests/nest_tests/resources/delay_test_plastic_synapse.nestml index f7ba1ff2d..3b11d1597 100644 --- a/tests/nest_tests/resources/delay_test_plastic_synapse.nestml +++ b/tests/nest_tests/resources/delay_test_plastic_synapse.nestml @@ -1,7 +1,6 @@ -""" -delay_test_synapse_plastic -########################## -""" +# delay_test_synapse_plastic +# ########################## +# model delay_test_plastic_synapse: state: x ms = 0 ms diff --git a/tests/nest_tests/resources/delay_test_synapse.nestml b/tests/nest_tests/resources/delay_test_synapse.nestml index a403c650b..0441297c4 100644 --- a/tests/nest_tests/resources/delay_test_synapse.nestml +++ b/tests/nest_tests/resources/delay_test_synapse.nestml @@ -1,7 +1,6 @@ -""" -delay_test_synapse -################## -""" +# delay_test_synapse +# ################## +# model delay_test_synapse: state: x ms = 0 ms diff --git a/tests/nest_tests/resources/dopa_second_order_synapse.nestml b/tests/nest_tests/resources/dopa_second_order_synapse.nestml index 794248f6f..4eb3caef5 100644 --- a/tests/nest_tests/resources/dopa_second_order_synapse.nestml +++ b/tests/nest_tests/resources/dopa_second_order_synapse.nestml @@ -1,35 +1,34 @@ -""" -dopa_second_order_synapse -######################### - - -Description -+++++++++++ - -This model is used to test second-order integration of dopamine spikes. - - - -Copyright statement -+++++++++++++++++++ - -This file is part of NEST. - -Copyright (C) 2004 The NEST Initiative - -NEST is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -NEST is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with NEST. If not, see . -""" +# dopa_second_order_synapse +# ######################### +# +# +# Description +# +++++++++++ +# +# This model is used to test second-order integration of dopamine spikes. +# +# +# +# Copyright statement +# +++++++++++++++++++ +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . +# model dopa_second_order_synapse: state: dopa_rate real = 0. diff --git a/tests/nest_tests/resources/homogeneous_parameters_synapse.nestml b/tests/nest_tests/resources/homogeneous_parameters_synapse.nestml index c53105bc6..7f6864a91 100644 --- a/tests/nest_tests/resources/homogeneous_parameters_synapse.nestml +++ b/tests/nest_tests/resources/homogeneous_parameters_synapse.nestml @@ -1,11 +1,10 @@ -""" -Static synapse -############## - -Description -+++++++++++ -A synapse where the synaptic strength (weight) does not evolve with simulated time, but is defined as a (constant) parameter. -""" +# Static synapse +# ############## +# +# Description +# +++++++++++ +# A synapse where the synaptic strength (weight) does not evolve with simulated time, but is defined as a (constant) parameter. +# model static_synapse: parameters: diff --git a/tests/nest_tests/resources/iaf_cond_exp_Istep_neuron.nestml b/tests/nest_tests/resources/iaf_cond_exp_Istep_neuron.nestml index a348b9540..e4fdc2b3f 100644 --- a/tests/nest_tests/resources/iaf_cond_exp_Istep_neuron.nestml +++ b/tests/nest_tests/resources/iaf_cond_exp_Istep_neuron.nestml @@ -1,26 +1,25 @@ -""" -iaf_cond_exp_Istep_neuron - Simple conductance based leaky integrate-and-fire neuron model with step current -############################################################################################################ - -Description -+++++++++++ - -This is a variation of iaf_cond_exp [1] that incorporates a stepwise-constant injected current, defined according to a vector of times (``t_step``) and a vector of current amplitudes at those times (``I_step``). - -References -++++++++++ - -.. [1] Meffin H, Burkitt AN, Grayden DB (2004). An analytical - model for the large, fluctuating synaptic conductance state typical of - neocortical neurons in vivo. Journal of Computational Neuroscience, - 16:159-175. - DOI: https://doi.org/10.1023/B:JCNS.0000014108.03012.81 - -See also -++++++++ - -iaf_psc_delta, iaf_psc_exp, iaf_cond_exp -""" +# iaf_cond_exp_Istep_neuron - Simple conductance based leaky integrate-and-fire neuron model with step current +# ############################################################################################################ +# +# Description +# +++++++++++ +# +# This is a variation of iaf_cond_exp [1] that incorporates a stepwise-constant injected current, defined according to a vector of times (``t_step``) and a vector of current amplitudes at those times (``I_step``). +# +# References +# ++++++++++ +# +# .. [1] Meffin H, Burkitt AN, Grayden DB (2004). An analytical +# model for the large, fluctuating synaptic conductance state typical of +# neocortical neurons in vivo. Journal of Computational Neuroscience, +# 16:159-175. +# DOI: https://doi.org/10.1023/B:JCNS.0000014108.03012.81 +# +# See also +# ++++++++ +# +# iaf_psc_delta, iaf_psc_exp, iaf_cond_exp +# model iaf_cond_exp_Istep_neuron: state: V_m mV = E_L # membrane potential diff --git a/tests/nest_tests/resources/iaf_psc_exp_multisynapse.nestml b/tests/nest_tests/resources/iaf_psc_exp_multisynapse.nestml index 621918172..2c73778ba 100644 --- a/tests/nest_tests/resources/iaf_psc_exp_multisynapse.nestml +++ b/tests/nest_tests/resources/iaf_psc_exp_multisynapse.nestml @@ -1,16 +1,15 @@ -""" -iaf_psc_exp_multisynapse - Leaky integrate-and-fire neuron model with multiple ports -#################################################################################### - -Description -+++++++++++ - -Used in NESTML unit testing. - -For more information about the model, see iaf_psc_exp in the ``models`` directory. - -For more information about "multisynapse" models, please refer to the NESTML documentation. -""" +# iaf_psc_exp_multisynapse - Leaky integrate-and-fire neuron model with multiple ports +# #################################################################################### +# +# Description +# +++++++++++ +# +# Used in NESTML unit testing. +# +# For more information about the model, see iaf_psc_exp in the ``models`` directory. +# +# For more information about "multisynapse" models, please refer to the NESTML documentation. +# model iaf_psc_exp_multisynapse_neuron: state: V_m mV = E_L # membrane potential diff --git a/tests/nest_tests/resources/iaf_psc_exp_multisynapse_vectors.nestml b/tests/nest_tests/resources/iaf_psc_exp_multisynapse_vectors.nestml index eec261c0f..305fcf53e 100644 --- a/tests/nest_tests/resources/iaf_psc_exp_multisynapse_vectors.nestml +++ b/tests/nest_tests/resources/iaf_psc_exp_multisynapse_vectors.nestml @@ -1,16 +1,15 @@ -""" -iaf_psc_exp_multisynapse - Leaky integrate-and-fire neuron model with multiple ports -#################################################################################### - -Description -+++++++++++ - -Used in NESTML unit testing. - -For more information about the model, see iaf_psc_exp in the ``models`` directory. - -For more information about "multisynapse" models, please refer to the NESTML documentation. -""" +# iaf_psc_exp_multisynapse - Leaky integrate-and-fire neuron model with multiple ports +# #################################################################################### +# +# Description +# +++++++++++ +# +# Used in NESTML unit testing. +# +# For more information about the model, see iaf_psc_exp in the ``models`` directory. +# +# For more information about "multisynapse" models, please refer to the NESTML documentation. +# model iaf_psc_exp_multisynapse_vectors_neuron: state: V_m mV = E_L # membrane potential diff --git a/tests/nest_tests/resources/iaf_psc_exp_nonlineardendrite.nestml b/tests/nest_tests/resources/iaf_psc_exp_nonlineardendrite.nestml index a81642585..cb29de804 100644 --- a/tests/nest_tests/resources/iaf_psc_exp_nonlineardendrite.nestml +++ b/tests/nest_tests/resources/iaf_psc_exp_nonlineardendrite.nestml @@ -1,36 +1,35 @@ -""" -iaf_psc_exp_nonlineardendrite.nestml -#################################### - -Description -+++++++++++ - -Neuron model used in ``non_linear_dendrite_test.py``. - -A dendritic action potential occurs when the net synaptic current exceeds the threshold value ``i_th``. An extra, pulse-shaped dendritic current is then activated with amplitude ``I_dend_ap`` and duration ``T_dend_ap``. - -For more detailed information and references, please see the active dendrite tutorial at ``doc/tutorials/active_dendrite/nestml_active_dendrite_tutorial.ipynb``. - -Copyright statement -+++++++++++++++++++ - -This file is part of NEST. - -Copyright (C) 2004 The NEST Initiative - -NEST is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -NEST is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with NEST. If not, see . -""" +# iaf_psc_exp_nonlineardendrite.nestml +# #################################### +# +# Description +# +++++++++++ +# +# Neuron model used in ``non_linear_dendrite_test.py``. +# +# A dendritic action potential occurs when the net synaptic current exceeds the threshold value ``i_th``. An extra, pulse-shaped dendritic current is then activated with amplitude ``I_dend_ap`` and duration ``T_dend_ap``. +# +# For more detailed information and references, please see the active dendrite tutorial at ``doc/tutorials/active_dendrite/nestml_active_dendrite_tutorial.ipynb``. +# +# Copyright statement +# +++++++++++++++++++ +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . +# model iaf_psc_exp_nonlineardendrite: state: V_m mV = 0 mV # membrane potential diff --git a/tests/nest_tests/resources/iaf_psc_exp_resolution_test.nestml b/tests/nest_tests/resources/iaf_psc_exp_resolution_test.nestml index 2de1cd1be..d659d2e78 100644 --- a/tests/nest_tests/resources/iaf_psc_exp_resolution_test.nestml +++ b/tests/nest_tests/resources/iaf_psc_exp_resolution_test.nestml @@ -1,12 +1,11 @@ -""" -iaf_psc_exp_resolution_test -########################### - -Description -+++++++++++ - -Used to test resolution() function. -""" +# iaf_psc_exp_resolution_test +# ########################### +# +# Description +# +++++++++++ +# +# Used to test resolution() function. +# model iaf_psc_exp_resolution_test_neuron: state: V_m mV = E_L diff --git a/tests/nest_tests/resources/input_ports.nestml b/tests/nest_tests/resources/input_ports.nestml index e60aa7b8b..057039a89 100644 --- a/tests/nest_tests/resources/input_ports.nestml +++ b/tests/nest_tests/resources/input_ports.nestml @@ -1,34 +1,33 @@ -""" -input_ports.nestml -################## - - -Description -+++++++++++ - -This test is used to test the declaration of both vectorized and non-vectorized input ports. - - -Copyright statement -+++++++++++++++++++ - -This file is part of NEST. - -Copyright (C) 2004 The NEST Initiative - -NEST is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -NEST is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with NEST. If not, see . -""" +# input_ports.nestml +# ################## +# +# +# Description +# +++++++++++ +# +# This test is used to test the declaration of both vectorized and non-vectorized input ports. +# +# +# Copyright statement +# +++++++++++++++++++ +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . +# model input_ports: state: bar pA = 0 pA diff --git a/tests/nest_tests/resources/input_ports_in_loop.nestml b/tests/nest_tests/resources/input_ports_in_loop.nestml index 8fea931f1..ec8a253a5 100644 --- a/tests/nest_tests/resources/input_ports_in_loop.nestml +++ b/tests/nest_tests/resources/input_ports_in_loop.nestml @@ -1,34 +1,33 @@ -""" -input_ports_in_loop.nestml -########################## - - -Description -+++++++++++ - -This test is used to test the usage of both vectorized and non-vectorized input ports in loops - - -Copyright statement -+++++++++++++++++++ - -This file is part of NEST. - -Copyright (C) 2004 The NEST Initiative - -NEST is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -NEST is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with NEST. If not, see . -""" +# input_ports_in_loop.nestml +# ########################## +# +# +# Description +# +++++++++++ +# +# This test is used to test the usage of both vectorized and non-vectorized input ports in loops +# +# +# Copyright statement +# +++++++++++++++++++ +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . +# model input_ports_loop: state: bar real = 0 diff --git a/tests/nest_tests/resources/integrate_odes_nonlinear_test.nestml b/tests/nest_tests/resources/integrate_odes_nonlinear_test.nestml index 22fde3bdd..9c9189956 100644 --- a/tests/nest_tests/resources/integrate_odes_nonlinear_test.nestml +++ b/tests/nest_tests/resources/integrate_odes_nonlinear_test.nestml @@ -1,6 +1,5 @@ -""" -Model for testing the integrate_odes() function. -""" +# Model for testing the integrate_odes() function. +# model integrate_odes_nonlinear_test: state: test_1 real = 0. diff --git a/tests/nest_tests/resources/integrate_odes_test.nestml b/tests/nest_tests/resources/integrate_odes_test.nestml index ae0f80452..8d9ec0cea 100644 --- a/tests/nest_tests/resources/integrate_odes_test.nestml +++ b/tests/nest_tests/resources/integrate_odes_test.nestml @@ -1,6 +1,5 @@ -""" -Model for testing the integrate_odes() function. -""" +# Model for testing the integrate_odes() function. +# model integrate_odes_test: state: test_1 real = 0. diff --git a/tests/nest_tests/resources/integrate_odes_test_params.nestml b/tests/nest_tests/resources/integrate_odes_test_params.nestml index d6430e537..8b8734d6f 100644 --- a/tests/nest_tests/resources/integrate_odes_test_params.nestml +++ b/tests/nest_tests/resources/integrate_odes_test_params.nestml @@ -1,6 +1,5 @@ -""" -Model for testing the integrate_odes() function. -""" +# Model for testing the integrate_odes() function. +# model integrate_odes_test: state: test_1 real = 0. diff --git a/tests/nest_tests/resources/integrate_odes_test_params2.nestml b/tests/nest_tests/resources/integrate_odes_test_params2.nestml index 616401e48..261333b42 100644 --- a/tests/nest_tests/resources/integrate_odes_test_params2.nestml +++ b/tests/nest_tests/resources/integrate_odes_test_params2.nestml @@ -1,6 +1,5 @@ -""" -Model for testing the integrate_odes() function. -""" +# Model for testing the integrate_odes() function. +# model integrate_odes_test: state: test_1 real = 0. diff --git a/tests/nest_tests/resources/minimal_neuron.nestml b/tests/nest_tests/resources/minimal_neuron.nestml index fd7692a8a..392e4b025 100644 --- a/tests/nest_tests/resources/minimal_neuron.nestml +++ b/tests/nest_tests/resources/minimal_neuron.nestml @@ -1,31 +1,30 @@ -""" -minimal_neuron.nestml -##################### - -This is a very minimal neuron model for testing, containing as few blocks as possible. - - -Copyright statement -+++++++++++++++++++ - -This file is part of NEST. - -Copyright (C) 2004 The NEST Initiative - -NEST is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -NEST is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with NEST. If not, see . -""" - +# minimal_neuron.nestml +# ##################### +# +# This is a very minimal neuron model for testing, containing as few blocks as possible. +# +# +# Copyright statement +# +++++++++++++++++++ +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . + +# model minimal_neuron: output: spike diff --git a/tests/nest_tests/resources/random_functions_illegal_neuron.nestml b/tests/nest_tests/resources/random_functions_illegal_neuron.nestml index 9954459d3..1778a3115 100644 --- a/tests/nest_tests/resources/random_functions_illegal_neuron.nestml +++ b/tests/nest_tests/resources/random_functions_illegal_neuron.nestml @@ -1,29 +1,28 @@ -""" -random_functions_illegal_neuron.nestml -###################################### - - -Copyright statement -+++++++++++++++++++ - -This file is part of NEST. - -Copyright (C) 2004 The NEST Initiative - -NEST is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -NEST is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with NEST. If not, see . -""" - +# random_functions_illegal_neuron.nestml +# ###################################### +# +# +# Copyright statement +# +++++++++++++++++++ +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . + +# model random_functions_illegal_neuron: state: noise real = random_normal(0,sigma_noise) diff --git a/tests/nest_tests/resources/random_functions_illegal_synapse.nestml b/tests/nest_tests/resources/random_functions_illegal_synapse.nestml index 7790640e4..8e7d027e7 100644 --- a/tests/nest_tests/resources/random_functions_illegal_synapse.nestml +++ b/tests/nest_tests/resources/random_functions_illegal_synapse.nestml @@ -1,29 +1,28 @@ -""" -random_functions_illegal_synapse.nestml -####################################### - - -Copyright statement -+++++++++++++++++++ - -This file is part of NEST. - -Copyright (C) 2004 The NEST Initiative - -NEST is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -NEST is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with NEST. If not, see . -""" - +# random_functions_illegal_synapse.nestml +# ####################################### +# +# +# Copyright statement +# +++++++++++++++++++ +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . + +# model random_functions_illegal_synapse: state: w real = 1 # Synaptic weight diff --git a/tests/nest_tests/resources/test_delta_kernel_neuron.nestml b/tests/nest_tests/resources/test_delta_kernel_neuron.nestml index 20f4bebc5..be8c1eff7 100644 --- a/tests/nest_tests/resources/test_delta_kernel_neuron.nestml +++ b/tests/nest_tests/resources/test_delta_kernel_neuron.nestml @@ -1,12 +1,11 @@ -""" -test_delta_kernel -################# - -Description -+++++++++++ - -Used in NESTML unit testing. -""" +# test_delta_kernel +# ################# +# +# Description +# +++++++++++ +# +# Used in NESTML unit testing. +# model test_delta_kernel_neuron: state: x mV = 0 mV diff --git a/tests/nest_tests/resources/test_plasticity_dynamics_neuron.nestml b/tests/nest_tests/resources/test_plasticity_dynamics_neuron.nestml index cd7b44d13..ac18960a4 100644 --- a/tests/nest_tests/resources/test_plasticity_dynamics_neuron.nestml +++ b/tests/nest_tests/resources/test_plasticity_dynamics_neuron.nestml @@ -1,34 +1,33 @@ -""" -test_plasticity_dynamics_neuron.nestml -####################################### - -Dummy test neuron for plasticity dynamics test. - -Will parrot spikes received on the ``spikes_parrot`` port. - -Has a dummy, second ``spikes_plastic`` port to support STDP-like plastic synapses. - - -Copyright statement -+++++++++++++++++++ - -This file is part of NEST. - -Copyright (C) 2004 The NEST Initiative - -NEST is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -NEST is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with NEST. If not, see . -""" +# test_plasticity_dynamics_neuron.nestml +# ####################################### +# +# Dummy test neuron for plasticity dynamics test. +# +# Will parrot spikes received on the ``spikes_parrot`` port. +# +# Has a dummy, second ``spikes_plastic`` port to support STDP-like plastic synapses. +# +# +# Copyright statement +# +++++++++++++++++++ +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . +# model test_plasticity_dynamics_neuron: state: dummys real = 0 diff --git a/tests/nest_tests/resources/test_plasticity_dynamics_synapse.nestml b/tests/nest_tests/resources/test_plasticity_dynamics_synapse.nestml index b32786f24..16a9e929e 100644 --- a/tests/nest_tests/resources/test_plasticity_dynamics_synapse.nestml +++ b/tests/nest_tests/resources/test_plasticity_dynamics_synapse.nestml @@ -1,32 +1,31 @@ -""" -test_plasticity_dynamics_synapse.nestml -####################################### - -Dummy test synapse for plasticity dynamics test. - -This model is based on "simple_stdp_synapse" in https://github.com/saeedark/Fast-SNN-PymoNNto-rch/blob/main/Benchmarks/Simple/nest_native_LIF.py (Copyright (c) 2023 PesarAmmehZA). It was originally licensed under the MIT License, a copy of which can be found at https://github.com/saeedark/Fast-SNN-PymoNNto-rch/blob/main/LICENSE. The MIT license permits redistribution under the GPL v2 license. - - -Copyright statement -+++++++++++++++++++ - -This file is part of NEST. - -Copyright (C) 2004 The NEST Initiative - -NEST is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -NEST is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with NEST. If not, see . -""" +# test_plasticity_dynamics_synapse.nestml +# ####################################### +# +# Dummy test synapse for plasticity dynamics test. +# +# This model is based on "simple_stdp_synapse" in https://github.com/saeedark/Fast-SNN-PymoNNto-rch/blob/main/Benchmarks/Simple/nest_native_LIF.py (Copyright (c) 2023 PesarAmmehZA). It was originally licensed under the MIT License, a copy of which can be found at https://github.com/saeedark/Fast-SNN-PymoNNto-rch/blob/main/LICENSE. The MIT license permits redistribution under the GPL v2 license. +# +# +# Copyright statement +# +++++++++++++++++++ +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . +# model test_plasticity_dynamics_synapse: state: w real = 1.0 diff --git a/tests/nest_tests/resources/weight_test_assigned_synapse.nestml b/tests/nest_tests/resources/weight_test_assigned_synapse.nestml index 9271adaf4..47e2ce4cc 100644 --- a/tests/nest_tests/resources/weight_test_assigned_synapse.nestml +++ b/tests/nest_tests/resources/weight_test_assigned_synapse.nestml @@ -1,7 +1,6 @@ -""" -weight_test_assigned_synapse -########################### -""" +# weight_test_assigned_synapse +# ########################### +# model weight_test_assigned_synapse: state: w real = 1 # Synaptic weight diff --git a/tests/nest_tests/resources/weight_test_plastic_synapse.nestml b/tests/nest_tests/resources/weight_test_plastic_synapse.nestml index bededd562..307b2cd04 100644 --- a/tests/nest_tests/resources/weight_test_plastic_synapse.nestml +++ b/tests/nest_tests/resources/weight_test_plastic_synapse.nestml @@ -1,7 +1,6 @@ -""" -weight_test_plastic_synapse -########################### -""" +# weight_test_plastic_synapse +# ########################### +# model weight_test_plastic_synapse: state: x real = 0 diff --git a/tests/resources/BlockTest.nestml b/tests/resources/BlockTest.nestml index 96b587f54..940eb14b7 100644 --- a/tests/resources/BlockTest.nestml +++ b/tests/resources/BlockTest.nestml @@ -1,39 +1,38 @@ -""" -BlockTest.nestml -################ - - -Description -+++++++++++ - -This model is used to test if all non-actively used types of blocks are readable, and if the corresponding AST -can be created. It is used to test the following part of the grammar: - -forStmt : 'for' var=NAME 'in' vrom=expression '...' - to=expression 'step' step=signedNumericLiteral BLOCK_OPEN block BLOCK_CLOSE; -whileStmt : 'while' expression BLOCK_OPEN block BLOCK_CLOSE; - - -Copyright statement -+++++++++++++++++++ - -This file is part of NEST. - -Copyright (C) 2004 The NEST Initiative - -NEST is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -NEST is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with NEST. If not, see . -""" +# BlockTest.nestml +# ################ +# +# +# Description +# +++++++++++ +# +# This model is used to test if all non-actively used types of blocks are readable, and if the corresponding AST +# can be created. It is used to test the following part of the grammar: +# +# forStmt : 'for' var=NAME 'in' vrom=expression '...' +# to=expression 'step' step=signedNumericLiteral BLOCK_OPEN block BLOCK_CLOSE; +# whileStmt : 'while' expression BLOCK_OPEN block BLOCK_CLOSE; +# +# +# Copyright statement +# +++++++++++++++++++ +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . +# model BlockTest: update: while j < 3.14 and j>0 or False==true: diff --git a/tests/resources/CommentTest.nestml b/tests/resources/CommentTest.nestml index f07116df2..2bf50c84f 100644 --- a/tests/resources/CommentTest.nestml +++ b/tests/resources/CommentTest.nestml @@ -1,35 +1,34 @@ -""" -CommentTest.nestml -################## - - -Description -+++++++++++ - -This model is used to test whether comments are detected and processed as such. Moreover, it tests -if all comments are attached to their respective elements. - - -Copyright statement -+++++++++++++++++++ - -This file is part of NEST. - -Copyright (C) 2004 The NEST Initiative - -NEST is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -NEST is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with NEST. If not, see . -""" +# CommentTest.nestml +# ################## +# +# +# Description +# +++++++++++ +# +# This model is used to test whether comments are detected and processed as such. Moreover, it tests +# if all comments are attached to their respective elements. +# +# +# Copyright statement +# +++++++++++++++++++ +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . +# model commentTest: #model in comment ok #state pre comment ok diff --git a/tests/resources/CompoundAssignmentWithDifferentButCompatibleUnits.nestml b/tests/resources/CompoundAssignmentWithDifferentButCompatibleUnits.nestml index 928f27f36..a80dc43d9 100644 --- a/tests/resources/CompoundAssignmentWithDifferentButCompatibleUnits.nestml +++ b/tests/resources/CompoundAssignmentWithDifferentButCompatibleUnits.nestml @@ -1,28 +1,27 @@ -""" -CompoundAssignmentWithDifferentButCompatibleUnits.nestml -######################################################## - - -Copyright statement -+++++++++++++++++++ - -This file is part of NEST. - -Copyright (C) 2004 The NEST Initiative - -NEST is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -NEST is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with NEST. If not, see . -""" +# CompoundAssignmentWithDifferentButCompatibleUnits.nestml +# ######################################################## +# +# +# Copyright statement +# +++++++++++++++++++ +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . +# model BlockTest: state: lhs V = 0 V diff --git a/tests/resources/DeclarationWithDifferentButCompatibleUnitMagnitude.nestml b/tests/resources/DeclarationWithDifferentButCompatibleUnitMagnitude.nestml index 4e407bebd..a51e88194 100644 --- a/tests/resources/DeclarationWithDifferentButCompatibleUnitMagnitude.nestml +++ b/tests/resources/DeclarationWithDifferentButCompatibleUnitMagnitude.nestml @@ -1,28 +1,27 @@ -""" -DeclarationWithDifferentButCompatibleUnitMagnitude.nestml -######################################################### - - -Copyright statement -+++++++++++++++++++ - -This file is part of NEST. - -Copyright (C) 2004 The NEST Initiative - -NEST is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -NEST is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with NEST. If not, see . -""" +# DeclarationWithDifferentButCompatibleUnitMagnitude.nestml +# ######################################################### +# +# +# Copyright statement +# +++++++++++++++++++ +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . +# model BlockTest: state: lhs mV = 10V diff --git a/tests/resources/DeclarationWithDifferentButCompatibleUnits.nestml b/tests/resources/DeclarationWithDifferentButCompatibleUnits.nestml index f61235999..3b2a3eedf 100644 --- a/tests/resources/DeclarationWithDifferentButCompatibleUnits.nestml +++ b/tests/resources/DeclarationWithDifferentButCompatibleUnits.nestml @@ -1,28 +1,27 @@ -""" -DeclarationWithDifferentButCompatibleUnits.nestml -################################################# - - -Copyright statement -+++++++++++++++++++ - -This file is part of NEST. - -Copyright (C) 2004 The NEST Initiative - -NEST is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -NEST is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with NEST. If not, see . -""" +# DeclarationWithDifferentButCompatibleUnits.nestml +# ################################################# +# +# +# Copyright statement +# +++++++++++++++++++ +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . +# model BlockTest: state: V_m mV = (10 pA) / (100 pF) * (1 ms) diff --git a/tests/resources/DeclarationWithSameVariableNameAsUnit.nestml b/tests/resources/DeclarationWithSameVariableNameAsUnit.nestml index 9fe17b708..5e1c7841c 100644 --- a/tests/resources/DeclarationWithSameVariableNameAsUnit.nestml +++ b/tests/resources/DeclarationWithSameVariableNameAsUnit.nestml @@ -1,28 +1,27 @@ -""" -DeclarationWithDifferentButCompatibleUnits.nestml -################################################# - - -Copyright statement -+++++++++++++++++++ - -This file is part of NEST. - -Copyright (C) 2004 The NEST Initiative - -NEST is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -NEST is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with NEST. If not, see . -""" +# DeclarationWithDifferentButCompatibleUnits.nestml +# ################################################# +# +# +# Copyright statement +# +++++++++++++++++++ +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . +# model BlockTest: state: V mV = -70. mV diff --git a/tests/resources/DirectAssignmentWithDifferentButCompatibleNestedUnits.nestml b/tests/resources/DirectAssignmentWithDifferentButCompatibleNestedUnits.nestml index a7d9d6192..2e374b089 100644 --- a/tests/resources/DirectAssignmentWithDifferentButCompatibleNestedUnits.nestml +++ b/tests/resources/DirectAssignmentWithDifferentButCompatibleNestedUnits.nestml @@ -1,28 +1,27 @@ -""" -DirectAssignmentWithDifferentButCompatibleNestedUnits.nestml -############################################################ - - -Copyright statement -+++++++++++++++++++ - -This file is part of NEST. - -Copyright (C) 2004 The NEST Initiative - -NEST is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -NEST is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with NEST. If not, see . -""" +# DirectAssignmentWithDifferentButCompatibleNestedUnits.nestml +# ############################################################ +# +# +# Copyright statement +# +++++++++++++++++++ +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . +# model BlockTest: state: lhs mV = 0 mV diff --git a/tests/resources/DirectAssignmentWithDifferentButCompatibleUnits.nestml b/tests/resources/DirectAssignmentWithDifferentButCompatibleUnits.nestml index 4f6f1dbd8..c9f722e0f 100644 --- a/tests/resources/DirectAssignmentWithDifferentButCompatibleUnits.nestml +++ b/tests/resources/DirectAssignmentWithDifferentButCompatibleUnits.nestml @@ -1,28 +1,27 @@ -""" -DirectAssignmentWithDifferentButCompatibleUnits.nestml -###################################################### - - -Copyright statement -+++++++++++++++++++ - -This file is part of NEST. - -Copyright (C) 2004 The NEST Initiative - -NEST is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -NEST is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with NEST. If not, see . -""" +# DirectAssignmentWithDifferentButCompatibleUnits.nestml +# ###################################################### +# +# +# Copyright statement +# +++++++++++++++++++ +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . +# model BlockTest: state: lhs mV = 0 mV diff --git a/tests/resources/ExpressionCollection.nestml b/tests/resources/ExpressionCollection.nestml index f0edec72b..e133401b2 100644 --- a/tests/resources/ExpressionCollection.nestml +++ b/tests/resources/ExpressionCollection.nestml @@ -1,36 +1,35 @@ -""" -ExpressionCollection.nestml -########################### - - -Description -+++++++++++ - -This test model is used to test if parsing of expression works as required. - -For more details see ExpressionParserTest.py. - - -Copyright statement -+++++++++++++++++++ - -This file is part of NEST. - -Copyright (C) 2004 The NEST Initiative - -NEST is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -NEST is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with NEST. If not, see . -""" +# ExpressionCollection.nestml +# ########################### +# +# +# Description +# +++++++++++ +# +# This test model is used to test if parsing of expression works as required. +# +# For more details see ExpressionParserTest.py. +# +# +# Copyright statement +# +++++++++++++++++++ +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . +# model ExpressionCollection: state: r integer = 2 # counts number of tick during the refractory period diff --git a/tests/resources/ExpressionTypeTest.nestml b/tests/resources/ExpressionTypeTest.nestml index 9130415c1..5897a10c8 100644 --- a/tests/resources/ExpressionTypeTest.nestml +++ b/tests/resources/ExpressionTypeTest.nestml @@ -1,45 +1,44 @@ -""" -ExpressionTypeTest.nestml -######################### - - -Description -+++++++++++ - -This test is used to test the resolution of symbols. - expression : leftParentheses='(' term=expression rightParentheses=')' - | left=expression powOp='**' right=expression - | unaryOperator term=expression - | left=expression (timesOp='*' | divOp='/' | moduloOp='%') right=expression - | left=expression (plusOp='+' | minusOp='-') right=expression - | left=expression bitOperator right=expression - | left=expression comparisonOperator right=expression - | logicalNot='not' term=expression - | left=expression logicalOperator right=expression - | condition=expression '?' ifTrue=expression ':' ifNot=expression - | simpleExpression - - -Copyright statement -+++++++++++++++++++ - -This file is part of NEST. - -Copyright (C) 2004 The NEST Initiative - -NEST is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -NEST is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with NEST. If not, see . -""" +# ExpressionTypeTest.nestml +# ######################### +# +# +# Description +# +++++++++++ +# +# This test is used to test the resolution of symbols. +# expression : leftParentheses='(' term=expression rightParentheses=')' +# | left=expression powOp='**' right=expression +# | unaryOperator term=expression +# | left=expression (timesOp='*' | divOp='/' | moduloOp='%') right=expression +# | left=expression (plusOp='+' | minusOp='-') right=expression +# | left=expression bitOperator right=expression +# | left=expression comparisonOperator right=expression +# | logicalNot='not' term=expression +# | left=expression logicalOperator right=expression +# | condition=expression '?' ifTrue=expression ':' ifNot=expression +# | simpleExpression +# +# +# Copyright statement +# +++++++++++++++++++ +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . +# model expressionType_test: state: time s = 2 s diff --git a/tests/resources/FunctionBodyReturnStatementWithDifferentButCompatibleUnits.nestml b/tests/resources/FunctionBodyReturnStatementWithDifferentButCompatibleUnits.nestml index 939febdb9..9526ec3a3 100644 --- a/tests/resources/FunctionBodyReturnStatementWithDifferentButCompatibleUnits.nestml +++ b/tests/resources/FunctionBodyReturnStatementWithDifferentButCompatibleUnits.nestml @@ -1,28 +1,27 @@ -""" -FunctionBodyReturnStatementWithDifferentButCompatibleUnits.nestml -################################################################# - - -Copyright statement -+++++++++++++++++++ - -This file is part of NEST. - -Copyright (C) 2004 The NEST Initiative - -NEST is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -NEST is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with NEST. If not, see . -""" +# FunctionBodyReturnStatementWithDifferentButCompatibleUnits.nestml +# ################################################################# +# +# +# Copyright statement +# +++++++++++++++++++ +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . +# model BlockTest: function foo(bar mV) V: return bar diff --git a/tests/resources/FunctionCallWithDifferentButCompatibleUnits.nestml b/tests/resources/FunctionCallWithDifferentButCompatibleUnits.nestml index e215c7c89..4c73943c7 100644 --- a/tests/resources/FunctionCallWithDifferentButCompatibleUnits.nestml +++ b/tests/resources/FunctionCallWithDifferentButCompatibleUnits.nestml @@ -1,28 +1,27 @@ -""" -FunctionCallWithDifferentButCompatibleUnits.nestml -################################################## - - -Copyright statement -+++++++++++++++++++ - -This file is part of NEST. - -Copyright (C) 2004 The NEST Initiative - -NEST is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -NEST is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with NEST. If not, see . -""" +# FunctionCallWithDifferentButCompatibleUnits.nestml +# ################################################## +# +# +# Copyright statement +# +++++++++++++++++++ +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . +# model BlockTest: function foo(bar mV): return diff --git a/tests/resources/FunctionParameterTemplatingTest.nestml b/tests/resources/FunctionParameterTemplatingTest.nestml index 763ff8a50..d81c903fa 100644 --- a/tests/resources/FunctionParameterTemplatingTest.nestml +++ b/tests/resources/FunctionParameterTemplatingTest.nestml @@ -1,34 +1,33 @@ -""" -FunctionParameterTemplatingTest.nestml -###################################### - - -Description -+++++++++++ - -This test is used to test the correct derivation of types when functions use templated type parameters. - - -Copyright statement -+++++++++++++++++++ - -This file is part of NEST. - -Copyright (C) 2004 The NEST Initiative - -NEST is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -NEST is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with NEST. If not, see . -""" +# FunctionParameterTemplatingTest.nestml +# ###################################### +# +# +# Description +# +++++++++++ +# +# This test is used to test the correct derivation of types when functions use templated type parameters. +# +# +# Copyright statement +# +++++++++++++++++++ +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . +# model templated_function_parameters_type_test: state: force N = 1.5 N diff --git a/tests/resources/MagnitudeCompatibilityTest.nestml b/tests/resources/MagnitudeCompatibilityTest.nestml index ca70aa3be..1e1f7ec2b 100644 --- a/tests/resources/MagnitudeCompatibilityTest.nestml +++ b/tests/resources/MagnitudeCompatibilityTest.nestml @@ -1,34 +1,33 @@ -""" -ExpressionTypeTest.nestml -######################### - - -Description -+++++++++++ - -Test the implicit conversions between units of matching base types. - - -Copyright statement -+++++++++++++++++++ - -This file is part of NEST. - -Copyright (C) 2004 The NEST Initiative - -NEST is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -NEST is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with NEST. If not, see . -""" +# ExpressionTypeTest.nestml +# ######################### +# +# +# Description +# +++++++++++ +# +# Test the implicit conversions between units of matching base types. +# +# +# Copyright statement +# +++++++++++++++++++ +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . +# model expressionType_test: state: volts V = 2 V diff --git a/tests/resources/NestMLPrinterTest.nestml b/tests/resources/NestMLPrinterTest.nestml index 6041ee0af..087fe983b 100644 --- a/tests/resources/NestMLPrinterTest.nestml +++ b/tests/resources/NestMLPrinterTest.nestml @@ -1,35 +1,34 @@ -""" -NestMLPrinterTest.nestml -######################## - - -Description -+++++++++++ - -Test whether the NestML printer and beautifier works as intended. - - -Copyright statement -+++++++++++++++++++ - -This file is part of NEST. - -Copyright (C) 2004 The NEST Initiative - -NEST is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -NEST is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with NEST. If not, see . -""" +# NestMLPrinterTest.nestml +# ######################## +# +# +# Description +# +++++++++++ +# +# Test whether the NestML printer and beautifier works as intended. +# +# +# Copyright statement +# +++++++++++++++++++ +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . # model pre +# model aeif_cond_alpha_implicit: # state pre state: # state in diff --git a/tests/resources/ResolutionTest.nestml b/tests/resources/ResolutionTest.nestml index b2e367939..2fbccb85f 100644 --- a/tests/resources/ResolutionTest.nestml +++ b/tests/resources/ResolutionTest.nestml @@ -1,34 +1,33 @@ -""" -ResolutionTest.nestml -##################### - - -Description -+++++++++++ - -This test is used to test the resolution of symbols. - - -Copyright statement -+++++++++++++++++++ - -This file is part of NEST. - -Copyright (C) 2004 The NEST Initiative - -NEST is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -NEST is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with NEST. If not, see . -""" +# ResolutionTest.nestml +# ##################### +# +# +# Description +# +++++++++++ +# +# This test is used to test the resolution of symbols. +# +# +# Copyright statement +# +++++++++++++++++++ +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . +# model resolution_test: state: test1 integer = 10 diff --git a/tests/resources/RhsFunctionCallWithDifferentButCompatibleUnits.nestml b/tests/resources/RhsFunctionCallWithDifferentButCompatibleUnits.nestml index c7f2495a1..fdcb972bb 100644 --- a/tests/resources/RhsFunctionCallWithDifferentButCompatibleUnits.nestml +++ b/tests/resources/RhsFunctionCallWithDifferentButCompatibleUnits.nestml @@ -1,28 +1,27 @@ -""" -RhsFunctionCallWithDifferentButCompatibleUnits.nestml -##################################################### - - -Copyright statement -+++++++++++++++++++ - -This file is part of NEST. - -Copyright (C) 2004 The NEST Initiative - -NEST is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -NEST is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with NEST. If not, see . -""" +# RhsFunctionCallWithDifferentButCompatibleUnits.nestml +# ##################################################### +# +# +# Copyright statement +# +++++++++++++++++++ +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . +# model BlockTest: state: lhs mV = 0 mV diff --git a/tests/resources/neuron_event_inv_priority_test.nestml b/tests/resources/neuron_event_inv_priority_test.nestml index 89a98f104..94452db60 100644 --- a/tests/resources/neuron_event_inv_priority_test.nestml +++ b/tests/resources/neuron_event_inv_priority_test.nestml @@ -1,34 +1,33 @@ -""" -event_inv_priority_test_neuron -############################## - - -Description -+++++++++++ - -This model is used to test the sequencing of event handlers in neuron models. - - -Copyright statement -+++++++++++++++++++ - -This file is part of NEST. - -Copyright (C) 2004 The NEST Initiative - -NEST is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -NEST is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with NEST. If not, see . -""" +# event_inv_priority_test_neuron +# ############################## +# +# +# Description +# +++++++++++ +# +# This model is used to test the sequencing of event handlers in neuron models. +# +# +# Copyright statement +# +++++++++++++++++++ +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . +# model event_inv_priority_test_neuron: state: tr real = 1. diff --git a/tests/resources/neuron_event_priority_test.nestml b/tests/resources/neuron_event_priority_test.nestml index 80b3a8b33..5770bba80 100644 --- a/tests/resources/neuron_event_priority_test.nestml +++ b/tests/resources/neuron_event_priority_test.nestml @@ -1,34 +1,33 @@ -""" -event_priority_test_neuron -########################## - - -Description -+++++++++++ - -This model is used to test the sequencing of event handlers in neuron models. - - -Copyright statement -+++++++++++++++++++ - -This file is part of NEST. - -Copyright (C) 2004 The NEST Initiative - -NEST is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -NEST is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with NEST. If not, see . -""" +# event_priority_test_neuron +# ########################## +# +# +# Description +# +++++++++++ +# +# This model is used to test the sequencing of event handlers in neuron models. +# +# +# Copyright statement +# +++++++++++++++++++ +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . +# model event_priority_test_neuron: state: tr real = 1. diff --git a/tests/resources/random_number_generators_test.nestml b/tests/resources/random_number_generators_test.nestml index 59bf28c9c..b65210e62 100644 --- a/tests/resources/random_number_generators_test.nestml +++ b/tests/resources/random_number_generators_test.nestml @@ -1,28 +1,27 @@ -""" -random_number_generators_test.nestml -#################################### - - -Copyright statement -+++++++++++++++++++ - -This file is part of NEST. - -Copyright (C) 2004 The NEST Initiative - -NEST is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -NEST is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with NEST. If not, see . -""" +# random_number_generators_test.nestml +# #################################### +# +# +# Copyright statement +# +++++++++++++++++++ +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . +# model test_random: state: p mV = random_normal(500 mV, 25 mV) diff --git a/tests/resources/synapse_event_inv_priority_test.nestml b/tests/resources/synapse_event_inv_priority_test.nestml index 17b971aac..61932fb06 100644 --- a/tests/resources/synapse_event_inv_priority_test.nestml +++ b/tests/resources/synapse_event_inv_priority_test.nestml @@ -1,34 +1,33 @@ -""" -synapse_event_inv_priority_test.nestml -###################################### - - -Description -+++++++++++ - -This model is used to test the sequencing of event handlers in synapse models. - - -Copyright statement -+++++++++++++++++++ - -This file is part of NEST. - -Copyright (C) 2004 The NEST Initiative - -NEST is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -NEST is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with NEST. If not, see . -""" +# synapse_event_inv_priority_test.nestml +# ###################################### +# +# +# Description +# +++++++++++ +# +# This model is used to test the sequencing of event handlers in synapse models. +# +# +# Copyright statement +# +++++++++++++++++++ +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . +# model event_inv_priority_test_synapse: state: tr real = 1. diff --git a/tests/resources/synapse_event_priority_test.nestml b/tests/resources/synapse_event_priority_test.nestml index 3cef60ae6..4bb5a3b84 100644 --- a/tests/resources/synapse_event_priority_test.nestml +++ b/tests/resources/synapse_event_priority_test.nestml @@ -1,34 +1,33 @@ -""" -event_priority_test_synapse -########################### - - -Description -+++++++++++ - -This model is used to test the sequencing of event handlers in synapse models. - - -Copyright statement -+++++++++++++++++++ - -This file is part of NEST. - -Copyright (C) 2004 The NEST Initiative - -NEST is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -NEST is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with NEST. If not, see . -""" +# event_priority_test_synapse +# ########################### +# +# +# Description +# +++++++++++ +# +# This model is used to test the sequencing of event handlers in synapse models. +# +# +# Copyright statement +# +++++++++++++++++++ +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . +# model event_priority_test_synapse: state: tr real = 1. diff --git a/tests/test_nestml_printer.py b/tests/test_nestml_printer.py index b8c48b7d3..4f3f4e3ed 100644 --- a/tests/test_nestml_printer.py +++ b/tests/test_nestml_printer.py @@ -126,13 +126,13 @@ def test_neuron_with_comments(self): assert neuron == model_printer.print(model) def test_neuron_with_docstring(self): - neuron = '"""hello, world\n" \ - "\n" \ - "3.141592653589793"""\n' \ + neuron = "# hello, world\n" \ + "# \n" \ + "# 3.141592653589793\n" \ "model test:\n" \ " parameters:\n" \ " foo integer = 0\n" - model = ModelParser.parse_model(neuron) + model = ModelParser.parse_nestml_compilation_unit(neuron) model_printer = NESTMLPrinter() assert neuron == model_printer.print(model) diff --git a/tests/valid/CoCoConvolveNotCorrectlyParametrized.nestml b/tests/valid/CoCoConvolveNotCorrectlyParametrized.nestml index c4a6a213a..63f67cbf5 100644 --- a/tests/valid/CoCoConvolveNotCorrectlyParametrized.nestml +++ b/tests/valid/CoCoConvolveNotCorrectlyParametrized.nestml @@ -1,36 +1,35 @@ -""" -CoCoConvolveNotCorrectlyParametrized.nestml -########################################### - - -Description -+++++++++++ - -This model is used to test if broken CoCos are identified correctly. Here, if convolve has been correctly provided with a state block defined variable and a spike input port. - -Positive case. - - -Copyright statement -+++++++++++++++++++ - -This file is part of NEST. - -Copyright (C) 2004 The NEST Initiative - -NEST is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -NEST is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with NEST. If not, see . -""" +# CoCoConvolveNotCorrectlyParametrized.nestml +# ########################################### +# +# +# Description +# +++++++++++ +# +# This model is used to test if broken CoCos are identified correctly. Here, if convolve has been correctly provided with a state block defined variable and a spike input port. +# +# Positive case. +# +# +# Copyright statement +# +++++++++++++++++++ +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . +# model CoCoConvolveNotCorrectlyParametrized: parameters: tau ms = 20 ms diff --git a/tests/valid/CoCoConvolveNotCorrectlyProvided.nestml b/tests/valid/CoCoConvolveNotCorrectlyProvided.nestml index 4d465d60e..39b505b31 100644 --- a/tests/valid/CoCoConvolveNotCorrectlyProvided.nestml +++ b/tests/valid/CoCoConvolveNotCorrectlyProvided.nestml @@ -1,36 +1,35 @@ -""" -CoCoConvolveNotCorrectlyProvided.nestml -####################################### - - -Description -+++++++++++ - -This model is used to test if broken CoCos are identified correctly. Here, if convolve has been correctly provided with a state block defined variable and a spike input port. - -Positive case. - - -Copyright statement -+++++++++++++++++++ - -This file is part of NEST. - -Copyright (C) 2004 The NEST Initiative - -NEST is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -NEST is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with NEST. If not, see . -""" +# CoCoConvolveNotCorrectlyProvided.nestml +# ####################################### +# +# +# Description +# +++++++++++ +# +# This model is used to test if broken CoCos are identified correctly. Here, if convolve has been correctly provided with a state block defined variable and a spike input port. +# +# Positive case. +# +# +# Copyright statement +# +++++++++++++++++++ +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . +# model CoCoConvolveNotCorrectlyProvided: equations: kernel test = 10 diff --git a/tests/valid/CoCoEachBlockUnique.nestml b/tests/valid/CoCoEachBlockUnique.nestml index ea222cef0..5e780e79b 100644 --- a/tests/valid/CoCoEachBlockUnique.nestml +++ b/tests/valid/CoCoEachBlockUnique.nestml @@ -1,34 +1,33 @@ -""" -CoCoEachBlockUnique.nestml -########################## - -Description -+++++++++++ - -This model is used to test if broken CoCos are identified correctly. Here, if each block is defined at most once. - -Positive Case. - -Copyright statement -+++++++++++++++++++ - -This file is part of NEST. - -Copyright (C) 2004 The NEST Initiative - -NEST is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -NEST is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with NEST. If not, see . -""" +# CoCoEachBlockUnique.nestml +# ########################## +# +# Description +# +++++++++++ +# +# This model is used to test if broken CoCos are identified correctly. Here, if each block is defined at most once. +# +# Positive Case. +# +# Copyright statement +# +++++++++++++++++++ +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . +# model CoCoEachBlockUnique: state:# each block is unique test1 integer = 0 # no variable is redeclared in the same scope, thus everything correct diff --git a/tests/valid/CoCoElementInSameLine.nestml b/tests/valid/CoCoElementInSameLine.nestml index 94f462c7e..ab420b918 100644 --- a/tests/valid/CoCoElementInSameLine.nestml +++ b/tests/valid/CoCoElementInSameLine.nestml @@ -1,37 +1,36 @@ -""" -CoCoElementInSameLine.nestml -############################ - - -Description -+++++++++++ - -This model is used to check if all cocos work correctly by detecting corresponding broken context. Here, if -recursive definition is detected. - -Positive case. - - -Copyright statement -+++++++++++++++++++ - -This file is part of NEST. - -Copyright (C) 2004 The NEST Initiative - -NEST is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -NEST is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with NEST. If not, see . -""" +# CoCoElementInSameLine.nestml +# ############################ +# +# +# Description +# +++++++++++ +# +# This model is used to check if all cocos work correctly by detecting corresponding broken context. Here, if +# recursive definition is detected. +# +# Positive case. +# +# +# Copyright statement +# +++++++++++++++++++ +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . +# model CoCoElementInSameLine: state: test1 integer = 1 # no recursive definition occurred, thus everything correct diff --git a/tests/valid/CoCoElementNotDefined.nestml b/tests/valid/CoCoElementNotDefined.nestml index 6ff49c2e4..2d9b108b0 100644 --- a/tests/valid/CoCoElementNotDefined.nestml +++ b/tests/valid/CoCoElementNotDefined.nestml @@ -1,37 +1,36 @@ -""" -CoCoElementNotDefined.nestml -############################ - - -Description -+++++++++++ - -This model is used to check if all cocos work correctly by detecting corresponding broken context. Here, if -definition with not defined references is detected. - -Positive case. - - -Copyright statement -+++++++++++++++++++ - -This file is part of NEST. - -Copyright (C) 2004 The NEST Initiative - -NEST is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -NEST is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with NEST. If not, see . -""" +# CoCoElementNotDefined.nestml +# ############################ +# +# +# Description +# +++++++++++ +# +# This model is used to check if all cocos work correctly by detecting corresponding broken context. Here, if +# definition with not defined references is detected. +# +# Positive case. +# +# +# Copyright statement +# +++++++++++++++++++ +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . +# model CoCoElementNotDefined: state: test integer = 0 diff --git a/tests/valid/CoCoFunctionCallNotConsistentWrongArgNumber.nestml b/tests/valid/CoCoFunctionCallNotConsistentWrongArgNumber.nestml index 94359b09d..13766a280 100644 --- a/tests/valid/CoCoFunctionCallNotConsistentWrongArgNumber.nestml +++ b/tests/valid/CoCoFunctionCallNotConsistentWrongArgNumber.nestml @@ -1,36 +1,35 @@ -""" -CoCoFunctionCallNotConsistentWrongArgNumber.nestml -################################################## - - -Description -+++++++++++ - -This model is used to test if broken CoCos are identified correctly. Here, if function calls have the right number of arguments. - -Positive case. - - -Copyright statement -+++++++++++++++++++ - -This file is part of NEST. - -Copyright (C) 2004 The NEST Initiative - -NEST is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -NEST is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with NEST. If not, see . -""" +# CoCoFunctionCallNotConsistentWrongArgNumber.nestml +# ################################################## +# +# +# Description +# +++++++++++ +# +# This model is used to test if broken CoCos are identified correctly. Here, if function calls have the right number of arguments. +# +# Positive case. +# +# +# Copyright statement +# +++++++++++++++++++ +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . +# model CoCoFunctionCallNotConsistentWrongArgNumber: state: test integer = max(1,2) # max is provided with correct number of arguments and types, thus everything is correct diff --git a/tests/valid/CoCoFunctionNotUnique.nestml b/tests/valid/CoCoFunctionNotUnique.nestml index a519cb25c..49ff397a8 100644 --- a/tests/valid/CoCoFunctionNotUnique.nestml +++ b/tests/valid/CoCoFunctionNotUnique.nestml @@ -1,37 +1,36 @@ -""" -CoCoFunctionNotUnique.nestml -############################ - - -Description -+++++++++++ - -This model is used to test if broken CoCos are identified correctly. Here, if redeclaration of predefined functions -is detected. - -Positive Case. - - -Copyright statement -+++++++++++++++++++ - -This file is part of NEST. - -Copyright (C) 2004 The NEST Initiative - -NEST is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -NEST is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with NEST. If not, see . -""" +# CoCoFunctionNotUnique.nestml +# ############################ +# +# +# Description +# +++++++++++ +# +# This model is used to test if broken CoCos are identified correctly. Here, if redeclaration of predefined functions +# is detected. +# +# Positive Case. +# +# +# Copyright statement +# +++++++++++++++++++ +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . +# model CoCoFunctionNotUnique: function deltaNew(Tau_a ms,Tau_b ms) real: # deltaNew is not predefined, thus everything is correct test real = 1 diff --git a/tests/valid/CoCoFunctionRedeclared.nestml b/tests/valid/CoCoFunctionRedeclared.nestml index a6abc8b8a..b0cc9fc05 100644 --- a/tests/valid/CoCoFunctionRedeclared.nestml +++ b/tests/valid/CoCoFunctionRedeclared.nestml @@ -1,37 +1,36 @@ -""" -CoCoFunctionRedeclared.nestml -############################# - - -Description -+++++++++++ - -This model is used to check if all cocos work correctly by detecting corresponding broken context. -Here, if redeclaration of functions has been detected. - -Positive case. - - -Copyright statement -+++++++++++++++++++ - -This file is part of NEST. - -Copyright (C) 2004 The NEST Initiative - -NEST is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -NEST is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with NEST. If not, see . -""" +# CoCoFunctionRedeclared.nestml +# ############################# +# +# +# Description +# +++++++++++ +# +# This model is used to check if all cocos work correctly by detecting corresponding broken context. +# Here, if redeclaration of functions has been detected. +# +# Positive case. +# +# +# Copyright statement +# +++++++++++++++++++ +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . +# model CoCoFunctionRedeclared: function maxGt(arg1 integer,arg2 integer) integer: # both functions have different names, thus everything is if arg1>arg2: diff --git a/tests/valid/CoCoIllegalExpression.nestml b/tests/valid/CoCoIllegalExpression.nestml index 092e8f077..45368223c 100644 --- a/tests/valid/CoCoIllegalExpression.nestml +++ b/tests/valid/CoCoIllegalExpression.nestml @@ -1,37 +1,36 @@ -""" -CoCoIllegalExpression.nestml -############################ - - -Description -+++++++++++ - -This model is used to test if broken CoCos are identified correctly. Here, illegal expressions, e.g. -type(lhs)!= type(rhs) are detected. - -Positive case. - - -Copyright statement -+++++++++++++++++++ - -This file is part of NEST. - -Copyright (C) 2004 The NEST Initiative - -NEST is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -NEST is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with NEST. If not, see . -""" +# CoCoIllegalExpression.nestml +# ############################ +# +# +# Description +# +++++++++++ +# +# This model is used to test if broken CoCos are identified correctly. Here, illegal expressions, e.g. +# type(lhs)!= type(rhs) are detected. +# +# Positive case. +# +# +# Copyright statement +# +++++++++++++++++++ +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . +# model CoCoIllegalExpression: state: test boolean = True diff --git a/tests/valid/CoCoIncorrectReturnStatement.nestml b/tests/valid/CoCoIncorrectReturnStatement.nestml index 95cd6dc87..bf0d0208b 100644 --- a/tests/valid/CoCoIncorrectReturnStatement.nestml +++ b/tests/valid/CoCoIncorrectReturnStatement.nestml @@ -1,37 +1,36 @@ -""" -CoCoIncorrectReturnStatement.nestml -################################### - - -Description -+++++++++++ - -This model is used to test if broken CoCos are identified correctly. Here, if user defined functions without -a proper return statement and wrong type are detected. - -Positive case. - - -Copyright statement -+++++++++++++++++++ - -This file is part of NEST. - -Copyright (C) 2004 The NEST Initiative - -NEST is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -NEST is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with NEST. If not, see . -""" +# CoCoIncorrectReturnStatement.nestml +# ################################### +# +# +# Description +# +++++++++++ +# +# This model is used to test if broken CoCos are identified correctly. Here, if user defined functions without +# a proper return statement and wrong type are detected. +# +# Positive case. +# +# +# Copyright statement +# +++++++++++++++++++ +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . +# model CoCoIncorrectReturnStatement: function foo() mV:# correct return type is given test mV = 10mV diff --git a/tests/valid/CoCoInitValuesWithoutOde.nestml b/tests/valid/CoCoInitValuesWithoutOde.nestml index af506b410..11adef768 100644 --- a/tests/valid/CoCoInitValuesWithoutOde.nestml +++ b/tests/valid/CoCoInitValuesWithoutOde.nestml @@ -1,37 +1,36 @@ -""" -CoCoInitValuesWithoutOde.nestml -############################### - - -Description -+++++++++++ - -This model is used to test if broken CoCos are identified correctly. Here, if initial block variables without ode -declarations are detected. Moreover, if initial values without a right-hand side are detected. - -Positive case. - - -Copyright statement -+++++++++++++++++++ - -This file is part of NEST. - -Copyright (C) 2004 The NEST Initiative - -NEST is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -NEST is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with NEST. If not, see . -""" +# CoCoInitValuesWithoutOde.nestml +# ############################### +# +# +# Description +# +++++++++++ +# +# This model is used to test if broken CoCos are identified correctly. Here, if initial block variables without ode +# declarations are detected. Moreover, if initial values without a right-hand side are detected. +# +# Positive case. +# +# +# Copyright statement +# +++++++++++++++++++ +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . +# model CoCoInitValuesWithoutOde: state: V_m mV = 10mV diff --git a/tests/valid/CoCoInlineExpressionHasNoRhs.nestml b/tests/valid/CoCoInlineExpressionHasNoRhs.nestml index 695e5a32f..e49e87387 100644 --- a/tests/valid/CoCoInlineExpressionHasNoRhs.nestml +++ b/tests/valid/CoCoInlineExpressionHasNoRhs.nestml @@ -1,36 +1,35 @@ -""" -CoCoInlineExpressionHasNoRhs.nestml -################################### - - -Description -+++++++++++ - -This model is used to check if all cocos work correctly by detecting corresponding broken context. Here, if a inline does not a rhs. - -Positive case. - - -Copyright statement -+++++++++++++++++++ - -This file is part of NEST. - -Copyright (C) 2004 The NEST Initiative - -NEST is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -NEST is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with NEST. If not, see . -""" +# CoCoInlineExpressionHasNoRhs.nestml +# ################################### +# +# +# Description +# +++++++++++ +# +# This model is used to check if all cocos work correctly by detecting corresponding broken context. Here, if a inline does not a rhs. +# +# Positive case. +# +# +# Copyright statement +# +++++++++++++++++++ +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . +# model CoCoInlineExpressionHasNoRhs: equations: inline V_rest mV = 10mV # a rhs is defined, thus everything is correct diff --git a/tests/valid/CoCoInlineExpressionWithSeveralLhs.nestml b/tests/valid/CoCoInlineExpressionWithSeveralLhs.nestml index 711143321..671440950 100644 --- a/tests/valid/CoCoInlineExpressionWithSeveralLhs.nestml +++ b/tests/valid/CoCoInlineExpressionWithSeveralLhs.nestml @@ -1,36 +1,35 @@ -""" -CoCoInlineExpressionWithSeveralLhs.nestml -######################################### - - -Description -+++++++++++ - -This model is used to check if all cocos work correctly by detecting corresponding broken context. Here, if a inline with several lhs is detected. - -Positive case. - - -Copyright statement -+++++++++++++++++++ - -This file is part of NEST. - -Copyright (C) 2004 The NEST Initiative - -NEST is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -NEST is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with NEST. If not, see . -""" +# CoCoInlineExpressionWithSeveralLhs.nestml +# ######################################### +# +# +# Description +# +++++++++++ +# +# This model is used to check if all cocos work correctly by detecting corresponding broken context. Here, if a inline with several lhs is detected. +# +# Positive case. +# +# +# Copyright statement +# +++++++++++++++++++ +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . +# model CoCoInlineExpressionWithSeveralLhs: equations: inline V_rest mV = 10mV # only one lhs for a inline, thus everything correct diff --git a/tests/valid/CoCoInputPortWithRedundantTypes.nestml b/tests/valid/CoCoInputPortWithRedundantTypes.nestml index 967f51a4c..2e4bea075 100644 --- a/tests/valid/CoCoInputPortWithRedundantTypes.nestml +++ b/tests/valid/CoCoInputPortWithRedundantTypes.nestml @@ -1,36 +1,35 @@ -""" -CoCoInputPortWithRedundantTypes.nestml -###################################### - - -Description -+++++++++++ - -This model is used to test if broken CoCos are identified correctly. Here, if each input port is defined uniquely, i.e., no redundant keywords are used. - -Positive case. - - -Copyright statement -+++++++++++++++++++ - -This file is part of NEST. - -Copyright (C) 2004 The NEST Initiative - -NEST is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -NEST is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with NEST. If not, see . -""" +# CoCoInputPortWithRedundantTypes.nestml +# ###################################### +# +# +# Description +# +++++++++++ +# +# This model is used to test if broken CoCos are identified correctly. Here, if each input port is defined uniquely, i.e., no redundant keywords are used. +# +# Positive case. +# +# +# Copyright statement +# +++++++++++++++++++ +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . +# model CoCoInputPortWithRedundantTypes: input: spikeInh <- inhibitory spike # no redundant keywords used, thus correct diff --git a/tests/valid/CoCoIntegrateOdesCalledIfEquationsDefined.nestml b/tests/valid/CoCoIntegrateOdesCalledIfEquationsDefined.nestml index cc92cfea7..375880885 100644 --- a/tests/valid/CoCoIntegrateOdesCalledIfEquationsDefined.nestml +++ b/tests/valid/CoCoIntegrateOdesCalledIfEquationsDefined.nestml @@ -1,36 +1,35 @@ -""" -CoCoIntegrateOdesCalledIfEquationsDefined.nestml -################################################ - - -Description -+++++++++++ - -This model is used to test the check that integrate_odes() is called if one or more dynamical equations are defined. - -Positive case. - - -Copyright statement -+++++++++++++++++++ - -This file is part of NEST. - -Copyright (C) 2004 The NEST Initiative - -NEST is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -NEST is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with NEST. If not, see . -""" +# CoCoIntegrateOdesCalledIfEquationsDefined.nestml +# ################################################ +# +# +# Description +# +++++++++++ +# +# This model is used to test the check that integrate_odes() is called if one or more dynamical equations are defined. +# +# Positive case. +# +# +# Copyright statement +# +++++++++++++++++++ +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . +# model CoCoIntegrateOdesCalledIfEquationsDefined: state: x real = 1. diff --git a/tests/valid/CoCoInternalAssignedOutsideBlock.nestml b/tests/valid/CoCoInternalAssignedOutsideBlock.nestml index ec940587a..3c25194e3 100644 --- a/tests/valid/CoCoInternalAssignedOutsideBlock.nestml +++ b/tests/valid/CoCoInternalAssignedOutsideBlock.nestml @@ -1,37 +1,36 @@ -""" -CoCoInternalAssignedOutsideBlock.nestml -######################################## - - -Description -+++++++++++ - -This model is used to check if all cocos work correctly by detecting corresponding broken context. Here, if -assignment of values to internals outside of internals blocks is detected. - -Positive example. - - -Copyright statement -+++++++++++++++++++ - -This file is part of NEST. - -Copyright (C) 2004 The NEST Initiative - -NEST is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -NEST is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with NEST. If not, see . -""" +# CoCoInternalAssignedOutsideBlock.nestml +# ######################################## +# +# +# Description +# +++++++++++ +# +# This model is used to check if all cocos work correctly by detecting corresponding broken context. Here, if +# assignment of values to internals outside of internals blocks is detected. +# +# Positive example. +# +# +# Copyright statement +# +++++++++++++++++++ +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . +# model CoCoInternalAssignedOutsideBlock: internals: # internal is not assigned outside the block, thus everything is correct test mV = 10 mV diff --git a/tests/valid/CoCoInvariantNotBool.nestml b/tests/valid/CoCoInvariantNotBool.nestml index 40e8dde10..a075140d5 100644 --- a/tests/valid/CoCoInvariantNotBool.nestml +++ b/tests/valid/CoCoInvariantNotBool.nestml @@ -1,37 +1,36 @@ -""" -CoCoInvariantNotBool.nestml -########################### - - -Description -+++++++++++ - -This model is used to test if broken CoCos are identified correctly. Here, if the correct type of invariants -is detected and invariants are correctly constructed. - -Positive case. - - -Copyright statement -+++++++++++++++++++ - -This file is part of NEST. - -Copyright (C) 2004 The NEST Initiative - -NEST is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -NEST is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with NEST. If not, see . -""" +# CoCoInvariantNotBool.nestml +# ########################### +# +# +# Description +# +++++++++++ +# +# This model is used to test if broken CoCos are identified correctly. Here, if the correct type of invariants +# is detected and invariants are correctly constructed. +# +# Positive case. +# +# +# Copyright statement +# +++++++++++++++++++ +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . +# model CoCoInvariantNotBool: state: V_notBool mV = 10mV [[V_notBool > V_notBool]]# this should not be detected although on logical level incorrect diff --git a/tests/valid/CoCoKernelType.nestml b/tests/valid/CoCoKernelType.nestml index 2d12b05b5..a9b9e2d0b 100644 --- a/tests/valid/CoCoKernelType.nestml +++ b/tests/valid/CoCoKernelType.nestml @@ -1,38 +1,37 @@ -""" -CoCoKernelCorrectlyTyped.nestml -############################### - - -Description -+++++++++++ - -This model is used to test if broken CoCos are identified correctly. - -Here, the kernel is defined with a correct type. - -Positive case. - - -Copyright statement -+++++++++++++++++++ - -This file is part of NEST. - -Copyright (C) 2004 The NEST Initiative - -NEST is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -NEST is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with NEST. If not, see . -""" +# CoCoKernelCorrectlyTyped.nestml +# ############################### +# +# +# Description +# +++++++++++ +# +# This model is used to test if broken CoCos are identified correctly. +# +# Here, the kernel is defined with a correct type. +# +# Positive case. +# +# +# Copyright statement +# +++++++++++++++++++ +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . +# model CoCoKernelCorrectlyTyped: parameters: tau ms = 10 ms diff --git a/tests/valid/CoCoMultipleNeuronsWithEqualName.nestml b/tests/valid/CoCoMultipleNeuronsWithEqualName.nestml index cbba23f84..6c908f00f 100644 --- a/tests/valid/CoCoMultipleNeuronsWithEqualName.nestml +++ b/tests/valid/CoCoMultipleNeuronsWithEqualName.nestml @@ -1,42 +1,42 @@ -""" -CoCoMultipleNeuronsWithEqualName.nestml -####################################### - - -Description -+++++++++++ - -This model is used to test if broken CoCos are identified correctly. Here, if several neurons with equal name -are detected. - -Positive case. - - -Copyright statement -+++++++++++++++++++ - -This file is part of NEST. - -Copyright (C) 2004 The NEST Initiative - -NEST is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -NEST is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with NEST. If not, see . -""" +# CoCoMultipleNeuronsWithEqualName.nestml +# ####################################### +# +# +# Description +# +++++++++++ +# +# This model is used to test if broken CoCos are identified correctly. Here, if several neurons with equal name +# are detected. +# +# Positive case. +# +# +# Copyright statement +# +++++++++++++++++++ +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . +# model CoCoMultipleNeuronsWithEqualName: state: v_m mV = -10 mV +# model CoCoMultipleNeuronsWithEqualNameNot: # names are not equal, thus should not be detected as an error state: v_m mV = -10 mV diff --git a/tests/valid/CoCoNestNamespaceCollision.nestml b/tests/valid/CoCoNestNamespaceCollision.nestml index c9b495edb..fad05baf6 100644 --- a/tests/valid/CoCoNestNamespaceCollision.nestml +++ b/tests/valid/CoCoNestNamespaceCollision.nestml @@ -1,36 +1,35 @@ -""" -CoCoNestNamespaceCollision.nestml -################################# - -Description -+++++++++++ - -This model is used to test if broken CoCos are identified correctly. Here, if the collision with the nest namespace -is detected. - -Positive case. - - -Copyright statement -+++++++++++++++++++ - -This file is part of NEST. - -Copyright (C) 2004 The NEST Initiative - -NEST is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -NEST is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with NEST. If not, see . -""" +# CoCoNestNamespaceCollision.nestml +# ################################# +# +# Description +# +++++++++++ +# +# This model is used to test if broken CoCos are identified correctly. Here, if the collision with the nest namespace +# is detected. +# +# Positive case. +# +# +# Copyright statement +# +++++++++++++++++++ +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . +# model CoCoNestNamespaceCollision: function handler(Tau_1 mV): # handler is not a NEST specific function, thus everything correct return diff --git a/tests/valid/CoCoNoOrderOfEquations.nestml b/tests/valid/CoCoNoOrderOfEquations.nestml index 59cb14aaf..83facf70c 100644 --- a/tests/valid/CoCoNoOrderOfEquations.nestml +++ b/tests/valid/CoCoNoOrderOfEquations.nestml @@ -1,36 +1,35 @@ -""" -CoCoNoOrderOfEquations.nestml -############################# - - -Description -+++++++++++ - -This model is used to test if broken CoCos are identified correctly. Here, if the order of equations is correct. - -Positive case. - - -Copyright statement -+++++++++++++++++++ - -This file is part of NEST. - -Copyright (C) 2004 The NEST Initiative - -NEST is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -NEST is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with NEST. If not, see . -""" +# CoCoNoOrderOfEquations.nestml +# ############################# +# +# +# Description +# +++++++++++ +# +# This model is used to test if broken CoCos are identified correctly. Here, if the order of equations is correct. +# +# Positive case. +# +# +# Copyright statement +# +++++++++++++++++++ +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . +# model CoCoNoOrderOfEquations: state: V_m mV = 10mV diff --git a/tests/valid/CoCoOdeCorrectlyTyped.nestml b/tests/valid/CoCoOdeCorrectlyTyped.nestml index 6c08bbb5e..05a356b9c 100644 --- a/tests/valid/CoCoOdeCorrectlyTyped.nestml +++ b/tests/valid/CoCoOdeCorrectlyTyped.nestml @@ -1,38 +1,37 @@ -""" -CoCoOdeCorrectlyTyped.nestml -############################ - - -Description -+++++++++++ - -This model is used to test if broken CoCos are identified correctly. - -Here, ODE is defined with correct typing. - -Positive case. - - -Copyright statement -+++++++++++++++++++ - -This file is part of NEST. - -Copyright (C) 2004 The NEST Initiative - -NEST is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -NEST is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with NEST. If not, see . -""" +# CoCoOdeCorrectlyTyped.nestml +# ############################ +# +# +# Description +# +++++++++++ +# +# This model is used to test if broken CoCos are identified correctly. +# +# Here, ODE is defined with correct typing. +# +# Positive case. +# +# +# Copyright statement +# +++++++++++++++++++ +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . +# model CoCoOdeCorrectlyTyped: state: # variable is now defined in the initial block, thus everything is correct. V_m mV = 10 mV diff --git a/tests/valid/CoCoOdeVarNotInInitialValues.nestml b/tests/valid/CoCoOdeVarNotInInitialValues.nestml index a45b85ccf..9be6a7ac8 100644 --- a/tests/valid/CoCoOdeVarNotInInitialValues.nestml +++ b/tests/valid/CoCoOdeVarNotInInitialValues.nestml @@ -1,37 +1,36 @@ -""" -CoCoOdeVarNotInInitialValues.nestml -################################### - - -Description -+++++++++++ - -This model is used to test if broken CoCos are identified correctly. Here, if ode is defiend for a variable outside -the initial-values block. - -Positive case. - - -Copyright statement -+++++++++++++++++++ - -This file is part of NEST. - -Copyright (C) 2004 The NEST Initiative - -NEST is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -NEST is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with NEST. If not, see . -""" +# CoCoOdeVarNotInInitialValues.nestml +# ################################### +# +# +# Description +# +++++++++++ +# +# This model is used to test if broken CoCos are identified correctly. Here, if ode is defiend for a variable outside +# the initial-values block. +# +# Positive case. +# +# +# Copyright statement +# +++++++++++++++++++ +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . +# model CoCoOdeVarNotInInitialValues: state: # variable is now defined in the initial block, thus everything is correct. V_m mV = 10mV diff --git a/tests/valid/CoCoOutputPortDefinedIfEmitCall.nestml b/tests/valid/CoCoOutputPortDefinedIfEmitCall.nestml index 65b591fe2..1dfae6626 100644 --- a/tests/valid/CoCoOutputPortDefinedIfEmitCall.nestml +++ b/tests/valid/CoCoOutputPortDefinedIfEmitCall.nestml @@ -1,36 +1,35 @@ -""" -CoCoOutputPortDefinedIfEmitCall.nestml -###################################### - - -Description -+++++++++++ - -This model is used to test if broken CoCos are identified correctly. Here, if the output is not defined. Based on the ``iaf_psc_exp`` model at Sep 2020. - -Positive case. - - -Copyright statement -+++++++++++++++++++ - -This file is part of NEST. - -Copyright (C) 2004 The NEST Initiative - -NEST is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -NEST is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with NEST. If not, see . -""" +# CoCoOutputPortDefinedIfEmitCall.nestml +# ###################################### +# +# +# Description +# +++++++++++ +# +# This model is used to test if broken CoCos are identified correctly. Here, if the output is not defined. Based on the ``iaf_psc_exp`` model at Sep 2020. +# +# Positive case. +# +# +# Copyright statement +# +++++++++++++++++++ +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . +# model iaf_psc_exp_neuron: output: spike diff --git a/tests/valid/CoCoParameterAssignedOutsideBlock.nestml b/tests/valid/CoCoParameterAssignedOutsideBlock.nestml index 14ce4ae25..b1d72ca88 100644 --- a/tests/valid/CoCoParameterAssignedOutsideBlock.nestml +++ b/tests/valid/CoCoParameterAssignedOutsideBlock.nestml @@ -1,37 +1,36 @@ -""" -CoCoParameterAssignedOutsideBlock.nestml -######################################## - - -Description -+++++++++++ - -This model is used to check if all cocos work correctly by detecting corresponding broken context. Here, if -assignment of values to parameters outside of parameter blocks is detected. - -Positive example. - - -Copyright statement -+++++++++++++++++++ - -This file is part of NEST. - -Copyright (C) 2004 The NEST Initiative - -NEST is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -NEST is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with NEST. If not, see . -""" +# CoCoParameterAssignedOutsideBlock.nestml +# ######################################## +# +# +# Description +# +++++++++++ +# +# This model is used to check if all cocos work correctly by detecting corresponding broken context. Here, if +# assignment of values to parameters outside of parameter blocks is detected. +# +# Positive example. +# +# +# Copyright statement +# +++++++++++++++++++ +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . +# model CoCoParameterAssignedOutsideBlock: parameters: # parameter is not assigned outside the block, thus everything is correct test mV = 10mV diff --git a/tests/valid/CoCoPrioritiesCorrectlySpecified.nestml b/tests/valid/CoCoPrioritiesCorrectlySpecified.nestml index d9075a56a..51004cd2f 100644 --- a/tests/valid/CoCoPrioritiesCorrectlySpecified.nestml +++ b/tests/valid/CoCoPrioritiesCorrectlySpecified.nestml @@ -1,34 +1,33 @@ -""" -CoCoPrioritiesCorrectlySpecified.nestml -####################################### - - -Description -+++++++++++ - -This model is used to test the sequencing of event handlers in synapse models. - - -Copyright statement -+++++++++++++++++++ - -This file is part of NEST. - -Copyright (C) 2004 The NEST Initiative - -NEST is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -NEST is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with NEST. If not, see . -""" +# CoCoPrioritiesCorrectlySpecified.nestml +# ####################################### +# +# +# Description +# +++++++++++ +# +# This model is used to test the sequencing of event handlers in synapse models. +# +# +# Copyright statement +# +++++++++++++++++++ +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . +# model priorities_correctly_specified_synapse: input: pre_spikes <- spike diff --git a/tests/valid/CoCoResolutionLegallyUsed.nestml b/tests/valid/CoCoResolutionLegallyUsed.nestml index 9be89fe2d..7938a7436 100644 --- a/tests/valid/CoCoResolutionLegallyUsed.nestml +++ b/tests/valid/CoCoResolutionLegallyUsed.nestml @@ -1,34 +1,33 @@ -""" -CoCoResolutionLegallyUsed.nestml -################################ - - -Description -+++++++++++ - -This model is used to test the use of the predefined ``resolution()`` function. - - -Copyright statement -+++++++++++++++++++ - -This file is part of NEST. - -Copyright (C) 2004 The NEST Initiative - -NEST is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -NEST is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with NEST. If not, see . -""" +# CoCoResolutionLegallyUsed.nestml +# ################################ +# +# +# Description +# +++++++++++ +# +# This model is used to test the use of the predefined ``resolution()`` function. +# +# +# Copyright statement +# +++++++++++++++++++ +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . +# model resolution_legally_used_synapse: parameters: d ms = 1 ms diff --git a/tests/valid/CoCoSpikeInputPortWithoutType.nestml b/tests/valid/CoCoSpikeInputPortWithoutType.nestml index 06a4967c9..dc3df614c 100644 --- a/tests/valid/CoCoSpikeInputPortWithoutType.nestml +++ b/tests/valid/CoCoSpikeInputPortWithoutType.nestml @@ -1,36 +1,35 @@ -""" -CoCoSpikeInputPortWithoutType.nestml -#################################### - - -Description -+++++++++++ - -This model is used to test if broken CoCos are identified correctly. Here, if spike input ports without a data-type are detected. - -Positive case. - - -Copyright statement -+++++++++++++++++++ - -This file is part of NEST. - -Copyright (C) 2004 The NEST Initiative - -NEST is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -NEST is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with NEST. If not, see . -""" +# CoCoSpikeInputPortWithoutType.nestml +# #################################### +# +# +# Description +# +++++++++++ +# +# This model is used to test if broken CoCos are identified correctly. Here, if spike input ports without a data-type are detected. +# +# Positive case. +# +# +# Copyright statement +# +++++++++++++++++++ +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . +# model CoCoSpikeInputPortWithoutType: input: # port is provided with a type, thus everything is correct spikeAll <- spike diff --git a/tests/valid/CoCoStateVariablesInitialized.nestml b/tests/valid/CoCoStateVariablesInitialized.nestml index a88b2035e..817deacbf 100644 --- a/tests/valid/CoCoStateVariablesInitialized.nestml +++ b/tests/valid/CoCoStateVariablesInitialized.nestml @@ -1,35 +1,34 @@ -""" -CoCoStateVariablesInitialized.nestml -#################################### - -Description -+++++++++++ - -This model is used to test if broken CoCos are identified correctly. Here, if initial values are provided for all state variables declared in the ``state`` block. - -Positive case. - - -Copyright statement -+++++++++++++++++++ - -This file is part of NEST. - -Copyright (C) 2004 The NEST Initiative - -NEST is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -NEST is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with NEST. If not, see . -""" +# CoCoStateVariablesInitialized.nestml +# #################################### +# +# Description +# +++++++++++ +# +# This model is used to test if broken CoCos are identified correctly. Here, if initial values are provided for all state variables declared in the ``state`` block. +# +# Positive case. +# +# +# Copyright statement +# +++++++++++++++++++ +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . +# model CoCoStateVariablesInitialized: state: V_m mV = 10 mV diff --git a/tests/valid/CoCoUnitNumeratorNotOne.nestml b/tests/valid/CoCoUnitNumeratorNotOne.nestml index a715948f8..750ff66fb 100644 --- a/tests/valid/CoCoUnitNumeratorNotOne.nestml +++ b/tests/valid/CoCoUnitNumeratorNotOne.nestml @@ -1,37 +1,36 @@ -""" -CoCoUnitNumeratorNotOne.nestml -############################## - - -Description -+++++++++++ - -This model is used to check if all cocos work correctly by detecting corresponding broken context. Here, if the -incorrect numerator of the unit is detected. - -Positive case. - - -Copyright statement -+++++++++++++++++++ - -This file is part of NEST. - -Copyright (C) 2004 The NEST Initiative - -NEST is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -NEST is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with NEST. If not, see . -""" +# CoCoUnitNumeratorNotOne.nestml +# ############################## +# +# +# Description +# +++++++++++ +# +# This model is used to check if all cocos work correctly by detecting corresponding broken context. Here, if the +# incorrect numerator of the unit is detected. +# +# Positive case. +# +# +# Copyright statement +# +++++++++++++++++++ +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . +# model CoCoUnitNumeratorNotOne: state: test1 1/s = 10/s # the numerator is correctly stated as 1, thus everything correct diff --git a/tests/valid/CoCoValueAssignedToInputPort.nestml b/tests/valid/CoCoValueAssignedToInputPort.nestml index 9a76bebd2..92d23869d 100644 --- a/tests/valid/CoCoValueAssignedToInputPort.nestml +++ b/tests/valid/CoCoValueAssignedToInputPort.nestml @@ -1,36 +1,35 @@ -""" -CoCoValueAssignedToInputPort.nestml -################################### - - -Description -+++++++++++ - -This model is used to test if broken CoCos are identified correctly. Here, if assignment of values to input ports is detected. - -Positive case. - - -Copyright statement -+++++++++++++++++++ - -This file is part of NEST. - -Copyright (C) 2004 The NEST Initiative - -NEST is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -NEST is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with NEST. If not, see . -""" +# CoCoValueAssignedToInputPort.nestml +# ################################### +# +# +# Description +# +++++++++++ +# +# This model is used to test if broken CoCos are identified correctly. Here, if assignment of values to input ports is detected. +# +# Positive case. +# +# +# Copyright statement +# +++++++++++++++++++ +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . +# model CoCoValueAssignedToInputPort: input: spikeInh <- inhibitory spike diff --git a/tests/valid/CoCoVariableDefinedAfterUsage.nestml b/tests/valid/CoCoVariableDefinedAfterUsage.nestml index 00e40acdd..95eb5ad4f 100644 --- a/tests/valid/CoCoVariableDefinedAfterUsage.nestml +++ b/tests/valid/CoCoVariableDefinedAfterUsage.nestml @@ -1,36 +1,35 @@ -""" -CoCoVariableDefinedAfterUsage.nestml -#################################### - - -Description -+++++++++++ - -This model is used to test if broken CoCos are identified correctly. Here, if usage before declaration is detected. - -Positive case. - - -Copyright statement -+++++++++++++++++++ - -This file is part of NEST. - -Copyright (C) 2004 The NEST Initiative - -NEST is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -NEST is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with NEST. If not, see . -""" +# CoCoVariableDefinedAfterUsage.nestml +# #################################### +# +# +# Description +# +++++++++++ +# +# This model is used to test if broken CoCos are identified correctly. Here, if usage before declaration is detected. +# +# Positive case. +# +# +# Copyright statement +# +++++++++++++++++++ +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . +# model CoCoVariableDefinedAfterUsage: state: test2 integer = 10 diff --git a/tests/valid/CoCoVariableNotDefined.nestml b/tests/valid/CoCoVariableNotDefined.nestml index f24dc5011..499ee94ac 100644 --- a/tests/valid/CoCoVariableNotDefined.nestml +++ b/tests/valid/CoCoVariableNotDefined.nestml @@ -1,36 +1,35 @@ -""" -CoCoVariableNotDefined.nestml -############################# - - -Description -+++++++++++ - -This model is used to test if broken CoCos are identified correctly. Here, if not defined variables are detected. - -Positive case. - - -Copyright statement -+++++++++++++++++++ - -This file is part of NEST. - -Copyright (C) 2004 The NEST Initiative - -NEST is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -NEST is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with NEST. If not, see . -""" +# CoCoVariableNotDefined.nestml +# ############################# +# +# +# Description +# +++++++++++ +# +# This model is used to test if broken CoCos are identified correctly. Here, if not defined variables are detected. +# +# Positive case. +# +# +# Copyright statement +# +++++++++++++++++++ +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . +# model CoCoVariableNotDefined: state: test1 integer = 0 diff --git a/tests/valid/CoCoVariableRedeclared.nestml b/tests/valid/CoCoVariableRedeclared.nestml index 98a47d610..23976be08 100644 --- a/tests/valid/CoCoVariableRedeclared.nestml +++ b/tests/valid/CoCoVariableRedeclared.nestml @@ -1,36 +1,35 @@ -""" -CoCoVariableRedeclared.nestml -############################# - - -Description -+++++++++++ - -This test is used to test the functionality of the coco which ensures that redeclaration of symbols is detected - -Positive case. - - -Copyright statement -+++++++++++++++++++ - -This file is part of NEST. - -Copyright (C) 2004 The NEST Initiative - -NEST is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -NEST is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with NEST. If not, see . -""" +# CoCoVariableRedeclared.nestml +# ############################# +# +# +# Description +# +++++++++++ +# +# This test is used to test the functionality of the coco which ensures that redeclaration of symbols is detected +# +# Positive case. +# +# +# Copyright statement +# +++++++++++++++++++ +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . +# model CoCoVariableRedeclared: state: test1 mV = 20mV diff --git a/tests/valid/CoCoVariableRedeclaredInSameScope.nestml b/tests/valid/CoCoVariableRedeclaredInSameScope.nestml index e89668c0e..a96f277b9 100644 --- a/tests/valid/CoCoVariableRedeclaredInSameScope.nestml +++ b/tests/valid/CoCoVariableRedeclaredInSameScope.nestml @@ -1,37 +1,36 @@ -""" -CoCoVariableRedeclaredInSameScope.nestml -######################################## - - -Description -+++++++++++ - -This model is used to check if all cocos work correctly by detecting corresponding broken context. Here, if -a variable has been redeclared in a single scope. - -Positive case. - - -Copyright statement -+++++++++++++++++++ - -This file is part of NEST. - -Copyright (C) 2004 The NEST Initiative - -NEST is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -NEST is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with NEST. If not, see . -""" +# CoCoVariableRedeclaredInSameScope.nestml +# ######################################## +# +# +# Description +# +++++++++++ +# +# This model is used to check if all cocos work correctly by detecting corresponding broken context. Here, if +# a variable has been redeclared in a single scope. +# +# Positive case. +# +# +# Copyright statement +# +++++++++++++++++++ +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . +# model CoCoVariableRedeclaredInSameScope: state: test1 integer = 10 diff --git a/tests/valid/CoCoVariableWithSameNameAsUnit.nestml b/tests/valid/CoCoVariableWithSameNameAsUnit.nestml index 61bd8d2d0..6d580979e 100644 --- a/tests/valid/CoCoVariableWithSameNameAsUnit.nestml +++ b/tests/valid/CoCoVariableWithSameNameAsUnit.nestml @@ -1,36 +1,35 @@ -""" -CoCoVariableRedeclared.nestml -############################# - - -Description -+++++++++++ - -This model is used to test if broken CoCos are identified correctly. Here, if redeclaration of symbols is detected. - -Negative case. - - -Copyright statement -+++++++++++++++++++ - -This file is part of NEST. - -Copyright (C) 2004 The NEST Initiative - -NEST is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -NEST is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with NEST. If not, see . -""" +# CoCoVariableRedeclared.nestml +# ############################# +# +# +# Description +# +++++++++++ +# +# This model is used to test if broken CoCos are identified correctly. Here, if redeclaration of symbols is detected. +# +# Negative case. +# +# +# Copyright statement +# +++++++++++++++++++ +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . +# model CoCoVariableWithSameNameAsUnit: state: eV mV = 1 mV # should not conflict with predefined unit eV but throw a warning diff --git a/tests/valid/CoCoVectorDeclarationSize.nestml b/tests/valid/CoCoVectorDeclarationSize.nestml index 9e58fd08b..1f73f378f 100644 --- a/tests/valid/CoCoVectorDeclarationSize.nestml +++ b/tests/valid/CoCoVectorDeclarationSize.nestml @@ -1,38 +1,36 @@ -""" -CoCoVectorParameterSize.nestml -############################## - - -Description -+++++++++++ - -This model is used to test if broken CoCos are identified correctly. -Here, if the vector parameter or the size of the vector is greater than 0. - -Positive case. - - -Copyright statement -+++++++++++++++++++ - -This file is part of NEST. - -Copyright (C) 2004 The NEST Initiative - -NEST is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -NEST is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with NEST. If not, see . -""" - +# CoCoVectorParameterSize.nestml +# ############################## +# +# +# Description +# +++++++++++ +# +# This model is used to test if broken CoCos are identified correctly. +# Here, if the vector parameter or the size of the vector is greater than 0. +# +# Positive case. +# +# +# Copyright statement +# +++++++++++++++++++ +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . +# model CoCoVectorParameterSize: state: V_m [10] mV = -10. mV diff --git a/tests/valid/CoCoVectorInNonVectorDeclaration.nestml b/tests/valid/CoCoVectorInNonVectorDeclaration.nestml index 77d9babd9..66781157a 100644 --- a/tests/valid/CoCoVectorInNonVectorDeclaration.nestml +++ b/tests/valid/CoCoVectorInNonVectorDeclaration.nestml @@ -1,37 +1,36 @@ -""" -CoCoVectorInNonVectorDeclaration.nestml -####################################### - - -Description -+++++++++++ - -This model is used to test if broken CoCos are identified correctly. Here, if vectors in non-vector declaration -are detected. - -Positive case. - - -Copyright statement -+++++++++++++++++++ - -This file is part of NEST. - -Copyright (C) 2004 The NEST Initiative - -NEST is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -NEST is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with NEST. If not, see . -""" +# CoCoVectorInNonVectorDeclaration.nestml +# ####################################### +# +# +# Description +# +++++++++++ +# +# This model is used to test if broken CoCos are identified correctly. Here, if vectors in non-vector declaration +# are detected. +# +# Positive case. +# +# +# Copyright statement +# +++++++++++++++++++ +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . +# model CoCoVectorInNonVectorDeclaration: state: g_ex [ten] mV = 10mV diff --git a/tests/valid/CoCoVectorInputPortSizeAndType.nestml b/tests/valid/CoCoVectorInputPortSizeAndType.nestml index aa230ad49..bf0f5fa37 100644 --- a/tests/valid/CoCoVectorInputPortSizeAndType.nestml +++ b/tests/valid/CoCoVectorInputPortSizeAndType.nestml @@ -1,37 +1,36 @@ -""" -CoCoVectorInputPortSizeAndType.nestml -##################################### - - -Description -+++++++++++ - -This model is used to test if broken CoCos are identified correctly. -Here, if the size parameter in the input port is of the type integer and is greater than 0. - -Positive case. - - -Copyright statement -+++++++++++++++++++ - -This file is part of NEST. - -Copyright (C) 2004 The NEST Initiative - -NEST is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -NEST is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with NEST. If not, see . -""" +# CoCoVectorInputPortSizeAndType.nestml +# ##################################### +# +# +# Description +# +++++++++++ +# +# This model is used to test if broken CoCos are identified correctly. +# Here, if the size parameter in the input port is of the type integer and is greater than 0. +# +# Positive case. +# +# +# Copyright statement +# +++++++++++++++++++ +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . +# model CoCoVectorInputPortSizeAndType: input: foo[2] <- spike diff --git a/tests/valid/CoCoVectorParameterDeclaration.nestml b/tests/valid/CoCoVectorParameterDeclaration.nestml index 4f37279c2..4e57f1ada 100644 --- a/tests/valid/CoCoVectorParameterDeclaration.nestml +++ b/tests/valid/CoCoVectorParameterDeclaration.nestml @@ -1,38 +1,37 @@ -""" -CoCoVectorParameterDeclaration.nestml -##################################### - - -Description -+++++++++++ - -This model is used to test if broken CoCos are identified correctly. -Here, if the vector parameter is declared in the correct block. - -Positive case. - - -Copyright statement -+++++++++++++++++++ - -This file is part of NEST. - -Copyright (C) 2004 The NEST Initiative - -NEST is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -NEST is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with NEST. If not, see . -""" - +# CoCoVectorParameterDeclaration.nestml +# ##################################### +# +# +# Description +# +++++++++++ +# +# This model is used to test if broken CoCos are identified correctly. +# Here, if the vector parameter is declared in the correct block. +# +# Positive case. +# +# +# Copyright statement +# +++++++++++++++++++ +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . + +# model CoCoVectorParameterDeclaration: state: v_m [size] mV = -55 mV diff --git a/tests/valid/CoCoVectorParameterType.nestml b/tests/valid/CoCoVectorParameterType.nestml index c1bb940d9..6d064a4c2 100644 --- a/tests/valid/CoCoVectorParameterType.nestml +++ b/tests/valid/CoCoVectorParameterType.nestml @@ -1,38 +1,37 @@ -""" -CoCoVectorParameterType.nestml -############################## - - -Description -+++++++++++ - -This model is used to test if broken CoCos are identified correctly. -Here, if the vector parameter is of the type integer. - -Positive case. - - -Copyright statement -+++++++++++++++++++ - -This file is part of NEST. - -Copyright (C) 2004 The NEST Initiative - -NEST is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -NEST is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with NEST. If not, see . -""" - +# CoCoVectorParameterType.nestml +# ############################## +# +# +# Description +# +++++++++++ +# +# This model is used to test if broken CoCos are identified correctly. +# Here, if the vector parameter is of the type integer. +# +# Positive case. +# +# +# Copyright statement +# +++++++++++++++++++ +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . + +# model CoCoVectorParameterDeclaration: state: v_m [size] mV = -55 mV diff --git a/tests/valid/CompoundOperatorWithDifferentButCompatibleUnits.nestml b/tests/valid/CompoundOperatorWithDifferentButCompatibleUnits.nestml index 077f1df62..c2f74603a 100644 --- a/tests/valid/CompoundOperatorWithDifferentButCompatibleUnits.nestml +++ b/tests/valid/CompoundOperatorWithDifferentButCompatibleUnits.nestml @@ -1,28 +1,27 @@ -""" -CompoundOperatorWithDifferentButCompatibleUnits.nestml -######################################################## - - -Copyright statement -+++++++++++++++++++ - -This file is part of NEST. - -Copyright (C) 2004 The NEST Initiative - -NEST is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -NEST is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with NEST. If not, see . -""" +# CompoundOperatorWithDifferentButCompatibleUnits.nestml +# ######################################################## +# +# +# Copyright statement +# +++++++++++++++++++ +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . +# model CompoundOperatorTest: state: lhs V = 1 V diff --git a/tests/valid/DocstringCommentTest.nestml b/tests/valid/DocstringCommentTest.nestml index aa23ffcc9..aab11cd65 100644 --- a/tests/valid/DocstringCommentTest.nestml +++ b/tests/valid/DocstringCommentTest.nestml @@ -1,36 +1,35 @@ -""" -DocstringCommentTest.nestml -########################### - - -Description -+++++++++++ - -This model is used to test whether docstring comments are detected at any place other than just before the model keyword. - -Positive case. - - -Copyright statement -+++++++++++++++++++ - -This file is part of NEST. - -Copyright (C) 2004 The NEST Initiative - -NEST is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -NEST is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with NEST. If not, see . -""" +# DocstringCommentTest.nestml +# ########################### +# +# +# Description +# +++++++++++ +# +# This model is used to test whether docstring comments are detected. +# +# Positive case. +# +# +# Copyright statement +# +++++++++++++++++++ +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . +# model docstringCommentTest: state: # foo From ef8a819e1830c447dbe5f35ed8e1da165e888354 Mon Sep 17 00:00:00 2001 From: "C.A.P. Linssen" Date: Wed, 19 Feb 2025 03:12:26 -0800 Subject: [PATCH 25/25] add include statement --- .../IncludeStatementRefractory.nestml | 60 +++++++++---------- .../resources/IncludeStatementTest.nestml | 60 +++++++++---------- .../resources/IncludeStatementTest2.nestml | 60 +++++++++---------- .../resources/IncludeStatementTest3.nestml | 60 +++++++++---------- .../resources/IncludeStatementTest4.nestml | 60 +++++++++---------- .../resources/IncludeStatementTest5.nestml | 60 +++++++++---------- .../resources/IncludeStatementTest6.nestml | 60 +++++++++---------- tests/test_cocos.py | 18 +++--- tests/test_function_parameter_templating.py | 2 +- 9 files changed, 213 insertions(+), 227 deletions(-) diff --git a/tests/nest_tests/resources/IncludeStatementRefractory.nestml b/tests/nest_tests/resources/IncludeStatementRefractory.nestml index 24b1b6432..acd66d835 100644 --- a/tests/nest_tests/resources/IncludeStatementRefractory.nestml +++ b/tests/nest_tests/resources/IncludeStatementRefractory.nestml @@ -1,33 +1,31 @@ -""" -IncludeStatementRefractory.nestml -################################# - - -Description -+++++++++++ - -Test whether the include statement works as intended. - -Copyright statement -+++++++++++++++++++ - -This file is part of NEST. - -Copyright (C) 2004 The NEST Initiative - -NEST is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -NEST is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with NEST. If not, see . -""" - +# IncludeStatementRefractory.nestml +# ################################# +# +# +# Description +# +++++++++++ +# +# Test whether the include statement works as intended. +# +# Copyright statement +# +++++++++++++++++++ +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . +# model include_statement_refractory: include "includes/include_refractory_mechanism.nestml" diff --git a/tests/nest_tests/resources/IncludeStatementTest.nestml b/tests/nest_tests/resources/IncludeStatementTest.nestml index f0e8e001c..38679c620 100644 --- a/tests/nest_tests/resources/IncludeStatementTest.nestml +++ b/tests/nest_tests/resources/IncludeStatementTest.nestml @@ -1,34 +1,32 @@ -""" -IncludeStatementTest.nestml -########################### - - -Description -+++++++++++ - -Test whether the include statement works as intended. - -Copyright statement -+++++++++++++++++++ - -This file is part of NEST. - -Copyright (C) 2004 The NEST Initiative - -NEST is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -NEST is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with NEST. If not, see . -""" - +# IncludeStatementTest.nestml +# ########################### +# +# +# Description +# +++++++++++ +# +# Test whether the include statement works as intended. +# +# Copyright statement +# +++++++++++++++++++ +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . +# model include_statement: state: diff --git a/tests/nest_tests/resources/IncludeStatementTest2.nestml b/tests/nest_tests/resources/IncludeStatementTest2.nestml index ef12d68a2..883da0915 100644 --- a/tests/nest_tests/resources/IncludeStatementTest2.nestml +++ b/tests/nest_tests/resources/IncludeStatementTest2.nestml @@ -1,34 +1,32 @@ -""" -IncludeStatementTest.nestml -########################### - - -Description -+++++++++++ - -Test whether the include statement works as intended. - -Copyright statement -+++++++++++++++++++ - -This file is part of NEST. - -Copyright (C) 2004 The NEST Initiative - -NEST is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -NEST is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with NEST. If not, see . -""" - +# IncludeStatementTest2.nestml +# ############################ +# +# +# Description +# +++++++++++ +# +# Test whether the include statement works as intended. +# +# Copyright statement +# +++++++++++++++++++ +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . +# model include_statement2: state: diff --git a/tests/nest_tests/resources/IncludeStatementTest3.nestml b/tests/nest_tests/resources/IncludeStatementTest3.nestml index 4031387fb..fda85cbe6 100644 --- a/tests/nest_tests/resources/IncludeStatementTest3.nestml +++ b/tests/nest_tests/resources/IncludeStatementTest3.nestml @@ -1,34 +1,32 @@ -""" -IncludeStatementTest.nestml -########################### - - -Description -+++++++++++ - -Test whether the include statement works as intended. - -Copyright statement -+++++++++++++++++++ - -This file is part of NEST. - -Copyright (C) 2004 The NEST Initiative - -NEST is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -NEST is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with NEST. If not, see . -""" - +# IncludeStatementTest3.nestml +# ############################ +# +# +# Description +# +++++++++++ +# +# Test whether the include statement works as intended. +# +# Copyright statement +# +++++++++++++++++++ +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . +# model include_statement3: state: diff --git a/tests/nest_tests/resources/IncludeStatementTest4.nestml b/tests/nest_tests/resources/IncludeStatementTest4.nestml index bd33bcea9..ae68e6794 100644 --- a/tests/nest_tests/resources/IncludeStatementTest4.nestml +++ b/tests/nest_tests/resources/IncludeStatementTest4.nestml @@ -1,34 +1,32 @@ -""" -IncludeStatementTest4.nestml -########################### - - -Description -+++++++++++ - -Test whether the include statement works as intended. - -Copyright statement -+++++++++++++++++++ - -This file is part of NEST. - -Copyright (C) 2004 The NEST Initiative - -NEST is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -NEST is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with NEST. If not, see . -""" - +# IncludeStatementTest4.nestml +# ############################ +# +# +# Description +# +++++++++++ +# +# Test whether the include statement works as intended. +# +# Copyright statement +# +++++++++++++++++++ +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . +# model include_statement4: state: diff --git a/tests/nest_tests/resources/IncludeStatementTest5.nestml b/tests/nest_tests/resources/IncludeStatementTest5.nestml index 60dd23ec7..3963e7d3d 100644 --- a/tests/nest_tests/resources/IncludeStatementTest5.nestml +++ b/tests/nest_tests/resources/IncludeStatementTest5.nestml @@ -1,34 +1,32 @@ -""" -IncludeStatementTest5.nestml -########################### - - -Description -+++++++++++ - -Test whether the include statement works as intended. - -Copyright statement -+++++++++++++++++++ - -This file is part of NEST. - -Copyright (C) 2004 The NEST Initiative - -NEST is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -NEST is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with NEST. If not, see . -""" - +# IncludeStatementTest5.nestml +# ############################ +# +# +# Description +# +++++++++++ +# +# Test whether the include statement works as intended. +# +# Copyright statement +# +++++++++++++++++++ +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . +# model include_statement5: include "includes/include_statement_model_test_state_block.nestml" include "includes/include_statement_model_test_parameters_block.nestml" diff --git a/tests/nest_tests/resources/IncludeStatementTest6.nestml b/tests/nest_tests/resources/IncludeStatementTest6.nestml index 92236a197..7c41af0fd 100644 --- a/tests/nest_tests/resources/IncludeStatementTest6.nestml +++ b/tests/nest_tests/resources/IncludeStatementTest6.nestml @@ -1,34 +1,32 @@ -""" -IncludeStatementTest6.nestml -########################### - - -Description -+++++++++++ - -Test whether the include statement works as intended. - -Copyright statement -+++++++++++++++++++ - -This file is part of NEST. - -Copyright (C) 2004 The NEST Initiative - -NEST is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -NEST is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with NEST. If not, see . -""" - +# IncludeStatementTest6.nestml +# ############################ +# +# +# Description +# +++++++++++ +# +# Test whether the include statement works as intended. +# +# Copyright statement +# +++++++++++++++++++ +# +# This file is part of NEST. +# +# Copyright (C) 2004 The NEST Initiative +# +# NEST is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# NEST is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NEST. If not, see . +# model include_statement6: include "includes/include_statement_model_oncondition_block.nestml" include "includes/include_statement_model_onreceive_block.nestml" diff --git a/tests/test_cocos.py b/tests/test_cocos.py index 9cfa1a417..e02005a19 100644 --- a/tests/test_cocos.py +++ b/tests/test_cocos.py @@ -78,7 +78,7 @@ def test_valid_integrate_odes_called_if_equations_defined(self): def test_invalid_element_not_defined_in_scope(self): model = self._parse_and_validate_model(os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'invalid')), 'CoCoVariableNotDefined.nestml')) - assert len(Logger.get_all_messages_of_level_and_or_node(model, LoggingLevel.ERROR)) == 7 + assert len(Logger.get_all_messages_of_level_and_or_node(model, LoggingLevel.ERROR)) == 3 def test_valid_element_not_defined_in_scope(self): model = self._parse_and_validate_model(os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'valid')), 'CoCoVariableNotDefined.nestml')) @@ -107,7 +107,7 @@ def test_valid_each_block_unique(self): def test_invalid_function_unique_and_defined(self): model = self._parse_and_validate_model(os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'invalid')), 'CoCoFunctionNotUnique.nestml')) - assert len(Logger.get_all_messages_of_level_and_or_node(model, LoggingLevel.ERROR)) == 12 + assert len(Logger.get_all_messages_of_level_and_or_node(model, LoggingLevel.ERROR)) == 4 def test_valid_function_unique_and_defined(self): model = self._parse_and_validate_model(os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'valid')), 'CoCoFunctionNotUnique.nestml')) @@ -147,7 +147,7 @@ def test_valid_order_of_equations_correct(self): def test_invalid_numerator_of_unit_one(self): model = self._parse_and_validate_model(os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'invalid')), 'CoCoUnitNumeratorNotOne.nestml')) - assert len(Logger.get_all_messages_of_level_and_or_node(model, LoggingLevel.ERROR)) == 3 + assert len(Logger.get_all_messages_of_level_and_or_node(model, LoggingLevel.ERROR)) == 1 def test_valid_numerator_of_unit_one(self): model = self._parse_and_validate_model(os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'valid')), 'CoCoUnitNumeratorNotOne.nestml')) @@ -199,7 +199,7 @@ def test_valid_internals_assigned_only_in_internals_block(self): def test_invalid_function_with_wrong_arg_number_detected(self): model = self._parse_and_validate_model(os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'invalid')), 'CoCoFunctionCallNotConsistentWrongArgNumber.nestml')) - assert len(Logger.get_all_messages_of_level_and_or_node(model, LoggingLevel.ERROR)) == 3 + assert len(Logger.get_all_messages_of_level_and_or_node(model, LoggingLevel.ERROR)) == 1 def test_valid_function_with_wrong_arg_number_detected(self): model = self._parse_and_validate_model(os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'valid')), 'CoCoFunctionCallNotConsistentWrongArgNumber.nestml')) @@ -215,7 +215,7 @@ def test_valid_init_values_have_rhs_and_ode(self): def test_invalid_incorrect_return_stmt_detected(self): model = self._parse_and_validate_model(os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'invalid')), 'CoCoIncorrectReturnStatement.nestml')) - assert len(Logger.get_all_messages_of_level_and_or_node(model, LoggingLevel.ERROR)) == 12 + assert len(Logger.get_all_messages_of_level_and_or_node(model, LoggingLevel.ERROR)) == 4 def test_valid_incorrect_return_stmt_detected(self): model = self._parse_and_validate_model(os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'valid')), 'CoCoIncorrectReturnStatement.nestml')) @@ -231,7 +231,7 @@ def test_valid_ode_vars_outside_init_block_detected(self): def test_invalid_convolve_correctly_defined(self): model = self._parse_and_validate_model(os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'invalid')), 'CoCoConvolveNotCorrectlyProvided.nestml')) - assert len(Logger.get_all_messages_of_level_and_or_node(model, LoggingLevel.ERROR)) == 3 + assert len(Logger.get_all_messages_of_level_and_or_node(model, LoggingLevel.ERROR)) == 1 def test_valid_convolve_correctly_defined(self): model = self._parse_and_validate_model(os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'valid')), 'CoCoConvolveNotCorrectlyProvided.nestml')) @@ -271,7 +271,7 @@ def test_valid_vector_parameter_size(self): def test_invalid_convolve_correctly_parameterized(self): model = self._parse_and_validate_model(os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'invalid')), 'CoCoConvolveNotCorrectlyParametrized.nestml')) - assert len(Logger.get_all_messages_of_level_and_or_node(model, LoggingLevel.ERROR)) == 3 + assert len(Logger.get_all_messages_of_level_and_or_node(model, LoggingLevel.ERROR)) == 1 def test_valid_convolve_correctly_parameterized(self): model = self._parse_and_validate_model(os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'valid')), 'CoCoConvolveNotCorrectlyParametrized.nestml')) @@ -287,7 +287,7 @@ def test_valid_invariant_correctly_typed(self): def test_invalid_expression_correctly_typed(self): model = self._parse_and_validate_model(os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'invalid')), 'CoCoIllegalExpression.nestml')) - assert len(Logger.get_all_messages_of_level_and_or_node(model, LoggingLevel.ERROR)) == 3 + assert len(Logger.get_all_messages_of_level_and_or_node(model, LoggingLevel.ERROR)) == 1 def test_valid_expression_correctly_typed(self): model = self._parse_and_validate_model(os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'valid')), 'CoCoIllegalExpression.nestml')) @@ -295,7 +295,7 @@ def test_valid_expression_correctly_typed(self): def test_invalid_compound_expression_correctly_typed(self): model = self._parse_and_validate_model(os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'invalid')), 'CompoundOperatorWithDifferentButCompatibleUnits.nestml')) - assert len(Logger.get_all_messages_of_level_and_or_node(model, LoggingLevel.ERROR)) == 15 + assert len(Logger.get_all_messages_of_level_and_or_node(model, LoggingLevel.ERROR)) == 5 def test_valid_compound_expression_correctly_typed(self): model = self._parse_and_validate_model(os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'valid')), 'CompoundOperatorWithDifferentButCompatibleUnits.nestml')) diff --git a/tests/test_function_parameter_templating.py b/tests/test_function_parameter_templating.py index 090a6e18e..b93e06780 100644 --- a/tests/test_function_parameter_templating.py +++ b/tests/test_function_parameter_templating.py @@ -33,4 +33,4 @@ class TestFunctionParameterTemplating: def test(self): fname = os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), "resources", "FunctionParameterTemplatingTest.nestml"))) generate_target(input_path=fname, target_platform="NONE", logging_level="DEBUG") - assert len(Logger.get_all_messages_of_level_and_or_node("templated_function_parameters_type_test", LoggingLevel.ERROR)) == 8 + assert len(Logger.get_all_messages_of_level_and_or_node("templated_function_parameters_type_test", LoggingLevel.ERROR)) == 5