HQ9+ (HQ9+)

Перейти к навигации Перейти к поиску

HQ9+ — шуточный эзотерический язык программирования, созданный Клифом Биффлом во время зимних каникул в 2000-2001 годах, который состоит из четырёх команд, каждая из которых представляет один символ: H, Q, 9, и +. Этот язык не является полным по Тьюрингу.

Общие сведения

[править | править код]

HQ9+ — это шуточный язык, каждая команда которого представляет собой обычную задачу, которую выполняет начинающий программист, когда учится программировать или когда изучает новый язык программирования. Обычное упражнение — написать программу, которая выводит сообщение «Hello, world!». Существуют некоторые языки программирования, на которых это действительно трудно сделать, однако для HQ9+ это элементарная задача, команда H выведет это сообщение. Одна из самых тяжёлых задач для многих языков программирования — создать куайн (программу, выводящую собственный код). На HQ9+ эти задачи становятся тривиальными.

Интерпретатор для HQ9+ очень легко написать, поэтому их было создано очень много. Например, интерпретатор HQ9+ на Python был написан приблизительно за 5 минут и имеет всего лишь 16 строк. Также существует транслятор, написанный на Си, который переводит исходный код с HQ9+ на Си и содержит всего лишь 40 строк.

Существует также другой шутливый язык программирования HQ9++, известный также как HQ9+ с классами, объектно-ориентированная версия, созданная Девидом Морган-Маром (David Morgan-mar). В ней добавлена новая команда, ++ , которая увеличивает счётчик два раза и создает объект. В соответствии с принципом сокрытия информации доступ к этому объекту невозможен.

Кроме того, существует язык HQ9±, в котором, по сравнению с HQ9++, добавлен оператор '-' для проверки правильности программы. Результаты проверки зависят от местонахождения оператора:

  • если он стоит первым символом в программе, то это синтаксическая ошибка
  • после «H» — происходит ошибка ввода-вывода
  • после «Q» — программа уходит в бесконечную рекурсию (хорошая реализация должна рухнуть после переполнения стека)
  • после «9» — начинается бесконечный цикл
  • после «+» — производится деление единицы на ноль
  • после «++» — выбрасывает виртуальное исключение, являющееся методом нового подкласса стандартного суперкласса. В соответствии с лучшими принципами сокрытия данных, не существует способа перехватить это исключение.
Исходный код Вывод
H Hello world!
HQ Hello world!
HQ
QQQQ QQQQ
QQQQ
QQQQ
QQQQ
Q+Q+Q Q+Q+Q
Q+Q+Q
Q+Q+Q

Реализации

[править | править код]

Язык является очень простым для реализации. Ниже приведена реализация интерпретатора на Python.

first_string_pattern = '{0} {1} of beer on the wall, {0} {1} of beer.'
second_string_pattern = 'Take one down and pass it around, {} {} of beer on the wall.'

counter = 0

source = input()

for c in source:
    if c == 'H':
        print('Hello world!')
    elif c == 'Q':
        print(source)
    elif c == '9':
        for bottle in range(99, 0, -1):
          with_right_postfix = 'bottles' if bottle != 1 else 'bottle'
          print(first_string_pattern.format(bottle, with_right_postfix))
          with_right_postfix = 'bottles' if bottle - 1 != 1 else 'bottle'
          print(second_string_pattern.format(bottle - 1 if bottle - 1 != 0 else 'no more', with_right_postfix))
          print()
        print('No more bottles of beer on the wall, no more bottles of beer.')
        print('Go to the store and buy some more, 99 bottles of beer on the wall.')
          
    elif c == '+':
        counter += 1
    else:
        print('Syntax error!')

Реализация на C++:

#include <iostream>
#include <conio.h>

using namespace std;

int main()
{
    system("title HQ9+");
    int count = 0;
    string source;
    char ch;
    cout << "Source: ";
    cin >> source;
    system("cls");
    for(int i = 0; i < source.size(); i++)
    {
        ch = source[i];
        if(ch == 'H')
        {
            cout << "Hello, World!" << endl;
        } else if(ch == 'Q')
        {
            cout << source << endl;
        } else if(ch == '9')
        {
            for(int beer = 99; beer > 1; beer--)
            {
                cout << beer << " bottles of beer on the wall, " << beer << " bottles of beer" << endl;
                cout << "Take one down, pass it around, " << beer - 1 << " bottles of beer on the wall!" << endl;
                cout << endl;
            }
            cout << "1 bottle of beer on the wall, 1 bottle of beer." << endl;
            cout << "Take one down and pass it around, no more bottles of beer on the wall." << endl;
            cout << endl;
            cout << "No more bottles of beer on the wall, no more bottles of beer." << endl;
            cout << "Go to the store and buy some more, 99 bottles of beer on the wall." << endl;
        } else if(ch == '+')
        {
            count++;
        } else
        {
            cout << "Syntax error!" << endl;
        }
    }
    getch();
    return 0;
}

Примечания

[править | править код]