Transpile simple Python to Scheme(Racket)
Project description
PySchemeTranspiler
This transpiler is only working in Python version 3.8.* due to changes in the AST module from 3.9 onwards
PYST is a transpiler between python and Scheme(Racket) source code. It tries to mimic the behavior of CPython and makes simple builtin functions available to the user. It works solely with the Python builtin AST module and does not have any dependencies.
Work in Progress
There might still be special edge cases not documented that can cause faulty transpilation. If you come across such a case, please submit the code that did not transpile correctly as an issue here on GitHub or email me privately.
Roadmap/Todos
Supported features
Language features
- Variables
- Constants
- Arithmetic
- Custom Functions
- Builtins (print, input, range, len; Type converters: int, float, str, bool)
- Types: int, float, str, bool, None, List[{Type}] (Indexing + append, pop and insert), Tuple[{Type, ...}]
- If, elif, else (also nested) (comparators eg.
!=
==
>=
andin
(for List and Tuple) but notis
oris not
) - MultiAssign swapping (
seq[n - 1], seq[n] = seq[n], seq[n - 1]
) - Augmented assignment (
a += 17
) - If expressions (
var = a if b else c
) __name__ == '__main__'
-> will always be true- For (also nested) (also multi-target e.g.
for i, j in [[0, 1], [2, 3], [4, 5]]:
) - Assert
Typing system
PYST has a fully fledged typing system and matches types at transpile-time. While most types can dynamically be deduced lists
still need to be annotated in the standard python way, for example: myList: List[int] = [1,2,3]
. This restriction is necessary because PYST can not infer a type for an empty list. Type annotations are always checked. To create a pending type you may assign a variable to None: var = None
. This will make the type pending and allow later assigning of a different value. After a type is determined it may not be changed but can be set to None again. None can act as a nullptr
value as in C++ to create optional returns. The variable which has a type but is set to a value of None
may still be used like one with a value of its own type, any runtime errors may be avoided by the user (a None check for example: if var != None:
).
Reserved names
To avoid undefined behavior during transpilation, you should avoid reassigning the special names: int, float, str, bool, list, print, input, range, len, deepcopy, toList and __{anything}__
Error and warning system
PYST tries to make errors as transparent as possible. If a transpilation error is encountered, a clear message explaining it and the exact place it occurred will be presented to the user. For example the following code will result in a transpilation error:
def willError(arg1: List[int]) -> int:
return arg1[17]
my_list: List[float] = [1,2,3]
print(willError(my_list))
[TypeError] type <TList: <class 'float'>> can not be applied to argument of type <TList: <class 'int'>>
6>6: print(willError(my_list))
^
Caveats
Multiple returns
Please ensure all paths in all functions return at least None
(PYST will implicitly add this return if missing). Multiple return statements in functions must be written so that they are the last executed entity in their function, for example with an if statement:
def testFunc(something: int) -> int:
if something:
return something
else:
return None # This could also be a plain 'return'
Note that the else is mandatory here as the first return would fall through to the None
return otherwise.
PYST will intentionally fail when an incorrect usage of return
could lead to unexpected behavior.
Usage
usage: pystranspile [-h] [-version] -input INPUT -output OUTPUT [-exportable]
Transpile simple Python to Scheme(Racket).
optional arguments:
-h, --help show this help message and exit
-version display the current version
-input INPUT path to file that should be transpiled
-output OUTPUT path to file the transpiled code should be saved in
-exportable don't wrap all usercode in a main function to allow easier exports (this might cause extra outputs)
Copyright (C) 2021 Rubin Raithel
You may abbreviate the above mentioned flags to -i
, -o
, -e
and -v
.
PYST is installed as a globally available script and does therefore not require the python3
prefix but can still be invoked with it by typing python3 -m pyschemetranspiler
.
Installation
PYST is currently not available on the PyPi and can therefore only be installed through a local clone of this repo and the command pip install .
which will make the pystranspile
command globally available.
License
PYST is currently licensed under the GPLv3 license.
Copyright (C) 2021 Rubin Raithel
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
File details
Details for the file pyschemetranspiler-1.3.tar.gz
.
File metadata
- Download URL: pyschemetranspiler-1.3.tar.gz
- Upload date:
- Size: 36.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/3.4.1 importlib_metadata/4.6.1 pkginfo/1.7.1 requests/2.25.1 requests-toolbelt/0.9.1 tqdm/4.61.2 CPython/3.9.6
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | a84caabc0b785c63c12f9313200349e20a79ce512eb6dd1277941a1b2468af9f |
|
MD5 | 57ee52c1b6d5560c791a1700b4331443 |
|
BLAKE2b-256 | 0bb109792e888f3bfda29904b7961c048942d541a60f801a6b94d2c033a1989a |
File details
Details for the file pyschemetranspiler-1.3-py3-none-any.whl
.
File metadata
- Download URL: pyschemetranspiler-1.3-py3-none-any.whl
- Upload date:
- Size: 40.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/3.4.1 importlib_metadata/4.6.1 pkginfo/1.7.1 requests/2.25.1 requests-toolbelt/0.9.1 tqdm/4.61.2 CPython/3.9.6
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | e59a69124eeb7e9b1a1bbefbc22f224646f2d2e34f9c808951ba1cf011cdeb28 |
|
MD5 | ba461e56c4ad209041b832e5a4d28454 |
|
BLAKE2b-256 | 58ae57572368c0d4d71eadd73a7e504fbf75374c1d34224c5720ef2f43fec992 |