Ce document presente la programmation avec multilingual en francais.
Il couvre les capacites du langage, le flux d'execution, les exemples pratiques, et les points d'extension.
multilingual permet d'ecrire du code dans plusieurs langues humaines, tout en conservant un modele semantique unique.
Concretement:
- vous ecrivez des mots-cles dans votre langue (ex.
soit,pour,dans,afficher); - le compilateur interne les mappe vers des concepts universels;
- le code est transpile en Python puis execute.
Les fichiers source du langage utilisent l'extension .ml (par exemple bonjour.ml).
Depuis la racine du projet:
pip install -r requirements.txt
# ou
pip install .# Anglais
print("Hello world")
# Francais
afficher("Bonjour le monde")
Lancer le REPL en francais:
multilingual repl --lang fr
# alternative dev/debug:
# python -m multilingualprogramming repl --lang frAfficher aussi le Python genere:
multilingual repl --lang fr --show-python
# alternative dev/debug:
# python -m multilingualprogramming repl --lang fr --show-pythonExecuter un fichier source (ex. bonjour.ml):
afficher("Bonjour le monde")
multilingual run bonjour.ml --lang fr
# alternative dev/debug:
# python -m multilingualprogramming run bonjour.ml --lang frsoit total = 0
soit nom = "Alice"
Sortie attendue: aucune sortie directe (variables initialisees).
si total > 0:
afficher("positif")
sinon:
afficher("nul ou negatif")
Sortie attendue (si total = 0): nul ou negatif
soit somme = 0
pour i dans intervalle(5):
somme = somme + i
afficher(somme)
Sortie attendue: 10
déf carre(x):
retour x * x
afficher(carre(6))
Sortie attendue: 36
soit valeurs = [10, 20, 30, 40]
afficher(valeurs[1:3])
afficher(valeurs[::-1])
Sortie attendue:
[20, 30][40, 30, 20, 10]
soit carres = [x * x pour x dans intervalle(6)]
afficher(carres)
Sortie attendue: [0, 1, 4, 9, 16, 25]
Le pipeline prend en charge:
- classes (exemple):
classe Compteur:
déf __init__(soi, depart):
soi.valeur = depart
déf incrementer(soi):
soi.valeur = soi.valeur + 1
retour soi.valeur
soit c = Compteur(10)
afficher(c.incrementer())
Sortie attendue: 11
- imports (exemple):
importer math
soit rayon = 3
soit surface = math.pi * rayon * rayon
afficher(surface)
Sortie attendue: environ 28.2743338823
- assertions (exemple):
soit resultat = somme([1, 2, 3])
affirmer resultat == 6
afficher("test ok")
Sortie attendue: test ok (sinon erreur d'assertion si la condition est fausse).
-
autres capacites avancees:
-
affectations chainees (exemple):
a = b = c = 7
afficher(a, b, c)
Sortie attendue: 7 7 7
- deconstruction de tuples (exemple):
soit point = (4, 9)
soit x, y = point
afficher(x, y)
Sortie attendue: 4 9
- parametres par defaut,
*args,**kwargs(exemple):
déf decrire(nom, role="developpeur", *competences, **meta):
afficher("Nom:", nom)
afficher("Role:", role)
afficher("Competences:", competences)
afficher("Meta:", meta)
decrire("Nina", "ingenieure", "python", "tests", equipe="plateforme", senior=True)
Sortie attendue (exemple):
-
Nom: Nina -
Role: ingenieure -
Competences: ('python', 'tests') -
Meta: {'equipe': 'plateforme', 'senior': True} -
decorateurs (exemple):
déf tracer(fn):
déf wrapper(*args, **kwargs):
afficher("appel de", fn.__name__)
retour fn(*args, **kwargs)
retour wrapper
@tracer
déf addition(a, b):
retour a + b
afficher(addition(2, 5))
Sortie attendue:
-
appel de addition -
7 -
f-strings (exemple):
soit nom = "Amina"
soit score = 95
afficher(f"{nom} a obtenu {score}%")
Sortie attendue: Amina a obtenu 95%
- chaines multilignes / triple quotes (exemple):
soit message = """Ligne 1
Ligne 2
Ligne 3"""
afficher(message)
Sortie attendue:
Ligne 1
Ligne 2
Ligne 3
- annotations de type (variables, parametres, retour):
soit age: entier = 42
déf saluer(nom: chaine) -> chaine:
retour f"Bonjour {nom}"
Sortie attendue (exemple): Bonjour Alice pour afficher(saluer("Alice")).
Note: les deux formes chaine et chaîne sont acceptees.
- litteraux d'ensemble (
set):
soit uniques = {1, 2, 2, 3}
afficher(uniques)
Sortie attendue: un ensemble contenant 1, 2, 3 (ordre non garanti).
avecavec plusieurs gestionnaires de contexte:
avec open("a.txt") comme a, open("b.txt") comme b:
afficher(a.read(), b.read())
Sortie attendue: contenu des deux fichiers, avec fermeture des deux contextes.
Note: certains built-ins et methodes Python restent sous leur nom universel
(par exemple open, read).
- depliage de dictionnaires:
soit base = {"langue": "fr", "niveau": "intermediaire"}
soit extra = {"niveau": "avance", "theme": "tests"}
soit profil = {**base, **extra}
afficher(profil)
Sortie attendue: {'langue': 'fr', 'niveau': 'avance', 'theme': 'tests'}.
- litteraux numeriques hex/octal/binaire et notation scientifique:
soit hexa = 0xFF
soit octal = 0o77
soit binaire = 0b1010
soit petit = 1.5e-3
afficher(hexa, octal, binaire, petit)
Sortie attendue: 255 63 10 0.0015.
- programmation asynchrone (
async/await):
importer asyncio
asynchrone déf telecharger(url: chaine) -> chaine:
retour f"contenu simulé pour {url}"
asynchrone déf lire(url: chaine) -> chaine:
retour attendre telecharger(url)
afficher(asyncio.run(lire("https://exemple.fr")))
Sortie attendue: contenu simulé pour https://exemple.fr.
Note: attendre (await) est valide uniquement dans une fonction asynchrone.
- operateur walrus (
:=):
soit resultat = (n := 10) + 5
afficher(n, resultat)
Sortie attendue: 10 15.
Certains built-ins universels ont des alias localises. Exemples frequents:
intervalle(...)pourrange(...)longueur(...)pourlen(...)somme(...)poursum(...)afficher(...)pour l'affichage
Les noms universels Python restent utilisables en parallele.
Le fichier examples/complete_features_fr.ml montre un scenario couvrant
plusieurs capacites combinees dans un seul programme.
- import avance avec alias:
importer math
depuis math importer sqrt comme root_fn
- boucle
tantque:
soit compteur = 0
tantque compteur < 2:
compteur = compteur + 1
- logique booleenne localisee:
soit drapeau_ok = Vrai et non Faux
affirmer drapeau_ok
- gestion d'exceptions (
essayer/sauf/finalement):
essayer:
soit racine = root_fn(16)
sauf Exception comme erreur_geree:
soit racine = 0
finalement:
afficher(racine)
- test d'identite avec
Rien:
afficher(total_acc est Rien)
Pour reproduire exactement cet exemple:
multilingual run examples/complete_features_fr.ml --lang fr
# alternative dev/debug:
# python -m multilingualprogramming run examples/complete_features_fr.ml --lang fr:helpafficher l'aide:language frforcer la langue francaise:pythonactiver/desactiver l'affichage du Python genere:watactiver/desactiver l'affichage du code WAT (WebAssembly Text) genere (alias:wasm):rustactiver/desactiver l'affichage du bridge Rust/Wasmtime genere (alias:wasmtime):resetvider l'etat de la session:kw [XX]lister les mots-cles:ops [XX]lister les symboles et operateurs:qquitter
Drapeaux de demarrage equivalents :
multilingual repl --lang fr --show-python # afficher Python au demarrage
multilingual repl --lang fr --show-wat # afficher WAT au demarrage
multilingual repl --lang fr --show-rust # afficher Rust/Wasmtime au demarrageLe flux est identique pour toutes les langues:
Lexertokenize le code source Unicode.Parserconstruit un AST.SemanticAnalyzervalide portees, symboles et coherence.PythonCodeGeneratorgenere du Python executable.ProgramExecutorlance l'execution avec les built-ins runtime.
Ce design permet d'ajouter des langues sans reecrire parser/codegen.
Points d'entree principaux:
from multilingualprogramming import (
Lexer,
Parser,
SemanticAnalyzer,
PythonCodeGenerator,
ProgramExecutor,
REPL,
KeywordRegistry,
)Signatures des constructeurs importants:
# Lexer : source est le premier argument positionnel (pas un argument nommé)
lexer = Lexer(source_code, language="fr") # correct
# lexer = Lexer(language="fr") # TypeError — source manquant
# ProgramExecutor : language doit être passé à __init__, pas à transpile/execute
executor = ProgramExecutor(language="fr")
python_code = executor.transpile(source_code) # correct
# executor = ProgramExecutor()
# executor.transpile(source_code, language="fr") # TypeErrorAutres modules utiles:
- numeriques:
MPNumeral,UnicodeNumeral,RomanNumeral,ComplexNumeral,FractionNumeral; - date/heure:
MPDate,MPTime,MPDatetime; - inspection AST:
ASTPrinter.
soit base = [1, 2, 3, 4, 5]
soit pairs = [x pour x dans base si x % 2 == 0]
déf moyenne(liste):
retour somme(liste) / longueur(liste)
si longueur(pairs) > 0:
afficher("Pairs:", pairs)
afficher("Moyenne:", moyenne(pairs))
sinon:
afficher("Aucune valeur paire")
Sortie attendue:
Pairs: [2, 4]Moyenne: 3.0
- Utiliser un seul style lexical par fichier (francais ou autre) pour garder le code lisible.
- Verifier les mots-cles disponibles via
:kw fr. - Activer
--show-pythonau debug pour comprendre la transpilation. - Ecrire des tests de bout en bout avec
ProgramExecutorpour valider la semantique.
language doit etre passe au constructeur (__init__), pas a transpile() ou execute():
# Correct
executor = ProgramExecutor(language="fr")
python_code = executor.transpile(source_code)
result = executor.execute(source_code)
# Incorrect — provoque un TypeError
executor = ProgramExecutor()
executor.transpile(source_code, language="fr") # TypeError- Mots-cles complets (tous les mots-cles + alias built-ins): mots_cles.md
- Modules et projets multi-fichiers (packages, imports, tests): modules.md
- Backends WAT/WASM (
:wat,:rust, playground): wasm.md - Guide usage: USAGE.md
- Reference technique: README docs
- Vue design (architecture + roadmap): design.md
- Onboarding nouvelles langues: language_onboarding.md