Какого то значения для ошибки как например в Golang - нет. И вложенных функций и вложенных классов тоже нет, и не будут. Ну можно конечно сделать какой то соглашение, что число -123456 будет означать что завершилось что то ошибкой
Для предотвращения исключения new(), можно целиком заменить инструкцию, примерно так:
replace {
$source;
if (!$2) {
out("FATAL");
}
}
Программа при исключении завершится только если там такое прописано. Пока что в стандартной библеотеке нет одной такой функцией, поэтому пока завершать программу вне main() нужно вручную через ASM syscall или ExitProcess.
И в исключении можно писать всё что угодно, потому что на этапе вставки проверок и прочего пройден только синтаксический анализ, но ошибки вылезут при парсинге. Так как код вставляется - обработчик в исключении имеет доступ ко всему, что имеют остальные в этом скоупе.
Исключения будут описаны заранее в стандартной библеотеке, вручную ничего описывать не пртидётся. Если у вас очень много делений, то да, на каждое действие будет немногие оверхед на несколько примерно 20-35 тактов процессора. Но никто не обязывает пользоваться исключениями если вам нужна максимальная скорость. В теории это может компенсироваться оптимизациями LLVM, но я не проверял. Слышал что с оптимизациями прирост от 50% до 200%, не проверял
Ну если new() не выделил память, указатель не валидный, и обращаться по нему - сегфолт. new() магическим образом не будет пытаться ещё раз пробовать выделение в памяти.
Ну вообще язык делает упор не в ООП. Реализовано это все без оверхеда (по типу vtable), классы это те же структуры, методы это функции которые неявно получают объект как аргумент. new() и delete() - под капотом те же malloc/free, но вызывают конструктор или деструктуор (delete() автоматически выставляет указатель на null)
В отличии от препроцессора, исключения могут и вставлять проверки, захватывать значения, и проводить с ними действия. Если написать #define, препроцессор заменит всё что совпадает, не проверяя последующие или предыдущие токены
Я поленился, и решил просто дать ИИ искходники языка, и скинуть эту статью, вот что выдал:
Это как раз то, для чего Flame делался. var Node* node = new Node() — autodel вставит delete автоматически после последнего использования. Иерархия владения выражается естественно: документ владеет карточками, карточки — элементами. Деструкторы вызываются по цепочке. Это уже работает.
Здесь Flame пока ничего специального не предлагает. Copy-on-write придётся писать руками — завернуть стиль в структуру со счётчиком ссылок и клонировать при изменении. Это решаемо, но языковой поддержки нет. Можно сделать через notdel указатели для "слабого" хранения общих ресурсов.
Перекрёстные ссылки с автообрывом
Вот здесь пока больная точка. В Flame нет слабых ссылок в смысле weak_ptr. Коннектор, ссылающийся на другой элемент, получит висячий указатель после удаления цели. Нужно будет либо добавить в язык концепцию weak*, либо делать это через явный реестр/ID и проверку.
Удаление карточки из метода элемента этой карточки
autodel здесь может конфликтовать — если self удаляется в процессе выполнения метода, это UB. Это общая проблема даже в C++. Flame наследует её.
Копирование с сохранением топологии
Нужен явный "deep copy с remapping" — обойти дерево, создать копии, построить таблицу старый указатель → новый, пройти заново и перешить ссылки. Языковой магии нет, но класс с new-конструктором это выразит чисто.
С недавнего времени autodel автоматический, его писать не надо. Можно написать notdel чтобы предотавратить удаление компилятором...
Нет, это сегфолт. В языке исключения пока созданы чтоб их предотвращать проверками, а не обрабатывать. И исключение вставляет и заменяет проверки ещё на этапе дерева токенов, поэтому будет исключение или не будет, если это местечко описано в исключении - проверка ставится или заменяется
Да, спустя время верится, что результат будет. Уже сейчас неплохие результаты. Не хватает сообщества, чтоб быстро выявлять баги и недочёты. Пока концепция справляется с любыми припятствами, в том числе и цикличных ссылок, но не уверен что на 100%....
autodel на такое не расчитан, если говорить про висячую ссылку. В будущем что нибудь придумаю, спасибо за замечание! Но в Flame это не проблема потому что autodel не считает ссылки — он просто вызывает delete по области видимости. B удалится, потом A удалится. Висячий указатель внутри уже удалённого B — это проблема программиста, но утечки не будет.
Удаление будет после выхода из цикла. Если передать значение через разыменовывание - это не изменит поведение. А если передать в поле структуры указатель... то autodel сработает криво. Спасибо за замечание, можете писать такое в issues в GitHub. Поработаю над этим!
Нет, отличие от других макросов - это то, что вносятся правки на уровне токенов, а не AST (если в тексте написано что это в AST, извиняюсь, статья была отправлена на модерацию 2 недели назад, с тех пор многое изменилось). Это позволяет менять грамматику гибко, например:
exception Repeat {
var int count;
instruction {
repeat %n:count
}
replace {
for (int i = 0; i < count; i++)
}
}
// Этого в грамматике нет, но исключение позволяет так писать
repeat 5 { //это превратится в for цикл
log("Hello");
}
Это называются исключениями, потому что изначально задумывалось как автоматическое выявление опасных мест и вставка проверки...
Потому что check {} в исключении опирается на ; как завершение прошлой инструкции. Это может временно, со временем точки с запятой могут стать необязательным.
Какого то значения для ошибки как например в Golang - нет. И вложенных функций и вложенных классов тоже нет, и не будут. Ну можно конечно сделать какой то соглашение, что число -123456 будет означать что завершилось что то ошибкой
Для предотвращения исключения new(), можно целиком заменить инструкцию, примерно так:
Программа при исключении завершится только если там такое прописано. Пока что в стандартной библеотеке нет одной такой функцией, поэтому пока завершать программу вне main() нужно вручную через ASM syscall или ExitProcess.
И в исключении можно писать всё что угодно, потому что на этапе вставки проверок и прочего пройден только синтаксический анализ, но ошибки вылезут при парсинге. Так как код вставляется - обработчик в исключении имеет доступ ко всему, что имеют остальные в этом скоупе.
Исключения будут описаны заранее в стандартной библеотеке, вручную ничего описывать не пртидётся. Если у вас очень много делений, то да, на каждое действие будет немногие оверхед на несколько примерно 20-35 тактов процессора. Но никто не обязывает пользоваться исключениями если вам нужна максимальная скорость. В теории это может компенсироваться оптимизациями LLVM, но я не проверял. Слышал что с оптимизациями прирост от 50% до 200%, не проверял
Ну если new() не выделил память, указатель не валидный, и обращаться по нему - сегфолт. new() магическим образом не будет пытаться ещё раз пробовать выделение в памяти.
Ну, там в имени в начале есть символ звёздочки, а со звёздочкой аллоцировать в стеке нельзя через alloca().
Вот пример:
Насколько я знаю, так препроцессор не умеет
В языке так и есть, там в парсере прямо так и написано, что "->" и "." делают одно и то же
Имел в виду что если поле структуры которая ещё сама не удалена указывает на уже удалённый объект - поле останется висячим
Ну вообще язык делает упор не в ООП. Реализовано это все без оверхеда (по типу vtable), классы это те же структуры, методы это функции которые неявно получают объект как аргумент. new() и delete() - под капотом те же malloc/free, но вызывают конструктор или деструктуор (delete() автоматически выставляет указатель на null)
Владение наследуется
В отличии от препроцессора, исключения могут и вставлять проверки, захватывать значения, и проводить с ними действия. Если написать
#define, препроцессор заменит всё что совпадает, не проверяя последующие или предыдущие токеныЯ поленился, и решил просто дать ИИ искходники языка, и скинуть эту статью, вот что выдал:
Это как раз то, для чего Flame делался.
var Node* node = new Node()— autodel вставитdeleteавтоматически после последнего использования. Иерархия владения выражается естественно: документ владеет карточками, карточки — элементами. Деструкторы вызываются по цепочке. Это уже работает.Неизменяемые ресурсы (стили, битмапы) — copy-on-write
Здесь Flame пока ничего специального не предлагает. Copy-on-write придётся писать руками — завернуть стиль в структуру со счётчиком ссылок и клонировать при изменении. Это решаемо, но языковой поддержки нет. Можно сделать через
notdelуказатели для "слабого" хранения общих ресурсов.Перекрёстные ссылки с автообрывом
Вот здесь пока больная точка. В Flame нет слабых ссылок в смысле
weak_ptr. Коннектор, ссылающийся на другой элемент, получит висячий указатель после удаления цели. Нужно будет либо добавить в язык концепциюweak*, либо делать это через явный реестр/ID и проверку.Удаление карточки из метода элемента этой карточки
autodel здесь может конфликтовать — если
selfудаляется в процессе выполнения метода, это UB. Это общая проблема даже в C++. Flame наследует её.Копирование с сохранением топологии
Нужен явный "deep copy с remapping" — обойти дерево, создать копии, построить таблицу
старый указатель → новый, пройти заново и перешить ссылки. Языковой магии нет, но класс сnew-конструктором это выразит чисто.С недавнего времени autodel автоматический, его писать не надо. Можно написать notdel чтобы предотавратить удаление компилятором...
Нет, это сегфолт. В языке исключения пока созданы чтоб их предотвращать проверками, а не обрабатывать. И исключение вставляет и заменяет проверки ещё на этапе дерева токенов, поэтому будет исключение или не будет, если это местечко описано в исключении - проверка ставится или заменяется
Да, спустя время верится, что результат будет. Уже сейчас неплохие результаты. Не хватает сообщества, чтоб быстро выявлять баги и недочёты. Пока концепция справляется с любыми припятствами, в том числе и цикличных ссылок, но не уверен что на 100%....
Нет, поля класса нужно вручную чистить в деструкуторе. Пока что, автоудаляемые поля не изобретены, но скоро будут
autodel работает только для переменных в куче. Но спасибо за замечание, логичнее сделать notdel чтоб говорить компилятору самому не удалять...
autodel на такое не расчитан, если говорить про висячую ссылку. В будущем что нибудь придумаю, спасибо за замечание! Но в Flame это не проблема потому что
autodelне считает ссылки — он просто вызываетdeleteпо области видимости.Bудалится, потомAудалится. Висячий указатель внутри уже удалённогоB— это проблема программиста, но утечки не будет.Удаление будет после выхода из цикла. Если передать значение через разыменовывание - это не изменит поведение. А если передать в поле структуры указатель... то autodel сработает криво. Спасибо за замечание, можете писать такое в issues в GitHub. Поработаю над этим!
Нет, отличие от других макросов - это то, что вносятся правки на уровне токенов, а не AST (если в тексте написано что это в AST, извиняюсь, статья была отправлена на модерацию 2 недели назад, с тех пор многое изменилось). Это позволяет менять грамматику гибко, например:
Это называются исключениями, потому что изначально задумывалось как автоматическое выявление опасных мест и вставка проверки...
Потому что check {} в исключении опирается на ; как завершение прошлой инструкции. Это может временно, со временем точки с запятой могут стать необязательным.