Пишем свой интерпретируемый шестнадцатиричный язык программирования для QR-кодов

в 16:18, , рубрики: java, QR-коды, дополненная реальность, интерпретатор, ненормальное программирование, Программирование, метки: , , ,

Вдохновившись проектом Google Glass, я подумал, как хорошо было бы сделать крайне простой, но мощный инструмент дополненной реальности специально для таких очков. И почему бы не сделать его на основе такой широко используемой технологии как QR-коды. Так родилась задумка языка QuRava — набора байтов, записанных в QR-коде и интерпретируемого в полноценную программу, реализующую часть возможностей языка Java.

Хочу сразу предупредить, что все нижеизложенное — альфа-версия, сделано за несколько вечеров. Поэтому по поводу маленьких возможностей сильно не ругайтесь и вопросов про отсутствие лямбда-исчисления не задавайте.
Пишем свой интерпретируемый шестнадцатиричный язык программирования для QR кодов

1. Предназначение

Как мне кажется, большинство инструментов дополненной реальности напрочь оторваны от реальности. Они красивые, интересные, но бесполезны для практического применения. И мне захотелось сделать технологию, которая была бы крайне проста и удобна для повседневного пользования. Лучшее, что пришло на ум — это встроить интерпретируемый язык в QR-коды. Они уже широко распространены, и не вызывают у людей отторжения. Их можно распечатать и прилепить в любое место, будь то столик кафе или витрина магазина. Они считываются почти мгновенно, и поэтому с помощью Google Glass можно будет отображать программы в реальном времени.

Плюсы такого подхода очевидны:

  • нужна лишь программа-интерпретатор и сам QR-код, не нужно никакого дополнительного оборудования
  • стандартизированность интерфейсов; людям не нужно обучаться заново каждый раз
  • огромные потенциальные возможности: например, можно сделать заказ в кафе, посмотрев на столик, или заказать билеты на рок-концерт, посмотрев на афишу
  • элементарная простота и дешевизна создания и распространения программок

Но есть и минусы:

  • маленький размер программы. Решается выкачкой дополнительной логики по сети
  • возможно легче было бы скачивать из интернета по QR-ссылке код на каком-нибудь скриптовом языке, хоть это и медленнее
  • вспоминается роман Стивенсона «Лавина», в котором люди, посмотрев на черно-белое изображение, плавили себе мозги

2. Структура языка

В QR-коды информация записывается с помощью последовательности участков по 8 бит каждый. Поэтому язык я решил создать на основе байтового исчисления, то бишь на основе шестнадцатеричных символов от 00 до FF. Сначала в голову пришла идея записи в штрих-код байт-кода Java, но я отказался от нее из-за избыточности данного подхода. Интерпретируемый язык для QR должен быть очень краток, так штрих-код может содержать в себе в лучшем случае лишь 2 килобайта памяти. Да и много возможностей этому языку много не надо.

Пока что в языке используются лишь три вида конструкций: переменные, процедуры и компоненты Андроид. У каждого объекта этих трех типов есть свой подтип (например, для переменных это 00-boolean, 01 — int, 02-float, 03-String), однобайтовое имя и тело. Для удобство парсера перед каждой конструкцией ставится байт длины.
Например в синтаксической конструкции {06,01,AA,00,00,00,03} содержится следующее:

  • Первый байт — байт длины, равный 6, и парсер считывает 6 байтов после него
  • Второй байт — байт типа данных. Он равен 01, что означает integer
  • Третий байт означает имя переменной. Здесь переменная названа AA, и после интерпретатор будет знать ее именно под этим прозвищем
  • После идет 4 байта тела. Означают, что переменной изначально присвоено значение равное 3

В процедурах же задается список примитивных операций. Например {4,14,АА,АА,ВВ} означает АА = АА + ВВ;

