/
nv-lang
/
nova
Обзор
Документация
Войти
/
nv-lang
/
nova
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
Аналитика
main
std/src/runtime/defaults.nv
253 строки
10 KB
Evgeniy Golovin
merge: comment-hygiene-2 — чистка комментариев std (batch 1-20) + линт-свип 330→13
01 авг 2026, 18:13
01 авг 2026, 18:13
bb8b33d
Код
Авторство
О чём код?
// Canonical `.new()` constructors для типов // с единственным очевидным default-значением. // // stdlib предоставляет `.new()` только для канонических типов // (числовые, bool, str, []T, Option). Для своих типов разработчик // пишет `.new()` явно — compiler НЕ автогенерирует. module runtime.defaults // ─── Numeric types ─── // `int.new() => 0` — арифметический нейтрал. export fn int.new() -> Self => 0 // Unsigned integers. export fn u8.new() -> Self => 0 export fn u16.new() -> Self => 0 export fn u32.new() -> Self => 0 export fn u64.new() -> Self => 0 // uint = alias u64 (Nova-side); primitive type в codegen. export fn uint.new() -> Self => 0 // Signed integers. export fn i8.new() -> Self => 0 export fn i16.new() -> Self => 0 export fn i32.new() -> Self => 0 export fn i64.new() -> Self => 0 // Floating point. export fn f32.new() -> Self => 0.0 export fn f64.new() -> Self => 0.0 // ─── Boolean ─── // `bool.new() => false` — логический нейтрал. export fn bool.new() -> Self => false // ─── Primitive @compare ─── // // Primitives имеют native operators (< > == etc.). @compare добавлен для // [T Compare] bound satisfaction + synthesis chain. /// Compare.compare for char (codepoint-based ordering). export fn char @compare(other char) -> int => if @ < other { -1 } else if @ > other { 1 } else { 0 } // ─── char ASCII-core API ─── // ASCII-классификация/case/digit через char-сравнения (codepoint order); ноль // Unicode-таблиц. Семантика == Rust `char::is_ascii_*`/`to_digit`. (В defaults.nv, // не embedded char.nv: Nova-body методы на builtin char эмитятся только из // disk-loaded prelude-модуля, как char @compare.) Unicode-aware — Phase B. export fn char @is_ascii() -> bool => @ <= '\u{7F}' export fn char @is_ascii_digit() -> bool => @ >= '0' && @ <= '9' export fn char @is_ascii_lowercase() -> bool => @ >= 'a' && @ <= 'z' export fn char @is_ascii_uppercase() -> bool => @ >= 'A' && @ <= 'Z' export fn char @is_ascii_alphabetic() -> bool => @is_ascii_lowercase() || @is_ascii_uppercase() export fn char @is_ascii_alphanumeric() -> bool => @is_ascii_alphabetic() || @is_ascii_digit() export fn char @is_ascii_hexdigit() -> bool => @is_ascii_digit() || (@ >= 'a' && @ <= 'f') || (@ >= 'A' && @ <= 'F') // ASCII whitespace (space, \t, \n, \r, \x0C) — как Rust (без \x0B vertical-tab). export fn char @is_ascii_whitespace() -> bool => @ == ' ' || @ == '\t' || @ == '\n' || @ == '\r' || @ == '\u{0C}' // ASCII case mapping (a-z↔A-Z); прочие символы — без изменений. export fn char @to_ascii_uppercase() -> char { if @is_ascii_lowercase() { (@ as int - 32).to_char() ?? @ } else { @ } } export fn char @to_ascii_lowercase() -> char { if @is_ascii_uppercase() { (@ as int + 32).to_char() ?? @ } else { @ } } // Цифровое значение в системе `radix` (2..=36): '0'-'9'→0-9, 'a'/'A'-..→10-35. // `None` если radix вне [2,36] / не цифра / значение >= radix. Rust `char::to_digit`. export fn char @to_digit(radix int) -> Option[int] { if radix < 2 || radix > 36 { return None } ro c = @ as int mut d = -1 if @ >= '0' && @ <= '9' { d = c - ('0' as int) } else if @ >= 'a' && @ <= 'z' { d = c - ('a' as int) + 10 } else if @ >= 'A' && @ <= 'Z' { d = c - ('A' as int) + 10 } if d < 0 || d >= radix { return None } Some(d) } // UTF-8-кодировка codepoint'а в 4-байтный массив с длиной. // Возвращает кортеж ([4]u8, byte-length) — «слайс по значению»: данные, // потом длина (конвенция {ptr,len}/{data,len,cap}). // Rust `char::encode_utf8` (возвращает срез, здесь кортеж + хвостовые нули). export fn char @encode_utf8() -> ([4]u8, int) { mut out [4]u8 = [0, 0, 0, 0] ro cp = @ as int mut len int = 0 if cp < 0x80 { out[0] = cp as u8 len = 1 } else if cp < 0x800 { out[0] = (0xC0 | (cp >> 6)) as u8 out[1] = (0x80 | (cp & 0x3F)) as u8 len = 2 } else if cp < 0x10000 { out[0] = (0xE0 | (cp >> 12)) as u8 out[1] = (0x80 | ((cp >> 6) & 0x3F)) as u8 out[2] = (0x80 | (cp & 0x3F)) as u8 len = 3 } else { out[0] = (0xF0 | (cp >> 18)) as u8 out[1] = (0x80 | ((cp >> 12) & 0x3F)) as u8 out[2] = (0x80 | ((cp >> 6) & 0x3F)) as u8 out[3] = (0x80 | (cp & 0x3F)) as u8 len = 4 } (out, len) } // Байт-длина UTF-8-кодировки codepoint'а (1-4). Rust `char::len_utf8`. export fn char @len_utf8() -> int => @encode_utf8().1 // ASCII case-insensitive equality. Rust `char::eq_ignore_ascii_case`. export fn char @eq_ignore_ascii_case(other char) -> bool => @to_ascii_lowercase() == other.to_ascii_lowercase() /// Compare.compare for int (signum, overflow-safe). export fn int @compare(other int) -> int => if @ < other { -1 } else if @ > other { 1 } else { 0 } // Unsigned integers. export fn u8 @compare(other Self) -> int => if @ < other { -1 } else if @ > other { 1 } else { 0 } export fn u16 @compare(other Self) -> int => if @ < other { -1 } else if @ > other { 1 } else { 0 } export fn u32 @compare(other Self) -> int => if @ < other { -1 } else if @ > other { 1 } else { 0 } export fn u64 @compare(other Self) -> int => if @ < other { -1 } else if @ > other { 1 } else { 0 } export fn uint @compare(other Self) -> int => if @ < other { -1 } else if @ > other { 1 } else { 0 } // Signed integers. export fn i8 @compare(other Self) -> int => if @ < other { -1 } else if @ > other { 1 } else { 0 } export fn i16 @compare(other Self) -> int => if @ < other { -1 } else if @ > other { 1 } else { 0 } export fn i32 @compare(other Self) -> int => if @ < other { -1 } else if @ > other { 1 } else { 0 } export fn i64 @compare(other Self) -> int => if @ < other { -1 } else if @ > other { 1 } else { 0 } // Floating point. export fn f32 @compare(other Self) -> int => if @ < other { -1 } else if @ > other { 1 } else { 0 } export fn f64 @compare(other Self) -> int => if @ < other { -1 } else if @ > other { 1 } else { 0 } // bool ordering — false < true (canonical Boolean order). export fn bool @compare(other Self) -> int => (@ as int) - (other as int) // min / max — scalar value comparison. // Returns the smaller / larger of the two values. export fn int @min(other int) -> int => if @ < other { @ } else { other } export fn int @max(other int) -> int => if @ > other { @ } else { other } export fn u8 @min(other Self) -> Self => if @ < other { @ } else { other } export fn u8 @max(other Self) -> Self => if @ > other { @ } else { other } export fn u16 @min(other Self) -> Self => if @ < other { @ } else { other } export fn u16 @max(other Self) -> Self => if @ > other { @ } else { other } export fn u32 @min(other Self) -> Self => if @ < other { @ } else { other } export fn u32 @max(other Self) -> Self => if @ > other { @ } else { other } export fn u64 @min(other Self) -> Self => if @ < other { @ } else { other } export fn u64 @max(other Self) -> Self => if @ > other { @ } else { other } export fn uint @min(other Self) -> Self => if @ < other { @ } else { other } export fn uint @max(other Self) -> Self => if @ > other { @ } else { other } export fn i8 @min(other Self) -> Self => if @ < other { @ } else { other } export fn i8 @max(other Self) -> Self => if @ > other { @ } else { other } export fn i16 @min(other Self) -> Self => if @ < other { @ } else { other } export fn i16 @max(other Self) -> Self => if @ > other { @ } else { other } export fn i32 @min(other Self) -> Self => if @ < other { @ } else { other } export fn i32 @max(other Self) -> Self => if @ > other { @ } else { other } export fn i64 @min(other Self) -> Self => if @ < other { @ } else { other } export fn i64 @max(other Self) -> Self => if @ > other { @ } else { other } export fn f32 @min(other Self) -> Self => if @ < other { @ } else { other } export fn f32 @max(other Self) -> Self => if @ > other { @ } else { other } export fn f64 @min(other Self) -> Self => if @ < other { @ } else { other } export fn f64 @max(other Self) -> Self => if @ > other { @ } else { other } // clamp — restrict value to [lo, hi] range. // int @clamp is covered by the `fn[T Ints] T @clamp(lo T, hi T) -> T` blanket // (std/prelude/protocols.nv). // f64/f32 @clamp stay concrete — float ∉ Ints (float clamp not part of the blanket). export fn f64 @clamp(lo f64, hi f64) -> f64 => if @ < lo { lo } else if @ > hi { hi } else { @ } // `f32 @clamp` — mechanical mirror of `f64 @clamp`, byte-identical contract // (same lo>hi behavior as f64/Ints @clamp — `@ < lo` checked first, never // returns `@` on an inverted range). export fn f32 @clamp(lo f32, hi f32) -> f32 => if @ < lo { lo } else if @ > hi { hi } else { @ } // sign/predicate methods (where mathematically meaningful). // signum: -1 / 0 / +1 by sign. is_negative / is_positive: strict sign tests. // Pure if-expressions (same shape as @clamp) — resolved + lowered like any // `.nv`-declared method, no Rust hardcode (§3). // // `int @signum`/`@is_negative`/`@is_positive` concrete-on-int-only bodies are // covered by the `fn[T SignedInt] ...` blanket (std/prelude/protocols.nv, // рядом с `@clamp`-бланкетом) — one body for i8/i16/i32/i64/int instead of // ×N concrete methods.