A C/C++ source generation package.
First, some context:
- Documents contain declarations.
- Declarations contain other declarations, statements and expressions.
- Some statements contain other statements and expressions.
- Expressions are either operators or literals. Operators contain other expressions.
The general usage flow is:
- Populate a
Document
withDeclaration
s of your choice. - Format it as a string with any
DocumentFormatter
subclass.
import cxx
even_odd_enum = (
cxx.EnumBuilder("EvenOdd", scoped=True)
.add_member("Even")
.add_member("Odd")
.build()
)
get_even_odd_function = (
cxx.FunctionBuilder("GetEvenOdd", "EvenOdd")
.add_specifier("inline")
.add_argument("int", "value", cxx.literals.integer(0))
.add_statement(
cxx.statements.return_(
cxx.operators.other.conditional(
cxx.operators.arithmetic.remainder(
cxx.literals.identifier("value"),
cxx.literals.integer(2),
),
cxx.literals.identifier("EvenOdd::Odd"),
cxx.literals.identifier("EvenOdd::Even"),
)
)
)
.build()
)
document = (
cxx.DocumentBuilder(header=True)
.add_declaration(even_odd_enum.definition)
.add_declaration(get_even_odd_function.definition)
.build()
)
formatter = cxx.ClangFormatter(configuration_style="google")
print(formatter.format(document))
Output:
#pragma once
enum class EvenOdd {
Even,
Odd,
};
inline EvenOdd GetEvenOdd(int value = 0) {
return value % 2 ? EvenOdd::Odd : EvenOdd::Even;
}
The "factory" API allows you to create any element:
cxx.document(...) -> Document
cxx.declarations.[specific declaration type](...) -> Declaration
cxx.literals.[specific literal type](...) -> Literal
cxx.operators.[specific operator type](...) -> Operator
cxx.statements.[specific statement type](...) -> Statement
Some elements are awkward to create this way - such as functions, which contain arguments, internal statements, specifiers, and so on. For those elements, you should use a builder.
There are several builders:
cxx.ClassBuilder
cxx.EnumBuilder
cxx.FunctionBuilder
cxx.NamespaceBuilder
cxx.DocumentBuilder
cxx.CompoundStatementBuilder
cxx.FunctionCallOperatorBuilder
cxx.VariableDeclarationBuilder
This is a list of language features this package doesn't currently support. This is not due to any inherent difficulty - other things were prioritized.
- Initializer list -
int arr[3] = { 0, 1, 2 };
- For-range loop -
for (auto a : vec) { ... }
- Structured binding -
auto [a, b] = ...;
- Multiple-variable simple declaration -
int a=5, b=2;
- Multiple-type typedef declaration -
typedef int INT, *PINT;
- Typedef-specifier for declaration -
typedef struct { ... } S;
- Exception handling -
try
,catch
,throw
- Template and template specialization -
template <typename T>
- New operator -
new
- Delete operator -
delete
- Float/decimal literals -
0.123
Install and configure poetry:
pip3 install poetry
poetry config virtualenvs.in-project true
Install development dependencies and pre-commit hook
poetry install --with dev
pre-commit install
Run the tests:
poetry run pytest