ПО, ЭВМ и АСУ из Таможенного Союза

Информация о пользователе

Привет, Гость! Войдите или зарегистрируйтесь.


Вы здесь » ПО, ЭВМ и АСУ из Таможенного Союза » Рефал » Интерпретатор Рефал-5 (базисный)


Интерпретатор Рефал-5 (базисный)

Сообщений 1 страница 9 из 9

1

Здравствуйте.

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

Прежде всего, язык основан на идее нормальных алгорифмов Маркова. Это один из общепринятых способов (наряду с Машиной Тьюринга и Лямбдой Чёрча) формализации алгоритма. В современных языках реализован как сопоставление с образцом (pattern-matching). Базисный Рефал и состоит из одних сопоставлений (расширенный Рефал-5 подслащен условиями и блоками). Этого достаточно, что бы написать компилятор Рефал (например Refal-05). Рефал позволяет обходиться без компиляторов БНФ-нотаций в привычные языки программирования.

Рефал-5 по В.Ф. Турчину определён со следующими привязками к английскому и латинской раскладке:
1. английские имена функций стандартной библиотеки;
2. префикс в именах переменных определяет их тип и является латинской буквой с последующей точкой (s. e. или t.);
3. вызовы функций заключаются в вычислительные скобки: < >
4. блоки (тела функций) — в скобки фигурные { }.

Имена функций изменить не проблема. К буквенным префиксам добавил аналог из знаков препинания. Вместо s. (сопоставляется одному символу) можно писать ?, вместо e. (сопоставляется произвольному количеству символов) — точку или многоточие, и ! вместо t. (терм - либо один символ, либо выражение в () скобках). Что делать с угловыми и фигурными скобками, пока не ясно, оставил как есть. Нач/кон вместо { } по смыслу подходят не очень (т.к. имитируется подобие системы уравнений из математики, а не императивная последовательность).

Ослабил требования к именам идентификаторов, могут включать спецсимволы (в оригинале имя может включать минус или подчёркивание). Сам язык разрешает определять идентификаторы в произвольном месте неявно (интерпретатор выводит предупреждение), наряду с использованием их в образце (для сопоставления) позволяет эмулировать имена функций, которые включают пробел. Что позволяет уйти ВотОтЭтого-и-этого. Кроме того, имя функции в моей реализации не обязательно писать перед её аргументами. Порядок слов в русском языке произволен.

Вот пример простейшей программы:

Код:
  // Допустимы комментарии в одну строку в стиле С++
  
  * Вариант классической РЕФАЛ-программы.
  
  Начало = <Палиндром? <удалить пробелы "я разуму уму заря    ">>
           <Палиндром? <удалить пробелы "я иду съ мечемъ судия">>;
                                               * Гавриил Державин
  
  Палиндром? {
     ?символ … ?символ = <Палиндром? …>;
     ?символ           = <Вывод "Палиндром">;
                       = <Вывод "Палиндром">;
             …         = <Вывод "Остаток: "…>;
  }
  
  удалить {
     пробелы .символы " " .остаток = <удалить пробелы .символы .остаток>;
     пробелы … = …;
  }
  
  * явное определение не обязательно.
  пробелы;
  
  Вывод { . = <Prout .> }

Интерпретатор минималистичен и реализован целиком на Си, задуман как встраиваемый. Пока работает под Linux (пригоден для запуска сценариев на Рефал в командной строке). Слабонервным исходники транслятора (в байткод для исполнителя) смотреть не стоит, это одна функция в 1500 строк, из которых 171 goto и 259 case.

Благодарю за внимание.

Отредактировано С.Т. (2021-03-20 15:28:38)

0

2

С.Т. написал(а):

Благодарю за внимание.

Здравствуйте, мы видим Ваше сообщение, и оно очень интересное. Расскажите, пожалуйста, каковы Ваши дальнейшие планы. Спасибо.

0

3

Хороший вопрос. Вспоминается поговорка про желание рассмешить Бога. :-)

