Dark.Langv2.0.0
Документация · Dark 2.0.0

Язык для тех, кто дочитывает до end.

Dark — простой, динамический язык программирования. Понятный синтаксис, ООП, менеджер пакетов и компилятор в исполняемый файл — всё в одном интерпретаторе.

Эта документация поможет изучить синтаксис языка и его стандартную библиотеку — от первой переменной до сборки собственного `.exe`.

ООП и наследование Менеджер пакетов dpm Компиляция через Nuitka Python-расширения
vsp210.philosophy()

О языке

Dark — это современный, динамический язык программирования, созданный для простоты и эффективности. Его синтаксис интуитивно понятен, что делает его отличным выбором как для начинающих, так и для опытных разработчиков.

Для удобной разработки рекомендуется использовать официальное расширение для Visual Studio Code — оно даёт подсветку синтаксиса, автодополнение, проверку ошибок в реальном времени и панель управления пакетами прямо в редакторе.

Секрет. В стандартной библиотеке есть модуль vsp210 — вызовите vsp210.philosophy() в REPL, чтобы увидеть диалог целиком, или vsp210.history(), чтобы узнать историю создателя языка. Подробности — во вкладке «Стандартная библиотека».

Готовы начать? Откройте вкладку «Синтаксис» слева — или, если вы уже писали код на Dark, сразу переходите к нужному модулю стандартной библиотеки.

Язык

Синтаксис

Основы языка: переменные, типы данных, операторы и управляющие конструкции.

Переменные

Переменные объявляются с помощью оператора присваивания =. Имена переменных могут содержать буквы, цифры и знак подчёркивания, но не могут начинаться с цифры.

my_variable = 10
another_var = "Hello, Dark!"
is_active = true

Множественное присваивание

Можно присвоить сразу несколько переменных за раз — двумя способами.

Параллельное присваивание нескольких значений:

a, b = 1, 2
println(a) # 1
println(b) # 2

Или распаковка одного списка (либо строки) на несколько переменных — количество переменных слева должно совпадать с количеством элементов:

coords = [10, 20]
x, y = coords
println(x) # 10
println(y) # 20

Типы данных

Числа (Number): целые и с плавающей точкой. Например: 42, 3.14.

Строки (String): текст в двойных, одинарных или обратных кавычках (бэктиках): "some text", 'some text', `some text`. Строки поддерживают доступ к символам по индексу, как и списки.

Строки в обратных кавычках — особые: внутри {выражение} подставляется результат вычисления, а не печатается как текст. Двойных и одинарных кавычек это не касается — там {} остаётся обычным текстом.

name = "Dark"
age = 16

println(`Привет, {name}! Тебе {age} лет.`)
# Выведет: Привет, Dark! Тебе 16 лет.

println("Привет, {name}!") # Выведет буквально: Привет, {name}!

Внутри {} можно писать любое выражение — не только имя переменной: арифметику, обращение к атрибуту объекта, индексацию, вызов метода.

items = ["a", "b", "c"]
println(`Первый элемент: {items[0]}, всего: {items.len()}, сумма: {2 + 2 * 10}`)

Чтобы вывести буквальную фигурную скобку внутри бэктик-строки, а не подстановку, удвойте её: {{ и }}.

println(`Так пишут подстановку: {{name}}`)
# Выведет: Так пишут подстановку: {name}

Булевы (Boolean): true или false.

Списки (List): упорядоченная коллекция элементов в квадратных скобках. Доступ к элементам — по индексу (нумерация с 0):

my_list = ["a", "b", "c"]
println(my_list[1]) # Выведет "b"

my_list[1] = "B" # Изменение элемента по индексу
println(my_list) # Выведет ["a", "B", "c"]

Словари (Dictionary): коллекция пар ключ-значение в фигурных скобках. Доступ к значениям — двумя способами:

person = {"name": "Alex", "age": 30}

# Через квадратные скобки
println(person["name"]) # Выведет "Alex"

# Через точку (если ключ - валидный идентификатор)
println(person.age) # Выведет 30

Операторы

Dark поддерживает стандартные арифметические (+, -, *, /), сравнительные (==, !=, <, >, <=, >=) и логические операторы.

Логические операторы (and / or / not)

