k1lib.kast module
Small module with helper functions to analyze and manipulate Python abstract syntax tree
- class k1lib.kast.walk[source]
Bases:
BaseCli
- class k1lib.kast.pretty[source]
Bases:
BaseCli
- k1lib.kast.py2js(m)[source]
Converts simple python expression into js code. Example:
kast.py2js("x+3") # returns ('(x+3)', {'x'}) kast.py2js("lambda x: x+3") # returns ('(x+3)', {'x'}) kast.py2js("lambda y: y+3") # returns ('(y+3)', {'y'}) kast.py2js("lambda y: y+3*x") # returns ('(y+(3*x))', {'x', 'y'}) kast.py2js("x<3 and 45>10") # returns ('((x<3)&&(45>10))', {'x'}) kast.py2js("abs((x//5.1) * 2.3)") # returns ('Math.abs((Math.floor(x/5.1)*2.3))', {'x'}) kast.py2js("not x > 3") # returns ('!(x>3)', {'x'})
This will return a tuple of 2 objects. First is the JS code, and second is the set of unknown variables in the JS code. If the code is a lambda function, then it only considers what’s inside the function. More complex examples:
# returns ('[...Array(10).keys()].map((x, i) => [x, i]).filter(([x, y]) => ((x%3)===1)).map(([x, y]) => (Math.pow(x, y)+z))', {'z'}) kast.py2js("[x**y + z for x, y in enumerate(range(10)) if x % 3 == 1]")
Both JS and Python code when run should return [1, 256, 823543] for z = 0.
A lot of builtin Python functions are transpiled automatically, including:
abs, all, any, divmod, enumerate, float, getattr, hasattr, int, iter len, list, max, min, pow, print, range, reversed, round, set, setattr str, sum, tuple, type, zip
Other builtin operations don’t quite make sense though. But the neat thing is, any functions beyond these builtin functions are not transpiled, and instead just passes along to the JS code. This allows you to kinda mix and match code styles from both Python and JS. For example:
# returns ("(document.querySelector(('#' + someIdx + '_tail')).style['color'] = (((Math.round(Math.pow(x, 2))===Math.abs(-12))) ? ('red') : ('green')))", {'someIdx', 'x'}) kast.py2js("setattr(document.querySelector(f'#{someIdx}_tail').style, 'color', 'red' if round(x**2) == Math.abs(-12) else 'green')")
See how we’re both using the Python transpiled
**
(toMath.pow(...)
), yet usesMath.abs(...)
directly, which is not defined in Python, but is defined in JS, without any trouble. Also notice thatdocument.querySelector
and f-strings work too. So in short, overall syntax is Python’s, but you can call random JS functions!This can do lots of transformations, but don’t expect it to be airtight. I’ve done all I can to make the thing airtight, but I’m sure you can come up with some complex scenario where it would fail. This is meant to be applied on short pieces of code only.