994 заметки с тегом

программирование

99 бутылок: Lua

Пока ещё помню язык Луа, который я использовал для написания «Морского боя» в азбуке Морзе, надо бы продолжить им сериал о «99 бутылках пива на стене».

73. Lua — скриптовый язык, который чаще всего применяют для встраивания, например — нередко используют для описания сценариев в играх. Объектная модель прототипная, напоминает ДжаваСкрипт, но в Луа она мощнее.

Язык очень простой, учится элементарно, но при этом довольно мощный.

А вот стандартная библиотека подкачала, простой пример — в ней нет функции задержки, когда она мне понадобилась, пришлось её импортировать из Си. Или есть модуль, который хоть как-то позволяет работать с ЮТФ-8, но в нём даже нет простого способа получить символ по его номеру или поменять регистр строки.

function beer(b)
    if b == 1 then
        return '1 bottle'
    else
        return (b == 0 and 'no' or b) .. ' bottles'
    end
end

b = beer(99)

for i = 99, 1, -1 do
    print(b .. ' of beer on the wall, ' .. b .. ' of beer.')
    b = beer(i - 1)
    print('Take one down and pass it around, ' .. b .. ' of beer on the wall.\n')
end

print([[No more bottles of beer on the wall, no more bottles of beer.
Go to the store and buy some more, 99 bottles of beer on the wall.]])
 6 комментариев    210   7 дн   99   lua   программирование

День Радио

Сегодня, 7 мая в России отмечают День радио — в этот день, 125 лет назад российский физик Александр Степанович Попов на заседании Русского физико-химического общества продемонстрировал «прибор, предназначенный для показывания быстрых колебаний в атмосферном электричестве».

К этому юбилею, превозмогая лень, прокрастинацию и уныние от «самоизоляции», мне удалось наконец дописать игрушку, которую я задумал ещё несколько лет назад. Игра была готова неделю назад, но я всё никак не мог сделать последний шаг — добавить описание и выложить наружу.

Отладочный режим получившегося «Морского боя», в обычном режиме видно только мигание светодиода

Для практики в моей любимой дисциплине — «ненормальном программировании», очень хотелось написать какую-то игрушку, в которую играть нужно будет кодом Морзе.

В итоге, для этого я выбрал «Морской бой». В моём варианте игрок вводит информацию клавишей левого «Шифта», а компьютер отвечает, мигая светодиодом кнопки «Капс Лок». Чуть более подробные правила есть в репозитории проекта.

Обёртка и некоторые функции (мигание светодиодом, опрос «Шифта» и функция задержки) написаны на Си, остальная часть — на языке «Лу́а» (Lua). Давно хотелось изучить этот странноватый язык поглубже, а тут ещё удалось поучиться встраивать его в Си.

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

Диграфы в Си немного запутывают и вносят в код толику безумия

Пока работал над игрой, приходилось много гуглить, в очередной раз поразился, как много кода люди бездумно копируют друг у друга. Реализация мигания светодиодом, например, кочует из проекта в проект в неизменном виде — видно, что никто из скопировавших не понимает как этот код вообще работает. Я в нём попытался разобраться и написать чуть чище, чем буквально везде.

Для тех безумцев, которые захотят попробовать скопмилировать этот вариант «Морского боя» и сыграть, ещё раз привожу репозиторий проекта (только под «МакОСь») — https://github.com/bolknote/battleship.

 2 комментария    310   18 дн   lua   программирование   си

«Разрабы»

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

Раньше к утру я был в относительной норме, но теперь чувствую, как внутри копится какое-то напряжение, похожее на сжатую пружину в механических часах, которое теперь только нарастает.

Чтобы его как-то сбросить, решил вечерами смотреть сериалы — возможно какие-то новые визуальные раздражители и развлекательный контент помогут справиться со стрессом.

Код на экране рабочего места русского программиста Сергея Павлова, одного из героев сериала

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

Тема квантовых компьютеров находится на самой границе моих интересов, но всё же в их сторону я иногда поглядываю.

Пока посмотрел только первую серию. В ней заметную часть экранного времени только что принятый в команду русский программист Сергей Павлов шокировано пялится на некий квантовый код, который довольно чётко видно зрителю.