Начну с того, зачем сделал интерпретатор, когда можно было добавить поддержку многобайтных символов в тот же Рефал-5λ, ведь он существенно богаче возможностями.
Однажды я стал свидетелем навязчивой популяризации так называемой "Russian Operating System and Application™" (представляет собой дистрибутив Linux). Тот, кто предполагался как жертва рекламы, возразил агенту, что вопреки ожиданиям не обнаружил в терминале возможности отдавать команды на русском языке, потому выбрал вариант зарубежный. Похоже на дежурную шутку, но человек оказался серьёзен. Он отдал предпочтение специфичной NixOS, для администрирования которой желательно знание Haskell, и изучил его, первым языком. Полагаю, такой пользователь мог бы освоить и другой язык, например Рефал. О консольных командах на русском или чём-то большем я пока всерьёз не думал.

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

Библиотека. "Стандартная" для Рефал-5 мало для чего годится. Так или иначе придётся её расширять-изменять, то есть создать свою. И, кстати, возможно (опыт имеется) реализовать без привязки к стандартной библиотеке Си, что бы работала поверх голого ядра Linux. Возможно добавить поддержку Windows. Насчёт других ОС сложно сходу говорить предметно.

Вот такие пока "планы", плюс надеюсь увидеть пожелания и найти пищу для размышлений.

0

4

С.Т. написал(а):

надеюсь увидеть пожелания

Мне было бы интересно поверх голого ядра Linux под процессор Arm-v8 (он же Байкал-М).
Ну и в идеале без языка Си.

Отредактировано Лис (2021-03-22 19:07:25)

0

5

Напишу подробнее по поводу "голого ядра". Сейчас в Linux практически любой исполняемый файл импортирует библиотеку libc.so (даже компилятор языка Rust, якобы являющегося заменой Си). В ней содержатся реализации как функций языка Си (printf()), так и функции POSIX (mmap()). Первые функции выполняют некую работу, вторые, как правило, просто вызывают ядро.

Что из этого и зачем используется в интерпретаторе:

1. Программа на Рефал работает с так называемым Полем Зрения (ПЗ). Интерпретатор хранит его в двусвязном списке (так же как и программы на Рефал-5λ, но в данной машине представление на 64-х разрядных архитектурах компактнее на треть, поскольку вместо указателей используются индексы). По сути реализуется свой менеджер памяти со сборкой мусора. Использование malloc() в таком сценарии мало что даёт помимо перерасхода памяти. Соответственно вместо неё использована mremap() (индексы вместо указателей позволяют перемещать страницы при росте "кучи").

2. Один из возможных сценариев использования -- создание "пакетного менеджера", от которого требуется работоспособность при нарушении целостности ОС. Для поддержки локалей libc.so использует внешние данные и требует три раза присесть и сказать "кю". Потому вместо setlocale() и mbtowc() написан примитивный велосипед.

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

4. Внутри библиотеки для ввода-вывода в текущей версии используются fprintf(), fopen() и т.п. Плохо себе представляю программу на Рефале, где бы потребовалось указывать спецификаторы формата "%s" и т.п. Результатное выражение в Рефал само по себе более мощный "спецификатор". Кроме того, в унаследованной библиотеке работа с файлами выглядит вот так:

Код:
тест {
   .имя =
      <Putout 0>
      <Putout 0 'Копируем "'.имя'"'>
      <Open 'r' 1 'tests/' .имя>
      <Open 'w' 2 '/tmp/' .имя>
      <копируй 1 в 2>
      <Close 1>
      <Close 2>
      <Open 'r' 3 '/tmp/' .имя>
      <копируй 3 в 0>
      <Close 3>
}

Явное указание дескрипторов (1, 2, 3) выглядит анахронизмом, а 'w' китайской грамотой.
В переработанной библиотеке эти функции оправданно заменить на свою реализацию (read() + write() с буферизацией). Возможно, и сокеты туда же (если понадобятся); раз уж Рефал высокоуровневый язык, значит и абстрагироваться в полный рост.

