Inferno Programmer's Guide / Руководство программиста по ОС Inferno: Chapter 3 - Limbo Programming

← →
Английский оригинал Перевод на русский

Сожалеем, но текст оригинала доступен только зарегистрированным пользователям.

Программирование на Limbo

rapidfx 30.04.09 в 09:23

0

Обзор

rapidfx 30.04.09 в 09:23

0

В этой главе делается обзор возможностей, которые важны как для Limbo-программирования, так и в программном окружении Inferno.

В этой части описываются:
* Модули
* I/O
* Нити
* Каналы
* Графическое программирование

rapidfx 30.04.09 в 09:26

0

Модули

rapidfx 30.04.09 в 09:26

0

В Limbo модули - основной строительный материал для программ. Про каждую программу можно сказать - это "модуль".
Limbo-модули не только делят программу на меньшие части, а еще:
* Группируют функции и данные в логичные, отдельные пакеты
* Отделяет интерфейс от его реализации
* Имеют хорошо определенный интерфейс, который предоставляет механизм доступа к модулю
* Тип определенный через его интерфейс
* Предоставляют динамически загружаемые библиотеки
* Могут быть переписаны без перекомпиляции или перекомпоновки программы пользователем
* Составлять Limbo-приложение как набор взаимодействующих компонентов содержащих данные и функции.

wuffur 30.04.09 в 13:38

0

Интерфейс и реализация

j1m 30.04.09 в 09:41

0

Limbo-модули могут сочетать интерфейс и реализацию. Программа Greet (приветствие!) показанная в программном листинге 2-1 на странице 2-2 - пример этого. В данном случае только функция init объявлена в объявлении модуля и поэтому, ей можно пользоваться вне ее.
Вместе с модульной моделью программирования на Limbo, разделение интерфейса и реализации важная концепция. Это означает, что программа на Limbo может динамически загружать и выгружать модули или библиотеки.

wuffur 30.04.09 в 13:48

0

Inferno Reference API иллюстрирует мощь этого на Limbo. Функциональность групп программного интерфейса (API) описывается в небольших подгружаемых модулях. У них хорошо определен интерфейс, который содержится в файлах интерфейса модуля. Исполняемый код содержится в файле реализации.

wuffur 30.04.09 в 13:53

0

Inferno Reference API иллюстрирует мощь этого в Limbo. API группирует функциональность в небольшие загружаемые модули, с хорошо определенными интерфейсами содержащимися в файлах-интерфейсах модулей. Исполняемый код содержится в файле реализации

rapidfx 04.05.09 в 18:21

0

Файл интерфейса модуля

j1m 30.04.09 в 10:27

0

Интерфейс public доступа к модулю содержится в файле его интерфейса, они по соглашению с имеют расширение ".m". Это аналогично заголовочным файлам на C/C++ (.h).
The Inferno Reference API по соглашению хранится в директории /module.
Файл интерфейса модуля определяет public данные и функции члены. Там определен типы и интерфейсы функций, которые могу использоваться другими программами. Это определение интерфейса модуля.
Программа 3-1 - пример простого файла интерфейса модуля:

wuffur 30.04.09 в 14:12

0

1 Greet: module {
2 init: fn(ctxt: ref Draw->context, argv: list of string);
3 };

j1m 30.04.09 в 10:24

0

Это объявление одной функции - init.
Листинг программы 3-2 показывает другой пример небольшой программы, модуль Random генерации случайных числе из Inferno Reference API(/module/rand.m)

rapidfx 30.04.09 в 17:13

0
+2

1 Rand: module
2 {
3 PATH: con "/dis/lib/rand.dis";
4 # init sets a seed
5 init: fn(seed: int);
6 # rand returns something in 0 .. modulus-1
7 # (if 0 < modulus < 2^31)
8 rand: fn(modulus: int): int;
9 # (if 0 < modulus < 2^53)
10 bigrand: fn(modulus: big): big;
11 };

wuffur 30.04.09 в 14:24

0

Здесь определена строковая константа PATH, в которой содержится путь к скомпилированному файлу реализации и трем функция init, rand и big rand. Строковая константа PATH - соглашение в Limbo-модулях.

wuffur 30.04.09 в 14:27

0

Файл реализации

j1m 30.04.09 в 10:25

0

Реализация модуля содержится в его файле реализации, который по соглашению находится в файле с расширением .b. Это исполняемый оператор программы. Также он может называться файлом с исходниками. Пример файлов реализации находится в ветке /appl.
Листинг программы 3-2 - файл реализации для файла интерфейса модуля показанного в листинге программы 3-1:
Program Listing 3-3 greet.b
1 implement Greet;
2
3 include "sys.m";
4 include "draw.m";
5 include "greet.m";
6
7 sys: Sys;
8
9 init(ctxt: ref Draw->context, argv: list of string) {
10 sys = load Sys Sys->PATH;
11
12 if ((tl argv) != nil)
13 sys->print("Hello, %s!\n", hd (tl argv));
14 else
15 sys->print("Hello, wor1d!\n");
16 }

