Заметка про экспериментальный редактор кода. Создавался для исследования бинарных данных. Графический клиент, консольный интерфейс и встраиваемая библиотека.
Основная идея - каждое изменение мгновенно применяется, любое изменение можно отменить. Концепция похожа на систему контроля версий, только работает не с текстом, а с памятью программы. Понравилось - фиксируешь, не понравилось - откатываешь.
Примечательные возможности:
Живой кодинг.
Создание контрольных точек.
Отладка с перемещением во времени.
Смещения, адреса и размеры в битах (да, если в байте 7 или 9 бит)
Тэгирование данных

Живой кодинг.
Что такое live coding?
Live coding - программирование на-лету или интерактивное программирование. Описывается как форма искусства или импровизации, техника написания и тестирования кода в уже запущенной программе.
Горячая замена
В компилируемых языках, чаще используют отладчик с заменой кода. Применяется JIT или подмена точки входа в функцию. Другой распространенный способ, исполняемый файл не изменяется, код выносят в динамическую библиотеку, перекомпилируют и загружают поверх старой. Стабильно работают правки функций и методов, менять сигнатуры или удалять что-то, не рекомендуется.
В интерпретируемых языках предпочитают REPL. Пользователь самостоятельно загружает необходимую часть кода. Чтобы заменить файл целиком, и не потерять значения глобальных переменных, добавляют проверку на повторную инициализацию.
;; Язык Clojure. defonce - определяет переменную только один раз
(defonce ChatHistory [])
// Язык Javascript. Первая инициализация, устанавливаем дефолтное значение.
if (window['ChatHistory'] == undefined)
window['ChatHistory'] = [];
Основной недостаток - легко поломать рабочее состояние.
Даже когда используется неизменяемая модель памяти или копирование, проще перезапустить отладку, чем ремонтировать поврежденные переменные.

Создание контрольных точек
Когда вводишь в REPL сложное выражение, и где-то в середине вылетает исключение, происходит неприятная ситуация. Часть выражения изменила среду, например, сработало чтение из файла и заполнение буфера. Другая часть, парсинг и запись, не отработали. Если исправить ошибку и повторно выполнить выражение, получится совершенно другой результат. Позиция в файле уже переместилась, а буфер заполнен.
В один из таких моментов, хочется сказать: пожалуйста, верни всё обратно. Так и появилась дурацкая идея, сохранить все переменные, а затем восстановить. Некоторые изменения необратимы, время, запись в сетевой сокет. Другие можно имитировать, например, печать на консоль или изменение позиции в файле.

Отладка с перемещением во времени
Когда программа падает, бывает сложно определить причину. Кто испортил указатель, почему индекс массива вычисляется неправильно. В таких случаях добавляют логи или ставят точку останова выше места падения, чтобы проследить путь.
Для сложных случаев есть специальные инструменты, такие как rr. Программу запускают под отладкой и ведется запись каждого действия. Файл записи можно отматывать назад.
XEH по желанию пользователя, включает обратную отладку опцией "RDebug". В простых случаях, достаточно поправить значения переменных и продолжить исполнение.

Заморозка изменений
Область кода редактора не сильно отличается от REPL. Более удобное редактирование и подсветка ошибок. Если нажать запуск, то текущий код исполняется, перемещается в историю и создается контрольная точка. Так проще сфокусироваться на новой порции кода, и не запускать уже отлаженный код. История измененией сохраняется линейно, кнопка "разморозить" собирает все буферы в один исходный файл.
Пример, декодируем base64 строку и исследуем содержимое. Применим xor шифрование, чтобы раскрыть текстовое сообщение. open-input - открывает строку на чтение, а редактор прикрепляет текущий контекст к области данных.
Обратите внимание, во время набора цикла получилась бесконечная петля. Интерпретатор остановил исполнение с ошибкой "превышен лимит инструкций".

Битовые строки
Редактор работает с битовыми строками, порядок чтения MSB. Хорошо для работы с экзотическими форматами и структурами без выравнивания. Плохо для повседневной работы, приходится учитывать что смещения битовые. Текстовое представление битовой строки: шестнадцатеричные буквы A-F кодируют 4 бита, одиночные биты 0 - ., 1 - x.
Пример, сдвигаем позицию в файле на 3 бита.

