SOL - Safe Overt Language (читать - "СОЛЬ").

(C) by Vladimir Kladov, 2010.

Надежный язык программирования. Что означает это словосочетание? Ниже приводятся ссылки на материал, который можно одновременно считать и описанием языка, и спецификацией для построения компилятора. И в котором можно найти и ответ на поставленный вопрос. Кроме того, материал содержит отключаемые расширенные комментарии, которые можно рассматривать как пояснения позиции автора по каждому вопросу.

Надежный Явный Язык программирования SOL - основная спецификация с комментариями.
Особенности работы с данными в нитях SOL - дополнение №1.
Параноидальные средства защиты: контрольная сумма, шифрование данных и байт-кода - дополнение №2.

Ниже следует краткий обзор основных изменений.

Предыдущая версия спецификации была значительно более сумбурно сформулирована, в итоге она стала противоречить сама себе (в некоторых местах) и превращаться в нечто труднореализумое практически, и пришлось приложить немало усилий, чтобы выстроить в новой версии более логичную и живучую конструкцию. По крайней мере, при формулировке каждого очередного тезиса я не забывал посмотреть на написанное или придуманное еще и с позиции написания реального компилятора.

В итоге, во многих моментах язык существенно изменился. Более жесткими стали требования на синтаксис, язык стал строго ориентирован на строки, многострочные операторы, строчные константы и комментарии исключены, введены правила для переноса строк (символ продолжения  - многоточие в начале строки) и размещения нескольких операторов в одной строке (через разделитель ';'). Введен и строго соблюдается принцип минимально необходимого контекста, достаточного для выяснения того, чем является написанный идентификатор - локальной переменной, параметром, глобальной переменной, константой, функцией и т.д. Все блоки теперь оформляются с использованием двухбуквенных скобок IF-FI, DO-OD, GO-OG, IS-SI, слово END оставлено только для завершения всего модуля. Принцип размещения финальной скобки блока в начале строки подтвержден и усилен. Благодаря коротким завершающим скобкам блоков и использованию ключевых слов и специальных операторных знаков длиной не более 3 символов, теперь имеется возможность оформлять код всегда с обеспечением отступа ровно в 4 символа для обозначения вложенности блоков операторов.

Функции должны вызываться при наличии более одного параметра с указанием имен параметров (но имеются и правила для упрощенного вызова без указания имен параметров - в отдельных специально оговоренных случаях). Постфиксная запись вызова функций в стиле ОБЪЕКТ..МЕТОД разрешена для всех случаев и служит синтаксическим заменителем обычного префиксного вызова функций в виде МЕТОД{ ОБЪЕКТ ... }.

Разрешены и предложены для более активного использования вложенные функции. В то же время, введены более жесткие правила на размер оформляемого кода и ширину строки, не позволяющие записывать в пределах одного блока более 40 строк кода, записывать слишком длинные строки (более 72 символов в строку кода), делать большие пропуски между строками (более двух пустых строк) и т.д.

Введено правило использования NONE-объектов вместо уже привычного всем NULL'а (или NIL'а), который просто был физически равен числу 0 в других языках. Добавлен механизм работы с подстроками, позволяющий во многих случаях обойтись без копирования подстроки и создания для нее отдельного массива в памяти. Основная идея о разделении указателей-ссылок на три категории (сильные - удерживающие, слабые - использующие, сверх-сильные - исключительные) сохранена и усилена обязанностью дописывать соответственно двойной, одиночный или тройной суффикс & к имени переменной - ссылки. Важнейший принцип - изоляции объектов в пределах одной нити в каждый момент времени - подтвержден и только несколько иначе сформулирован.

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

Взамен указателей функций введен механизм переназначаемых функций-переменных, в итоге более мощный, чем механизм методов в Delphi - благодаря присоединению к ссылке на код до трех числовых значений и значений указателей.

Некоторые изменения появились в части переопределения операторов арифметики, логики и других бинарных и унарных операций с объектами. Теперь разрешено даже больше, чем раньше, но введен принцип близкоконтекстной декларации (в пределах 20 строк выше по тексту), позволяющий проинформировать читателя кода об использовании переопределенных операторов.

Изменены некоторые принципы работы с массивами. Дополнительно появились абстрактные массивы, заменяющие собой перечислители, имеющиеся в новомодных языках. Появились "переменные только для чтения", избавляющие от необходимости вводить в язык свойства.

