memgraph/include/query_engine/code_generator.hpp

82 lines
2.4 KiB
C++
Raw Normal View History

#pragma once
#include "config/config.hpp"
2016-02-26 06:49:35 +08:00
#include "cypher/ast/ast.hpp"
#include "cypher/compiler.hpp"
2016-08-29 21:51:31 +08:00
#include "logging/default.hpp"
#include "query_engine/exceptions/errors.hpp"
#include "template_engine/engine.hpp"
#include "traverser/cpp_traverser.hpp"
#include "utils/string/file.hpp"
#include "utils/type_discovery.hpp"
using std::string;
template <typename Stream>
class CodeGenerator
{
public:
CodeGenerator() : logger(logging::log->logger("CodeGenerator")) {}
void generate_cpp(const std::string &query, const uint64_t stripped_hash,
const std::string &path)
2016-02-11 06:34:49 +08:00
{
// TODO: optimize; one time initialization -> be careful that object
// has a state
// TODO: multithread test
CppTraverser cpp_traverser;
2016-02-26 06:49:35 +08:00
// get paths
2016-08-30 12:34:08 +08:00
#ifdef BARRIER
string template_path = CONFIG(config::BARRIER_TEMPLATE_CPU_CPP_PATH);
#else
2016-02-11 06:34:49 +08:00
string template_path = CONFIG(config::TEMPLATE_CPU_CPP_PATH);
2016-08-30 12:34:08 +08:00
#endif
2016-02-11 06:34:49 +08:00
string template_file = utils::read_file(template_path.c_str());
2016-02-26 06:49:35 +08:00
2016-07-18 01:32:35 +08:00
// syntax tree generation
try {
tree = compiler.syntax_tree(query);
} catch (const std::runtime_error &e) {
logger.error("Syntax error: {}", query);
throw QueryEngineException(std::string(e.what()));
2016-07-18 01:32:35 +08:00
}
cpp_traverser.reset();
2016-07-18 01:32:35 +08:00
// code generation
try {
tree.root->accept(cpp_traverser);
} catch (const SemanticError &e) {
throw e;
2016-07-18 01:32:35 +08:00
} catch (const std::exception &e) {
logger.error("AST traversal error: {}", std::string(e.what()));
throw QueryEngineException("Unknown code generation error");
2016-07-18 01:32:35 +08:00
}
2016-02-26 06:49:35 +08:00
// save the code
2016-02-11 06:34:49 +08:00
string generated = template_engine.render(
template_file, {{"class_name", "CodeCPU"},
{"stripped_hash", std::to_string(stripped_hash)},
{"query", query},
2016-08-30 12:34:08 +08:00
#ifdef BARRIER
2016-08-31 06:23:12 +08:00
{"stream", "RecordStream<::io::Socket>"},
2016-08-30 12:34:08 +08:00
#else
{"stream", type_name<Stream>().to_string()},
2016-08-30 12:34:08 +08:00
#endif
{"code", cpp_traverser.code}});
2016-07-18 01:32:35 +08:00
logger.debug("generated code: {}", generated);
2016-07-17 08:22:43 +08:00
utils::write_file(generated, path);
}
2016-02-26 06:49:35 +08:00
protected:
Logger logger;
private:
template_engine::TemplateEngine template_engine;
2016-02-26 06:49:35 +08:00
ast::Ast tree;
cypher::Compiler compiler;
};