EditWYSIWYGAttachPrintable
r4 - 26 Jul 2004 - 13:33:00 - OrloVYou are here: TWiki >  Refaldevel Web > CppBackend

C++ backend

Выражения

Надо написать.

Функции

Определение рефал-функции в C++-программе имеет следующий вид:

RF_FUNC (FName, args, ress)
    ...
RF_END

args — входные параметры (аргументы) функции, ress — результаты. На месте многоточия идёт тело функции.

Параметры args и ress имеют следующий синтаксис:

args ::= RF_VOID | (RF_ARG var_names;;)
ress ::= RF_VOID | (RF_RES var_names;;)
var_names ::= ident | ident, var_names

ident — C++-идентификатор.

Аргументы являются совершенно обычными рефал-выражениями, с которыми в теле функции можно производить все те операции, что и с любыми другими объектами класса Expr.

Есть два способа означивания выходных переменных:

  1. Присваивание выходной переменной выражения:
    • res = expr;
  2. Вызов функции (см. #RefalFunctionCalls), которая запишет свой результат в данную выходную переменную. Например:
    • RF_CALL (F, /*void*/, res);

Никаких других действий с выходными переменными, кроме их означивания каким-либо из приведённых двух способов, выполнять нельзя.
? Разумно ли это ограничение? Может быть разрешить делать с переменными, уже получившими значения, всё то же, что можно делать с обычными выражениями?

Штатный возврат (return) из функции осуществляется либо по достижении выражения RF_END, либо если встретится выражение return true; К моменту осуществления штатного возврата все выходные переменные должны быть определены.

Функция завершается неуспехом (возвращает $fail), если встретилось выражение retfail; В этом случае выходные переменные не обязаны быть определёнными.

Примеры:

RF_FUNC (Left, (RF_ARG s_Left, s_Len, e_Exp;;), (RF_RES e_SubExp;;))
    /*
     * Отбросить от e_Exp первые s_Left термов, а затем от того
     * что останется взять первые s_Len термов и записать в
     * e_SubExp.
     * (Для простоты корректность аргументов не проверяется.)
     */
     e_SubExp = Expr(e_Exp, s_Left.cast_to<Integer>(),
                             s_Len.cast_to<Integer>());
RF_END

RF_FUNC (_eq_, (RF_ARG e_Exp1, e_Exp2;;), RF_VOID)
    /*
     * Если e_Exp1 не равно e_Exp2, то выдать $fail.
     */
    if (Expr::compare(e_Exp1, e_Exp2) != 0)
        retfail;
RF_END

Объекты

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

В C++ объекты представляются производными классами от базового класса rfrt::Object, который реализует подсчёт ссылок на объект и его удаление в случае, когда соответствующий символ-ссылка больше не входит ни в какие объектные выражения.
ALERT! Внимание, сборка мусора в циклических структурах, образованных за счёт (прямых или косвенных) ссылок на объект из его содержимого, в данный момент не поддержана!

Подробнее о создании классов, представляющих новые типы объектов, см. Cpp User Object HowTo? .

В Рефале любому объектному выражению соответствует некоторое печатное представление. Для того чтобы сделать печать объектов более осмысленной, чем просто вывод динамически сгенерированного символа-ссылки, в классе rfrt::Object определён виртуальный метод to_string(), с помощью которого можно задавать разные печатные представления для объектов разных типов.

По умолчанию печатное представление объекта выглядит так: <Object|addr>, где addr — адрес памяти, по которому располагается объект.

Стандартные объекты Рефала+ имеют следующие печатные представления (addr — адрес объекта):

  • Ящики: <Box|addr|content>, где content — печатное представление содержимого ящика.
    ALERT! Так сделано исключительно в порядке эксперимента. Содержимое может быть очень большим, и даже снова содержать ссылку на печатуемый ящик. Поэтому стандартное представление должно включать только адрес содержимого. А функция, аналогичная Print, но распечатывающая содержимое ящиков, пишется на Рефале в две строчки.
  • Таблицы: <Table|addr>.
  • Каналы: <Channel|addr|fileno>, где fileno — дескриптор файла, с которым связан канал, либо -1, если канал не связан ни с каким файлом.
  • Векторы: <Vector|addr|data_addr>, где data_addr — адрес, по которому располагается массив выражений (содержимое вектора).
  • Строки: строка является своим печатным представлением.

Особенности реализиций для различных платформ

Edit | WYSIWYG | Attach | Printable | Raw View | Backlinks: Web, All Webs | History: r7 < r6 < r5 < r4 < r3 | More topic actions...
 
R+

This site is powered by the TWiki collaboration platformCopyright © by the contributing authors. All material on this collaboration platform is the property of the contributing authors.
Ideas, requests, problems regarding TWiki? Send feedback