Бібліотека stdl імпортує вбудовані класи, об’єкти та функції, які необхідні для розробки програм на мові Mash Script, зокрема для роботи з рядками, введенням-виведенням, математичними операціями та іншими можливостями.

У цій публікації акцент робиться на огляді функціоналу, доступного в бібліотеці stdl, а не на базовому синтаксисі. Це зроблено для зручності, щоб ви могли швидко знайти інформацію про те, що міститься в цій бібліотеці, без зайвих пояснень, які можна знайти у інших відповідних довгочитах.

Імпорти

Ось фрагмент коду з імпортом всіх необхідних класів. Ви можете скопіювати цей код до своєї програми замість імпортування stdl, і все має працювати належним чином.

using Array as array; // Масиви
using Dict as dict;   // Словники

using Number as number;   // Дробові та цілі числа 
using String as string;   // Рядки
using Boolean as boolean; // Булеве значення (true, false)

using Type as type;     // Клас, який описує тип
using Module as module; // Клас, який описує модуль

using Function as function; // Клас, який описує функцію

using null; // Клас null (Нічого)
using NaN;  // Клас NaN (Не число)

using Console; // Клас для керування консоллю
using In;      // Клас для введення даних з клавіатури
using Out;     // Клас для виведення даних на консоль

using Math; // Аналог 'math' у python

Ключове слово using імпортує класи з Python для використання в Mash Script. Зверніть увагу, що клас має бути написаний за спеціальними правилами. Ми ще повернемося до цієї теми в майбутньому.

Найближчим часом на цьому профілі буде опубліковано докладний огляд усіх базових типів даних.


Змінні

Змінна endl:

string endl = '\n';

Псевдоніми

Псевдоніми до вбудованих типів:

typedef null void()
    {    }


typedef null dynamic()
    {    }


typedef number int([args], {kwargs}) 
{
    return number(*args, *kwargs).toint();
}


typedef number float([args], {kwargs}) 
{
    return number(*args, *kwargs);
}


typedef number pointer(id_: string | int=&null)
{
    if(typeof(id_) == number)
        { return id_ }
    else
        { return encrypt('' &id_) }
}

Тут ви бачите тип void, який фактично є еквівалентом null. Але void використовується при оголошенні функції, це має суто естетичний сенс:

void main()
{
    /* Тіло... */
}


Псевдоніми можуть обробляти дані, забезпечуючи їх правильність. Наприклад, при оголошенні змінної типу number рекомендується використовувати int або float, щоб уточнити, який саме тип числа ви очікуєте.

int i;          // i = 0
int i { 3.14 }; // i = 3 (Відкидає дробову частину)

int i = 3.14;   // i = 3.14 (Не добре)
float i = 3.14; // i = 3.14 (Так краще)

Змінна i усе одно має тип number, але використання int робить код більш безпечним та зрозумілим для сприйняття.


Функції

Функція isinstance

Функція isinstance призначена для перевірки типу об'єкта obj__ на відповідність одному чи декільком типам, які передаються у параметрі type_or_array.

boolean isinstance(obj__: dynamic, type_or_array: type | array[type])
{
    if(typeof(type_or_array) == array)
    {
        return obj__.__type__ in type_or_array;
    }
    else
    {
        return obj__.__type__ == type_or_array;
    }
}

Якщо type_or_array є одним типом, функція перевіряє, чи співпадає тип об'єкта obj__ з переданим типом і повертає true або false відповідно.

Якщо type_or_array є масивом типів, функція перевіряє, чи належить тип об'єкта obj__ хоча б одному з типів масиву і також повертає true або false:

isinstance('Рядок 1', [number, string]) // true
isinstance('Рядок 2', string) // true
isinstance('Рядок 3', [number, boolean]) // false

Функція assert

Функція assert використовується під час налагодження коду для перевірки, чи є умова істинною. Якщо умова не виконується (повертає false), то генерується виключення AssertionError.

void assert(condition: boolean, msg: string='')
{
    if(!condition)
    {
        Console.error('AssertionError', msg);
    }
}

Наприклад, ви можете використовувати assert для перевірки передумов перед викликом функції, як показано в прикладі нижче:

assert(x > 0, "Значення 'x' має бути більше нуля");

Функція length

Викликати метод __length__ у об'єктів array, string та інших не дуже зручно. Тому існує функція length, аналогічна len у Python.

