Skip to main content

Evaluate C++ using Python and Zig

Project description

ecpz - Evaluate C++ using Python and Zig

Do you need to evaluate some simple C++ code from inside your application, and it should work cross-platform (Linux, Mac and Windows) without causing a headache?

You've seen it all, quine-relay stopped being amusing years ago, and you feel the itch for something new?

No problem, easy-peasy with ecpz!


This little package combines the ubiquity of Python and ingeniuity of the Zig toolchain to give you the ability to compile C++ snippets without pain.

If you have a non-trivial project consisting of more than one source file, you should probably configure and build it properly using e.g. CMake.

If you need an interactive C++ code execution environment (i.e. a REPL), check out cling.

But if for some reason you need to produce and execute some ad-hoc throw-away C++ snippets as a part of your workflow, ecpz might be just what you need!

Usage

Install ecpz using pip or uv and check ecpz --help for all options.

In the following, the features of ecpz are illustrated by some examples.

ecpz run

Compile and run a single source file provided either as argument or via standard input.

For example, create hello.cpp:

#include <print>

int main() {
  std::println("Hello world!");
}

And run it:

$ cat hello.cpp | ecpz --clang-arg -std=c++23 run
Hello world!

ecpz print

Evaluates some expressions and pretty-print them using std::print(ln) (note that this automatically implies -std=c++23).

For example, create a header prelude.hpp:

#include <numbers>
#include <type_traits>

inline double tau() {
  return 2 * std::numbers::pi;
}

And now run:

$ ecpz --prelude prelude.hpp print "{:.3f} {} {} {}" "tau()" "[](){ int i=0; ++i; return i; }()" "std::is_same_v<int, double>" "std::is_same_v<int, int32_t>"
6.283 1 false true

You can set the ECPZ_PRELUDE environment variable to the path of your custom header to make it always included by default. Note that as usual, CLI arguments override equivalent environment variables.

Creating a Quine

Usually, using I/O to let code open itself directly is forbidden and considered bad sportsmanship. Everybody agrees that the following things are clear cases of cheating:

  • reading a hard-coded string filename
  • using the argv[0] trick to reflect back the name of the current file/executable
  • reading the file using some compile- or runtime reflection capabilities of the programming language
  • adding and using a special quine command in a custom programming language or environment

We will do none of these things. Create some source file FILE with the following content:

#include "ecpz/subprocess.hpp"
int main(int i, char** a) {
    using b = std::istreambuf_iterator<char>; using c = std::string;
    auto d = [](auto e){ std::ifstream f(e, std::ios::binary); return c(b(f), b()); };
    std::vector<c> e(i+3, a[i-1]); e[0]="ecpz"; e[1]="run";
    auto f = i%2 == 0 ? subprocess::run(e).output : d(a[i-1]);
    subprocess::set_bin(); std::cout<<f;
}

Now run it with ecpz run FILE FILE and convince yourself that we do not cheat in such despicable and reprehensible ways as the ones listed above!

Spoiler

Nobody ever said that we cannot just...

  • run a C++ source file through ecpz,
    • which uses a Python package,
      • which provides the zig toolchain,
        • which provides clang,
    • to compile and then run the program, which
      • runs its arguments through ecpz,
        • compiling and then running the same program, which now finally
          • prints the file passed to it as the argument

Or, at least I did not get the memo that this is illegal. In that case I apologize for wasting your time.

But even if this is still cheating - isn't cheating in glorious ways not also a form of art?

Limitations

The following issues are fixable, i.e. only a matter of more effort and time:

  • currently only synchronous execution is supported, no I/O buffering or streaming
  • currently it is not possible to pipe input data into ecpz run to pass it as stdin

Acknowledgements

Thanks to sheredom for creating subprocess.h, the only true header-only C(++) subprocess library I could find!

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

ecpz-0.1.0.tar.gz (17.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

ecpz-0.1.0-py3-none-any.whl (17.0 kB view details)

Uploaded Python 3

File details

Details for the file ecpz-0.1.0.tar.gz.

File metadata

  • Download URL: ecpz-0.1.0.tar.gz
  • Upload date:
  • Size: 17.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.12.9

File hashes

Hashes for ecpz-0.1.0.tar.gz
Algorithm Hash digest
SHA256 9a32d5bcb20e0fa9f120d059f54fff2397c090834d5f3a7bfdecdc8279d06944
MD5 7aa8bd56aedaf058af66d3ed3c101178
BLAKE2b-256 3e528b0ad6cf03d54368809738f38f910fe762d3da4f8bd03939cb91469a2c39

See more details on using hashes here.

File details

Details for the file ecpz-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: ecpz-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 17.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.12.9

File hashes

Hashes for ecpz-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 229cf66966eb51eb71ce067dedd545930a044a33c0b9e88c0b9383744ec6c82c
MD5 13e374485c54ee967a81f008e68b490d
BLAKE2b-256 5ea0ffade4de74bcce08e1eeef855844a8702c9b0a858a15e4a8976bb6963b9f

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page