Skip to content

Commit

Permalink
Merge pull request #376 from SylvainCorlay/support-complete-requests
Browse files Browse the repository at this point in the history
Add support for is_complete requests
  • Loading branch information
SylvainCorlay committed Jan 4, 2021
2 parents 2ba2a25 + df50669 commit 2174787
Show file tree
Hide file tree
Showing 5 changed files with 61 additions and 64 deletions.
8 changes: 3 additions & 5 deletions include/xeus-cling/xinterpreter.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,12 @@
#ifndef XEUS_CLING_INTERPRETER_HPP
#define XEUS_CLING_INTERPRETER_HPP

#include <iostream>
#include <sstream>
#include <streambuf>
#include <string>
#include <vector>

#include "cling/Interpreter/Interpreter.h"
#include "cling/MetaProcessor/MetaProcessor.h"
#include "cling/MetaProcessor/InputValidator.h"

#include "nlohmann/json.hpp"

Expand Down Expand Up @@ -77,8 +75,8 @@ namespace xcpp

std::string get_stdopt(int argc, const char* const* argv);

cling::Interpreter m_cling;
cling::MetaProcessor m_processor;
cling::Interpreter m_interpreter;
cling::InputValidator m_input_validator;
std::string m_version;

xmagics_manager xmagics;
Expand Down
32 changes: 13 additions & 19 deletions src/xinspect.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@

#include "cling/Interpreter/Interpreter.h"
#include "cling/Interpreter/Value.h"
#include "cling/MetaProcessor/MetaProcessor.h"
#include "cling/Utils/Output.h"

#include "pugixml.hpp"
Expand Down Expand Up @@ -84,39 +83,34 @@ namespace xcpp
}
};

std::string find_type(const std::string& expression, cling::MetaProcessor& m_processor)
std::string find_type(const std::string& expression, cling::Interpreter& interpreter)
{
cling::Interpreter::CompilationResult compilation_result;
cling::Value result;
std::string typeString;

// add typeinfo in include files in order to use typeid
std::string code = "#include <typeinfo>";
m_processor.process(code.c_str(), compilation_result, &result);
auto compilation_result = interpreter.process(code.c_str(), &result);

// try to find the typename of the class
code = "typeid(" + expression + ").name();";

// Temporarily dismissing all std::cerr and std::cout resulting from `m_processor.process`
auto errorlevel = 0;
// Temporarily dismissing all std::cerr and std::cout resulting from `interpreter.process`
compilation_result = interpreter.process(code.c_str(), &result);
{
auto cout_strbuf = std::cout.rdbuf();
auto cerr_strbuf = std::cerr.rdbuf();
auto null = xnull();
std::cout.rdbuf(&null);
std::cerr.rdbuf(&null);

errorlevel = m_processor.process(code.c_str(), compilation_result, &result);
compilation_result = interpreter.process(code.c_str(), &result);

std::cout.rdbuf(cout_strbuf);
std::cerr.rdbuf(cerr_strbuf);
}

if (errorlevel)
{
m_processor.cancelContinuation();
}
else if (compilation_result == cling::Interpreter::kSuccess)
if (compilation_result == cling::Interpreter::kSuccess)
{
// we found the typeid
std::string valueString;
Expand Down Expand Up @@ -175,7 +169,7 @@ namespace xcpp
return result;
}

void inspect(const std::string& code, nl::json& kernel_res, cling::MetaProcessor& m_processor)
void inspect(const std::string& code, nl::json& kernel_res, cling::Interpreter& interpreter)
{
std::string tagconf_dir = xtl::prefix_path() + XCPP_TAGCONFS_DIR;
std::string tagfiles_dir = xtl::prefix_path() + XCPP_TAGFILES_DIR;
Expand All @@ -198,7 +192,7 @@ namespace xcpp
// Method or variable of class found (xxxx.yyyy)
if (std::regex_search(to_inspect, method, std::regex(R"((.*)\.(\w*)$)")))
{
std::string typename_ = find_type(method[1], m_processor);
std::string typename_ = find_type(method[1], interpreter);

if (!typename_.empty())
{
Expand Down Expand Up @@ -232,7 +226,7 @@ namespace xcpp
}
else
{
std::string typename_ = find_type(to_inspect, m_processor);
std::string typename_ = find_type(to_inspect, interpreter);
find_string = (typename_.empty()) ? to_inspect : typename_;
}

Expand Down Expand Up @@ -323,8 +317,8 @@ namespace xcpp
using xpreamble::pattern;
const std::string spattern = R"(^\?)";

xintrospection(cling::MetaProcessor& p)
: m_processor{p}
xintrospection(cling::Interpreter& p)
: m_interpreter{p}
{
pattern = spattern;
}
Expand All @@ -334,7 +328,7 @@ namespace xcpp
std::regex re(spattern + R"((.*))");
std::smatch to_inspect;
std::regex_search(code, to_inspect, re);
inspect(to_inspect[1], kernel_res, m_processor);
inspect(to_inspect[1], kernel_res, m_interpreter);
}

virtual xpreamble* clone() const override
Expand All @@ -344,7 +338,7 @@ namespace xcpp

private:

cling::MetaProcessor& m_processor;
cling::Interpreter& m_interpreter;
};
}
#endif
54 changes: 34 additions & 20 deletions src/xinterpreter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,16 +37,15 @@ namespace xcpp
void interpreter::configure_impl()
{
// Process #include "xeus/xinterpreter.hpp" in a separate block.
cling::Interpreter::CompilationResult compilation_result;
m_processor.process("#include \"xeus/xinterpreter.hpp\"", compilation_result, nullptr, true);

m_interpreter.process("#include \"xeus/xinterpreter.hpp\"", nullptr, nullptr, true);
// Expose interpreter instance to cling
std::string block = "xeus::register_interpreter(static_cast<xeus::xinterpreter*>((void*)" + std::to_string(intptr_t(this)) + "));";
m_processor.process(block.c_str(), compilation_result, nullptr, true);
m_interpreter.process(block.c_str(), nullptr, nullptr, true);
}