int length(object_: dynamic)
{
    return object_.__length__();
}
length('Hello')   // 5
length([1, 2, 3]) // 3

Функція split

Функція split розділяє об'єкт на n частин.

Аргументи:

  • object_: dynamic — об'єкт, який потрібно розділити.

  • n: int — кількість частин, на які потрібно розділити об'єкт.

Повертає:

  • Масив, що містить n частин об'єкту. Якщо об'єкт не може бути розділений рівно на n частин, залишкова частина додається як останній елемент масиву.

Функція створює масив pieces, який містить перші n елементів об'єкту, та масив other, який містить залишкову частину. Потім функція об'єднує ці два масиви та повертає результат.

array split(object_: dynamic, n: int)
{
    var pieces: array = [object_[i] for(i in range(n))];
    var other: array = object_[pieces.length() : ];
    return [*pieces, other];
}

Приклади:

split('Hello Name!', 4) // поверне ['H', 'e', 'l', 'l', 'o Name!'].

split('string', 6) // поверне ['s', 't', 'r', 'i', 'n', 'g', ''].

В наступному прикладі змінні name та age отримають значення 'Steve' та 23, а other буде масивом ['Cook', 'Paris'].

array user = ['Steve', 23, 'Cook', 'Paris']; 
string name, age, other = *split(user, 2); 

Функція table

Функція table призначена для створення таблиці з заданими аргументами та організації їх у вказану кількість стовпців.

Аргументи:

  • [args]: dynamic — Аргументи, які будуть відображені у таблиці.

  • columns: int — Кількість стовпців у таблиці. За замовчуванням: 2.

  • {kwargs}: dict — Додаткові іменовані аргументи, передані в Out.table.

Повертає:

  • string: повертає таблицю у вигляді рядка.

string table([args], {kwargs}, columns: int=2)
{
    if(columns < 0)
        return;

    int col = 0;
    array result = [[]];

    foreach(string item in args)
    {
        Out.println(item, col, result);

        if(col == columns) 
        {
            col = 0;
            result << [];
        }

        result[-1] << item;
        col++
    }

    return Out.table(result, *kwargs, file=null);
}

Приклад перший, таблиця 3 на 2:

table(1, 2, 3,
      4, 5, 6,
      columns=3);

Повертає рядок:

╭───┬───┬───╮
│ 1 │ 2 │ 3 │
├───┼───┼───┤
│ 4 │ 5 │ 6 │
╰───┴───┴───╯

Приклад другий, таблиця 2 на 3:

table('Name:', 'Age:',
      'Steve', '23',
      'Alex',  '54',
      tablefmt='html');

Повертає рядок:

<table>
<tbody>
<tr><td>Name:</td><td>Age:</td></tr>
<tr><td>Steve</td><td>23  </td></tr>
<tr><td>Alex </td><td>54  </td></tr>
</tbody>
</table>

Класи

Клас Data

Клас Data реалізує функціонал, схожий на об'єкти JavaScript.

class Data
{
	/* ... */

	string __string__()
	{
		return this.__dict__ &'';
	}
}

Приклад:

void main()
{
    Data flower = new[] Data {
        name: 'Ромашка',
        image: 'https://www.google.com/...',
        other_names: ['роман', 'ромен', 'невістка', 'рум`янок']
    }

    Out.println(flower);
}

Результат:

{'name': 'Ромашка', 'image': 'https://www.google.com/...', 'other_names': ['роман', 'ромен', 'невістка', 'рум`янок']}

Весь файл

/* 
 *
 *    Stdlib
 *
 *    This module provides the standard library for Mash Script.
 *    
 */

using Array as array;
using Dict as dict;

using Number as number;
using String as string;
using Boolean as boolean;

using Type as type;
using Module as module;

using Function as function;

using null;
using NaN;

using Console;
using In;
using Out;

using Math;


/* variables */

string endl = '\n';




/* typedefs */

typedef null void()
    {    }


typedef null dynamic()
    {    }


typedef number int([args], {kwargs}) 
{
    return number(*args, *kwargs).toint();
}


typedef number float([args], {kwargs}) 
{
    return number(*args, *kwargs);
}


typedef number pointer(id_: string | int=&null)
{
    if(typeof(id_) == number)
        { return id_ }
    else
        { return encrypt('' &id_) }
}




/* Decorators */

function classmethod(func_: function)
{
    dynamic wrapper(this: dynamic, [args], {kwargs})
    {
        func_(this.__type__, *args, *kwargs);
    }

    wrapper.set_name(func_.__name__);

    return wrapper;
}