Так как Google Glass еще не вышли, то я написал программу-интерпретатор под Андроид. Поэтому в QuRavе сейчас поддерживаются именно компоненты Андроид. Пока что только Button, TextView и Edit Text. Можно задать их положение на экране, текст на них, а для кнопок добавить указание на процедуру, вызываемую при нажатии. Например, {05,09,05,02,03,08} означает создание кнопки (код 09) с именем 05, положением на экране 02 (вверху по центру, по системе старых телефонных хардварных клавиатур от 1 до 9), с текстом строки по имени 03 и вызовом процедуры по имени 08 при нажатии.

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

3. Интерпретатор

Основной парсер интерпретатора читает программу, разбивает ее на куски и рассылает их субпарсерам, которые в свою очередь могут иметь свои субпарсеры. На основе результатов работы многочисленных парсеров программа по кусочкам собирается на не менее малочисленных фабриках. Готовые процедуры, переменные и компоненты попадают в класс Main.
Пишем свой интерпретируемый шестнадцатиричный язык программирования для QR кодов
В классе Main все содержится в отдельных HashMap'ах. Примером такой HashMap'ы является namesOfVariables:

public Object getVariable(Byte name)
{
	return namesOfVariables.get(name);
}

А чтобы доступ к переменным и компонентам был из процедур и примитивных операций, класс Procedure является наследником класса ProgramUnit (на рисунке обозначен как Main), а примитивная операция расширяет класс Procedure.
В классе процедуры переопределен метод взятия переменной. Добавив к нему еще пару строк, можно реализовать механизм локальных переменных.

@Override 
public Object getVariable(Byte name)
{
	return superiorUnit.getVariable(name);		
}

Если честно, то интерпретатор самая скучная часть сделанного, поэтому хватит о нем.

4. Пример использования

А сейчас покажу Вам то, ради чего Вы собственно и начали читать эту статью. Пример действующей программы на языке QuRava.
В данном примере использованы числа типа byte, а не их hex-эквиваленты!

02,03,00 — объявление пустой строки по имени 00
02,01,01 — объявление переменной типа int по имени 01
02,01,02 — объявление переменной типа int по имени 02
06,03,03,80,108,117,115 — объявление строки с текстом «Plus»

04,11,04,01,00 — создание изменяемого текстового поля по имени 04
05,09,05,02,03,08 — создание кнопки по имени 05 вызывающей при нажатии процедуру 08
04,11,06,03,00 — создание изменяемого текстового поля по имени 06
04,13,07,08,00 — создание неизменяемого текстового поля по имени 07

31,04,08 — объявление процедуры по имени 08
........03,42,00,04 — читаем текст, записанный в поле 04 и кладем его в строку 00
........03,41,01,00 — переводим строку 00 в int и записываем результат в переменную 01
........03,42,00,06 — читаем текст, записанный в поле 06 и кладем его в строку 00
........03,41,02,00 — переводим строку 00 в int и записываем результат в переменную 02
........04,14,01,01,02 — складываем переменные 01 и 02 и записываем результат в 01
........03,40,00,01 — переводим значение 01 в строку и записываем результат в 00
........03,43,07,00 — выводим в текстовое поле 07 строку 00

Ну и собственно демонстрация работы: (извините за качество)

5. Дальнейшее развитие

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

  • разработать простой и мощный синтаксис
  • добавить регулярные выражения, массивы, циклы и многое другое
  • распределить все примитивные операции по библиотекам, дублирующим основные классы-библиотеки самой Java (такие как Math или Arrays например.
  • добавить возможность вызова процедур из других процедур и локальных переменных
  • добавить работу с сетью, функцию скачивания из сети дополнительного контента к программе или даже логики
  • написать кучу стандартных библиотек
  • написать компилятор под desktop и маленькую, но удобную IDE к нему
  • написать всеобъемлюющую справку к языку
  • выложить проект на github

К сожалению пока что показывать еще почти нечего, поэтому не выложу никаких ссылок. Если будет интересно, то поработаю над этим и напишу еще одну статью.
А пока что хочу провести опрос.

Автор: SergioShpadi

Источник

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js