Для сложных условий используются and, or и not.

# Пример с 'and'
if age > 18 and has_license == true then
    println("Можно водить машину")
end

# Пример с 'or'
if is_weekend or is_holiday then
    println("Время отдыхать!")
end

# Пример с 'not'
is_ready = false
if not is_ready then
    println("Ещё не готово.")
end

# Пример not с операторами сравнения
if not (a > b) then
    println("a не больше b")
end

Операторы поддерживают «короткое замыкание» (short-circuiting): в выражении A and B, если A ложно, то B не вычисляется.

Управляющие конструкции

if · then · else

Условный оператор. Блок else не обязателен.

if x > 10 then
    println("x is greater than 10")
else
    println("x is not greater than 10")
end

while

Цикл, который выполняется, пока условие истинно.

i = 0
while i < 5 do
    println(i)
    i = i + 1
end

for

Цикл для итерации по элементам списка, строки или ключам словаря.

my_list = [1, 2, 3]
for item in my_list do
    println(item)
end

Функции

Определение пользовательских функций:

function add(a, b) do
    return a + b
end

result = add(5, 3)
println(result) # Выведет 8

Функция может не возвращать значение — тогда return используется для досрочного выхода:

function check_age(age) do
    if age < 18 then
        println("Доступ запрещен.")
        return # Досрочный выход из функции
    end
    println("Доступ разрешен.")
end

Обработка ошибок (try…except)

Конструкция try…except перехватывает ошибки времени выполнения, предотвращая аварийное завершение программы.

try do
    # Код, который может вызвать ошибку
except e do
    # Код, который выполнится в случае ошибки.
    # 'e' - это словарь с информацией об ошибке.
end

С версии 0.3.1 сообщения об ошибках стали более понятными: Dark показывает не только описание ошибки, но и строку кода с указателем на проблемное место, а также полную трассировку стека вызовов, если ошибка произошла внутри функции.

function inner_function() do
    c = 10 / 0 # Ошибка здесь
end

function middle_function() do
    inner_function() # Вызов, ведущий к ошибке
end

middle_function()

Вывод в консоли будет выглядеть так:

Трассировка вызовов (от последнего к первому):
  Файл "D:\...\script.dark", строка 8, в функция 'middle_function'
  Файл "D:\...\script.dark", строка 2, в функция 'inner_function'

Ошибка выполнения: деление на ноль
  [Файл: "D:\...\script.dark", строка 2, позиция 12]

  2 |     c = 10 / 0 # Ошибка здесь
    |            ^
--------------------------------------------------------------------

Пример

try do
    result = 10 / 0
except e do
    println("Произошла ошибка: " + e["message"])
end

assert

assert(условие, сообщение) проверяет условие. Если оно ложно — выводит сообщение в консоль. Оба аргумента обязательны и передаются в скобках через запятую.

age = -5
assert(age >= 0, "Возраст не может быть отрицательным")
Важно. В отличие от assert во многих других языках, здесь это не аварийная остановка программы — при провале проверки сообщение просто печатается, и выполнение продолжается дальше. Для остановки выполнения при ошибке используйте try…except и явный вызов ошибки, либо os.exit().

Импорт модулей

Для использования кода из других файлов (модулей) используется ключевое слово import. Путь указывается в двойных кавычках, расширение .dark или .py указывать не нужно. Синонимом import служит use.

# Импортируем стандартный модуль os
import "os"
# или так:
use "os"

# Импортируем пользовательский модуль из файла my_module.dark
import "my_module"

os.system("cls")
my_module.my_function()

Можно импортировать конкретные имена из модуля конструкцией from … use …:

# В файле my_math.dark есть PI = 3.14 и функция square(x)
from "my_math" use PI, square

println(PI)        # Выведет 3.14
println(square(5)) # Выведет 25

С версии 1.2.0 Dark поддерживает импорт модулей напрямую из интернета:

from "https://raw.githubusercontent.com/Dark-Tehno/Dark-Lang-Source-Code/refs/heads/main/example/script.dark" use PI

println(PI)

Комментарии

Однострочные комментарии начинаются с символа #.

# Это комментарий. Он будет проигнорирован.
variable = 1 # Это тоже комментарий.

Директивы