/* functions */

boolean isinstance(obj__: dynamic, type_or_array: type | array[type])
{
    if(typeof(type_or_array) == array)
    {
        return typeof(obj__) in type_or_array;
    }
    else
    {
        return typeof(obj__) == type_or_array;
    }
}


void assert(condition: boolean, msg='')
{
    if(!condition):
        Console.error('AssertionError', msg);
}


int length(object_: dynamic)
{
    return object_.__length__();
}


array split(object_: dynamic, n: int)
{
`    split(object: dynamic, n: int) -> array

    Splits an object into n pieces.

    Arguments:
    - object_: dynamic - The object to split.
    - n:       int - The number of pieces to split the object into.

    Returns:
    - Array - An array containing n pieces of the object. If the object cannot be evenly split into n pieces, the remaining part is appended as the last element of the array.

    Example 1:
    split('Hello Name!', 4)  => ['H', 'e', 'l', 'l', 'o Name!']

    Example 2:
    split('string', 6)       => ['s', 't', 'r', 'i', 'n', 'g', '']

    Example 3:
    array user = ['Steve', 23, 'Cook', 'Paris'];
    string name, age, other = *split(user, 2);

    // prints: Steve 23 ['Cook', 'Paris']
    Out.print(name, age, other);                
    `
    var pieces: array = [object_[i] for(i in range(n))];
    var other: array = object_[pieces.length() : ];
    return [*pieces, other];
}


string table([args], {kwargs}, columns: int=2)
{
`    tabletable([args], \{kwargs\}, columns: int=2) -> string

    Returns a table with the given arguments, organizing them into the specified number of columns.

    Arguments:
    - [args]:   dynamic  - The arguments to be displayed in the table.
    - columns:  int  - The number of columns in the table. Default is 2.
    - \{kwargs\}: dict - Additional keyword arguments passed to Out.table.

    Returns:
    - string: returns the table as a string.

    Example 1:                ╭───┬───┬───╮
    table(1, 2, 3,            │ 1 │ 2 │ 3 │
          4, 5, 6,        =>  ├───┼───┼───┤
          columns=3           │ 4 │ 5 │ 6 │
    );                        ╰───┴───┴───╯

    Example 2:
    table('Name:', 'Age:',
          'Steve', '23',
          'Alex',  '54',
          tablefmt='html');

    // returns:
    <table>
    <tbody>
    <tr><td>Name:</td><td>Age:</td></tr>
    <tr><td>Steve</td><td>23  </td></tr>
    <tr><td>Alex </td><td>54  </td></tr>
    </tbody>
    </table>
    `;

    if(columns < 0)
        return;

    int col = 0;
    array result = [[]];

    foreach(let item: string in args)
    {
        Out.println(item, col, result);

        if(col == columns) 
        {
            col = 0;
            result << [];
        }

        result[-1] << item;
        col++
    }

    return Out.table(result, *kwargs, file=null);
}




/* classes */

class Data
{
    dict all()
    {
        return this.__dict__;
    }

    string __string__()
    {
        return this.__dict__ &'';
    }
}

Підсумок

Завдяки бібліотеці stdl, розробники можуть швидко створювати програми на мові Mash Script за допомогою функцій та класів, які надає ця бібліотека. Тут також вже вказані імпорти всіх основних класів. Детальні описи кожного елементу бібліотеки надаються в окремих довгочитах.

Плескайте, залишайте свої коментарі та думки про те, як можна покращити цю мову!

Поділись своїми ідеями в новій публікації.
Ми чекаємо саме на твій довгочит!
Romashka
Romashka@Romashka

Створюю інтерпретатор Mash Src

99Прочитань
1Автори
1Читачі
На Друкарні з 16 березня

Більше від автора

  • Mash Script: Базовий синтаксис

    Опис базової структури програми написаної мовою Mash Script

    Теми цього довгочиту:

    Programming
  • λanguage: Написання парсера

    Написання парсера - це досить складне завдання. У сутності, він повинен перетворити фрагмент коду у "абстрактне синтаксичне дерево". Це структуроване представлення програми в пам'яті, воно абстрактне в тому сенсі, що не має значення, з яких саме символів складається вихідний код.

    Теми цього довгочиту:

    Парсер

Вам також сподобається

Коментарі (0)

Підтримайте автора першим.
Напишіть коментар!

Вам також сподобається