Сообщение [Nitra] Новости от 28.06.2017 от 27.06.2017 23:53
Изменено 29.06.2017 12:53 VladD2
[Nitra] Новости от 28.06.2017
BindResult[TSymbol]
Провел масштабную модернизацию механизма связывания (binding-а).
Зачем это нужно и что это дает?
В Nitra биндинг встроен в библиотеки. Код биндинга зашит в библиотечный ast Reference.
Это дает некоторую автоматику и обобщенный принцип. Но это несло в себе существенный недостаток. Дело в том, что связывание всегда производится с базовым типом символа DeclarationSymbol. Это значит, что связывании проводится с первым попавшимся символом. В дальнейшем, во время резолва, можно уточнить тип символа, но если в области видимости был символ неподходящего типа, то мы получали ошибку, так как информация о затененных (этим символом) других символов терялась.
Я долго думал что сделать, чтобы можно было производить связывание (или уточнение связывания) с затененными сиволами. В итоге остановился на следующем решении.
Теперь связывание проходит не с конкретным символом или их списком (в случае неоднозначности), а со специальным типом способным хранить иерархию символов. Это вариантный тип BindResult[TSymbol]. Он может хранить следующие варианты:
| Single
| Multiple
| Hiding
| Union
| Nil
Можно сказать, что этот тип повторяет иерархию областей видимости (Scope-в), но без излишних деталей и вложенности.
Этот тип сам по себе может отражать пустое связывание (т.е. отсутствие подходящих символов), неоднозначное связывание, а так же отражает информацию о сокрытии и объединение символов.
Для этого типа доступны методы:
public Filter[TConcreteSymbol]() : BindResult[TConcreteSymbol]
where TConcreteSymbol : DeclarationSymbol
/// Filter by predicate. Filter by TConcreteSymbol If predicate is null.
public Filter[TConcreteSymbol](predicate : Predicate[TConcreteSymbol]) : BindResult[TConcreteSymbol]
where TConcreteSymbol : DeclarationSymbol
public Map[TConcreteSymbol](algorithm : ResolutionAlgorithm[TSymbol, TConcreteSymbol]) : BindResult[TConcreteSymbol]
where TConcreteSymbol : DeclarationSymbol
Которые позволяют фильтровать BindResult[TSymbol] по типу и значению символов и отображать BindResult[X] на BindResult[Y].
Связывание более 1 символа не является автоматически ошибкой, так в процессе резолва лишние символы могут быть отброшены.
То что BindResult хранит иерархию сокрытия позволяет процедуре резолва пройти по иерархии вниз отбросив скрывающие символы и взять скрытые. Так если произошло связывание с локальной переменной, но процедура резолва хочет произвести связывание с одноименным типом, она может отфильтровать BindResult по типу и отбросить, таким образом, локальные переменные и поля.
Так же BindResult удобен и для связывания с членами (members) типов, так как естественным образом представляет как неоднозначность, так и сокрытие одноименных символов базового типа.
Ref[TSymbol]
Претерпел изменения и Ref[TSymbol] используемый в Nitra при резолве. Ref[TSymbol] перестал быть вариантным, так как за хранение информации о неоднозначности и неудаче резолва или связывания переехала в BindResult.
В задачи Ref теперь входит кэширование значения символов, описание взаимосвязей резовлва (по средствам свойства ResolvedTo) и информировании пользователя о неудаче связывания.
У Ref[TSymbol] есть ряд наследников оптимизирующих хранение и кэширование данных.
Ну, и Ref[TSymbol] по-прежнему реализуют псевдо-зависимые свойства позволяющие использовать их в коде вычисления зависимых свойств.
ast Reference и Scope
Немного изменился интерфейс ast-а Reference и типа Scope. Их методы Bind, как бы, вывернуты наизнанку.
Теперь методы Bind у Scope возвращают BindResult[TSymbol], а метод Reference.Bind принимает в качестве параметра Scope и возвращает Ref[TSymbol].
public partial class Reference : AstBase
{
public Bind[TSymbol](scope : Scope) : Ref[TSymbol]
where TSymbol : DeclarationSymbol
...
}
public abstract class Scope : ISerializable
{
public abstract Bind[TSymbol](reference : Reference) : BindResult[TSymbol] where TSymbol : DeclarationSymbol;
public abstract Bind[TSymbol](isMatch : Predicate[TSymbol]) : BindResult[TSymbol] where TSymbol : DeclarationSymbol;
...
}
Кроме того был убран метод Scope.BindMany. Зато появился метод Bind принимающий предикат. Так же бы удален метод автодополнение при вводе. Теперь его роль будет играть метод Bind принимающий предикат.
[Nitra] Новости от 28.06.2017
BindResult[TSymbol]
Провел масштабную модернизацию механизма связывания (binding-а).
Зачем это нужно и что это дает?
В Nitra биндинг встроен в библиотеки. Код биндинга зашит в библиотечный ast Reference.
Это дает некоторую автоматику и обобщенный принцип. Но это несло в себе существенный недостаток. Дело в том, что связывание всегда производится с базовым типом символа DeclarationSymbol. Это значит, что связывании проводится с первым попавшимся символом. В дальнейшем, во время резолва, можно уточнить тип символа, но если в области видимости был символ неподходящего типа, то мы получали ошибку, так как информация о затененных (этим символом) других символов терялась.
Я долго думал что сделать, чтобы можно было производить связывание (или уточнение связывания) с затененными сиволами. В итоге остановился на следующем решении.
Теперь связывание проходит не с конкретным символом или их списком (в случае неоднозначности), а со специальным типом способным хранить иерархию символов. Это вариантный тип BindResult[TSymbol]. Он может хранить следующие варианты (и их комбинации):
| Single
| Multiple
| Hiding
| Union
| Nil
Можно сказать, что этот тип повторяет иерархию областей видимости (Scope-в), но без излишних деталей и вложенности.
Этот тип сам по себе может отражать пустое связывание (т.е. отсутствие подходящих символов), неоднозначное связывание, а так же отражает информацию о сокрытии и объединение символов.
Для этого типа доступны методы:
public Filter[TConcreteSymbol]() : BindResult[TConcreteSymbol]
where TConcreteSymbol : DeclarationSymbol
/// Filter by predicate. Filter by TConcreteSymbol If predicate is null.
public Filter[TConcreteSymbol](predicate : Predicate[TConcreteSymbol]) : BindResult[TConcreteSymbol]
where TConcreteSymbol : DeclarationSymbol
public Map[TConcreteSymbol](algorithm : ResolutionAlgorithm[TSymbol, TConcreteSymbol]) : BindResult[TConcreteSymbol]
where TConcreteSymbol : DeclarationSymbol
Которые позволяют фильтровать BindResult[TSymbol] по типу и значению символов и отображать BindResult[X] на BindResult[Y].
Связывание более 1 символа не является автоматически ошибкой, так в процессе резолва лишние символы могут быть отброшены.
То что BindResult хранит иерархию сокрытия позволяет процедуре резолва пройти по иерархии вниз отбросив скрывающие символы и взять скрытые. Так если произошло связывание с локальной переменной, но процедура резолва хочет произвести связывание с одноименным типом, она может отфильтровать BindResult по типу и отбросить, таким образом, локальные переменные и поля.
Так же BindResult удобен и для связывания с членами (members) типов, так как естественным образом представляет как неоднозначность, так и сокрытие одноименных символов базового типа.
Ref[TSymbol]
Претерпел изменения и Ref[TSymbol] используемый в Nitra при резолве. Ref[TSymbol] перестал быть вариантным, так как за хранение информации о неоднозначности и неудаче резолва или связывания переехала в BindResult.
В задачи Ref теперь входит кэширование значения символов, описание взаимосвязей резовлва (по средствам свойства ResolvedTo) и информировании пользователя о неудаче связывания.
У Ref[TSymbol] есть ряд наследников оптимизирующих хранение и кэширование данных.
Ну, и Ref[TSymbol] по-прежнему реализуют псевдо-зависимые свойства позволяющие использовать их в коде вычисления зависимых свойств.
ast Reference и Scope
Немного изменился интерфейс ast-а Reference и типа Scope. Их методы Bind, как бы, вывернуты наизнанку.
Теперь методы Bind у Scope возвращают BindResult[TSymbol], а метод Reference.Bind принимает в качестве параметра Scope и возвращает Ref[TSymbol].
public partial class Reference : AstBase
{
public Bind[TSymbol](scope : Scope) : Ref[TSymbol]
where TSymbol : DeclarationSymbol
...
}
public abstract class Scope : ISerializable
{
public abstract Bind[TSymbol](reference : Reference) : BindResult[TSymbol] where TSymbol : DeclarationSymbol;
public abstract Bind[TSymbol](isMatch : Predicate[TSymbol]) : BindResult[TSymbol] where TSymbol : DeclarationSymbol;
...
}
Кроме того был убран метод Scope.BindMany. Зато появился метод Bind принимающий предикат. Так же бы удален метод автодополнение при вводе. Теперь его роль будет играть метод Bind принимающий предикат.