Стикеры и тэги
Ко всем значениям можно добавить тэги. Они прикрепляются как дополнительный скрытый атрибут. Например, println проверяет тэг "fmt", как отформатировать число. Редактор ищет подсказку, каким цветом отображать значение, есть ли комментарий.

Язык команд
За основу взял стэковые Forth/T1, чтобы работа в REPL была максимально простой. Хорошая выразительность, краткая запись, необязательно сохранять промежуточный результат в переменных. Forth позволяет изменять ключевые конструкции языка или создавать новые, но часть проверок происходит во время исполнения. T1 более строгий, запускает только завершенные контексты.
trial> endif
ERROR: <buffer#2>:1:1
endif
^
balance endif with preceding if/else
Вместо препроцессора используется мета-контекст. Код выполниться во время компиляции. Можно создавать функции, константы или генерировать код, но нельзя получить доступ к переменным времени исполнения.
Пример, #( открывает контекст, #) - закрывает. Все что остается на стэке, записывается в байткод константой.
: fib dup 1 > if
dup 2 - fib
swap 1 - fib
+
endif
;
\ считаем факториал во время компиляции
#( 20 fib #) var fib-of-20
\ Результат компиляции в байткод
\ 000f: loadi64 6765
\ 00010: store heap.0x5
Структурное редактирование
Структурный редактор загружает файлы без ошибок. Пользователь должен заранее их исправить в текстовом режиме. Редактор учитывает переносы строк, чтобы сохранить оригинальное форматирование. Сложные конструкции группируются в блоки, чтобы нельзя было нарушить структуру программы. Числа и литералы проходят валидацию ввода.
Первая попытка, вертикальная расстановка блоков, плохо воспринимается.

Вторая попытка, больше похож на режим vim с окном для тулов. Остановился на расстановке маркеров D&D вокруг каждого элемента при наведении, но результат мне не понравился.

Заключение
Вот такой эксперимент. Графический интерфейс постоянно пытается превратиться в классическую IDE. Если добавить все функции, интерфейс станет слишком перегружен, а без них пользоваться неудобно. Это явный признак, что надо переосмыслить подход.
Песочница в браузере
Примеры запускаются из меню Help -> Examples
Консоль и реализация языка: repo xeh
Графический редкатор linux/windows/mac/wasm: repo xeh_egui
Комментарии (10)

VBDUnit
14.10.2025 17:52Офигенно! Захотелось что‑то подобное с интерактивной отладкой прикрутить в своём поделии (тоже эксперимент :)), но боюсь тут работы будет на полгода, и оно точно превратится в IDE.
Если добавить все функции, интерфейс станет слишком перегружен, а без них пользоваться неудобно. Это явный признак, что надо переосмыслить подход.
Насколько я понял, весь эксперимент как раз и является сам по себе переосмыслением классического подхода не то что к отладке, а вообще к процессу разработки.
Имхо: все‑не все, но многие из классических функций сюда впихнуть можно без сваливания в «обычный IDE», просто нужно будет продолжать всё переосмысливать, и думать над каждой фичей отдельно и на свежую голову. Вполне вероятно, что некоторые функции просто отвалятся за ненадобностью, а другие сольются в одну.
Может быть здесь не будет лишним какой‑нибудь сопровождающий отладку AI‑ассистент. Он может быть даже невидимым, то есть это не тупо какой‑то очередной чат, а просто повышенная «умность» среды, когда она сама понимает, на что обратить внимание и какие значения куда вывести, какие действия ненавязчиво предложить в конкретно этой ситуации.

rivo Автор
14.10.2025 17:52AI для отладки не пробовал применять, интересно что получиться. Заставлял его код писть, новые языки он не умеет учить, а общие указания или Forth, вполне хорошо выдает.

