8.8 KiB
2. Principes généraux du langage
2.1 Philosophie — V1 REQUIS — FIGÉ
Saselang vise un langage :
- fortement et statiquement typé ;
- explicite ;
- lisible ;
- déterministe ;
- performant ;
- portable ;
- avec peu de magie ;
- sans complexité cachée de type C++ ;
- sans exposition systématique à l'utilisateur d'un modèle de lifetimes façon Rust ;
- sans garbage collector obligatoire pour les cibles natives ;
- sans retours implicites ;
- sans préprocesseur textuel ;
- sans multiplication de syntaxes synonymes.
Principe directeur :
boring but working : une règle stable et prévisible vaut mieux qu'une syntaxe plus courte mais ambiguë.
Lorsqu'une forme légèrement plus longue supprime un implicite ou une ambiguïté réelle, Saselang privilégie l'explicite. La concision n'est pas un objectif supérieur à la lisibilité du contrat.
2.2 Mots-clés — V1 REQUIS — FIGÉ
Les mots-clés du langage sont en anglais.
La documentation de référence peut exister en français et en anglais.
Les mots utilisés par Saselang, les mots réservés pour une évolution future et une liste reserved-foreign issue des grands langages restent interdits comme identifiants utilisateur. Ces catégories peuvent recevoir des diagnostics différents sans changer cette interdiction.
dowhile, elseif et in sont des mots-clés actifs Saselang. La forme historique do ... while n'existe pas ; do reste néanmoins interdit comme identifiant et appartient à reserved-foreign. elif est également interdit/réservé comme mot étranger : Saselang utilise uniquement elseif. Les mots historiques ou étrangers correspondant à des doublons rejetés tels que until, repeat, unless ou loop restent réservables dans reserved-foreign sans recevoir de sémantique Saselang.
2.3 Une sémantique par concept — V1 REQUIS — FIGÉ
Saselang évite les alias syntaxiques ne produisant aucune différence sémantique réelle.
Exemples actuellement rejetés :
and comme alias de &&
or comme alias de ||
=== en plus de l'identité explicite
++ et --
ternaire ?: si les formes productrices de `match`/`if` avec `emit` couvrent le besoin
Deux formes ne coexistent que lorsqu'elles représentent réellement des comportements différents, par exemple :
&& / || short-circuit
& / | / ^ logique eager sur bool
2.4 Sémantique indépendante du target — V1 REQUIS — FIGÉ
Une cible peut changer la représentation physique d'un type, jamais sa signification observable.
Lorsqu'une capacité n'existe pas sur une cible, le compilateur ou le resolver doit produire une erreur explicite plutôt que modifier silencieusement la sémantique.
2.5 Encodage lexical et ASCII du code — V1 REQUIS — FIGÉ
Les fichiers source Saselang sont encodés en UTF-8.
Le code lexicalement significatif reste ASCII :
keywords
identifiers
numeric literals
operators
punctuation
syntactic whitespace
namespace syntax
Unicode est autorisé dans les zones dont le contenu textuel le justifie :
String literals
char literals
ordinary comments
Saseldoc comments
Un identifiant accentué ou un whitespace Unicode non ASCII placé dans le code est une erreur. Saselang n'accepte notamment pas les espaces insécables, espaces fines ou caractères Unicode ressemblant visuellement à une ponctuation ASCII comme substituts syntaxiques.
Le BOM UTF-8 est accepté uniquement au tout début du fichier et ignoré. Il n'est jamais requis. Le formatter officiel peut produire des fichiers sans BOM comme représentation canonique.
Les fins de ligne physiques LF, CRLF et CR sont acceptées et normalisées lexicalement en une même notion de fin de ligne.
Le whitespace syntaxique autorisé est limité à :
U+0020 SPACE
U+0009 TAB
U+000A LF
U+000D CR
Indentation et retours à la ligne n'ont aucune signification grammaticale. Un programme Saselang valide peut, hors contenu textuel significatif, être écrit sur une seule ligne.
Un caractère NUL brut dans le fichier source est interdit hors représentation valide dans un littéral.
2.6 Identifiants — V1 REQUIS — FIGÉ
Les identifiants utilisateur sont ASCII, sensibles à la casse et suivent la forme générale :
[A-Za-z_][A-Za-z0-9_]*
Saselang n'impose pas camelCase, PascalCase, snake_case ou UPPER_SNAKE_CASE aux fonctions, méthodes, variables, constantes, paramètres ou membres. Les outils officiels, formatter compris, ne doivent pas renommer automatiquement les identifiants pour imposer un style.
La seule contrainte de casse structurelle est celle des types nominaux non primitifs : leur premier caractère doit être une lettre ASCII majuscule.
Les identifiants commençant par deux underscores sont réservés au compilateur, au runtime et au tooling Saselang :
_value // utilisateur autorisé
__value // réservé interne
Les raw/escaped identifiers destinés à contourner un mot réservé sont interdits : pas de backticks ni de forme équivalente à r#identifier.
2.7 Ponctuation et tokenisation — V1 REQUIS — FIGÉ EN PRINCIPE
La ponctuation ASCII utilisée ou réservée est traitée explicitement par le lexer. Les caractères Unicode ressemblants ne sont jamais des alias.
Les principaux rôles V1 sont notamment :
( ) grouping, calls, control headers, parameters
[ ] indexing et constructions définies par leur grammaire
{ } blocks et constructions à accolades
; fin d'un statement ou d'une déclaration sans corps
, séparation de deux éléments ; séparateur de listes init/update dans for
. qualification de namespace
:: qualification de membre/symbole
=> séparateur grammatical pattern -> bloc dans match
= assignment
+ - * / % arithmetic
& | ^ ~ bitwise/logical selon type ; | sépare aussi les alternatives d'un pattern
! logical negation / !=
< > comparaison, shifts et syntaxe générique selon contexte
.. famille de délimiteurs de Range, avec >.., ..< et >..<
' char delimiter
" String delimiter
_ identifiant / séparateur numérique / wildcard de pattern selon contexte
Les caractères suivants restent disponibles/réservés lorsqu'ils n'ont pas déjà un rôle lexical précis :
# raw-string delimiter et shebang autorisé seulement selon sa règle dédiée
@ réservé hors commentaires/Saseldoc
$ réservé, notamment pendant la finalisation de l'interpolation
? réservé sans sémantique V1 encore attribuée
` réservé/interdit à l'utilisateur
\ uniquement selon les règles d'escape des littéraux
Le ? est réservé sans recevoir de sémantique avant la fermeture du groupe Option/Nullable/propagation d'erreur.
Le lexer applique la règle du plus long token valide (longest match) pour les séquences définies telles que >>=, <<=, ::, !=, &&, etc. Cette règle ne crée jamais un opérateur inexistant.
Les commentaires et les littéraux sont reconnus avant d'interpréter leur contenu comme ponctuation ou opérateurs.
Dans un contexte générique, le parser peut interpréter une séquence lexicale telle que >> comme deux fermetures > lorsque la grammaire l'exige, afin d'autoriser par exemple :
Map<String,List<int32>>
sans espace artificiel.
2.8 Diagnostics de style et lints — V1 REQUIS — FIGÉ EN PRINCIPE
Le compilateur Saselang distingue les erreurs de correction/sémantique des observations de qualité de code.
Par défaut, une construction valide n'est pas signalée simplement parce qu'une valeur, une variable locale, un paramètre ou un item privé n'est jamais réutilisé. Par exemple :
{
int32 myvar = 42;
}
est valide sans warning obligatoire, même si myvar disparaît à la fin du bloc sans avoir été lu.
Les diagnostics tels que unused local, unused parameter, unused private item, dead private declaration ou équivalents relèvent d'un système de lint configurable et désactivable. Ils peuvent être explicitement activés par l'utilisateur, le projet ou un outil d'analyse, mais ne font pas partie du comportement diagnostic par défaut du langage.
Le formatter ne doit pas devenir un linter de nommage ni modifier la sémantique du programme.
2.8 Mutabilité par défaut — V1 REQUIS — FIGÉ
Saselang est mutable par défaut lorsque le type expose des opérations mutantes valides.
Le langage n'impose pas de mot-clé mut pour le cas ordinaire et n'adopte pas l'immutabilité par défaut.
String text = "abc";
text::append("def"); // OK si append est une méthode mutante de String
const est la restriction explicite qui retire les droits de mutation depuis un accès donné.
Cette règle vise une ergonomie syntaxique familière, proche des langages objets classiques, sans introduire un modèle d'ownership/borrowing visible de type Rust.