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
| Fonction | Description |
|---|---|
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
| Fonction | Description |
|---|---|
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.
| Fonction | Description |
|---|---|
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 :
| Fonction | Description |
|---|---|
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
| Fonction | Description |
|---|---|
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 :
| Fonction | Description |
|---|---|
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 :
| Fonction | Description |
|---|---|
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 :
| Fonction | Description |
|---|---|
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 :
| Fonction | Description |
|---|---|
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.
| Fonction | Description |
|---|---|
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).
| Fonction | Description |
|---|---|
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.
| Fonction | Description |
|---|---|
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
.tonpeut 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_biasci-dessus) —tenseur + tenseur-de-forme-différente(diffusion façon NumPy) ne marche pas. - Pas d'autodiff intégré.
ton.tensorte donne les opérations forward et les helpers_gradcorrespondants pour construire la rétropropagation à la main — il n'y a pas de suivi automatique du graphe de calcul. Voir le module communautaireatome(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
Valuetypé 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.