Modules système intégrés

TON618 est livré avec douze modules système intégrés. Ce ne sont pas des fichiers sur le disque — ils vivent dans l'interpréteur — mais tu les importes quand même avec IMPORT://ton.<nom> avant de les utiliser, exactement comme un module utilisateur :

IMPORT://ton.sys
IMPORT://ton.os
IMPORT://ton.requests
IMPORT://ton.random
IMPORT://ton.time
IMPORT://ton.json
IMPORT://ton.mathutils
IMPORT://ton.strings
IMPORT://ton.encoding
IMPORT://ton.regex
IMPORT://ton.path
IMPORT://ton.tensor

Appeler une des fonctions ci-dessous sans d'abord importer son module échoue avec une erreur "undefined function" — c'est voulu : un script ne paie (et n'expose) que les fonctions intégrées qu'il a effectivement demandées. Chaque module suit la convention de nommage recommandée pour les modules utilisateur ci-dessus : chaque fonction est préfixée par le nom du module lui-même.

#ton.sys — informations sur l'exécution & le processus

FonctionDescription
sys_args()Tableau des arguments de ligne de commande passés après le chemin du script (ton618 script.ton foo bar → ["foo", "bar"])
sys_platform()"windows", "termux", "macos", ou "linux" — détecté automatiquement (Termux est distingué d'un Linux classique via la variable d'environnement $PREFIX)
sys_arch()"x64", "arm64", "arm", "x86", ou "unknown"
sys_version()La version de l'interpréteur lui-même (ex. "beta-1.0.1"), identique à ton618 --version
sys_exit(code)Arrête immédiatement tout le programme avec le code de sortie donné
sys_sleep(ms)Met en pause l'exécution pendant le nombre de millisecondes donné

#ton.os — variables d'environnement & système de fichiers

FonctionDescription
os_name()"nt" sur Windows, "posix" ailleurs
os_getenv(nom)La valeur d'une variable d'environnement, ou nil si absente
os_setenv(nom, valeur)Définit une variable d'environnement pour ce processus ; renvoie si ça a réussi
os_cwd()Le dossier de travail actuel
os_exists(chemin)Si un fichier ou dossier existe
os_isfile(chemin) / os_isdir(chemin)Si chemin existe et est ce genre d'entrée
os_mkdir(chemin)Crée un dossier (et les dossiers parents manquants)
os_remove(chemin)Supprime un fichier ou un dossier vide
os_rename(src, dst)Renomme/déplace un fichier ou dossier
os_copy(src, dst)Copie un fichier, en écrasant dst s'il existe déjà
os_listdir(chemin)Tableau des noms d'entrées directement dans un dossier (non récursif)
os_readlines(chemin)Tableau des lignes du fichier (sans retours à la ligne finaux)
os_appendfile(chemin, contenu)Ajoute du texte à un fichier, le créant si besoin
os_tempdir()Le dossier temporaire du système

#ton.requests — un client HTTP minimal

Un petit client HTTP sans dépendance (sockets bruts, même esprit que le serveur intégré). Limitation : http:// seulement, pas de TLS/https:// — il n'y a pas de bibliothèque SSL embarquée, donc il peut parler à des services locaux, d'autres serveurs TON618, ou n'importe quel point d'accès HTTP simple, mais pas à une API exclusivement HTTPS.

FonctionDescription
requests_get(url)Effectue une requête GET
requests_post(url, [corps])Effectue une requête POST avec un corps chaîne optionnel
requests_request(methode, url, [corps])Effectue une requête avec n'importe quelle méthode HTTP

Les trois renvoient un ton.dict de même forme :

{
    ok: true,      // si une réponse a été reçue du tout
    status: 200,     // le code de statut HTTP (0 si la requête a totalement échoué)
    body: "...",       // le corps brut de la réponse
    error: ""            // une raison lisible quand ok est faux
}
IMPORT://ton.requests

ton.dict res = requests_get("http://localhost:8081/api/users")
if res["ok"] {
    print("Status: " + str(res["status"]))
    print(res["body"])
} else {
    print("Requête échouée : " + res["error"])
}

#ton.random — outils de hasard supplémentaires

Complète le random() toujours disponible avec quelques motifs courants :

FonctionDescription
random_int(min, max)Un entier dans [min, max], inclusif des deux côtés
random_float()Un flottant dans [0, 1)
random_choice(arr)Un élément uniformément aléatoire d'un tableau non vide
random_shuffle(arr)Mélange un tableau en place (Fisher-Yates) et le retourne
random_seed(n)Réamorce le générateur aléatoire de façon déterministe — utile pour des tests reproductibles

#ton.time — horloges & timestamps

FonctionDescription
time_now()Secondes depuis l'epoch Unix
time_millis()Millisecondes depuis l'epoch Unix — pratique pour mesurer un temps écoulé
time_string([timestamp])Une chaîne d'heure locale lisible ; par défaut maintenant
time_sleep(ms)Met en pause l'exécution pendant le nombre de millisecondes donné (identique à sys_sleep)

#ton.json — parsing JSON & affichage indenté

Le json(x) toujours disponible transforme déjà une valeur en JSON compact. IMPORT://ton.json ajoute l'autre sens, plus un format multi-lignes :

FonctionDescription
json_parse(texte)Parse une chaîne JSON en ton.dict/ton.array/scalaire
json_stringify(valeur)Identique à json(valeur), fourni sous un nom cohérent pour les scripts qui importent ce module
json_pretty(valeur)Identique à json_stringify, indenté sur plusieurs lignes pour une sortie lisible
IMPORT://ton.json
IMPORT://ton.requests

ton.dict res = requests_get("http://localhost:8081/api/users")
ton.array users = json_parse(res["body"])
print(len(users))

#ton.mathutils — trigonométrie, logs & stats

Complète les sqrt/pow/abs/floor/ceil/round/min/max toujours disponibles avec trigonométrie, logarithmes, et petits outils de statistiques/théorie des nombres :

FonctionDescription
mathutils_pi() / mathutils_e()Les constantes π et e
mathutils_sin/cos/tan(x), mathutils_asin/acos/atan(x), mathutils_atan2(y, x)Trigonométrie, en radians
mathutils_log(x) / mathutils_log2(x) / mathutils_log10(x) / mathutils_exp(x)Logarithmes naturel, base-2, base-10, et e^x
mathutils_hypot(x, y)sqrt(x*x + y*y), calculé sans dépassement
mathutils_degrees(rad) / mathutils_radians(deg)Conversion d'unité d'angle
mathutils_clamp(x, lo, hi)Restreint x à [lo, hi]
mathutils_lerp(a, b, t)Interpolation linéaire entre a et b à t (0..1)
mathutils_sign(x)-1, 0, ou 1
mathutils_gcd(a, b) / mathutils_lcm(a, b)PGCD / PPCM de deux entiers
mathutils_factorial(n)n! pour un entier non-négatif n
mathutils_is_prime(n)true si n est premier
mathutils_sum(arr) / mathutils_mean(arr) / mathutils_median(arr) / mathutils_stddev(arr)Somme, moyenne, médiane, et écart-type d'un tableau numérique
mathutils_min_of(arr) / mathutils_max_of(arr)Plus petit/grand nombre d'un tableau (contrairement à min()/max(), qui prennent des arguments séparés)
IMPORT://ton.mathutils

print(mathutils_gcd(48, 18))          // 6
print(mathutils_mean([1, 2, 3, 4]))   // 2.5
print(mathutils_clamp(15, 0, 10))     // 10

#ton.strings — aides supplémentaires sur les chaînes

Complète les upper/lower/trim/split/replace/contains/substring toujours disponibles :

FonctionDescription
strings_starts_with(s, prefixe) / strings_ends_with(s, suffixe)Tests de préfixe/suffixe
strings_repeat(s, n)Répète s n fois
strings_reverse(s)Inverse une chaîne (le reverse() toujours disponible ne marche que sur les tableaux)
strings_capitalize(s)Met en majuscule la première lettre, en minuscule le reste
strings_pad_left(s, largeur, [car]) / strings_pad_right(s, largeur, [car])Complète s jusqu'à largeur avec car (" " par défaut)
strings_center(s, largeur, [car])Centre s dans largeur, en complétant des deux côtés avec car
strings_count(s, sous)Nombre d'occurrences non chevauchantes de sous dans s
strings_trim_start(s) / strings_trim_end(s)Supprime les espaces seulement au début/à la fin de s (trim() supprime les deux)
strings_words(s)Tableau des mots séparés par des espaces (contrairement à split(), qui a besoin d'un séparateur exact)
strings_replace_first(s, recherche, remp)Remplace seulement la première occurrence de recherche
strings_snake_case(s)"Hello World" → "hello_world"
strings_camel_case(s)"hello_world" → "helloWorld"
IMPORT://ton.strings

print(strings_capitalize("hello world"))  // "Hello world"
print(strings_pad_left("7", 3, "0"))      // "007"

#ton.encoding — base64, hex, et encodage URL

Encodeurs/décodeurs sans dépendance pour les formats dont les scripts ont le plus souvent besoin en parlant à des API web :

FonctionDescription
base64_encode(s) / base64_decode(s)Base64 standard
hex_encode(s) / hex_decode(s)Hexadécimal en minuscules
url_encode(s) / url_decode(s)Encodage pourcentage (aussi utilisé en interne pour parser la query string d'une requête du serveur local)
IMPORT://ton.encoding

print(base64_encode("hello world"))  // aGVsbG8gd29ybGQ=
print(url_encode("a b/c"))            // a%20b%2Fc

#ton.regex — recherche de motifs

Reposant sur la bibliothèque standard <regex> de C++ (syntaxe ECMAScript) — pas de dépendance externe, et la même variante de regex que JavaScript.

FonctionDescription
regex_test(s, motif)Si motif correspond quelque part dans s
regex_match(s, motif)[correspondanceComplète, groupe1, groupe2, ...] pour la première correspondance, ou nil
regex_find_all(s, motif)Tableau de toutes les correspondances complètes trouvées dans s
regex_replace(s, motif, remp)s avec chaque correspondance remplacée ; remp peut utiliser $1, $2... pour les groupes capturés
regex_split(s, motif)Tableau de sous-chaînes, en découpant s à chaque correspondance
IMPORT://ton.regex

print(regex_test("hello123", "[0-9]+"))                          // true
print(regex_replace("2024-01-15", "(\\d+)-(\\d+)-(\\d+)", "$3/$2/$1"))  // 15/01/2024

#ton.path — manipulation de chemins de fichiers

Manipulation de chaînes/chemins pure — aucun accès disque (voir ton.os pour ça).

FonctionDescription
path_join(a, b, ...)Assemble n'importe quel nombre de segments de chemin avec le séparateur de la plateforme
path_basename(p)Le nom de fichier avec son extension
path_dirname(p)Le dossier parent
path_extension(p)L'extension avec le point, ou "" si aucune
path_stem(p)Le nom de fichier sans son extension
path_absolute(p)Un chemin absolu (résolu par rapport au dossier de travail actuel)
IMPORT://ton.path

print(path_join("a", "b", "c.txt"))     // a/b/c.txt
print(path_extension("/foo/bar.txt"))    // .txt

#ton.tensor — petits tableaux numériques 1D/2D pour du ML basique

Un tenseur est un ton.dict avec deux champs — {shape: [...], data: [...]} (data est plat, ordre ligne par ligne) — donc il s'affiche, se str()-ise et se json()-ise comme n'importe quel dict. Les fonctions ci-dessous implémentent les opérations élément-par-élément/matmul/réduction en vraies boucles C++ (sans repasser par l'AST), un vrai gain de vitesse par rapport à la même boucle écrite à la main en TON618 — mais lis les limites honnêtes ci-dessous avant de construire quoi que ce soit d'ambitieux dessus. Cette même convention {shape, data} est celle sur laquelle le module communautaire atome (un simple fichier .ton, pas une partie de l'interpréteur — voir ton618 install atome) construit sa couche d'autodiff/entraînement.

FonctionDescription
tensor_zeros(shape) / tensor_ones(shape) / tensor_full(shape, valeur)Un nouveau tenseur de la forme donnée (1 ou 2 dimensions), rempli
tensor_random(shape, [lo=0, hi=1])Un nouveau tenseur rempli de valeurs aléatoires uniformes dans [lo, hi) (utilise le même RNG que random()/ton.random — seed avec random_seed() pour des runs reproductibles)
tensor_from_array(arr)Construit un tenseur depuis un tableau plat (1D) ou un tableau de tableaux de même longueur (2D)
tensor_to_array(t)L'inverse : un ton.array classique (imbriqué pour du 2D)
tensor_shape(t) / tensor_size(t)Le tableau de forme / le nombre total d'éléments
tensor_clone(t)Une copie profonde — t et ses champs dict/array sont sinon des références partagées comme n'importe quel dict, donc muter un alias mute tous les autres
tensor_reshape(t, nouvelleForme)Un nouveau tenseur vue des mêmes données avec une forme différente (le nombre d'éléments doit correspondre)
tensor_get(t, indices) / tensor_set(t, indices, valeur)Lit/écrit un élément — indices est [i] en 1D, [ligne, colonne] en 2D
tensor_add(a, b) / tensor_sub(a, b) / tensor_mul(a, b) / tensor_div(a, b)Élément par élément ; un côté peut être un nombre simple (diffusion scalaire), mais deux tenseurs doivent avoir la même forme — il n'y a pas de diffusion façon NumPy entre tenseurs de formes différentes
tensor_add_bias(mat, bias)Ajoute un biais 1D à chaque ligne d'une matrice 2D — la seule exception délibérée à "pas de diffusion", exactement ce dont une couche dense/linéaire a besoin
tensor_matmul(a, b)Multiplication matricielle 2D (a en m×k, b en k×n, résultat en m×n)
tensor_transpose(t)Transposition 2D
tensor_sum(t) / tensor_mean(t) / tensor_max(t) / tensor_min(t)Réduit tous les éléments à un seul nombre (pas de réduction par axe)
tensor_relu(t) / tensor_sigmoid(t) / tensor_tanh(t) / tensor_exp(t) / tensor_log(t)Fonctions d'activation/maths élément par élément
tensor_softmax(t)Softmax sur tout le vecteur (1D) ou ligne par ligne (2D)
tensor_relu_grad(entree) / tensor_sigmoid_grad(sortie) / tensor_tanh_grad(sortie)Dérivées élément par élément pour de la rétropropagation faite à la main — sigmoid_grad/tanh_grad prennent la sortie de cette fonction (moins cher à exprimer ainsi), tandis que relu_grad prend son entrée
tensor_map(t, fn)Applique une ton.function/expression de fonction à chaque élément — plus lent que les natives ci-dessus (un appel interpréteur par élément) mais marche avec n'importe quelle fonction scalaire personnalisée
tensor_argmax(t)L'index de l'élément le plus grand (1D), ou un index par ligne (2D) — l'opération "quelle classe ça a prédit"
tensor_conv1d(signal, noyau, [pas=1])Convolution 1D "valid" (corrélation croisée) sur des tenseurs 1D à un seul canal : out[i] = somme_j signal[i*pas+j] * noyau[j] — voir le module communautaire atome pour comment des couches Conv1D multi-canaux (et leur gradient) sont construites à partir de cette primitive
tensor_to_bytes(t)Empaquette les données du tenseur en octets bruts IEEE-754 float64 (endianness native), renvoyés sous forme de ton.string — combiné à writefile (qui écrit les octets exacts d'une chaîne), ça permet à un module d'écrire de vrais fichiers binaires plutôt que du JSON texte. Pas portable entre machines d'endianness différente
tensor_from_bytes(octets, forme)L'inverse de tensor_to_bytes — décode une chaîne d'octets bruts (ex. depuis readfile + substring) en un tenseur de la forme donnée ; erreur si la longueur en octets ne correspond pas au nombre d'éléments de forme × 8
IMPORT://ton.tensor

ton.dict a = tensor_from_array([[1, 2], [3, 4]])
ton.dict b = tensor_from_array([[5, 6], [7, 8]])
print(tensor_to_array(tensor_matmul(a, b)))   // [[19, 22], [43, 50]]
print(tensor_to_array(tensor_relu(tensor_from_array([-1, 0, 2]))))  // [0, 0, 2]

Limites honnêtes — à lire avant de construire quoi que ce soit d'ambitieux sur ton.tensor :

  • CPU uniquement. Il n'y a aucun backend de calcul GPU (pas de bindings CUDA/OpenCL) nulle part dans cet interpréteur, et ça ne changera pas — le "support GPU" n'est pas quelque chose qu'un module .ton peut ajouter tout seul.
  • Formes 1D et 2D seulement — pas de tenseurs 3D+ (donc pas de batchs d'images, pas de tenseurs façon têtes d'attention, etc. sans les astuces d'aplatissement/reshape faites toi-même).
  • Seulement une diffusion scalaire (plus l'exception explicite tensor_add_bias ci-dessus) — tenseur + tenseur-de-forme-différente (diffusion façon NumPy) ne marche pas.
  • Pas d'autodiff intégré. ton.tensor te donne les opérations forward et les helpers _grad correspondants pour construire la rétropropagation à la main — il n'y a pas de suivi automatique du graphe de calcul. Voir le module communautaire atome (ton618 install atome) pour une couche d'autodiff/entraînement construite à partir de zéro sur cette base.
  • Pas du tout compétitif avec une vraie bibliothèque numérique. Ce sont toujours des boucles C++ sur un tableau de Value typé dynamiquement — un vrai travail pour un petit langage, mais loin des performances BLAS/cuDNN. Bien pour apprendre, des modèles jouets, et de petites expériences ; pas pour entraîner quoi que ce soit à échelle réelle.

Modifier cette page sur GitHub