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

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

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



    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.

    В классе 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

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

    Only registered users can participate in poll. Log in, please.

    Что Вы думаете насчет моей поделки?

    • 52.2%Это интересно и над этим стоит поработать296
    • 36.0%Это прикольно, но не более того204
    • 11.8%Что этот бред делает в моей ленте?67
    AdBlock has stolen the banner, but banners are not teeth — they will be back

    More
    Ads

    Comments 37

      +16
      Разместил плакат с QuRava-трояном и ботнет из Google Glass готов :)
        0
        Буквально несколько месяцев назад на хабре была статья об опасности подмены QR-кодов, а в разрезе данной статьи эта опасность выглядит так — злоумышленник может спокойно наклеить поверх магазинного кода свой код, и вы будете покупать печеньки у него. А для того чтобы защититься от этого, понадобится не язык разрабатывать а интерфейсы и стандарты.
        p.s. но направление мысли нравится
        +14
        Вот и пример технологии, внешне неотличимой от магии.

        И ведь всё ещё находятся ограниченные люди, которые спрашивают: ну зачем детям и подросткам (а также взрослым людям, особенно взрослым людям!) читать (играть, смотреть) фэнтэзи, это же не про реальный мир, ну что оно своим фанатам даёт?!…

        Умственные навыки мышления, полезные для выживания в техномагическом грядущем — вот что оно даёт, вот что!…
          +1
          Хорошо сказали)
            –1
            /me кастует плюсик вашему комментарию.
            +3
            Идея отличная.

            Есть вопрос: я не специалист по андроиду, но первое что приходит в голову: почему не заюзать какой-нибудь встраиваемый язык типа Lua, чтоб не делать велосипеды?
              0
              Мощность языка избыточна. Да и может не поместиться в код. Даже крупные коды вмещают до двух с чем-то килобайт. А маленькие и того меньше. Ну и понятное дело, всегда приятно сделать что-то свое.
                0
                Можно поиграться с алгоритмами сжатия, но Вы, имхо, правы, полноценный язык — слишком жирно, а то найдутся умельцы трояны писать.
                  0
                  Если язык интерпретируемый — то можно запускать в песочнице — доступ в сеть только через спец-демон, например (как это у Ms Store приложений с файловой системой — там для получения доступа к произвольному каталогу нужно вызвать функцию API, которая вызывает диалоговое окно что работает В ДРУГОМ ПРОЦЕССЕ и только тогда приложение получает доступ к тому каталогу. Плюс, все приложения работают в спец-песочнице.)
              –8
              Задумка классная, мне понравилось, но я бы поставил на будущие за html и js.
                +3
                php забыли :-)
                  +1
                  После появления Node.js можно обходиться без PHP, сочиняя и серверную часть на джаваскриптах.
                    +1
                    Причем тут пхп?
                    На html и canvas сейчас можно сделать любой интерфейс, на js (с небольшими доработками под андроид) написать любую логику.

                    Можно делать специальные пакеты, ссылку предоставлять в QR коде.

                    P.S. если вы не согласны, что будущие за js, отпишите ваши мысли, мне просто очень любопытно.
                  +8
                  называете язык Qurva и резонанс в Польше, аналогичный недавнему с Fedora и RPi обеспечен :)

                  А по сабжу — почему бы просто не кодировать в QR байт-код Java?
                    +3
                    Мне кажется, что полноценная Java для этого дела слишком велика и неповоротлива, но я подумаю над Вашим предложением.
                    UPD: Еще возможны проблемы с Oracle.
                      0
                      А что насчёт байткода Питона?
                    +1
                    Я бы посоветовал начать непосредственно с битовых инструкций. Можно очень много сэкономить на месте, если не мерять все октетами (а вам то этого и не надо). Проблему необходимых «отступов» для тех же строк можно решить разными секциями (как это делается в бинарных файлах).
                      0
                      Спасибо за совет. Почитаю об этом.
                        +3
                        Вики говорит, что в QR-код помещается чуть менее 3Kb. В принципе, AVR-ки впролне можно натаскивать на простые задачи впихивая все и в 2Kb, так что у этой задачи есть потенциальный практический успех (что сложно сказать о практическом применении, но это все же отличный just for fun).

                        Добавить сюда хорошую компрессию (мы же это выполняем на шустром современном железе) – и можно выручить еще немного места.

                        Остается вопрос – что будут делать эти приложения? Так или иначе, нужны примитивные арифметические операции, циклы. Это можно не придумывать заново, а взять один из наборов инструкций, которые хорошо себя чувствуют в тесном окружении. ARM Thumb сразу приходит в голову, потому что его можно было бы выполнять сразу на железе, но на самом деле этот набор было бы полезно расширить какими-то высокоуровневыми «прикладными» инструкциями (т.е. построить CISC архитектуру, в противовес RISC).

                        Успехов в общем, и обязательно отпишитесь по результатам, даже если ничего не выгорит (особенно если ничего не выгорит – будет интересно узнать о том, что вы перепробовали).
                      0
                      <комментарий удален>
                        +3
                        Два килобайта кода – это не так уж и много для создания осмысленных приложений, да и у кодов большого размера будут проблемы с чтением из-за небольшого размера элементов.
                        Что такого в перспективе позволит сделать QuRava, чего нельзя достичь ссылкой на небольшое HTML5/js приложение, кроме работы в офлайне? Мне приходит на ум только демосцена из-за примечательной конструкции языка и ограничения на объём программы.
                          0
                          Сразу на ум приходит несколько вещей.
                          1) Доступ к хардварным частям устройства. Через HTML/js это если и возможно, то очень трудно
                          2) Доступ к частям операционной системы.
                          3) Стандартизация интерфейсов. Хорошо, когда гайдлайны по UI намертво вшиты в платформу. Например, интерфейс любого приложения под Андроид, сделанного стандартными средствами может быть плох, но не отвратителен. А если дать разработчикам возможность лепить на HTML/js, то родится адское множество монстров.

                          Хотя, возможно, Вы и правы. Время покажет.
                          +2
                          Добавите функцию по функционалу сравнимой с Ok glass. Send SMS with text… on number… и — думаю Вашу программу будут заинтересованы продвигать ОЧЕНЬ многие люди :D
                            +1
                            Не-е-ет! Вот очередной виток этих premium sms не надо, пожалуйста.
                              +1
                              Это скорее типа такой ситуации — идешь по улице, увидел QR код и БАЦ — уже на счете не хватает примерно так 10$ :)
                                0
                                Так все совремменые (и не очень) телефоны всегда требуют разрешения (или отправка sms у них прописана как permission)
                                  0
                                  в Android достаточно получить это разрешение при установке — а в Glass стоит модифицированный Android 4.x ветки.
                                    0
                                    Ага, и это разрешение приходится выдавать всяким программулинам при установке. С помощью Cyanogenmod (а также некоторых программ) такие разрешения можно отозвать, но не уверен, что такая возможность будет с Glass.
                              0
                              Идея очень и очень крутая
                                0
                                Непонятно, как отличать обыный код со ссылкой от программы?
                                  0
                                  Чего ж непонятного? Другой тип КуАр-коду поставить.
                                  +1
                                  Посмотрите в сторону форт-машин. Стековый язык, возможно, подошёл бы вам больше.
                                    0
                                    Запилить бакэнд для LLVM, и можно на чём угодно будет писать. Или наоборот — фронтэнд, и исполнять на любой железяке.
                                      0
                                      Всё равно выходит некий байт-код, хоть и интерпретируемый!
                                      А почему бы тогда вообще не посмотреть в сторону какого-нибудь существующего ассемблера и плясать на его основе? Под X86, помню, была куча 4К-демок с графикой и прочим. А уж тут в «виртуальный кристалл» можно не стесняться вставлять высокоуровневые инструкции.
                                      Z80, MSP430 или ARM, минус их сугубо аппаратные ограничения, плюс высокоуровневые возможности.
                                        0
                                        представляю гуглоглассеров и иже с ними тогда когда эту штуку возьмут в оборот рекламщики — идешь по городу и по всюду не просто билборды с тектом а вылезающее 3д — машущее руками и предлагающее купить.
                                          0
                                          Уж лучше специальные ссылки на сайты сервисов с параметрами.
                                          Учитывая что андроид приложение (специализированное) может перехватывать свои ссылки, то обращения в сеть не будет (например карты или ютуб так делают).
                                          А если у человека нет этой специальной программы, то он просто попадет на сайт, который все нужное покажет или предложит ее установить.
                                            0
                                            Есть ли какие-нибудь новости с QuRava? Как поживает проект?

                                            Only users with full accounts can post comments. Log in, please.