Строка в начале файла, начинающаяся с #!, объявляет директиву.

#!nocache
# Это директива, которая отключает кеширование для этого файла.
# Полезно при разработке, чтобы изменения в файле сразу применялись.
#!USE_WITH_PYTHON
# Эта директива включает интеграцию с Python, позволяя использовать модуль `python`.
# Требуется для выполнения Python-кода внутри Dark-скрипта.
python.exec('print("Hello from Python!")')

# или версия с созданием переменных:
python_code = """
a = input("Enter something: ")
print(f"You entered: {a}")
def greet(name):
    return f"Hello, {name}!"
b = greet("World")
"""
vars = python.exec(python_code)
println(vars['a'])
println(vars['b'])
Язык

ООП: классы и объекты

Dark поддерживает объектно-ориентированное программирование: собственные типы данных объединяют данные (атрибуты) и функции для работы с ними (методы) в единое целое.

Определение классов

Класс определяется ключевым словом class, за которым следует имя класса и блок do…end.

class Animal do
    # ... методы и атрибуты ...
end

Конструктор (__main__)

Метод __main__ — конструктор. Он вызывается автоматически при создании объекта. Первый параметр конструктора (и любого метода) — ссылка на сам объект, по соглашению его называют object.

class Animal do
    function __main__(object, name) do
        object.name = name # Создание и инициализация атрибута 'name'
    end
end

Создание объектов (экземпляров)

Новый объект создаётся вызовом имени класса как функции. Аргументы передаются в __main__ (кроме первого object, который передаётся автоматически).

my_dog = Animal("Рекс")
println(my_dog.name) # Выведет "Рекс"

Атрибуты — переменные, принадлежащие объекту. Методы — функции класса, работающие с данными объекта.

Специальные методы

Можно определить, как стандартные операторы (+, *, == и т.д.) работают с экземплярами класса — через специальные методы.

ОператорИмя методаОписание
+__add__Сложение
-__sub__Вычитание
*__mul__Умножение
/__div__Деление
==__eq__Равенство
!=__ne__Неравенство
<__lt__Меньше чем
>__gt__Больше чем
<=__le__Меньше или равно
>=__ge__Больше или равно
class Vector do
    function __main__(object, x, y) do
        object.x = x
        object.y = y
    end

    function __add__(object, other) do
        return Vector(object.x + other.x, object.y + other.y)
    end
end

v1 = Vector(2, 3)
v2 = Vector(10, 5)
v3 = v1 + v2 # Здесь вызывается __add__
# v3 будет объектом Vector с x=12, y=8

Приватные члены (инкапсуляция)

Если имя атрибута или метода начинается с двух подчёркиваний (__), он считается приватным. Доступ к таким членам возможен только из методов того же класса.

class BankAccount do
    function __main__(object, owner, initial_balance) do
        object.owner = owner
        object.__balance = initial_balance # Приватный атрибут
    end

    # Публичный метод для получения баланса
    function get_balance(object) do
        return object.__balance # Доступ внутри класса разрешен
    end
end

my_account = BankAccount("VSP", 1000)

# Это сработает
println(my_account.get_balance()) # Выведет 1000

# А это вызовет ошибку, так как __balance - приватный
# println(my_account.__balance)
Язык

Встроенные функции и методы

Базовые функции доступны без импорта. Методы вызываются через точку на значении нужного типа.

print(value) / print()

Выводит значение в консоль без переноса строки. Без аргументов — ничего не делает.

println(value) / println()

Выводит значение и добавляет перенос строки. Без аргументов — просто перенос строки.

input()

Читает строку текста от пользователя.

to_int(value)

Преобразует значение в целое число. Рекомендуется использовать с try…except.

to_str(value)

Преобразует значение в строку.

to_float(value)

Преобразует значение в число с плавающей точкой. Рекомендуется использовать с try…except.

type(value)

Возвращает тип значения (например, "string", "number").

enumerate(list_or_string)

Возвращает список пар [индекс, значение] — работает со списками и строками. Удобно сочетать с циклом for и множественным присваиванием:

fruits = ["яблоко", "груша", "слива"]
for pair in enumerate(fruits) do
    i, item = pair
    println(to_str(i) + ": " + item)
