Chelodina is a transpiler that converts LOGO:
TO triangle :length
REPEAT 3 [ FORWARD :length RIGHT 120 ]
END
TO flower :length :count
REPEAT 150 [
triangle :length
RIGHT 360 / :count
]
END
TO web
REPEAT 6 [ flower 150 18 ]
END
web
Into Python:
import turtle
def triangle(p_length):
for _ in range(3):
turtle.forward(p_length)
turtle.right(120.0)
def flower(p_length, p_count):
for _ in range(150):
triangle(p_length)
turtle.right(360.0 / p_count)
def web():
for _ in range(6):
flower(150.0, 18.0)
web()
turtle.done()
pip install chelodina
usage: chelodina [-h] --input INPUT [--run]
arguments:
-h, --help show this help message and exit
--input INPUT Logo source file
--run Run the transpiled code
There's some ready examples to try if you clone the repository:
chelodina --input examples/example1.logo
You can also trigger the program to run in a GUI:
chelodina --input examples/example1.logo --run
- Implemented:
- Motion functions:
FORWARD
,BACK
,LEFT
,RIGHT
,SETPOS
,SETX
,SETY
,SETHEADING
,SETH
,HOME
- Screen functions:
DONE
,CLEARSCREEN
- Control structures:
REPEAT
- Function calls and definitions with optional parameters
- Binary operations
- Motion functions:
This is still on an early stage, I focused on making some examples work. Functions with similar structure are trivial to implement, but I want to focus on improving the tests first.
For grammar reference look at grammar.bnf.
- Validations for a valid AST (e.g. to make sure a function parameter exists before trying to use it on a statement) are not user friendly yet. I suggest double-checking your programs elsewhere first.
- Only tested on Python 3.6+ so far.
Use pipenv to install dependencies:
pipenv install --dev
Run tests with:
pipenv run tests
Automatically run tests after detecting changes with:
pipenv run tests-watch
- The easy way is to write tests to debug your code. Feel free to use
assert False
where necessary. - If you need to run tests along anything that sends to or needs the standard output (a debugger like pdb or pudb), you'll need to run
pytest
directly:pytest --capture=no
. - There's a library to pretty-print your AST in the
utils
package. Usage example:
from chelodina import compiler
from chelodina.utils.debug import parseprint
logo_code = """
to myfunction
forward 51.0
left 91
end
"""
parsed_ast = compiler.get_ast(logo_code)
parseprint(parsed)
And you'll see the resulting AST:
Module(body=[
Import(names=[
alias(name='turtle', asname=None),
]),
FunctionDef(name='myfunction', args=arguments(args=[], vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]), body=[
Expr(value=Call(func=Attribute(value=Name(id='turtle', ctx=Load()), attr='forward', ctx=Load()), args=[
Num(n=51.0),
], keywords=[])),
Expr(value=Call(func=Attribute(value=Name(id='turtle', ctx=Load()), attr='left', ctx=Load()), args=[
Num(n=91.0),
], keywords=[])),
], decorator_list=[], returns=None),
Expr(value=Call(func=Attribute(value=Name(id='turtle', ctx=Load()), attr='done', ctx=Load()), args=[], keywords=[])),
])
I use black for code formatting, please install the pre-commit hook before doing a PR. This will be enforced with a linter check in the future.
You can run the command manually too:
black .
Not required, but if you install EditorConfig in your editor of choice it will make your life easier.