- BrainTools - https://www.braintools.ru -
Недельки 2 назад я написал статью про свой скриптовый язык для wiremock wiremockjs [1] В комментариях мне написал Гаузер Эрих Генрихович. Он рассказал, что ещё в 1999 году разработал собственный язык программирования — «Эллочка».
Мне стало дико интересно, что это за зверь. Я не думал долго: взял Perplexity, скормил ему всё, что нашёл про язык на сайтах автора. И попробовал тут же, раз есть описание языка и синтаксиса реализовать на windows. Язык выбрал не самый популярный, но на нем я уже пробовал создавать свою маленькую консольную операционную систему Prometheus OS, но это тема отдельной статьи. Мне показалось это жутко интересным. Это некое подобие потока, вам интересно и вы уже пишите и разбираете язык, а не задаете вопросы зачем и почему. Пропал для общества примерно на час.
Почему стало интересно? Для языка wiremockjs [1] я использовал ANTLR. А тут DOS и «Эллочка» это однопроходный интерпретатор. Не надо разбирать и строить синтаксическое дерево, обход этого дерева в ANTLR. Плюс ограничения самой операционной системы DOS. Да и накатили воспоминания когда игры таскал на floppy дисках, хотя у меня уже стояла windows 98.
За час получилось реализовать:
Числовые переменные (A-Z), одномерные и двумерные массивы.
Присваивание: A=expr, A[i]=expr, A[i,j]=expr, неявные циклы A[]=expr, A[,]=expr.
Управляющие операторы: GOTO, ESLI (с условиями >>,<<,>=,<=,==,|=), SLEP, RADI/GRDS, ORUP/ORDN.
Ввод/вывод (текстовый режим через ANSI): LIST, VVOD, CLSC, CFON, CSIM, STRO, STLB.
Математические функции: &RAN#, &SIN, &COS, &TAN, &ASN, &ACS, &ATN, &EXP, &LOG, &INT, &FRC, &ABS, &SGN, &SQR.
Метки (@label) и переходы по номеру строки или метке.
Системные: EXIT, STOP, базовый MEMC.
Простейший скрипт который получилось выполнить выглядел так.
! Пример программы на Ellochka: приветствие и простой цикл
! (комментарии начинаются с восклицательного знака)
LIST 'Введите ваше имя: '
VVOD $0
LIST 'Привет, '; $0; '!'
A=1
@LOOP
LIST 'Итерация номер '; A
A=A+1
ESLI A << 6; @LOOP
LIST 'Готово!'
EXIT
А структура проекта так:
src/state.zig — таблицы переменных, массивов, строк (включая массив статических строк $A–$Z фиксированной длины 75 символов и динамические строки $0–$9 произвольной длины до 1024 символов), режимы исполнения, палитра.
src/errors.zig — единый набор ошибок парсинга и выполнения.
src/lexer.zig — построчный лексер (токенизация одной строки), поддерживает числа без ведущего нуля (.011).
src/expr.zig — парсер и вычислитель арифметических выражений; математические функции (&SIN, &COS, &SQR и т.д.), унарные +/-, индексация массивов включая сокращённую форму A[] (индекс текущей неявной итерации).
src/program.zig — загрузка программы, таблица меток, адресация по номерам строк; лимит длины строки (75) считается в Unicode-символах, а не в байтах UTF-8 (важно для кириллицы).
src/statement.zig — разбор и выполнение всех 62 операторов.
src/graphics.zig — графический слой: окно Win32 + закадровый DIB-буфер 24bpp, насос сообщений (pumpMessages) для отзывчивости окна во время блокирующих операций (WAIT, MENU).
src/main.zig — точка входа, главный цикл интерпретатора.
Честное признание: возможно, вы скажете, что код писал не я. И будете правы — код генерировала нейросеть. Моя роль заключалась в поиске информации, её агрегации, архитектурных решениях, ревью, код-дирекшене и тестировании.
Воодушевлённый успехом, я решил продолжить вечером. И мне хотелось попробовать запустить оригинальный скрипт sample.ela.
«Эллочка» — интерпретируемый язык, созданный Гаузером Эрихом Генриховичем [2] в Баку. Он задумывался как язык, доступный пользователю без специальной подготовки в программировании, но при этом получил возможности для прикладных и научных расчётов.
Язык поддерживает числовые и текстовые переменные, одномерные и двумерные массивы, работу с файлами, графику, переходы, математические функции и специализированные операции. В оригинальном описании определены 62 оператора — системные, управляющие, файловые, графические, математические и другие.
Оригинальный DIKAR v7 разрабатывался для MS-DOS в 1999–2001 годах. Он включал редактор, справку, пошаговый и командный режимы, диагностику ошибок и комплект примеров. (https://erichware.com/inform/dikar.htm [4])
Вот тут стоит сделать отступление. Я не использовал в данном случае cloude code или open code или codex. Вся магия происходила в чате. Но в последних обновлениях Claude Sonnet 4.5, а именно эту нейросеть я использовал для генерации кода, есть нюанс. Claude Sonnet 4.5 изменился по сравнению с предыдущей версией. Она начинала спорить и не делала, то что я просил или упрощала код. Я нашел решение. Я описывал подробно задачу и просил задать вопросы Cloude Sonet. И вот с этими вопросам я шел в другую нейросеть, а именно в обычный поисковик google в режиме ИИ. Составлял подробнейшие многостраничные ответы. Дополнительно уточняя или искал информацию в интернете. Где то ходил отдельно по некоторым вопросам в DeepSeek. И вот с такими подробными ответами Cloude Sonet уже не сопротивлялся. На реализацию всех 62 операторов потратил примерно 9 часов.
Вы не представляете, сколько нюансов и вопросов возникало при переносе интерпретатора. Но это было жутко интересно.
Интерпретатор я писал на Zig 0.16.0-dev. Кульминацией было запустить оригинальный sample.ela. На zig это расширения *.ell. Оригинальный скрипт sample.ela я переводил в utf-8 и потом уже запускал. Конечно же с первого раза не запустилось. Но скрипт sample.ela я запустил даже раньше чем перевел все операторы “Эллочки”. Это был успех. Не имея исходников, только по описанию удалось воссоздать язык «Эллочка».
По своей невнимательности я не сразу нашел скрипты написанные автором на языке Эллочка. Эрих Генрихович потом подсказал, что все есть тут [5]. Запускать Dikar-я в эмуляторе DOS я стал только после того как запустил sample.ela. У Эриха Генриховича Dikar это не только интерпретатор Эллочки но и программа, которая имеет редактор, помощник, пошаговый и командный режимы работы, а также подробную диагностику ошибок. То есть если встречается ошибка [6] в скрипте Dikar останавливается на данной строке и предлагает поправить. В интерпретаторе я лишь в консоль вывожу строку где произошла ошибка. Ну и я реализовывал только интерпретатор без IDE Dikar.
В последствии я еще в течении недели комитил измененения, запускал оригинальные скрипты в DOS и проверял все операторы. Проверил все кроме сложных математических операторов:
LIRA — линейная алгебра / решение СЛАУ;
POLI — вычисление полинома;
DTRM — определитель;
APRO — полиномиальная МНК-аппроксимация;
REAK — нелинейная реакционная модель;
NTGR — численное интегрирование;
TRAN — решение нелинейной системы;
USER — пользовательская модель.
В отличие от версии DOS в Windows в консоли нельзя реализовать графику и все графические операторы я уже реализовывал и запускал в отдельном окне. Позже чтобы максимально Эллочка соотвествовала оригинальной я в графическом режиме добавил меню и вывод текста в самом графическом режиме.
Раз интерпретатор был написан, то почему бы не написать игру и вспомнить старые добрые игры на DOS.
В репозитории на GitHub есть каталог examples [7] с программами для проверки и изучения реализации.
Два наглядных примера игр:
snake.ell [8] — игра «Змейка» в текстовом режиме;
snake_graphics.ell [9] — графическая версия игры.
Они полезны не только как демонстрации. Текстовая «Змейка» проверяет обработку клавиатуры, экранный вывод, условия, переходы и переменные. Графическая версия дополнительно проверяет графический режим и рисование.
А вот как выглядит оригинальный код игры «Piton» Эриха Генриховича (публикуется с разрешения автора):
!================== piton.ela =============================================
! A - код клавиши
! B - размер описания
! C - флаг ожидания
! D - текущая длина питона
! E - оставшееся число кроликов
! F - оптимальное число ходов
! G - текущий шаг по X
! H - текущий шаг по Y
! I - счетчик
! J - счетчик
! K - максимальное число кроликов
! L - число записей
! M - количество очков
! N - текущее число ходов
! O - текущая задержка
! P - ширина окна
! Q - высота окна
! R - X начала окна
! S - Y начала окна
! T - текущая задержка
! U - текущий уровень
! V - X кролика
! W - Y кролика
! X - X головы питона
! Y - Y головы питона
! Z - ширина питона
!==========================================================================
B:20
P:50
Q:50
R:20
S:120
K:9
Z:5
size B
size [99]=X;Y;P
data 1;B;@opisanie
$0='piton.dat'
graf
csim 3
I:0
incr I
stro I
stlb 40
$1=$I
list $1
esli I << B; -5
cvet 8;63;63;63
orup
csim 8
rama R-1; S-1; R+P*Z; S+Q*Z
pain R+1; S+1; 8
csim 15
rama R; S; R+P*Z-1; S+Q*Z-1
pain R+1; S+1; 15
csim 1
rama R; S; R+P*Z-1; S+Q*Z-1
U:1
D:2
M:0
G:1
H:0
X=&int(P/2)
Y=&int(Q/2)
X[1]=X-1
Y[1]=Y-1
X[2]=X
Y[2]=Y
E=K
lenf $0;L
esli &frc(L/16) |= 0; @newkrolik
L=L/16
csim 13
I:0
@cikl1
incr I
esli I >> L; @newkrolik
getf $0;$1;12;I*16-16
getf $0;J;4;I*16-4
P[I]=J
stro I+B
stlb 40
list $1;J
goto @cikl1
@newkrolik
V=&int((P-1)*&ran#+1)
W=&int((Q-1)*&ran#+1)
csim 4
krug R+V*Z; S+W*Z; Z/2; 1
pixl R+V*Z; S+W*Z
N:0
stro 2
stlb 1
csim 11
list ' Уровень:';U
list ' Осталось кроликов:';E
O=600-U*100
F=&int(&sqr((X-V)^2+(Y-W)^2))
@stepudav
csim 2
krug R+X*Z; S+Y*Z; Z/2; 1
pixl R+X*Z; S+Y*Z
csim 15
krug R+X[1]*Z; S+Y[1]*Z; Z/2; 1
pixl R+X[1]*Z; S+Y[1]*Z
esli C |= 0; +3
wait C
esli C == 27; @konec
I:0
incr I
X[I]=X[I+1]
Y[I]=Y[I+1]
esli I << D-1; -3
incr N
slep O
keys A
esli A == 27; @konec
esli A |= {49,57} +6
A=A-48
H=&sgn((A-4)*(A-5)*(A-6))
G=A-&int(A/3)*3-2
esli G >> -2; +2
G=G+3
X=X+G
Y=Y+H
esli X |= {1,P-1} @rezultat
esli Y |= {1,Q-1} @rezultat
I:0
incr I
esli X[I] |= X; +2
esli Y[I] == Y; @rezultat
esli I << D; -3
X[D]=X
Y[D]=Y
esli X |= V; @stepudav
esli Y |= W; @stepudav
M=M+&int(F/N*50000/O*&sqr(U))
incr D
decr E
esli E >> 0; +4
E=K
incr U
esli U >> 5; +2
goto @newkrolik
stro 2
stlb 1
csim 11
list ' Осталось кроликов:';E
stro 28
stlb 2
csim 4
list 'Все кролики съедены!'
@rezultat
stro 29
stlb 2
csim 14
list 'Результат:';M
csim 7
stro 30
stlb 1
maxa P;J
esli P[J] >> M; @label1
A:1e6
I:0
incr I
esli A <= P[I]; +3
A=P[I]
J=I
esli I << 10; -4
vvod ' Введите Ваше имя: ';$1
$1=$1+%chr(12,32)
$1=%mid($1,1,12)
putf $0;$1;12;J*16-16
putf $0;M;4;J*16-4
@label1
wait
@konec
exit
!--------------------------------------------------------------------------
@opisanie
Установите режим NUM LOCK!
Игра проходит в квадратном поле,
всего 5 уровней сложности, различающихся
скоростью движения и длиной питона.
Управление движением питона произ-
водится цифровыми клавишами на дополни-
тельной клавиатуре в соответствующем
направлении (в режиме NUM LOCK).
Клавиша 5 прекращает игру с выводом
результата, клавиша <Esc> - немедленно.
В случае, если питон ударится о
края поля или пересечет свое тело, он
погибает и выводится результат игры.
На каждом уровне необходимо прогло-
тить 9 кроликов и проползти при этом ми-
нимальный путь. Текущий уровень и остав-
шееся количество кроликов постоянно вы-
водятся на экран.
10 лучших результатов запоминаются
в файле `piton.dat`:
!==========================================================================
Пример игры в Морской бой:
Эти примеры показывают, что Эллочка подходит не только для расчётов. На её основе можно было создавать и интерактивные графические программы и игры.
Автор языка — Гаузер Эрих Генрихович. Информация об авторе: hauserich.vgd.name [10].
Исходный код на zig: github.com/malexple/ellochka-zig [12]
Автор: FilipLinx
Источник [13]
Сайт-источник BrainTools: https://www.braintools.ru
Путь до страницы источника: https://www.braintools.ru/article/34635
URLs in this post:
[1] wiremockjs: https://habr.com/ru/articles/1066180/
[2] Гаузером Эрихом Генриховичем: https://hauserich.vgd.name/
[3] Описание языка Ellochka: https://erichware.com/inform/ellochka.htm
[4] DIKAR v7 — оригинальный DOS-интерпретатор: https://erichware.com/inform/dikar.htm
[5] тут: https://erichware.com/inform/elafiles.htm
[6] ошибка: http://www.braintools.ru/article/4192
[7] examples: https://github.com/malexple/ellochka-zig/tree/master/examples
[8] snake.ell: https://raw.githubusercontent.com/malexple/ellochka-zig/blob/master/examples/snake.ell
[9] snake_graphics.ell: https://github.com/malexple/ellochka-zig/blob/master/examples/snake_graphics.ell
[10] hauserich.vgd.name: https://hauserich.vgd.name
[11] Материалы автора о языке: https://erichware.com/litvor/elacompw.htm
[12] Исходный код реализации на Zig: https://github.com/malexple/ellochka-zig
[13] Источник: https://habr.com/ru/articles/1072306/?utm_source=habrahabr&utm_medium=rss&utm_campaign=1072306
Нажмите здесь для печати.