end

"my string".len()

Возвращает количество символов в строке.

"my string".upper()

Возвращает новую строку в верхнем регистре.

"my string".lower()

Возвращает новую строку в нижнем регистре.

" str ".strip()

Удаляет пробельные символы в начале и в конце строки.

"string".startswith(prefix)

Возвращает true, если строка начинается с prefix.

"string".endswith(suffix)

Возвращает true, если строка заканчивается на suffix.

"string".find(substring)

Ищет подстроку, возвращает индекс первого вхождения или -1.

"string".replace(old, new)

Заменяет все вхождения old на new.

"string".split(separator)

Разбивает строку на список строк по разделителю.

"string".join(list)

Объединяет список строк в одну строку с указанным разделителем.

my_list.len()

Возвращает количество элементов в списке.

my_list.append(item)

Добавляет элемент в конец списка.

my_list.pop()

Удаляет и возвращает последний элемент списка.

my_list.insert(index, item)

Вставляет элемент item на позицию index.

my_list.remove(item)

Удаляет первое вхождение элемента item.

my_list.index(item)

Возвращает индекс первого вхождения элемента item.

my_list.count(item)

Возвращает количество вхождений элемента item.

my_list.reverse()

Обращает порядок элементов в списке.

my_list.sort()

Сортирует элементы списка на месте.

my_list.clear()

Удаляет все элементы из списка.

my_dict.len()

Возвращает количество пар ключ-значение в словаре.

my_dict.keys()

Возвращает список всех ключей.

my_dict.values()

Возвращает список всех значений.

my_dict.items()

Возвращает список пар ключ-значение (в виде списков из двух элементов).

my_dict.get(key, default)

Возвращает значение по ключу или default, если ключ не найден.

my_dict.pop(key, default)

Удаляет ключ и возвращает его значение; если не найден — default или ошибка.

my_dict.popitem()

Удаляет и возвращает последнюю пару ключ-значение как список из двух элементов.

my_dict.clear()

Удаляет все элементы из словаря.

my_dict.update(other_dict)

Добавляет пары ключ-значение из other_dict.

my_dict.setdefault(key, default)

Возвращает значение ключа; если отсутствует — вставляет default и возвращает его.

Библиотека

Стандартная библиотека

Dark поставляется с набором встроенных модулей для типовых задач. Импортируйте модуль — import "os" — и вызывайте функции через точку: os.getcwd().

Модуль vsp210 от создателя

vsp210.history()

Возвращает историю создателя языка Dark.

vsp210.philosophy()

Возвращает философию языка Dark. (секретная функция)

vsp210.calculator()

Запускает калькулятор, написанный для примера.

vsp210.version()

Возвращает версию языка Dark.

vsp210.docs()

Отправляет пользователя на страницу документации языка Dark.

vsp210.telegram()

Отправляет пользователя в телеграм-канал создателя языка Dark.

Попробуйте сами. Наберите vsp210.philosophy() в REPL (dark --repl) — это не просто справка, а маленький диалог о самом языке.

Модуль http

http.get(url)

Выполняет HTTP GET-запрос и возвращает словарь с status_code, headers и body (сырой объект ответа — передайте его в http.json() или http.text()).

http.post(url, data, headers?)

Выполняет HTTP POST-запрос с телом data (словарь) и необязательным словарём заголовков headers. Возвращает словарь с status_code, headers и response (сырой объект ответа).

http.json(response)

Парсит объект ответа как JSON и возвращает словарь или список Dark. Если тело не валидный JSON — вызывается ошибка.

http.text(response)

Возвращает текст тела ответа.

На заметку. Обратите внимание: у http.get() объект ответа лежит в ключе body, а у http.post() — в ключе response. Это разные ключи, а не опечатка в примере ниже.
import "http"

result = http.get("https://api.example.com/data")
if result["status_code"] == 200 then
    data = http.json(result["body"])
    println(data)
end

Модуль math

math.sqrt(number)

Вычисляет квадратный корень числа.

math.pow(base, exp)

Вычисляет base в степени exp.

math.floor(number)

Возвращает наибольшее целое, меньшее или равное number.

math.ceil(number)

Возвращает наименьшее целое, большее или равное number.

math.pi()

