Open Mazdaywik opened 8 years ago
Роберт Тебиев (@tebrobert), работавший над этой задачей, вроде как ушёл из вуза. Поэтому задача переходит на следующий осенний семестр.
Забираю задачу себе, поскольку в качестве курсового её никто не взял.
Сначала, вроде как Роберт (@tebrobert) восстановился, приходил на консультацию, а сегодня я узнал, что он снова ушёл. Задачу исключаю из вехи.
Задача актуальна для курсового проекта.
Никто не взял как тему курсового.
Задача снова вывешивается на курсовую работу.
Кстати, на момент написания комментария — это самая старая задача из открытых.
Задача не была выбрана в качестве курсовой.
Не буду предлагать на курсовую, т.к. задача подразумевает изменение рантайма, объём которых мне сейчас не очевиден.
Мне кажется, задачу нужно разбить на несколько подзадач, чтобы с ней можно было как-то работать. Примерно так:
Добрый день, @tonal!
Выбор внутреннего представления — UTF-32. Данные в памяти представляются как двусвязные списки звеньев с тегом и полем информации:
https://github.com/bmstu-iu9/refal-5-lambda/blob/21d12cc4071e73f4297f0ba958c31b7e3a54aff6/src/lib/refalrts.h#L114-L134
Так что, если заменить char
на int
, никакого перерасхода памяти не будет.
Для представления имён функций и символов-слов будет использоваться UTF-8 ради компактности и удобства работы.
Хорошего окончания года @Mazdaywik!
Тут есть чуток ремарок: а) Некоторые символы могут иметь представление как 2 и более кода. Самые очевидные Й и Ё - они могут быть представлены 1 собственно символом, или 2мя - основным и надстрочным совмещённым. б) Хуже того. Сортировка может зависеть от несколькобуквенных последовательностей - возникает неоднозначность при сопоставлениях с образцом... в) В том же Haskell-е именно такое представление и было изначально. Но оказалось, что для реальной работы оно изрядно тормозное. Поэтому сейчас используются пакеты ByteString при любой сколько-нибудь массовой работы со строками (в компиляторе так же).
См. П 5 и П 1.б.
(п5) В том же Python-е стандартизировали комментарий в начале файла, в котором можно указать кодировку. Если не указано - считается utf-8. В С++ добавили флаг компиляции, позволяющий указать кодировку исходника. В Haskell - зафиксировали utf-8. Но, в любом случае компилятор должен быть осведомлён о кодировке, и использовать какие-то библиотеки для конвертации. Предоставлять ли их как доступные в рантайм - вопрос открытый. Но у компилятора они должны быть.
@tonal, спасибо за интересные дополнения, в частности, за опыт с другими языками программирования. С Хаскелем я не работал, поэтому этих тонкостей не знал. С Python работал, в глубины особенностей реализации Юникода и кодировок не углублялся. Знаю только про комментарий-кодировку (правда, не знаю, как Python работает с файлами в кодировках UTF-16 и UTF-32 без BOM).
Флаг компилятора в C++ с кодировкой исходника — это, по-видимому, особенность той реализации C++, которой Вы пользуетесь. Странно было бы, если бы эту функцию затребовали в Стандарте. Вообще C++11 и последующие уже поддерживают строковые литералы в UTF-16 и UTF-32, поэтому как-то работать с этим надо.
По поводу того, как хранить составные символы (ё, й, ñ, ударе́ние…) в памяти — как они загрузились из файла, так и хранить. Но при этом иметь библиотечные функции для приведения текста к той или иной нормальной форме (там их 4). Потому что учитывать эти составные символы в процессе сопоставления с образцом — жутко сложно и накладно.
Кстати, на macOS почему-то «ё» и «й» по умолчанию представляются парой кодовых точек. Иногда мне присылают картинки, созданные на macOS, в именах которых находятся упомянутые буквы. IrfanView открыть их не может.
Кстати, знаки-модификаторы сейчас используются не только для точек над «ё». Эмодзям можно задать цвет кожи и пол, которые тоже задаются модификаторами. Без модификатора цвета кожи смайлик показывается жёлтым, с модификатором — от розового до чёрного. Без модификатора пола — какой-то пол по умолчанию, у разных смайликов разный. Сейчас я пишу с компьютера с Windows 7, на нём геморно смайлики вводить. Сяду за компьютер с Windows 10 — накидаю примеров в комментарии, если не забуду.
А вообще, хороший вопрос, как правильно компилировать файлы с разными кодировками.
В самом языке имена функций и переменных сейчас могут содержать только латинские буквы ASCII с учётом регистра символа, поэтому кодировка на них не влияет. Влияет кодировка на константы — литеры (characters) и символы-слова в кавычках (что-то вроде цитированных имён в Лиспе). Сейчас они просто рассматриваются как байты. Если исходник в кодировке UTF-8, то русская буква в памяти будет храниться как два отдельных character’а, какой-нибудь иероглиф — три или четыре.
Но если поддерживать Юникод, то нужно предложить разумное поведение для случая, когда кодировка исходника не определена. Например, можно так: если определена правильно (есть псевдокомментарий, или начинается на BOM и при считывании не было ошибок), то компилируется тихо-спокойно. Если не определена, то на символы с кодом больше 127 (кроме комментариев) можно выдавать предупреждение или даже ошибку, что это какая-то фигня.
Хороший вопрос с нормализацией и символами-словами с составными знаками (вроде тех же «ё»). Исходники могут совместно правиться под разными системами, и один и тот же по начертанию и написанию символ будет представлен в файле по-разному. Но он при этом во время выполнения должен быть одним и тем же. Возможное решение — для символов-слов принудительно применять нормализацию. Для символов-литер это менее актуально, но тоже можно применять некую нормальную форму (какую из четырёх?).
Сейчас из поддержки Юникода компилятор умеет только игнорировать UTF-8 BOM в начале — не выдаёт на него ошибку.
Текущая реализация Рефала-5λ не поддерживает Юникод, интерпретирует текст как последовательность байт. Поэтому с текстами в кодировке UTF-8 он частично совместим, ровно на столько, на сколько UTF 8 может заменить однобайтную кодировку.
Требуется реализовать поддержку Юникода и кодировок символов на уровне лексики (в частности, национальные символы в идентификаторах), библиотеки времени выполнения и библиотеки стандартных функций.
Библиотеку для Юникода можно реализовывать тремя путями:
<locale>
и<wctype.h>
, но насколько точно и переносимо они поддерживают Юникод в разных версиях компиляторов — точно не знаю.У каждого варианта свои достоинства и недостатки, нужно будет выбрать какой-то один и его реализовать.
¹ Чучхэ (кор.) — идеология опоры на собственные силы