Skip to content

Commit 4b573e4

Browse files
committed
feat: simdjson and PythonModuleLoader refactor
1 parent d938480 commit 4b573e4

File tree

9 files changed

+122
-53
lines changed

9 files changed

+122
-53
lines changed

README.md

+8-11
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,13 @@
22

33
### B Compiler to z80 in C++
44

5-
* The frontend is built with an [easy-to-read LALR(1) grammar and parser generator in python](https://github.com/jahan-addison/xion/tree/master), that interfaces with C++ via CPython
5+
* The frontend (Lexer, Parser) and first-pass is built with an [easy-to-use LALR(1) grammar and parser generator in python](https://github.com/jahan-addison/xion/tree/master), that interfaces with C++ via libpython or json via `simdjson`
66
* The backend will focus on modern work in SSA, Sea of Nodes, and compiler optimizations through IR breakthroughs in LLVM, gcc, V8, and related toolchains
77

88

9+
<img src="docs/images/roxas-2.png" width="800px" alt="sunil sapkota twitter" > </img>
10+
11+
912
### Installation
1013

1114
* Install git submodules
@@ -38,19 +41,13 @@ make
3841

3942
* [Simple and Efficient Construction of Static Single
4043
Assignment Form](https://c9x.me/compile/bib/braun13cc.pdf)
44+
* [Engineering a compiler](https://shop.elsevier.com/books/engineering-a-compiler/cooper/978-0-12-815412-0)
4145

4246
Check the [project board](https://github.com/users/jahan-addison/projects/3/views/1) for development and feature progress.
4347

44-
<table border="0">
45-
<td width="350px">
46-
<b>Apache License 2.0</b>
47-
<br>Grammar under CC0 1.0<br>
48-
<i>roxas</i>
49-
</td>
50-
<td border="0"><img src="docs/images/roxas.jpg" width="400px" alt="sunil sapkota twitter" > </img></td>
51-
</table>
48+
### License
5249

50+
Apache 2 License.
5351

54-
#### Special Thanks
5552

56-
* [Engineering a compiler](https://shop.elsevier.com/books/engineering-a-compiler/cooper/978-0-12-815412-0)
53+
![img2](docs/roxas-xion-axel.jpg)

cppcheck.suppress

+3-2
Original file line numberDiff line numberDiff line change
@@ -19,5 +19,6 @@ unusedFunction
1919
// libpython uses this a lot, unfortunately
2020
cstyleCast
2121

22-
// Suppress python directories
23-
*:*python*
22+
// ignore dependencies
23+
*:*python*
24+
*:*_deps*

docs/images/roxas-2.png

761 KB
Loading

docs/images/roxas-xion-axel.jpg

7.91 KB
Loading

roxas/main.cc

+19-9
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,19 @@
1616

1717
#include <cstdlib>
1818
#include <iostream>
19-
#include <roxas/ast.h>
2019
#include <roxas/python_module.h>
20+
#include <roxas/util.h>
2121

22+
/**
23+
* @brief
24+
* Arguments
25+
* Loads a Parser via a python module frontend for the first pass.
26+
*
27+
* 1) Python module importable name
28+
* 2) Directory to python module
29+
* 3) Path to B program
30+
* 4) Optional path to a python venv
31+
*/
2232
int main(int argc, const char* argv[])
2333
{
2434
if (argc < 4) {
@@ -32,15 +42,15 @@ int main(int argc, const char* argv[])
3242
return EXIT_FAILURE;
3343
}
3444
try {
35-
// Dependency venv Example:
36-
// ~/.cache/pypoetry/virtualenvs/xion-I1_4RUhc-py3.11/lib/python3.11/site-packages
37-
auto parse_tree =
38-
argc == 5 ? roxas::ParseTreeModuleLoader(
39-
argv[2], argv[1], argv[3], argv[4])
40-
: roxas::ParseTreeModuleLoader(argv[2], argv[1], argv[3]);
41-
std::cout << parse_tree.call_method_on_module(
42-
"get_source_program_ast_as_string")
45+
auto source = roxas::util::read_file_from_path(argv[3]);
46+
auto python_module =
47+
argc == 5 ? roxas::PythonModuleLoader(argv[2], argv[1], argv[4])
48+
: roxas::PythonModuleLoader(argv[2], argv[1]);
49+
50+
std::cout << python_module.call_method_on_module(
51+
"get_source_program_ast_as_json", { source })
4352
<< std::endl;
53+
4454
} catch (std::runtime_error& e) {
4555
std::cerr << "Runtime Exception :: " << e.what() << std::endl;
4656
return EXIT_FAILURE;

roxas/python_module.cc

+11-30
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,6 @@
1414
* limitations under the License.
1515
*/
1616

17-
#include <filesystem>
18-
#include <fstream>
1917
#include <roxas/python_module.h>
2018
#include <sstream>
2119
#include <stdexcept>
@@ -24,25 +22,6 @@
2422

2523
namespace roxas {
2624

27-
namespace fs = std::filesystem;
28-
29-
/**
30-
* @brief read source file
31-
*
32-
* @param path path to file
33-
* @return std::string
34-
*/
35-
std::string read_source_file(fs::path path)
36-
{
37-
std::ifstream f(path, std::ios::in | std::ios::binary);
38-
const auto sz = fs::file_size(path);
39-
40-
std::string result(sz, '\0');
41-
f.read(result.data(), sz);
42-
43-
return result;
44-
}
45-
4625
/**
4726
* @brief PythonModuleLoader constructor
4827
*
@@ -83,14 +62,15 @@ PythonModuleLoader::PythonModuleLoader(std::string_view module_path,
8362
* @param args initializer list of arguments to pass to the python method
8463
* @return std::string result of method call
8564
*/
86-
std::string call_method_on_module(std::string_view method_name,
87-
std::initializer_list<std::string> args);
65+
std::string PythonModuleLoader::call_method_on_module(
66+
std::string_view method_name,
67+
std::initializer_list<std::string> args)
8868
{
8969
std::string ret{};
9070
PyObject *pModule, *pDict, *pFunc, *vModule;
9171

9272
// Load the module object
93-
pModule = PyImport_ImportModule(module_name_.c_str());
73+
pModule = PyImport_ImportModule(module_name_.data());
9474

9575
if (pModule == NULL) {
9676
throw std::runtime_error("memory error: failed to allocate pModule");
@@ -114,7 +94,7 @@ std::string call_method_on_module(std::string_view method_name,
11494
}
11595

11696
// pFunc is also a borrowed reference
117-
pFunc = PyDict_GetItemString(pDict, method_name.c_str());
97+
pFunc = PyDict_GetItemString(pDict, method_name.data());
11898

11999
if (pFunc == NULL) {
120100
Py_DECREF(pModule);
@@ -124,16 +104,17 @@ std::string call_method_on_module(std::string_view method_name,
124104

125105
if (PyCallable_Check(pFunc)) {
126106
PyObject *pValue, *pArgs;
127-
int pIndex = 0;
107+
int index = 0;
128108
pArgs = PyTuple_New(args.size());
129109
// construct the arguments from the initializer list `args'
130-
for (std::string arg const& : args) {
110+
for (std::string const& arg : args) {
131111
if (arg == "true") {
132-
PyTuple_SetItem(pArgs, pIndex, Py_True);
112+
PyTuple_SetItem(pArgs, index, Py_True);
133113
} else if (arg == "false") {
134-
PyTuple_SetItem(pArgs, pIndex, Py_False);
114+
PyTuple_SetItem(pArgs, index, Py_False);
135115
} else {
136-
PyTuple_SetItem(pArgs, index, PyUnicode_FromString(arg));
116+
PyTuple_SetItem(
117+
pArgs, index, PyUnicode_FromString(arg.c_str()));
137118
}
138119
index++;
139120
}

roxas/util.cc

+43
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
/*
2+
* Copyright (c) Jahan Addison
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
#include <fstream>
18+
#include <roxas/util.h>
19+
20+
namespace roxas {
21+
22+
namespace util {
23+
24+
/**
25+
* @brief read source file
26+
*
27+
* @param path path to file
28+
* @return std::string
29+
*/
30+
std::string read_file_from_path(fs::path path)
31+
{
32+
std::ifstream f(path, std::ios::in | std::ios::binary);
33+
const auto sz = fs::file_size(path);
34+
35+
std::string result(sz, '\0');
36+
f.read(result.data(), sz);
37+
38+
return result;
39+
}
40+
41+
} // namespace util
42+
43+
} // namespace roxas

roxas/util.h

+37
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
/*
2+
* Copyright (c) Jahan Addison
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
#pragma once
18+
19+
#include <filesystem>
20+
21+
namespace roxas {
22+
23+
namespace util {
24+
25+
namespace fs = std::filesystem;
26+
27+
/**
28+
* @brief read a file from a fs::path
29+
*
30+
* @param path path to file
31+
* @return std::string
32+
*/
33+
std::string read_file_from_path(fs::path path);
34+
35+
} // namespace util
36+
37+
} // namespace roxas

0 commit comments

Comments
 (0)