В этом вопросе язык для надёжного программирования ближе всего к Оберону, но с более жёсткими условиями по недопущению перекрытия.
Все используемые идентификаторы кроме предопределённых должны быть предварительно объявлены. Имя, использованное для объявления на уровне раздела или функции, должно быть уникальным в одной области видимости, за исключением предварительного объявления функции, что нужно для возможности косвенной рекурсии. Имя объявления, сделанного внутри функции также должно быть уникальным во всей функции, в том числе и для не пересекающихся областей видимости внутри неё.
Объявление-d, сделанное на уровне раздела-s доступно по имени от начала его появления в тексте до конца s. В других разделах-so d доступно только в том случае, если оно было помечено как экспортируемое в s, и только в тех из них, где s был импортирован. Доступ к d в so осуществляется черезимпортированное имя s - ins, следующей за ним разделяющей точкой и именем d
section s { const(c = d + 1; // ошибка - d ещё не объявлена +d = 0; // пометка объявления "+" как экспортированное e = d + 1) proc p() { const(f = d; e = 6) // ошибка - е уже объявлено в этой области уровнем выше ... } }. section so { import (ins = so) // переименовываем, s недоступна для использования const (d = ins.d; e = so.d; // ошибка, раздел s был переименован для использования f = ins.e) // ошибка, объявление е не было экспортировано в s proc p() { { const (a = 3) ... } { const (a = 0.6)// ошибка - хотя a=0.6 объявлена в другой области ... // видимости, но в пределах одной процедуры, } // что запрещено } }.Имя объявления, сделанного на уровне структуры должно быть уникальным лишь в пределах самой структуры. Имя может совпадать как с предопределёнными именами, так и с именами, объявленными на уровне раздела, функций и других структур, в том числе вложенных, так как из-за строго иерархического обращения к элементам структуры не может быть никакого кофликта имён.
section a { const (b = 1) var (r struct { r struct { r, b int } } ) proc p() { r.r.r = 0; r.r.b = b } }
В языке нет разновидности импорта, позволяющей включать экспортированные объявления других разделов в область видимости импортирующего раздела так, как будто они являются его собственными. Это сомнительное удобство вносит неразбириху относительно принадлежности используемых сущностей и создаёт возможность для появления ошибок в результате манипуляций с импортом и расширения интерфейса используемых разделов.
Из заданных ограничений следует, что имена объявлений, сделанные внутри функции могут совпадать с именами объявлений, сделанных в других функциях. Также, имя внутри функции может совпадать с именем одной из функций, объявленных ниже по тексту. Это послабление нужно для возможности создания однопроходного транслятора.
section a { const(+a = 10)// обращение к собственному модулю не предусмотрено, // поэтому имя объявления может совпадать с именем модуля. proc +b() { const(c = a; d = 4)// d объявлена ниже, поэтому не входит в текущую ... // область видимости } proc +d() { // область видимости d = 4 закончилась внутри b() const(c = a + 1)// хотя с уже встречается в b(), но так как области // b() и d() не пересекаются, то объявление правильно. ... } }
Запрет на перекрытие имён и возможность иметь несколько конкретизаций синтаксисов создают трудности, требующие разрешения:
- Невозможность использования подходящего имени, если оно уже занято предопределённым идентификатором, что может быть неприятным, если их будет много.
- Невозможность использования объявления с именем, совпадающим с ключевым словом, от модуля, написанного под другой синтаксис.
Для разрешния этого можно использовать спец-символ, обозначающий, что помеченное имя имеет пользовательское происхождение.
section @const { // @ как в C# const (+@section = 1) }
Можно рассмотреть и другую возможность — отказ от ключевых слов и ограниченное число предопределённых имён. При необходимости добавления новых в обновлённой версии языка, они добавляются в псевдораздел, чтобы исключить пересечение с именами в разделе, написанном ранее. Но это решение пока кажется сложней и проблематичней. Вариант, в котором наоборот — все ключевые слова и предопределённые идентификаторы помечены, кажется слишком неудобным и уродливым.
@section m { @const (c = 1) @type (t @int) @var (v t) @func f(i t) (res @bool) { res = i < @max(t) / 2 } }
Комментариев нет:
Отправить комментарий