SmallScript Hello World
SmallScript представляет собой надмножество языка Smalltalk
с поддержкой декларативного скрипто-ориентированного программирования.
Это позволит разработчикам, незнакомым со Smalltalk, работать
в привычном им режиме - написание исходного текста, создание приложения
и его запуск.
SmallScript полностью поддерживает все синтаксические конструкции
стандарта Smalltalk и вводит множество своих. К тому же он поддерживает C-style
конструкции, такие, как условия, циклы, вызов методов, обработка исключения и прочие.
Следует отметить, что синтаксис находится на стадии разработки, поэтому
в будущем возможны изменения.
В своих примерах мы будем придерживаться максимальной совместимости
с классическим Smalltalk.
Компиляция и запуск
В состав SmallScript.AOS SDK входят две утилиты - cssc.exe и wssc.exe.
Первая из них служит для создания/запуска консольных приложений, вторая - для визуальных
и системных.
Стандартные расширения исходных файлов SmallScript - .ss, .ssc, .ssw.
Два последних явно указывают, какую утилиту использовать при запуске файла с таким расширением.
Такое расширение имеет смысл давать только главному модулю, для остальных можно использовать .ss.
Если передать имя скрипта в одну из утилит, например "cssc myscript.ssс",
то указанный скрипт выполнится. Команды, предназначенные для непосредственного выполнения
должны заключаться в блок Eval [ ... ].
Чтобы скомпилировать исполняемый файл или библиотеку, это нужно указать явно.
cssc -name:myscript -target:exe myscript.ssc
cssc -name:mylibrary -target:dll mylibrary.ss
На выходе будут созданы файлы myscript.exe и mylibrary.dll.
Размер исполняемого файла начинается с 3-х килобайт. Для его запуска требуется
библиотека AOS.DLL из состава SmallScript.AOS.
Аналогичный эффект будет иметь следующая директива в исходном коде:
Module name: myscript.
Compiler cmds: '-target:exe'.
То есть, команда Compiler cmds: '...' аналогична командной строке компилятора.
Для того, чтобы указать точку входа в для исполняемого файла, нужно создать
функцию с атрибутом $entrypoint. В скриптовом режиме такая функция
также будет запущена точто так же, как блок Eval.
Приложение HelloWorld
Создайте файл HelloWorld.ssc, добавьте следующие строки
и запустите его командой "cssc HelloWorld.ssc":
Eval
[
stdout cr << 'Hello World!'
]
Подобным образом в SmallScript можно запускать любые примеры на Smalltalk,
только для этого нужно создать файл с расширением .ssc, все команды
заключить в блок Eval [ ... ] и в качестве последней команды
написать stdout cr << ...
Для того, чтобы можно было сделать из данного скрипта испоняемый файл,
нужно указать его имя и описать функцию, являющуюся точкой входа.
Module name: HelloWorld.
Function [<$entrypoint>
Main
stdout cr << 'Hello World!'
]
Директива включения
Поддерживаются директивы включения исходных файлов и подключения модулей.
Данная команда включает исходный текст MyScript.ss в текущий файл.
Является аналогом #include.
Include path: MyScript.
Модули
Модуль представляет собой завершенную единицу, содержащую в себе любые определения и
имеющую свое пространство имен. Модуль можеть быть включен в состав других модулей
и оформлен отдельностоящим dll или exe файлом.
Объявление модуля должно идти в начале файла и выглядит так:
Module name: MyModule.
Данная команда загружает модуль:
Load module: AOSUnit.
После этого можно использовать объявления, содержащиеся в нем:
Class name: MyTest
extends: AOSUnit.TestCase
{
}
Чтобы включить обласить видимости AOSUnit в свой модуль
и указывать просто TestCase, нужно написать следующую конструкцию:
Module name: MyApplication
imports: AOSUnit.
Load module: AOSUnit.
Имя модуля совпадает с именем соответствующего namespace-а.
Если имя не указано, то по умолчанию принимается DefaultProject.
Создание классов
SmallScript поддерживает декларативный способ описания классов:
Class name: MyClass extends: Object
fields: auto x, y; z;
class_fields: auto instance;
{
Method [
foo: aFoo bar: aBar
" do anything here ... "
]
Class_method [
new
^super new foo: 1 bar: 'xxx'
]
}
Создастся класс MyClass.
У него будут переменные экземпляра x, y, z и переменная класса instance.
Модификатор auto означает, что для указанных переменных будут созданы
соответствующие accessor-методы. Например, для x это будут сообщения #x и #x:,
так, что к этой переменной можно будет образаться извне.
Также будет добавлен метод экземпляра #foo:bar: и метод класса #new.
Для того, что расширить имеющийся класс, используется следующая конструкция:
Class ref.name: Integer
{
Method [
factorial
^self <= 0
ifTrue: [1]
ifFalse: [self * (self - 1) factorial]
]
}
По умолчанию добавление методов происходит в область видимости модуля, где был создан класс.
Можно явно задать область видимости, чтобы скрыть или, наоборот, распространить объявление
на всю систему. Все стандартные классы объявлены в системной области видимости, которая
имеет имя AOS.
При любых вызовах алгоритм посылки сообщения ищет необходимый метод сначала
в текущей области видимости, потом в тех, которые были подключены, а потом в системной.
Даже если метод с заданным именем имеется в получателе сообщения, он не будет найден,
если его область видимости недоступна из места вызова.
Проиллюстрируем это примером:
Module name: HelloWorld.
Class ref.name: Integer
{
Method scope: HelloWorld [
factorial
^'cannot compute'
]
Class_method [
factorial10
^10 factorial
]
}
Function [<$entrypoint>
Main
stdout cr << 10 factorial.
stdout cr << Integer factorial10.
]
Метод factorial добавляется в область видимости HelloWorld и,
таким образом, не перезаписывает стандартную реализацию. В методе Main
происходит вызов 10 factorial двумя различными способами - напрямую,
и посредством метода factorial10 из класса Integer. Так как
этот класс является системным, то его областью видимости является AOS.
Результатом выполнения данного кода будет следующее:
cannot compute
3628800
Таким образом можно осуществить различное представление системы с разных
точек зрения. Этот метод позволяет решить многие проблемы,
связанные с одновременным созданием многих проектов несколькими разработчиками.
Данный подход называется субъектно-ориентированным программированием.
А модули в данном случае служат субъектами.
Заключение
Полученные знания уже позволят продолжить дальнейшее изучение SmallScript.
В заключение следует отметить, что в его комплект также входит базовая
утилита AExplorer с некоторыми возможностями Workspace и Class Browser.
Она позволяет просматривать исходные коды системы и запускать фрагменты
кода.
|