С учётом вышеуказанного возможно исключить зависимость не только от fprintf() сотоварищи, но и вообще от libc.so, реализовав системные вызовы и другие "мелочи".

С другой стороны, опасно рассматривать Рефал как универсальный язык для всего на свете. Скорее всего, для каких-то применений разумнее использовать готовые библиотеки, которые написаны на Си и тянут за собой libc.so. Потому пока для себя не смог обосновать необходимость избавляться от стандартной библиотеки Си столь кардинально. В общем, хотелось бы понять, какие задачи оно бы решало.

Отредактировано С.Т. (2021-03-25 08:15:20)

0

6

Лис написал(а):

Ну и в идеале без языка Си.

Вот тут я не понял. Интерпретатор должен быть написан на чём-то, что можно перевести в машинный код. Тот же Рефал-5λ транслирует в Си, что позволяет собирать в итоге под Эльбрус. Это проще, чем прикрутить к LLVM генерацию машкода Е2К (насколько знаю, уже реализовано, но вряд ли на данном этапе результат лучше по качеству чем у родного Си компилятора).

0

7

С.Т. написал(а):

Вот тут я не понял.

О, это великая лисоконцепция (оспариваемая некоторыми посетителями).

Суть такова:

С.Т. написал(а):

что можно перевести в машинный код.

В машинный код можно перевести символьную запись этого машинного кода.
Например биту со значением  "земля" сопоставим символ "0",
а биту с "высоким потенциалом" сопоставим символ "1".
Тогда ячейку памяти можно будет описать при помощи восьми символов (то есть примерно 8 байтов).

С.Т. написал(а):

Си, что позволяет собирать в итоге под Эльбрус

Это верно, что Си играет роль "платформонезависимого ассемблера".
Но я не про это сейчас.

Рефал-то рекламируется как средство позволяющее
описать преобразование высокоуровневого кода в любые цепочки символов.
Рынок у нас в 2021м году состоит из 100000 процессоров Байкал-М и 10000 процессоров Эльбрус.
Значит первым логично сделать под архитектуру Arm v8, чтобы покрыть бо́льшую часть рынка.
Кроме того, это должно заработать и под Raspberry Pi (архитектура такая же, ядро тоже Linux, устройства не нужны)

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

Отредактировано Лис (2021-03-25 09:47:29)

0

8

Лис написал(а):

В машинный код можно перевести символьную запись этого машинного кода.
Например биту со значением  "земля" сопоставим символ "0",
а биту с "высоким потенциалом" сопоставим символ "1".
Тогда ячейку памяти можно будет описать при помощи восьми символов (то есть примерно 8 байтов).

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

Лис написал(а):

Рефал-то рекламируется как средство позволяющее
описать преобразование высокоуровневого кода в любые цепочки символов.

Возможно реализовать генератор кода в добавок к массе уже существующих. Не понятно, какую практическую задачу это решает. Другой вопрос, это качество оптимизации. Intel в своё время не смогли обеспечить приемлемый уровень для Itanium.

Лис написал(а):

Рынок у нас в 2021м году состоит из 100000 процессоров Байкал-М и 10000 процессоров Эльбрус.
Значит первым логично сделать под архитектуру Arm v8, чтобы покрыть бо́льшую часть рынка.

Генерация Си-кода охватывает 100000 + 10000.

0

9

Лис написал(а):

... есть библиотека иностранной разработки для отбрасывания окончаний слов.
...
задача, которую надо решить, состоит вовсе не в поиске по коду.

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

(источник)

На всякий случай. В данном интерпретаторе таблица символов реализована префиксным деревом (тернарным). Формат хранения данных в структуре позволяет выполнять поиск начальных частей идентификаторов, то есть без окончаний. Пока такой поиск не реализован, поскольку применений ему я не нашёл.

Отредактировано С.Т. (2021-04-16 12:44:56)

0


Вы здесь » ПО, ЭВМ и АСУ из Таможенного Союза » Рефал » Интерпретатор Рефал-5 (базисный)