-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 1ed0eb9
Showing
7 changed files
with
744 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
# Byte-compiled / optimized / DLL files | ||
__pycache__/ | ||
*.py[cod] | ||
*$py.class | ||
|
||
# C extensions | ||
*.so | ||
|
||
# Distribution / packaging | ||
.Python | ||
build/ | ||
develop-eggs/ | ||
dist/ | ||
downloads/ | ||
eggs/ | ||
.eggs/ | ||
lib/ | ||
lib64/ | ||
parts/ | ||
sdist/ | ||
var/ | ||
wheels/ | ||
*.egg-info/ | ||
.installed.cfg | ||
*.egg | ||
MANIFEST | ||
|
||
# Installer logs | ||
pip-log.txt | ||
pip-delete-this-directory.txt | ||
|
||
# Unit test / coverage reports | ||
htmlcov/ | ||
.tox/ | ||
.coverage | ||
.coverage.* | ||
.cache | ||
nosetests.xml | ||
coverage.xml | ||
*.cover | ||
.hypothesis/ | ||
.pytest_cache/ | ||
|
||
# Sphinx documentation | ||
docs/_build/ | ||
|
||
# PyBuilder | ||
target/ | ||
|
||
# Jupyter Notebook | ||
.ipynb_checkpoints | ||
|
||
# pyenv | ||
.python-version | ||
|
||
# Environments | ||
.env | ||
.venv | ||
env/ | ||
venv/ | ||
ENV/ | ||
env.bak/ | ||
venv.bak/ | ||
|
||
# Spyder project settings | ||
.spyderproject | ||
.spyproject | ||
|
||
# Rope project settings | ||
.ropeproject | ||
|
||
# mkdocs documentation | ||
/site | ||
|
||
# mypy | ||
.mypy_cache/ | ||
|
||
# IDEs | ||
.idea/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
{ | ||
"python.testing.pytestArgs": [ | ||
"." | ||
], | ||
"python.testing.unittestEnabled": false, | ||
"python.testing.pytestEnabled": true | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
# C-Py-Py | ||
|
||
```python | ||
from cpp import * | ||
|
||
x = (cpp)[std::vector<int>v({1, 2, 3})] | ||
x.push_back(4) | ||
(cpp)[std::cout] << "Vector x: " << x << (cpp)[std::endl] | ||
# -> prints 'Vector x: [1, 2, 3]' | ||
for i in auto& x: | ||
(cpp)[std::cout] << "Incrementing " << i << "..." << (cpp)[std::endl] | ||
# -> prints 'Incrementing 1...', 'Incrementing 2...', etc. | ||
i += 1 | ||
|
||
(cpp)[std::cout] << "Vector after: " << x << (cpp)[std::endl] | ||
# -> prints 'Vector after: [2, 3, 4, 5]' | ||
``` | ||
|
||
## How? | ||
|
||
### Template notation | ||
|
||
The `<>` template notation was quite difficult to pull off. Python has a weird concept of multiple-boolean-operators, so the following: | ||
|
||
```python | ||
x = (cpp)[std::vector<int>v({1, 2, 3})] | ||
``` | ||
|
||
is equivalent to | ||
|
||
```python | ||
x = (cpp)[std::((vector < int) and (int > v({1, 2, 3})))] | ||
``` | ||
|
||
We can then overwrite the less than operator for the object `vector` to simply return True, so that it's negligible: | ||
|
||
```python | ||
x = (cpp)[std::(True and (int > v({1, 2, 3})))] | ||
x = (cpp)[std::(int > v({1, 2, 3}))] | ||
``` | ||
|
||
Now we can overwrite the less than operator on a different class (`v`, in this case) so that it simply takes in a fully formed vector object as `self` and a type as the comparison, then tries to transform that into a new vector of the type in the comparison. This would be equivalent to: | ||
|
||
```python | ||
x = (cpp)[std::(v({1, 2, 3}))] | ||
``` | ||
|
||
### C++-style namespacing | ||
|
||
Nearly there. For the namespacing (`::`), we turn to the only place in the Python syntax where adjacent colons are allowed: slice notation. The code above is equivalent to: | ||
|
||
```python | ||
x = cpp[slice(std, None, v({1, 2, 3}))] | ||
``` | ||
|
||
We can define `cpp` to be an instance of a class that overrides the `__getitem__` method to simply return the rightmost part of the slice: | ||
|
||
```python | ||
class cpp: | ||
def __getitem__(self, other: slice): | ||
return other.step | ||
cpp = cpp() | ||
``` | ||
|
||
Now the code is equivalent to just: | ||
|
||
```python | ||
x = v({1, 2, 3}) | ||
``` | ||
|
||
where `v` is essentially a thin wrapper around `list`. | ||
|
||
### cout | ||
|
||
`cout` performs a small sleight-of-hand. Since Python is evaluated left-to-right, we have to have the `<<` operator reduce each of the expressions down into a single format string, then pass that to `endl` to actually do the printing. We do this by making `cout`.__lshift__() return a `Coutable`: | ||
|
||
```python | ||
class _Coutable: | ||
def __init__(self, o) -> None: | ||
self._total_str: str = format(o) | ||
|
||
def __lshift__(self, other: Any) -> Self: | ||
if other is endl: | ||
print(self._total_str) | ||
self._total_str = self._total_str + format(other) | ||
return self | ||
``` | ||
|
||
This class will just keep accumulating objects' formatted representations until it hits endl, when it will print everything out. | ||
|
||
### Taking references | ||
|
||
Unfortunately, Python's `for _ in _:` syntax is pretty rigid, and won't allow any operations in-between for and in, so we have to stick the `auto&` on the right side. This | ||
|
||
## Why? | ||
|
||
Scientists are hard at work trying to come up with an answer to that question. |
Oops, something went wrong.