# 5. Types primitifs ## 5.1 Liste V1 — V1 REQUIS — FIGÉ ```text int8 int16 int32 int64 int128 int256 uint8 uint16 uint32 uint64 uint128 uint256 float16 float32 float64 float128 bool char ``` `Void` est un type/symbole spécial du Core/langage et ne doit pas être confondu avec un tuple vide. ### 5.1.1 Statut de `Void` — V1 REQUIS — FIGÉ `Void` représente explicitement l'absence de valeur utile ou de payload de succès. Il n'est pas un type de stockage général. Usages autorisés en V1 : ```text -> Void Result Result ``` Exemple : ```text func save() -> Result { ... return Result::Ok(Void); } ``` Les usages suivants sont interdits : ```text Void value; field Void Option Nullable Array Range ``` `return Void;` reste obligatoire dans une callable à retour direct `Void`. `Result` exprime un succès sans payload utile tout en conservant un canal d'erreur explicite. ## 5.2 Largeur exacte — V1 REQUIS — FIGÉ La largeur d'un type primitif ne dépend jamais de la cible. Il n'existe pas de `int`, `uint` ou `usize` dont la largeur change suivant la plateforme. Si un target ne sait pas représenter un type demandé, il produit une erreur de compilation. ## 5.3 Primitives et Object — V1 REQUIS — FIGÉ Les primitives : - ne sont pas des classes ; - n'héritent pas de `Object` ; - ne sont pas définissables par l'utilisateur ; - peuvent exposer des opérations compiler/Core-known avec syntaxe membre lorsque cela simplifie l'API. Exemple : ```text value::toString() float16::fromInt32(value) ``` ## 5.4 Représentation des entiers — V1 REQUIS — FIGÉ Les entiers signés utilisent une sémantique binaire définie en complément à deux pour les opérations bitwise. ## 5.5 Arithmétique des entiers — V1 REQUIS — FIGÉ Overflow arithmétique : checked et déterministe en debug comme en release. ```text overflow statiquement prouvable -> erreur de compilation overflow dynamique -> faute runtime déterministe ``` Des méthodes explicites pourront fournir : ```text wrapping saturating checked ``` Division entière : troncature vers zéro. Division par zéro : ```text statique -> erreur compilation dynamique -> faute runtime ``` `MIN / -1` est un overflow. Le reste `%` respecte : ```text a == (a / b) * b + (a % b) ``` et son signe suit le dividende. Le modulo euclidien sera une opération explicite du Core/SDK. ## 5.6 Floats — V1 REQUIS — À FINALISER La sémantique flottante suit le standard IEEE 754 normatif explicitement adopté par la révision de Saselang concernée. Une nouvelle révision d'IEEE 754 ne modifie jamais silencieusement une version déjà publiée de Saselang : elle doit être adoptée explicitement par une révision ultérieure de la spécification. Pour la révision `0.2.18`, la référence normative est **IEEE 754-2019**, standard actif le plus récent au moment de cette révision. Un projet de révision futur ne remplace pas cette référence tant qu'un nouveau standard final n'a pas été publié puis explicitement adopté. Les littéraux sont arrondis vers le type flottant cible selon les règles IEEE applicables ; Saselang n'exige pas qu'un littéral décimal soit représentable exactement. Les comparaisons flottantes conservent notamment les propriétés IEEE applicables : `NaN == NaN` est faux et `+0.0 == -0.0` est vrai. Les types `float*` relèvent donc de l'égalité partielle générale et ne satisfont pas directement la relation réflexive requise par `Equatable`. Les règles de conversion, `NaN`, infinities et zéros signés déjà figées sont détaillées au chapitre 24 et dans l'annexe `A-numeric-conversions.md`. Les règles restantes des opérations flottantes, notamment division par zéro et comportement de `%`, doivent encore être fermées avant implémentation finale. ## 5.7 Littéraux numériques — V1 REQUIS — FIGÉ EN PRINCIPE Entiers : ```text 42 decimal 0b101010 binary 0o52 octal 0x2a hexadecimal ``` Les préfixes de base sont canoniquement en minuscules : `0b`, `0o`, `0x`. Les séparateurs `_` sont autorisés uniquement entre deux chiffres valides appartenant à une même composante numérique : ```text 1_000_000 0b1010_1100 0xffff_ffff 1.234_567 1.0e1_000 ``` Sont notamment invalides : `_1`, `1_`, `1__0`, `0x_ff`, `1_.0`, `1._0`, `1e_10`. Un littéral flottant décimal contient un point décimal et/ou un exposant `e`/`E` : ```text 1.0 0.5 42.25 1e6 1.5e-3 ``` Les formes `1.` et `.5` ne sont pas canoniques et sont interdites ; écrire `1.0` et `0.5`. Les suffixes courts sont réservés et retenus : ```text i8 i16 i32 i64 i128 i256 u8 u16 u32 u64 u128 u256 f16 f32 f64 f128 ``` Exemples : ```text 42i32 42u64 1.5f16 ``` Un littéral non suffixé est typé par le contexte lorsqu'un type attendu existe et que sa valeur est représentable. Sans contexte, le type par défaut est `int32` pour un entier et `float64` pour un flottant. Cette contextualisation des littéraux ne constitue pas une inférence générale du type des variables et n'introduit aucune promotion implicite entre valeurs déjà typées. Le signe négatif n'appartient pas au token numérique : `-42` est l'opérateur unaire `-` appliqué au littéral `42`. L'analyse constante doit néanmoins permettre les minimums signés exacts tels que `int8 x = -128;` en validant la valeur finale contextualisée. Un entier littéral hors plage de son type contextualisé ou suffixé produit une erreur de compilation. Le frontend peut représenter temporairement les littéraux entiers avec une précision arbitraire pendant l'analyse avant validation du type final. Un littéral flottant est arrondi selon IEEE vers le type cible. Un overflow du littéral lui-même hors plage du type cible est une erreur de compilation plutôt qu'une conversion silencieuse en infinity. NaN et les infinities ne sont pas des pseudo-littéraux lexicaux ; ils sont exposés par le Core selon une API à finaliser. ### 5.7.1 Flottants hexadécimaux — V1 RÉSERVÉ / PROBABLE V2 La syntaxe des flottants hexadécimaux est réservée dès V1 afin de préserver les usages bas niveau futurs, même si l'implémentation complète peut être différée : ```text 0x1.0p0 0x1.8p1 0x1.ffp10 0x1.0p-20 ``` `p` introduit l'exposant binaire. Les suffixes flottants courts pourront s'appliquer à cette forme, par exemple `0x1.8p1f32`. La forme canonique utilise `0x` et `p` en minuscules. Le séparateur `_` suit la même règle générale d'utilisation entre chiffres valides. ### 5.7.2 Conversion explicite et bitcast — V1 REQUIS — DIRECTION FIGÉE Les suffixes de littéral et les conversions explicites sont deux mécanismes distincts et complémentaires : ```text 1f16 1::toFloat16() ``` La première forme donne directement un type au littéral ; la seconde exprime une conversion numérique explicite. Les primitives peuvent exposer des opérations compiler/Core-known telles que `toFloat16()`. Une conversion numérique reste distincte de : ```text bitcast(value) ``` qui réinterprète les bits selon les règles de `bitcast`. Les règles de plage et d'échec des conversions sont différées au groupe casts/conversions. ## 5.8 Abstraction Core `Numeric` — V1 REQUIS — DIRECTION FIGÉE Le Core doit fournir une véritable abstraction nominale `Numeric`. `Numeric` n'est pas une catégorie syntaxique spéciale du compilateur et ne remplace pas les types primitifs. Elle sert à exprimer des contrats génériques réels : ```text where T implements Numeric ``` Les primitives numériques Saselang satisfont le contrat `Numeric` via le Core. Les types utilisateurs pourront satisfaire `Numeric` uniquement en implémentant explicitement son contrat lorsque celui-ci sera définitivement spécifié. La présence de méthodes ressemblant à des opérations numériques ne suffit jamais par duck typing. La hiérarchie exacte de `Numeric`, ses membres et ses relations éventuelles avec `Comparable` et les interfaces `Op...` restent à fermer lors de la définition exhaustive du Core. ---