interpreter::interpreter(int argc, const char* const* argv)
: m_cling(argc, argv, LLVM_DIR), m_processor(m_cling, cling::errs()),
: m_interpreter(argc, argv, LLVM_DIR),
m_input_validator(),
m_version(get_stdopt(argc, argv)), // Extract C++ language standard version from command-line option
xmagics(),
p_cout_strbuf(nullptr), p_cerr_strbuf(nullptr),
Expand Down Expand Up @@ -86,14 +85,14 @@ namespace xcpp
auto blocks = split_from_includes(code.c_str());

auto errorlevel = 0;
auto indent = 0;

std::string ename;
std::string evalue;
cling::Value output;
cling::Interpreter::CompilationResult compilation_result;

// If silent is set to true, temporarily dismiss all std::cerr and
// std::cout outpus resulting from `m_processor.process`.
// std::cout outputs resulting from `m_interpreter.process`.

auto cout_strbuf = std::cout.rdbuf();
auto cerr_strbuf = std::cerr.rdbuf();
Expand All @@ -113,7 +112,7 @@ namespace xcpp
// Attempt normal evaluation
try
{
indent = m_processor.process(block, compilation_result, &output, true);
compilation_result = m_interpreter.process(block, &output, nullptr, true);
}

// Catch all errors
Expand Down Expand Up @@ -147,7 +146,6 @@ namespace xcpp
// If an error was encountered, don't attempt further execution
if (errorlevel)
{
m_processor.cancelContinuation();
break;
}
}
Expand Down Expand Up @@ -215,7 +213,7 @@ namespace xcpp
auto text = split_line(code, delims, _cursor_pos);
std::string to_complete = text.back().c_str();

compilation_result = m_cling.codeComplete(code.c_str(), _cursor_pos, result);
compilation_result = m_interpreter.codeComplete(code.c_str(), _cursor_pos, result);

// change the print result
for (auto& r : result)
Expand Down Expand Up @@ -245,23 +243,39 @@ namespace xcpp
nl::json kernel_res;

auto dummy = code.substr(0, cursor_pos);
// FIX: same pattern as in inspect function (keep only one)
// TODO: same pattern as in inspect function (keep only one)
std::string exp = R"(\w*(?:\:{2}|\<.*\>|\(.*\)|\[.*\])?)";
std::regex re_method{"(" + exp + R"(\.?)*$)"};
std::smatch magic;
if (std::regex_search(dummy, magic, re_method))
{
inspect(magic[0], kernel_res, m_processor);
inspect(magic[0], kernel_res, m_interpreter);
}
return kernel_res;
}

nl::json interpreter::is_complete_request_impl(const std::string& /*code*/)
nl::json interpreter::is_complete_request_impl(const std::string& code)
{
// TODO: use indentation returned from processing the code to determine
// if the code is complete.
nl::json kernel_res;
kernel_res["status"] = "complete";

m_input_validator.reset();
cling::InputValidator::ValidationResult Res = m_input_validator.validate(code);
if (Res == cling::InputValidator::kComplete)
{
kernel_res["status"] = "complete";
}
else if (Res == cling::InputValidator::kIncomplete)
{
kernel_res["status"] = "incomplete";
}
else if (Res == cling::InputValidator::kMismatch)
{
kernel_res["status"] = "invalid";
}
else
{
kernel_res["status"] = "unknown";
}
kernel_res["indent"] = "";
return kernel_res;
}
Expand Down Expand Up @@ -316,7 +330,7 @@ namespace xcpp
// return value is the number of characters _excluding_ the null byte.
std::va_list args_bufsz;
va_copy(args_bufsz, args);
size_t bufsz = vsnprintf(NULL, 0, format, args_bufsz);
std::size_t bufsz = vsnprintf(NULL, 0, format, args_bufsz);
va_end(args_bufsz);

