File: codegen_compatibility_visitor.cpp

package info (click to toggle)
nmodl 0.6-4
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 6,016 kB
  • sloc: cpp: 28,492; javascript: 9,841; yacc: 2,804; python: 1,971; lex: 1,674; xml: 181; sh: 136; ansic: 37; makefile: 17; pascal: 7
file content (168 lines) | stat: -rw-r--r-- 4,921 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
/*************************************************************************
 * Copyright (C) 2023 Blue Brain Project
 *
 * This file is part of NMODL distributed under the terms of the GNU
 * Lesser General Public License. See top-level LICENSE file for details.
 *************************************************************************/

#include <catch2/catch_test_macros.hpp>
#include <catch2/matchers/catch_matchers_string.hpp>

#include "ast/program.hpp"
#include "codegen/codegen_compatibility_visitor.hpp"
#include "parser/nmodl_driver.hpp"
#include "test/unit/utils/test_utils.hpp"
#include "visitors/perf_visitor.hpp"
#include "visitors/symtab_visitor.hpp"

using Catch::Matchers::ContainsSubstring;

using namespace nmodl;
using namespace visitor;
using namespace codegen;

using nmodl::parser::NmodlDriver;

/// Return true if it failed and false otherwise
bool runCompatibilityVisitor(const std::string& nmodl_text) {
    const auto& ast = NmodlDriver().parse_string(nmodl_text);
    SymtabVisitor().visit_program(*ast);
    PerfVisitor().visit_program(*ast);
    return CodegenCompatibilityVisitor().find_unhandled_ast_nodes(*ast);
}

SCENARIO("Uncompatible constructs should failed", "[codegen][compatibility_visitor]") {
    GIVEN("A mod file containing an EXTERNAL construct") {
        std::string const nmodl_text = R"(
            NEURON {
                EXTERNAL apc_metap
            }
        )";

        THEN("should failed") {
            bool failed = runCompatibilityVisitor(nmodl_text);
            REQUIRE(failed);
        }
    }
    GIVEN("A mod file containing a written GLOBAL var") {
        std::string const nmodl_text = R"(
            NEURON {
                GLOBAL foo
            }

            PROCEDURE bar() {
                foo = 1
            }
        )";

        THEN("should failed") {
            bool failed = runCompatibilityVisitor(nmodl_text);
            REQUIRE(failed);
        }
    }
    GIVEN("A mod file containing a written un-writtable var") {
        std::string const nmodl_text = R"(
            PARAMETER {
                foo = 1
            }

            PROCEDURE bar() {
                foo = 1
            }
        )";

        THEN("should failed") {
            bool failed = runCompatibilityVisitor(nmodl_text);
            REQUIRE(failed);
        }
    }
    GIVEN("A mod file with BBCOREPOINTER without bbcore_read / bbcore_write") {
        std::string const nmodl_text = R"(
            NEURON {
                BBCOREPOINTER rng
            }
        )";

        THEN("should failed") {
            bool failed = runCompatibilityVisitor(nmodl_text);
            REQUIRE(failed);
        }
    }
    GIVEN("A mod file with BBCOREPOINTER without bbcore_write") {
        std::string const nmodl_text = R"(
            NEURON {
                BBCOREPOINTER rng
            }

            VERBATIM
            static void bbcore_read(double* x, int* d, int* xx, int* offset, _threadargsproto_) {
            }
            ENDVERBATIM
        )";

        THEN("should failed") {
            bool failed = runCompatibilityVisitor(nmodl_text);
            REQUIRE(failed);
        }
    }
    GIVEN("A mod file with BBCOREPOINTER without bbcore_read") {
        std::string const nmodl_text = R"(
            NEURON {
                BBCOREPOINTER rng
            }

            VERBATIM
            static void bbcore_write(double* x, int* d, int* xx, int* offset, _threadargsproto_) {
            }
            ENDVERBATIM
        )";

        THEN("should failed") {
            bool failed = runCompatibilityVisitor(nmodl_text);
            REQUIRE(failed);
        }
    }
    GIVEN("A mod file with BBCOREPOINTER with bbcore_read / bbcore_write") {
        std::string const nmodl_text = R"(
            NEURON {
                BBCOREPOINTER rng
            }

            VERBATIM
            static void bbcore_read(double* x, int* d, int* xx, int* offset, _threadargsproto_) {
            }
            static void bbcore_write(double* x, int* d, int* xx, int* offset, _threadargsproto_) {
            }
            ENDVERBATIM
        )";

        THEN("should succeed") {
            bool failed = runCompatibilityVisitor(nmodl_text);
            REQUIRE(!failed);
        }
    }
    GIVEN("A mod file with a no SOLVE method") {
        std::string const nmodl_text = R"(
            BREAKPOINT {
                SOLVE state
            }
        )";

        THEN("should succeed") {
            bool failed = runCompatibilityVisitor(nmodl_text);
            REQUIRE(!failed);
        }
    }
    GIVEN("A mod file with a invalid SOLVE method") {
        std::string const nmodl_text = R"(
            BREAKPOINT {
                SOLVE state METHOD runge
            }
        )";

        THEN("should failed") {
            bool failed = runCompatibilityVisitor(nmodl_text);
            REQUIRE(failed);
        }
    }
}