Skip to main content

Koskript

Koskript

Koskript is a simple, embeddable, and lightweight scripting language designed to be used as a DSL inside Python applications. It features dynamic typing, lexical scoping, and native Python interop — letting you expose any Python function or object directly to your scripts.

NOTE: Koskript is currently in early development. Features like module imports, more types, and performance improvements are on the way.


Features

  • Dynamic typing.
  • Block-level lexical scoping with local declarations
  • Native Python interop via KoskriptObject
  • if, elseif, else
  • while, for, foreach loops with break / continue
  • Member access — map.key.subkey
  • Index access — array[0], map["key"]
  • First-class functions and lambda expressions
  • Arithmetic (+, -, *, /, %), comparison and logical operators
  • Embeddable in any Python application

Installation

Clone the repository and import it directly into your project:

git clone https://github.com/alesisce/koskript.git

PyPI package coming soon.


Quick Start

from koskript import KoskriptRuntime

runtime = KoskriptRuntime({
    "print": print
})
runtime.execute("""
local x = 10
local y = 26

print(x+y)
""")

Any Python value or callable you pass in is wrapped automatically — no need to build KoskriptObject yourself.


Example

// Student grade checker
local students = {
    "Aleix": {
        "age": 17,
        "grade": 95
    },
    "Maria": {
        "age": 15,
        "grade": 72
    },
    "Juan": {
        "age": 18,
        "grade": 88
    }
}

local passing_grade = 75
                   
foreach (name, data in students) {
    local grade = data.grade

    if (grade >= passing_grade) {
        print("PASS:", name, "->", grade) // Depends on how you implement it.
    } elseif (grade >= 60) {
        print("NEAR PASS:", name, "->", grade)
    } else {
        print("FAIL:", name, "->", grade)
    }
}

Output:

PASS: Aleix -> 95
NEAR PASS: Maria -> 72
PASS: Juan -> 88

Language Reference

Types

Type Description
int Integer number
float Floating-point number
string Text string
bool true or false
null The absence of a value
array Ordered list
map Key-value store

Variables

local x = 10
local pi = 3.14
local name = "Koskript"
local active = true
local missing = null
local items = [1, 2, 3]
local empty = []
local config = { "debug": true, "version": 1 }

Variables declared with local are scoped to the block they are declared in — including if, while, for and foreach bodies.

Functions

fn add(a, b) {
    return a + b
}

local result = add(10, 20)

Operators

local a = 2 + 3 * 4      // 14  (precedence: * / % before + -)
local b = 10 % 3         // 1
local c = -a             // unary minus
local d = (a + b) * 2    // grouping with parentheses

if (x >= 10 and not done or retry) {
    // ...
}
Operators Description
+ - * / % Arithmetic
-x Unary minus
== != > < >= <= Comparison
and or not Logical (short-circuiting)
( ) Grouping

Control Flow

if (x > 10) {
    print("big")
} elseif (x == 10) {
    print("exact")
} else {
    print("small")
}

Lambda Functions

local greet = () {
    print("Hello world")
}

greet()

// lambdas can take parameters and return values
local add = (a, b) {
    return a + b
}

print(add(1, 2))

// invoke a lambda literal directly
print((() { return 42 })())

Loops

// while
while (x > 0) {
    x = x - 1
}

// for — iterate array
for (item in items) {
    print(item)
}

// foreach — iterate map
foreach (key, value in config) {
    print(key, value)
}

break exits the nearest loop and continue skips to the next iteration:

for (item in items) {
    if (item == 2) {
        continue   // skip this item
    }
    if (item == 5) {
        break      // stop looping
    }
    print(item)
}

Member Access

local user = { "name": "Aleix", "age": 17 }
print(user.name)
print(user.age)

Index Access

local items = [10, 20, 30]
print(items[0])        // 10
print(items[-1])       // 30

local config = { "debug": true }
print(config["debug"]) // true

// member access and indexing can be chained
local data = { "nums": [1, 2, 3] }
print(data.nums[1])    // 2

Strings

Strings support single or double quotes and the escapes \n, \t, \r, \0, \\, \" and \':

print("line one\nline two")

Comments

// line comments start with two slashes

Reserved Keywords

The following words cannot be used as identifiers:

if elseif else while for foreach fn return local true false null and or not in break continue

Python Interop

Any Python value or callable can be exposed to Koskript. They are wrapped in a KoskriptObject automatically:

from koskript import KoskriptRuntime

runtime = KoskriptRuntime({
    "print": print,
    "len": len,
})

# add more later — register() is chainable
runtime.register("sqrt", math.sqrt)
runtime["now"] = time.time

Embedding API

execute() returns the value of the last evaluated expression, or the value of a top-level return:

runtime = KoskriptRuntime({"print": print})
result = runtime.execute("local x = 10\nx * 2")   # 20
result = runtime.execute("return 1 + 2")           # 3

For a quick one-off script, use the run() helper:

from koskript import run

run("print(1 + 2)", print=print)   # 3

Errors raised by scripts are available under koskript.Errors:

from koskript import Errors

try:
    runtime.execute("local a = [1]\nprint(a[5])")
except Errors.RuntimeError as e:
    print(e)

Roadmap

  • Index access (array[0], map["key"])
  • float type
  • null type
  • break / continue statements
  • Module imports (import "mymodule")
  • Performance improvements
  • Standard library
  • PyPI package
  • Custom parser (remove Lark dependency)
  • VM-based execution

License

Koskript is licensed under the Mozilla Public License 2.0 (MPL-2.0).

You are free to use, modify, and redistribute Koskript. However, you may not redistribute this project under a different name or claim authorship of the Koskript language.

Koskript is a trademark of Alesis.


Built with ❤️ by Alesis

Metadata

Release files for koskript 1.2.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for koskript 1.2.1
File Size Uploaded
koskript-1.2.1.tar.gz 26.7 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for koskript 1.2.1
File Interpreter ABI Platform
koskript-1.2.1-py3-none-any.whl Python 3 none any Details

Total release size: 50.2 kB

Release files / koskript-1.2.1.tar.gz

Download URL koskript-1.2.1.tar.gz
Size 26.7 kB
Tags Source
SHA-256 checksum
How to use checksums
1323226059f586d3a118005f609cb41f84060381bf3c1b2e7cb11090445edaac
BLAKE2b-256 checksum
How to use checksums
0259a4ec1ebb7c9114ed40a74779b3c7fe6ab4abb83fcf4d86183d1b3f57f1ae
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.14.6

Release files / koskript-1.2.1-py3-none-any.whl

Download URL koskript-1.2.1-py3-none-any.whl
Size 23.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
234e07d081e3625f5734404f06dc792b3c3425d893c5028cbcda7b55426799e3
BLAKE2b-256 checksum
How to use checksums
10e3d04a0fe317f4395f61fed4633d85ca247a00ceb3a809b1551c9f698902ae
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.14.6

Release history Release notifications | RSS feed

1.4.2

2 release files

1.4.1

2 release files

1.4.0

2 release files

1.3.1

2 release files

This release

1.2.1 This release

2 release files

1.2.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page