wuffur 30.04.09 в 14:29

0

Файл реализации содержит определение функции, которое объявлено в файле интерфейса модуля.
Файл реализации может также содержать private данные и объявление функций членов и определение.
Например, файл реализации модуля Random (генерации случайных чисел)
(/appl/lib/rand.b )

wuffur 30.04.09 в 14:43

0

1 implement Rand;
2
3 include "rand.m";
4
5 rsalt: big;
6
7 init(seed: int)
8 {
9 rsalt = big seed;
10 }
11
12 MASK: con (big l«63)-(big 1);
13
14 rand(modulus: int): int
15 {
16 rsalt = rsalt * big 1103515245 + big 12345;
17 if(modulus <= 0)
18 return 0;
19 return int (((rsalt&MASK)»10) % big modulus);
20 }
21
22 bigrand(modulus: big): big
23 {
24 rsalt = rsalt * big 1103515245 + big 12345;
25 if(modulus <= big 0)
26 return big 0;
27 return ((rsalt&MASK)»10) % modulus;
28 }

j1m 30.04.09 в 10:26

0

В этом файле находятся определяние трех public членов, init, rand и big rand, также как и private члены, такие как rsalt или MASK.

wuffur 30.04.09 в 14:53

0

Исполняемый файл

j1m 30.04.09 в 10:27

0

Скомпилированный файл реализации - это исполняемый файл с расширением (.dis) по соглашению находится в директории /dis.
Исполняемый файл - это объект который загружается во время исполнения. Это происходит с помощью оператора load.
Например для загрузки rand, dis-файл, оператор загрузки выглядит так:
rand := load Rand Rand->PATH;
Это подробнее обсуждается на странице 3-9.

wuffur 30.04.09 в 14:57

0

Структура модуля

j1m 30.04.09 в 10:27

0

Основная структура Limbo-модулей включает следующее:
* Секция реализации
* Объявление интерфейса модуля( необходимо всем файлам)
* Определение функций ( нужно только для файлов реализации)

wuffur 30.04.09 в 14:59

0

Секция Implementation

j1m 30.04.09 в 10:28

0

Секция реализации внутри Limbo-модуля определяет, какой модуль реализуется. Вначале находится оператор implement, как здесь:
implement Greet;
По соглашению оператор include также внутри секции реализации. Например:
include "sys.m"; include "draw.m";

wuffur 30.04.09 в 15:05

0

Объявление интерфейса модуля

j1m 30.04.09 в 10:28

0

Объявление интерфейса модуля определяет public доступную часть модули. Она включает все public типы и функции. Если у модуля есть отдельный файл модуль интерфейса - .m файл, то он содержит объяление этого интерфейса. Например:
Greet: module {
init: fn(ctxt: ref Display->Draw, args: list of string);
};

wuffur 30.04.09 в 15:12

0

Здесь говориться, что Greet - модуль. Интерфейс public доступа происходит через функцию init, которая принимает два аргумента.

wuffur 30.04.09 в 15:28

0

Определение функций

j1m 30.04.09 в 10:29

0

Определение функции которая объявлена в модуле интерфейса и в файле реализации. В не зависимости, является ли модуль интерфейса отдельным файлом, или он находится в файле реальзации, определение функции остается тем же самым.
Например, нижеследующее является определением функции объявленой в модуле-интерфесе Greet:

rapidfx 30.04.09 в 17:25

0
+1

init(ctxt: ref Draw->context, argv: list of string) {
sys = load sys Sys->PATH;
if ((tl argv) != nil)
sys->print("He"l"lo, %s!\n", hd (tl argv)); else
sys->print("He"l"lo, wor1d!\n");
}

j1m 30.04.09 в 10:30

0

Использование модулей

j1m 30.04.09 в 10:30

0

Данные модуля и члены функции доступные путем включения файла модуля-интерфейса и загрузки файла-реализации в код программы Limbo.

rapidfx 30.04.09 в 17:28

0

Оператор include

j1m 30.04.09 в 10:30

0

Как упоминалось ранее, в Limbo, слово include является зарегистрированным, а не директивой препроцессора. Выражение include указывает файл модуля-интерфейса (.m) который вы хотите включить в свою программу. Это необходимо сделать перед тем как вы загрузите или воспользуетесь данными этого модуля или функциями-членами .
Имя файла следующее за ключевым словом include всегда заключено в двойные кавычки (например, " sys.m"). Если не указан явный пусь к файлу, Limbo ищет его текущей рабочей директории. Если файл не найден, он ищется в директориях указанных в опции -l компилятора Limbo. Если и это не удается, он ищется в каталоге /module.

rapidfx 30.04.09 в 17:36

0

Оператор load

j1m 30.04.09 в 10:30

0

