The website "dmilvdv.narod.ru." is not registered with uCoz.
If you are absolutely sure your website must be here,
please contact our Support Team.
If you were searching for something on the Internet and ended up here, try again:

About uCoz web-service

Community

Legal information

5.5 Реализация суперкласса — Var

5.5 Реализация суперкласса — Var

Предыдущая  Содержание  Следующая V*D*V

screen() вызывает new(), чтобы создать новую переменную символа, и возвращает его в распознаватель, который вставляет его в дерево выражений. Поэтому Var должна создавать записи таблицы символов, которые могут работать подобно узлам, то есть при определении struct Var нам необходимо расширить struct Name, чтобы унаследовать способность жить в таблице символов, и необходимо поддерживать динамически скомпонованные функции, применимые к узлам выражений. Описываем интерфейс в Var.h:

 

const void * Var;

const void * Assign;

 

Переменная имеет имя и значение. Если вычисляется арифметическое выражение, необходимо вернуть компонент .value. Если выражение удаляется, удалять переменную узла не надо, так как она живёт в таблице символов:

 

struct Var { struct Name _; double value; };

 

#define value(tree) (((struct Var *) tree) -> value)

 

static double doVar (const void * tree)

{

    return value(tree);

}

 

static void freeVar (void * tree)

{

}

 

Как уже обсуждалось в разделе 4.6, код упрощается предоставлением функции доступа к значению.

Создание переменной требует выделения памяти для struct Var, вставки динамической копии имени переменной и значения VAR для маркера, заданного распознавателем:

 

static void * mkVar (va_list ap) {

    struct Var * node = calloc(1, sizeof(struct Var));

    const char * name = va_arg(ap, const char *);

    size_t len = strlen(name);

 

    assert(node);

    node -> _.name = malloc(len+1);

    assert(node -> _.name);

    strcpy((void *) node -> _.name, name);

    node -> _.token = VAR;

    return node;

}

 

static struct Type _Var = { mkVar, doVar, freeVar };

 

const void * Var = & _Var;

 

new() заботится о вставке описания типа Var в узел до того, как символ возвращается в screen() или любому, кто захочет использовать его.

Технически, mkVar() является конструктором для Name. Тем не менее, динамически должны сохраняться только имена переменных. Поскольку мы решили, что в нашем калькуляторе конструктор отвечает за выделение памяти для объекта, то не можем позволить конструктору Var вызывать конструктор Name, чтобы создать компоненты .name и .token — конструктор Name выделил бы память для struct Name, а не для struct Var.

 

Предыдущая  Содержание  Следующая