Skip to content

Commit 213d4dd

Browse files
committed
Use split_from_includes
1 parent 227329c commit 213d4dd

File tree

3 files changed

+115
-26
lines changed

3 files changed

+115
-26
lines changed

src/xinterpreter.cpp

+33-26
Original file line numberDiff line numberDiff line change
@@ -137,9 +137,6 @@ __get_cxx_version ()
137137
{
138138
nl::json kernel_res;
139139

140-
141-
auto input_guard = input_redirection(config.allow_stdin);
142-
143140
// Check for magics
144141
for (auto& pre : preamble_manager.preamble)
145142
{
@@ -151,7 +148,11 @@ __get_cxx_version ()
151148
}
152149
}
153150

151+
// Split code from includes
152+
auto blocks = split_from_includes(code.c_str());
153+
154154
auto errorlevel = 0;
155+
155156
std::string ename;
156157
std::string evalue;
157158
//bool compilation_result = false;
@@ -173,30 +174,36 @@ __get_cxx_version ()
173174

174175
std::string err;
175176

176-
// Attempt normal evaluation
177-
try
178-
{
179-
StreamRedirectRAII R(err);
180-
output_value = Cpp::Evaluate(code.c_str(), &hadError);
181-
}
182-
catch (std::exception& e)
183-
{
184-
errorlevel = 1;
185-
ename = "Standard Exception: ";
186-
evalue = e.what();
187-
}
188-
catch (...)
189-
{
190-
errorlevel = 1;
191-
ename = "Error: ";
192-
}
177+
// Scope guard performing the temporary redirection of input requests.
178+
auto input_guard = input_redirection(config.allow_stdin);
193179

194-
if (hadError)
180+
for (const auto& block : blocks)
195181
{
196-
errorlevel = 1;
197-
ename = "Error: ";
198-
evalue = "Compilation error! " + err;
199-
std::cerr << err;
182+
// Attempt normal evaluation
183+
try
184+
{
185+
StreamRedirectRAII R(err);
186+
output_value = Cpp::Evaluate(block.c_str(), &hadError);
187+
}
188+
catch (std::exception& e)
189+
{
190+
errorlevel = 1;
191+
ename = "Standard Exception: ";
192+
evalue = e.what();
193+
}
194+
catch (...)
195+
{
196+
errorlevel = 1;
197+
ename = "Error: ";
198+
}
199+
200+
if (hadError)
201+
{
202+
errorlevel = 1;
203+
ename = "Error: ";
204+
evalue = "Compilation error! " + err;
205+
std::cerr << err;
206+
}
200207
}
201208

202209
// Flush streams
@@ -238,7 +245,7 @@ __get_cxx_version ()
238245
{
239246
// Publish a mime bundle for the last return value if
240247
// the semicolon was omitted.
241-
if (!config.silent && !hadError && trim(code).back() != ';') {
248+
if (!config.silent && !hadError && trim(blocks.back()).back() != ';') {
242249
nl::json pub_data = mime_repr(output_value);
243250
publish_execution_result(execution_counter, std::move(pub_data), nl::json::object());
244251
}

src/xparser.cpp

+76
Original file line numberDiff line numberDiff line change
@@ -54,4 +54,80 @@ namespace xcpp
5454

5555
return result;
5656
}
57+
58+
std::vector<std::string> get_lines(const std::string& input)
59+
{
60+
std::vector<std::string> lines;
61+
std::regex re("\\n");
62+
63+
std::copy(
64+
std::sregex_token_iterator(input.begin(), input.end(), re, -1),
65+
std::sregex_token_iterator(),
66+
std::back_inserter(lines)
67+
);
68+
return lines;
69+
}
70+
71+
std::vector<std::string> split_from_includes(const std::string& input)
72+
{
73+
// this function split the input into part where we have only #include.
74+
75+
// split input into lines
76+
std::vector<std::string> lines = get_lines(input);
77+
78+
// check if each line contains #include and concatenate the result in the good part of the result
79+
std::regex incl_re("\\#include.*");
80+
std::regex magic_re("^\\%\\w+");
81+
std::vector<std::string> result;
82+
result.push_back("");
83+
std::size_t current = 0; // 0 include, 1 other
84+
std::size_t rindex = 0; // current index of result vector
85+
for (std::size_t i = 0; i < lines.size(); ++i)
86+
{
87+
if (!lines[i].empty())
88+
{
89+
if (std::regex_search(lines[i], magic_re))
90+
{
91+
result.push_back(lines[i] + "\n");
92+
result.push_back("");
93+
rindex += 2;
94+
}
95+
else
96+
{
97+
if (std::regex_match(lines[i], incl_re))
98+
{
99+
// if we have #include in this line
100+
// but the current item of result vector contains
101+
// other things
102+
if (current != 0)
103+
{
104+
current = 0;
105+
result.push_back("");
106+
rindex++;
107+
}
108+
}
109+
else
110+
{
111+
// if we don't have #include in this line
112+
// but the current item of result vector contains
113+
// the include parts
114+
if (current != 1)
115+
{
116+
current = 1;
117+
result.push_back("");
118+
rindex++;
119+
}
120+
}
121+
// if we have multiple lines, we add a semicolon at the end of the lines that not contain
122+
// #include keyword (except for the last line)
123+
result[rindex] += lines[i];
124+
if (i != lines.size() - 1)
125+
{
126+
result[rindex] += "\n";
127+
}
128+
}
129+
}
130+
}
131+
return result;
132+
}
57133
}

src/xparser.hpp

+6
Original file line numberDiff line numberDiff line change
@@ -22,5 +22,11 @@ namespace xcpp
2222

2323
XEUS_CPP_API std::vector<std::string>
2424
split_line(const std::string& input, const std::string& delims, std::size_t cursor_pos);
25+
26+
XEUS_CPP_API
27+
std::vector<std::string> get_lines(const std::string& input);
28+
29+
XEUS_CPP_API
30+
std::vector<std::string> split_from_includes(const std::string& input);
2531
}
2632
#endif

0 commit comments

Comments
 (0)