Возвращает значение числа PI.

math.random(min, max)

Возвращает случайное целое число от min до max включительно.

math.randint(min, max)

То же самое, что math.random(min, max) — случайное целое число от min до max включительно.

На заметку. Раньше здесь была описана функция math.random_int() без аргументов, возвращающая дробное число — такой функции не существует. Актуальные сигнатуры выше.

Модуль os

os.getcwd()

Возвращает текущую рабочую директорию.

os.path_exists(path)

Проверяет, существует ли путь. Возвращает true или false.

os.mkdir(path)

Создаёт директорию.

os.rmdir(path)

Удаляет директорию.

os.remove(path)

Удаляет файл.

os.rename(old, new)

Переименовывает файл или директорию.

os.listdir(path)

Возвращает список содержимого директории.

os.getsize(path)

Возвращает размер файла.

os.isdir(path)

Проверяет, является ли путь директорией.

os.system(command)

Выполняет системную команду (например, "cls" или "clear").

os.exit(code)

Завершает выполнение программы. Сейчас переданный code не влияет на реальный код завершения процесса — можно вызывать и как os.exit().

Модуль stdlib

stdlib.range(start, stop)

Возвращает список чисел от start (включительно) до stop (не включительно).

stdlib.list_contains(list, item)

Проверяет, содержится ли item в list.

stdlib.list_join(list, separator)

Объединяет элементы списка в строку с указанным разделителем.

stdlib.dict_get(dict, key, default)

Получает значение из словаря по ключу, с возможностью указать значение по умолчанию.

stdlib.clamp(value, min, max)

Ограничивает значение value между min и max.

stdlib.json_decode(json_string)

Преобразует строку в формате JSON в словарь или список.

Чтение и запись файлов — не здесь: используйте модуль file.

stdlib.str_split(string, separator)

Разделяет строку по указанному разделителю и возвращает список.

stdlib.str_upper(string)

Преобразует строку в верхний регистр.

stdlib.str_lower(string)

Преобразует строку в нижний регистр.

stdlib.str_replace(string, old, new)

Заменяет все вхождения подстроки old на new.

Модуль time

time.time()

Возвращает текущее время в виде Unix timestamp (число секунд с 1 января 1970 года).

time.sleep(seconds)

Приостанавливает выполнение программы на указанное количество секунд.

Модуль file

Модуль для работы с файлами. file.open() возвращает файловый объект — его нужно передавать первым аргументом во все остальные функции модуля. Файлов можно держать открытыми одновременно сколько угодно, каждый со своим объектом.

Важно. Все функции ниже, кроме open, принимают файловый объект первым аргументом — например, file.read(f), а не file.read().

file.open(path, mode, encoding?)

Открывает файл и возвращает файловый объект. mode — строка: "r" (чтение), "w" (запись), "a" (дозапись), "r+" (чтение и запись). Необязательный третий аргумент — кодировка (например, "utf-8").

file.read(file_object)

Читает всё содержимое открытого файла и возвращает его как строку.

file.readline(file_object)

Читает одну строку из файла.

file.readlines(file_object)

Читает все строки из файла и возвращает их в виде списка.

file.write(file_object, content)

Записывает строку content в открытый файл.

file.seek(file_object, offset)

Перемещает позицию чтения/записи в файле на offset байт от начала.

file.close(file_object)

Закрывает ранее открытый файл.

Пример

f = file.open("notes.txt", "w")
file.write(f, "Привет из Dark!")
file.close(f)

f = file.open("notes.txt", "r")
println(file.read(f))
file.close(f)

Модуль color

Модуль для вывода цветного текста в консоль. Поддерживает именованные цвета, а также форматы RGB, HEX и HSL.

color.red() color.green() color.blue() color.yellow() color.cyan() color.magenta() color.white() color.black() color.orange() color.purple() color.pink() color.brown() color.gray() color.light_gray() color.dark_gray() color.light_blue() color.light_green() color.light_cyan() color.light_red() color.light_magenta() color.dark_red() color.dark_green() color.dark_blue() color.dark_yellow() color.dark_cyan() color.dark_magenta() color.dark_white() color.dark_black() color.dark_orange() color.dark_purple() color.dark_pink() color.dark_brown()