domix32
14.10.2025 17:52Как-то неочевидно происходит запуск. Я думал зелёное поле это типа индикатор FPS или что-то в этом роде, а оказалось это поле ввода. Примеры, которые его используют, не подставляю туда свои значения. И канвас по-умоланию маловат. Кажется для наглядности стоило бы автоматом процентов 200 ставить для них.
Попытки набирать текст в этом поле тригеррят какие-то глобальные хуки:
с - ставит фокус в поле редактора
o -триггерит открытие файла
m - вкл/выкл окна канваса
и так далее.
А почему не сделать как у других инструментов типа Strudel - закончил изменение, ctrl+enter автоматически триггерит Snapshot + Run и если что-то не скомпилировалось пишет куда-нибудь ошибку и возвращает последний снапшот.

rivo Автор
14.10.2025 17:52В браузере нельзя использовать мета хоткеи ctrl/alt, поэтому режим сделан как в vim, сначала снимается фокус с окна (Esc), а за тем вводится команда. Проверьте, что у вас фокус на редактор кода установлен. В десктопной версии запускается по ctrl+enter.
Hotkeys Open binary file...(Esc, O) Program - Run(Esc, R) or (Cmd+Enter) or (Ctrl+Enter) Program - Snapshot(Esc, S) Program - Rollback(Esc, L) Debugger - Next(Esc, B) Debugger - Reverse Next(Esc, N) Debugger - Enable Reverse Next(Esc, Y) Hex - Scroll Up(Esc, Arrow Up) Hex - Scroll Down(Esc, Arrow Down) Hex - Go To...(Esc, G) Focus on Code(Esc, E) Canvas - Show(Esc, M) Help - Show(Esc, H) Mouse Open binary file with Drag and Drop
domix32
14.10.2025 17:52Проблема 1. Коли у вас VIM mode то было бы неплохо отображать режим.
Проблема 2: Режимы не должны мешать вводу в поля. Попробуйте самостоятельно напечатать ручками хотя бы тот же думовский
update_fireв ваш Interval. Не скопировать, а именно напечатать.Проблема 3: не очень вимовские байндинги. Ну и стоит отметить что
Nиnобычно означаютShift+Nи простоN.Проблема 4. Ctrl + Enter работает не самым очевидным образом. Он взводит Freeze, о чём свидетельствует только активация кнопки Unfreeze и при этом становится доступно какой-то соседний буффер для ввода.

rivo Автор
14.10.2025 17:52Проблема 1-3
Это не vim режим, это костыль xD. По Esc снимается фокус ввода и можно какой-то хоткей вызвать.
Ctrl+r,Сtrl+s,F1-F12 и многие другие браузер перехватывает.
Назначил запуск на Ctrl+Enter, вроде, не конфликтует. Остальные хоткеи отключил. Согласен, они криво работают, лучше их спрятать в web версии.Проблема 4. Ctrl + Enter работает не самым очевидным образом. Он взводит Freeze, о чём свидетельствует только активация кнопки Unfreeze и при этом становится доступно какой-то соседний буффер для ввода.
Код который заморозился окрашивается в желтый цвет и наверх уезжает, его нельзя редактировать. Это как в REPL нажать Enter, буфер в историю перемещается. Поле ввода очищается и можно новый код писать.

rivo Автор
14.10.2025 17:52В режиме TRIAL(чекбокс в меню), программа компилируется и запускается прямо во время набора кода. Ошибки отображаются в статусной строке, красным цветом. Код без ошибок печатает статус
OK.
Если что-то не нравиться, достаточно отредактировать код или стереть. Программма откатиться к посленему удачному запускуRun.
Если результат подходит, то его надо зафиксировать кнопкойRun.С выключеной опицией TRIAL, редактирование будет как в классическом REPL. Во время набора текста ничего не происходит. Результат или ошибку отображает только после запуска. Снимки прораммы создаются вручную, кнопками Snapshot/Rollback.
Wesha
Это как НЕХ, только наоборот?
rivo Автор
Верно, из стэка данные выпрыгивают в обратном порядке. HЁХ редактор, тоже подходящая отсылочка.
alcotel
Это как ХАМ, только наоборот)) Как 3-ри поросёнка: hex-hex, hack-hack и crack-crack. Третий, судя по акценту, похоже, оказался приёмный.
Извините, с языка сорвалось, больше не буду. Автору - на самом деле респект за продуманность системы. Идей в общем у всех - навалом. Но продумать и дожать до состояния, когда кто-то ещё сможет этими наработками пользоваться - где-то 1:10, если не хуже.