Перед вызовом функций модуля приложение должно загрузить модуль.
Приложение использует результирующий дескриптор для описания модуля.
Например:
sys = load Sys Sys -> PATH;
mymod= load MyMod "/mymodules/mymod.dis";
Основная форма оператора load такова:
handle = load имя_модуля путь_к_модулю_реализации;

wuffur 30.04.09 в 20:19

0

Как показано в модулях из Inferno Reference API, соглашение об объявлении константы PATH находится в модуле, который содержит явный путь к файлу реализации. (Более подробно об Inferno Reference API смотрите Inferno Reference Manual)
Используйте оператор взятия члена модуля (->) для доступа к членам данным и членам функциям модуля.
Например:

wuffur 01.05.09 в 04:44

0

sys := load Sys Sys->PATH;
sys->print("Hello, world!\n");
В первой строке, переменная sys объявлена и ей присвоен тип дескриптора модуля Sys. Во второй сточке дескриптор sys используется для доступа к функции print с помощью оператора ->.
Модуль Sys использует специальную константу PATH:
sys: module {
PATH: con"$Sys" ;
}
Константа "$Sys" показывает, что это встроенный модуль. Функции встроенные в модуль - это код на C написанной для системы Inferno, не реализованный на Limbo и откомпилированный в файл .dis. В другие встроенные модули входят:
Draw, Keyring, Loader, Math, Prefab и Tk.

wuffur 01.05.09 в 19:16

0

Оператор import

j1m 30.04.09 в 10:31

0

Это необходимо для уточнения имен модуля соответствующим дескриптором модуля.
Для того чтобы сделать код на Limbo менее многословным, вы можете использовать оператор import, чтобы привести указанные типы и функции в текущую область видимости. Например, использование оператор import изменит код написанный ранее, теперь он будет похожим на это:
sys := load Sys Sys->PATH;
print: import sys;
print("Hello, world!\n");

wuffur 01.05.09 в 19:27

0
+1

По соглашению оператор statement следует за оператором include или оператором объявления дескриптора. Так у импортируемых данных или функции внутри модуля область видимости становится глобальной (доступны все функциям внутри модуля). Например, мы можем изменить программу Greet для импорта функции print.
Листинг программы 3-5 greetimport.b

wuffur 01.05.09 в 19:31

0

1 implement command;
2
3 include "sys.m";
4 include "draw.m";
5
6 sys: sys;
7 print: import sys;
8
9 Command: module {
10 init: fn(ctxt: ref Draw->context, argv: list of string); 11 };
12 init(ctxt: ref Draw->context, argv: list of string) {
13 sys = load sys Sys->PATH;
14
15 if ((tl argv) != nil)
16 print("Hello, %s!\n", hd (tl argv));
17 else
18 print("Hello, world!\n");
19 }

j1m 30.04.09 в 10:31

0

На 7ой строке, оператор import следует за объявлением дескриптора модуля Sys (строка 6). Далее функция может быть доступна как локальная, без квалификатора дескриптора модуля (строки 16 и 18).

wuffur 01.05.09 в 19:37

0

Ввод-вывод (I/O)

Функциональность ввода и вывода (I/O) - важный аспект виртуальности всех Limbo-программ.
Функции ввода-вывода на Limbo предоставляются Inferno Reference API.The Inferno Reference API описано подробнее в его справочном руководстве(Inferno Reference Manual).
Базовый ввод-вывод на Limbo содержится в модуле System (sys.m). Эти функции похожи на основные небуферизованные UNIX C функции. Большинство примеров до настоящего времени использовало функции ввода-вывода из модуля Sys.

wuffur 01.05.09 в 19:53

0

Другой модуль, буферизованный модуль ввода-вывода (bufio.m), предоставлеят фнкции буферизованного ввода-вывода которые похожи на функции стандарта ANSI C.
Другие модули в Inferno Reference API предоставляют более продвинутые и специализированные функции ввода и вывода, такие как модуль устройства указания (Device Pointer)((devpointer.m)), модуль инфракрасного удаленного контроля (ir.m) и модуль синхронизации ввода-вывода (timedio.m). Limbo-программа может использовать любую из комбинацию функций предоставляемых этими модулями.

wuffur 01.05.09 в 20:02

0

Базовый ввод-вывод

j1m 30.04.09 в 10:31

0

Базовый ввод-вывод - это стандартное средство ввода-вывода на Limbo. Существует восемь основных функций из модуля Sys показанных в таблице 3-1.
Таблица 3-1 базовые функции ввода-вывода в модуле Sys:

wuffur 01.05.09 в 20:05

0

create Создание файла
open Открытие файла
print Форматированная печать на стандартный поток вывода
fprint Форматированная печать в открытый файл
read Чтение открытого файла
write Запись в открытый файл
stream Копирование байтов из источника к месту назначению

wuffur 01.05.09 в 20:09

0

Файловые дескрипторы

j1m 30.04.09 в 10:32

0
Минутку...

Следующая страница →