Функции с приставкой dark_ — дополнительные варианты для нескольких базовых цветов; сейчас часть из них (white, black, orange, purple, brown) визуально совпадает со своей базовой версией, кроме dark_pink — у него отдельный, более глубокий оттенок.

Каждая функция принимает один аргумент — текст, который нужно раскрасить, и возвращает строку с ANSI-кодами: color.red(text), color.orange(text) и т.д.

color.rgb(r, g, b, text)

Окрашивает текст в указанный RGB-цвет (компоненты от 0 до 255).

color.rgba(r, g, b, a, text)

Окрашивает текст в RGBA-цвет. Альфа-канал a в большинстве терминалов не поддерживается и игнорируется.

color.hex(hex_string, text)

Окрашивает текст в HEX-цвет (например, "#ff6496").

color.hsl(h, s, l, text)

Окрашивает текст в HSL-цвет (h: 0–360, s: 0–100, l: 0–100).

Модуль weather

Получение текущей погоды через WeatherAPI. Требует собственный API-ключ WeatherAPI.

weather.initialization(api_key)

Проверяет ключ и возвращает объект сессии — передавайте его в weather.get_weather(). Если ключ неверный, вызывается ошибка.

weather.get_weather(session, city)

Выполняет запрос погоды для города city и возвращает сырой объект HTTP-ответа — как и в модуле http, используйте http.json() или http.text(), чтобы получить данные из него.

import "weather"
import "http"

session = weather.initialization("ВАШ_API_KEY")
response = weather.get_weather(session, "Moscow")
data = http.json(response)
println(data)

Модуль python

Модуль для прямой интеграции с Python. Требует директиву #!USE_WITH_PYTHON в начале файла.

python.exec(code_string)

Выполняет код Python (переданный строкой) в текущем окружении Dark. Позволяет обмениваться переменными между Dark и Python — см. пример во вкладке «Синтаксис → Директивы».

Библиотека

Python-расширения

Одна из самых мощных возможностей Dark — подключение модулей, написанных на Python. Это открывает доступ ко всей экосистеме библиотек Python.

Структура проекта

Для использования расширений создайте папку dark_extensions в корне проекта и помещайте туда .py-файлы модулей.

my_project/
├── dark_extensions/
│   └── math_ext.py
├── my_script.dark
└── ...

Создание модуля-расширения

Каждый Python-файл расширения должен содержать функцию get_module(), возвращающую словарь: ключи — имена, доступные в Dark, значения — соответствующие функции или переменные Python.

Все функции, вызываемые из Dark, должны принимать один аргумент — список (list) переданных параметров.

Пример: dark_extensions/math_ext.py

import math

# Функция принимает список аргументов от Dark
def power(args):
    if len(args) != 2:
        raise TypeError("pow() expects 2 arguments")
    return math.pow(args[0], args[1])

# Эта функция будет вызвана интерпретатором Dark
def get_module():
    return {
        "pi": math.pi,      # Экспорт переменной
        "pow": power         # Экспорт функции
    }

Использование в Dark

Импортируйте расширение как обычный модуль и используйте его содержимое:

import "math_ext"

println("Число PI из Python: " + math_ext.pi)

# Вызываем функцию из Python, передавая аргументы
# В Python они придут как список [2, 8]
result = math_ext.pow(2, 8)
println("2 в степени 8 = " + result) # Выведет 256.0
Инструменты

Менеджер пакетов (dpm)

Начиная с версии 0.3.6 в Dark встроен менеджер пакетов dpm (Dark Package Manager) — установка, удаление и управление Python-расширениями для ваших проектов. dpm работает только внутри активированного виртуального окружения denv.

Все команды выполняются через флаг --dpm:

dark --dpm <команда> [аргументы]

install

Устанавливает один или несколько пакетов. dpm ищет на GitHub публичные репозитории с именем, начинающимся на Dark_.

# Установит пакет из репозитория с именем Dark_utils
dark --dpm install utils

uninstall

Удаляет пакет из вашего окружения.

dark --dpm uninstall utils

list

Показывает список всех пакетов, установленных в текущем denv.

dark --dpm list

freeze

Сохраняет список установленных пакетов в файл requirements.txt — стандартный способ зафиксировать зависимости проекта.

