From 10405c42fdbcfa97f856c1de5237cfc5e313cf2d Mon Sep 17 00:00:00 2001 From: Volodymyr Korniichuk <9173519@gmail.com> Date: Sun, 1 Sep 2019 10:55:27 +0300 Subject: Added translation for [Rust/uk-ua] (#3613) * Added uk-ua tranlation for Rust * fixed lang * fixed "80-symbols per line" limit * Fix filename --- uk-ua/rust-ua.html.markdown | 331 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 331 insertions(+) create mode 100644 uk-ua/rust-ua.html.markdown (limited to 'uk-ua') diff --git a/uk-ua/rust-ua.html.markdown b/uk-ua/rust-ua.html.markdown new file mode 100644 index 00000000..4ec2b7c9 --- /dev/null +++ b/uk-ua/rust-ua.html.markdown @@ -0,0 +1,331 @@ +--- +language: rust +contributors: + - ["P1start", "http://p1start.github.io/"] +translators: + - ["Volodymyr Korniichuk", "https://github.com/ezhikus"] +filename: learnrust-uk.rs +lang: uk-ua +--- + +Rust - це мова програмування, що розрабляється спільнотою Mozilla Research +Rust поєднує в собі низькорівневий контроль швидкодії з високорівневими +інструментами забезпечення гарантій цілісності та безпеки. + +Rust досягає своїх цілей без автоматичного збирання сміття і не вимагає +наявності певного середовища виконання, що робить можливим пряму заміну +бібліотек, написаних на мові С на бібліотеки, написані на Rust. + +Перший реліз Rust (версія 0.1) вийшла в січні 2012 року і з тих пір оновлення +виходили так часто, що загальною порадою розробникам було не чекати якоїсь +стабільної версії, а використовувати нічні збірки компілятора. + +15 травня 2015 року вийшла версія Rust 1.0. Для цієї версії була дана гарантія +зворотної сумісності. Подальші нічні збірки покращили швидкість компіляції та +деякі інші аспекти. На даний момент оновлення Rust виходять кожні 6 тижнів. +Бета-версія Rust 1.1 вийшла одночасно з релізом Rust 1.0. + +Не зважаючи на те, що Rust є відносно низькорівневою мовою програмування, в +ній є деякі концепти, притаманні високорівневим мовам. Це робить Rust не лише +швидким, але й досить зручним та ефективним інструментом розробки. + +```rust +// Це коментар. Він починається в цьому рядку... +// і продовжується в цьому + +/// Цей коментар включає в себе документацію і підтримує markdown. +/// # Приклади +/// +/// ``` +/// let five = 5 +/// ``` + +/////////////// +// 1. Основи // +/////////////// + +#[allow(dead_code)] +// Функції +// `i32` - це 32-бітний цілочислений знаковий тип даних +fn add2(x: i32, y: i32) -> i32 { + // неявне повернення результату (в кінці рядку немає крапки з комою) + x + y +} + +#[allow(unused_variables)] +#[allow(unused_assignments)] +#[allow(dead_code)] +// Головна функція +fn main() { + // Числа // + + // Незмінне число + let x: i32 = 1; + + // суфікси для позначення цілого числа та числа з плаваючою змінною + let y: i32 = 13i32; + let f: f64 = 1.3f64; + + // Вивід типів + // Як правило, Rust може самостійно визначити тип змінної, отож + // ви можете не прописувати його явно + // В даному документі типи явно прописані в багатьох місцях, це зроблено + // виключно в навчальних цілях. В реальному коді вивід типів спрацює + // в більшості випадків + let implicit_x = 1; + let implicit_f = 1.3; + + // арифметика + let sum = x + y + 13; + + // Змінні + let mut mutable = 1; + mutable = 4; + mutable += 2; + + // Строки // + + // Строкові літерали + let x: &str = "Привіт, світ!"; + + // Друк на екран + println!("{} {}", f, x); // 1.3 Привіт, світ! + + // `String` – строка, що розміщується в "купі" + let s: String = "hello world".to_string(); + + // Строковий зріз - це незмінне відображення якоїсь строки (або її частини) + // Зріз можна розглядати як константну пару покажчиків (на початок та кінець + // якоїсь строки) + let s_slice: &str = &s; + + println!("{} {}", s, s_slice); // Привіт, світ! Привіт, світ! + + // Вектори/масиви // + + // Масив фіксованого розміру + let four_ints: [i32; 4] = [1, 2, 3, 4]; + + // Масив змінного розміру (вектор) + let mut vector: Vec = vec![1, 2, 3, 4]; + vector.push(5); + + // Зріз - незмінне відображення масиву + // Це схоже на строковий зріз, але в даному випадку мова йде про вектори + let slice: &[i32] = &vector; + + // Використовуйте `{:?}` щоб вивести щось в цілях відлагодження + println!("{:?} {:?}", vector, slice); // [1, 2, 3, 4, 5] [1, 2, 3, 4, 5] + + // Кортеж // + + // Кортеж - це набір фіксованого розміру, що включає значення кількох типів + let x: (i32, &str, f64) = (1, "привіт", 3.4); + + // розбираємо кортеж "х" на окремі змінні "a", "b" та "с" + let (a, b, c) = x; + println!("{} {} {}", a, b, c); // 1 привіт 3.4 + + // доступ по індексу + println!("{}", x.1); // привіт + + ////////////// + // 2. Типи // + ////////////// + + // Структура + struct Point { + x: i32, + y: i32, + } + + let origin: Point = Point { x: 0, y: 0 }; + + // Структура з безіменними полями, "кортежна структура" + struct Point2(i32, i32); + + let origin2 = Point2(0, 0); + + // перелічуваний тип даних + enum Direction { + Left, + Right, + Up, + Down, + } + + let up = Direction::Up; + + // перелічуваний тип даних з полями + enum OptionalI32 { + AnI32(i32), + Nothing, + } + + let two: OptionalI32 = OptionalI32::AnI32(2); + let nothing = OptionalI32::Nothing; + + // Узагальнене програмування // + + struct Foo { bar: T } + + // Ось так стандартна бібліотека Rust оголошує `Option` + enum Optional { + SomeVal(T), + NoVal, + } + + // Методи // + + impl Foo { + // Методи приймають неявний параметр `self` + fn get_bar(self) -> T { + self.bar + } + } + + let a_foo = Foo { bar: 1 }; + println!("{}", a_foo.get_bar()); // 1 + + // Типажі (в інших мовах програмування схожою сутністю є інтерфейси) // + + trait Frobnicate { + fn frobnicate(self) -> Option; + } + + impl Frobnicate for Foo { + fn frobnicate(self) -> Option { + Some(self.bar) + } + } + + let another_foo = Foo { bar: 1 }; + println!("{:?}", another_foo.frobnicate()); // Some(1) + + ///////////////////////// + // 3. Відповідність шаблону // + ///////////////////////// + + let foo = OptionalI32::AnI32(1); + match foo { + OptionalI32::AnI32(n) => println!("Це тип i32: {}", n), + OptionalI32::Nothing => println!("Це ніщо!"), + } + + // Складніший приклад + struct FooBar { x: i32, y: OptionalI32 } + let bar = FooBar { x: 15, y: OptionalI32::AnI32(32) }; + + match bar { + FooBar { x: 0, y: OptionalI32::AnI32(0) } => + println!("Числа рівні нулю!"), + FooBar { x: n, y: OptionalI32::AnI32(m) } if n == m => + println!("Числа однакові"), + FooBar { x: n, y: OptionalI32::AnI32(m) } => + println!("Числа різні: {} {}", n, m), + FooBar { x: _, y: OptionalI32::Nothing } => + println!("Друге число - ніщо!"), + } + + ///////////////////// + // 4. Потік керування // + ///////////////////// + + // Цикл `for` + let array = [1, 2, 3]; + for i in array.iter() { + println!("{}", i); + } + + // Діапазони + for i in 0u32..10 { + print!("{} ", i); + } + println!(""); + // друкує `0 1 2 3 4 5 6 7 8 9 ` + + // `if` + if 1 == 1 { + println!("Математика працює!"); + } else { + println!("Ой, лишенько..."); + } + + // `if` як вираз + let value = if true { + "добре" + } else { + "погано" + }; + + // Цикл `while` + while 1 == 1 { + println!("Всесвіт функціонує стабільно."); + // Вираз break перериває цикл + break + } + + // Нескінченний цикл + loop { + println!("Привіт!"); + // Вираз break перериває цикл + break + } + + ///////////////////////////////// + // 5. Вказівники і безпека пам'яті // + ///////////////////////////////// + + // Володіючий вказівник - тільки хтось один може "володіти" вказівником в + // будь-який момент. Це означає, що коли "Box" вийде за межі області + // видимості - його можна безпечно звільнити + let mut mine: Box = Box::new(3); + *mine = 5; // розіменування `mine` з присвоєнням йому нового значення + // `now_its_mine` перебирає на себе володіння над `mine`. Іншими словами, + // `mine` переміщується. + let mut now_its_mine = mine; + *now_its_mine += 2; + + println!("{}", now_its_mine); // 7 + // println!("{}", mine); // цей код не скомпілюється, оскільки тепер + // покажчиком на дані володіє `now_its_mine` + + // Посилання – незмінний вказівник на дані + // При створенні посилання на якесь значення, ми говоримо, що значення + // було "запозичене". Поки значення є запозиченим - воно не може бути + // змінене або переміщене. Запозичення пропадає, як тільки стається вихід з + // області видимості, де було створене посилання + let mut var = 4; + var = 3; + let ref_var: &i32 = &var; + + println!("{}", var); // На відміну від `mine`, `var` можна використати + println!("{}", *ref_var); + // var = 5; // цей код не скомпілюється, оскільки `var` зараз є запозиченим + // *ref_var = 6; // цей код також не зкомпілюється, оскільки `ref_var` + // є незмінним посиланням + + // Змінне посилання + // Значення можна запозичити з можливістю зміни. У цьому випадку доступ до + // оригінального значення втрачається. + let mut var2 = 4; + let ref_var2: &mut i32 = &mut var2; + *ref_var2 += 2; // '*' використовується для доступу до змінного посилання + + println!("{}", *ref_var2); // 6 , // при заміні на var2 код не зкомпілюється + // ref_var2 має тип &mut i32, отож зберігає посилання на i32, а не значення + // var2 = 2; // цей рядок не зкомпілюється, оскільки `var2` є запозиченим. +} +``` + +## Матеріали для самовдосконалення + +В даному матеріалі ми оглянули лише основи Rust. Більше матеріалу ви можете +знайти на сайті +[The Rust Programming Language](http://doc.rust-lang.org/book/index.html) +Також існує Reddit-розділ [/r/rust](http://reddit.com/r/rust). Люди на каналі +irc.mozilla.org також завжди раді допомогти новачкам. + +Ви можете спробувати можливості Rust за допомогою онлайн-компілятора на сторінці +[Rust playpen](http://play.rust-lang.org) або +[Rust website](http://rust-lang.org). -- cgit v1.2.3 From 4fafc4a432ff9008db111d5f269464d5c67ce5a5 Mon Sep 17 00:00:00 2001 From: Oleh Hromiak Date: Mon, 7 Oct 2019 17:18:34 +0300 Subject: Add [wasm/uk-ua] and update name in [python/uk-ua] --- uk-ua/python-ua.html.markdown | 2 +- uk-ua/wasm.html.markdown | 225 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 226 insertions(+), 1 deletion(-) create mode 100644 uk-ua/wasm.html.markdown (limited to 'uk-ua') diff --git a/uk-ua/python-ua.html.markdown b/uk-ua/python-ua.html.markdown index 23bc1796..4091e433 100644 --- a/uk-ua/python-ua.html.markdown +++ b/uk-ua/python-ua.html.markdown @@ -9,7 +9,7 @@ contributors: - ["asyne", "https://github.com/justblah"] - ["habi", "http://github.com/habi"] translators: - - ["Oleg Gromyak", "https://github.com/ogroleg"] + - ["Oleh Hromiak", "https://github.com/ogroleg"] filename: learnpython-ua.py --- diff --git a/uk-ua/wasm.html.markdown b/uk-ua/wasm.html.markdown new file mode 100644 index 00000000..b5a1f4dd --- /dev/null +++ b/uk-ua/wasm.html.markdown @@ -0,0 +1,225 @@ +--- +language: WebAssembly +filename: learnwasm-ua.wast +contributors: + - ["Dean Shaff", "http://dean-shaff.github.io"] +translators: + - ["Oleh Hromiak", "https://github.com/ogroleg"] +--- + +``` +;; learnwasm-ua.wast + +(module + ;; У WebAssembly весь код знаходиться в модулях. Будь-яка операція + ;; може бути записана за допомогою s-виразу. Також існує синтаксис "стек машини", + ;; втім, він не сумісний з проміжним бінарним представленням коду. + + ;; Формат бінарного проміжного представлення майже повністю сумісний + ;; з текстовим форматом WebAssembly. + ;; Деякі відмінності: + ;; local_set -> local.set + ;; local_get -> local.get + + ;; Код розміщується у функціях + + ;; Типи даних + (func $data_types + ;; WebAssembly має чотири типи даних: + ;; i32 - ціле число, 32 біти + ;; i64 - ціле число, 64 біти (не підтримується у JavaScript) + ;; f32 - число з плаваючою комою, 32 біти + ;; f64 - число з плаваючою комою, 64 біти + + ;; Створити локальну змінну можна за допомогою ключового слова "local". + ;; Змінні потрібно оголошувати на початку функції. + + (local $int_32 i32) + (local $int_64 i64) + (local $float_32 f32) + (local $float_64 f64) + + ;; Змінні, оголошені вище, ще не ініціалізовані, себто, не мають значення. + ;; Давайте присвоїмо їм значення за допомогою <тип даних>.const: + + (local.set $int_32 (i32.const 16)) + (local.set $int_32 (i64.const 128)) + (local.set $float_32 (f32.const 3.14)) + (local.set $float_64 (f64.const 1.28)) + ) + + ;; Базові операції + (func $basic_operations + + ;; Нагадаємо, у WebAssembly будь-що є s-виразом, включно + ;; з математичними виразами або зчитуванням значень змінних + + (local $add_result i32) + (local $mult_result f64) + + (local.set $add_result (i32.add (i32.const 2) (i32.const 4))) + ;; тепер add_result дорівнює 6! + + ;; Для кожної операції потрібно використовувати правильний тип: + ;; (local.set $mult_result (f32.mul (f32.const 2.0) (f32.const 4.0))) ;; Ніт! mult_result має тип f64! + (local.set $mult_result (f64.mul (f64.const 2.0) (f64.const 4.0))) ;; Ніт! mult_result має тип f64! + + ;; У WebAssembly є вбудовані функції накшталт математики та побітових операцій. + ;; Варто зазначити, що тут відсутні вбудовані тригонометричні функції. + ;; Тож нам потрібно: + ;; - написати їх самостійно (не найкраща ідея) + ;; - звідкись їх імпортувати (як саме - побачимо згодом) + ) + + ;; Функції + ;; Параметри вказуються ключовим словом `param`, значення, що повертається - `result` + ;; Поточне значення стеку і є значенням функції, що повертається + + ;; Ми можемо викликати інші функції за допомогою `call` + + (func $get_16 (result i32) + (i32.const 16) + ) + + (func $add (param $param0 i32) (param $param1 i32) (result i32) + (i32.add + (local.get $param0) + (local.get $param1) + ) + ) + + (func $double_16 (result i32) + (i32.mul + (i32.const 2) + (call $get_16)) + ) + + ;; Досі ми не могли що-небудь вивести на консоль і не мали доступу + ;; до високорівневої математики (степеневі функції, обрахунок експоненти або тригонометрія). + ;; Більше того, ми навіть не могли викликати WASM функції у Javascript! + ;; Виклик цих функцій у WebAssembly залежить від того, + ;; де ми знаходимось - чи це Node.js, чи середовище браузера. + + ;; Якщо ми у Node.js, то потрібно виконати два кроки. По-перше, ми маємо сконвертувати + ;; текстове представлення WASM у справжній код webassembly. + ;; Наприклад, ось так (Binaryen): + + ;; wasm-as learn-wasm.wast -o learn-wasm.wasm + + ;; Давай також застосуємо оптимізації: + + ;; wasm-opt learn-wasm.wasm -o learn-wasm.opt.wasm -O3 --rse + + ;; Тепер наш скомпільований WebAssembly можна завантажити у Node.js: + ;; const fs = require('fs') + ;; const instantiate = async function (inFilePath, _importObject) { + ;; var importObject = { + ;; console: { + ;; log: (x) => console.log(x), + ;; }, + ;; math: { + ;; cos: (x) => Math.cos(x), + ;; } + ;; } + ;; importObject = Object.assign(importObject, _importObject) + ;; + ;; var buffer = fs.readFileSync(inFilePath) + ;; var module = await WebAssembly.compile(buffer) + ;; var instance = await WebAssembly.instantiate(module, importObject) + ;; return instance.exports + ;; } + ;; + ;; const main = function () { + ;; var wasmExports = await instantiate('learn-wasm.wasm') + ;; wasmExports.print_args(1, 0) + ;; } + + ;; Цей код зчитує функції з importObject + ;; (вказано у асинхронній JavaScript функції instantiate), а потім експортує функцію + ;; "print_args", яку ми викликаємо у Node.js + + (import "console" "log" (func $print_i32 (param i32))) + (import "math" "cos" (func $cos (param f64) (result f64))) + + (func $print_args (param $arg0 i32) (param $arg1 i32) + (call $print_i32 (local.get $arg0)) + (call $print_i32 (local.get $arg1)) + ) + (export "print_args" (func $print_args)) + + ;; Завантаження даних з пам'яті WebAssembly. + ;; Наприклад, ми хочемо порахувати cos для елементів Javascript масиву. + ;; Нам потрібно отримати доступ до масиву і можливість ітерувати по ньому. + ;; У прикладі нижче ми змінимо існуючий масив. + ;; f64.load і f64.store приймають адресу числа у пам'яті *у байтах*. + ;; Для того, щоб отримати доступ до 3-го елементу масиву, ми маємо передати щось + ;; накшталт (i32.mul (i32.const 8) (i32.const 2)) у функцію f64.store. + + ;; У JavaScript ми викличемо `apply_cos64` таким чином + ;; (використаємо функцію instantiate з попереднього прикладу): + ;; + ;; const main = function () { + ;; var wasm = await instantiate('learn-wasm.wasm') + ;; var n = 100 + ;; const memory = new Float64Array(wasm.memory.buffer, 0, n) + ;; for (var i=0; i Date: Mon, 7 Oct 2019 22:35:03 +0300 Subject: Fix [wasm/ua] filename --- uk-ua/wasm-ua.html.markdown | 225 ++++++++++++++++++++++++++++++++++++++++++++ uk-ua/wasm.html.markdown | 225 -------------------------------------------- 2 files changed, 225 insertions(+), 225 deletions(-) create mode 100644 uk-ua/wasm-ua.html.markdown delete mode 100644 uk-ua/wasm.html.markdown (limited to 'uk-ua') diff --git a/uk-ua/wasm-ua.html.markdown b/uk-ua/wasm-ua.html.markdown new file mode 100644 index 00000000..b5a1f4dd --- /dev/null +++ b/uk-ua/wasm-ua.html.markdown @@ -0,0 +1,225 @@ +--- +language: WebAssembly +filename: learnwasm-ua.wast +contributors: + - ["Dean Shaff", "http://dean-shaff.github.io"] +translators: + - ["Oleh Hromiak", "https://github.com/ogroleg"] +--- + +``` +;; learnwasm-ua.wast + +(module + ;; У WebAssembly весь код знаходиться в модулях. Будь-яка операція + ;; може бути записана за допомогою s-виразу. Також існує синтаксис "стек машини", + ;; втім, він не сумісний з проміжним бінарним представленням коду. + + ;; Формат бінарного проміжного представлення майже повністю сумісний + ;; з текстовим форматом WebAssembly. + ;; Деякі відмінності: + ;; local_set -> local.set + ;; local_get -> local.get + + ;; Код розміщується у функціях + + ;; Типи даних + (func $data_types + ;; WebAssembly має чотири типи даних: + ;; i32 - ціле число, 32 біти + ;; i64 - ціле число, 64 біти (не підтримується у JavaScript) + ;; f32 - число з плаваючою комою, 32 біти + ;; f64 - число з плаваючою комою, 64 біти + + ;; Створити локальну змінну можна за допомогою ключового слова "local". + ;; Змінні потрібно оголошувати на початку функції. + + (local $int_32 i32) + (local $int_64 i64) + (local $float_32 f32) + (local $float_64 f64) + + ;; Змінні, оголошені вище, ще не ініціалізовані, себто, не мають значення. + ;; Давайте присвоїмо їм значення за допомогою <тип даних>.const: + + (local.set $int_32 (i32.const 16)) + (local.set $int_32 (i64.const 128)) + (local.set $float_32 (f32.const 3.14)) + (local.set $float_64 (f64.const 1.28)) + ) + + ;; Базові операції + (func $basic_operations + + ;; Нагадаємо, у WebAssembly будь-що є s-виразом, включно + ;; з математичними виразами або зчитуванням значень змінних + + (local $add_result i32) + (local $mult_result f64) + + (local.set $add_result (i32.add (i32.const 2) (i32.const 4))) + ;; тепер add_result дорівнює 6! + + ;; Для кожної операції потрібно використовувати правильний тип: + ;; (local.set $mult_result (f32.mul (f32.const 2.0) (f32.const 4.0))) ;; Ніт! mult_result має тип f64! + (local.set $mult_result (f64.mul (f64.const 2.0) (f64.const 4.0))) ;; Ніт! mult_result має тип f64! + + ;; У WebAssembly є вбудовані функції накшталт математики та побітових операцій. + ;; Варто зазначити, що тут відсутні вбудовані тригонометричні функції. + ;; Тож нам потрібно: + ;; - написати їх самостійно (не найкраща ідея) + ;; - звідкись їх імпортувати (як саме - побачимо згодом) + ) + + ;; Функції + ;; Параметри вказуються ключовим словом `param`, значення, що повертається - `result` + ;; Поточне значення стеку і є значенням функції, що повертається + + ;; Ми можемо викликати інші функції за допомогою `call` + + (func $get_16 (result i32) + (i32.const 16) + ) + + (func $add (param $param0 i32) (param $param1 i32) (result i32) + (i32.add + (local.get $param0) + (local.get $param1) + ) + ) + + (func $double_16 (result i32) + (i32.mul + (i32.const 2) + (call $get_16)) + ) + + ;; Досі ми не могли що-небудь вивести на консоль і не мали доступу + ;; до високорівневої математики (степеневі функції, обрахунок експоненти або тригонометрія). + ;; Більше того, ми навіть не могли викликати WASM функції у Javascript! + ;; Виклик цих функцій у WebAssembly залежить від того, + ;; де ми знаходимось - чи це Node.js, чи середовище браузера. + + ;; Якщо ми у Node.js, то потрібно виконати два кроки. По-перше, ми маємо сконвертувати + ;; текстове представлення WASM у справжній код webassembly. + ;; Наприклад, ось так (Binaryen): + + ;; wasm-as learn-wasm.wast -o learn-wasm.wasm + + ;; Давай також застосуємо оптимізації: + + ;; wasm-opt learn-wasm.wasm -o learn-wasm.opt.wasm -O3 --rse + + ;; Тепер наш скомпільований WebAssembly можна завантажити у Node.js: + ;; const fs = require('fs') + ;; const instantiate = async function (inFilePath, _importObject) { + ;; var importObject = { + ;; console: { + ;; log: (x) => console.log(x), + ;; }, + ;; math: { + ;; cos: (x) => Math.cos(x), + ;; } + ;; } + ;; importObject = Object.assign(importObject, _importObject) + ;; + ;; var buffer = fs.readFileSync(inFilePath) + ;; var module = await WebAssembly.compile(buffer) + ;; var instance = await WebAssembly.instantiate(module, importObject) + ;; return instance.exports + ;; } + ;; + ;; const main = function () { + ;; var wasmExports = await instantiate('learn-wasm.wasm') + ;; wasmExports.print_args(1, 0) + ;; } + + ;; Цей код зчитує функції з importObject + ;; (вказано у асинхронній JavaScript функції instantiate), а потім експортує функцію + ;; "print_args", яку ми викликаємо у Node.js + + (import "console" "log" (func $print_i32 (param i32))) + (import "math" "cos" (func $cos (param f64) (result f64))) + + (func $print_args (param $arg0 i32) (param $arg1 i32) + (call $print_i32 (local.get $arg0)) + (call $print_i32 (local.get $arg1)) + ) + (export "print_args" (func $print_args)) + + ;; Завантаження даних з пам'яті WebAssembly. + ;; Наприклад, ми хочемо порахувати cos для елементів Javascript масиву. + ;; Нам потрібно отримати доступ до масиву і можливість ітерувати по ньому. + ;; У прикладі нижче ми змінимо існуючий масив. + ;; f64.load і f64.store приймають адресу числа у пам'яті *у байтах*. + ;; Для того, щоб отримати доступ до 3-го елементу масиву, ми маємо передати щось + ;; накшталт (i32.mul (i32.const 8) (i32.const 2)) у функцію f64.store. + + ;; У JavaScript ми викличемо `apply_cos64` таким чином + ;; (використаємо функцію instantiate з попереднього прикладу): + ;; + ;; const main = function () { + ;; var wasm = await instantiate('learn-wasm.wasm') + ;; var n = 100 + ;; const memory = new Float64Array(wasm.memory.buffer, 0, n) + ;; for (var i=0; i local.set - ;; local_get -> local.get - - ;; Код розміщується у функціях - - ;; Типи даних - (func $data_types - ;; WebAssembly має чотири типи даних: - ;; i32 - ціле число, 32 біти - ;; i64 - ціле число, 64 біти (не підтримується у JavaScript) - ;; f32 - число з плаваючою комою, 32 біти - ;; f64 - число з плаваючою комою, 64 біти - - ;; Створити локальну змінну можна за допомогою ключового слова "local". - ;; Змінні потрібно оголошувати на початку функції. - - (local $int_32 i32) - (local $int_64 i64) - (local $float_32 f32) - (local $float_64 f64) - - ;; Змінні, оголошені вище, ще не ініціалізовані, себто, не мають значення. - ;; Давайте присвоїмо їм значення за допомогою <тип даних>.const: - - (local.set $int_32 (i32.const 16)) - (local.set $int_32 (i64.const 128)) - (local.set $float_32 (f32.const 3.14)) - (local.set $float_64 (f64.const 1.28)) - ) - - ;; Базові операції - (func $basic_operations - - ;; Нагадаємо, у WebAssembly будь-що є s-виразом, включно - ;; з математичними виразами або зчитуванням значень змінних - - (local $add_result i32) - (local $mult_result f64) - - (local.set $add_result (i32.add (i32.const 2) (i32.const 4))) - ;; тепер add_result дорівнює 6! - - ;; Для кожної операції потрібно використовувати правильний тип: - ;; (local.set $mult_result (f32.mul (f32.const 2.0) (f32.const 4.0))) ;; Ніт! mult_result має тип f64! - (local.set $mult_result (f64.mul (f64.const 2.0) (f64.const 4.0))) ;; Ніт! mult_result має тип f64! - - ;; У WebAssembly є вбудовані функції накшталт математики та побітових операцій. - ;; Варто зазначити, що тут відсутні вбудовані тригонометричні функції. - ;; Тож нам потрібно: - ;; - написати їх самостійно (не найкраща ідея) - ;; - звідкись їх імпортувати (як саме - побачимо згодом) - ) - - ;; Функції - ;; Параметри вказуються ключовим словом `param`, значення, що повертається - `result` - ;; Поточне значення стеку і є значенням функції, що повертається - - ;; Ми можемо викликати інші функції за допомогою `call` - - (func $get_16 (result i32) - (i32.const 16) - ) - - (func $add (param $param0 i32) (param $param1 i32) (result i32) - (i32.add - (local.get $param0) - (local.get $param1) - ) - ) - - (func $double_16 (result i32) - (i32.mul - (i32.const 2) - (call $get_16)) - ) - - ;; Досі ми не могли що-небудь вивести на консоль і не мали доступу - ;; до високорівневої математики (степеневі функції, обрахунок експоненти або тригонометрія). - ;; Більше того, ми навіть не могли викликати WASM функції у Javascript! - ;; Виклик цих функцій у WebAssembly залежить від того, - ;; де ми знаходимось - чи це Node.js, чи середовище браузера. - - ;; Якщо ми у Node.js, то потрібно виконати два кроки. По-перше, ми маємо сконвертувати - ;; текстове представлення WASM у справжній код webassembly. - ;; Наприклад, ось так (Binaryen): - - ;; wasm-as learn-wasm.wast -o learn-wasm.wasm - - ;; Давай також застосуємо оптимізації: - - ;; wasm-opt learn-wasm.wasm -o learn-wasm.opt.wasm -O3 --rse - - ;; Тепер наш скомпільований WebAssembly можна завантажити у Node.js: - ;; const fs = require('fs') - ;; const instantiate = async function (inFilePath, _importObject) { - ;; var importObject = { - ;; console: { - ;; log: (x) => console.log(x), - ;; }, - ;; math: { - ;; cos: (x) => Math.cos(x), - ;; } - ;; } - ;; importObject = Object.assign(importObject, _importObject) - ;; - ;; var buffer = fs.readFileSync(inFilePath) - ;; var module = await WebAssembly.compile(buffer) - ;; var instance = await WebAssembly.instantiate(module, importObject) - ;; return instance.exports - ;; } - ;; - ;; const main = function () { - ;; var wasmExports = await instantiate('learn-wasm.wasm') - ;; wasmExports.print_args(1, 0) - ;; } - - ;; Цей код зчитує функції з importObject - ;; (вказано у асинхронній JavaScript функції instantiate), а потім експортує функцію - ;; "print_args", яку ми викликаємо у Node.js - - (import "console" "log" (func $print_i32 (param i32))) - (import "math" "cos" (func $cos (param f64) (result f64))) - - (func $print_args (param $arg0 i32) (param $arg1 i32) - (call $print_i32 (local.get $arg0)) - (call $print_i32 (local.get $arg1)) - ) - (export "print_args" (func $print_args)) - - ;; Завантаження даних з пам'яті WebAssembly. - ;; Наприклад, ми хочемо порахувати cos для елементів Javascript масиву. - ;; Нам потрібно отримати доступ до масиву і можливість ітерувати по ньому. - ;; У прикладі нижче ми змінимо існуючий масив. - ;; f64.load і f64.store приймають адресу числа у пам'яті *у байтах*. - ;; Для того, щоб отримати доступ до 3-го елементу масиву, ми маємо передати щось - ;; накшталт (i32.mul (i32.const 8) (i32.const 2)) у функцію f64.store. - - ;; У JavaScript ми викличемо `apply_cos64` таким чином - ;; (використаємо функцію instantiate з попереднього прикладу): - ;; - ;; const main = function () { - ;; var wasm = await instantiate('learn-wasm.wasm') - ;; var n = 100 - ;; const memory = new Float64Array(wasm.memory.buffer, 0, n) - ;; for (var i=0; i Date: Tue, 8 Oct 2019 11:49:21 +0300 Subject: Fix [wasm/ua] lang param --- uk-ua/wasm-ua.html.markdown | 1 + 1 file changed, 1 insertion(+) (limited to 'uk-ua') diff --git a/uk-ua/wasm-ua.html.markdown b/uk-ua/wasm-ua.html.markdown index b5a1f4dd..34f8cef8 100644 --- a/uk-ua/wasm-ua.html.markdown +++ b/uk-ua/wasm-ua.html.markdown @@ -1,5 +1,6 @@ --- language: WebAssembly +lang: uk-ua filename: learnwasm-ua.wast contributors: - ["Dean Shaff", "http://dean-shaff.github.io"] -- cgit v1.2.3 From 6b5938017b5105066d27484605af8dd88fab183d Mon Sep 17 00:00:00 2001 From: AstiaSun Date: Mon, 28 Oct 2019 01:20:19 +0200 Subject: [mips/uk-ua] Add ukrainian translation for MIPS Assemly --- uk-ua/mips-ua.html.markdown | 366 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 366 insertions(+) create mode 100644 uk-ua/mips-ua.html.markdown (limited to 'uk-ua') diff --git a/uk-ua/mips-ua.html.markdown b/uk-ua/mips-ua.html.markdown new file mode 100644 index 00000000..20fa7638 --- /dev/null +++ b/uk-ua/mips-ua.html.markdown @@ -0,0 +1,366 @@ +--- +language: "MIPS Assembly" +filename: MIPS.asm +contributors: + - ["Stanley Lim", "https://github.com/Spiderpig86"] +translators: + - ["AstiaSun", "https://github.com/AstiaSun"] +lang: uk-ua +--- + +Мова асемблера MIPS (англ. Microprocessor without Interlocked Pipeline Stages) була написана для роботи з мікропорцесорами MIPS, парадигма яких була описана в 1981 році [Джоном Геннессі](https://uk.wikipedia.org/wiki/Джон_Лерой_Геннессі). Ці RISC процесори використовуються у таких вбудованих системах, як маршрутизатори та мережеві шлюзи. + +[Read More](https://en.wikipedia.org/wiki/MIPS_architecture) + +```asm +# Коментарі позначені як'#' + +# Всі символи після '#' ігноруються лексичним аналізатором асемблера. + +# Зазвичай програми поділяються на .data та .text частини + +.data # У цьому розділі дані зберігаються у пам'яті, виділеній в RAM, подібно до змінних + # в мовах програмування вищого рівня + + # Змінна оголошується наступним чином: [назва]: .[тип] [значенння] + # Наприклад: + hello_world: .asciiz "Hello World\n" # Оголосити текстову змінну + num1: .word 42 # word - це чисельний тип 32-бітного розряду + + arr1: .word 1, 2, 3, 4, 5 # Масив чисел + arr2: .byte 'a', 'b' # Масив буквених символів (розмір кожного - 1 байт) + buffer: .space 60 # Виділити місце в RAM + # (не очищується, тобто не заповнюється 0) + + # Розміри типів даних + _byte: .byte 'a' # 1 байт + _halfword: .half 53 # 2 байти + _word: .word 3 # 4 байти + _float: .float 3.14 # 4 байти + _double: .double 7.0 # 8 байтів + + .align 2 # Вирівнення пам'яті даних, де число + # показує кількість байтів, вирівнених + # у степені 2. (.align 2 означає + # чисельне (word) вирівнювання оскільки + # 2^2 = 4 байти) + +.text # Розділ, що містить інструкції та + # логіку програми + +.globl _main # Оголошує назву інструкції як + # глобальну, тобто, яка є доступною для + # всіх інших файлів + + _main: # програми MIPS виконують інструкції + # послідовно, тобто першочергово код + # буде виконуватись після цієї позначки + + # Виведемо на екран "hello world" + la $a0, hello_world # Завантажує адресу тексту у пам'яті + li $v0, 4 # Завантажує значення системної + # команди (вказуючи тип функціоналу) + syscall # Виконує зазначену системну команду + # з обраним аргументом ($a0) + + # Регісти (використовуються, щоб тримати дані протягом виконання програми) + # $t0 - $t9 # Тимчасові регістри використовуються + # для проміжних обчислень всередині + # підпрограм (не зберігаються між + # викликами функцій) + + # $s0 - $s7 # Збережені регісти, у яких значення + # збегіраються між викликами підпрограм. + # Зазвичай збегрігаються у стеку. + + # $a0 - $a3 # Регістри для передачі аргументів для + # підпрограм + # $v0 - $v1 # Регістри для значень, що повертаються + # від викликаної функції + + # Типи інструкції завантаження / збереження + la $t0, label # Скопіювати адресу в пам'яті, де + # зберігається значення змінної label + # в регістр $t0 + lw $t0, label # Скопівати чисельне значення з пам'яті + lw $t1, 4($s0) # Скопівати чисельне значення з адреси + # пам'яті ресгіста зі зміщенням в + # 4 байти (адреса + 4) + lb $t2, label # Скопіювати буквений символ в частину + # нижчого порядку регістра $t2 + lb $t2, 0($s0) # Скопіювати буквений символ з адреси + # в $s0 із зсувом 0 + # Подіне використання і 'lh' для halfwords + + sw $t0, label # Збегігти чисельне значення в адресу в + # пам'яті, що відповідає змінній label + sw $t0, 8($s0) # Збегігти чисельне значення в адресу, + # зазначеній у $s0, та зі зсувом у 8 байтів + # Така ж ідея використання 'sb' та 'sh' для буквених символів та halfwords. + # 'sa' не існує + + +### Математичні операції ### + _math: + # Пам'ятаємо, що попередньо потрібно завантажити данні в пам'ять + lw $t0, num # Із розділа з данними + li $t0, 5 # Або безпосередньо з константи + li $t1, 6 + add $t2, $t0, $t1 # $t2 = $t0 + $t1 + sub $t2, $t0, $t1 # $t2 = $t0 - $t1 + mul $t2, $t0, $t1 # $t2 = $t0 * $t1 + div $t2, $t0, $t1 # $t2 = $t0 / $t1 (Може не підтримуватись + # деякими версіями MARS) + div $t0, $t1 # Виконує $t0 / $t1. Отримати частку можна + # за допомогою команди 'mflo', остаток - 'mfhi' + + # Bitwise Shifting + sll $t0, $t0, 2 # Побітовий здвиг вліво з безпосереднім + # значенням (константою) 2 + sllv $t0, $t1, $t2 # Здвиг вліво зі змінною кількістю у + # регістрі + srl $t0, $t0, 5 # Побітовий здвиг вправо (не збегігає + # знак, знак розширюється 0) + srlv $t0, $t1, $t2 # Здвиг вправо зі змінною кількістю у + # регістрі + sra $t0, $t0, 7 # Побітовий арифметичний збвиг вправо + # (зберігає знак) + srav $t0, $t1, $t2 # Здвиг вправо зі змінною кількістю у + # регістрі + + # Bitwise operators + and $t0, $t1, $t2 # Побітове І (AND) + andi $t0, $t1, 0xFFF # Побітове І з беспосереднім значенням + or $t0, $t1, $t2 # Побітове АЛЕ (OR) + ori $t0, $t1, 0xFFF # Побітове АЛЕ з беспосереднім значенням + xor $t0, $t1, $t2 # Побітова виключна диз'юнкція (XOR) + xori $t0, $t1, 0xFFF # Побітове XOR з беспосереднім значенням + nor $t0, $t1, $t2 # Побітова стрілка Пірса (NOR) + +## Розгалуження ## + _branching: + # В овсновному інструкції розгалуження мають наступну форму: + #