Skip to content

Commit d938480

Browse files
committed
feat: simdjson and python module loader
1 parent cb2c249 commit d938480

File tree

5 files changed

+59
-44
lines changed

5 files changed

+59
-44
lines changed

CMakeLists.txt

+12-1
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,16 @@ endif()
5656
find_package (Python3 COMPONENTS Interpreter Development)
5757
include_directories(${PYTHON_INCLUDE_DIRS})
5858

59+
# CPM Packages
60+
61+
CPMAddPackage(
62+
NAME simdjson
63+
VERSION 3.11.3
64+
GITHUB_REPOSITORY simdjson/simdjson
65+
OPTIONS
66+
"SIMDJSON_BUILD_STATIC_LIB OFF"
67+
)
68+
5969
# Create standalone executable
6070

6171
file(GLOB_RECURSE headers CONFIGURE_DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/${PROJECT_NAME}/*.h")
@@ -70,4 +80,5 @@ target_include_directories(
7080
$<INSTALL_INTERFACE:${PROJECT_NAME}-${PROJECT_VERSION}>
7181
)
7282

73-
target_link_libraries (${PROJECT_NAME} Python3::Python)
83+
target_include_directories(${PROJECT_NAME} PUBLIC simdjson::simdjson Python3::Python)
84+
target_link_libraries(${PROJECT_NAME} PUBLIC simdjson::simdjson Python3::Python)

roxas/main.cc

+1-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
#include <cstdlib>
1818
#include <iostream>
1919
#include <roxas/ast.h>
20-
#include <roxas/parse_tree.h>
20+
#include <roxas/python_module.h>
2121

2222
int main(int argc, const char* argv[])
2323
{

roxas/parse_tree.cc roxas/python_module.cc

+27-24
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,10 @@
1616

1717
#include <filesystem>
1818
#include <fstream>
19-
#include <roxas/parse_tree.h>
19+
#include <roxas/python_module.h>
2020
#include <sstream>
2121
#include <stdexcept>
2222

23-
// https://docs.python.org/3/extending/embedding.html#pure-embedding
2423
#include <Python.h>
2524

2625
namespace roxas {
@@ -45,23 +44,20 @@ std::string read_source_file(fs::path path)
4544
}
4645

4746
/**
48-
* @brief ParseTreeModuleLoader constructor
47+
* @brief PythonModuleLoader constructor
4948
*
50-
* Constructs object that interfaces with a compiler frontend in python
49+
* Constructs object that interfaces with libpython
5150
*
52-
* @param module_path an absolute path to the frontend python module
51+
* @param module_path an absolute path to a python module
5352
* @param module_name the module name as a string
54-
* @param file_path an absolute path to the source file to parse
5553
* @param env_path an optional absolute path to a venv directory where
5654
* dependecies are installed
5755
*/
58-
ParseTreeModuleLoader::ParseTreeModuleLoader(std::string module_path,
59-
std::string module_name,
60-
std::string file_path,
61-
std::string const& env_path)
62-
: module_path_(std::move(module_path))
63-
, module_name_(std::move(module_name))
64-
, file_path_(std::move(file_path))
56+
PythonModuleLoader::PythonModuleLoader(std::string_view module_path,
57+
std::string_view module_name,
58+
std::string const& env_path)
59+
: module_path_(module_path)
60+
, module_name_(module_name)
6561
{
6662
std::ostringstream python_path;
6763
python_path << "sys.path.append(\"" << module_path_ << "\")";
@@ -80,14 +76,15 @@ ParseTreeModuleLoader::ParseTreeModuleLoader(std::string module_path,
8076
/**
8177
* @brief
8278
*
83-
* Call a method on the parser module and provides the result as a
79+
* Call a method on the python module and return the result as a
8480
* string
8581
*
8682
* @param method_name the method name
83+
* @param args initializer list of arguments to pass to the python method
8784
* @return std::string result of method call
8885
*/
89-
std::string ParseTreeModuleLoader::call_method_on_module(
90-
std::string const& method_name)
86+
std::string call_method_on_module(std::string_view method_name,
87+
std::initializer_list<std::string> args);
9188
{
9289
std::string ret{};
9390
PyObject *pModule, *pDict, *pFunc, *vModule;
@@ -127,13 +124,19 @@ std::string ParseTreeModuleLoader::call_method_on_module(
127124

128125
if (PyCallable_Check(pFunc)) {
129126
PyObject *pValue, *pArgs;
130-
pArgs = PyTuple_New(2);
131-
PyTuple_SetItem(
132-
pArgs,
133-
0,
134-
PyUnicode_FromString(read_source_file(file_path_).c_str()));
135-
PyTuple_SetItem(pArgs, 1, Py_True);
136-
127+
int pIndex = 0;
128+
pArgs = PyTuple_New(args.size());
129+
// construct the arguments from the initializer list `args'
130+
for (std::string arg const& : args) {
131+
if (arg == "true") {
132+
PyTuple_SetItem(pArgs, pIndex, Py_True);
133+
} else if (arg == "false") {
134+
PyTuple_SetItem(pArgs, pIndex, Py_False);
135+
} else {
136+
PyTuple_SetItem(pArgs, index, PyUnicode_FromString(arg));
137+
}
138+
index++;
139+
}
137140
pValue = PyObject_CallObject(pFunc, pArgs);
138141
if (pValue != NULL) {
139142
ret = std::string{ PyUnicode_AsUTF8(pValue) };
@@ -159,7 +162,7 @@ std::string ParseTreeModuleLoader::call_method_on_module(
159162
* @brief clean up
160163
*
161164
*/
162-
ParseTreeModuleLoader::~ParseTreeModuleLoader()
165+
PythonModuleLoader::~PythonModuleLoader()
163166
{
164167
Py_Finalize();
165168
}

roxas/parse_tree.h roxas/python_module.h

+18-17
Original file line numberDiff line numberDiff line change
@@ -16,59 +16,60 @@
1616

1717
#pragma once
1818

19+
#include <initializer_list>
1920
#include <string>
21+
#include <string_view>
2022

2123
namespace roxas {
2224

2325
/**
2426
* @brief
2527
*
26-
* Module loader via libpython interface to a compiler frontend (lexer/parser)
27-
* python module
28+
* Module loader via libpython.
2829
*
2930
*/
30-
class ParseTreeModuleLoader
31+
class PythonModuleLoader
3132
{
3233
public:
33-
ParseTreeModuleLoader(ParseTreeModuleLoader const&) = delete;
34+
PythonModuleLoader(PythonModuleLoader const&) = delete;
3435
/**
35-
* @brief ParseTreeModuleLoader constructor
36+
* @brief PythonModuleLoader constructor
3637
*
37-
* Constructs object that interfaces with a compiler frontend in python
38+
* Constructs object that interfaces with libpython
3839
*
39-
* @param module_path an absolute path to the frontend python module
40+
* @param module_path an absolute path to a python module
4041
* @param module_name the module name as a string
4142
* @param file_path an absolute path to the source file to parse
4243
* @param env_path an optional absolute path to a venv directory where
4344
* dependecies are installed
4445
*/
45-
ParseTreeModuleLoader(std::string module_path,
46-
std::string module_name,
47-
std::string file_path,
48-
std::string const& env_path = "");
46+
PythonModuleLoader(std::string_view module_path,
47+
std::string_view module_name,
48+
std::string const& env_path = "");
4949

5050
/**
5151
* @brief clean up
5252
*
5353
*/
54-
~ParseTreeModuleLoader();
54+
~PythonModuleLoader();
5555

5656
public:
5757
/**
5858
* @brief
5959
*
60-
* Call a method on the parser module and provides the result as a
60+
* Call a method on the python module and return the result as a
6161
* string
6262
*
6363
* @param method_name the method name
64+
* @param args initializer list of arguments to pass to the python method
6465
* @return std::string result of method call
6566
*/
66-
std::string call_method_on_module(std::string const& method_name);
67+
std::string call_method_on_module(std::string_view method_name,
68+
std::initializer_list<std::string> args);
6769

6870
private:
69-
std::string module_path_;
70-
std::string module_name_;
71-
std::string file_path_;
71+
std::string_view module_path_;
72+
std::string_view module_name_;
7273
};
7374

7475
} // namespace roxas

0 commit comments

Comments
 (0)