dark --dpm freeze

Файл requirements.txt позволяет установить все зависимости проекта одной командой — это делает проект переносимым и легко воспроизводимым на других машинах.

Создайте файл requirements.txt в корне проекта:

# requirements.txt
utils
requests_wrapper

Чтобы установить все пакеты из этого файла, выполните install без аргументов:

dark --dpm install

Вы можете легко поделиться своим расширением с сообществом.

  1. Создайте публичный репозиторий на GitHub. Его имя должно начинаться с префикса Dark_, например Dark_my_super_package.
  2. Структура репозитория. Внутри должна быть папка с именем, совпадающим с именем пакета (часть после Dark_), и в ней — файл __init__.py.
Dark_my_super_package/  (корень репозитория)
├── my_super_package/     (папка с кодом пакета)
│   ├── __init__.py
│   └── helpers.py
└── README.md

Содержимое __init__.py. Этот файл должен содержать функцию get_module(**kwargs), возвращающую словарь с экспортируемыми именами.

# Dark_my_super_package/my_super_package/__init__.py

def my_func(args):
    return "Hello from my package!"

def get_module(**kwargs):
    return {
        "hello": my_func
    }

После публикации репозитория любой пользователь сможет установить пакет командой: dark --dpm install my_super_package.

Инструменты

Аргументы запуска

Флаги командной строки интерпретатора dark.

--check
Проверяет синтаксис указанного файла без его выполнения. Полезно для быстрой проверки кода на ошибки.
dark --check my_script.dark
--compile (экспериментально)
Компилирует файл Dark в набор Python-файлов и, опционально, в нативный исполняемый файл через Nuitka.

На данный момент компиляция поддерживает большинство конструкций языка, но может не работать с некоторыми специфическими фичами — тестируйте на простых скриптах.

Флаги компиляции:

  • --out <путь> — каталог вывода компиляции (по умолчанию dark_py_build в рабочей директории). После генерации Python-кода вызывает Nuitka для сборки standalone-исполняемого файла.
  • --nonuitka — не создавать .exe-файл.
  • --nuitka-args="..." — дополнительные аргументы для Nuitka (оптимизации, исключения модулей и т.д.).

Поведение сборки:

  • <out_dir>/py_dark_code/ — копия внутреннего рантайма, необходимая для выполнения сгенерированного кода.
  • <out_dir>/<имя_скрипта>.py — сгенерированные Python-файлы.
  • При использовании Nuitka создаётся подпапка nuitka_build и итоговый дистрибутив в nuitka_build/*.dist/.
# Сгенерировать Python-код в папку ./build_output
dark --compile my_script.dark --out ./build_output

# Сгенерировать и собрать через Nuitka (требуется установленный пакет nuitka)
dark --compile my_script.dark --out ./build_output --nuitka-args="--onefile"
Требования. Для сборки нужен предустановленный компилятор C (например, MSVC на Windows). Компилятор копирует внутрь каталога вывода локальную реализацию py_dark_code, что делает сборку переносимой, и выводит индикатор прогресса при копировании и записи файлов.
--denv
Управляет виртуальными окружениями Dark (Dark Environment) — изолирует зависимости проектов.
# Создать новое виртуальное окружение в текущей директории
dark --denv denv

# Активировать существующее виртуальное окружение
source denv/bin/activate

# Деактивировать виртуальное окружение
deactivate
--parser
Запускает парсер Dark для указанного файла и выводит его абстрактное синтаксическое дерево (AST) в консоль. Полезно для отладки.
dark --parser my_script.dark
--version
Выводит текущую версию интерпретатора Dark.
dark --version
--help
Выводит справочную информацию по использованию интерпретатора и его аргументов.
dark --help
--repl
Запускает интерактивную консоль Dark (Read-Eval-Print Loop) — код можно вводить и выполнять построчно.
dark --repl
--dpm
Запускает менеджер пакетов Dark. Используется для установки, удаления и управления Python-расширениями — подробнее во вкладке «Менеджер пакетов (dpm)».
dark --dpm install my_package
run
Запускает файл, указанный в секции [project] файла denv.cfg. Работает только внутри активированного виртуального окружения denv.
dark run