Меня заинтересовало на чём же они там пишут. Знающие люди в чате бывших коллег сказали, что в кадре редактор «Емакс» («EMACS»). Я им никогда не пользовался, поэтому верю на слово.

Язык программирования в центре — преимущественно Пайтон с подключенными модулями (из знакомых мне — математический пакет numpy и пакет квантовых вычислений qiskit), но видны вкрапления чего-то Си-подобного (последние несколько строк) и чего-то мною неопознанного (с операторами do, case и hypo).

Честно сказать, я ждал какого-нибудь «Ку-шарпа» (Q#) или какого-то другого языка, придуманного для квантовых вычислений, но почему бы и не «Пайтон», язык сейчас на коне.

Вокруг окна с кодом наверное какие-то плагины редактора — место для заметок, потребление ресурсов (мы видим десятиядерную машину, у которой проблемы с доступной памятью — приходится серьёзно использовать своп), окно генератора случайных чисел и какой-то Gate Monitor.

Интересно для чего потребовалось делать мешанину из языков? Чтобы подчеркнуть, что это фантастика, а не реальный код? Или консультант тупо скопировал откуда-то готовые листинги и, не разбираясь, просто скроил из них нечто, что достаточно по-гиковски смотрится в кадре?

 3 комментария    400   1 мес   программирование

99 бутылок: CFAQ

Отдаю очередную дань своему давнему хобби — написанию американской традиционной песни про пиво на разнообразных языках программирования.

72. CFAQ (читается «СИФАК»). Очень люблю самодельные языки программирования, есть в них какое-то милое очарование, крафтовость с нотками олдскула. Услада сердцу после вездесущего Кровавого Энтерпрайза.

Когда узнал, что у известного писателя-фантаста Леонига Каганова есть собственный фреймворк для чипа ESP8266 со встроенным самописным скриптовым языком программирования «СИФАК», не мог пройти мимо. Леонид хоть и зарабатывает на жизнь литературными трудом, но когда-то работал программистом, разрабатывая на ассемблере модули устройств для геофизики и дозиметрии.

Язык, конечно, довольно простой, без поддержки подпрограмм или функций (их можно эмулировать отдельными файлами, передавая параметры через глобальные переменные), но с циклами, ветвлениями и переменными.

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

# 99.TXT. Написано Степанищевым Евгением, апрель 2020
B = 99
repeat -1 {
    Bt = {B}

    repeat 2 {
        if {Bt} = 0 {
            set S = no bottles
        } else {
            if {Bt} = 1 {
                set S = 1 bottle
            } else {
                set S = {Bt} bottles
            }
        }

        if {Bt} = {B} {
            echo {S} of beer on the wall, {S} of beer.<br>
        } else {
            echo Take one down and pass it around, {S} of beer on the wall.<br>
        }

        Bt -= 1
    }

    B -= 1

    if {B} = 0 {
        echo No more bottles of beer on the wall, no more bottles of beer.<br>
        echo Go to the store and buy some more, 99 bottles of beer on the wall.

        exit
    }
}

Первую версию программы писал вайтбордингом — мне её просто негде было запустить. К счастью Леонид предоставил тестовый стенд на побаловаться, я исправил все ошибки и теперь программа гарантированно работает, проверено. Правда все 99 «бутылок» она вывести не может — не хватает памяти в буфере вывода, так что испытывал на десяти.

Выполнение программы на стенде, предоставленном автором языка

Скудность конструкций языка компенсируется относительным богатством встроенных функций для работы с различным оборудованием и взаимодействия с внешним миром (например, он умеет выводить информацию через бота в мессенджер «Телеграм»), но в моей программе это, разумеется, не пригодилось.

 6 комментариев    332   1 мес   99   программирование

Три новые старые статьи

Свой собственный сайт появился у меня в ноябре 2000 года, кажется по адресу bolk.chat.ru. Позже мы познакомились с Алексом Экслером, который предложил хостится у него по адресу bolk.exler.ru, а в 2008-м году, после какого-то дискового сбоя, я переехал на свой домен bolknote.ru, где мой сайт обитает до сих пор. Недавно я перепечатал сюда часть своих бумажных дневников, начиная с 1989 года, и внизу, в подвале сайта у меня теперь в качестве старта сайта значится этот год.

Естественно моё присутствие в интернете началось не в 1989 году, но и до двухтысячного года что-то в интернет я писал. В частности, в 1999-м году опубликовал три статьи на «Цитфоруме» — «Хабре» того времени. В те времена это было очень круто, родители показывали бумажные распечатки своим знакомым.

Недавно, перевёрстывая некоторые старые заметки начала 2000-х, я обратил внимание, что все ссылки тех годов ведут в никуда — проекты или умерли, или сменили домен, или адресацию. Это подало мне идею перетащить сюда свои цитфорумские статьи, пока этот сайт ещё жив.

Точные даты публикаций, к сожалению, неизвестны, но я восстановил примерные, ориентируясь на дату появления моих заметок на сайте «Веб-архива»:

Что нового в JavaScript версии 1.3 от Netscape
Найди картинку. Неизведанные возможности Web-дизайна
Блоки try… catch… finally… в JScript 5

 Нет комментариев    273   1 мес   программирование

Cookie в PHP 7.4

Обнаружилась очень странная проблема у меня на сайте — некоторые комментаторы стали подписываться с плюсом между именем и фамилией. В первый раз я решил, что у человека это вышло случайно или, может, это что-то для него значит, но со временем появились и другие.

Выяснилось, что плюс появился сам собой, люди его и не думали ставить. Так я понял, что столкнулся с каким-то багом.

Слева как куки ставились до ПХП 7.4, справа — как ставятся теперь, пробел кодировался как «+», «плюс» — как «%2B»

В чём примерно дело, понятно стало почти сразу — в вебе пробел иногда кодируется как «+», видимо ошибка как-то связана с этим. Сначала я неправильно подумал, что «плюс» появляется в урле, но данные пользователей туда не попадают, потом сообразил заглянуть в «куки», провёл пару экспериментов и всё встало на свои места.

Проблема воспроизводится у тех комментаторов, которые оставили свой первый комментарий до того, как мой сайт перешёл на ПХП 7.4. В этой версии сменился способ кодирования пробела в «куках» (см. на скриншоте) — был +, стало %20.

В принципе, можно вернуть «статус-кво» следующим кодом:

if (strpos($_SERVER['HTTP_COOKIE'], '+') !== false) {
    parse_str(strtr($_SERVER['HTTP_COOKIE'], ['; ' => '&']), $_COOKIE);
}

Но хорошо бы внедрить в движок блога код, который будет перекодировать такие куки у пользователей.

 2 комментария    290   1 мес   php   php7   программирование   эгея

FFI: баг не будет исправлен?

В пхпешном FFI есть баг — можно, вызывав сишную функцию случайно изменить значение совершенно других переменных

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

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

Видимо, придётся жить с тем, что есть.

В прошлый раз, в качестве временной меры, я предлагал использовать str_repeat (или эквивалент) для того, чтобы разорвать запутанность двух переменных и таким образом предотвратить неожиданное их изменение. Это плохой приём, но я его задумывал в качестве временной меры.

Но раз это навсегда, давайте избегать сторонние эффекты правильно. Тот же читатель предлагает более корректный способ:

Первый параметр memcpy должен быть указателем на отдельно выделенную память достаточного размера. И в FFI есть метод для выделения памяти: FFI::new. Его и надо использовать вместо str_repeat.

Таким образом правильная работа с указателями должна выглядеть примерно вот так:

function memcpy(?string &$dst, string $src):void
{
    $len = strlen($src);
    // изготавливаем тип, в котором уместится копируемая строка
    $type = FFI::arrayType(FFI::type('char'), [$len]);
    // выделяем место под изготовленный тип
    $destination = FFI::new($type);

    FFI::cdef('char *memcpy(char *dst, const char *src, size_t len);')
       ->memcpy($destination, $src, $len);
    // преобразуем область памяти в строку
    $dst = FFI::string($destination, $len);
}

$rock = "ROCK";
var_dump($rock); // «ROCK»
memcpy($rock, "SOCK");
var_dump($rock); // «SOCK»

Что тут происходит?

Мы хотим вызвать сишную функцию для копирования одной строки в другую. В месте, куда мы собираемся копировать, должно быть выделено достаточное количество памяти, мы её выделяем методом FFI::new, передавая ему на вход специально изготовленный тип — указатель на массив однобайтовых символов длиной c копируемую строку.

После копирования преобразуем область памяти в пхпешную строку. Память, выделенная при помощи FFI::new, освободится автоматически.

 3 комментария    284   1 мес   php   php7   программирование

UnknownPlatformer

В одном из чатов по ПХП кинули файлом демку платформера, который использует для отрисовки OpenGL через FFI. Файл называется UnknownPlatformer.zip, это название я и вынес в заголовок.

В ней пока мало что есть — лес с эффектом параллакса, персонаж на первом плане, который управляется стрелками на клавиатуре, но всё это уже очень интересно.

Демка сделана на авторском микродвижке «Bic» (Because I Can), выглядит хорошо и я надеюсь на продолжение, к счастью автор забрасывать (пока?) его не намерен — следующим шагом собирается добавить камеру, нормальный viewport и внедрить паттерн «Entity component system». Движок мультиплатформенный, работает под всеми тремя основными операционными системами — «Виндоуз», «МакОС», «Линукс».

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

composer install
:; [[ $(uname) == "Darwin" ]] && brew install sdl2_image
php app.php
 Нет комментариев    318   2 мес   php   программирование

PHP 7.4 vs. PHP 8.0a

Резюме — в моём частном случае стало ощутимо быстрее, PHP 7.4 работал 63,9 секунд, 8.0a — 42,6.

Как многие знают, основной фишкой восьмой версии интерпретатора ПХП будет JIT. Обещают ускорение вычислительных задач, что немного не про веб, где в основном используется этот язык, но всё равно выглядит интересно.

В официальном репозитории альфа восьмой версии лежит уже давно, стало интересно сравнить её с «семёркой» — много ли даёт JIT приросту. Для подобных тестов я давно использую свой оптимизирующий транслятор «Брейнфака», с загруженной в него задачей вычисления числа Пи.

Восьмой ПХП собрался на моём «Макбуке» следующей последовательностью команд:

PATH=/usr/local/Cellar/bison/3.5.3/bin/:$PATH ./buildconf
./configure --prefix=/opt/php-bin/ --without-iconv --disable-xml \
--without-libxml --disable-simplexml --disable-xmlwriter --disable-dom --disable-xmlreader
make -j4
make install

Версию 7.4 ставил через «брю», сборочную конфигурацию оставил как есть, ничего не менял.

После небольшой коррекции php.ini в информации об интерпретаторе появились OPcache и JIT:

Скомпилированная версия PHP 8.0a со включенным JIT

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

Сравнение PHP 7.4 и 8.0a, со включённым и выключенным opcache (меньше — лучше)

Каждую версию интерпретатора я тестировал со включенным и выключенным OPcache десять раз, а результаты усреднил. Как видите, JIT существенно ускорил выполнение программы в моём случае (там огромное количество циклов и ветвлений) — 63,9 секунды против 42,6.

Что интересно — PHP 8.a без OPcache обогнал версию 7.4 со включенным opcache, это примечательный результат— значит сам «голый» интерпретатор тоже оптимизируют.

 Нет комментариев    364   2 мес   brainfuck   php7   php8   программирование

Комментарии в Си

Из документации к языку Си на сайте «Микрософта», секция про комментарии, описывается нестандартное расширение спецификации:

Comments beginning with two forward slashes (//) are terminated by the next newline character that is not preceded by an escape character. […] the newline character is preceded by a backslash (\), creating an «escape sequence». This escape sequence causes the compiler to treat the next line as part of the previous line. (For more information, see Escape Sequences.)

The default for Microsoft C is that the Microsoft extensions are enabled. Use /Za to disable these extensions.

То есть в примере ниже, если его скомпилировать в «Визуал Студио», выражение i++; на самом деле будет частью комментарий и не выполнится:

// мой комментарий \
    i++;

Счастливой отладки!

Добавлено позднее: в компиляторе gcc тоже работает, причём раскрашивается как комментарий в редакторах vim и «Саблайм».

 9 комментариев    299   2 мес   microsoft   программирование   си
Ранее Ctrl + ↓