RSL
RSL или Object RSL (аббр. от англ. R-Style Language) — объектно-ориентированный, предметно-ориентированный, интерпретируемый, проприетарный язык программирования, разработанный компанией R-Style Softlab для использования в своих программных продуктах.
RSL | |
---|---|
Класс языка | |
Тип исполнения | интерпретируемый |
Появился в | 1994 |
Автор | Сергей Кубрин |
Расширение файлов |
. |
Выпуск | 1151[1] (19 марта 2015) |
Система типов | динамическая |
Основные реализации | RS-Bank, InterBank, RS-Securities, RS-Payments |
Сайт | softlab.ru |
Среда разработки под названием «Оболочка RSL» включает в себя:
- текстовый редактор с двумя вариантами подсветки синтаксиса[2]
- отладчик
- интерпретатор / прекомпилятор
- редактор консольных диалоговых окон
- редактор структур БД Pervasive PSQL
- редактор графических отчётов Visual RSL
- SDK для создания подключаемых модулей на языке C DLM SDK
RSL также называют макроязыком, а программы на нём — макросами. Инструменты для создания и отладки программ на RSL доступны для свободного скачивания на сайте разработчика, однако такие макросы не должны содержать вызовов модулей, содержащих бизнес-логику и встроенных в основные программы R-Style Softlab. Интерпретатор реализован под Windows, позволяет работать под Wine. Ранние версии поддерживали MS-DOS.
Поддержка RSL встроена во все подсистемы АБС RS-Bank, а также InterBank, RS-Payments.
История
- 1994 — Создание языка RSL.
- 10.02.1997 — Возможность подключения модулей на C, C++ (DLM-модулей).
- 25.06.1997 — Поддержка объектов, создаваемых в среде выполнения RSL-программ.
- 10.07.1997 — Первый Object RSL.
- 16.03.1998 — Стандартный класс динамических массивов
TArray()
. - 21.04.1998 — DLM-модуль RSLX для поддержки ActiveX-объектов.
- 07.05.1998 — Стандартный класс
TbFile()
. - 21.05.1998 — Обработка ошибок при помощи конструкции
OnError()
и классаTrslError()
. - 25.04.2001 — Процедуры для взаимодействия с отладчиком.
- 29.11.2001 — Интеграция в RSL расширения для работы с терминалом (трёхуровневая архитектура) и новые универсальные функции для работы с файлами как на стороне сервера, так и на стороне терминала.
- 23.05.2002 — Базовая поддержка RSCOM (аналог технологии MS DCOM) в стандартном модуле RCW.
- 16.04.2003 — Поддержка модулей платформы .NET.
Модули языка
RSLSRV
Модуль RSLSRV регистрирует в системе объект RSLSrv.RslEngine, который позволяет использовать макрос на RSL как объект ActiveX. Глобальные переменные макроса становятся свойствами, а процедуры — методами. Например, пусть существует макрос myactivex.mac:
var str1:String = "Test string"; macro func1(a) return a*a; end;
тогда можно использовать следующий код на Visual Basic:
Sub TestRSL()
Set eng = CreateObject("RSLSrv.RslEngine")
Set MyObj = eng.LoadModule("myactivex.mac")
Debug.Print MyObj.str1 ' печатает Test string
Debug.Print MyObj.func1(2) ' печатает 4
End Sub
RSD
RSD — библиотека предназначена для универсального доступа к источникам данных, поддерживающим SQL, из программ на языках C++ и RSL. Объектная модель построена на основе ADO.
Библиотека имеет несколько уровней (каждый последующий уровень базируется на предыдущем: большую часть функциональности делегирует нижележащему уровню):
- Драйверы: а) Драйвер источника данных для обеспечения низкоуровневого доступа к сервисам библиотеки из языка C. Интерфейс универсален, но реализация специфична для источника данных. В настоящее время имеется драйвер для ODBC. б) Драйвер универсального набора записей (Recordset), который обеспечивает унифицированный навигационный доступ к данным.
- Классы C++ и объектно-ориентированный интерфейс доступа к данным, независимый от конкретного источника.
- Классы RSL и интерфейс для доступа из RSL.
Уровни 1 и 2 реализованы в виде DLL, а уровень 3 — как DLM.
RSLX
RsEngine
Windows Reports
Windows Reports — объектно-ориентированная библиотека для вывода отчётов в форматы офисных приложений MS Excel, MS Word, Internet Explorer. Библиотека основана на технологиях RSCOM и ActiveX. Большая часть написана на RSL, также в состав входят DLM-модули.
Работа с базами данных
RSL имеет встроенную поддержку работы с базами данных (БД), управляемых Pervasive PSQL (ранее Btrieve и Pervasive.SQL). Словари БД имеют расширение .def
(аналог .ddf
), файлы таблиц БД — .dbt
(аналог .mkd
). Также есть возможность работать с файлами БД .dbf
. Работа с SQL организована с использованием ADO через модуль RSLX и библиотеки RSD.
Синтаксис и языковые конструкции
В части синтаксиса RSL имеет общие черты с языками C++ и Pascal. Например, присваивание и операции сравнения «равно», «неравно» записываются так же, как и в C++ (=
, ==
, !=
). А логические операции — как в Pascal (and
, or
, not
).
Комментарии
RSL (аналогично C++) поддерживает комментарии двух типов: многострочные и однострочные.
/*
Пример большого комментария,
состоящего из нескольких строк
*/
// Вся оставшаяся часть строки является комментарием
Язык RSL разрешает наличие вложенных комментариев обоих типов как по отдельности, так и вместе.
Типы данных
Все поддерживаемые типы данных в RSL разделяются на скалярные и объектные.
Скалярные типы:
- Целочисленный:
Integer
. - С плавающей точкой:
Double
. - Двоично-десятичное число с плавающей точкой:
Decimal
,Numeric
. - Тип для денежных величин:
Money
. - Строковый:
String
. - Логический:
Bool
(имеющий значенияTRUE
иFALSE
). - Дата:
Date
. - Время:
Time
. - Дата и время:
DateTime
. - Адрес памяти:
MemAddr
. - Ссылка на процедуру RSL:
ProcRef
. - Ссылка на метод объекта RSL:
MethodRef
. - Тип специальных значений «Нулевое значение» и «Умалчиваемое значение»:
SpecVal
(имеющий значенияNullVal
иOptVal
). - Специальное значение «Пусто» без типа:
NULL
. - Обобщённый тип:
Variant
.
Объектные типы:
- Ссылка на объект «файл базы данных»:
Tbfile
. - Ссылка на объект «структура в памяти»:
TRecHandler
. - Ссылка на объект «массив значений»:
TArray
. - Ссылка на объект «текстовый файл»:
TStreamDoc
. - Ссылка на любой объект RSL-класса:
Object
.
В RSL предусмотрено неявное и явное преобразование из одного типа данных в другой.
- Неявное (автоматическое) преобразование происходит в следующих случаях:
- Когда в арифметической операции участвуют два операнда разных типов, для которых не определена явная процедура вычисления операции, происходит преобразование типа операнда с меньшим «весом» типа к типу операнда с большим «весом» типа. Ниже представлены варианты преобразования типов в соответствии с их «весами»:
Integer
→Double
→Numeric
→String
. - При присвоении переменной значения с типом, отличным от того, который был ей декларирован.
- При использовании в условных выражениях инструкций
if
иwhile
значений не булевого типа. В таком случае произойдет попытка преобразования в булев тип.
- Когда в арифметической операции участвуют два операнда разных типов, для которых не определена явная процедура вычисления операции, происходит преобразование типа операнда с меньшим «весом» типа к типу операнда с большим «весом» типа. Ниже представлены варианты преобразования типов в соответствии с их «весами»:
- Явные преобразования выполняются при помощи специальных процедур:
Int()
,Double()
,Decimal()
,Numeric()
,String()
,Money()
и др.
Объектно-ориентированные особенности языка
В 1997 году язык RSL стал объектно-ориентированным и изменил название на Object RSL[3]. Он вводит классы, которые обеспечивают три самых важных свойства объектно-ориентированного программирования (ООП): инкапсуляцию, наследование и полиморфизм.
Объекты
В RSL (в отличие от других языков программирования, к примеру, от C++) конструирование объектов происходит в два этапа:
- Создание объекта: выделение памяти с учётом [[Наследование (программирование)|иерархии наследования]], построение списков замен [[Виртуальный метод|виртуальных методов]], всем свойствам класса присваивается значение NULL. После этого, поскольку объект не содержит не-инициализированных данных, он готов к корректному разрушению.
- Инициализация объекта: вызов метода
Init
. Если инициализацию необходимо выполнить для класса-родителя, то его методInit
следует вызвать явно при инициализации класса-наследника.
Таким образом, в классах RSL деструкторы, определяемые пользователем, не применяются (объекты и их свойства удаляются автоматически).
Наследование
В RSL наследование позволяет описать новый класс на основе уже существующего (родительского, базового) класса. Таким образом, все методы и свойства класса-родителя также становятся методами и свойствами класса-наследника. Кроме этого, класс-наследник может добавлять свои свойства и методы или переопределять методы класса-родителя. Наследование позволяет строить иерархии классов. Множественное наследование в RSL запрещено.
При наследовании имя класса-родителя указывается в круглых скобках после ключевого слова Class
. Для инициализации класса-родителя необходимо вызвать предопределенный метод, название которого образуется путём добавления к имени класса-родителя приставки Init
.
Пример наследования классом Employee («Сотрудник») класса Person («Персона»), при добавлении к нему свойства Post («Должность»):
Class Person (Name, Surname) // Список свойств и методов класса Person end;
Class (Person) Employee (Name, Surname, Post) InitPerson (Name, Surname); // Инициализация класса Person в классе Employee Macro Report() println("Post: ", Post); end; end;
Инкапсуляция
В RSL инкапсуляция реализуется через указание уровня доступа к свойствам и методам класса, а также к переменным и процедурам макромодуля.
- В основной части макромодуля все переменные, процедуры и классы, объявленные без модификатора доступа, по умолчанию являются глобальными. Они становятся доступными не только внутри макромодуля, но и во всех остальных макромодулях, которые его импортируют. Также переменные можно сделать принудительно глобальными (об этом см. далее).
- Модификатор доступа
private
позволяет объявлять переменные, процедуры и классы как приватные, что накладывает запрет на доступ к ним извне. Этот модификатор является аналогом модификатораprotected
в C++. - С помощью модификатора
local
можно объявлять переменные, объекты и процедуры как локальные. Локальные переменные доступны только локальным процедурам. Невозможно обратиться к локальной переменной внутри любой другой процедуры макромодуля.
|
- Если указать модификатор
local
перед свойством класса, то оно перестает быть свойством класса, как таковым, и становится локальной переменной конструктора. Таким образом, модификаторlocal
применим только для процедур инициализации модуля и конструктора класса.
- Для получения доступа напрямую к переменным, которые находятся внутри процедур, нужно сделать их принудительно глобальными. Это осуществляется путём взятия их в фигурные скобки (
{}
):
|
- При этом
a
и{a}
— разные переменные. Если свойство класса взять в фигурные скобки, то оно перестанет быть свойством, как таковым, и стает глобальной переменной макромодуля. Обращение к нему будет осуществляться напрямую по имени, а не через ссылку на объект класса.
Уровни доступа к свойствам и методам класса:
Доступ | Локальный (local) |
Приватный (private) |
Глобальный | Принудительно глобальный |
В самом классе | да / нет | да | да (через объект класса) |
да |
В наследниках | нет | да | да (через объект класса) |
да |
Извне | нет | нет | да (через объект класса) |
да |
Уровни доступа к переменным, процедурам и объектам макромодуля:
Доступ | Локальный (local) |
Приватный (private) |
Глобальный | Принудительно глобальный |
В макромодуле | да / нет | да | да | да |
В модулях, которые импортируют данный |
нет | нет | да | да |
Полиморфизм
Все методы классов RSL являются виртуальными. Так, RSL реализует полиморфизм включения (или чистый полиморфизм) посредством наследования. При добавлении в классе-наследнике метода с именем, которое уже используется для одного из методов класса-родителя, метод наследника переопределит метод родителя. К методу родителя доступ будет только из метода наследника, который его переопределяет. Обращение к этому методу родителя осуществляется по его имени. Но в классе-наследнике вне переопределяющего метода не будет доступа к переопределенному методу родителя. Также станет невозможным обратиться к этому методу класса-родителя через ссылку на объект класса-наследника в основной части программы.
Class First() // Класс-родитель Var x = 2, y = 3;
Macro Sum() return x + y; end; end;
Class (First) Second() // Класс-наследник InitFirst(); Var a = 100;
Macro Sum() // Начало переопределения родительского метода Sum() return Sum() + a; // Использование родительского метода Sum() в методе Sum() наследника end; // Конец переопределения родительского метода Sum()
Macro Sum2() return Sum() + a; // Использование метода Sum() наследника end; end;
obj = Second(); // Создание объекта класса Second()
println(obj.Sum()); // Результат: 105 println(obj.Sum2()); // Результат: 205
Если в этом примере из класса-родителя убрать метод Sum()
, то в классе-наследнике произойдет рекурсивный вызов метода Sum()
.
Другое
Объявлять переменные и указывать их тип не обязательно. Операторы сравнения имеют более высокий приоритет, чем логические операторы. Например, если надо выполнить «действие» в том случае, когда переменная a равна 1 или 2, то необходимо применить следующую конструкцию:
if ((a == 1) or (a == 2)) // действие end;
Выполнение программы начинается с первой инструкции, не входящей в класс или процедуру, как в php.
macro func1 [I'm function 1]; end; // выполнение начнётся здесь [Let's go!];
Примеры программ
Программа «Hello, world!» на RSL[4]:
[Hello, world!];
Квайн на RSL (форматирование для удобства чтения):
s="''s=Print(SubStr(s,1,2)+StrFor(34)+s+StrFor(34)+StrFor(59)+SubStr(s,3));''"; Print(SubStr(s,1,2)+StrFor(34)+s+StrFor(34)+StrFor(59)+SubStr(s,3));
Примечания
- Для RS-Bank V. 5.50.003.58
- Для консольного режима и режима EasyWin.
- Но язык также продолжают сокращенно называть «RSL».
- RSL in The Hello World Collection (недоступная ссылка). Дата обращения: 28 июня 2009. Архивировано 5 декабря 2011 года.
Ссылки
- Кубрин С. Object RSL — объектно-ориентированная версия языка RSL. — М.: RS-Club, 1997. — № 4. — С. 63-67. Архивировано 21 апреля 2015 года.
- R-Style Softlab: форум по RSL, исходники на RSL
- Домашняя страница одного из ведущих разработчиков Сергея Кубрина
- Byte Россия. Создание контейнеров элементов управления ActiveX
- Мир ПК. Visual RSL — объектно-ориентированный генератор отчётов