Parser and transpiler for the Kahmi DSL.
Project description
kahmi-dsl
This is a Python-based configuration language for the Kahmi build system that is heavily inspired by Groovy and Gradle.
Example:
buildscript {
dependencies = ["kahmi-git", "kahmi-cxx"]
}
let cxx = load("kahmi-cxx")
let git = load("kahmi-git")
name = "myproject"
version = git.version()
cxx.build("main") {
srcs = glob("src/*.cpp")
type = "executable"
}
Syntax & Semantics
The Kahmi DSL basically wraps Python code and even extends it's normal syntax with multiline lambdas.
Every Kahmi script is executed in a given "context", that can be an arbitrary Python object which is addressable in Python expressions as "self". There are 3 different types of operations one can perform. Entering a Python expression or multiline lambda reverts the parser back into full Python mode (with the aforementioned multiline lambda support).
-
Define a local variable with the
let
KeywordLocal variables are defined using the
let
keyword. The variable can then be addressed in Python expressions or as call block targets (see below). The right hand side of the assignment must be a Python expression.let my_variable = 42
-
Set a property on the current context object
The same syntax but without the
let
keyword assigns the value to a member of the current context object instead of to a local variable.nmae = "my-project" version = git.version()
-
Configure blocks
A configure block basically generates a Python function, called the "closure", and passes it to the specified target. The closure that is defined after the target is passed to the target by either calling it's
configure()
method or calling the target directly.print("Hello, World!") # Call without body buildscript { dependencies = ["kahmi-python"] } cxx.build("main") { srcs = glob("src/*.cpp") }
-
Multi-line lambdas
The Kahmi DSL parser injects the ability to define multi-line lambdas in any Python expression. The lambda syntax is inspired by Javascript/Typescript and uses
=>
as the lambda arrow operation to connect the argument definition with the lambda body.A lambda with braces requires a return statement, otherwhise the return value of the lambda will be
None
. Single-statement lambdas are not currently supported with this syntax (although you can always fall back to standard syntaxlambda: <expr>
).let myFunc = () => { import random return random.random() } print(myFunc())
Nesting lambdas is supported and has the expected semantics except if used in comprehensions (as they introduce a new scope that can not be captured by the function definition that is a multi-line lambda is transpiled to).
-
Macros
Macros are plugins that can be enabled in the Kahmi DSL parser to implement custom parsing logic following a macro identifier. The Kahmi DSL parser comes with a YAML plugin out of the box:
buildscript { dependencies = !yaml { - kahmi-git - kahmi-python } }
Built-ins
Kahmi only provides two additional built-in functions on top of what is provided by Python, and they are only necessary for the execution of Kahmi's generated Python code.
Name | Description |
---|---|
self |
The root context object for the script. |
__lookup__(name, locals_, ctx) |
Helper function to resolve the targets of call blocks. |
Under the hood
Kahmi comes with a simple cli that allows you to run any Kahmi script, but given the limited ability to override the root context object it is expected that it does not serve much use outside of debugging and development.
$ python -m kahmi.dsl examples/hello.kmi
Using the -E
option, you can retrieve the Python code that a Kahmi file is transpiled to. This
is especially useful to understand how Kahmi constructs are converted into Python. Below are some
examples:
let msg = (name) => {
return 'Hello, ' + name
}('World')
print(msg)
def lambda_stdin_1_10(name):
return 'Hello, ' + name
msg = lambda_stdin_1_10('World')
__lookup__('print', locals(), self)(msg)
buildscript {
dependencies = ["kahmi-python"]
}
def __configure_buildscript(self):
self.dependencies = ['kahmi-python']
__configure_buildscript_self_target = __lookup__('buildscript', locals(), self)
if hasattr(__configure_buildscript_self_target, 'configure'):
__configure_buildscript_self_target.configure(__configure_buildscript)
else:
__configure_buildscript_self_target(__configure_buildscript)
Copyright © 2021 Niklas Rosenstein
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
Built Distribution
File details
Details for the file kahmi-dsl-0.1.0.tar.gz
.
File metadata
- Download URL: kahmi-dsl-0.1.0.tar.gz
- Upload date:
- Size: 14.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/3.2.0 pkginfo/1.6.1 requests/2.25.1 setuptools/50.3.2 requests-toolbelt/0.9.1 tqdm/4.54.1 CPython/3.7.3
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 7337cd87f4b3e958121a5568ede45fb5b42dede91c5fbe9789df335d7540a1c6 |
|
MD5 | 0f59d92c67513f3e4b7d04caa22ea7e9 |
|
BLAKE2b-256 | eb86afbe00279efe633579be6e1d1fe453bca209b969fa6e8e796a0cf2d37720 |
File details
Details for the file kahmi_dsl-0.1.0-py3-none-any.whl
.
File metadata
- Download URL: kahmi_dsl-0.1.0-py3-none-any.whl
- Upload date:
- Size: 15.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/3.2.0 pkginfo/1.6.1 requests/2.25.1 setuptools/50.3.2 requests-toolbelt/0.9.1 tqdm/4.54.1 CPython/3.7.3
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 1c0273c7e3deaab146933a7d051b9d7ec97d5c73a978ac3f159096eb875a9345 |
|
MD5 | 7464823b28db921d18ea06b50875abd9 |
|
BLAKE2b-256 | f770c3765f8d1e4ee42cd6e071b2bd7dd9023e3568d148f51bf49fff9bdd9180 |