// Create an empty string of that size.
Expand Down Expand Up @@ -411,16 +425,16 @@ namespace xcpp

void interpreter::init_preamble()
{
preamble_manager.register_preamble("introspection", new xintrospection(m_processor));
preamble_manager.register_preamble("introspection", new xintrospection(m_interpreter));
preamble_manager.register_preamble("magics", new xmagics_manager());
preamble_manager.register_preamble("shell", new xsystem());
}

void interpreter::init_magic()
{
preamble_manager["magics"].get_cast<xmagics_manager>().register_magic("executable", executable(m_cling));
preamble_manager["magics"].get_cast<xmagics_manager>().register_magic("executable", executable(m_interpreter));
preamble_manager["magics"].get_cast<xmagics_manager>().register_magic("file", writefile());
preamble_manager["magics"].get_cast<xmagics_manager>().register_magic("timeit", timeit(&m_processor));
preamble_manager["magics"].get_cast<xmagics_manager>().register_magic("timeit", timeit(&m_interpreter));
}

std::string interpreter::get_stdopt(int argc, const char* const* argv)
Expand Down
25 changes: 8 additions & 17 deletions src/xmagics/execution.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,24 +15,22 @@

#include "cling/Interpreter/Value.h"
#include "cling/Interpreter/Exception.h"
#include "cling/MetaProcessor/MetaProcessor.h"
#include "cling/Interpreter/Interpreter.h"
#include "cling/Utils/Output.h"

#include "execution.hpp"
#include "../xparser.hpp"

namespace xcpp
{
timeit::timeit(cling::MetaProcessor* p)
: m_processor(p)
timeit::timeit(cling::Interpreter* p)
: m_interpreter(p)
{
cling::Interpreter::CompilationResult compilation_result;

m_processor->process("#include <chrono>", compilation_result);

compilation_result = m_interpreter->process("#include <chrono>");
std::string init_timeit = "auto _t0 = std::chrono::high_resolution_clock::now();\n";
init_timeit += "auto _t1 = std::chrono::high_resolution_clock::now();\n";
m_processor->process(init_timeit.c_str(), compilation_result);
compilation_result = m_interpreter->process(init_timeit.c_str());
}

xoptions timeit::get_options()
Expand Down Expand Up @@ -111,11 +109,10 @@ namespace xcpp
}

auto errorlevel = 0;
auto indent = 0;
std::string ename;
std::string evalue;
cling::Value output;
cling::Interpreter::CompilationResult compilation_result;
cling::Interpreter::CompilationResult compilation_result = cling::Interpreter::kSuccess;

try
{
Expand All @@ -125,7 +122,7 @@ namespace xcpp
{
number = std::pow(10, n);
std::string timeit_code = inner(number, code);
indent = m_processor->process(timeit_code.c_str(), compilation_result, &output);
compilation_result = m_interpreter->process(timeit_code.c_str(), &output);
if (output.simplisticCastAs<double>() >= 0.2)
{
break;
Expand All @@ -139,7 +136,7 @@ namespace xcpp
for (std::size_t r = 0; r < repeat; ++r)
{
std::string timeit_code = inner(number, code);
indent = m_processor->process(timeit_code.c_str(), compilation_result, &output);
compilation_result = m_interpreter->process(timeit_code.c_str(), &output);
all_runs.push_back(output.simplisticCastAs<double>() / number);
mean += all_runs.back();
}
Expand Down Expand Up @@ -181,11 +178,5 @@ namespace xcpp
errorlevel = 1;
ename = "Interpreter Error";
}

// If an error was encountered, don't attempt further execution
if (errorlevel)
{
m_processor->cancelContinuation();
}
}
}
6 changes: 3 additions & 3 deletions src/xmagics/execution.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
#include <cstddef>
#include <string>

#include "cling/MetaProcessor/MetaProcessor.h"
#include "cling/Interpreter/Interpreter.h"

#include "xeus-cling/xmagics.hpp"
#include "xeus-cling/xoptions.hpp"
Expand All @@ -24,7 +24,7 @@ namespace xcpp
{
public:

timeit(cling::MetaProcessor* p);
timeit(cling::Interpreter* p);

virtual void operator()(const std::string& line) override
{
Expand All @@ -42,7 +42,7 @@ namespace xcpp

private:

cling::MetaProcessor* m_processor;
cling::Interpreter* m_interpreter;

xoptions get_options();
std::string inner(std::size_t number, const std::string& code) const;
Expand Down

0 comments on commit 2174787

Please sign in to comment.