В дополнение к циклам DO FOR и DO WHILE, появились циклы DO UNTIL и DO REPEAT, циклы DO WHILE и DO UNTIL имеют версии с пост-проверкой условия: DO ... OD WHILE и DO ... OD UNTIL. Шаг в цикле FOR обязан теперь задаваться константой (или оставаться 1 по умолчанию). Изменились правила использования переменной цикла FOR: теперь присваивать значение такой переменной нельзя вообще нигде, кроме как в результате использования ее в качестве переменной цикла. Взамен, введены четкие правила использования значения переменной цикла по окончании цикла. Метки циклов теперь допускаются только литерально-числовые. Так же, как и раньше, такие метки используются в операторах BREAK N и CONTINUE N для упрощения переходов изнутри глубоко вложенных циклов. Добавлен оператор множественного выбора CASE, с целью дать возможность на этапе компиляции контролировать отсутствие пересечений в множестве вариантов.

Более строгими стали правила декларации переменных. Оператор VAR теперь является обязательным при первой декларации переменной, и он гарантирует, что все переменные всегда будут проинициализированы до того, как использованы. Хотя, операторы VAR могут размещаться где угодно в блоке операторов или на уровне функции. В дополнение, введен необязательные оператор ZAP, завершающий область применения переменных.

Базовые типы данных теперь реализованы как родовые, и введены правила для применения умолчаний, позволяющие либо не указывать тип переменной вообще (в этом случае тип зависит от контекста при инициализации переменной или выводится от принятых на уровне модуля или проекта умолчаний), либо не уточнять разрядность (в этом случае используется умолчание для модуля, проекта или целевой платформы). Булевские операции и операции сдвигов по-прежнему запрещены для числовых значений, и для работы с ними как последовательностями логических нулей и единиц, они должны трансформироваться в булевские массивы (хотя бы и формально).

Константные функции, возвращающие одно и то же значение для одних и тех же параметров (и не использующие глобальные переменные и не константные функции), по-прежнему предназначаются для использования внутри константных выражений с параметрами - константами, что позволяет обеспечивать условную компиляцию кода без привлечения механизмов препроцессинга (макросов, включений, особых операторов условной компиляции).

Параметры функций, передающиеся по значению, отличаются от параметров, передающихся по ссылке, синтаксически. Последние имеют в качестве префикса двойной, а не одинарный символ @, и этот префикс должен употребляться вместе с именем параметра не только в заголовке функции, но и в теле функции.

В плане объектного программирования - добавлено множественное наследование. Интерфейсы и позднее связывание пока оставлены в стороне от основных рассуждений. Хотя правила для экспорта и импорта функций из внешних DLL прописаны достаточно четко.

Изменения коснулись обработки исключений - теперь обработчики исключений ON и обязательно исполняемый участок кода ALWAYS могут присутствовать внутри любого блока, в том числе блока цикла. Финализация и инициализация модуля могут теперь размазываться по тексту модуля и являться частью отдельных функций модуля.

Низкоуровневое программирование теперь реализовано исключительно в терминах доступа к низкоуровневым ресурсам - массивам памяти Memory[ ], портов Port[ ], специальных низкоуровневых функций Address, Size. Применение ассемблера из средств языка исключено в целях большей гибкости и многоплатформенности.

Значительное внимание на этот раз уделено эффективности создаваемого кода. Сюда входит и работа с подстроками, и разворачивание циклов FOR и REPEAT, и инлайн-вставки кода функций, и многие другие аспекты.

Более тщательно проработаны аспекты тестирования функций модуля. Теперь на уровне компилятора может быть обеспечен контроль исчерпываемости набора тестов, благодаря принципу сбору статистики о выполнении операторов и о получении всеми неконстантными логическими выражениями, использующимися в операторах IF, WHILE, UNTIL - обоих возможных состояний. Специфицированы средства для тестирования обработчиков исключительных ситуаций.

Принцип контроля на уровне компилятора степени надежности модулей сохранен, хотя и несколько модифицирован. Флаги ненадежности обязаны перечисляться в заголовке модуля, и компилятор имеет все средства для контроля соответствия перечисленных флагов ненадежности реальному положению дел.

В целом, язык стал более строгим, и надеюсь, более надежным. Главное, что он стал реализуемым и более обозримым.